dvoc.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 28k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. #include "stdafx.h"
  2. #pragma hdrstop
  3. #include "stdenum.h"
  4. #include <mshtmdid.h>
  5. #define SZ_ATL_SHEMBEDDING_WNDCLASS         TEXT("ATL Shell Embedding")
  6. HRESULT MakeSafeForScripting(IUnknown** ppDisp);
  7. class ATL_NO_VTABLE CWebViewFolderContents
  8.                     : public CComObjectRootEx<CComSingleThreadModel>
  9.                     , public CComCoClass<CWebViewFolderContents, &CLSID_WebViewFolderContents>
  10.                     , public CComControl<CWebViewFolderContents>
  11.                     , public IDispatchImpl<IShellFolderViewDual, &IID_IShellFolderViewDual, &LIBID_Shell32, 1, 0, CComTypeInfoHolder>
  12.                     , public IProvideClassInfo2Impl<&CLSID_WebViewFolderContents, NULL, &LIBID_Shell32, 1, 0, CComTypeInfoHolder>
  13.                     , public IPersistImpl<CWebViewFolderContents>
  14.                     , public IOleControlImpl<CWebViewFolderContents>
  15.                     , public IOleObjectImpl<CWebViewFolderContents>
  16.                     , public IViewObjectExImpl<CWebViewFolderContents>
  17.                     , public IOleInPlaceActiveObjectImpl<CWebViewFolderContents>
  18.                     , public IDataObjectImpl<CWebViewFolderContents>
  19.                     , public IObjectSafetyImpl<CWebViewFolderContents>
  20.                     , public IConnectionPointContainer
  21.                     , public IOleInPlaceObject
  22.                     , public IInternetSecurityMgrSite
  23.                     , public IWebViewOCWinMan
  24. {
  25. public:
  26.     CWebViewFolderContents();
  27.     ~CWebViewFolderContents();
  28.     DECLARE_POLY_AGGREGATABLE(CWebViewFolderContents);
  29.     DECLARE_NO_REGISTRY();
  30.     DECLARE_WND_CLASS(SZ_ATL_SHEMBEDDING_WNDCLASS)
  31. BEGIN_COM_MAP(CWebViewFolderContents)
  32.     // ATL Uses these in IUnknown::QueryInterface()
  33.     COM_INTERFACE_ENTRY_IMPL_IID(IID_IViewObject, IViewObjectEx)
  34.     COM_INTERFACE_ENTRY_IMPL_IID(IID_IViewObject2, IViewObjectEx)
  35.     COM_INTERFACE_ENTRY_IMPL(IViewObjectEx)
  36.     COM_INTERFACE_ENTRY_IMPL_IID(IID_IOleWindow, IOleInPlaceActiveObject)
  37.     COM_INTERFACE_ENTRY_IMPL(IOleInPlaceActiveObject)
  38.     COM_INTERFACE_ENTRY(IOleInPlaceObject)
  39.     COM_INTERFACE_ENTRY(IDispatch)
  40.     COM_INTERFACE_ENTRY(IProvideClassInfo2)
  41.     COM_INTERFACE_ENTRY(IProvideClassInfo)
  42.     COM_INTERFACE_ENTRY_IMPL(IOleControl)
  43.     COM_INTERFACE_ENTRY_IMPL(IOleObject)
  44.     COM_INTERFACE_ENTRY_IMPL(IDataObject)
  45.     COM_INTERFACE_ENTRY_IMPL(IObjectSafety)
  46.     COM_INTERFACE_ENTRY(IConnectionPointContainer)
  47.     COM_INTERFACE_ENTRY(IShellFolderViewDual)
  48.     COM_INTERFACE_ENTRY_IMPL(IPersist)
  49.     COM_INTERFACE_ENTRY(IInternetSecurityMgrSite)
  50.     COM_INTERFACE_ENTRY(IWebViewOCWinMan)
  51. END_COM_MAP()
  52.  
  53. // Declare the default message map
  54. BEGIN_MSG_MAP(CWebViewFolderContents)
  55.     MESSAGE_HANDLER(WM_SIZE, _OnSizeMessage) 
  56.     MESSAGE_HANDLER(WM_NOTIFY, _OnMessageForwarder) 
  57.     MESSAGE_HANDLER(WM_CONTEXTMENU, _OnMessageForwarder)
  58.     MESSAGE_HANDLER(WM_SETCURSOR, _OnMessageForwarder)
  59.     MESSAGE_HANDLER(WM_ERASEBKGND, _OnEraseBkgndMessage)
  60. END_MSG_MAP()
  61.     // *** IDispatch ***
  62.     virtual STDMETHODIMP Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS * pdispparams, VARIANT * pvarResult, EXCEPINFO * pexcepinfo, UINT * puArgErr);
  63.     virtual STDMETHODIMP GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** pptinfo);
  64.     virtual STDMETHODIMP GetIDsOfNames(REFIID riid, OLECHAR **rgszNames, UINT cNames, LCID lcid, DISPID * rgdispid);
  65.     // *** IProvideClassInfo ***
  66.     virtual STDMETHODIMP GetClassInfo(ITypeInfo** pptinfo);
  67.     // *** IInternetSecurityMgrSite ***
  68.     // virtual STDMETHODIMP GetWindow(HWND * lphwnd);              // Also in IOleWindow
  69.     virtual STDMETHODIMP EnableModeless(BOOL fEnable) { return IOleInPlaceActiveObjectImpl<CWebViewFolderContents>::EnableModeless(fEnable); };     // Also in IOleInPlaceActiveObject
  70.     // *** ShellFolderView ***
  71.     virtual STDMETHODIMP get_Application(IDispatch **ppid);
  72.     virtual STDMETHODIMP get_Parent (IDispatch **ppid);
  73.     virtual STDMETHODIMP get_Folder(Folder **ppid);
  74.     virtual STDMETHODIMP SelectedItems(FolderItems **ppid);
  75.     virtual STDMETHODIMP get_FocusedItem(FolderItem **ppid);
  76.     virtual STDMETHODIMP SelectItem(VARIANT *pvfi, int dwFlags);
  77.     virtual STDMETHODIMP PopupItemMenu(FolderItem * pfi, VARIANT vx, VARIANT vy, BSTR * pbs);
  78.     virtual STDMETHODIMP get_Script(IDispatch **ppid);
  79.     virtual STDMETHODIMP get_ViewOptions(long *plSetting);
  80.     // *** IOleWindow ***
  81.     virtual STDMETHODIMP GetWindow(HWND * lphwnd) { return IOleInPlaceActiveObjectImpl<CWebViewFolderContents>::GetWindow(lphwnd); };
  82.     virtual STDMETHODIMP ContextSensitiveHelp(BOOL fEnterMode) { return IOleInPlaceActiveObjectImpl<CWebViewFolderContents>::ContextSensitiveHelp(fEnterMode); };
  83.     // *** IOleObject ***
  84.     virtual STDMETHODIMP GetMiscStatus(DWORD dwAspect, DWORD *pdwStatus);
  85.     // *** IOleInPlaceObject ***
  86.     virtual STDMETHODIMP InPlaceDeactivate(void);
  87.     virtual STDMETHODIMP UIDeactivate(void) { return IOleInPlaceObject_UIDeactivate(); };
  88.     virtual STDMETHODIMP SetObjectRects(LPCRECT lprcPosRect, LPCRECT lprcClipRect);
  89.     virtual STDMETHODIMP ReactivateAndUndo(void)  { return E_NOTIMPL; };
  90.     // *** IOleInPlaceActiveObject ***
  91.     // our frame was activated, better do the activation thing.
  92.     STDMETHODIMP OnFrameWindowActivate(BOOL fActivate)
  93.     {
  94.         if (_hwndLV && fActivate)
  95.             ::SetFocus(_hwndLV);
  96.         return S_OK;
  97.     };
  98.     virtual STDMETHODIMP TranslateAccelerator(LPMSG pMsg);
  99.     // *** IWebViewOCWinMan ***
  100.     STDMETHODIMP SwapWindow(HWND hwndLV, IWebViewOCWinMan **pocWinMan);
  101.     // *** IConnectionPointContainer ***
  102.     STDMETHODIMP EnumConnectionPoints(IEnumConnectionPoints **ppEnum);
  103.     STDMETHODIMP FindConnectionPoint(REFIID riid, IConnectionPoint **ppCP);
  104.     // Over ride ATL functions.
  105.     LRESULT _OnMessageForwarder(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled);
  106.     LRESULT _OnEraseBkgndMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled);
  107.     LRESULT _OnSizeMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled);
  108.     HRESULT DoVerbUIActivate(LPCRECT prcPosRect, HWND hwndParent);
  109.     HRESULT DoVerbInPlaceActivate(LPCRECT prcPosRect, HWND hwndParent);
  110.     virtual STDMETHODIMP Close(DWORD dwSaveOption);
  111. protected:
  112.     // Helper functions;
  113.     HRESULT _SetupAutomationForwarders(void);
  114.     HRESULT _ReleaseAutomationForwarders(void);
  115.     HRESULT _OnInPlaceActivate(void);
  116.     void _ReleaseWindow(void);
  117.     void _ShowWindowLV(HWND hwndLV);
  118.     void _UnadviseAll();
  119.     class CConnectionPointForwarder : public IConnectionPoint
  120.     {
  121.         // IUnknown methods
  122.         //
  123.         virtual STDMETHODIMP QueryInterface(REFIID riid, LPVOID * ppvObj);
  124.         virtual STDMETHODIMP_(ULONG) AddRef(void);
  125.         virtual STDMETHODIMP_(ULONG) Release(void);
  126.         // IConnectionPoint methods
  127.         //
  128.         virtual STDMETHODIMP GetConnectionInterface(IID * pIID);
  129.         virtual STDMETHODIMP GetConnectionPointContainer(IConnectionPointContainer ** ppCPC);
  130.         virtual STDMETHODIMP Advise(LPUNKNOWN pUnkSink, DWORD * pdwCookie);
  131.         virtual STDMETHODIMP Unadvise(DWORD dwCookie);
  132.         virtual STDMETHODIMP EnumConnections(LPENUMCONNECTIONS * ppEnum) { return _pcpAuto->EnumConnections(ppEnum); }
  133.         IConnectionPoint *  _pcpAuto;
  134.         HDSA                _dsaCookies;
  135.         IUnknown*           _punkParent;
  136.         friend class CWebViewFolderContents;
  137.     };
  138.     friend class CConnectionPointForwarder;
  139.     CConnectionPointForwarder m_cpEvents;
  140.     IDefViewFrame2 *    _pdvf2;   // defview
  141.     BOOL                _fClientEdge;
  142.     BOOL                _fTabRecieved;
  143.     BOOL                _fCalledAutoArrange;
  144.     HWND                _hwndLV;
  145.     HWND                _hwndLVParent;
  146.     ITypeInfo *         _pClassTypeInfo; // ITypeInfo of class
  147.     // stuff added to delegate all of our work up to DefViews automation
  148.     IShellFolderViewDual *_pdispAuto;
  149. };
  150. LCID g_lcidLocaleUnicpp = MAKELCID(LANG_USER_DEFAULT, SORT_DEFAULT);
  151. // Helper function that can be used here and in main shell folder view window to get the
  152. // current view options...
  153. DWORD GetViewOptionsForDispatch()
  154. {
  155.     SHELLSTATE ss = {0};
  156.     DWORD dwSetting = 0;
  157.     // Get the view options to return...
  158.     SHGetSetSettings(&ss, 
  159.         SSF_SHOWALLOBJECTS|SSF_SHOWEXTENSIONS|SSF_SHOWCOMPCOLOR|
  160.             SSF_SHOWSYSFILES|SSF_DOUBLECLICKINWEBVIEW|SSF_DESKTOPHTML|SSF_WIN95CLASSIC,
  161.         FALSE);
  162.     // Aarg: mnuch the Bool:1 fields into a dword...
  163.     if (ss.fShowAllObjects) dwSetting |= SFVVO_SHOWALLOBJECTS;
  164.     if (ss.fShowExtensions) dwSetting |= SFVVO_SHOWEXTENSIONS;
  165.     if (ss.fShowCompColor) dwSetting |= SFVVO_SHOWCOMPCOLOR;
  166.     if (ss.fShowSysFiles) dwSetting |= SFVVO_SHOWSYSFILES;
  167.     if (ss.fDoubleClickInWebView) dwSetting |= SFVVO_DOUBLECLICKINWEBVIEW;
  168.     if (ss.fDesktopHTML) dwSetting |= SFVVO_DESKTOPHTML;
  169.     if (ss.fWin95Classic) dwSetting |= SFVVO_WIN95CLASSIC;
  170.     
  171.     return dwSetting;
  172. }
  173. CWebViewFolderContents::CWebViewFolderContents()
  174. {
  175.     DllAddRef();
  176.     // This allocator should have zero inited the memory, so assert the member variables are empty.
  177.     ASSERT(!_pdvf2);
  178.     ASSERT(!_hwndLV);
  179.     ASSERT(!_hwndLVParent);
  180.     ASSERT(!_fClientEdge);
  181.     ASSERT(!_fTabRecieved);
  182.     ASSERT(!_pClassTypeInfo);
  183.     ASSERT(!m_cpEvents._dsaCookies);
  184.     ASSERT(!_fCalledAutoArrange);
  185.     
  186.     m_bWindowOnly = TRUE;
  187.     m_bEnabled = TRUE;
  188.     m_bResizeNatural = TRUE;
  189.     m_cpEvents._punkParent = SAFECAST(this, IWebViewOCWinMan *);
  190.     GetWndClassInfo().m_wc.style &= ~(CS_HREDRAW|CS_VREDRAW);
  191. }
  192. CWebViewFolderContents::~CWebViewFolderContents()
  193. {
  194.     _UnadviseAll();
  195.     ASSERT(NULL == _pdvf2);
  196.     ASSERT(NULL == _hwndLV);
  197.     if (_pClassTypeInfo)
  198.         _pClassTypeInfo->Release();
  199.     ATOMICRELEASE(_pdvf2);
  200.     _ReleaseAutomationForwarders();
  201.     DllRelease();
  202. }
  203. // ATL maintainence functions
  204. LRESULT CWebViewFolderContents::_OnMessageForwarder(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled)
  205. {
  206.     if (_hwndLVParent)
  207.     {
  208.         bHandled = TRUE;
  209.         HWND hwnd = NULL;
  210.         // Forward these messages directly to DefView (don't let MSHTML eat them)
  211.         return ::SendMessage(_hwndLVParent, uMsg, wParam, lParam);
  212.     }
  213.     else
  214.         return 0;
  215. }
  216. LRESULT CWebViewFolderContents::_OnEraseBkgndMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled)
  217. {
  218.     // This function will just tell the default handler not to do anything and we
  219.     // will handle it.
  220.     // This is done in the case of WM_ERASEBKGND to...
  221.     // Avoid flicker by not erasing the background. This OC doesn't care
  222.     // about design-time issues - just usage on a Web View page.
  223.     bHandled = TRUE;
  224.     return 1;
  225. }
  226. LRESULT CWebViewFolderContents::_OnSizeMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled)
  227. {
  228.     // Now resize the DefView ListView window because ATL isn't very reliable at it.
  229.     if (_hwndLV)
  230.     {
  231.         // During re-parenting of _hwndLV by Trident, the size of the OC is not known to Trident.
  232.         // So, initially we get this message with 1 and 1 for the width and height, from it.
  233.         // And once Trident knows it's correct dimensions, we again get this message with the proper dim.
  234.         // We get a performance gain by not passing the first no-sense 1 x 1 dimension to _hwndLV.
  235.         //
  236.         if (m_rcPos.right - m_rcPos.left != 1 || m_rcPos.bottom - m_rcPos.top != 1)
  237.         {
  238.             ::SetWindowPos(_hwndLV, 0, 0, 0, m_rcPos.right - m_rcPos.left, m_rcPos.bottom - m_rcPos.top, SWP_NOZORDER);
  239.         }
  240.     }
  241.     bHandled = FALSE;
  242.     return 0;
  243. }
  244. HRESULT CWebViewFolderContents::DoVerbUIActivate(LPCRECT prcPosRect, HWND hwndParent)
  245. {
  246.     HRESULT hr = IOleObjectImpl<CWebViewFolderContents>::DoVerbUIActivate(prcPosRect, hwndParent);
  247.     if (SUCCEEDED(hr))
  248.     {
  249.         hr = _OnInPlaceActivate();
  250.     }
  251.     if (_hwndLV)
  252.     {
  253.         ::SetFocus(_hwndLV);
  254.     }
  255.     return hr;
  256. }
  257. // move from de-active to in-place-active
  258. HRESULT CWebViewFolderContents::_OnInPlaceActivate(void)
  259. {
  260.     HRESULT hr = S_OK;
  261.     if (_pdvf2 == NULL)
  262.     {
  263.         hr = IUnknown_QueryService(m_spClientSite, SID_DefView, IID_IDefViewFrame2, (void **)&_pdvf2);
  264.         if (EVAL(SUCCEEDED(hr)))
  265.         {
  266.             hr = _pdvf2->GetWindowLV2(&_hwndLV, SAFECAST(this, IWebViewOCWinMan *));
  267.             if (SUCCEEDED(hr))
  268.             {
  269.                 _ShowWindowLV(_hwndLV); // we got it -- show the listview
  270.             }
  271.         }
  272.     }
  273.     return hr;
  274. }
  275. HRESULT CWebViewFolderContents::DoVerbInPlaceActivate(LPCRECT prcPosRect, HWND hwndParent)
  276. {
  277.     HRESULT hr = IOleObjectImpl<CWebViewFolderContents>::DoVerbInPlaceActivate(prcPosRect, hwndParent);
  278.     if (EVAL(SUCCEEDED(hr)))
  279.     {
  280.         hr = _OnInPlaceActivate();
  281.     }
  282.     return hr;
  283. }
  284. HRESULT CWebViewFolderContents::InPlaceDeactivate(void)
  285. {
  286.     _ReleaseWindow();
  287.     ATOMICRELEASE(_pdvf2);
  288.     return IOleInPlaceObject_InPlaceDeactivate();
  289. }
  290. HRESULT CWebViewFolderContents::SetObjectRects(LPCRECT prcPosRect, LPCRECT prcClipRect)
  291. {
  292. //  WARNING: Do NOT move the EqualRect() comparison to after the
  293. //  IOleInPlaceObject_SetObjectRects declaration. The EqualRect()
  294. //  will always return an equal result then.
  295.     bool    bPositionRectDifferent = (EqualRect(&m_rcPos, prcPosRect) == 0);
  296.     HRESULT hres = IOleInPlaceObject_SetObjectRects(prcPosRect, prcClipRect);
  297. //  99/02/23 #294278 vtan: Trident did not call this routine when
  298. //  marquee selecting but it now does. The jumpy scrolling now
  299. //  manifests. Check that posRect has not changed before making
  300. //  any scroll position adjustments.
  301.     if (_hwndLV && _pdvf2 && (!_fCalledAutoArrange || bPositionRectDifferent))
  302.     {
  303.         _pdvf2->AutoAutoArrange(0);
  304.         _fCalledAutoArrange = TRUE;
  305.     }
  306.     return hres;
  307. }
  308. // *** IOleInPlaceActiveObject ***
  309. HRESULT CWebViewFolderContents::TranslateAccelerator(LPMSG pMsg)
  310. {
  311.     HRESULT hres = S_OK;
  312.     if (!_fTabRecieved)
  313.     {
  314.         hres = IOleInPlaceActiveObjectImpl<CWebViewFolderContents>::TranslateAccelerator(pMsg);
  315.         // If we did not handle this and if it is a tab (and we are not getting it in a cycle), forward it to trident, if present.
  316.         if (hres != S_OK && pMsg && (pMsg->wParam == VK_TAB || pMsg->wParam == VK_F6) && m_spClientSite)
  317.         {
  318.             IOleControlSite* pocs = NULL;
  319.             if (SUCCEEDED(m_spClientSite->QueryInterface(IID_IOleControlSite, (void **)&pocs)))
  320.             {
  321.                 DWORD grfModifiers = 0;
  322.                 if (GetKeyState(VK_SHIFT) & 0x8000)
  323.                 {
  324.                     grfModifiers |= 0x1;    //KEYMOD_SHIFT
  325.                 }
  326.                 if (GetKeyState(VK_CONTROL) & 0x8000)
  327.                 {
  328.                     grfModifiers |= 0x2;    //KEYMOD_CONTROL;
  329.                 }
  330.                 if (GetKeyState(VK_MENU) & 0x8000)
  331.                 {
  332.                     grfModifiers |= 0x4;    //KEYMOD_ALT;
  333.                 }
  334.                 _fTabRecieved = TRUE;
  335.                 hres = pocs->TranslateAccelerator(pMsg, grfModifiers);
  336.                 _fTabRecieved = FALSE;
  337.             }
  338.         }
  339.     }
  340.     return hres;
  341. }
  342. // *** IProvideClassInfo ***
  343. HRESULT CWebViewFolderContents::GetClassInfo(ITypeInfo ** ppTI)
  344. {
  345.     if (!_pClassTypeInfo) 
  346.         Shell32GetTypeInfo(LANGIDFROMLCID(g_lcidLocaleUnicpp), CLSID_WebViewFolderContents, &_pClassTypeInfo);
  347.     if (EVAL(_pClassTypeInfo))
  348.     {
  349.         _pClassTypeInfo->AddRef();
  350.         *ppTI = _pClassTypeInfo;
  351.         return S_OK;
  352.     }
  353.     *ppTI = NULL;
  354.     return E_FAIL;
  355. }
  356. HRESULT CWebViewFolderContents::GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** ppITypeInfo)
  357. {
  358.     HRESULT hr = S_OK;
  359.     *ppITypeInfo = NULL;
  360.     if (0 != itinfo)
  361.         return TYPE_E_ELEMENTNOTFOUND;
  362.     //Load a type lib if we don't have the information already.
  363.     if (NULL == *ppITypeInfo)
  364.     {
  365.         ITypeInfo * pITIDisp;
  366.         hr = Shell32GetTypeInfo(lcid, IID_IShellFolderViewDual, &pITIDisp);
  367.         if (SUCCEEDED(hr))
  368.         {
  369.             HRESULT hrT;
  370.             HREFTYPE hrefType;
  371.             // All our IDispatch implementations are DUAL. GetTypeInfoOfGuid
  372.             // returns the ITypeInfo of the IDispatch-part only. We need to
  373.             // find the ITypeInfo for the dual interface-part.
  374.             //
  375.             hrT = pITIDisp->GetRefTypeOfImplType(0xffffffff, &hrefType);
  376.             if (SUCCEEDED(hrT))
  377.                 hrT = pITIDisp->GetRefTypeInfo(hrefType, ppITypeInfo);
  378.             ASSERT(SUCCEEDED(hrT));
  379.             pITIDisp->Release();
  380.         }
  381.     }
  382.     return hr;
  383. }
  384. HRESULT CWebViewFolderContents::GetIDsOfNames(REFIID /*riid*/, LPOLESTR* rgszNames,
  385.     UINT cNames, LCID lcid, DISPID* rgdispid)
  386. {
  387.     ITypeInfo* pInfo;
  388.     HRESULT hr = GetTypeInfo(0, lcid, &pInfo);
  389.     if (pInfo != NULL)
  390.     {
  391.         hr = pInfo->GetIDsOfNames(rgszNames, cNames, rgdispid);
  392.         pInfo->Release();
  393.     }
  394.     TraceMsg(TF_DEFVIEW, "CWebViewFolderContents::GetIDsOfNames(DISPID=%ls, lcid=%d, cNames=%d) returned hr=%#08lx", *rgszNames, lcid, cNames, hr);
  395.     return hr;
  396. }
  397. HRESULT CWebViewFolderContents::Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS * pdispparams, VARIANT * pvarResult, EXCEPINFO * pexcepinfo, UINT * puArgErr)
  398. {
  399.     HRESULT hr = E_FAIL;
  400.     DISPPARAMS dispparams = {0};
  401.     if (!pdispparams)
  402.         pdispparams = &dispparams;  // otherwise OLE Fails when passed NULL.
  403.     if (dispidMember == DISPID_WINDOWOBJECT)
  404.     {
  405.         IDispatch * pdisp;
  406.         if (SUCCEEDED(get_Script(&pdisp)))
  407.         {
  408.             hr = pdisp->Invoke(dispidMember, riid, lcid, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr);
  409.             pdisp->Release();
  410.             return hr;
  411.         }
  412.         else
  413.             return DISP_E_MEMBERNOTFOUND;
  414.     }
  415.     // Make sure we are connected up to defviews automation.
  416.     hr = _SetupAutomationForwarders();
  417.     if (SUCCEEDED(hr))
  418.         hr = _pdispAuto->Invoke(dispidMember, riid, lcid, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr);
  419.     TraceMsg(TF_DEFVIEW, "CWebViewFolderContents::Invoke(DISPID=%#08lx, lcid=%d, wFlags=%d, pvarResult=%#08lx) returned hr=%#08lx", dispidMember, lcid, wFlags, pvarResult, hr);
  420.     return hr;
  421. }
  422. #define DW_MISC_STATUS (OLEMISC_SETCLIENTSITEFIRST | OLEMISC_ACTIVATEWHENVISIBLE | OLEMISC_CANTLINKINSIDE | OLEMISC_INSIDEOUT)
  423. HRESULT CWebViewFolderContents::GetMiscStatus(DWORD dwAspect, DWORD *pdwStatus)
  424. {
  425.     *pdwStatus = DW_MISC_STATUS;
  426.     return S_OK;
  427. }
  428.  
  429. // IWebViewOCWinMan
  430. HRESULT CWebViewFolderContents::SwapWindow(HWND hwndLV, IWebViewOCWinMan **ppocWinMan)
  431. {
  432.     *ppocWinMan = NULL;
  433.     _ReleaseWindow();
  434.     if (hwndLV)
  435.     {
  436.         _ShowWindowLV(hwndLV);
  437.         _InternalQueryInterface(IID_IWebViewOCWinMan, (void **)ppocWinMan);
  438.     }
  439.     return S_OK;
  440. }
  441. void CWebViewFolderContents::_ShowWindowLV(HWND hwndLV)
  442. {
  443.     if (!hwndLV)
  444.         return;
  445.     _hwndLV = hwndLV;
  446.     _hwndLVParent = ::GetParent(_hwndLV);
  447.     SHSetParentHwnd(_hwndLV, m_hWnd);
  448.     LONG lExStyle = ::GetWindowLong(_hwndLV, GWL_EXSTYLE);
  449.     _fClientEdge = lExStyle & WS_EX_CLIENTEDGE ? TRUE : FALSE;
  450.     if (_fClientEdge)
  451.     {
  452.         lExStyle &= ~WS_EX_CLIENTEDGE;
  453.         ::SetWindowLong(_hwndLV, GWL_EXSTYLE, lExStyle);
  454.     }
  455.     ::SetWindowPos(_hwndLV, 0, 0, 0, m_rcPos.right - m_rcPos.left
  456.                     , m_rcPos.bottom - m_rcPos.top
  457.                     , SWP_NOZORDER | SWP_SHOWWINDOW);
  458.     // BUGBUG kenwic 060399 #258594 We need to autoautoarrange the sfvext listview after we size it FIXED kenwic 060399
  459.     _pdvf2->AutoAutoArrange(0);
  460. }
  461. void CWebViewFolderContents::_ReleaseWindow()
  462. {
  463.     if (_hwndLV)
  464.     {
  465.         if (_fClientEdge)
  466.             SetWindowBits(_hwndLV, GWL_EXSTYLE, WS_EX_CLIENTEDGE, WS_EX_CLIENTEDGE);
  467.         ::ShowWindow(_hwndLV, SW_HIDE);       // HIDE IT SO IT doesn't flash before switching.
  468.         SHSetParentHwnd(_hwndLV, _hwndLVParent);
  469.         ::SetWindowPos(_hwndLV, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
  470.         _pdvf2->ReleaseWindowLV();
  471.         _hwndLV = NULL;
  472.     }
  473. }
  474. // *** IConnectionPointContainer ***
  475. HRESULT CWebViewFolderContents::EnumConnectionPoints(IEnumConnectionPoints **ppEnum)
  476. {
  477.     HRESULT hr = _SetupAutomationForwarders();
  478.     if (SUCCEEDED(hr))
  479.         hr = CreateInstance_IEnumConnectionPoints(ppEnum, 1, SAFECAST(&m_cpEvents, IConnectionPoint*));
  480.     return hr;
  481. }
  482. HRESULT CWebViewFolderContents::FindConnectionPoint(REFIID iid, IConnectionPoint **ppCP)
  483. {
  484.     *ppCP = NULL;
  485.     HRESULT hr = _SetupAutomationForwarders();
  486.     if (SUCCEEDED(hr))
  487.     {
  488.         if (IsEqualIID(iid, DIID_DShellFolderViewEvents) || IsEqualIID(iid, IID_IDispatch))
  489.         {
  490.             *ppCP = SAFECAST(&m_cpEvents, IConnectionPoint*);
  491.             (*ppCP)->AddRef();
  492.             hr = S_OK;
  493.         }
  494.         else
  495.         {
  496.             hr = E_NOINTERFACE;
  497.         }
  498.     }
  499.     return hr;
  500. }
  501. // *** IConnectionPoint ***
  502. //
  503. // Our IConnectionPoint is really implemented by defview's CFolder's connection point.
  504. // We just need to keep a count of outstanding references so we can force Unadvise
  505. // calls during "implicit unadvise during shutdown" cases like Trident.
  506. // (Is this really the spec?  It doesn't sound very robust...)
  507. //
  508. HRESULT CWebViewFolderContents::CConnectionPointForwarder::QueryInterface(REFIID riid, void **ppvObj)
  509. {
  510.     static const QITAB qit[] = {
  511.         QITABENT(CConnectionPointForwarder, IConnectionPoint),                  // IID_IConnectionPoint
  512.         { 0 }
  513.     };
  514.     return QISearch(this, qit, riid, ppvObj);
  515. }
  516. STDMETHODIMP_(ULONG) CWebViewFolderContents::CConnectionPointForwarder::AddRef(void)
  517. {
  518.     return _punkParent->AddRef();
  519. }
  520. STDMETHODIMP_(ULONG) CWebViewFolderContents::CConnectionPointForwarder::Release(void)
  521. {
  522.     return _punkParent->Release();
  523. }
  524.         
  525. HRESULT CWebViewFolderContents::CConnectionPointForwarder::GetConnectionInterface(IID * pIID)
  526. {
  527.     HRESULT hr = _pcpAuto->GetConnectionInterface(pIID);
  528.     if (SUCCEEDED(hr))
  529.     {
  530.         ASSERT(IsEqualIID(*pIID, DIID_DShellFolderViewEvents));
  531.     }
  532.     return hr;
  533. }
  534. HRESULT CWebViewFolderContents::CConnectionPointForwarder::GetConnectionPointContainer(IConnectionPointContainer ** ppCPC)
  535. {
  536.     return _punkParent->QueryInterface(IID_IConnectionPointContainer, (void**)ppCPC);
  537. }
  538. HRESULT CWebViewFolderContents::CConnectionPointForwarder::Advise(IUnknown * pUnkSink, DWORD * pdwCookie)
  539. {
  540.     if (!_dsaCookies)
  541.     {
  542.         _dsaCookies = DSA_Create(sizeof(*pdwCookie), 4);
  543.         if (!_dsaCookies)
  544.         {
  545.             *pdwCookie = 0;
  546.             return E_OUTOFMEMORY;
  547.         }
  548.     }
  549.     HRESULT hr = _pcpAuto->Advise(pUnkSink, pdwCookie);
  550.     if (SUCCEEDED(hr))
  551.     {
  552.         if (-1 == DSA_AppendItem(_dsaCookies, pdwCookie))
  553.         {
  554.             _pcpAuto->Unadvise(*pdwCookie);
  555.             *pdwCookie = 0;
  556.             hr = E_OUTOFMEMORY;
  557.         }
  558.     }
  559.     return hr;
  560. }
  561. HRESULT CWebViewFolderContents::CConnectionPointForwarder::Unadvise(DWORD dwCookie)
  562. {
  563.     int i = 0;
  564.     DWORD dw;
  565.     if (_dsaCookies)
  566.     {
  567.         while (DSA_GetItem(_dsaCookies, i++, &dw))
  568.         {
  569.             if (dw == dwCookie)
  570.             {
  571.                 DSA_DeleteItem(_dsaCookies, --i);
  572.                 return _pcpAuto->Unadvise(dwCookie);
  573.             }
  574.         }
  575.     }
  576.     // BUGBUG: we should probably shassert here
  577.     return E_FAIL;
  578. }
  579. void CWebViewFolderContents::_UnadviseAll()
  580. {
  581.     if (m_cpEvents._dsaCookies)
  582.     {
  583.         if (m_cpEvents._pcpAuto)
  584.         {
  585.             DWORD dw;
  586.             for (int i = 0; DSA_GetItem(m_cpEvents._dsaCookies, i, &dw); i++)
  587.             {
  588.                 m_cpEvents._pcpAuto->Unadvise(dw);
  589.             }
  590.         }
  591.         DSA_Destroy(m_cpEvents._dsaCookies);
  592.         m_cpEvents._dsaCookies = NULL;
  593.     }
  594. }
  595. HRESULT CWebViewFolderContents::Close(DWORD dwSaveOption)
  596. {
  597.     _UnadviseAll();
  598.     HRESULT hr = IOleObjectImpl<CWebViewFolderContents>::Close(dwSaveOption);
  599.     _ReleaseAutomationForwarders();
  600.     return hr;
  601. }
  602. HRESULT CWebViewFolderContents::_SetupAutomationForwarders(void)
  603. {
  604.     HRESULT hr = S_OK;
  605.     if (!m_cpEvents._pcpAuto)
  606.     {
  607.         IShellView *psv;
  608.         hr = IUnknown_QueryService(m_spClientSite, SID_DefView, IID_IShellView, (void **)&psv);
  609.         if (SUCCEEDED(hr))
  610.         {
  611.             IUnknown *punk;
  612.             hr = psv->GetItemObject(SVGIO_BACKGROUND, IID_IDispatch, (void**)&punk);
  613.             if (SUCCEEDED(hr))
  614.             {
  615.                 hr = punk->QueryInterface(IID_IShellFolderViewDual, (void**)&_pdispAuto);
  616.                 if (SUCCEEDED(hr))
  617.                 {
  618.                     if (SUCCEEDED(MakeSafeForScripting((IUnknown**)&_pdispAuto)))
  619.                     {
  620.                         IUnknown_SetSite(_pdispAuto, m_spClientSite);
  621.                         // Need to get the right interfaces
  622.                         IConnectionPointContainer* pcpcAuto;
  623.                         hr = _pdispAuto->QueryInterface(IID_IConnectionPointContainer, (void**)&pcpcAuto);
  624.                         if (SUCCEEDED(hr))
  625.                         {
  626.                             hr = pcpcAuto->FindConnectionPoint(IID_IDispatch, &m_cpEvents._pcpAuto);
  627.                             pcpcAuto->Release();
  628.                         }
  629.                         if (FAILED(hr))
  630.                         {
  631.                             IUnknown_SetSite(_pdispAuto, NULL);
  632.                             ATOMICRELEASE(_pdispAuto);
  633.                         }
  634.                     }
  635.                 }
  636.                 punk->Release();
  637.             }
  638.             psv->Release();
  639.         }
  640.     }
  641.     return hr;
  642. }
  643. HRESULT CWebViewFolderContents::_ReleaseAutomationForwarders(void)
  644. {
  645.     ATOMICRELEASE(m_cpEvents._pcpAuto);
  646.     if (_pdispAuto)
  647.         IUnknown_SetSite(_pdispAuto, NULL);
  648.     ATOMICRELEASE(_pdispAuto);
  649.     return S_OK;
  650. }
  651. // IShellFolderViewDual
  652. // We will let the folder object get created and have it maintain that we only have one
  653. // application object (with the site) set properly...
  654. HRESULT CWebViewFolderContents::get_Application(IDispatch **ppid)
  655. {
  656.     *ppid = NULL;
  657.     HRESULT hr = _SetupAutomationForwarders();
  658.     if (SUCCEEDED(hr))
  659.         hr = _pdispAuto->get_Application(ppid);
  660.     return hr;
  661. }
  662. HRESULT CWebViewFolderContents::get_Parent(IDispatch **ppid)
  663. {
  664.     *ppid = NULL;
  665.     HRESULT hr = _SetupAutomationForwarders();
  666.     if (SUCCEEDED(hr))
  667.         hr = _pdispAuto->get_Parent(ppid);
  668.     return hr;
  669. }
  670. HRESULT CWebViewFolderContents::get_Folder(Folder **ppid)
  671. {
  672.     *ppid = NULL;
  673.     HRESULT hr = _SetupAutomationForwarders();
  674.     if (SUCCEEDED(hr))
  675.         hr = _pdispAuto->get_Folder(ppid);
  676.     return hr;
  677. }
  678. HRESULT CWebViewFolderContents::SelectedItems(FolderItems **ppid)
  679. {
  680.     // We need to talk to the actual window under us
  681.     *ppid = NULL;
  682.     HRESULT hr = _SetupAutomationForwarders();
  683.     if (SUCCEEDED(hr))
  684.         hr = _pdispAuto->SelectedItems(ppid);
  685.     return hr;
  686. }
  687. HRESULT CWebViewFolderContents::get_FocusedItem(FolderItem **ppid)
  688. {
  689.     *ppid = NULL;
  690.     HRESULT hr = _SetupAutomationForwarders();
  691.     if (SUCCEEDED(hr))
  692.         hr = _pdispAuto->get_FocusedItem(ppid);
  693.     return hr;
  694. }
  695. HRESULT CWebViewFolderContents::SelectItem(VARIANT *pvfi, int dwFlags)
  696. {
  697.     HRESULT hr = _SetupAutomationForwarders();
  698.     if (SUCCEEDED(hr))
  699.         hr = _pdispAuto->SelectItem(pvfi, dwFlags);
  700.     return hr;
  701. }
  702. HRESULT CWebViewFolderContents::PopupItemMenu(FolderItem *pfi, VARIANT vx, VARIANT vy, BSTR * pbs)
  703. {
  704.     HRESULT hr = _SetupAutomationForwarders();
  705.     if (SUCCEEDED(hr))
  706.         hr = _pdispAuto->PopupItemMenu(pfi, vx, vy, pbs);
  707.     return hr;
  708. }
  709. HRESULT CWebViewFolderContents::get_Script(IDispatch **ppid)
  710. {
  711.     *ppid = NULL;
  712.     HRESULT hr = _SetupAutomationForwarders();
  713.     if (SUCCEEDED(hr))
  714.         hr = _pdispAuto->get_Script(ppid);
  715.     return hr;
  716. }
  717. HRESULT CWebViewFolderContents::get_ViewOptions(long *plSetting)
  718. {
  719.     HRESULT hr = _SetupAutomationForwarders();
  720.     if (SUCCEEDED(hr))
  721.         hr = _pdispAuto->get_ViewOptions(plSetting);
  722.     return hr;
  723. }
  724. STDAPI CWebViewFolderContents_CreateInstance(IUnknown *punkOuter, REFIID riid, void **ppvOut)
  725. {
  726.     return CComCreator< CComPolyObject< CWebViewFolderContents > >::CreateInstance((void *) punkOuter, riid, ppvOut);
  727. }