科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件利用MFC实现浏览器的定制与扩展

利用MFC实现浏览器的定制与扩展

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

由于本人在开发中经常要在程序中嵌入浏览器,为了符合自己的需求经常要对浏览器进行扩展和定制。

作者:李汉鹏 来源:VCKBASE 2007年10月19日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
定制消息框的标题

  我们在脚本中调用alert弹出消息框时,消息框的标题是微软预定义的“Microsoft Internet Explorer”,如下图:

  在自定义的控制站点类中实现IDocHostShowUI接口,在接口的ShowMessage方法中调用浏览器的OnShowMessage,我们重载 OnShowMessage虚函数即可定制消息框的标题,实现代码如下:
// 窗口标题"Microsoft Internet Explorer"的资源标识 
#define IDS_MESSAGE_BOX_TITLE 2213 
HRESULT CLhpHtmlView::OnShowMessage(HWND hwnd, 
                                    LPOLESTR lpstrText, 
                                    LPOLESTR lpstrCaption, 
                                    DWORD dwType, 
                                    LPOLESTR lpstrHelpFile, 
                                    DWORD dwHelpContext, 
                                    LRESULT * plResult) 
{ 
    //载入Shdoclc.dll 和IE消息框标题字符串 
    HINSTANCE hinstSHDOCLC = LoadLibrary(TEXT("SHDOCLC.DLL")); 
    if (hinstSHDOCLC == NULL) 
        return S_FALSE; 

 CString strBuf,strCaption(lpstrCaption); 
 strBuf.LoadString(hinstSHDOCLC, IDS_MESSAGE_BOX_TITLE); 

    // 比较IE消息框标题字符串和lpstrCaption 
    // 如果相同,用自定义标题替换 
 if(strBuf==lpstrCaption) 
        strCaption = m_DefaultMsgBoxTitle; 

    // 创建自己的消息框并且显示 
    *plResult = MessageBox(CString(lpstrText), strCaption, dwType); 

    //卸载Shdoclc.dll并且返回 
    FreeLibrary(hinstSHDOCLC); 
    return S_OK; 
}  
从代码中可以看到通过设定m_DefaultMsgBoxTitle的值来改变消息宽的标题,修改此值是同过SetDefaultMsgBoxTitle来实现
void CLhpHtmlView::SetDefaultMsgBoxTitle(CString strTitle) 
{ 
 m_DefaultMsgBoxTitle=strTitle; 
} 
  怎样定制、修改浏览器向Web服务器发送的HTTP请求头

  在集成了WebBrowser控件的应用中,Web服务器有时可能希望客户端(浏览器)发送的HTTP请求中附带一些额外的信息或自定义的 HTTP头字段,这样就必须在浏览器中控制向Web服务器发送的HTTP请求。 下面是捕获的一个普通的用浏览器发送的HTTP请求头:
GET /text7.htm HTTP/1.0 
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, \ 
application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */* 
Referer: http://localhost 
Accept-Language: en-us 
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; Poco 0.31; LHP Browser 1.01; \ 
.NET CLR 1.1.4322) 
Host: localhost 
Connection: Keep-Alive 

CHtmlView的  
void Navigate2( 
   LPCTSTR lpszURL, 
   DWORD dwFlags = 0, 
   LPCTSTR lpszTargetFrameName = NULL, 
   LPCTSTR lpszHeaders = NULL, 
   LPVOID lpvPostData = NULL, 
   DWORD dwPostDataLen = 0  
); 
  函数参数lpszHeaders可以指定HTTP请求头,示例如下:
Navigate2(_T("http://localhost"),NULL,NULL, "MyDefineField: TestValue"); 
  我们捕获的HTTP头如下:


  怎样修改浏览器标识

  在HTTP请求头中User-Agent字段表明了浏览器的版本以及操作系统的版本等信息。WEB服务器经常需要知道用户请求页面时是来自IE还是来自自己的客户端中的WebBrowser控件, 以便分开处理,而WebBrowser控件向WEB服务器发送的浏览器标识(User-Agent字段)跟用IE发送的是一样的,怎样区分自己的浏览器和IE呢? 微软没有提供现成的方法,要自己想法解决。 前面讨论的定制HTTP请求头就是为这一节准备的。 思路是这样的: 在自己的浏览器里处理每一个U页面请求,把请求头User-Agent改成自己想要的。 在CHtmlView的OnBeforeNavigate2虚函数里来修改HTTP请求是再好不过了,
#define WM_NVTO  (WM_USER+1000) 

class NvToParam 
{ 
public: 
 CString URL; 
 DWORD Flags; 
 CString TargetFrameName; 
 CByteArray PostedData; 
 CString Headers; 
}; 


void CDemoView::OnBeforeNavigate2(LPCTSTR lpszURL,  
                                  DWORD nFlags,  
                                  LPCTSTR lpszTargetFrameName,  
                                  CByteArray& baPostedData,  
                                  LPCTSTR lpszHeaders,  
                                  BOOL* pbCancel) 
{ 
 CString strHeaders(lpszHeaders); 
 if(strHeaders.Find("User-Agent:LHPBrowser 1.0") < 0)// 检查头里有没有自定义的User-Agent串 
 { 
  *pbCancel = TRUE;// 没有,取消这次导航 

  if(!strHeaders.IsEmpty()) 
   strHeaders += "\r\n"; 
  strHeaders += "User-Agent:LHPBrowser 1.0";// 加上自定义的User-Agent串 

  NvToParam* pNvTo = new NvToParam; 
  pNvTo->URL = lpszURL; 
  pNvTo->Flags = nFlags; 
  pNvTo->TargetFrameName = lpszTargetFrameName; 
  baPostedData.Copy(pNvTo->PostedData); 
  pNvTo->Headers = strHeaders; 

  // 发送一个自定义的导航消息,并把参数发过去 
  PostMessage(WM_NVTO,(WPARAM)pNvTo); 
  return; 
 } 

 CHtmlView::OnBeforeNavigate2(lpszURL,  
                              nFlags,  
                              lpszTargetFrameName,  
                              baPostedData,  
                              lpszHeaders,  
                              pbCancel); 
} 

LRESULT CDemoView::OnNvTo(WPARAM wParam, LPARAM lParam) 
{ 
 NvToParam* pNvTo = (NvToParam*)wParam; 
 Navigate2((LPCTSTR)pNvTo->URL,  
            pNvTo->Flags,  
            pNvTo->PostedData,  
            (LPCTSTR)pNvTo->TargetFrameName,  
            (LPCTSTR)pNvTo->Headers); 
 delete pNvTo; 
 return 1; 
} 
  在OnBeforeNavigate2中如果发现没有自定义的User-Agent串,就加上这个串,并取消本次导航,再Post一个消息(一定要POST,让OnBeforeNavigate2跳出以后再进行导航 ),在消息中再次导航,再次导航时请求头已经有了自己的标识,所以能正常的导航。
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章