分享
 
 
 

屏蔽CHtmlView\WebBrower控件右键菜单技巧合集

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

0.本文代码下载(http://skinart.y365.com/csdn/htmlcontextmenu.zip)(代码只是做演示用,没有做什么错误检查,请注意)

1.常被人鄙视的方法(PreTranslateMessage)

经常见到有人问怎么屏蔽html的右键菜单,有人答用PreTranslateMessage函数拦截wm_rbuttondown消息,于是总会有人说这种方法怎么烂,@_@,我真不知道为什么,不过我想这也是一种方法呀,而且非常简单,所以还是列出来吧:)

BOOL CPreTranslateMsgView::PreTranslateMessage(MSG* pMsg)

{

if ((pMsg->message == WM_RBUTTONDOWN)||(pMsg->message == WM_RBUTTONDBLCLK)){

CPoint point(pMsg->pt);

ScreenToClient(&point);

IHTMLDocument2* pdoc2=NULL;

IHTMLElement* pElement=NULL;

IDispatch* pDisp=NULL;

pDisp=GetHtmlDocument();

pDisp->QueryInterface(IID_IHTMLDocument2,(void**)&pdoc2);

pDisp->Release();

pdoc2->elementFromPoint(point.x,point.y,&pElement);

pdoc2->Release();

if(pElement){

BSTR ID;

pElement->get_id(&ID);

pElement->Release();

CString str=(LPCTSTR)(_bstr_t)ID;

if(str=="Layer1"){

CMenu menu;

menu.LoadMenu(IDR_MENU1 );

CMenu* pmenu=menu.GetSubMenu(0);

pmenu->TrackPopupMenu(0,pMsg->pt.x,pMsg->pt.y,this);

}

}

return TRUE;//如果想完全屏蔽掉,不显示任何菜单,直接返回TRUE就行,上面这些代码演示了怎么对html中特定ID的元素弹出自己想要显示的菜单

}else

return CHtmlView::PreTranslateMessage(pMsg);

}

2.通过子类化IE控件的窗口并处理WM_CONTEXTMENU消息

这是MSDN上介绍的方法,111222翻译了那文章,大家自己去看:

屏蔽CHtmlView\CWebBrower2右键菜单的非官方方法 111222(翻译)。

http://www.csdn.net/develop/Read_Article.asp?Id=10427

3.利用IDocHostUIHandler接口(官方提供的方法)

VC.net中的CDHtmlDialog就是这种方法了,想自己实现的可以参考这篇文章:

在对话框中显示网页,并屏蔽掉IE的弹出式菜单 wuya(原作)

http://www.csdn.net/develop/Read_Article.asp?Id=8813

4.利用COM的连接点机制,直接处理html元素的事件

我们先看看在VB中想屏蔽掉右键菜单是怎么做的:

Dim WithEvents m_doc As HTMLDocument

Private Function m_doc_oncontextmenu() As Boolean

m_doc_oncontextmenu = False

End Function

Private Sub WebBrowser1_DownloadComplete()

Set m_doc = WebBrowser1.Document

End Sub

呵呵,非常简单吧?处理HTMLDocument的oncontextmenu事件,视具体需要弹出自己的菜单,然后返回true或false就可以了。

同理,我们在VC中如果能响应html页面元素对象的事件并做出处理的话也可以达到屏蔽右键菜单的目的了,在VB中响应COM的事件被封装起来,用一个WithEvents关键字就轻松搞定,在VC中怎么实现??

我们知道COM是通过连接点机制来实现事件的,VC中你得在程序中实现一个特定的接口,并把这个接口的指针通过一定的途径传送给COM对象并通知它需要订阅该对象的消息。

下面通过处理HTMLDocument2的oncontextmenu事件来演示具体怎么在MFC程序中实现屏蔽掉右键菜单,同理你可以处理其它的像DIV,Button等元素的事件来制定相应的右键菜单。

