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

Windows Kernel

Development Platform:

Visual C++

  1. #include "stdafx.h"
  2. #pragma hdrstop
  3. #include "dvoc.h"
  4. LCID g_lcidLocaleUnicpp = MAKELCID(LANG_USER_DEFAULT, SORT_DEFAULT);
  5. // Helper function that can be used here and in main shell folder view window to get the
  6. // current view options...
  7. DWORD GetViewOptionsForDispatch()
  8. {
  9.     SHELLSTATE ss = {0};
  10.     DWORD dwSetting = 0;
  11.     // Get the view options to return...
  12.     SHGetSetSettings(&ss, 
  13.         SSF_SHOWALLOBJECTS|SSF_SHOWEXTENSIONS|SSF_SHOWCOMPCOLOR|
  14.             SSF_SHOWSYSFILES|SSF_DOUBLECLICKINWEBVIEW|SSF_DESKTOPHTML|SSF_WIN95CLASSIC,
  15.         FALSE);
  16.     // Aarg: mnuch the Bool:1 fields into a dword...
  17.     if (ss.fShowAllObjects) dwSetting |= SFVVO_SHOWALLOBJECTS;
  18.     if (ss.fShowExtensions) dwSetting |= SFVVO_SHOWEXTENSIONS;
  19.     if (ss.fShowCompColor) dwSetting |= SFVVO_SHOWCOMPCOLOR;
  20.     if (ss.fShowSysFiles) dwSetting |= SFVVO_SHOWSYSFILES;
  21.     if (ss.fDoubleClickInWebView) dwSetting |= SFVVO_DOUBLECLICKINWEBVIEW;
  22.     if (ss.fDesktopHTML) dwSetting |= SFVVO_DESKTOPHTML;
  23.     if (ss.fWin95Classic) dwSetting |= SFVVO_WIN95CLASSIC;
  24.     
  25.     return dwSetting;
  26. }
  27. CWebViewFolderContents::CWebViewFolderContents() : _psdf(NULL), _psfv(NULL)
  28. {
  29.     DllAddRef();
  30.     // This allocator should have zero inited the memory, so assert the member variables are empty.
  31.     ASSERT(!_pdvf);
  32.     ASSERT(!_pdvf2);
  33.     ASSERT(!_psfv);
  34.     ASSERT(!_hwndLV);
  35.     ASSERT(!_hwndLVParent);
  36.     ASSERT(!_fSetDefViewAutomationObject);
  37.     ASSERT(!_fClientEdge);
  38.     ASSERT(!_pClassTypeInfo);
  39.     ASSERT(!_psdf);
  40.     ASSERT(!_dwAdviseCount);
  41.     ASSERT(!_fReArrangeListView);
  42.     ASSERT(!_dsaCookies);
  43.     m_bWindowOnly = TRUE;
  44.     m_bEnabled = TRUE;
  45.     m_bRecomposeOnResize = TRUE;
  46.     m_bResizeNatural = TRUE;
  47. }
  48. CWebViewFolderContents::~CWebViewFolderContents()
  49. {
  50.     UnadviseAll();
  51.     ASSERT(NULL==_pdvf);
  52.     ASSERT(NULL==_pdvf2);
  53.     ASSERT(NULL==_psfv);
  54.     ASSERT(NULL==_hwndLV);
  55.     if (_pClassTypeInfo)
  56.         _pClassTypeInfo->Release();
  57.     if (_psdf) {
  58.         _psdf->SetSite(NULL);
  59.         _psdf->Release();
  60.     }
  61.     ATOMICRELEASE(_pdvf);
  62.     ATOMICRELEASE(_pdvf2);
  63.     ATOMICRELEASE(_psfv);
  64.     // m_pdisp doesn't have a ref so it's OK if it's not NULL.
  65.     if (_pmyiecp)
  66.         delete _pmyiecp;
  67.     DllRelease();
  68. }
  69. // ATL maintainence functions
  70. LRESULT CWebViewFolderContents::_OnMessageForwarder(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled)
  71. {
  72.     if (_hwndLVParent)
  73.     {
  74.         bHandled = TRUE;
  75.         HWND hwnd = NULL;
  76.         // Forward these messages directly to DefView (don't let MSHTML eat them)
  77.         return ::SendMessage(_hwndLVParent, uMsg, wParam, lParam);
  78.     }
  79.     else
  80.         return 0;
  81. }
  82. LRESULT CWebViewFolderContents::_OnEraseBkgndMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled)
  83. {
  84.     // This function will just tell the default handler not to do anything and we
  85.     // will handle it.
  86.     // This is done in the case of WM_ERASEBKGND to...
  87.     // Avoid flicker by not erasing the background. This OC doesn't care
  88.     // about design-time issues - just usage on a Web View page.
  89.     bHandled = TRUE;
  90.     return 1;
  91. }
  92. LRESULT CWebViewFolderContents::_OnSizeMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled)
  93. {
  94.     // Now resize the DefView ListView window because ATL isn't very reliable at it.
  95.     if (_hwndLV)
  96.     {
  97.         ::SetWindowPos(_hwndLV, 0, 0, 0, m_rcPos.right - m_rcPos.left, m_rcPos.bottom - m_rcPos.top, SWP_NOZORDER);
  98.         // We need to force a rearrange on IE401SHELL32 when the proper
  99.         // size is set.  This is a timing dependent hack, but it works right now.
  100.         if (_fReArrangeListView)
  101.         {
  102.             ListView_Arrange(_hwndLV, LVA_DEFAULT);
  103.             _fReArrangeListView = FALSE;
  104.         }
  105.     }
  106.     bHandled = FALSE;
  107.     return 0;
  108. }
  109. LRESULT CWebViewFolderContents::_OnReArrangeListView(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled)
  110. {
  111.     _fReArrangeListView = TRUE;
  112.     bHandled = TRUE;
  113.     return 1;
  114. }
  115. HRESULT CWebViewFolderContents::DoVerbUIActivate(LPCRECT prcPosRect, HWND hwndParent)
  116. {
  117.     HRESULT hr = IOleObjectImpl<CWebViewFolderContents>::DoVerbUIActivate(prcPosRect, hwndParent);
  118.     
  119.     if (SUCCEEDED(hr))
  120.     {
  121.         hr = _OnInPlaceActivate();
  122.     }
  123.     if (_hwndLV)
  124.     {
  125.         ::SetFocus(_hwndLV);
  126.     }
  127.     return hr;
  128. }
  129. void CWebViewFolderContents::UnadviseAll()
  130. {
  131.     if (_dsaCookies)
  132.     {
  133.         DWORD dw;
  134.         for (int i = 0; DSA_GetItem(_dsaCookies, i, &dw); i++)
  135.         {
  136.             Unadvise(dw);
  137.         }
  138.         DSA_Destroy(_dsaCookies);
  139.         _dsaCookies = NULL;
  140.     }
  141. }
  142.     
  143. HRESULT CWebViewFolderContents::Close(DWORD dwSaveOption)
  144. {
  145.     UnadviseAll();
  146.     ATOMICRELEASE(_psfv);
  147.     HRESULT hr = IOleObjectImpl<CWebViewFolderContents>::Close(dwSaveOption);
  148.     return hr;
  149. }
  150. // move from de-active to in-place-active
  151. HRESULT CWebViewFolderContents::_OnInPlaceActivate(void)
  152. {
  153.     HRESULT hr = S_OK;
  154.     if (_pdvf == NULL)
  155.     {
  156.         hr = IUnknown_QueryService(m_spClientSite, SID_DefView, IID_IDefViewFrame, (void **)&_pdvf);
  157.         if (EVAL(SUCCEEDED(hr)))
  158.         {
  159.             // Use the IDefViewFrame2 if we can get one; else fall back on IDefViewFrame.
  160.             if (_pdvf2 == NULL)
  161.             {
  162.                 hr = _pdvf->QueryInterface(IID_IDefViewFrame2, (LPVOID *)&_pdvf2);
  163.             }
  164.             if (_pdvf2 ? EVAL(SUCCEEDED(hr = _pdvf2->GetWindowLV2(&_hwndLV, SAFECAST(this, IWebViewOCWinMan *))))
  165.                        : EVAL(SUCCEEDED(hr = _pdvf ->GetWindowLV (&_hwndLV))))
  166.             {
  167.                 // we got it -- show the listview
  168.                 //
  169.                 _ShowWindowLV(_hwndLV);
  170.                 
  171.                 // IE 401 shell32 posts itself a message during GetWindowLV and it assumes
  172.                 // the last SetObjectRects call will occur before that message gets processed
  173.                 // This is a timing issue and is no longer the case.  Mimick what shell32
  174.                 // does so we can do the rearrange when the correct SetObjectRects comes through
  175.                 ::PostMessage(m_hWnd, WM_DVOC_REARRANGELISTVIEW, 0, 0);
  176.            }
  177.         }
  178.     }
  179.     return hr;
  180. }
  181. HRESULT CWebViewFolderContents::DoVerbInPlaceActivate(LPCRECT prcPosRect, HWND hwndParent)
  182. {
  183.     HRESULT hr = IOleObjectImpl<CWebViewFolderContents>::DoVerbInPlaceActivate(prcPosRect, hwndParent);
  184.     if (EVAL(SUCCEEDED(hr)))
  185.     {
  186.         hr = _OnInPlaceActivate();
  187.     }
  188.     return hr;
  189. }
  190. HRESULT CWebViewFolderContents::InPlaceDeactivate(void)
  191. {
  192.     _ReleaseWindow();
  193.     ATOMICRELEASE(_pdvf);
  194.     ATOMICRELEASE(_pdvf2);
  195.     _ClearAutomationObject();
  196.     ATOMICRELEASE(_psfv);
  197.     
  198.     return IOleInPlaceObject_InPlaceDeactivate();
  199. }
  200. HRESULT CWebViewFolderContents::SetObjectRects(LPCRECT lprcPosRect, LPCRECT lprcClipRect)
  201. {
  202.     HRESULT hres = IOleInPlaceObject_SetObjectRects(lprcPosRect, lprcClipRect);
  203.     if (_hwndLV && _pdvf2)
  204.     {
  205.         _pdvf2->AutoAutoArrange(0);
  206.     }
  207.     return hres;
  208. }
  209. // *** IOleInPlaceActiveObject ***
  210. HRESULT CWebViewFolderContents::TranslateAccelerator(LPMSG pMsg)
  211. {
  212.     HRESULT hres = S_OK;
  213.     if (!_fTabRecieved)
  214.     {
  215.         hres = IOleInPlaceActiveObjectImpl<CWebViewFolderContents>::TranslateAccelerator(pMsg);
  216.         // 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.
  217.         if (hres != S_OK && pMsg && (pMsg->wParam == VK_TAB || pMsg->wParam == VK_F6) && m_spClientSite)
  218.         {
  219.             IOleControlSite* pocs = NULL;
  220.             if (SUCCEEDED(m_spClientSite->QueryInterface(IID_IOleControlSite, (void **)&pocs)))
  221.             {
  222.                 DWORD grfModifiers = 0;
  223.                 if (GetKeyState(VK_SHIFT) & 0x8000)
  224.                 {
  225.                     grfModifiers |= 0x1;    //KEYMOD_SHIFT
  226.                 }
  227.                 if (GetKeyState(VK_CONTROL) & 0x8000)
  228.                 {
  229.                     grfModifiers |= 0x2;    //KEYMOD_CONTROL;
  230.                 }
  231.                 if (GetKeyState(VK_MENU) & 0x8000)
  232.                 {
  233.                     grfModifiers |= 0x4;    //KEYMOD_ALT;
  234.                 }
  235.                 _fTabRecieved = TRUE;
  236.                 hres = pocs->TranslateAccelerator(pMsg, grfModifiers);
  237.                 _fTabRecieved = FALSE;
  238.             }
  239.         }
  240.     }
  241.     return hres;
  242. }
  243. // *** IProvideClassInfo ***
  244. HRESULT CWebViewFolderContents::GetClassInfo(ITypeInfo ** ppTI)
  245. {
  246.     if (!_pClassTypeInfo) 
  247.         Shell32GetTypeInfo(LANGIDFROMLCID(g_lcidLocaleUnicpp), CLSID_WebViewFolderContents, &_pClassTypeInfo);
  248.     if (EVAL(_pClassTypeInfo))
  249.     {
  250.         _pClassTypeInfo->AddRef();
  251.         *ppTI = _pClassTypeInfo;
  252.         return S_OK;
  253.     }
  254.     *ppTI = NULL;
  255.     return E_FAIL;
  256. }
  257. // *** IDispatch ***
  258. HRESULT CWebViewFolderContents::GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** ppITypeInfo)
  259. {
  260.     HRESULT hr = S_OK;
  261.     *ppITypeInfo = NULL;
  262.     if (0 != itinfo)
  263.         return(TYPE_E_ELEMENTNOTFOUND);
  264.     /*
  265. #if 1
  266.     // docs say we can ignore lcid if we support only one LCID
  267.     // we don't have to return DISP_E_UNKNOWNLCID if we're *ignoring* it
  268.     ppITI = &m_pInfo;
  269. #else
  270.     //
  271.     // Since we returned one from GetTypeInfoCount, this function
  272.     // can be called for a specific locale.  We support English
  273.     // and neutral (defaults to English) locales.  Anything
  274.     // else is an error.
  275.     //
  276.     // After this switch statement, ppITI will point to the proper
  277.     // member pITypeInfo. If *ppITI is NULL, we know we need to
  278.     // load type information, retrieve the ITypeInfo we want, and
  279.     // then store it in *ppITI.
  280.     //
  281.     switch (PRIMARYLANGID(lcid))
  282.     {
  283.     case LANG_NEUTRAL:
  284.     case LANG_ENGLISH:
  285.         ppITI=&m_pInfo;
  286.         break;
  287.     default:
  288.         return(DISP_E_UNKNOWNLCID);
  289.     }
  290. #endif
  291. */
  292.     //Load a type lib if we don't have the information already.
  293.     if (NULL == *ppITypeInfo)
  294.     {
  295.         ITypeInfo * pITIDisp;
  296.         hr = Shell32GetTypeInfo(lcid, IID_IShellFolderViewDual, &pITIDisp);
  297.         if (SUCCEEDED(hr))
  298.         {
  299.             HRESULT hrT;
  300.             HREFTYPE hrefType;
  301.             // All our IDispatch implementations are DUAL. GetTypeInfoOfGuid
  302.             // returns the ITypeInfo of the IDispatch-part only. We need to
  303.             // find the ITypeInfo for the dual interface-part.
  304.             //
  305.             hrT = pITIDisp->GetRefTypeOfImplType(0xffffffff, &hrefType);
  306.             if (SUCCEEDED(hrT))
  307.                 hrT = pITIDisp->GetRefTypeInfo(hrefType, ppITypeInfo);
  308.             ASSERT(SUCCEEDED(hrT));
  309.             pITIDisp->Release();
  310.         }
  311.     }
  312.     return hr;
  313. }
  314. HRESULT CWebViewFolderContents::GetIDsOfNames(REFIID /*riid*/, LPOLESTR* rgszNames,
  315.     UINT cNames, LCID lcid, DISPID* rgdispid)
  316. {
  317.     ITypeInfo* pInfo;
  318.     HRESULT hr = GetTypeInfo(0, lcid, &pInfo);
  319.     if (pInfo != NULL)
  320.     {
  321.         hr = pInfo->GetIDsOfNames(rgszNames, cNames, rgdispid);
  322.         pInfo->Release();
  323.     }
  324.     TraceMsg(TF_DEFVIEW, "CWebViewFolderContents::GetIDsOfNames(DISPID=%ls, lcid=%d, cNames=%d) returned hr=%#08lx", *rgszNames, lcid, cNames, hr);
  325.     return hr;
  326. }
  327. HRESULT CWebViewFolderContents::Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS * pdispparams, VARIANT * pvarResult, EXCEPINFO * pexcepinfo, UINT * puArgErr)
  328. {
  329.     HRESULT hr = E_FAIL;
  330.     IDispatch * pdisp;
  331.     DISPPARAMS dispparams = {0};
  332.     if (!pdispparams)
  333.         pdispparams = &dispparams;  // otherwise OLE Fails when passed NULL.
  334. #ifdef CROSS_FRAME_SECURITY
  335.     switch (dispidMember)
  336.     {
  337.     // this 
  338.     case DISPID_SECURITYCTX:
  339.         ASSERT(pvarResult);
  340.         V_VT(pvarResult) = VT_BSTR;
  341.         hr = _GetFolderSecurity(&V_BSTR(pvarResult));
  342.         break;
  343.     default:
  344. #endif
  345.     if (dispidMember == DISPID_WINDOWOBJECT)
  346.     {
  347.         if (SUCCEEDED(get_Script(&pdisp)))
  348.         {
  349.             hr = pdisp->Invoke(dispidMember, riid, lcid, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr);
  350.             pdisp->Release();
  351.             return hr;
  352.         }
  353.         else
  354.             return DISP_E_MEMBERNOTFOUND;
  355.     }
  356.     // make sure we have an interface to hand off to Invoke
  357.     if (NULL == m_pdisp)
  358.     {
  359.         hr = _InternalQueryInterface(IID_IShellFolderViewDual, (LPVOID*)&m_pdisp);
  360.         ASSERT(SUCCEEDED(hr));
  361.         // don't hold a refcount on ourself
  362.         m_pdisp->Release();
  363.     }
  364.     ITypeInfo * pITypeInfo;
  365.     hr = GetTypeInfo(0, lcid, &pITypeInfo);
  366.     if (EVAL(SUCCEEDED(hr)))
  367.     {
  368.         //Clear exceptions
  369.         SetErrorInfo(0L, NULL);
  370.         hr = pITypeInfo->Invoke(m_pdisp, dispidMember, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr);
  371.         pITypeInfo->Release();
  372.     }
  373.     TraceMsg(TF_DEFVIEW, "CWebViewFolderContents::Invoke(DISPID=%#08lx, lcid=%d, wFlags=%d, pvarResult=%#08lx) returned hr=%#08lx", dispidMember, lcid, wFlags, pvarResult, hr);
  374. #ifdef CROSS_FRAME_SECURITY
  375.     }
  376. #endif
  377.     return hr;
  378. }
  379. #define DW_MISC_STATUS (OLEMISC_SETCLIENTSITEFIRST|OLEMISC_ACTIVATEWHENVISIBLE|OLEMISC_RECOMPOSEONRESIZE|OLEMISC_CANTLINKINSIDE|OLEMISC_INSIDEOUT)
  380. HRESULT CWebViewFolderContents::GetMiscStatus(DWORD dwAspect, DWORD *pdwStatus)
  381. {
  382.     *pdwStatus = DW_MISC_STATUS;
  383.     return S_OK;
  384. }
  385. // IExpDispSupport
  386. HRESULT CWebViewFolderContents::FindCIE4ConnectionPoint(REFIID riid, CIE4ConnectionPoint **ppccp)
  387. {
  388.     HRESULT hr = E_FAIL;
  389.     if (!ppccp)
  390.         return E_INVALIDARG;
  391.     *ppccp = NULL;
  392.     if (IsEqualIID(DIID_DShellFolderViewEvents, riid))
  393.     {
  394.         if (!_pmyiecp)
  395.             _pmyiecp = new CMyIE4ConnectionPoint(SAFECAST(this, IExpDispSupport *));
  396.         if (EVAL(_pmyiecp))
  397.         {
  398.             // Don't give ref because _pmyiecp doesn't do refs, we
  399.             // are assuming we will out live the one caller.  That's
  400.             // okay because we assume with good reason that it will only be one specific
  401.             // caller.
  402.             *ppccp = _pmyiecp;
  403.             hr = S_OK;
  404.         }
  405.     }
  406.     return hr;
  407. }
  408.  
  409. // IOleInPlaceActiveObject
  410. HRESULT CWebViewFolderContents::SwapWindow(HWND hwndLV, IWebViewOCWinMan **pocWinMan)
  411. {
  412.     HRESULT hres = S_OK;
  413.     ASSERT(pocWinMan);
  414.     *pocWinMan = NULL;
  415.     _ReleaseWindow();
  416.     if (!hwndLV)
  417.         return hres;
  418.     _ShowWindowLV(hwndLV);
  419.     if (FAILED(_InternalQueryInterface(IID_IWebViewOCWinMan, (LPVOID*)pocWinMan)))   
  420.         hres = S_FALSE;
  421.     return hres;
  422. }
  423. void CWebViewFolderContents::_ShowWindowLV(HWND hwndLV)
  424. {
  425.     if (!hwndLV)
  426.         return;
  427.     _hwndLV = hwndLV;
  428.     _hwndLVParent = ::GetParent(_hwndLV);
  429.     SHSetParentHwnd(_hwndLV, m_hWnd);
  430.     LONG lExStyle = ::GetWindowLong(_hwndLV, GWL_EXSTYLE);
  431.     _fClientEdge = lExStyle & WS_EX_CLIENTEDGE ? TRUE : FALSE;
  432.     if (_fClientEdge)
  433.     {
  434.         lExStyle &= ~WS_EX_CLIENTEDGE;
  435.         ::SetWindowLong(_hwndLV, GWL_EXSTYLE, lExStyle);
  436.     }
  437.     lExStyle = ListView_GetExtendedListViewStyle(_hwndLV);
  438.     // Switch off infotips for webview
  439.     lExStyle &= ~LVS_EX_INFOTIP;
  440.     ListView_SetExtendedListViewStyle(_hwndLV, lExStyle);
  441.     ::SetWindowPos(_hwndLV, 0, 0, 0, m_rcPos.right - m_rcPos.left, m_rcPos.bottom - m_rcPos.top, SWP_NOZORDER);
  442.     _pdvf->QueryInterface(IID_IShellFolderView, (void **)&_psfv);
  443.     // Incase We have been advised before we got here...
  444.     if (_fSetDefViewAutomationObject)
  445.         _SetAutomationObject();
  446.     return;
  447. }
  448. void CWebViewFolderContents::_ReleaseWindow()
  449. {
  450.     if (_hwndLV)
  451.     {
  452.         HWND hwndFocusPrev = GetFocus();
  453.         if (_fClientEdge)
  454.             SetWindowBits(_hwndLV, GWL_EXSTYLE, WS_EX_CLIENTEDGE, WS_EX_CLIENTEDGE);
  455.         SHSetParentHwnd(_hwndLV, _hwndLVParent);
  456.         ::SetWindowPos(_hwndLV, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
  457.         if (hwndFocusPrev == _hwndLV)
  458.             ::SetFocus(_hwndLV);
  459.         _pdvf->ReleaseWindowLV();
  460.         _hwndLV = NULL;
  461.     }
  462.     return;
  463. }
  464. // *** IConnectionPoint ***
  465. HRESULT CWebViewFolderContents::Advise(IUnknown * pUnkSink, DWORD * pdwCookie)
  466. {
  467.     HRESULT hr = S_OK;
  468.     if (!_dsaCookies)
  469.     {
  470.         _dsaCookies = DSA_Create(sizeof(*pdwCookie), 4);
  471.         if (!_dsaCookies)
  472.         {
  473.             *pdwCookie = 0;
  474.             hr = E_OUTOFMEMORY;
  475.         }
  476.     }
  477.     hr = IConnectionPointImpl<CWebViewFolderContents, &DIID_DShellFolderViewEvents>::Advise(pUnkSink, pdwCookie);
  478.     _dwAdviseCount++;
  479.     _SetAutomationObject();
  480.     if (SUCCEEDED(hr))
  481.     {
  482.         if (-1 == DSA_AppendItem(_dsaCookies, pdwCookie))
  483.         {
  484.             IConnectionPointImpl<CWebViewFolderContents, &DIID_DShellFolderViewEvents>::Unadvise(*pdwCookie);
  485.             *pdwCookie = 0;
  486.             hr = E_OUTOFMEMORY;
  487.         }
  488.     }
  489.     return hr;
  490. }
  491. HRESULT CWebViewFolderContents::Unadvise(DWORD dwCookie)
  492. {
  493.     HRESULT hr = E_FAIL;
  494.     if (_dsaCookies)
  495.     {
  496.         int i = 0;
  497.         DWORD dw;
  498.         while (DSA_GetItem(_dsaCookies, i++, &dw))
  499.         {
  500.             if (dw == dwCookie)
  501.             {
  502.                 DSA_DeleteItem(_dsaCookies, --i);
  503.                 hr = IConnectionPointImpl<CWebViewFolderContents, &DIID_DShellFolderViewEvents>::Unadvise(dwCookie);
  504.                 _dwAdviseCount--;
  505.                 _ClearAutomationObject();
  506.                 break;
  507.             }
  508.         }
  509.     }
  510.     return hr;
  511. }
  512. HRESULT CWebViewFolderContents::_SetAutomationObject(void)
  513. {
  514.     HRESULT hr = S_OK;
  515.     if (1 == _dwAdviseCount)
  516.     {
  517.         if (_psfv)
  518.         {
  519.             // Let Defview know about us...
  520.             hr = _psfv->SetAutomationObject(SAFECAST(this, IDispatch*));
  521.         }
  522.         // Set the flag anyway so that we know to do it again later...
  523.         _fSetDefViewAutomationObject = TRUE;
  524.     }
  525.     return hr;
  526. }
  527. HRESULT CWebViewFolderContents::_ClearAutomationObject(void)
  528. {
  529.     HRESULT hr = S_OK;
  530.     if ((0 == _dwAdviseCount) && _fSetDefViewAutomationObject)
  531.     {
  532.         if (_psfv)
  533.             hr = _psfv->SetAutomationObject(NULL);
  534.         _fSetDefViewAutomationObject = FALSE;
  535.     }
  536.     return hr;
  537. }
  538. // IShellFolderViewDual
  539. HRESULT CWebViewFolderContents::get_Application(IDispatch **ppid)
  540. {
  541.     // We will let the folder object get created and have it maintain that we only have one
  542.     // application object (with the site) set properly...
  543.     HRESULT hr = _GetFolder();
  544.     if (SUCCEEDED(hr))
  545.         hr = _psdf->get_Application(ppid);
  546.     return hr;
  547. }
  548. HRESULT CWebViewFolderContents::get_Parent(IDispatch **ppid)
  549. {
  550.     *ppid = NULL;
  551.     ASSERT(0);  // Error returns from script cause bad dialogs
  552.     return E_FAIL;
  553. }
  554. HRESULT CWebViewFolderContents::_GetFolderIDList(LPITEMIDLIST *ppidl)
  555. {
  556.     *ppidl = NULL;
  557.     IShellFolder *psf;
  558.     if (SUCCEEDED(_pdvf->GetShellFolder(&psf)))
  559.     {
  560.         IPersistFolder2 *ppf;
  561.         if (SUCCEEDED(psf->QueryInterface(IID_IPersistFolder2, (void **)&ppf)))
  562.         {
  563.             ppf->GetCurFolder(ppidl);
  564.             ppf->Release();
  565.         }
  566.         psf->Release();
  567.     }
  568.     if (*ppidl == NULL)
  569.     {
  570.         LPITEMIDLIST pidl;
  571.         if (SUCCEEDED(_psfv->GetObject(&pidl, (UINT)-42)) && pidl)
  572.         {
  573.             *ppidl = ILClone(pidl);
  574.         }
  575.     }
  576.     ASSERT(*ppidl);  // Error returns from script cause bad dialogs
  577.     return *ppidl ? S_OK : E_FAIL;
  578. }
  579.     
  580. #ifdef CROSS_FRAME_SECURITY
  581. HRESULT CWebViewFolderContents::_GetFolderSecurity(BSTR *pbstr)
  582. {
  583.     *pbstr = NULL;
  584.     LPITEMIDLIST pidl;
  585.     HRESULT hres = _GetFolderIDList(&pidl);
  586.     if (SUCCEEDED(hres))
  587.     {
  588.         TCHAR szURL[MAX_URL_STRING];
  589.         if (SHGetPathFromIDList(pidl, szURL))
  590.         {
  591.             DWORD dwChar = ARRAYSIZE(szURL);
  592.             hres = UrlCreateFromPath(szURL, szURL, &dwChar, 0);    // in place!
  593.             if (SUCCEEDED(hres))
  594.             {
  595.                 *pbstr = TCharSysAllocString(szURL);
  596.                 hres = *pbstr ? S_OK : E_OUTOFMEMORY;
  597.             }
  598.         }
  599.         else
  600.             hres = E_FAIL;
  601.     }
  602.     ASSERT(SUCCEEDED(hres));  // Error returns from script cause bad dialogs
  603.     return hres;
  604. }
  605. #endif
  606. HRESULT CWebViewFolderContents::_GetFolder()
  607. {
  608.     HRESULT hres = E_FAIL;
  609.     if (_pdvf)
  610.     {
  611.         if (_psdf)
  612.             return NOERROR;
  613.         LPITEMIDLIST pidl;
  614.         if (EVAL(SUCCEEDED(_GetFolderIDList(&pidl))))
  615.         {
  616.             IShellFolder *psf = NULL;
  617.             // For objects that cheat and not have a unique pidl to folder mapping
  618.             _pdvf->GetShellFolder(&psf);
  619.             // We assume we need the parent window to the defview...
  620.             hres = CSDFolder_Create(::GetParent(_hwndLVParent), pidl, psf, &_psdf);
  621.             SAFERELEASE(psf);
  622.             if (SUCCEEDED(hres))
  623.             {
  624.                 _psdf->SetSite(m_spClientSite);
  625.                 hres = MakeSafeForScripting((IUnknown**)&_psdf);
  626.             }
  627.             ILFree(pidl);
  628.         }
  629.     }
  630.     ASSERT(SUCCEEDED(hres));  // Error returns from script cause bad dialogs
  631.     return hres;
  632. }
  633. HRESULT CWebViewFolderContents::get_Folder(Folder **ppid)
  634. {
  635.     HRESULT hres;
  636.     *ppid = NULL;
  637.     hres = _GetFolder();
  638.     if (SUCCEEDED(hres))
  639.         hres = _psdf->QueryInterface(IID_Folder, (void **)ppid);
  640.     ASSERT(SUCCEEDED(hres));  // Error returns from script cause bad dialogs
  641.     return hres;
  642. }
  643. HRESULT CWebViewFolderContents::SelectedItems(FolderItems **ppid)
  644. {
  645.     // We need to talk to the actual window under us
  646.     *ppid = NULL;
  647.     HRESULT hres = _GetFolder();
  648.     if (EVAL(SUCCEEDED(hres)))
  649.     {
  650.         hres = CSDFldrItems_Create(_psdf, TRUE, ppid);
  651.         if (EVAL(SUCCEEDED(hres)))
  652.             hres = MakeSafeForScripting((IUnknown**)ppid);
  653.     }
  654.     ASSERT(SUCCEEDED(hres));  // Error returns from script cause bad dialogs
  655.     return hres;
  656. }
  657. HRESULT CWebViewFolderContents::get_FocusedItem(FolderItem **ppid)
  658. {
  659.     *ppid = NULL;
  660.     HRESULT hres = _GetFolder();
  661.     if (EVAL(SUCCEEDED(hres)))
  662.     {
  663.         hres = S_FALSE;
  664.         if (_psfv)
  665.         {
  666.             LPITEMIDLIST pidl;
  667.             if (SUCCEEDED(_psfv->GetObject(&pidl, (UINT)-2)) && pidl)
  668.             {
  669.                 hres = CSDFldrItem_Create(_psdf, pidl, ppid);
  670.                 if (SUCCEEDED(hres))
  671.                 {
  672.                     hres = MakeSafeForScripting((IUnknown**)ppid);
  673.                 }
  674.                 // Don't free pidl as we did not copy it...
  675.                 // ILFree(pidl);
  676.             }
  677.         }
  678.         else
  679.             hres = E_FAIL;
  680.     }
  681.     ASSERT(SUCCEEDED(hres));  // Error returns from script cause bad dialogs
  682.     return hres;
  683. }
  684. HRESULT CWebViewFolderContents::SelectItem(VARIANT *pvfi, int dwFlags)
  685. {
  686.     HRESULT hres = E_FAIL;
  687.     if (_pdvf && _psfv)
  688.     {
  689.         LPCITEMIDLIST pidl = VariantToConstIDList(pvfi);
  690.         if (pidl)
  691.         {
  692.             IShellView *psv;
  693.             hres = _psfv->QueryInterface(IID_IShellView, (void **)&psv);
  694.             if (SUCCEEDED(hres))
  695.             {
  696.                 hres = psv->SelectItem(pidl, dwFlags);
  697.                 psv->Release();
  698.             }
  699.         }
  700.     }
  701.     ASSERT(SUCCEEDED(hres));  // Error returns from script cause bad dialogs
  702.     return hres;
  703. }
  704. HRESULT CWebViewFolderContents::PopupItemMenu(FolderItem *pfi, VARIANT vx, VARIANT vy, BSTR * pbs)
  705. {
  706.     ASSERT(0);  // Error returns from script cause bad dialogs
  707.     return E_NOTIMPL;
  708. }
  709. HRESULT CWebViewFolderContents::get_Script(IDispatch **ppid)
  710. {
  711.     HRESULT hr;
  712.     IHTMLDocument * phtmld;
  713.     IShellView  * psv;
  714.     *ppid = NULL;
  715.     if (_psfv) {
  716.         hr = _psfv->QueryInterface(IID_IShellView, (void **)&psv);
  717.         if (SUCCEEDED(hr)) {
  718.             // lets see if there is a IHTMLDocument that is below us now...    
  719.             hr = psv->GetItemObject(SVGIO_BACKGROUND, IID_IHTMLDocument, (void **)&phtmld);
  720.             if (SUCCEEDED(hr)) {
  721.                 hr = MakeSafeForScripting((IUnknown **)&phtmld);
  722.                 if (SUCCEEDED(hr)) {
  723.                     hr = phtmld->get_Script(ppid);
  724.                     phtmld->Release();
  725.                 }
  726.             }
  727.             psv->Release();
  728.         }
  729.     } else {
  730.         hr = E_FAIL;
  731.     }
  732.    ASSERT(SUCCEEDED(hr));  // Error returns from script cause bad dialogs
  733.    return hr;
  734. }
  735. HRESULT CWebViewFolderContents::get_ViewOptions(long *plSetting)
  736. {
  737.     *plSetting = (LONG)GetViewOptionsForDispatch();
  738.     return S_OK;
  739. }
  740. HRESULT CMyIE4ConnectionPoint::DoInvokeIE4(LPBOOL pf, LPVOID *ppv, DISPID dispid, DISPPARAMS *pdispparams)
  741. {
  742.     // Shell32 never asks for a cancel
  743.     ASSERT(pf == NULL && ppv == NULL);
  744.     // Forward the invoke to our parent WebViewFolderContents.
  745.     return IUnknown_CPContainerInvokeParam(m_punk, DIID_DShellFolderViewEvents,
  746.                         dispid, NULL, 0);
  747. }