在您的 WebBrowser 中调用隐藏命令






4.77/5 (15投票s)
2004 年 9 月 12 日
2分钟阅读

137191

2281
演示了一种创新的方法来调用隐藏命令,以在你的基于 WebBrowser 的应用程序中显示模态对话框,例如“添加到收藏夹”对话框,“导入/导出向导”对话框。
引言
通常,当在 MFC 应用程序中宿主 WebBrowser 控件时,我们会调用 `m_pBrowserApp` ( `IWebBrowser2` 接口) 的 `ExecWB` 方法来调用常见的 web 浏览器命令 (缩放浏览器,选择浏览器中的所有文本等)。
我们还调用 `queryInterface` 来获取 `IOleCommandTarget` 接口的 `IDispatch` 指针,并调用它的 `Exec` 方法来调用“在此页面中查找”对话框或“查看源代码”命令。但是仍然存在一些我们**无法**调用的对话框,即“**添加到收藏夹**”对话框,“**导入/导出向导**”对话框。虽然我们可以通过 `IShellUIHelper` 接口调用“AddFavorite”命令和“ImportExportFavorites”命令,但前一个命令会导致一个与应用程序主框架无关的非模态“添加到收藏夹”对话框,而后一个命令的结果非常简单。
本文将介绍一种创新但简单的方法,在你的 web 浏览器中调用**模态**“添加到收藏夹”对话框和**模态**“导入/导出向导”对话框。
背景
这个想法来自 MSDN 中“**WebBrowser 定制**”的 `IDocHostUIHandler::ShowContextMenu` 演示。 `IDocHostUIHandler::ShowContextMenu` 演示向我们展示了从相关资源文件 "SHDOCLC.DLL" 手动构建 IE 上下文菜单并从中删除“**查看源代码**”的方法。代码的关键点是弹出上下文菜单后,它调用 `SendMessage()` API,通过 `WM_COMMAND` 消息将 `TrackPopupMenu()` 返回的 **MenuItem ID** 发送到“**Internet Explorer_Server**”窗口。因此,如果我们获取“添加到收藏夹”命令或“导入/导出向导”命令的 MenuItem ID,我们或许可以解决上述问题。
...... // Show shortcut menu int iSelection = ::TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, ppt->x, ppt->y, 0, hwnd, (RECT*)NULL); // Send selected shortcut menu item command to shell LRESULT lr = ::SendMessage(hwnd, WM_COMMAND, iSelection, NULL); ......
使用代码
一些命令消息由“**Internet Explorer_Server**”窗口处理,而另一些命令消息由其父“**Shell DocObject View**”窗口处理。因此,首先要从你的 `CHtmlView` 中获取这两个窗口的窗口句柄。为了简化解决方案,我从 Paul DiLascia 那里借用了下面可爱的 `CFindWnd` 类。
//////////////////////////////////////////////////////////////// // MSDN Magazine -- August 2003 // If this code works, it was written by Paul DiLascia. // If not, I don't know who wrote it. // Compiles with Visual Studio .NET on Windows XP. Tab size=3. // // --- // This class encapsulates the process of finding a window with a given class name // as a descendant of a given window. To use it, instantiate like so: // // CFindWnd fw(hwndParent,classname); // // fw.m_hWnd will be the HWND of the desired window, if found. // class CFindWnd { private: ////////////////// // This private function is used with EnumChildWindows to find the child // with a given class name. Returns FALSE if found (to stop enumerating). // static BOOL CALLBACK FindChildClassHwnd(HWND hwndParent, LPARAM lParam) { CFindWnd *pfw = (CFindWnd*)lParam; HWND hwnd = FindWindowEx(hwndParent, NULL, pfw->m_classname, NULL); if (hwnd) { pfw->m_hWnd = hwnd; // found: save it return FALSE; // stop enumerating } EnumChildWindows(hwndParent, FindChildClassHwnd, lParam); // recurse return TRUE; // keep looking } public: LPCSTR m_classname; // class name to look for HWND m_hWnd; // HWND if found // ctor does the work--just instantiate and go CFindWnd(HWND hwndParent, LPCSTR classname) : m_hWnd(NULL), m_classname(classname) { FindChildClassHwnd(hwndParent, (LPARAM)this); } }; void CDemoView::InvokeShellDocObjCommand(int nID) { CFindWnd FindIEWnd( m_wndBrowser.m_hWnd, "Shell DocObject View"); ::SendMessage( FindIEWnd.m_hWnd, WM_COMMAND, MAKEWPARAM(LOWORD(nID), 0x0), 0 ); } void CDemoView::InvokeIEServerCommand(int nID) { CFindWnd FindIEWnd( m_wndBrowser.m_hWnd, "Internet Explorer_Server"); ::SendMessage( FindIEWnd.m_hWnd, WM_COMMAND, MAKEWPARAM(LOWORD(nID), 0x0), 0 ); }
由“Internet Explorer_Server”窗口处理的命令 ID
#define ID_IE_CONTEXTMENU_ADDFAV 2261 #define ID_IE_CONTEXTMENU_VIEWSOURCE 2139 #define ID_IE_CONTEXTMENU_REFRESH 6042
由“Shell DocObject View”窗口处理的命令 ID
#define ID_IE_FILE_SAVEAS 258 #define ID_IE_FILE_PAGESETUP 259 #define ID_IE_FILE_PRINT 260 #define ID_IE_FILE_NEWWINDOW 275 #define ID_IE_FILE_PRINTPREVIEW 277 #define ID_IE_FILE_NEWMAIL 279 #define ID_IE_FILE_SENDDESKTOPSHORTCUT 284 #define ID_IE_HELP_ABOUTIE 336 #define ID_IE_HELP_HELPINDEX 337 #define ID_IE_HELP_WEBTUTORIAL 338 #define ID_IE_HELP_FREESTUFF 341 #define ID_IE_HELP_PRODUCTUPDATE 342 #define ID_IE_HELP_FAQ 343 #define ID_IE_HELP_ONLINESUPPORT 344 #define ID_IE_HELP_FEEDBACK 345 #define ID_IE_HELP_BESTPAGE 346 #define ID_IE_HELP_SEARCHWEB 347 #define ID_IE_HELP_MSHOME 348 #define ID_IE_HELP_VISITINTERNET 349 #define ID_IE_HELP_STARTPAGE 350 #define ID_IE_FILE_IMPORTEXPORT 374 #define ID_IE_FILE_ADDTRUST 376 #define ID_IE_FILE_ADDLOCAL 377 #define ID_IE_FILE_NEWPUBLISHINFO 387 #define ID_IE_FILE_NEWCORRESPONDENT 390 #define ID_IE_FILE_NEWCALL 395 #define ID_IE_HELP_NETSCAPEUSER 351 #define ID_IE_HELP_ENHANCEDSECURITY 375
以下代码演示了如何调用**模态“添加到收藏夹”对话框**。
void CDemoView::OnFavAddtofav()
{
InvokeIEServerCommand(ID_IE_CONTEXTMENU_ADDFAV);
}
关注点
你知道,整夜工作,最终找到答案。我称之为幸福!