通过查阅MSDN,可以知道要响应HTMLDocument2的事件必须在程序中实现HTMLDocumentEvents2接口,这个接口是Dispinterface类型的,而在MFC想实现一个IDispatch接口就简单的就是从CCmdTarget类派生一个新类并用DECLARE_DISPATCH_MAP,BEGIN_DISPATCH_MAP,DISP_FUNCTION_ID,END_DISPATCH_MAP等宏来添加接口函数,由于CHtmlView或是CDialog都是间接派生自CCmdTarget的,所以直接在这些类上实现这个接口就可以了,以对话框加IE控件为例(稍微改动可用于CHtmlView),实现如下:

1.新建基于对话框工程命名为HtmlDemoDialog,在主对话框中加入Microsoft Web Browser控件并生成包装类等。

2.在主对话框类头文件CHtmlDemoDialogDlg.h中加入

#include <MsHTML.h>//定义了IHTMLDocument2等接口

#include <mshtmdid.h>//定义了HTMLDocumentEvents2接口的方法DISPID

class CCHtmlDemoDialogDlg : public CDialog

{

...

DECLARE_DISPATCH_MAP()//声明dispatch map表

public:

BOOL onHtmlContextMenu(IHTMLEventObj *pEvtObj);

//事件处理函数,原型可以参考MSDN中关于HTMLDocumentEvents2的说明

DWORD m_dwCookie;

//用于标记一个连接点

IHTMLDocument2* pDoc2;

//想要处理事件的COM对象的指针

...

}

2.在对话框类实现文件CHtmlDemoDialogDlg.cpp中加入

#include <afxctl.h>//定义了AfxConnectionAdvise、AfxConnectionUnadvise等函数,等会连接到事件源时要用到

...

//填充dispatch map表,以供Invoke()调用

BEGIN_DISPATCH_MAP(CCHtmlDemoDialogDlg, CDialog)

DISP_FUNCTION_ID(CCHtmlDemoDialogDlg, "oncontextmenu", DISPID_HTMLDOCUMENTEVENTS2_ONCONTEXTMENU, onHtmlContextMenu, VT_BOOL, VTS_DISPATCH)

END_DISPATCH_MAP()

...

CWebbrowserDlg::CWebbrowserDlg(CWnd* pParent /*=NULL*/)

: CDialog(CWebbrowserDlg::IDD, pParent)

{

EnableAutomation();//必须有,否则等会用GetIDispatch()时会失败.

...

}

BOOL CCHtmlDemoDialogDlg::onHtmlContextMenu(IHTMLEventObj *pEvtObj)

{

//在成功连接上事件源后,每次用户右击都会调用这个函数,你可以根据pEvtObj来判断当前光标位置等,然后决定是自己弹出菜单,让IE弹出菜单,还是什么都不做...

return FALSE;

}

void CCHtmlDemoDialogDlg::OnDocumentCompleteExplorer1(LPDISPATCH pDisp, VARIANT FAR* URL)

{

//处理WebBrowser控件的DocumentComplete事件,并初始化pDoc2指针和连接到事件源

HRESULT hr=m_wb.GetDocument()->QueryInterface(IID_IHTMLDocument2,(void**)&pDoc2);

BOOL Ret = AfxConnectionAdvise(

pDoc2, //可连接对象的接口指针

DIID_HTMLDocumentEvents2, //连接接口ID

GetIDispatch(FALSE), //把内嵌的IDispatch实现类的一个对象实例m_xDispatch传了出去

FALSE, //donod addref

&m_dwCookie ); //cookie to break connection later...

if(Ret){

AfxMessageBox("成功挂接上");

}

}

3.到这里,基本步骤都以完成,运行后如果没有什么灾难发生的话可以看到"成功挂接上"的消息框,并且在IE控件中点击右键不会弹出菜单,断开事件连接的代码如下:

AfxConnectionUnadvise(pDoc2,

DIID_HTMLDocumentEvents2 ,

GetIDispatch(FALSE),

FALSE,

m_dwCookie );

其余的善后工作交给你去处理了.

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有