* CMenuBand: Increase the refcount of m_smc before returning it.
* CMenuBand: Improve the closing logic so that the object is reusable when it needs to be, and can still be released properly.
* CMenuDeskBar: Protect self against unexpected termination.
* CMenuFocusManager: Refcount objects that are being used.
* CStartMenu: Properly release the created objects after it's done using them (by using CComPtr instead of raw pointers).

[BROWSEUI]
* AddressBand: Release the addressband site when closing the band.
* InternetToolbar: Do not filter away ALL the items of the favorites folder.
* InternetToolbar: Do not AddRef a CComPtr that already did the refcounting itself.

CORE-8690

svn path=/branches/shell-experiments/; revision=64929
This commit is contained in:
David Quintana 2014-10-23 17:17:16 +00:00
parent 121e60dbda
commit 1cd79168e1
9 changed files with 248 additions and 39 deletions

View file

@ -104,7 +104,10 @@ HRESULT STDMETHODCALLTYPE CMenuBand::GetMenuInfo(
return E_INVALIDARG;
if (ppsmc)
{
m_psmc->AddRef();
*ppsmc = m_psmc;
}
if (puId)
*puId = m_uId;
@ -373,6 +376,8 @@ HRESULT STDMETHODCALLTYPE CMenuBand::ShowDW(BOOL fShow)
if (m_Show == fShow)
return S_OK;
m_Show = fShow;
if (m_staticToolbar != NULL)
{
hr = m_staticToolbar->ShowWindow(fShow);
@ -413,8 +418,6 @@ HRESULT STDMETHODCALLTYPE CMenuBand::ShowDW(BOOL fShow)
hr = m_focusManager->PopMenuBar(this);
}
m_Show = fShow;
return S_OK;
}
@ -435,19 +438,14 @@ HRESULT STDMETHODCALLTYPE CMenuBand::CloseDW(DWORD dwReserved)
if (m_staticToolbar != NULL)
{
m_staticToolbar->Close();
delete m_staticToolbar;
m_staticToolbar = NULL;
}
if (m_SFToolbar != NULL)
{
m_SFToolbar->Close();
delete m_staticToolbar;
m_staticToolbar = NULL;
}
if (m_site) m_site.Release();
if (m_psmc) m_psmc.Release();
if (m_subMenuChild) m_subMenuChild.Release();
if (m_subMenuParent) m_subMenuParent.Release();
if (m_childBand) m_childBand.Release();
@ -596,7 +594,7 @@ HRESULT CMenuBand::_SetParentBand(CMenuBand * parent)
HRESULT CMenuBand::_IsPopup()
{
return m_subMenuParent ? S_OK : S_FALSE;
return !(m_dwFlags & SMINIT_VERTICAL);
}
HRESULT CMenuBand::_IsTracking()
@ -606,9 +604,14 @@ HRESULT CMenuBand::_IsTracking()
HRESULT STDMETHODCALLTYPE CMenuBand::SetClient(IUnknown *punkClient)
{
if (m_subMenuChild)
CComPtr<IMenuPopup> child = m_subMenuChild;
m_subMenuChild = NULL;
if (child)
{
ReleaseCComPtrExpectZero(m_subMenuChild);
IUnknown_SetSite(child, NULL);
child.Release();
}
if (!punkClient)
@ -989,15 +992,29 @@ HRESULT CMenuBand::_CancelCurrentPopup()
HRESULT CMenuBand::_OnPopupSubMenu(IShellMenu * childShellMenu, POINTL * pAt, RECTL * pExclude, BOOL keyInitiated)
{
HRESULT hr = 0;
IBandSite* pBandSite;
IDeskBar* pDeskBar;
CComPtr<IBandSite> pBandSite;
CComPtr<IDeskBar> pDeskBar;
// Create the necessary objects
#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

@ -47,6 +47,19 @@ CMenuDeskBar::~CMenuDeskBar()
{
}
LRESULT CMenuDeskBar::_OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
{
this->AddRef();
bHandled = FALSE;
return 0;
}
void CMenuDeskBar::OnFinalMessage(HWND /* hWnd */)
{
this->Release();
}
HRESULT STDMETHODCALLTYPE CMenuDeskBar::Initialize(THIS)
{
return S_OK;
@ -245,8 +258,8 @@ HRESULT STDMETHODCALLTYPE CMenuDeskBar::SetSite(IUnknown *pUnkSite)
}
else
{
DestroyWindow();
SetClient(NULL);
DestroyWindow();
}
return S_OK;
@ -450,6 +463,8 @@ HRESULT STDMETHODCALLTYPE CMenuDeskBar::SetSubMenu(IMenuPopup *pmp, BOOL fSet)
HRESULT STDMETHODCALLTYPE CMenuDeskBar::OnSelect(DWORD dwSelectType)
{
CComPtr<IDeskBar> safeThis = this;
/* As far as I can tell, the submenu hierarchy looks like this:
*
* The DeskBar's Child is the Band it contains.
@ -493,6 +508,7 @@ HRESULT STDMETHODCALLTYPE CMenuDeskBar::OnSelect(DWORD dwSelectType)
HRESULT CMenuDeskBar::_CloseBar()
{
CComPtr<IDeskBar> safeThis = this;
CComPtr<IDeskBarClient> dbc;
HRESULT hr;

View file

@ -50,6 +50,7 @@ private:
BOOL m_Shown;
DWORD m_ShowFlags;
virtual void OnFinalMessage(HWND hWnd);
public:
CMenuDeskBar();
virtual ~CMenuDeskBar();
@ -60,6 +61,7 @@ public:
DECLARE_WND_CLASS_EX(_T("BaseBar"), CS_SAVEBITS | CS_DROPSHADOW, COLOR_3DFACE)
BEGIN_MSG_MAP(CMenuDeskBar)
MESSAGE_HANDLER(WM_CREATE, _OnCreate)
MESSAGE_HANDLER(WM_SIZE, _OnSize)
MESSAGE_HANDLER(WM_NOTIFY, _OnNotify)
MESSAGE_HANDLER(WM_PAINT, _OnPaint)
@ -125,6 +127,7 @@ public:
private:
// message handlers
LRESULT _OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
LRESULT _OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
LRESULT _OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
LRESULT _OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);

View file

@ -759,7 +759,9 @@ HRESULT CMenuFocusManager::UpdateFocus()
HRESULT CMenuFocusManager::PushMenuBar(CMenuBand * mb)
{
TRACE("PushTrackedPopup %p\n", mb);
DbgPrint("PushMenuBar %p\n", mb);
mb->AddRef();
_ASSERT(m_bandCount == 0);
@ -772,7 +774,9 @@ HRESULT CMenuFocusManager::PushMenuBar(CMenuBand * mb)
HRESULT CMenuFocusManager::PushMenuPopup(CMenuBand * mb)
{
TRACE("PushTrackedPopup %p\n", mb);
DbgPrint("PushTrackedPopup %p\n", mb);
mb->AddRef();
_ASSERT(!m_current || m_current->type != TrackedMenuEntry);
@ -793,7 +797,7 @@ HRESULT CMenuFocusManager::PushMenuPopup(CMenuBand * mb)
HRESULT CMenuFocusManager::PushTrackedPopup(HMENU popup)
{
TRACE("PushTrackedPopup %p\n", popup);
DbgPrint("PushTrackedPopup %p\n", popup);
_ASSERT(m_bandCount > 0);
_ASSERT(!m_current || m_current->type != TrackedMenuEntry);
@ -802,7 +806,7 @@ HRESULT CMenuFocusManager::PushTrackedPopup(HMENU popup)
if (FAILED_UNEXPECTEDLY(hr))
return hr;
TRACE("PushTrackedPopup %p\n", popup);
DbgPrint("PushTrackedPopup %p\n", popup);
m_selectedMenu = popup;
m_selectedItem = -1;
m_selectedItemFlags = 0;
@ -816,7 +820,7 @@ HRESULT CMenuFocusManager::PopMenuBar(CMenuBand * mb)
CMenuBand * mbc;
HRESULT hr;
TRACE("PopMenuBar %p\n", mb);
DbgPrint("PopMenuBar %p\n", mb);
hr = PopFromArray(&type, &mbc, NULL);
if (FAILED_UNEXPECTEDLY(hr))
@ -834,6 +838,8 @@ HRESULT CMenuFocusManager::PopMenuBar(CMenuBand * mb)
mbc->_SetParentBand(NULL);
mbc->Release();
hr = UpdateFocus();
if (FAILED_UNEXPECTEDLY(hr))
return hr;
@ -853,7 +859,7 @@ HRESULT CMenuFocusManager::PopMenuPopup(CMenuBand * mb)
CMenuBand * mbc;
HRESULT hr;
TRACE("PopMenuPopup %p\n", mb);
DbgPrint("PopMenuPopup %p\n", mb);
hr = PopFromArray(&type, &mbc, NULL);
if (FAILED_UNEXPECTEDLY(hr))
@ -871,6 +877,8 @@ HRESULT CMenuFocusManager::PopMenuPopup(CMenuBand * mb)
mbc->_SetParentBand(NULL);
mbc->Release();
hr = UpdateFocus();
if (FAILED_UNEXPECTEDLY(hr))
return hr;
@ -890,7 +898,7 @@ HRESULT CMenuFocusManager::PopTrackedPopup(HMENU popup)
HMENU hmenu;
HRESULT hr;
TRACE("PopTrackedPopup %p\n", popup);
DbgPrint("PopTrackedPopup %p\n", popup);
hr = PopFromArray(&type, NULL, &hmenu);
if (FAILED_UNEXPECTEDLY(hr))

View file

@ -390,9 +390,9 @@ extern "C"
HRESULT WINAPI
CStartMenu_Constructor(REFIID riid, void **ppv)
{
IShellMenu* pShellMenu;
IBandSite* pBandSite;
IDeskBar* pDeskBar;
CComPtr<IShellMenu> pShellMenu;
CComPtr<IBandSite> pBandSite;
CComPtr<IDeskBar> pDeskBar;
HRESULT hr;
IShellFolder * psf;

View file

@ -254,6 +254,8 @@ HRESULT STDMETHODCALLTYPE CAddressBand::CloseDW(DWORD dwReserved)
m_hWnd = NULL;
IUnknown_SetSite(fAddressEditBox, NULL);
if (fAddressEditBox) fAddressEditBox.Release();
if (fSite) fSite.Release();

View file

@ -587,11 +587,13 @@ HRESULT STDMETHODCALLTYPE CMenuCallback::GetObject(LPSMDATA psmd, REFIID riid, v
hResult = newMenu->SetShellFolder(favoritesFolder, favoritesPIDL, orderRegKey, SMSET_BOTTOM | SMINIT_CACHED | SMINV_ID);
if (favoritesPIDL)
ILFree(favoritesPIDL);
if (SUCCEEDED(hResult))
fFavoritesMenu.Attach(newMenu.Detach());
if (FAILED(hResult))
return hResult;
fFavoritesMenu = newMenu;
}
if (fFavoritesMenu.p == NULL)
return E_FAIL;
return fFavoritesMenu->QueryInterface(riid, ppvObject);
}
@ -665,7 +667,7 @@ HRESULT STDMETHODCALLTYPE CMenuCallback::CallbackSM(LPSMDATA psmd, UINT uMsg, WP
case 49:
break;
case 0x10000000:
break;
return S_OK;
}
return S_FALSE;
}
@ -744,8 +746,6 @@ HRESULT CInternetToolbar::CreateMenuBar(IShellMenu **pMenuBar)
}
#endif
menubar->AddRef();
if (FAILED_UNEXPECTEDLY(hResult))
{
hResult = CoCreateInstance(CLSID_MenuBand, NULL, CLSCTX_INPROC_SERVER,

View file

@ -4040,3 +4040,154 @@ library ShellObjects
interface IShellItem2;
}
}
enum _OPPROGDLGF
{
OPPROGDLG_DEFAULT = 0,
OPPROGDLG_ENABLEPAUSE = 0x80,
OPPROGDLG_ALLOWUNDO = 0x100,
OPPROGDLG_DONTDISPLAYSOURCEPATH = 0x200,
OPPROGDLG_DONTDISPLAYDESTPATH = 0x400,
OPPROGDLG_NOMULTIDAYESTIMATES = 0x800,
OPPROGDLG_DONTDISPLAYLOCATIONS = 0x1000
};
typedef DWORD OPPROGDLGF;
enum _PDMODE
{
PDM_DEFAULT = 0,
PDM_RUN = 0x1,
PDM_PREFLIGHT = 0x2,
PDM_UNDOING = 0x4,
PDM_ERRORSBLOCKING = 0x8,
PDM_INDETERMINATE = 0x10
};
typedef DWORD PDMODE;
typedef enum PDOPSTATUS
{
PDOPS_RUNNING = 1,
PDOPS_PAUSED = 2,
PDOPS_CANCELLED = 3,
PDOPS_STOPPED = 4,
PDOPS_ERRORS = 5
} PDOPSTATUS;
typedef enum _SPACTION
{
SPACTION_NONE = 0,
SPACTION_MOVING = 1,
SPACTION_COPYING = 2,
SPACTION_RECYCLING = 3,
SPACTION_APPLYINGATTRIBS = 4,
SPACTION_DOWNLOADING = 5,
SPACTION_SEARCHING_INTERNET = 6,
SPACTION_CALCULATING = 7,
SPACTION_UPLOADING = 8,
SPACTION_SEARCHING_FILES = 9,
SPACTION_DELETING = 10,
SPACTION_RENAMING = 11,
SPACTION_FORMATTING = 12,
SPACTION_COPY_MOVING = 13
} SPACTION;
[
uuid(0C9FB851-E5C9-43EB-A370-F0677B13874C),
object,
pointer_default(unique)
]
interface IOperationsProgressDialog : IUnknown
{
HRESULT StartProgressDialog(
[in] HWND hwndOwner,
[in] OPPROGDLGF flags);
HRESULT StopProgressDialog();
HRESULT SetOperation(
[in] SPACTION action);
HRESULT SetMode(
[in] PDMODE mode);
HRESULT UpdateProgress(
[in] ULONGLONG ullPointsCurrent,
[in] ULONGLONG ullPointsTotal,
[in] ULONGLONG ullSizeCurrent,
[in] ULONGLONG ullSizeTotal,
[in] ULONGLONG ullItemsCurrent,
[in] ULONGLONG ullItemsTotal);
HRESULT UpdateLocations(
[in, optional] IShellItem *psiSource,
[in, optional] IShellItem *psiTarget,
[in, optional] IShellItem *psiItem);
HRESULT ResetTimer();
HRESULT PauseTimer();
HRESULT ResumeTimer();
HRESULT GetMilliseconds(
[out] ULONGLONG *pullElapsed,
[out] ULONGLONG *pullRemaining);
HRESULT GetOperationStatus(
[out] PDOPSTATUS *popstatus);
};
[
uuid(947aab5f-0a5c-4c13-b4d6-4bf7836fc9f8),
object,
pointer_default(unique)
]
interface IFileOperation : IUnknown
{
HRESULT Advise(
[in] IFileOperationProgressSink *pfops,
[out] DWORD *pdwCookie);
HRESULT Unadvise(
[in] DWORD dwCookie);
HRESULT SetOperationFlags(
[in] DWORD dwOperationFlags);
HRESULT SetProgressMessage(
[in] LPCWSTR pszMessage);
HRESULT SetProgressDialog(
[in] IOperationsProgressDialog *popd);
HRESULT SetProperties(
[in] IPropertyChangeArray *pproparray);
HRESULT SetOwnerWindow(
[in] HWND hwndOwner);
HRESULT ApplyPropertiesToItem(
[in] IShellItem *psiItem);
HRESULT ApplyPropertiesToItems(
[in] IUnknown *punkItems);
HRESULT RenameItem(
[in] IShellItem *psiItem,
[in] LPCWSTR pszNewName,
[in] IFileOperationProgressSink *pfopsItem);
HRESULT RenameItems(
[in] IUnknown *pUnkItems,
[in] LPCWSTR pszNewName);
HRESULT MoveItem(
[in] IShellItem *psiItem,
[in] IShellItem *psiDestinationFolder,
[in] LPCWSTR pszNewName,
[in] IFileOperationProgressSink *pfopsItem);
HRESULT MoveItems(
[in] IUnknown *punkItems,
[in] IShellItem *psiDestinationFolder);
HRESULT CopyItem(
[in] IShellItem *psiItem,
[in] IShellItem *psiDestinationFolder,
[in] LPCWSTR pszCopyName,
[in] IFileOperationProgressSink *pfopsItem);
HRESULT CopyItems(
[in] IUnknown *punkItems,
[in] IShellItem *psiDestinationFolder);
HRESULT DeleteItem(
[in] IShellItem *psiItem,
[in] IFileOperationProgressSink *pfopsItem);
HRESULT DeleteItems(
[in] IUnknown *punkItems);
HRESULT NewItem(
[in] IShellItem *psiDestinationFolder,
[in] DWORD dwFileAttributes,
[in] LPCWSTR pszName,
[in] LPCWSTR pszTemplateName,
[in] IFileOperationProgressSink *pfopsItem);
HRESULT PerformOperations();
HRESULT GetAnyOperationsAborted(
[out] BOOL *pfAnyOperationsAborted);
};

View file

@ -638,7 +638,7 @@ public:
STDMETHOD_(ULONG, AddRef)()
{
int rc = this->InternalAddRef();
DbgPrint("RefCount is now %d(++)!\n", rc);
DbgPrint("RefCount is now %d(++)! %s\n", rc, __FUNCTION__);
return rc;
}
@ -647,9 +647,15 @@ public:
ULONG newRefCount;
newRefCount = this->InternalRelease();
DbgPrint("RefCount is now %d(--)!\n", newRefCount);
if (newRefCount == 0)
{
DbgPrint("RefCount is now 0! Deleting! %s\n", newRefCount, __FUNCTION__);
delete this;
}
else
{
DbgPrint("RefCount is now %d(--)! %s\n", newRefCount, __FUNCTION__);
}
return newRefCount;
}
@ -691,6 +697,12 @@ public:
}
};
#ifdef DEBUG_CCOMOBJECT
# define _CComObject CComDebugObject
#else
# define _CComObject CComObject
#endif
template<class T>
void ReleaseCComPtrExpectZero(CComPtr<T>& cptr, BOOL forceRelease = FALSE)
{
@ -721,7 +733,7 @@ HRESULT inline ShellObjectCreator(REFIID riid, R ** ppv)
if (ppv == NULL)
return E_POINTER;
*ppv = NULL;
ATLTRY(obj = new CComObject<T>);
ATLTRY(obj = new _CComObject<T>);
if (obj.p == NULL)
return E_OUTOFMEMORY;
hResult = obj->QueryInterface(riid, reinterpret_cast<void **>(ppv));
@ -740,7 +752,7 @@ HRESULT inline ShellObjectCreatorInit(REFIID riid, R ** ppv)
if (ppv == NULL)
return E_POINTER;
*ppv = NULL;
ATLTRY(obj = new CComObject<T>);
ATLTRY(obj = new _CComObject<T>);
if (obj.p == NULL)
return E_OUTOFMEMORY;
hResult = obj->QueryInterface(riid, reinterpret_cast<void **>(&result));
@ -766,7 +778,7 @@ HRESULT inline ShellObjectCreatorInit(REFIID riid, void ** ppv)
if (ppv == NULL)
return E_POINTER;
*ppv = NULL;
ATLTRY(obj = new CComObject<T>);
ATLTRY(obj = new _CComObject<T>);
if (obj.p == NULL)
return E_OUTOFMEMORY;
hResult = obj->QueryInterface(riid, reinterpret_cast<void **>(&result));
@ -792,7 +804,7 @@ HRESULT inline ShellObjectCreatorInit(T1 initArg1, REFIID riid, R ** ppv)
if (ppv == NULL)
return E_POINTER;
*ppv = NULL;
ATLTRY(obj = new CComObject<T>);
ATLTRY(obj = new _CComObject<T>);
if (obj.p == NULL)
return E_OUTOFMEMORY;
hResult = obj->QueryInterface(riid, reinterpret_cast<void **>(&result));
@ -818,7 +830,7 @@ HRESULT inline ShellObjectCreatorInit(T1 initArg1, T2 initArg2, REFIID riid, R *
if (ppv == NULL)
return E_POINTER;
*ppv = NULL;
ATLTRY(obj = new CComObject<T>);
ATLTRY(obj = new _CComObject<T>);
if (obj.p == NULL)
return E_OUTOFMEMORY;
hResult = obj->QueryInterface(riid, reinterpret_cast<void **>(&result));
@ -844,7 +856,7 @@ HRESULT inline ShellObjectCreatorInit(T1 initArg1, T2 initArg2, T3 initArg3, REF
if (ppv == NULL)
return E_POINTER;
*ppv = NULL;
ATLTRY(obj = new CComObject<T>);
ATLTRY(obj = new _CComObject<T>);
if (obj.p == NULL)
return E_OUTOFMEMORY;
hResult = obj->QueryInterface(riid, reinterpret_cast<void **>(&result));
@ -870,7 +882,7 @@ HRESULT inline ShellObjectCreatorInit(T1 initArg1, T2 initArg2, T3 initArg3, T4
if (ppv == NULL)
return E_POINTER;
*ppv = NULL;
ATLTRY(obj = new CComObject<T>);
ATLTRY(obj = new _CComObject<T>);
if (obj.p == NULL)
return E_OUTOFMEMORY;
hResult = obj->QueryInterface(riid, reinterpret_cast<void **>(&result));