note|note : DuiDesigner 添加的 WebBrowser 网页被打开后不能控制网页行为
今天在对DuiLib显示嵌入网页编码, 想屏蔽内嵌网页的右键菜单, 网上查到的方法, 和手头Demo的方法大体一致, 比较简洁.
但是我这一直不行,找了一下午..., 这是咋了.
手头还有一个Demo是OK的, 下午没找出来,是哪有不同,引起网页不能被控制.
看来看去,不是代码写的有问题.
开始比对使用内嵌网页的对话框加载的skin.xml有啥不同, 这回看出不同了,做了个试验,定位并修复了此问题
用 DuiDesigner 添加的浏览器控件如下:
【note|note : DuiDesigner 添加的 WebBrowser 网页被打开后不能控制网页行为】
必须手工改为如下, 主要是控件类名必须是 "WebBrowser", CLSID用设计器填写的是对的
改完后, 在DuiDesigner 中看到是如下样子
文章图片
如果我们用DuiDesigner插入一个网页浏览器控件,就达不到手工修改的效果.
因为手工在设计器中插入一个控件时, 控件的控件类名称"WebBrowser"根本没有输入的地方.
即使CLSID输入对了, 控件类名还是"ActiveX"
就是这个原因导致网页加载后,不受控制.
将查到的资料整理后, 屏蔽内嵌网页右键菜单的代码片段如下:
从CWebBrowserEventHandler继承一个类,当一个内嵌页面被导航前, 设置该网页的事件捕获器.
/// @fileWebBrowserEventHandlerEx.h
/// @brief接住网页事件#ifndef __WEB_BROWSER_EVENT_HANDLER_EX_H__
#define __WEB_BROWSER_EVENT_HANDLER_EX_H__class CWebBrowserEventHandlerEx :
public CWebBrowserEventHandler
{
public:
CWebBrowserEventHandlerEx(void);
virtual ~CWebBrowserEventHandlerEx(void);
virtual void NavigateComplete2(IDispatch *pDisp, VARIANT *&url);
virtual void BeforeNavigate2(
IDispatch * pDisp,
VARIANT *& url,
VARIANT *& Flags,
VARIANT *& TargetFrameName,
VARIANT *& PostData,
VARIANT *& Headers,
VARIANT_BOOL *& Cancel);
virtual void ProgressChange(LONG nProgress, LONG nProgressMax);
virtual HRESULT STDMETHODCALLTYPE GetHostInfo(DOCHOSTUIINFO __RPC_FAR *pInfo);
virtual HRESULT STDMETHODCALLTYPE GetExternal(IDispatch __RPC_FAR *__RPC_FAR *ppDispatch);
virtual HRESULT STDMETHODCALLTYPE ShowContextMenu(
DWORD dwID,
POINT __RPC_FAR *ppt,
IUnknown __RPC_FAR *pcmdtReserved,
IDispatch __RPC_FAR *pdispReserved);
private:
IDispatch * m_pDisp;
};
#endif // #ifndef __WEB_BROWSER_EVENT_HANDLER_EX_H__
//
void CMainDlg::InitWindow()
{
UiInit();
///< we call Ui control on InitWindow better than other position
}void CMainDlg::UiInit()
{
/// ...
/// 内嵌网页的控件用Xml设计器添加后,必须手工修改如下, 否则控制不了网页的行为
/// original :
/// now : /// #define ELEMENT_ACTIVEX_WEB_PAGE L"ActiveX_WebPage"
/// CWebBrowserUI * m_pActivexWebPage
m_pActivexWebPage= static_cast(m_PaintManager.FindControl(ELEMENT_ACTIVEX_WEB_PAGE));
/// CTabLayoutUI * m_pTabView
/// get m_pTabView too
/// .../// CWebBrowserEventHandlerEx * m_pWebEventHandler
m_pWebEventHandler = new CWebBrowserEventHandlerEx();
/// 网上资料说: 第一次使用CWebBrowserUI时, 要先导航到空白页, 再导航到目标页,
/// 才能使事件捕捉器生效.
/// 从试验结果看, 确实这样, 只有同一控件, 第二次加载网页时, 修改的网页事件才生效
WebBrowserInit(m_pActivexWebPage);
/// #define URL_BLANK_PAGEL"about:blank"
//WebBrowserNavigate(m_pActivexWebPage, URL_BLANK_PAGE);
WebBrowserNavigate(m_pActivexWebPage, GetUrl());
///< GetUrl() get our url want show/// 如果有多个内嵌网页躲在一个Tab页中, 需要切换到被加载的网页, 让她show出来
m_pTabView->SelectItem(m_pActivexWebPage);
}BOOL CMainDlg::WebBrowserInit(CWebBrowserUI * pActivexUi)
{
BOOL bRc = FALSE;
if (NULL == pActivexUi)
return FALSE;
pActivexUi->SetDelayCreate(false);
/// 本来用的就是系统的WebBrowser控件, 不能再创建控件了, 否则报错
/// 这样起来的内嵌网页, 一定是IE了
// return (true == pActivexUi->CreateControl(CLSID_WebBrowser));
return TRUE;
}BOOL CMainDlg::WebBrowserNavigate(CWebBrowserUI * pActivexUi, WCHAR * pcUrl)
{
IWebBrowser2 * pWebBrowser = NULL;
if ((NULL == pActivexUi) || (NULL == pcUrl))
return FALSE;
pActivexUi->GetControl(IID_IWebBrowser2, (void**)&pWebBrowser);
if (NULL == pWebBrowser)
return FALSE;
/// @todo 传进自己的 CWebBrowserEventHandler *, 是否多个网页可以公用一个事件捕捉器 ?
/// 初步试验结果看来是可以的, 要区分是哪个内嵌网页, 没做试验呢
/// 如果每个内嵌网页都单独对应一个CWebBrowserEventHandler *, 是最简单的
pActivexUi->SetWebBrowserEventHandler(m_pWebEventHandler);
///< 设置网页的事件捕获器
pWebBrowser->Navigate(_bstr_t(pcUrl), NULL, NULL, NULL, NULL);
pWebBrowser->Release();
}//
推荐阅读
- 编写字典程序
- 怎么将桌面上的CAD图纸添加到软件中进行BMP格式转换()
- 2147483647与int型
- 怎样把一个字典的数据添加到另一个字典中()
- 培养习惯的倦怠期可以添加变化~74
- 如何在Kubernetes|如何在Kubernetes 里添加自定义的 API 对象(一)
- Checked#15:|Checked#15: Evernote 真的要被替代了么()
- Ubuntu|Ubuntu 下添加开机启动脚本
- 如何把excel导入endnote
- Android|Android Room 的坑