您的位置:首页 > 其它

VS2008 CWebBrowser2 屏蔽右键 去掉3D边框 去掉滚动条

2012-02-20 02:02 330 查看
目前手上的项目是VS2008的,要用到WebBrowser控件。以前虽然有接触过WebBrowser控件,但是由于没有动手做过,所以,在这次使用的时候,仍然是遇到了一些问题。



首先,在往窗口中添加WebBrowser控件时就遇到了问题:

VS2008 跟 VC6 不同:

VC6 中,直接拖到窗口中的 WebBrowser 控件对应的就是 CWebBrowser2 类,并会自动添加响应文件到项目中。

VS2008 中,浏览器控件对应的是CExporler1类,并且,在拖入该控件后,没有与之对应的.h/.cpp文件添加到项目中。

所以,我们的操作如下:

1. CWebBrowser2.h 和 CWebBrowser2.cpp 是通过 “项目->添加->类->MFC->ActicX控件中的MFC类” 添加到项目中的。

2. 控件添加:资源->右键->添加ActiveX控件->选择浏览器控件

3. 在资源中添加了浏览器控件后,通过手动添加代码,将CWebBrowser2变量和控件关联起来。

eg:DDX_Control(pDX, IDC_EXPLORER_MINIIE,m_MyIE);



在对控件的位置等进行另外一系列的设置后,链接一个URL,发现了一些小问题,就是:如何才能屏蔽右键,去掉滚动条,去掉3D边框??

答案就是:IE控件定制UI 。



IE控件定制UI的相关接口:IDocHostUIHandler ,IDocHostShowUI ,IOleCommandTarget

IDocHostUIHandler :定制浏览器界面有关的行为。定制 the menus, toolbars, and context menus used by MSHTML 。

IDocHostShowUI :提供 机制/途径 显示 message boxes and Help (就是进行对话框等的拦截)。

IOleCommandTarget :enables objects and their containers to dispatch commands to each other (宿主和控件之间按键的信息传递)。

除了上述之外还有:IDispatch(作用:)



为了解决我的问题,新建一个类来定制浏览器控件的UI。这个类需要继承自IDocHostUIHandler ,并实现IDocHostUIHandler 的接口(“实现接口”意味着QueryInterface、AddRef、Release三个方法必须实现)。

eg:class CMyWebBrowserActiveXFuncUI:public IDocHostUIHandler {......};



IDocHostUIHandler 的接口,我们必须要全部重写,不过我们不需要修改的就直接 return E_NOTIMPL;代表我们不做任何操作;否则就是 使用我们自定义的UI ,然后 return S_OK; return S_OK的话,相应的系统项就不会再进行了。



与我们的问题紧要相关的就是“宿主信息标记”,什么是“宿主信息标记”呢

“宿主信息标记”用N个标记位来控制浏览器的许多性质,如:

· 禁用浏览器的3D的边缘;

· 禁止滚动条;

· 禁用脚本;

· 定义双击处理的方式;

· 禁用浏览器的自动完成功能;

  Eg. 要使网页元素不能被选中做法是:给浏览器的“宿主信息标记”加上DOCHOSTUIFLAG_DIALOG标记......
(更多详情请参考MSDN的DOCHOSTUIFLAG帮助)

  

怎样修改“宿主信息标记”?

 在我们的类中实现IDocHostUIHandler的GetHostInfo方法,在这个方法中可指定“宿主信息标记”,如:

STDMETHODIMP GetHostInfo(DOCHOSTUIINFO
FAR *pInfo)

{

if(!pInfo) return E_INVALIDARG;

pInfo->cbSize = sizeof(DOCHOSTUIINFO);

pInfo->dwFlags = DOCHOSTUIFLAG_NO3DBORDER

|
DOCHOSTUIFLAG_DISABLE_HELP_MENU

|
DOCHOSTUIFLAG_DIALOG

|DOCHOSTUIFLAG_SCROLL_NO;

pInfo->dwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT;

return S_OK;

}



除此之外,与菜单相关的还有 ShowContextMenu
方法:

STDMETHODIMP ShowContextMenu(DWORD
dwID, POINT FAR* ppt,IUnknown FAR* pcmdtReserved,IDispatch FAR* pdispReserved)

