diff --git a/base/shell/rshell/CMenuBand.cpp b/base/shell/rshell/CMenuBand.cpp index 4ea59fdb36a..13e1bc749b9 100644 --- a/base/shell/rshell/CMenuBand.cpp +++ b/base/shell/rshell/CMenuBand.cpp @@ -56,7 +56,9 @@ CMenuBand::CMenuBand() : m_popupBar(NULL), m_popupItem(-1), m_Show(FALSE), - m_shellBottom(FALSE) + m_shellBottom(FALSE), + m_trackedPopup(NULL), + m_trackedHwnd(NULL) { m_focusManager = CMenuFocusManager::AcquireManager(); } @@ -418,6 +420,16 @@ HRESULT STDMETHODCALLTYPE CMenuBand::ShowDW(BOOL fShow) HRESULT STDMETHODCALLTYPE CMenuBand::CloseDW(DWORD dwReserved) { + if (m_subMenuChild) + { + m_subMenuChild->OnSelect(MPOS_CANCELLEVEL); + } + + if (m_subMenuChild) + { + DbgPrint("Child object should have removed itself.\n"); + } + ShowDW(FALSE); if (m_staticToolbar != NULL) @@ -594,7 +606,10 @@ HRESULT CMenuBand::_IsTracking() HRESULT STDMETHODCALLTYPE CMenuBand::SetClient(IUnknown *punkClient) { - m_subMenuChild = NULL; + if (m_subMenuChild) + { + ReleaseCComPtrExpectZero(m_subMenuChild); + } if (!punkClient) { @@ -738,10 +753,16 @@ HRESULT CMenuBand::_TrackSubMenu(HMENU popup, INT x, INT y, RECT& rcExclude) UINT flags = TPM_VERPOSANIMATION | TPM_VERTICAL | TPM_LEFTALIGN; HWND hwnd = m_menuOwner ? m_menuOwner : m_topLevelWindow; + m_trackedPopup = popup; + m_trackedHwnd = hwnd; + m_focusManager->PushTrackedPopup(popup); ::TrackPopupMenuEx(popup, flags, x, y, hwnd, ¶ms); m_focusManager->PopTrackedPopup(popup); + m_trackedPopup = NULL; + m_trackedHwnd = NULL; + _DisableMouseTrack(FALSE); return S_OK; @@ -950,11 +971,19 @@ HRESULT CMenuBand::_MenuItemHotTrack(DWORD changeType) HRESULT CMenuBand::_CancelCurrentPopup() { - if (!m_subMenuChild) - return S_FALSE; + if (m_subMenuChild) + { + HRESULT hr = m_subMenuChild->OnSelect(MPOS_CANCELLEVEL); + return hr; + } - HRESULT hr = m_subMenuChild->OnSelect(MPOS_CANCELLEVEL); - return hr; + if (m_trackedPopup) + { + ::SendMessage(m_trackedHwnd, WM_CANCELMODE, 0, 0); + return S_OK; + } + + return S_FALSE; } HRESULT CMenuBand::_OnPopupSubMenu(IShellMenu * childShellMenu, POINTL * pAt, RECTL * pExclude, BOOL keyInitiated) @@ -1044,6 +1073,11 @@ HRESULT CMenuBand::_MenuBarMouseUp(HWND hwnd, INT item) return S_OK; } +HRESULT CMenuBand::_HasSubMenu() +{ + return m_popupBar ? S_OK : S_FALSE; +} + HRESULT STDMETHODCALLTYPE CMenuBand::InvalidateItem(LPSMDATA psmd, DWORD dwFlags) { UNIMPLEMENTED; diff --git a/base/shell/rshell/CMenuBand.h b/base/shell/rshell/CMenuBand.h index 0b9020c5f54..3cb74f1b1ee 100644 --- a/base/shell/rshell/CMenuBand.h +++ b/base/shell/rshell/CMenuBand.h @@ -68,6 +68,9 @@ private: BOOL m_Show; BOOL m_shellBottom; + HMENU m_trackedPopup; + HWND m_trackedHwnd; + public: CMenuBand(); virtual ~CMenuBand(); @@ -194,6 +197,7 @@ public: HRESULT _KillPopupTimers(); HRESULT _MenuBarMouseDown(HWND hwnd, INT item); HRESULT _MenuBarMouseUp(HWND hwnd, INT item); + HRESULT _HasSubMenu(); BOOL UseBigIcons() { diff --git a/base/shell/rshell/CMenuDeskBar.cpp b/base/shell/rshell/CMenuDeskBar.cpp index cef88c532ac..96cf7b3a5b1 100644 --- a/base/shell/rshell/CMenuDeskBar.cpp +++ b/base/shell/rshell/CMenuDeskBar.cpp @@ -171,7 +171,17 @@ HRESULT STDMETHODCALLTYPE CMenuDeskBar::SetClient(IUnknown *punkClient) CComPtr pDeskBandClient; HRESULT hr; - m_Client.Release(); + if (m_Client) + { + hr = m_Client->QueryInterface(IID_PPV_ARG(IDeskBarClient, &pDeskBandClient)); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + pDeskBandClient->SetDeskBarSite(NULL); + + pDeskBandClient = NULL; + m_Client = NULL; + } if (punkClient == NULL) return S_OK; @@ -222,9 +232,19 @@ HRESULT STDMETHODCALLTYPE CMenuDeskBar::SetSite(IUnknown *pUnkSite) if (m_Shown) _CloseBar(); + m_SubMenuParent = NULL; + m_Site = pUnkSite; - IUnknown_QueryService(m_Site, SID_SMenuPopup, IID_PPV_ARG(IMenuPopup, &m_SubMenuParent)); + if (m_Site) + { + IUnknown_QueryService(m_Site, SID_SMenuPopup, IID_PPV_ARG(IMenuPopup, &m_SubMenuParent)); + } + else + { + DestroyWindow(); + SetClient(NULL); + } return S_OK; } diff --git a/base/shell/rshell/CStartMenu.cpp b/base/shell/rshell/CStartMenu.cpp index 3609630664e..23ec6aad5a4 100644 --- a/base/shell/rshell/CStartMenu.cpp +++ b/base/shell/rshell/CStartMenu.cpp @@ -151,7 +151,14 @@ private: int csidl = 0; IShellMenu *pShellMenu; +#if USE_SYSTEM_MENUBAND + hr = CoCreateInstance(CLSID_MenuBand, + NULL, + CLSCTX_INPROC_SERVER, + IID_PPV_ARG(IShellMenu, &pShellMenu)); +#else hr = CMenuBand_Constructor(IID_PPV_ARG(IShellMenu, &pShellMenu)); +#endif if (FAILED_UNEXPECTEDLY(hr)) return hr; @@ -394,15 +401,36 @@ CStartMenu_Constructor(REFIID riid, void **ppv) LPITEMIDLIST pidlPrograms; CComPtr psfPrograms; +#if USE_SYSTEM_MENUBAND + hr = CoCreateInstance(CLSID_MenuBand, + NULL, + CLSCTX_INPROC_SERVER, + IID_PPV_ARG(IShellMenu, &pShellMenu)); +#else hr = CMenuBand_Constructor(IID_PPV_ARG(IShellMenu, &pShellMenu)); +#endif if (FAILED_UNEXPECTEDLY(hr)) return hr; +#if USE_SYSTEM_MENUSITE + hr = CoCreateInstance(CLSID_MenuBandSite, + NULL, + CLSCTX_INPROC_SERVER, + IID_PPV_ARG(IBandSite, &pBandSite)); +#else hr = CMenuSite_Constructor(IID_PPV_ARG(IBandSite, &pBandSite)); +#endif if (FAILED_UNEXPECTEDLY(hr)) return hr; +#if USE_SYSTEM_MENUDESKBAR + hr = CoCreateInstance(CLSID_MenuDeskBar, + NULL, + CLSCTX_INPROC_SERVER, + IID_PPV_ARG(IDeskBar, &pDeskBar)); +#else hr = CMenuDeskBar_Constructor(IID_PPV_ARG(IDeskBar, &pDeskBar)); +#endif if (FAILED_UNEXPECTEDLY(hr)) return hr; diff --git a/dll/win32/browseui/desktopipc.cpp b/dll/win32/browseui/desktopipc.cpp index aec6a95fb9a..7ee18bbd3c0 100644 --- a/dll/win32/browseui/desktopipc.cpp +++ b/dll/win32/browseui/desktopipc.cpp @@ -345,22 +345,6 @@ cleanup0: return params; } - -/************************************************************************* -* SHOnCWMCommandLine [BROWSEUI.127] -*/ -extern "C" BOOL WINAPI SHOnCWMCommandLine(HANDLE hSharedInfo) -{ - DbgPrint("SHOnCWMCommandLine\n"); - - PIE_THREAD_PARAM_BLOCK params = ParseSharedPacket(hSharedInfo); - - if (params) - return SHOpenFolderWindow(params); - - return FALSE; -} - /************************************************************************* * SHCreateIETHREADPARAM [BROWSEUI.123] */ @@ -441,6 +425,23 @@ extern "C" void WINAPI SHDestroyIETHREADPARAM(IEThreadParamBlock *param) LocalFree(param); } +/************************************************************************* +* SHOnCWMCommandLine [BROWSEUI.127] +*/ +extern "C" BOOL WINAPI SHOnCWMCommandLine(HANDLE hSharedInfo) +{ + DbgPrint("SHOnCWMCommandLine\n"); + + PIE_THREAD_PARAM_BLOCK params = ParseSharedPacket(hSharedInfo); + + if (params) + return SHOpenFolderWindow(params); + + SHDestroyIETHREADPARAM(params); + + return FALSE; +} + /************************************************************************* * SHOpenFolderWindow [BROWSEUI.102] * see SHOpenNewFrame below for remarks diff --git a/dll/win32/browseui/internettoolbar.cpp b/dll/win32/browseui/internettoolbar.cpp index bcfcb060381..3a86b5067dd 100644 --- a/dll/win32/browseui/internettoolbar.cpp +++ b/dll/win32/browseui/internettoolbar.cpp @@ -994,27 +994,6 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::ShowDW(BOOL fShow) return S_OK; } -template -void ReleaseCComPtrExpectZero(CComPtr& cptr, BOOL forceRelease = FALSE) -{ - if (cptr.p != NULL) - { - int nrc = cptr->Release(); - if (nrc > 0) - { - DbgPrint("WARNING: Unexpected RefCount > 0 (%d)!\n", nrc); - if (forceRelease) - { - while (nrc > 0) - { - nrc = cptr->Release(); - } - } - } - cptr.Detach(); - } -} - HRESULT STDMETHODCALLTYPE CInternetToolbar::CloseDW(DWORD dwReserved) { HRESULT hResult; diff --git a/dll/win32/browseui/shellbrowser.cpp b/dll/win32/browseui/shellbrowser.cpp index ea02d0c9ac6..b45f116bbbe 100644 --- a/dll/win32/browseui/shellbrowser.cpp +++ b/dll/win32/browseui/shellbrowser.cpp @@ -2563,6 +2563,9 @@ HRESULT STDMETHODCALLTYPE CShellBrowser::v_MayTranslateAccelerator(MSG *pmsg) return S_OK; } + if (!fCurrentShellView) + return S_FALSE; + return fCurrentShellView->TranslateAcceleratorW(pmsg); } @@ -3070,27 +3073,6 @@ LRESULT CShellBrowser::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &b return 0; } -template -void ReleaseCComPtrExpectZero(CComPtr& cptr, BOOL forceRelease = FALSE) -{ - if (cptr.p != NULL) - { - int nrc = cptr->Release(); - if (nrc > 0) - { - DbgPrint("WARNING: Unexpected RefCount > 0!\n"); - if (forceRelease) - { - while (nrc > 0) - { - nrc = cptr->Release(); - } - } - } - cptr.Detach(); - } -} - LRESULT CShellBrowser::OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) { HRESULT hr; diff --git a/dll/win32/shell32/shlview.cpp b/dll/win32/shell32/shlview.cpp index 333917fe8fe..b94b22286f7 100644 --- a/dll/win32/shell32/shlview.cpp +++ b/dll/win32/shell32/shlview.cpp @@ -341,37 +341,38 @@ class CDefView : typedef void (CALLBACK *PFNSHGETSETTINGSPROC)(LPSHELLFLAGSTATE lpsfs, DWORD dwMask); -CDefView::CDefView() +CDefView::CDefView() : + m_hWndList(NULL), + m_hWndParent(NULL), + m_hMenu(NULL), + m_menusLoaded(FALSE), + m_uState(0), + m_cidl(0), + m_apidl(NULL), + m_hNotify(0), + m_hAccel(NULL), + m_dwAspects(0), + m_dwAdvf(0), + m_iDragOverItem(0), + m_cScrollDelay(0), + m_isEditing(FALSE), + m_hView(NULL) { - m_hWndList = NULL; - m_hWndParent = NULL; - m_FolderSettings.fFlags = 0; - m_FolderSettings.ViewMode = 0; - m_hMenu = NULL; - m_menusLoaded = FALSE; - m_uState = 0; - m_cidl = 0; - m_apidl = NULL; - m_sortInfo.bIsAscending = FALSE; - m_sortInfo.nHeaderID = 0; - m_sortInfo.nLastHeaderID = 0; - m_hNotify = 0; - m_hAccel = NULL; - m_dwAspects = 0; - m_dwAdvf = 0; - m_iDragOverItem = 0; - m_cScrollDelay = 0; - m_ptLastMousePos.x = 0; - m_ptLastMousePos.y = 0; - m_isEditing = FALSE; - ZeroMemory(&m_Category, sizeof(m_Category)); - m_hView = NULL; + m_FolderSettings = { 0 }; + m_sortInfo = { 0 }; + m_ptLastMousePos = { 0 }; + m_Category = { 0 }; } CDefView::~CDefView() { TRACE(" destroying IShellView(%p)\n", this); + if (m_hWnd) + { + DestroyViewWindow(); + } + SHFree(m_apidl); } @@ -2122,12 +2123,35 @@ HRESULT WINAPI CDefView::DestroyViewWindow() /*Make absolutely sure all our UI is cleaned up.*/ UIActivate(SVUIA_DEACTIVATE); + if (m_hAccel) + { + // "Accelerator tables loaded from resources are freed automatically when the application terminates." -- MSDN + m_hAccel = NULL; + } + + if (m_hView) + { + DestroyMenu(m_hView); + m_hView = NULL; + } + if (m_hMenu) { DestroyMenu(m_hMenu); + m_hView = NULL; + } + + if (m_hWndList) + { + ::DestroyWindow(m_hWndList); + m_hWndList = NULL; + } + + if (m_hWnd) + { + DestroyWindow(); } - DestroyWindow(); m_pShellBrowser.Release(); m_pCommDlgBrowser.Release(); diff --git a/include/reactos/undocshell.h b/include/reactos/undocshell.h index 4fc7ec43017..e5c2193f858 100644 --- a/include/reactos/undocshell.h +++ b/include/reactos/undocshell.h @@ -691,6 +691,27 @@ public: } }; +template +void ReleaseCComPtrExpectZero(CComPtr& cptr, BOOL forceRelease = FALSE) +{ + if (cptr.p != NULL) + { + int nrc = cptr->Release(); + if (nrc > 0) + { + DbgPrint("WARNING: Unexpected RefCount > 0 (%d)!\n", nrc); + if (forceRelease) + { + while (nrc > 0) + { + nrc = cptr->Release(); + } + } + } + cptr.Detach(); + } +} + template HRESULT inline ShellObjectCreator(REFIID riid, R ** ppv) {