I have a c++ shell extension dll. The Initialize method is called twice, if I click on the explorer window left pane tree view folders. But if I click any folders on the explorer window right pane, the Initialize method called once.
The issue is my newly added menu items shows twice in the context menu, if I click on the left pane tree view.
I am wondering, is it a window functionality? I have commented all my implementation and tested with the below code:
IFACEMETHODIMP CMyContextMenu::QueryContextMenu(HMENU hmenu, UINT /*uIndex*/, UINT cmdFirst, UINT /*uidCmdLast*/, UINT /*uFlags*/ )
{
UINT cmdId = uidCmdFirst;
OutputDebugString(L"QueryContextMenu");
return MAKE_HRESULT ( SEVERITY_SUCCESS, FACILITY_NULL, cmdId - mdFirst );
}
IFACEMETHODIMP CMyContextMenu::Initialize(LPCITEMIDLIST pidlFolder, LPDATAOBJECT pDO, HKEY /*hkeyProgID*/)
{
OutputDebugString(L"Initialize");
return S_OK;
}
When I click on left pane, the DebugViewr output is:
Initialize
QueryContextMenu
Initialize
QueryContextMenu
NoRemove Directory
{
NoRemove Background
{
NoRemove ShellEx
{
NoRemove ContextMenuHandlers
{
ForceRemove myContext = s '{AE843198-3C5D-4EA6-B74F-7A41FC91D7FF}'
}
}
}
}
NoRemove Directory
{
NoRemove ShellEx
{
NoRemove ContextMenuHandlers
{
ForceRemove myContext = s '{AE843198-3C5D-4EA6-B74F-7A41FC91D7FF}'
}
}
}
The above registry entry is causing this issue in Win 7, If I remove "NoRemove Background", the context menu will be displayed once in tree view. But if I click on folder empty area Initialize method will not be invoked.
I am posting a working example from my real program (an application specific code omitted for clarity). Please try it.
STDMETHODIMP CShlExtExample::Initialize (
LPCITEMIDLIST pidlFolder, LPDATAOBJECT pDataObj, HKEY hProgID )
{
FORMATETC fmt = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
STGMEDIUM stg = { TYMED_HGLOBAL };
HDROP hDrop;
// Look for CF_HDROP data in the data object.
if ( FAILED( pDataObj->GetData ( &fmt, &stg ) ))
{
// Return an "invalid argument" error.
return E_INVALIDARG;
}
// Get a pointer to the actual data.
hDrop = (HDROP) GlobalLock ( stg.hGlobal );
if ( NULL == hDrop )
return E_INVALIDARG;
// Make sure there is at least one file to show menu for.
UINT uNumFiles = DragQueryFile ( hDrop, 0xFFFFFFFF, NULL, 0 );
HRESULT hr = S_OK;
if ( 0 == uNumFiles )
{
GlobalUnlock ( stg.hGlobal );
ReleaseStgMedium ( &stg );
return E_INVALIDARG;
}
// Application specific code.
GlobalUnlock ( stg.hGlobal );
ReleaseStgMedium ( &stg );
return hr;
}
STDMETHODIMP CShlExtExample::QueryContextMenu (
HMENU hmenu, UINT uMenuIndex, UINT uidFirstCmd,
UINT uidLastCmd, UINT uFlags )
{
// If the flags include CMF_DEFAULTONLY then do nothing.
if ( uFlags & CMF_DEFAULTONLY )
return MAKE_HRESULT ( SEVERITY_SUCCESS, FACILITY_NULL, 0 );
InsertMenu ( hmenu, uMenuIndex, MF_BYPOSITION, uidFirstCmd, _T("Test Item") );
return MAKE_HRESULT ( SEVERITY_SUCCESS, FACILITY_NULL, 1 );
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.