急急!!在CHtmlView的右键菜单上加上我的菜单

icecore 2000-06-03 11:08:00
小弟正在做的一个项目要求在CMyView:public CHtmlView所已经支持的右键菜单上加上几项我的菜单.
我本来在CMyView中对WM_INITMENUPOPUP进行拦截,发现程序流程根本未到这里.
进一步发现在CMyView中对WM_RBUTTONUP和WM_CONTEXTMENU进行拦截,程序流程均未到这里.
(spy++证实这三个message均发到了一个Internet Explorer_Server对象,应该是他拦截了
这些message,我估计他是IWebBrowser2接口的COM 对象.)
各位快救小弟,另外最好不要是操纵注册表的方法,因为我要加入的是动态信息.
如果大哥你知道操纵注册表去实现的方法,也请告之.
icecore 急急急!!!十万火急!
...全文
208 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
vcmfc 2000-12-06
  • 打赏
  • 举报
回复
关注!
icecore 2000-06-08
  • 打赏
  • 举报
回复
就这个问题,MicroSoft官方站点的说法是:
A common requirement of hosting the WebBrowser control is the ability to override or add to the context menus that are displayed as the result of a right-click in the browser window. This is of particular interest to applications that are using the WebBrowser control to view rich content but do not want the user to know that HTML is being viewed. This is also advantageous for applications that do not want the user to be able to view the HTML source for the content.
There are two techniques available to achieve this. The first involves the use of the IDocHostUIHandler interface and allows an application to disable or replace the context menus. The second technique involves the use of the registry and allows the existing context menus to be extended.
From Topic:"Browser Overview" Web Workshop provided
CCustomControlSite::XDocHostUIHandler::ShowContextMenu method Called from MSHTML to display a context menu.
From Q236312
具体涉及的600多行代码还只是能做到在CHtmlView中不显示IE的快捷菜单,离我的要求还差很多。这里我也证实了IE既不是把菜单定义放在注册表中,也不是我设想的另一种方法。方法很复杂的。而且,我在我的Win95+IE4.0+VC6.0+ 401comupd平台上,实做了一下,竟然是无效页面错。MicroSoft的示例平台是WinNT。
就这个问题,我的做法是:
你有没有用过NetAnts,他实现了将固定的菜单项加到IE的快捷菜单上(我正是了解了NetAnts的做法后,才在MicroSoft官方站点上得到详细的文档的)。
我查了一下注册表,在
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuEx下NetAnts加了两个主键,比如一个是Download &All by NetAnts。在HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt\Download &All by NetAnts
下的一个字符串表明"c:\PROGRA~1\NETANTS\NAGetAll.htm",IE将加载NAGetAll.htm,但不会显示该文件 (MicroSoft的文档中说是将该文件加载到一个隐藏的对话框中) 。下面列出NAGetAll.htm:
<script language="VBScript">
On Error Resume Next
set NetAntsApi = CreateObject( "NetAnts.API" )
if err<>0 then
Alert("NetAnts not properly installed on this PC!")
else
set links = external.menuArguments.document.links
ReDim params(links.length*2)
params(0)=external.menuArguments.document.Url
for i = 0 to links.length-1
params(i*2+1)=links(i).href
params(i*2+2)=links(i).innerText
next
NetAntsApi.AddUrlList params
end if
</script>
看过去就是生成对象,从网页里获得信息,调用方法。
我能不能采用类似的方法?我的项目是一个上下文无关文法的所有分析表的构造软件。我本来的想法是在IE的快捷菜单上加一项Popup的,他下面就列出所有的文法项目(MF_POPUP)和该文法的表项目(MF_STRING)。我实现了两个TabView,用户可能关掉TabView,所以我得在菜单里再列出所有的文法项目和该文法的表项目。我可以在框架的下拉菜单中列出,并不一定要在IE的快捷菜单上列出。但这样似乎我的软件连快捷菜单都没了(IE的明显不是我的)。
我现在的想法是在我的软件的客户端第一次启动时,操纵注册表,在里面加上一项:列出所有文法和表格(&L)。也启动一个.htm文件。在他里面也创建一个自动化对象RidIE,也调用一个方法MsgDispatch,这个方法也是启动GF(或则GF已经启动),再去得到GF的App对象,再就是在某一位置(或则当前的位置)TrackPopupMenu,因为有多少文法是无法事先得知的,所以不能用MFC的消息映射机制,
解决方法有两种。
一种是使用未公开的技术:
BOOL TrackPopupMenu(UINT nFlag,int x,int y,CWnd* pWnd,LPCRECT lpRect=NULL);
第一个未写入文档的特性是:该函数的第一个参数nFlag还可以取另外两个值:TPM_NONOTIFY与TPM_RETURNCMD。从它们的名字可以看出来,TPM_NONOTIFY的作用是使TrackPopupMenu函数不发送菜单消息通知应用程序。TPM_RETURNCMD的作用是使函数将本该发送出去的菜单消息作为返回值返回。这时函数的返回值是UINT类型的,就是选中的菜单ID。这就是该函数第二个未写入文档的特性。注意,这个技术将一直有效,因为在新的TrackPopupMenuEx函数中,该技术被公开了。
这样,不用担心什么用来接收菜单命令消息的窗口,我设为NULL。
方法MsgDispatch由主框架去得到两个TabView,再利用这一技术我可以在那个被IE间接调用的方法MsgDispatch中,根据TrackPopupMenu的返回值决定怎样去发消息给两个TabView,让他们负责去切换(参见TabView处)。
比如:返回值是IDM_GRAMMA+302,则就是TabViewG的第四项和TabViewI的第三项。
另一种解决方法是正规的:
就是去重载CMainFrame::OnCmdMsg(实际上是CcmdTarget的)。对ID大于IDM_GRAMMA的都处理(发消息给TabView),不处理的返回0。

我用spy程序看了一下,消息没有发到view窗口来,而且view窗口离
Internet Explorer_Server对象还有两级距离,我想还有一种可行的办法就是,先取到该窗口句柄,然后用子类化技术截取该消息。。而且所得到的效果是最理想的,和我的预计是一样的效果。我模拟在CMainFrame中截获WM_INITMENU,再InsertMenu了一项,非常好。实现起来,也是较容易的。正如你说的那样:从View到Internet Explorer_Server还有两级。我看了一下是ShellEmbedding和ShellDocObjectView。因此,我可以用SDK函数EnumChildWindows和回调函数EnumChildProc来得到Internet Explorer_Server的句柄,在EnumChildProc(第二次被调用)里完成子类化的工作。
MicroSoft官方意见效果不太好,又要了解IE的内部架构和一系列的接口,而且实现起来代码量很大(MicroSoft已经提供),奇怪的无效页面错。
Nothing is impossible in the digital world--OUR WORLD.
superbat 2000-06-05
  • 打赏
  • 举报
回复
guanzhu
icecore 2000-06-05
  • 打赏
  • 举报
回复
我搞定了,有三种方法。
有人想知道,说一下,我就贴出来。
(还有,我的帖子打错了,是对WM_INITMENU进行拦截,发现程序流程根本未到这里.
当然,其他的什么WM_INITMENUPOPUP,WM_CONTEXTMENU...也是一样。
icecore 2000-06-05
  • 打赏
  • 举报
回复
我搞定了,有三种方法。
有人想知道,说一下,我就贴出来。
我的帖子打错了,是WM_INITMENU。

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