[BROWSEUI]

* SHOnCWMCommandLine: Fix IETHREADPARAM leak.

[SHELL32]
* Fix HMENU leak of the popup used in the view mode button of the toolbar.

[RSHELL]
* Undo a previous change to help debug the leaks.
* Remove child submenus when closing a menu band.
* Add some extra verification for debugging purposes. 

[BROWSEUI]
[RSHELL]
[SHELL32]
* Move ReleaseCComPtrExpectZero to the shared header.

svn path=/branches/shell-experiments/; revision=64858
This commit is contained in:
David Quintana 2014-10-20 21:35:22 +00:00
parent b138a8620d
commit 96cdae0a7c
9 changed files with 184 additions and 91 deletions

View file

@ -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, &params);
m_focusManager->PopTrackedPopup(popup);
m_trackedPopup = NULL;
m_trackedHwnd = NULL;
_DisableMouseTrack(FALSE);
return S_OK;
@ -950,13 +971,21 @@ 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;
}
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)
{
HRESULT hr = 0;
@ -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;

View file

@ -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()
{

View file

@ -171,7 +171,17 @@ HRESULT STDMETHODCALLTYPE CMenuDeskBar::SetClient(IUnknown *punkClient)
CComPtr<IDeskBarClient> 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;
if (m_Site)
{
IUnknown_QueryService(m_Site, SID_SMenuPopup, IID_PPV_ARG(IMenuPopup, &m_SubMenuParent));
}
else
{
DestroyWindow();
SetClient(NULL);
}
return S_OK;
}

View file

@ -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<IShellFolder> 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;

View file

@ -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

View file

@ -994,27 +994,6 @@ HRESULT STDMETHODCALLTYPE CInternetToolbar::ShowDW(BOOL fShow)
return S_OK;
}
template<class T>
void ReleaseCComPtrExpectZero(CComPtr<T>& 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;

View file

@ -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<class T>
void ReleaseCComPtrExpectZero(CComPtr<T>& 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;

View file

@ -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();
}
m_pShellBrowser.Release();
m_pCommDlgBrowser.Release();

View file

@ -691,6 +691,27 @@ public:
}
};
template<class T>
void ReleaseCComPtrExpectZero(CComPtr<T>& 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<class T, class R>
HRESULT inline ShellObjectCreator(REFIID riid, R ** ppv)
{