在资源管理器左窗格上两次调用Windows 7外壳扩展dll Initialize方法
Windows 7 - Shell Extension dll Initialize method called twice on explorer left pane
我有一个c++外壳扩展dll。如果我单击资源管理器窗口左窗格树视图文件夹,则会调用Initialize方法两次。但是,如果我单击资源管理器窗口右窗格上的任何文件夹,Initialize方法就会调用一次。
问题是,如果我单击左窗格树视图,我新添加的菜单项会在上下文菜单中显示两次。
我想知道,这是一个窗口功能吗?我已经评论了我的所有实现,并用以下代码进行了测试:
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的输出是:
初始化
查询上下文菜单
初始化
查询上下文菜单
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}'
}
}
}
上面的注册表项导致了Win7中的这个问题,如果我删除"NoRemove Background",上下文菜单将在树视图中显示一次。但如果我点击文件夹空白区域,初始化方法将不会被调用。
我发布了一个来自真实程序的工作示例(为了清晰起见,省略了特定于应用程序的代码)。请试试。
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 );
}
相关文章:
- Active Directory:从网络服务帐户下运行的Windows服务调用ADsOpenObject时失败
- 如何从Windows控制台调用.exe(C++)以在不同的目录(或任何目录)中创建文件夹?
- 意外的 IConnectionPointImpl::不建议调用 Windows Embedded Compact 7
- 如何链接 DLL 以供 LoadLibrary() 使用(在 Windows 上的 C++ 中)并从调用 exe 导入变
- 程序在对mouse_event的 Windows API 调用中冻结
- Windows 是否可以调用静态库中的 WinMain 函数C++
- 从 dll 调用 opencv 垫到 Windows 表单,图像出现故障
- 从 Python 调用 Windows DLL 函数时出错
- 从 C# Windows 应用程序调用 C dll 会导致 svchost.exe 崩溃
- 如何监视应用程序进行的Windows系统API调用?
- Windows 生成文件 (名称) - 语法错误: 宏调用中缺少")"
- 如何在Windows中使用FindNextFile调用来列出目录内容?
- 错误:没有匹配的成员函数调用 'upper_bound' =>仅在 macOS 上 => Windows 和 Linux 都很好
- 何时调用 Windows 控制台应用程序需要 CoInitialize
- Windows 生物识别服务在调用 WinBioCaptureSample 时循环运行 SensorAdapterSta
- 在 Windows 启动时调用应用程序时无法正常启动
- 从 Windows KMD 调用用户空间 API 函数
- Windows的WGET忽略了使用CreateProcess()调用选项
- 调用C++dll的C#dll在windows 10上找不到该dll
- 如何在Windows调用的DLL和主应用程序之间进行通信