IContextMenu3 HandleMenuMsg2 从未被调用

发布于 2024-08-13 08:50:11 字数 3238 浏览 11 评论 0原文

我正在尝试实现一个扩展 IContextMenu3IShellExtInit 的 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)
{
...
}

有了所有这些,菜单项就会出现在资源管理器上下文菜单中,但不会显示图像,两种方法 HandleMenuMsgHandleMenuMsg2 从未被调用,我正在测试的系统是 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

网白 2024-08-20 08:50:11

我今天正好在研究这个问题,并遇到了你的问题。当我使用纯 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.)

痴意少年 2024-08-20 08:50:11

menuiteminfo.fMask = MIIM_FTYPE | MIIM_ID | MIIM_SUBMENU | MIIM_SUBMENU MIIM_数据 | MIIM_BITMAP | MIIM_BITMAP | MIIM_STRING;

fmask 指定您要插入的项目类型。在该行中,您说该项目是位图字符串子菜单。

另外,您指定 MIIM_DATA 但不设置dwMenuData

menuiteminfo.fMask = MIIM_FTYPE | MIIM_ID | MIIM_SUBMENU | MIIM_DATA | MIIM_BITMAP | MIIM_STRING;

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文