{

// return E_NOTIMPL; //返回 E_NOTIMPL 正常弹出系统右键菜单

HRESULT hRet = S_OK; //返回S_OK 则可屏蔽系统右键菜单



return
hRet;

}



如何把我们的类跟浏览器控件连接起来呢??

答案:通过ICustomDoc来关联IDocHostUIHandler。

新写个类继承IDocHostUIHandler ,然后在浏览器事件中通过 ICustomDoc::SetUIHandler 进行挂载(在事件OnBeforeNavigate2Explorer1(...)或OnNavigateComplete2Explorer1(...)中执行
,可参看:【Delphi】如何挂上IDocHostUIHandler接口实现 道理是相同的)。



:CHtmlView不需要这个操作,CHtmlView的定制都是采用CHtmlView的派生类,扩展或定制都将在派生类上实现。(不过,SetUIHandler是在DocumentComplete的处理里面调用的,所以,更改的特性需要在这之前就处理)





通过上述修改,我们成功屏蔽了右键菜单,但是滚动条和3D边框都还是存在的,这可是为什么呢?明明在 GetHostInfo
中已经进行了设置了呀??...不知道...



好吧,我们换个角度换个方法,百度到:

这两个小问题, 写出代码要几百行, 只能简单地说:

1.3D边, 归IDocHostUIHandler::GetHostInfo(...)管, 有个FLAG, 叫DOCHOSTUIFLAG_NO3DBORDER;

2.滚动条归网页管, 从Document
(IHTMLDocument2...)入手



.....这.....,那好,先修改滚动条吧....

在包含浏览器控件的容器中,响应浏览器控件的
DocumentCompleteExplorer事件:

#include
<mshtml.h>

void CMyWebShow::DocumentCompleteExplorerMiniie(LPDISPATCH pDisp, VARIANT* URL)

{

// TODO: 在此处添加消息处理程序代码

HRESULT
hr;

//IDispatch *pDisp = this->m_Web2.GetDocument();

pDisp = this->m_MyIE.get_Document(); // MyIE 就是你的IE控件生成的对象

IHTMLDocument2 *pDocument = NULL;

IHTMLElement* pEl;

IHTMLBodyElement * pBodyEl;

hr = pDisp->QueryInterface(IID_IHTMLDocument2, (void**)&pDocument);

if(SUCCEEDED(pDocument->get_body(&pEl)))

{

if(SUCCEEDED(pEl->QueryInterface(IID_IHTMLBodyElement, (void**)&pBodyEl)))

{

pBodyEl->put_scroll(L"no"); //去滚动条(网页中滚动条设置为no 那么不管IE窗口与网页是否匹配 都不会显示滚动条)

}

IHTMLStyle *phtmlStyle;

pEl->get_style(&phtmlStyle);

if(phtmlStyle !=
NULL)

{

phtmlStyle->put_overflow(L"hidden");

phtmlStyle->put_border(L"none"); //去除边网页边框

phtmlStyle->Release();

pEl->Release();

}

}



}



事实证明,上面的操作确实解决了滚动体条的问题。



那3D边框呢?

我试了修改浏览器控件的属性(CWND层的WM_BOND属性),没有效果。

在进行消除滚动条操作时,顺便把网页层次的边框消除了。但出来的效果依然是有3D边框的。

为什么我的设置回事无效的呢??

得到解决方法:

第一次打开网页,会因为DOCUMNET()得到空而没起作用,程序起来后就让控件浏览一个 about:blank 页来屏蔽这问题

结果:解决了3D边框的问题.....(不明白为什么)。



那,解决了3D边框的问题,是不是也解决了原先的滚动条的问题了呢??

经过试验,答案是肯定的。

在添加了“about:balnk”之后,GetHostInfo
中的设置都起作用了,没了边框,没了滚动条,没了右键响应。


这是为什么呢?????





另:控件本身没有集成地址栏

一般都是用个editctrl来做成地址栏,获取用户输入后,用浏览器控件进行链接。

转帖:http://blog.sina.com.cn/s/blog_4b3c1f950102dtqs.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: