现在的位置: 首页 > 综合 > 正文

Keep Passing the Open Windows

2013年10月29日 ⁄ 综合 ⁄ 共 4215字 ⁄ 字号 评论关闭

I  am  developing  a  custom  browser  using  the  Microsoft  Foundation  Class  (MFC)  CHtmlView  class.  I  want  to  make  all  windows  open  within  my  custom  browser,  and  not  in  Microsoft  Internet  Explorer.  
 
Dhiren  Vyas  
 
The  Web  Team  replies:  
 
As  you  probably  already  know,  developing  your  own  custom  browser  gives  you  complete  control  over  your  user  interface  whilst  making  use  of  the  incredible  technology  that  Internet  Explorer  has  to  offer.  You  get  to  choose  what  your  browser  looks  like  and  what  it  can  do  for  your  customers.  Microsoft  Visual  C++  makes  this  task  even  easier  by  providing  an  MFC  class,  CHtmlView,  that  implements  a  view  based  on  the  WebBrowser  control—a  reusable  component  of  Internet  Explorer.  
 
There  are  obstacles,  though.  When  a  Web  page  opens  a  window  (by  calling  window.open,  for  example)  an  Internet  Explorer  object  is  created.  This  means  that  the  Web  page  will  appear  in  an  Internet  Explorer  window.  If  you  want  all  windows  to  appear  in  your  application,  you  can  use  the  NewWindow2  event,  available  on  the  DWebBrowserEvents2  interface.  We'll  demonstrate  how  this  event  can  be  used  in  a  multiple  document  interface  (MDI)  MFC  application.  We'll  be  brief  because  this  subject  is  covered  in  detail  in  the  Knowledge  Base  article  HOWTO:  Use  the  WebBrowser  Control  NewWindow2  Event  (Q184876).  
 
First  let's  create  an  MDI  MFC  application  using  the  AppWizard.  During  the  final  page  of  the  wizard,  select  a  view  class  that  is  derived  from  CHtmlView.  Then  use  the  ClassWizard  to  add  an  event  handler  for  the  NewWindow2  event.  Finally,  add  code  to  your  NewWindow2  event  handler  function:  
 
void  CMyHtmlView::OnNewWindow2(LPDISPATCH*  ppDisp,  BOOL*  Cancel)    
{  
     //  Get  a  pointer  to  the  application  object.  
     CWinApp*  pApp  =  AfxGetApp();  
 
     //  Get  the  correct  document  template.  
     POSITION  pos  =  pApp->GetFirstDocTemplatePosition();  
     CDocTemplate*  pDocTemplate  =  pApp->GetNextDocTemplate(  pos  );  
 
     //  Create  a  new  frame.  
     CFrameWnd*  pFrame  =  pDocTemplate->CreateNewFrame(  
                                                                                   GetDocument(),  
                                                                                   (CFrameWnd*)AfxGetMainWnd()  );  
 
     //  Activate  the  frame.  
     pDocTemplate->InitialUpdateFrame(  pFrame,  NULL  );  
     CNewWindow2View*  pView  =  (CNewWindow2View*)pFrame->GetActiveView();  
 
     //  Pass  pointer  of  WebBrowser  object.  
     pView->SetRegisterAsBrowser(  TRUE  );  
     *ppDisp  =  pView->GetApplication();        
}  
 
Navigate  to  a  Web  page  that  opens  a  new  window  and  you'll  see  the  Web  page  displayed  in  your  application.  This  works  because  your  application  intercepts  the  NewWindow2  event,  creates  a  new  document/frame/view  combination,  and  passes  the  IDispatch  for  the  WebBrowser  object.  This  causes  your  CHtmlView-derived  class  to  be  used  to  display  the  Web  page.  Note  that  the  WebBrowser  object  must  be  created  each  time  and  not  have  navigated  to  a  URL,  or  this  won’t  work.  
 
You'll  probably  want  to  make  this  more  useful  by  obtaining  the  window  information,  such  as  the  height  and  width,  so  that  you  can  modify  your  view  accordingly.  A  simple  approach  to  this  is  to  handle  the  BeforeNavigate2  event  that  is  fired  after  the  new  window  is  created.  Add  the  following  code  to  your  application  to  resize  the  view  to  the  size  of  the  new  window.  Note  that  this  is  an  overridden  method  that  allows  access  to  the  WebBrowser  object,  and  that  an  additional  Boolean  member,  m_bResizeWindow,  is  required.  Set  this  to  false  in  the  constructor  and  true  in  the  NewWindow2  event  handler  to  ensure  this  code  is  only  called  for  new  windows.  
 
void  CMyHtmlView::BeforeNavigate2(LPDISPATCH  pDisp,  VARIANT*  URL,  
           VARIANT*  Flags,  VARIANT*  TargetFrameName,  
           VARIANT*  PostData,  VARIANT*  Headers,  BOOL*  Cancel)  
{  
     if  (  m_bResizeWindow  )  
     {  
     IWebBrowser2*      pWB  =  NULL;  
 
           //  QI  the  dispatch  for  WebBrowser  control.  
           HRESULT  hr  =  pDisp->QueryInterface(  IID_IWebBrowser2,  
                                                                                   (void**)pWB  );  
           if  (  SUCCEEDED(hr)  )  
           {  
           long  x,y;  
 
                 //  Get  dimensions.  
                 pWB->get_Width(  x  );  
                 pWB->get_Height(  y  );  
 
                 //  Resize  frame.  
                 SetScrollSizes(  MM_TEXT,  CSize(x,y)  );  
                 ResizeParentToFit();  
                 pWB->Release();  
           }  
           m_bResizeWindow  =  false;  
     }  
}  

抱歉!评论已关闭.