IContextMenu3 HandleMenuMsg2 从未被调用
我正在尝试实现一个扩展 IContextMenu3
和 IShellExtInit
的 shell 扩展,并且我正在使用 HBMMENU_CALLBACK 方法 但在我的项目中方法 HandleMenuMsg2 或
HandleMenuMsg
永远不会被调用。
谁能解释一下接收 HandleMenuMsg2
调用需要什么?
我的 ATL 对象是这样实现的:
// CTestPlugin
class ATL_NO_VTABLE CTestPlugin :
public CComObjectRootEx<CComMultiThreadModel>,
public CComCoClass<CTestPlugin, &CLSID_CTestPlugin>,
public IShellExtInit,
public IContextMenu3
{
public:
CTestPlugin();
~CTestPlugin();
HRESULT FinalConstruct();
void FinalRelease();
public:
DECLARE_REGISTRY_RESOURCEID(IDR_TESTPLUGIN)
DECLARE_NOT_AGGREGATABLE(CTestPlugin)
BEGIN_COM_MAP(CTestPlugin)
COM_INTERFACE_ENTRY(IShellExtInit)
COM_INTERFACE_ENTRY(IContextMenu)
COM_INTERFACE_ENTRY(IContextMenu2)
COM_INTERFACE_ENTRY(IContextMenu3)
END_COM_MAP()
DECLARE_PROTECT_FINAL_CONSTRUCT()
...
// IShellExtInit
STDMETHODIMP Initialize(LPCITEMIDLIST, LPDATAOBJECT, HKEY);
// IContextMenu
STDMETHODIMP GetCommandString(UINT, UINT, UINT*, LPSTR, UINT)
{ return S_OK; }
STDMETHODIMP InvokeCommand(LPCMINVOKECOMMANDINFO);
STDMETHODIMP QueryContextMenu(HMENU, UINT, UINT, UINT, UINT);
// IContextMenu2
STDMETHODIMP HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam);
// IContextMenu3
STDMETHODIMP HandleMenuMsg2(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pResult);
我正在插入菜单项,如 nanoANT 页面中所述:
bool CTestPlugin::AddNewMenuItem(HMENU hmenu, UINT un_menu_text_id, UINT un_menu_index, UINT icon, UINT& uCmdID)
{
TCHAR chText[MAX_PATH];
::LoadString(
_AtlModule.m_hResInstance,
un_menu_text_id,
chText,
MAX_PATH);
MENUITEMINFO menuiteminfo;
ZeroMemory(&menuiteminfo, sizeof(menuiteminfo));
menuiteminfo.cbSize = sizeof(menuiteminfo);
menuiteminfo.fMask = MIIM_FTYPE | MIIM_ID | MIIM_SUBMENU | MIIM_DATA | MIIM_BITMAP | MIIM_STRING;
menuiteminfo.fType = MFT_STRING;
menuiteminfo.dwTypeData = chText;
menuiteminfo.cch = _tcslen(chText);
if (icon) {
menuiteminfo.hbmpItem =
SysInfo::Instance().IsVistaOrLater()
?
_AtlModule.m_iconBitmapUtils.IconToBitmapPARGB32(_AtlModule.m_hResInstance, icon)
:
HBMMENU_CALLBACK;
}
menuiteminfo.wID = (UINT)uCmdID++;
m_mapIdToIcon[menuiteminfo.wID] = icon;
return (TRUE==InsertMenuItem(hmenu, un_menu_index, TRUE, &menuiteminfo));
}
STDMETHODIMP CTestPlugin::HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LRESULT res;
return HandleMenuMsg2(uMsg, wParam, lParam, &res);
}
STDMETHODIMP CTestPlugin::HandleMenuMsg2(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pResult)
{
...
}
有了所有这些,菜单项就会出现在资源管理器上下文菜单中,但不会显示图像,两种方法 HandleMenuMsg
和HandleMenuMsg2
从未被调用,我正在测试的系统是 WinXP(在 vista 中一切正常,因为我们使用 hbmpItem
)。
我缺少一些初始化还是什么?谁能给我解释一下吗?
谢谢
I'm trying to implement a shell extension that extends IContextMenu3
and IShellExtInit
, and i'm inserting menu items using the method described in section HBMMENU_CALLBACK method but in my project the method HandleMenuMsg2
or the HandleMenuMsg
is never called.
Can anyone please explain me what is required to receive the HandleMenuMsg2
calls?
My ATL object is implemented like that:
// CTestPlugin
class ATL_NO_VTABLE CTestPlugin :
public CComObjectRootEx<CComMultiThreadModel>,
public CComCoClass<CTestPlugin, &CLSID_CTestPlugin>,
public IShellExtInit,
public IContextMenu3
{
public:
CTestPlugin();
~CTestPlugin();
HRESULT FinalConstruct();
void FinalRelease();
public:
DECLARE_REGISTRY_RESOURCEID(IDR_TESTPLUGIN)
DECLARE_NOT_AGGREGATABLE(CTestPlugin)
BEGIN_COM_MAP(CTestPlugin)
COM_INTERFACE_ENTRY(IShellExtInit)
COM_INTERFACE_ENTRY(IContextMenu)
COM_INTERFACE_ENTRY(IContextMenu2)
COM_INTERFACE_ENTRY(IContextMenu3)
END_COM_MAP()
DECLARE_PROTECT_FINAL_CONSTRUCT()
...
// IShellExtInit
STDMETHODIMP Initialize(LPCITEMIDLIST, LPDATAOBJECT, HKEY);
// IContextMenu
STDMETHODIMP GetCommandString(UINT, UINT, UINT*, LPSTR, UINT)
{ return S_OK; }
STDMETHODIMP InvokeCommand(LPCMINVOKECOMMANDINFO);
STDMETHODIMP QueryContextMenu(HMENU, UINT, UINT, UINT, UINT);
// IContextMenu2
STDMETHODIMP HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam);
// IContextMenu3
STDMETHODIMP HandleMenuMsg2(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pResult);
And i'm inserting menu items like described in the nanoANT page:
bool CTestPlugin::AddNewMenuItem(HMENU hmenu, UINT un_menu_text_id, UINT un_menu_index, UINT icon, UINT& uCmdID)
{
TCHAR chText[MAX_PATH];
::LoadString(
_AtlModule.m_hResInstance,
un_menu_text_id,
chText,
MAX_PATH);
MENUITEMINFO menuiteminfo;
ZeroMemory(&menuiteminfo, sizeof(menuiteminfo));
menuiteminfo.cbSize = sizeof(menuiteminfo);
menuiteminfo.fMask = MIIM_FTYPE | MIIM_ID | MIIM_SUBMENU | MIIM_DATA | MIIM_BITMAP | MIIM_STRING;
menuiteminfo.fType = MFT_STRING;
menuiteminfo.dwTypeData = chText;
menuiteminfo.cch = _tcslen(chText);
if (icon) {
menuiteminfo.hbmpItem =
SysInfo::Instance().IsVistaOrLater()
?
_AtlModule.m_iconBitmapUtils.IconToBitmapPARGB32(_AtlModule.m_hResInstance, icon)
:
HBMMENU_CALLBACK;
}
menuiteminfo.wID = (UINT)uCmdID++;
m_mapIdToIcon[menuiteminfo.wID] = icon;
return (TRUE==InsertMenuItem(hmenu, un_menu_index, TRUE, &menuiteminfo));
}
STDMETHODIMP CTestPlugin::HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LRESULT res;
return HandleMenuMsg2(uMsg, wParam, lParam, &res);
}
STDMETHODIMP CTestPlugin::HandleMenuMsg2(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pResult)
{
...
}
With all this the menu entries apear in explorer context menu but no images are displayed, both methods HandleMenuMsg
and HandleMenuMsg2
are never called, and the system that i'm testing is WinXP (in vista all is ok because we use the hbmpItem
).
I'm missing some inicialization or what? can anyone explain me?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我今天正好在研究这个问题,并遇到了你的问题。当我使用纯 WinAPI 时,我不确定 MFC 语义,但我最好的猜测是您的
QueryInterface()
可能不处理对 IContextMenu3 接口的请求。(尽管您可能很久以前就解决了这个问题。不过,其他人可能会发现了解这个问题很有用。)
I happen to have been working on this today, and ran across your question. As I use pure WinAPI, I am not sure about the MFC semantics, but my best guess is that your
QueryInterface()
probably does not handle a request for the IContextMenu3 interface.(Although you probably solved this problem a long time ago. Still, others might find a use to knowing.)
fmask 指定您要插入的项目类型。在该行中,您说该项目是位图字符串子菜单。
另外,您指定 MIIM_DATA 但不设置
dwMenuData
。The fmask specifies what type of item you are inserting. On that line you say that the item is a bitmap string submenu.
Also, you specify MIIM_DATA but dont set
dwMenuData
.