我有一个c++外壳扩展dll。如果单击资源管理器窗口左侧窗格树视图文件夹,则将调用两次初始化方法。但是,如果我单击资源管理器窗口右侧窗格中的任何文件夹,则初始化方法调用一次。
问题是,如果单击左侧窗格树视图,新添加的菜单项将在上下文菜单中显示两次。
我在想,这是一个窗口功能吗?我已经对所有实现进行了注释,并使用以下代码进行了测试:
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;
}当我单击左窗格时,DebugViewr输出是:
初始化
QueryContextMenu
初始化
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}'
}
}
}上面的注册表项在Win 7中导致了这个问题,如果我删除"NoRemove背景“,上下文菜单将在树视图中显示一次。但是,如果我单击文件夹,空区域初始化方法将不会被调用。
发布于 2012-03-27 22:18:08
我正在发布一个实际程序中的工作示例(为了清晰起见,省略了一个特定于应用程序的代码)。请试试看。
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 );
}https://stackoverflow.com/questions/9893036
复制相似问题