prevctrl.cpp
上传用户:xhy777
上传日期:2007-02-14
资源大小:24088k
文件大小:14k
源码类别:

系统编程

开发平台:

Visual C++

  1. // PrevCtrl.cpp : Implementation of CPreview
  2. #include "precomp.h"
  3. #include "shimgvw.h"
  4. #include "PrevCtrl.h"
  5. #define MIN(x,y)    ((x<y)?x:y)
  6. #define MAX(x,y)    ((x>y)?x:y)
  7. /////////////////////////////////////////////////////////////////////////////
  8. // CPreview
  9. /////////////////////////////////////////////////////////////////////////////
  10. // Control Message handlers
  11. /////////////////////////////////////////////////////////////////////////////
  12. LRESULT CPreview::OnCreate(UINT , WPARAM , LPARAM , BOOL& )
  13. {
  14.     ATLTRACE( _T("CPreview::OnCreaten") );
  15.     RECT rcWnd;
  16.     GetClientRect( &rcWnd );
  17.     // Create the preview window
  18.     if ( m_cwndPreview.Create(m_hWnd, rcWnd, NULL, WS_CHILD|WS_VISIBLE, 0 ) )
  19.     {
  20.         m_cwndPreview.SetNotify( this );
  21.         return 0;
  22.     }
  23.     return -1;
  24. }
  25. LRESULT CPreview::OnActivate(UINT , WPARAM , LPARAM , BOOL& bHandled)
  26. {
  27.     ATLTRACE( _T("CPreview::OnActivaten") );
  28.     m_cwndPreview.SetFocus();
  29.     bHandled = false;
  30.     return 0;
  31. }
  32. HRESULT CPreview::OnDrawAdvanced(ATL_DRAWINFO& )
  33. {
  34.     ATLTRACE( _T("CPreview::OnDrawAdvancedn") );
  35.     return S_OK;
  36. }
  37. LRESULT CPreview::OnEraseBkgnd(UINT , WPARAM , LPARAM , BOOL& )
  38. {
  39.     ATLTRACE( _T("CPreview::OnEraseBkgndn") );
  40.     return TRUE;
  41. }
  42. LRESULT CPreview::OnSize(UINT , WPARAM , LPARAM lParam, BOOL& )
  43. {
  44.     ATLTRACE( _T("CPreview::OnSizen") );
  45.     ::SetWindowPos(m_cwndPreview.m_hWnd, NULL, 0,0,
  46.         LOWORD(lParam), HIWORD(lParam), SWP_NOZORDER | SWP_NOACTIVATE);
  47.     return 0;
  48. }
  49. // IObjectSafety::GetInterfaceSafetyOptions
  50. //
  51. // This method never gets called.  We are safe for any and every thing.  There should
  52. // be no possible way that this control could lose, destroy, or expose data.
  53. STDMETHODIMP CPreview::GetInterfaceSafetyOptions(REFIID riid, DWORD *pdwSupportedOptions,
  54.                                                   DWORD *pdwEnabledOptions)
  55. {
  56.     ATLTRACE(_T("IObjectSafetyImpl::GetInterfaceSafetyOptionsn"));
  57.     if (pdwSupportedOptions == NULL || pdwEnabledOptions == NULL)
  58.         return E_POINTER;
  59.     HRESULT hr = S_OK;
  60.     if (riid == IID_IDispatch || riid == IID_IPersistPropertyBag)
  61.     {
  62.         *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;
  63.         *pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;
  64.     }
  65.     else
  66.     {
  67.         *pdwSupportedOptions = 0;
  68.         *pdwEnabledOptions = 0;
  69.         hr = E_NOINTERFACE;
  70.     }
  71.     return hr;
  72. }
  73. STDMETHODIMP CPreview::SetInterfaceSafetyOptions(REFIID riid, DWORD dwSupportedOptions,
  74.                                                   DWORD dwEnabledOptions)
  75. {
  76. ATLTRACE(_T("IObjectSafetyImpl::SetInterfaceSafetyOptionsn"));
  77. // We are always safe for any data or script call on both of these interfaces
  78. if (riid == IID_IDispatch || riid == IID_IPersistPropertyBag)
  79. {
  80. return S_OK;
  81. }
  82. return E_NOINTERFACE;
  83. }
  84. // IPersistPropertyBag::Load
  85. //
  86. // We have the following properties that we can load from the property bag:
  87. //      Toolbar         false/zero = don't show the toolbar, otherwise show the toolbar
  88. //      Full Screen     false/zero = don't show fullscreen button on toolbar, otherwise show the button
  89. //      Context Menu    false/zero = don't show context menu, otherwise show the context menu when the user right clicks
  90. //      Print Button    false/zero = don't show print button on toolbar, otherwise show the button
  91. STDMETHODIMP CPreview::Load(IPropertyBag * pPropBag, IErrorLog * pErrorLog)
  92. {
  93.     HRESULT hr;
  94.     VARIANT var;
  95.     BOOL bDummy = TRUE;
  96.     var.vt = VT_UI4;
  97.     var.ulVal = TRUE;
  98.     hr = pPropBag->Read(L"Toolbar", &var, NULL);
  99.     if (SUCCEEDED(hr) && var.vt==VT_UI4)
  100.     {
  101.         m_cwndPreview.IV_OnSetOptions(IV_SETOPTIONS,IVO_TOOLBAR,var.ulVal,bDummy);
  102.     }
  103.     var.vt = VT_UI4;
  104.     var.ulVal = TRUE;
  105.     hr = pPropBag->Read(L"Full Screen", &var, NULL);
  106.     if (SUCCEEDED(hr) && var.vt==VT_UI4)
  107.     {
  108.         m_cwndPreview.IV_OnSetOptions(IV_SETOPTIONS,IVO_FULLSCREENBTN,var.ulVal,bDummy);
  109.     }
  110.     var.vt = VT_UI4;
  111.     var.ulVal = TRUE;
  112.     hr = pPropBag->Read(L"Print Button", &var, NULL);
  113.     if (SUCCEEDED(hr) && var.vt==VT_UI4)
  114.     {
  115.         m_cwndPreview.IV_OnSetOptions(IV_SETOPTIONS,IVO_PRINTBTN,var.ulVal,bDummy);
  116.     }
  117.     var.vt = VT_UI4;
  118.     var.ulVal = TRUE;
  119.     hr = pPropBag->Read(L"Context Menu", &var, NULL);
  120.     if (SUCCEEDED(hr) && var.vt==VT_UI4)
  121.     {
  122.         m_cwndPreview.IV_OnSetOptions(IV_SETOPTIONS,IVO_CONTEXTMENU,var.ulVal,bDummy);
  123.     }
  124.     var.vt = VT_UI4;
  125.     var.ulVal = FALSE;
  126.     hr = pPropBag->Read(L"Allow Online", &var, NULL);
  127.     if (SUCCEEDED(hr) && var.vt==VT_UI4)
  128.     {
  129.         m_cwndPreview.IV_OnSetOptions(IV_SETOPTIONS,IVO_ALLOWGOONLINE,var.ulVal,bDummy);
  130.     }
  131.     return S_OK;
  132. }
  133. // IPreview Methods:
  134. STDMETHODIMP CPreview::ShowFile(BSTR bstrFileName, int iSelectCount)
  135. {
  136.     m_cwndPreview.SendMessage( IV_SHOWFILEW, iSelectCount, (LPARAM)bstrFileName );
  137.     return S_OK;
  138. }
  139. STDMETHODIMP CPreview::Show(VARIANT var)
  140. {
  141.     HRESULT hr;
  142.     FolderItem * pfi;
  143.     FolderItems * pfis;
  144.     switch (var.vt)
  145.     {
  146.     case VT_UNKNOWN:
  147.     case VT_DISPATCH:
  148.         // QI for Folder Item
  149.         if ( var.punkVal )
  150.         {
  151.             hr = var.punkVal->QueryInterface(IID_FolderItem, (void**)&pfi);
  152.             if ( SUCCEEDED(hr) )
  153.             {
  154.                 // If the item is a link we want to get the link's target:
  155.                 VARIANT_BOOL vbool;
  156.                 hr = pfi->get_IsLink(&vbool);
  157.                 if ( SUCCEEDED(hr) && (VARIANT_FALSE != vbool) )    // IsLink returns TRUE, not VARIANT_TRUE
  158.                 {
  159.                     IDispatch * pdisp;
  160.                     hr = pfi->get_GetLink(&pdisp);
  161.                     if ( SUCCEEDED(hr) && pdisp )
  162.                     {
  163.                         IShellLinkDual2 * psl2;
  164.                         hr = pdisp->QueryInterface( IID_IShellLinkDual2, (void**)&psl2 );
  165.                         if ( SUCCEEDED(hr) && psl2 )
  166.                         {
  167.                             FolderItem * pfiTarg;
  168.                             hr = psl2->get_Target(&pfiTarg);
  169.                             if ( SUCCEEDED(hr) && pfiTarg )
  170.                             {
  171.                                 pfi->Release();
  172.                                 pfi = pfiTarg;
  173.                             }
  174.                             psl2->Release();
  175.                         }
  176.                         pdisp->Release();
  177.                     }
  178.                 }
  179.                 // We now have the folder item for the target, get it's context menu.  We
  180.                 // look at the context menu to see if the item is printable.
  181.                 FolderItemVerbs * pfivs;
  182.                 BOOL bPrintable = FALSE;        // assume not printable to start with
  183.                 hr = pfi->Verbs( &pfivs );
  184.                 if ( SUCCEEDED(hr) )
  185.                 {
  186.                     long cVerbs;
  187.                     hr = pfivs->get_Count(&cVerbs);
  188.                     if ( SUCCEEDED(hr) )
  189.                     {
  190.                         FolderItemVerb * pverb;
  191.                         VARIANT varItem;
  192.                         varItem.vt = VT_I4;
  193.                         for ( --cVerbs; cVerbs >= 0; cVerbs-- )
  194.                         {
  195.                             varItem.lVal = cVerbs;
  196.                             hr = pfivs->Item( varItem, &pverb );
  197.                             if ( SUCCEEDED(hr) )
  198.                             {
  199.                                 // BUGBUG: Need to add a method to get the canonical verb name
  200.                                 BSTR bstr;
  201.                                 hr = pverb->get_Name( &bstr );
  202.                                 if ( SUCCEEDED(hr) )
  203.                                 {
  204.                                     // BUGBUG: should check against the canonical string "&Print" which will avoid all
  205.                                     // this load and convert to WCHAR crap
  206.                                     WCHAR szPrint[256];
  207.                                     if ( LoadStringWrapW(_Module.GetModuleInstance(), IDS_PRINT, szPrint, ARRAYSIZE(szPrint)) )
  208.                                     {
  209.                                         if ( 0 == StrCmpW( bstr, szPrint ) )
  210.                                         {
  211.                                             bPrintable = TRUE;
  212.                                             cVerbs = -1;
  213.                                         }
  214.                                     }
  215.                                     SysFreeString(bstr);
  216.                                 }
  217.                                 pverb->Release();
  218.                             }
  219.                         }
  220.                     }
  221.                     pfivs->Release();
  222.                 }
  223.                 // Now we need to know the path for this item.  We can only view items if
  224.                 // we can get a path or URL to the target so some namespaces aren't viewable.
  225.                 BSTR bstr;
  226.                 hr = pfi->get_Path(&bstr);
  227.                 if ( SUCCEEDED(hr) )
  228.                 {
  229.                     m_cwndPreview.SendMessage( IV_SHOWFILEW, 1, (LPARAM)bstr );
  230.                     SysFreeString(bstr);
  231.                     hr = S_OK;
  232.                 }
  233.                 else
  234.                 {
  235.                     // we couldn't get the path so we will display the "No Preview" message
  236.                     bPrintable = FALSE;
  237.                     m_cwndPreview.SendMessage( IV_SHOWFILEW, 1, NULL );
  238.                     hr = S_FALSE;
  239.                 }
  240.                 // Finally we need to set the printable verb.  We do this after setting the
  241.                 // path above to avoid the possibility of processing a print when we don't
  242.                 // know the path.
  243.                 put_printable(bPrintable);
  244.                 // now release the Folder Item pointer
  245.                 pfi->Release();
  246.                 return hr;
  247.             }
  248.             else if ( SUCCEEDED( var.punkVal->QueryInterface(IID_FolderItems, (void**)&pfis) ) )
  249.             {
  250.                 // currently in the multi-select case we just show the multi-select message.
  251.                 // eventually this should go to slideshow mode
  252.                 m_cwndPreview.SendMessage( IV_SHOWFILEW, 2, NULL );
  253.                 pfis->Release();
  254.                 return S_FALSE;
  255.             }
  256.         }
  257.         // the unknown pointer isn't for an object type that we know about
  258.         return E_INVALIDARG;
  259.     case VT_BSTR:
  260.         m_cwndPreview.SendMessage( IV_SHOWFILEW, 1, (LPARAM)var.bstrVal );
  261.         break;
  262.     case VT_BOOL:
  263.         // show(false) will hide the currently previewed item
  264.         if ( VARIANT_FALSE == var.boolVal )
  265.         {
  266.             m_cwndPreview.SendMessage( IV_SHOWFILEW, 0, NULL );
  267.             return S_OK;
  268.         }
  269.         else
  270.         {
  271.             return E_INVALIDARG;
  272.         }
  273.     default:
  274.         return E_INVALIDARG;
  275.     }
  276. return S_OK;
  277. }
  278. //***   IsVK_TABCycler -- is key a TAB-equivalent
  279. // ENTRY/EXIT
  280. //  dir     0 if not a TAB, non-0 if a TAB
  281. // NOTES
  282. //  NYI: -1 for shift+tab, 1 for tab
  283. //  cloned from browseui/util.cpp (BUGBUG move to shlwapi?)
  284. //
  285. int IsVK_TABCycler(MSG *pMsg)
  286. {
  287.     if (!pMsg)
  288.         return 0;
  289.     if (pMsg->message != WM_KEYDOWN)
  290.         return 0;
  291.     if (! (pMsg->wParam == VK_TAB || pMsg->wParam == VK_F6))
  292.         return 0;
  293. #if 0 // todo?
  294.     return (GetAsyncKeyState(VK_SHIFT) < 0) ? -1 : 1;
  295. #endif
  296.     return 1;
  297. }
  298. //***
  299. // NOTES
  300. //  hard-coded 1/2/4 (vs. KEYMOD_*) is same thing atlctl.h does.  go figure...
  301. DWORD GetGrfMods()
  302. {
  303.     DWORD dwMods;
  304.     dwMods = 0;
  305.     if (GetAsyncKeyState(VK_SHIFT) < 0)
  306.         dwMods |= 1;    // KEYMOD_SHIFT
  307.     if (GetAsyncKeyState(VK_CONTROL) < 0)
  308.         dwMods |= 2;    // KEYMOD_CONTROL
  309.     if (GetAsyncKeyState(VK_MENU) < 0)
  310.         dwMods |= 4;    // KEYMOD_MENU
  311.     return dwMods;
  312. }
  313. STDMETHODIMP CPreview::TranslateAccelerator( LPMSG lpmsg )
  314. {
  315.     ATLTRACE( _T("CPreview::TranslateAcceleratorn") );
  316.     if ( m_cwndPreview.TranslateAccelerator(lpmsg) )
  317.     {
  318.         return S_OK;
  319.     }
  320.     if ( IsVK_TABCycler(lpmsg) )
  321.     {
  322.         // REVIEW: looks like newer versions of ATL might do this for us so
  323.         // possibly we can replace w/ call to SUPER::TA when we upgrade.
  324.         CComQIPtr <IOleControlSite, &IID_IOleControlSite> spOCS(m_spClientSite);
  325.         if (spOCS) {
  326.             return spOCS->TranslateAccelerator(lpmsg, GetGrfMods());
  327.         }
  328.     }
  329.     return S_FALSE;
  330. }
  331. STDMETHODIMP CPreview::OnFrameWindowActivate( BOOL fActive )
  332. {
  333.     if ( fActive )
  334.     {
  335.         m_cwndPreview.SetFocus();
  336.     }
  337.     return S_OK;
  338. }
  339. LRESULT CPreview::OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  340. {
  341.     ATLTRACE( _T("CPreview::OnSetFocusn") );
  342.  
  343.     LRESULT ret = CComControl<CPreview>::OnSetFocus(uMsg,wParam,lParam, bHandled);
  344.     m_cwndPreview.SetFocus();
  345.     return ret;
  346. }
  347. STDMETHODIMP CPreview::get_printable(BOOL * pVal)
  348. {
  349.     *pVal = m_cwndPreview.GetPrintable();
  350.     return S_OK;
  351. }
  352. STDMETHODIMP CPreview::put_printable(BOOL newVal)
  353. {
  354.     BOOL bDummy = TRUE;
  355.  
  356.     m_cwndPreview.IV_OnSetOptions(IV_SETOPTIONS,IVO_PRINTABLE,newVal,bDummy);
  357.     return S_OK;
  358. }
  359. STDMETHODIMP CPreview::get_cxImage(long * pVal)
  360. {
  361.     // REVIEW: Return an error and set output to zero if no image is currently displayed?
  362.     *pVal = m_cwndPreview.m_ctlPreview.m_cxImage;
  363.     return S_OK;
  364. }
  365. STDMETHODIMP CPreview::get_cyImage(long * pVal)
  366. {
  367.     // REVIEW: Return an error and set output to zero if no image is currently displayed?
  368.     *pVal = m_cwndPreview.m_ctlPreview.m_cyImage;
  369.     return S_OK;
  370. }