利用MFC实现浏览器的定制与扩展(4)(转帖)

来源:互联网 发布:网络云盘下载 编辑:程序博客网 时间:2024/05/19 06:46

 去掉讨厌的异常警告

  在程序中使用了CHtmlView以后,我们在调整窗口大小的时候经常会看到输出窗口输出的异常警告: ReusingBrowser.exe 中的 0x77e53887 处最可能的异常: Microsoft C++ exception: COleException @ 0x0012e348 。

Warning: constructing COleException, scode = DISP_E_MEMBERNOTFOUND($80020003). 

  这是由于CHtmlView在处理WM_SIZE消息时的一点小问题引起的,采用如下代码处理WM_SIZE消息就不会有此警告了

void CLhpHtmlView::OnSize(UINT nType, int cx, int cy) {  CFormView::OnSize(nType, cx, cy);  if (::IsWindow(m_wndBrowser.m_hWnd))   {    CRect rect;    GetClientRect(rect);    // 就这一句与CHtmlView的不同   ::AdjustWindowRectEx(rect, GetStyle(), FALSE, WS_EX_CLIENTEDGE);   m_wndBrowser.SetWindowPos(NULL,                              rect.left,                              rect.top,                              rect.Width(),                              rect.Height(),                              SWP_NOACTIVATE | SWP_NOZORDER);   }  } 


  怎样处理浏览器内的拖放


  有时可能有这样的需求,我们希望在资源管理器里托一个文件到浏览器而做出相应的处理,甚至是将文件拖到某一个网页元素上来做出相应的处理,而浏览器默认的处理拖放文件操作是将文件打开,但WebBrowser控件给了我们一个自己处理拖放的机会。 那就是在自定义的控制站点类中实现IDocHostUIHandler,在接口IDocHostUIHandler的GetDropTarget方法中调用 浏览器类的OnGetDropTarget虚函数。要处理网页内的拖放,必需在OnGetDropTarget函数中返回一个自己定义的IDropTarget接口指针, 所以我们自己写一个类CMyOleDropTarget从COleDropTarget类派生,并且在实现IDropTarget接口,此类的代码在这就不列出了,请下载演示 程序,参考文件MyOleDropTarget.h和MyOleDropTarget.cpp。我们看CLhpHtmlView中OnGetDropTarget的代码

HRESULT CLhpHtmlView::OnGetDropTarget(LPDROPTARGET pDropTarget, LPDROPTARGET* ppDropTarget ) {  m_DropTarget.SetIEDropTarget(pDropTarget);  LPDROPTARGET pMyDropTarget;  pMyDropTarget = (LPDROPTARGET)m_DropTarget.GetInterface(&IID_IDropTarget);  if(pMyDropTarget)  {   *ppDropTarget = pMyDropTarget;   pMyDropTarget->AddRef();   return S_OK;  }  return S_FALSE; } 

  m_DropTarget即为自定义的处理拖放的对象。这样就能通过在从CLhpHtmlView派生的类中重载OnDragEnter、OnDragOver、 OnDrop、OnDragLeave虚函数来处理拖放了。在这里顺带讲一下视图是怎样处理拖放的。 要使视图处理拖放,首先在视图里添加一个COleDropTarget(或派生类)成员变量,如CLhpHtmlView中的“CMyOleDropTarget m_DropTarget;”,再在 视图创建时调用COleDropTarget对象的ReGISter,即把视图与COleDropTarget对象关联起来,如CLhpHtmlView中的“m_DropTarget.Register(this);”,再对拖放 触发的事件进行相应的处理, OnDragEnter 把某对象拖入到视图时触发,在此检测拖入的对象是不是视图想接受的对象,如是返回“DROPEFFECT_MOVE”表示接受此对象,如

if(pDataObject->IsDataAvailable(CF_HDROP))// 被拖对象是文件吗?  return DROPEFFECT_MOVE; 

  OnDragOver 被拖对象在视图上移动,同OnDragEnter一样检测拖入对象,如果要接受此对象返回“DROPEFFECT_MOVE”。 OnDrop 拖着被拖对象在视图上放开鼠标,在这里对拖入对象做出处理; OnDragLeave 拖着被拖对象离开视图。 C++的代码写好了,但事情还没完,还必须在网页里用脚本对拖放事件进行处理, 即页面里哪个元素要接受拖放对象哪个元素就要处理ondragenter、ondragover、ondrop,代码其实很简单,让事件的返回值为false即可,这样 C++的代码才有机会处理拖放事件,代码如下:

...... <td ondragenter="event.returnValue = false" ondragover="event.returnValue = false" / ondrop="event.returnValue = false"> ...... 

  如果要使整个视图都接受拖放,则在Body元素中处理此三个事件。 注意:别忘了让工程对OLE的支持即在初始化应用程序时调用AfxOleInit()。

  怎样禁止网页元素的选取

  用网页做界面时多数情况下是不希望网页上的元素是能够被鼠标选中的, 要使网页元素不能被选中做法是:给浏览器的“宿主信息标记”加上DOCHOSTUIFLAG_DIALOG标记。

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

  • 禁用浏览器的3D的边缘;
  • 禁止滚动条;
  • 禁用脚本;
  • 定义双击处理的方式;
  • 禁用浏览器的自动完成功能;

  ...... 更多详情请参考MSDN的DOCHOSTUIFLAG帮助。

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

  在CDocHostSite中实现IDocHostUIHandler, 在GetHostInfo方法中调用浏览器的OnGetHostInfo虚函数,在虚函数OnGetHostInfo中便可指定“宿主信息标记”,如:

HRESULT CLhpHtmlView::OnGetHostInfo(DOCHOSTUIINFO * pInfo) {  pInfo->cbSize = sizeof(DOCHOSTUIINFO);  pInfo->dwFlags = DOCHOSTUIFLAG_DIALOG |                       DOCHOSTUIFLAG_THEME  |                       DOCHOSTUIFLAG_NO3DBORDER |                       DOCHOSTUIFLAG_SCROLL_NO;  pInfo->dwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT;  return S_OK; } 


  用脚本也可实现: 在Head中加入脚本:

document.onselectstart=new Function(’’return false’’); 


  或者

<body onselectstart="return false">。 

  其它

  在CLhpHtmlView中还提供了几个函数, 修改网页元素的内容:

BOOL PutElementHtml(CString ElemID,CString Html);
  取表单元素的值:
BOOL GetElementValue(CString ElemID,CString& Value); 


  设置表单元素的值:

BOOL PutElementValue(CString ElemID,CString Value); 


  给表单元素设置焦点:

void ElementSetFocus(CString EleName);

感谢作者 http://blog.xj163.cn/blog.php?do=showone&tid=60718

原创粉丝点击