| V_VT(&var2) = VT_I4; V_I4(&var2) = dwID; hr = spCT->Exec(&CGID_ShellDocView, SHDVID_ADDMENUEXTENSIONS, 0, &var1, &var2); // Remove View Source DeleteMenu(hMenu, IDM_VIEWSOURCE, MF_BYCOMMAND);//删除“查看源文件”菜单项 // Show shortcut menu int iSelection = ::TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,//返回用户选择的菜单命令ID 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进行内部处理。 FreeLibrary(hinstSHDOCLC); return S_OK; } |
从上面的例子我们看出,基本的方法就是根据“shdoclc.dll”文件中的菜单资源建立菜单,再通过来自pcmdTarget的IOlcCommandTarget接口获得“编码”菜单以及HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt下的定义扩展菜单,然后以TPM_RETURNCMD标志调用TrackPopupMenu或TrackPopupMenuEx弹出菜单,并将返回的菜单命令ID教给浏览器窗口进行处理。这种方法可以调用许多通过浏览器无法直接调用的命令和对话框(参阅:《Internet Explorer 编程简述(五)调用IE隐藏的命令》)。 所以,我们只需要在弹出菜单之前做一些自定义操作即可达到修改默认菜单的目的,如上面代码中就用删除了“查看源文件”菜单项。 2)问题 如果我们不仅仅是删除默认的菜单项或是修改了默认的菜单项,还添加了自己的菜单项,会出现什么情况呢?由于使用了类似于MFC中UpdateUI的机制,遇到不认识的CommandID,浏览器就会将其状态设置为Disabled,所以我们自己添加的菜单是无法被选择的。 可以想到,如果把菜单状态设置为Enabled,并通过TPM_RETURNCMD标志调用TrackPopupMenu或TrackPopupMenuEx,再把返回的命令ID教给合适的窗口(如主框架窗口)去处理不就行了。关键点就在于如何把菜单状态设置为Enabled。 3)实现 解决的办法是截获WM_INITMENUPOPUP消息,在菜单创建以后,尚未显示之前修改菜单项状态,那浏览器就没有办法了。截获WM_INITMENUPOPUP消息则可使用子类化(subclass)的技术,前面通过IOleWindow接口我们得到了浏览器窗口的句柄hwnd,则可以这样做:
| HMENU g_hPubMenu = NULL; WNDPROC g_lpPrevWndProc = NULL; LRESULT CALLBACK CustomMenuWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (uMsg == WM_INITMENUPOPUP) { | 系列文章:Internet Explorer编程简述(一) (二) (三) (四) (五) (六)
|