【发布时间】:2020-03-03 10:40:58
【问题描述】:
所以我会继续回到 CodeProject 上的这篇文章:
https://www.codeproject.com/Articles/4758/How-to-customize-the-context-menus-of-a-WebBrowser
然后我意识到文章顶部的这句话:
修改后的示例项目使用了一种新的更好的自定义方法,本文的下一次更新将全面讨论这种方法,希望在几周内准备就绪。我正在发布这个半文档化且未经过全面测试的代码,因为我有迹象表明一些开发人员可能需要比我下一次更新的那一天更早地拥有这个代码。对于每个修改后的示例,还有一个 Readme.htm 文件,简要描述了示例的工作原理。
我以为我很难理解文章 sn-ps 与下载源代码中的代码!所以我读了自述文件,上面写着:
在 MFC 7 中,
CHtmlView嵌入了对IDocHostUIHandler的支持,因此我只需重写CHtmlView::OnShowContextMenu方法,然后调用::CustomShowContextMenu()函数(在CustomMenus.cpp 中),其工作原理如第5 节所述我原来的文章。
所以,我决定在我的项目中添加自己的函数覆盖:
HRESULT CChristianLifeMinistryHtmlView::OnShowContextMenu(DWORD dwID, LPPOINT ppt,
LPUNKNOWN pcmdtReserved, LPDISPATCH pdispReserved)
{
return CustomContextMenu(ppt, pcmdtReserved);
}
并且我添加了类似的自定义菜单功能:
HRESULT CustomContextMenu(POINT* ppt, IUnknown* pcmdtReserved)
{
IOleWindow* oleWnd = NULL;
HWND hwnd = NULL;
HMENU hMainMenu = NULL;
HMENU hPopupMenu = NULL;
HRESULT hr = 0;
INT iSelection = 0;
if ((ppt == NULL) || (pcmdtReserved == NULL))
goto error;
hr = pcmdtReserved->QueryInterface(IID_IOleWindow, (void**)&oleWnd);
if ((hr != S_OK) || (oleWnd == NULL))
goto error;
hr = oleWnd->GetWindow(&hwnd);
if ((hr != S_OK) || (hwnd == NULL))
goto error;
hMainMenu = LoadMenu(AfxGetInstanceHandle(),
MAKEINTRESOURCE(IDR_MENU_HTML_POPUP));
if (hMainMenu == NULL)
goto error;
hPopupMenu = GetSubMenu(hMainMenu, 0);
if (hPopupMenu == NULL)
goto error;
// Show shortcut menu
iSelection = ::TrackPopupMenu(hPopupMenu,
TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,
ppt->x,
ppt->y,
0,
hwnd,
(RECT*)NULL);
// Send selected shortcut menu item command to shell
if (iSelection != 0)
(void) ::SendMessage(hwnd, WM_COMMAND, iSelection, NULL);
error:
if (hMainMenu != NULL)
::DestroyMenu(hMainMenu);
return S_OK;
}
最后,我添加了一个菜单资源:
IDR_MENU_HTML_POPUP MENU
BEGIN
POPUP "CustomPopup"
BEGIN
MENUITEM "View Source", 2139
MENUITEM SEPARATOR
MENUITEM "Select All", 31
END
END
菜单 ID 值基于 IDM_ 版本,它们都有效。
然后我尝试使用我自己的事件处理程序将我自己的菜单项添加到该列表中,它显示为禁用。
难道不能在CHtmlView上下文菜单中添加我们自己的菜单项吗?
我想添加我自己的菜单项“打印预览”,然后它只是向我的父“编辑器”发布一条消息,以模拟在那里单击“打印预览”。但似乎任何添加到此菜单的自定义项始终是灰色的。
如果我添加一个“打印预览”菜单项并将其值设为 2003(IDM_PRINTPREVIEW),它只会触发原始打印预览机制。而且我不能将我自己的事件处理程序添加到我的CChristianLifeMinistryHtmlView 类中,因为它不被尊重。
我发现这个article 提到:
如果您选择用自己的菜单替换标准菜单,您可以 仍然将菜单扩展附加到您的自定义菜单。只需包括一个 菜单定义中的空白
IDM_MENUEXT_PLACEHOLDER菜单选项 指示要插入自定义命令的位置。菜单扩展 在此占位符之前插入。您也可以添加自己的 通过插入菜单选项自定义命令到标准菜单 在IDM_MENUEXT_PLACEHOLDER之前,如下例所示。#define IDM_MENUEXT_PLACEHOLDER 6047 // If the placeholder is gone or was never there, then just exit if (GetMenuState(hMenu, IDM_MENUEXT_PLACEHOLDER, MF_BYCOMMAND) != (UINT) -1) { InsertMenu(hMenu, // The Context Menu IDM_MENUEXT_PLACEHOLDER, // The item to insert before MF_BYCOMMAND|MF_STRING, // by item ID and str value IDM_MENUEXT_FIRST__ + nExtCur, // the command ID (LPTSTR)aOpts[nExtCur].pstrText);// The menu command text // Remove placeholder DeleteMenu(hMenu, IDM_MENUEXT_PLACEHOLDER, MF_BYCOMMAND); }扩展的菜单 ID 介于
IDM_MENUEXT_FIRST__和IDM_MENUEXT_LAST__之间,最多 33 个自定义 命令。
我知道我设计的不对,但我为占位符添加了一个菜单项,然后为打印预览添加了另一个菜单项 ID 为 IDM_MENUEXT_FIRST__。然后我向它添加了一个菜单处理程序。菜单项不再被禁用,这很好。但是点击它什么也没做。
这个问题涉及到:
更新
我想我已经找到了解决办法,很快就会给出答案。
【问题讨论】:
标签: c++ mfc webbrowser-control