王朝网络
分享
 
 
 

如何禁用HTML页面的上下文菜单

王朝vc·作者佚名  2006-01-17
宽屏版  字体: |||超大  

图一 不想要的上下文菜单

其实,要解决这个问题有一个非常简单的办法,真是易如反掌,甚至不用写任何C++代码!只要在HTML页面中加一行指令即可:

//

//

这条指令告诉浏览器不要显示上下文菜单。也可以象下面这样写:

//

oncontextmenu="ShowMyMenu(); return false"

//

ShowMyMenu是一个显示定制菜单的JavaScript过程。本文例子代码之一AboutHtml1使用的就是oncontextmenu。源代码可以从本文的开始处下载。

由于VC知识库是一个关于C++以及Visual C++的网站,与JavaScript之类的脚本语言没什么关系。所以我们要用另一种稍微复杂一点的方法来实现相同的事情,那就是用C++来做。为此,正规的C++方法是实现IDocHostUIHandler接口,而且要做的事情很多。至于为什么要实现它,请参见有关文档。用WM_CONTEXTMENU 或者 WM_RBUTTONDOWN来处理这个问题的思路的确是通常Windows做事情的方式。但是问题是CHtmlCtrl窗口不是真正的输入窗口。窗口有很多种,只要用Spy++工具看一下我们的例子程序就知道在你眼前会出现多少种窗口。如图二所示,在实际的输入窗口上,浏览器窗口有三级父/子窗口。

Dialog

AfxFrameOrView42d // CHtmlCtrl

Shell Embedding

Shell DocObject View

Internet Explorer_Server

它是个接收输入的Internet Explorer_Server服务器窗口,并且如果你想要截获WM_CONTEXTMENU消息,必须子类化这个窗口。在MFC中,这意味着你必须获取HWND并调用SubclassWindow。记住了,这是一种非常规方式,而且微软的那帮家伙也明确禁止这样做,不过我还是根据原来的程序写了另一个版本AboutHtml2,我这么做了。

图二在Spy++中的父/子关系

获得这个神秘的Internet Explorer_Server HWND的方法有很多种。但FindWindow不行,因为它只能得到顶层窗口。由于此服务器窗口是浏览器的曾孙(great-grandchild),在所有层次上都没有同胞兄弟,所以下列算法成立:

static HWND GetLastChild(HWND hwndParent)

{

HWND hwnd = hwndParent;

while (TRUE) {

HWND hwndChild = ::GetWindow(hwnd, GW_CHILD);

if (hwndChild==NULL)

return hwnd;

hwnd = hwndChild;

}

return NULL;

}

这个函数假设只有单子继承链,如同浏览器中的一个窗口——即每个父窗口肯定有一个子窗口——并且获取最末尾(或最小)的子窗口就是Internet Explorer_Server窗口。一旦取得HWND,剩下的事情便是写一个新的MFC类对它进行子类化。

class CMyIEWnd : public CWnd {

public:

afx_msg void OnContextMenu(CWnd* pWnd, CPoint pos) { }

DECLARE_MESSAGE_MAP();

};

这个类重载WM_CONTEXTMENU,其它什么事情也不做:OnContextMenu是个空函数,返回的东西不显示菜单,也不调用基类(CWnd)的方法。使用CMyIEWnd时,在CMyHtmlCtrl中添加一个实例:

//

class CMyHtmlCtrl : public CHtmlCtrl {

protected:

CMyIEWnd m_myIEWnd;

};

//

把这一切联系在一起的最关键的一步是调用SubclassWindow。但在哪里调用以及什么时候调用呢?最好时机是在浏览器加载页面之后。

void CMyHtmlCtrl::OnNavigateComplete2(LPCTSTR strURL)

{

if (!m_myIEWnd.m_hWnd) {

HWND hwnd = GetLastChild(m_hWnd);

m_myIEWnd.SubclassWindow(hwnd);

}

}

具体处理过程是这样的:当用户打开“关于”对话框,对话框创建CHtmlCtrl窗口来打开文档,当浏览器将文档打开以后,它发送一个通知,MFC将这个通知定向到OnNavigateComplete2。CMyHtmlCtrl::OnNavigateComplete2调用GetLastChild来获得“真正的”输入窗口并将它子类化。这时所有的消息将通过CMyIEWnd类去往Internet Explorer_Server,包括WM_CONTEXTMENU。这里要注意,IE的HWND是可以修改的,所以如果除了“关于”对话框外,你还想做一些其它的事情的话,必须要对HWND进行反子类化(unsubclass)和重子类化(resubclass)处理。

使用这个技术有两个重要事情需要注意。第一,它功能很强,因为你子类化了“真正的”IE窗口,你可以做几乎任何事情。第二,如果你不小心而使用不当,那将会发生最糟糕最糟糕的事情。一旦你用这种方法控制了资源管理器窗口,等于是把所有赌注放进去了。记住不要用不正当的方式去玩弄浏览器,而是要通过正式接口(IDocHostUIHandler)定制它!否则后果不堪设想。

相关文章:VC6中使用CHtmlView在对话框控制中显示HTML文件

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
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- 王朝网络 版权所有