1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/msw/webview_ie.cpp 
   3 // Purpose:     wxMSW wxWebViewIE class implementation for web view component 
   4 // Author:      Marianne Gagnon 
   6 // Copyright:   (c) 2010 Marianne Gagnon, 2011 Steven Lamerton 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  10 // For compilers that support precompilation, includes "wx.h". 
  11 #include "wx/wxprec.h" 
  13 #if defined(__BORLANDC__) 
  17 #include "wx/msw/webview_ie.h" 
  19 #if wxUSE_WEBVIEW && wxUSE_WEBVIEW_IE 
  26 #include "wx/msw/registry.h" 
  27 #include "wx/msw/missing.h" 
  28 #include "wx/filesys.h" 
  29 #include "wx/dynlib.h" 
  31 wxIMPLEMENT_DYNAMIC_CLASS(wxWebViewIE
, wxWebView
); 
  33 BEGIN_EVENT_TABLE(wxWebViewIE
, wxControl
) 
  34     EVT_ACTIVEX(wxID_ANY
, wxWebViewIE::onActiveXEvent
) 
  35     EVT_ERASE_BACKGROUND(wxWebViewIE::onEraseBg
) 
  38 bool wxWebViewIE::Create(wxWindow
* parent
, 
  46     if (!wxControl::Create(parent
, id
, pos
, size
, style
, 
  47                            wxDefaultValidator
, name
)) 
  54     m_historyLoadingFromList 
= false; 
  55     m_historyEnabled 
= true; 
  56     m_historyPosition 
= -1; 
  57     m_zoomType 
= wxWEB_VIEW_ZOOM_TYPE_TEXT
; 
  59     if (::CoCreateInstance(CLSID_WebBrowser
, NULL
, 
  60                            CLSCTX_INPROC_SERVER
, // CLSCTX_INPROC, 
  61                            IID_IWebBrowser2 
, (void**)&m_webBrowser
) != 0) 
  63         wxLogError("Failed to initialize IE, CoCreateInstance returned an error"); 
  67     m_ie
.SetDispatchPtr(m_webBrowser
); // wxAutomationObject will release itself 
  69     m_webBrowser
->put_RegisterAsBrowser(VARIANT_TRUE
); 
  70     m_webBrowser
->put_RegisterAsDropTarget(VARIANT_TRUE
); 
  72     m_container 
= new wxActiveXContainer(this, IID_IWebBrowser2
, m_webBrowser
); 
  74     SetBackgroundStyle(wxBG_STYLE_PAINT
); 
  75     SetDoubleBuffered(true); 
  80 wxWebViewIE::~wxWebViewIE() 
  82     for(unsigned int i 
= 0; i 
< m_factories
.size(); i
++) 
  84         m_factories
[i
]->Release(); 
  88 void wxWebViewIE::LoadURL(const wxString
& url
) 
  90     m_ie
.CallMethod("Navigate", (BSTR
) url
.wc_str()); 
  93 void wxWebViewIE::SetPage(const wxString
& html
, const wxString
& baseUrl
) 
  95     BSTR bstr 
= SysAllocString(html
.wc_str()); 
  97     // Creates a new one-dimensional array 
  98     SAFEARRAY 
*psaStrings 
= SafeArrayCreateVector(VT_VARIANT
, 0, 1); 
  99     if (psaStrings 
!= NULL
) 
 103         HRESULT hr 
= SafeArrayAccessData(psaStrings
, (LPVOID
*)¶m
); 
 105         param
->bstrVal 
= bstr
; 
 106         hr 
= SafeArrayUnaccessData(psaStrings
); 
 108         IHTMLDocument2
* document 
= GetDocument(); 
 109         document
->write(psaStrings
); 
 112         // SafeArrayDestroy calls SysFreeString for each BSTR 
 113         SafeArrayDestroy(psaStrings
); 
 115         //We send the events when we are done to mimic webkit 
 117         wxWebViewEvent 
event(wxEVT_COMMAND_WEB_VIEW_NAVIGATED
, 
 118                              GetId(), baseUrl
, ""); 
 119         event
.SetEventObject(this); 
 120         HandleWindowEvent(event
); 
 122         //Document complete event 
 123         event
.SetEventType(wxEVT_COMMAND_WEB_VIEW_LOADED
); 
 124         event
.SetEventObject(this); 
 125         HandleWindowEvent(event
); 
 129         wxLogError("wxWebViewIE::SetPage() : psaStrings is NULL"); 
 134 wxString 
wxWebViewIE::GetPageSource() const 
 136     IHTMLDocument2
* document 
= GetDocument(); 
 137     IHTMLElement 
*bodyTag 
= NULL
; 
 138     IHTMLElement 
*htmlTag 
= NULL
; 
 140     HRESULT hr 
= document
->get_body(&bodyTag
); 
 143         hr 
= bodyTag
->get_parentElement(&htmlTag
); 
 147             htmlTag
->get_outerHTML(&bstr
); 
 148             source 
= wxString(bstr
); 
 158 wxWebViewZoom 
wxWebViewIE::GetZoom() const 
 162         case wxWEB_VIEW_ZOOM_TYPE_LAYOUT
: 
 163             return GetIEOpticalZoom(); 
 164         case wxWEB_VIEW_ZOOM_TYPE_TEXT
: 
 165             return GetIETextZoom(); 
 170     //Dummy return to stop compiler warnings 
 171     return wxWEB_VIEW_ZOOM_MEDIUM
; 
 175 void wxWebViewIE::SetZoom(wxWebViewZoom zoom
) 
 179         case wxWEB_VIEW_ZOOM_TYPE_LAYOUT
: 
 180             SetIEOpticalZoom(zoom
); 
 182         case wxWEB_VIEW_ZOOM_TYPE_TEXT
: 
 190 void wxWebViewIE::SetIETextZoom(wxWebViewZoom level
) 
 192     //We do not use OLECMDID_OPTICAL_GETZOOMRANGE as the docs say the range 
 193     //is 0 to 4 so the check is unnecessary, these match exactly with the 
 196     VariantInit (&zoomVariant
); 
 197     V_VT(&zoomVariant
) = VT_I4
; 
 198     V_I4(&zoomVariant
) = level
; 
 203             m_webBrowser
->ExecWB(OLECMDID_ZOOM
, 
 204                                  OLECMDEXECOPT_DONTPROMPTUSER
, 
 206     wxASSERT(result 
== S_OK
); 
 209 wxWebViewZoom 
wxWebViewIE::GetIETextZoom() const 
 212     VariantInit (&zoomVariant
); 
 213     V_VT(&zoomVariant
) = VT_I4
; 
 218             m_webBrowser
->ExecWB(OLECMDID_ZOOM
, 
 219                                  OLECMDEXECOPT_DONTPROMPTUSER
, 
 221     wxASSERT(result 
== S_OK
); 
 223     //We can safely cast here as we know that the range matches our enum 
 224     return static_cast<wxWebViewZoom
>(V_I4(&zoomVariant
)); 
 227 void wxWebViewIE::SetIEOpticalZoom(wxWebViewZoom level
) 
 229     //We do not use OLECMDID_OPTICAL_GETZOOMRANGE as the docs say the range 
 230     //is 10 to 1000 so the check is unnecessary 
 232     VariantInit (&zoomVariant
); 
 233     V_VT(&zoomVariant
) = VT_I4
; 
 235     //We make a somewhat arbitray map here, taken from values used by webkit 
 238         case wxWEB_VIEW_ZOOM_TINY
: 
 239             V_I4(&zoomVariant
) = 60; 
 241         case wxWEB_VIEW_ZOOM_SMALL
: 
 242             V_I4(&zoomVariant
) = 80; 
 244         case wxWEB_VIEW_ZOOM_MEDIUM
: 
 245             V_I4(&zoomVariant
) = 100; 
 247         case wxWEB_VIEW_ZOOM_LARGE
: 
 248             V_I4(&zoomVariant
) = 130; 
 250         case wxWEB_VIEW_ZOOM_LARGEST
: 
 251             V_I4(&zoomVariant
) = 160; 
 260             m_webBrowser
->ExecWB((OLECMDID
)63 /*OLECMDID_OPTICAL_ZOOM*/, 
 261                                  OLECMDEXECOPT_DODEFAULT
, 
 264     wxASSERT(result 
== S_OK
); 
 267 wxWebViewZoom 
wxWebViewIE::GetIEOpticalZoom() const 
 270     VariantInit (&zoomVariant
); 
 271     V_VT(&zoomVariant
) = VT_I4
; 
 276             m_webBrowser
->ExecWB((OLECMDID
)63 /*OLECMDID_OPTICAL_ZOOM*/, 
 277                                  OLECMDEXECOPT_DODEFAULT
, NULL
, 
 279     wxASSERT(result 
== S_OK
); 
 281     const int zoom 
= V_I4(&zoomVariant
); 
 283     //We make a somewhat arbitray map here, taken from values used by webkit 
 286         return wxWEB_VIEW_ZOOM_TINY
; 
 288     else if (zoom 
> 65 && zoom 
<= 90) 
 290         return wxWEB_VIEW_ZOOM_SMALL
; 
 292     else if (zoom 
> 90 && zoom 
<= 115) 
 294         return wxWEB_VIEW_ZOOM_MEDIUM
; 
 296     else if (zoom 
> 115 && zoom 
<= 145) 
 298         return wxWEB_VIEW_ZOOM_LARGE
; 
 300     else /*if (zoom > 145) */ //Using else removes a compiler warning 
 302         return wxWEB_VIEW_ZOOM_LARGEST
; 
 306 void wxWebViewIE::SetZoomType(wxWebViewZoomType type
) 
 311 wxWebViewZoomType 
wxWebViewIE::GetZoomType() const 
 316 bool wxWebViewIE::CanSetZoomType(wxWebViewZoomType type
) const 
 318     //IE 6 and below only support text zoom, so check the registry to see what 
 319     //version we actually have 
 320     wxRegKey 
key(wxRegKey::HKLM
, "Software\\Microsoft\\Internet Explorer"); 
 322     key
.QueryValue("Version", value
); 
 324     long version 
= wxAtoi(value
.Left(1)); 
 325     if(version 
<= 6 && type 
== wxWEB_VIEW_ZOOM_TYPE_LAYOUT
) 
 331 void wxWebViewIE::Print() 
 333     m_webBrowser
->ExecWB(OLECMDID_PRINTPREVIEW
, 
 334                          OLECMDEXECOPT_DODEFAULT
, NULL
, NULL
); 
 337 bool wxWebViewIE::CanGoBack() const 
 340         return m_historyPosition 
> 0; 
 345 bool wxWebViewIE::CanGoForward() const 
 348         return m_historyPosition 
!= static_cast<int>(m_historyList
.size()) - 1; 
 353 void wxWebViewIE::LoadHistoryItem(wxSharedPtr
<wxWebViewHistoryItem
> item
) 
 356     for(unsigned int i 
= 0; i 
< m_historyList
.size(); i
++) 
 358         //We compare the actual pointers to find the correct item 
 359         if(m_historyList
[i
].get() == item
.get()) 
 362     wxASSERT_MSG(pos 
!= static_cast<int>(m_historyList
.size()), 
 363                  "invalid history item"); 
 364     m_historyLoadingFromList 
= true; 
 365     LoadURL(item
->GetUrl()); 
 366     m_historyPosition 
= pos
; 
 369 wxVector
<wxSharedPtr
<wxWebViewHistoryItem
> > wxWebViewIE::GetBackwardHistory() 
 371     wxVector
<wxSharedPtr
<wxWebViewHistoryItem
> > backhist
; 
 372     //As we don't have std::copy or an iterator constructor in the wxwidgets 
 373     //native vector we construct it by hand 
 374     for(int i 
= 0; i 
< m_historyPosition
; i
++) 
 376         backhist
.push_back(m_historyList
[i
]); 
 381 wxVector
<wxSharedPtr
<wxWebViewHistoryItem
> > wxWebViewIE::GetForwardHistory() 
 383     wxVector
<wxSharedPtr
<wxWebViewHistoryItem
> > forwardhist
; 
 384     //As we don't have std::copy or an iterator constructor in the wxwidgets 
 385     //native vector we construct it by hand 
 386     for(int i 
= m_historyPosition 
+ 1; i 
< static_cast<int>(m_historyList
.size()); i
++) 
 388         forwardhist
.push_back(m_historyList
[i
]); 
 393 void wxWebViewIE::GoBack() 
 395     LoadHistoryItem(m_historyList
[m_historyPosition 
- 1]); 
 398 void wxWebViewIE::GoForward() 
 400     LoadHistoryItem(m_historyList
[m_historyPosition 
+ 1]); 
 403 void wxWebViewIE::Stop() 
 405     m_ie
.CallMethod("Stop"); 
 408 void wxWebViewIE::ClearHistory() 
 410     m_historyList
.clear(); 
 411     m_historyPosition 
= -1; 
 414 void wxWebViewIE::EnableHistory(bool enable
) 
 416     m_historyEnabled 
= enable
; 
 417     m_historyList
.clear(); 
 418     m_historyPosition 
= -1; 
 421 void wxWebViewIE::Reload(wxWebViewReloadFlags flags
) 
 425     V_VT(&level
) = VT_I2
; 
 429         case wxWEB_VIEW_RELOAD_DEFAULT
: 
 430             V_I2(&level
) = REFRESH_NORMAL
; 
 432         case wxWEB_VIEW_RELOAD_NO_CACHE
: 
 433             V_I2(&level
) = REFRESH_COMPLETELY
; 
 436             wxFAIL_MSG("Unexpected reload type"); 
 439     m_webBrowser
->Refresh2(&level
); 
 442 bool wxWebViewIE::IsOfflineMode() 
 444     wxVariant out 
= m_ie
.GetProperty("Offline"); 
 446     wxASSERT(out
.GetType() == "bool"); 
 448     return out
.GetBool(); 
 451 void wxWebViewIE::SetOfflineMode(bool offline
) 
 453     // FIXME: the wxWidgets docs do not really document what the return 
 454     //        parameter of PutProperty is 
 458             m_ie
.PutProperty("Offline", (offline 
? 
 464 bool wxWebViewIE::IsBusy() const 
 466     if (m_isBusy
) return true; 
 468     wxVariant out 
= m_ie
.GetProperty("Busy"); 
 470     wxASSERT(out
.GetType() == "bool"); 
 472     return out
.GetBool(); 
 475 wxString 
wxWebViewIE::GetCurrentURL() const 
 477     wxVariant out 
= m_ie
.GetProperty("LocationURL"); 
 479     wxASSERT(out
.GetType() == "string"); 
 480     return out
.GetString(); 
 483 wxString 
wxWebViewIE::GetCurrentTitle() const 
 485     IHTMLDocument2
* document 
= GetDocument(); 
 488     document
->get_nameProp(&title
); 
 490     return wxString(title
); 
 493 bool wxWebViewIE::CanCut() const 
 495     return CanExecCommand("Cut"); 
 498 bool wxWebViewIE::CanCopy() const 
 500     return CanExecCommand("Copy"); 
 502 bool wxWebViewIE::CanPaste() const 
 504     return CanExecCommand("Paste"); 
 507 void wxWebViewIE::Cut() 
 512 void wxWebViewIE::Copy() 
 517 void wxWebViewIE::Paste() 
 519     ExecCommand("Paste"); 
 522 bool wxWebViewIE::CanUndo() const 
 524     return CanExecCommand("Undo"); 
 526 bool wxWebViewIE::CanRedo() const 
 528     return CanExecCommand("Redo"); 
 531 void wxWebViewIE::Undo() 
 536 void wxWebViewIE::Redo() 
 541 void wxWebViewIE::SetEditable(bool enable
) 
 543     IHTMLDocument2
* document 
= GetDocument(); 
 545         document
->put_designMode(SysAllocString(L
"On")); 
 547         document
->put_designMode(SysAllocString(L
"Off")); 
 552 bool wxWebViewIE::IsEditable() const 
 554     IHTMLDocument2
* document 
= GetDocument(); 
 556     document
->get_designMode(&mode
); 
 558     if(wxString(mode
) == "On") 
 564 void wxWebViewIE::SelectAll() 
 566     ExecCommand("SelectAll"); 
 569 bool wxWebViewIE::HasSelection() const 
 571     IHTMLDocument2
* document 
= GetDocument(); 
 572     IHTMLSelectionObject
* selection
; 
 574     HRESULT hr 
= document
->get_selection(&selection
); 
 578         selection
->get_type(&type
); 
 579         sel 
= wxString(type
); 
 580         selection
->Release(); 
 583     return sel 
!= "None"; 
 586 void wxWebViewIE::DeleteSelection() 
 588     ExecCommand("Delete"); 
 591 wxString 
wxWebViewIE::GetSelectedText() const 
 593     IHTMLDocument2
* document 
= GetDocument(); 
 594     IHTMLSelectionObject
* selection
; 
 596     HRESULT hr 
= document
->get_selection(&selection
); 
 600         hr 
= selection
->createRange(&disrange
); 
 603             IHTMLTxtRange
* range
; 
 604             hr 
= disrange
->QueryInterface(IID_IHTMLTxtRange
, (void**)&range
); 
 608                 range
->get_text(&text
); 
 609                 selected 
= wxString(text
); 
 614         selection
->Release(); 
 620 wxString 
wxWebViewIE::GetSelectedSource() const 
 622     IHTMLDocument2
* document 
= GetDocument(); 
 623     IHTMLSelectionObject
* selection
; 
 625     HRESULT hr 
= document
->get_selection(&selection
); 
 629         hr 
= selection
->createRange(&disrange
); 
 632             IHTMLTxtRange
* range
; 
 633             hr 
= disrange
->QueryInterface(IID_IHTMLTxtRange
, (void**)&range
); 
 637                 range
->get_htmlText(&text
); 
 638                 selected 
= wxString(text
); 
 643         selection
->Release(); 
 649 void wxWebViewIE::ClearSelection() 
 651     IHTMLDocument2
* document 
= GetDocument(); 
 652     IHTMLSelectionObject
* selection
; 
 654     HRESULT hr 
= document
->get_selection(&selection
); 
 658         selection
->Release(); 
 663 wxString 
wxWebViewIE::GetPageText() const 
 665     IHTMLDocument2
* document 
= GetDocument(); 
 668     HRESULT hr 
= document
->get_body(&body
); 
 672         body
->get_innerText(&out
); 
 673         text 
= wxString(out
); 
 680 void wxWebViewIE::RunScript(const wxString
& javascript
) 
 682     IHTMLDocument2
* document 
= GetDocument(); 
 683     IHTMLWindow2
* window
; 
 684     wxString language 
= "javascript"; 
 685     HRESULT hr 
= document
->get_parentWindow(&window
); 
 690         V_VT(&level
) = VT_EMPTY
; 
 691         window
->execScript(SysAllocString(javascript
), SysAllocString(language
), &level
); 
 696 void wxWebViewIE::RegisterHandler(wxSharedPtr
<wxWebViewHandler
> handler
) 
 698     wxDynamicLibrary 
urlMon(wxT("urlmon.dll")); 
 699     if(urlMon
.HasSymbol(wxT("CoInternetGetSession"))) 
 701         typedef HRESULT (WINAPI 
*CoInternetGetSession_t
)(DWORD
, IInternetSession
**, DWORD
); 
 702         wxDYNLIB_FUNCTION(CoInternetGetSession_t
, CoInternetGetSession
, urlMon
); 
 704         ClassFactory
* cf 
= new ClassFactory(handler
); 
 705         IInternetSession
* session
; 
 706         HRESULT res 
= (*pfnCoInternetGetSession
)(0, &session
, 0); 
 709             wxFAIL_MSG("Could not retrive internet session"); 
 712         HRESULT hr 
= session
->RegisterNameSpace(cf
, CLSID_FileProtocol
, handler
->GetName(), 0, NULL
, 0); 
 715             wxFAIL_MSG("Could not register protocol"); 
 717         m_factories
.push_back(cf
); 
 721         wxFAIL_MSG("urlmon does not contain CoInternetGetSession"); 
 725 bool wxWebViewIE::CanExecCommand(wxString command
) const 
 727     IHTMLDocument2
* document 
= GetDocument(); 
 728     VARIANT_BOOL enabled
; 
 730     document
->queryCommandEnabled(SysAllocString(command
.wc_str()), &enabled
); 
 733     return (enabled 
== VARIANT_TRUE
); 
 736 void wxWebViewIE::ExecCommand(wxString command
) 
 738     IHTMLDocument2
* document 
= GetDocument(); 
 739     document
->execCommand(SysAllocString(command
.wc_str()), VARIANT_FALSE
, VARIANT(), NULL
); 
 743 IHTMLDocument2
* wxWebViewIE::GetDocument() const 
 745     wxVariant variant 
= m_ie
.GetProperty("Document"); 
 746     IHTMLDocument2
* document 
= (IHTMLDocument2
*)variant
.GetVoidPtr(); 
 753 void wxWebViewIE::onActiveXEvent(wxActiveXEvent
& evt
) 
 755     if (m_webBrowser 
== NULL
) return; 
 757     switch (evt
.GetDispatchId()) 
 759         case DISPID_BEFORENAVIGATE2
: 
 763             wxString url 
= evt
[1].GetString(); 
 764             wxString target 
= evt
[3].GetString(); 
 766             wxWebViewEvent 
event(wxEVT_COMMAND_WEB_VIEW_NAVIGATING
, 
 767                                  GetId(), url
, target
); 
 768             event
.SetEventObject(this); 
 769             HandleWindowEvent(event
); 
 771             if (!event
.IsAllowed()) 
 773                 wxActiveXEventNativeMSW
* nativeParams 
= 
 774                     evt
.GetNativeParameters(); 
 775                 *V_BOOLREF(&nativeParams
->pDispParams
->rgvarg
[0]) = VARIANT_TRUE
; 
 778             // at this point, either the navigation event has been cancelled 
 779             // and we're not busy, either it was accepted and IWebBrowser2's 
 780             // Busy property will be true; so we don't need our override 
 787         case DISPID_NAVIGATECOMPLETE2
: 
 789             wxString url 
= evt
[1].GetString(); 
 790             // TODO: set target parameter if possible 
 791             wxString target 
= wxEmptyString
; 
 792             wxWebViewEvent 
event(wxEVT_COMMAND_WEB_VIEW_NAVIGATED
, 
 793                                  GetId(), url
, target
); 
 794             event
.SetEventObject(this); 
 795             HandleWindowEvent(event
); 
 799         case DISPID_PROGRESSCHANGE
: 
 805         case DISPID_DOCUMENTCOMPLETE
: 
 807             //Only send a complete even if we are actually finished, this brings 
 808             //the event in to line with webkit 
 810             m_webBrowser
->get_ReadyState( &rs 
); 
 811             if(rs 
!= READYSTATE_COMPLETE
) 
 814             wxString url 
= evt
[1].GetString(); 
 816             //As we are complete we also add to the history list, but not if the 
 817             //page is not the main page, ie it is a subframe 
 818             //We also have to check if we are loading a file:// url, if so we  
 819             //need to change the comparison as ie passes back a different style 
 821             if(m_historyEnabled 
&& !m_historyLoadingFromList 
&&  
 822               (url 
== GetCurrentURL() ||  
 823               (GetCurrentURL().substr(0, 4) == "file" &&  
 824                wxFileSystem::URLToFileName(GetCurrentURL()).GetFullPath() == url
))) 
 826                 //If we are not at the end of the list, then erase everything 
 827                 //between us and the end before adding the new page 
 828                 if(m_historyPosition 
!= static_cast<int>(m_historyList
.size()) - 1) 
 830                     m_historyList
.erase(m_historyList
.begin() + m_historyPosition 
+ 1, 
 831                                         m_historyList
.end()); 
 833                 wxSharedPtr
<wxWebViewHistoryItem
> item(new wxWebViewHistoryItem(url
, GetCurrentTitle())); 
 834                 m_historyList
.push_back(item
); 
 837             //Reset as we are done now 
 838             m_historyLoadingFromList 
= false; 
 839             // TODO: set target parameter if possible 
 840             wxString target 
= wxEmptyString
; 
 841             wxWebViewEvent 
event(wxEVT_COMMAND_WEB_VIEW_LOADED
, GetId(), 
 843             event
.SetEventObject(this); 
 844             HandleWindowEvent(event
); 
 848         case DISPID_STATUSTEXTCHANGE
: 
 853         case DISPID_TITLECHANGE
: 
 855             wxString title 
= evt
[0].GetString(); 
 857             wxWebViewEvent 
event(wxEVT_COMMAND_WEB_VIEW_TITLE_CHANGED
, 
 858                                  GetId(), GetCurrentURL(), ""); 
 859             event
.SetString(title
); 
 860             event
.SetEventObject(this); 
 861             HandleWindowEvent(event
); 
 865         case DISPID_NAVIGATEERROR
: 
 867             wxWebViewNavigationError errorType 
= wxWEB_NAV_ERR_OTHER
; 
 868             wxString errorCode 
= "?"; 
 869             switch (evt
[3].GetLong()) 
 871             case INET_E_INVALID_URL
: // (0x800C0002L or -2146697214) 
 872                 errorCode 
= "INET_E_INVALID_URL"; 
 873                 errorType 
= wxWEB_NAV_ERR_REQUEST
; 
 875             case INET_E_NO_SESSION
: // (0x800C0003L or -2146697213) 
 876                 errorCode 
= "INET_E_NO_SESSION"; 
 877                 errorType 
= wxWEB_NAV_ERR_CONNECTION
; 
 879             case INET_E_CANNOT_CONNECT
: // (0x800C0004L or -2146697212) 
 880                 errorCode 
= "INET_E_CANNOT_CONNECT"; 
 881                 errorType 
= wxWEB_NAV_ERR_CONNECTION
; 
 883             case INET_E_RESOURCE_NOT_FOUND
: // (0x800C0005L or -2146697211) 
 884                 errorCode 
= "INET_E_RESOURCE_NOT_FOUND"; 
 885                 errorType 
= wxWEB_NAV_ERR_NOT_FOUND
; 
 887             case INET_E_OBJECT_NOT_FOUND
: // (0x800C0006L or -2146697210) 
 888                 errorCode 
= "INET_E_OBJECT_NOT_FOUND"; 
 889                 errorType 
= wxWEB_NAV_ERR_NOT_FOUND
; 
 891             case INET_E_DATA_NOT_AVAILABLE
: // (0x800C0007L or -2146697209) 
 892                 errorCode 
= "INET_E_DATA_NOT_AVAILABLE"; 
 893                 errorType 
= wxWEB_NAV_ERR_NOT_FOUND
; 
 895             case INET_E_DOWNLOAD_FAILURE
: // (0x800C0008L or -2146697208) 
 896                 errorCode 
= "INET_E_DOWNLOAD_FAILURE"; 
 897                 errorType 
= wxWEB_NAV_ERR_CONNECTION
; 
 899             case INET_E_AUTHENTICATION_REQUIRED
: // (0x800C0009L or -2146697207) 
 900                 errorCode 
= "INET_E_AUTHENTICATION_REQUIRED"; 
 901                 errorType 
= wxWEB_NAV_ERR_AUTH
; 
 903             case INET_E_NO_VALID_MEDIA
: // (0x800C000AL or -2146697206) 
 904                 errorCode 
= "INET_E_NO_VALID_MEDIA"; 
 905                 errorType 
= wxWEB_NAV_ERR_REQUEST
; 
 907             case INET_E_CONNECTION_TIMEOUT
: // (0x800C000BL or -2146697205) 
 908                 errorCode 
= "INET_E_CONNECTION_TIMEOUT"; 
 909                 errorType 
= wxWEB_NAV_ERR_CONNECTION
; 
 911             case INET_E_INVALID_REQUEST
: // (0x800C000CL or -2146697204) 
 912                 errorCode 
= "INET_E_INVALID_REQUEST"; 
 913                 errorType 
= wxWEB_NAV_ERR_REQUEST
; 
 915             case INET_E_UNKNOWN_PROTOCOL
: // (0x800C000DL or -2146697203) 
 916                 errorCode 
= "INET_E_UNKNOWN_PROTOCOL"; 
 917                 errorType 
= wxWEB_NAV_ERR_REQUEST
; 
 919             case INET_E_SECURITY_PROBLEM
: // (0x800C000EL or -2146697202) 
 920                 errorCode 
= "INET_E_SECURITY_PROBLEM"; 
 921                 errorType 
= wxWEB_NAV_ERR_SECURITY
; 
 923             case INET_E_CANNOT_LOAD_DATA
: // (0x800C000FL or -2146697201) 
 924                 errorCode 
= "INET_E_CANNOT_LOAD_DATA"; 
 925                 errorType 
= wxWEB_NAV_ERR_OTHER
; 
 927             case INET_E_CANNOT_INSTANTIATE_OBJECT
: 
 928                 // CoCreateInstance will return an error code if this happens, 
 929                 // we'll handle this above. 
 932             case INET_E_REDIRECT_FAILED
: // (0x800C0014L or -2146697196) 
 933                 errorCode 
= "INET_E_REDIRECT_FAILED"; 
 934                 errorType 
= wxWEB_NAV_ERR_OTHER
; 
 936             case INET_E_REDIRECT_TO_DIR
: // (0x800C0015L or -2146697195) 
 937                 errorCode 
= "INET_E_REDIRECT_TO_DIR"; 
 938                 errorType 
= wxWEB_NAV_ERR_REQUEST
; 
 940             case INET_E_CANNOT_LOCK_REQUEST
: // (0x800C0016L or -2146697194) 
 941                 errorCode 
= "INET_E_CANNOT_LOCK_REQUEST"; 
 942                 errorType 
= wxWEB_NAV_ERR_OTHER
; 
 944             case INET_E_USE_EXTEND_BINDING
: // (0x800C0017L or -2146697193) 
 945                 errorCode 
= "INET_E_USE_EXTEND_BINDING"; 
 946                 errorType 
= wxWEB_NAV_ERR_OTHER
; 
 948             case INET_E_TERMINATED_BIND
: // (0x800C0018L or -2146697192) 
 949                 errorCode 
= "INET_E_TERMINATED_BIND"; 
 950                 errorType 
= wxWEB_NAV_ERR_OTHER
; 
 952             case INET_E_INVALID_CERTIFICATE
: // (0x800C0019L or -2146697191) 
 953                 errorCode 
= "INET_E_INVALID_CERTIFICATE"; 
 954                 errorType 
= wxWEB_NAV_ERR_CERTIFICATE
; 
 956             case INET_E_CODE_DOWNLOAD_DECLINED
: // (0x800C0100L or -2146696960) 
 957                 errorCode 
= "INET_E_CODE_DOWNLOAD_DECLINED"; 
 958                 errorType 
= wxWEB_NAV_ERR_USER_CANCELLED
; 
 960             case INET_E_RESULT_DISPATCHED
: // (0x800C0200L or -2146696704) 
 961                 // cancel request cancelled... 
 962                 errorCode 
= "INET_E_RESULT_DISPATCHED"; 
 963                 errorType 
= wxWEB_NAV_ERR_OTHER
; 
 965             case INET_E_CANNOT_REPLACE_SFP_FILE
: // (0x800C0300L or -2146696448) 
 966                 errorCode 
= "INET_E_CANNOT_REPLACE_SFP_FILE"; 
 967                 errorType 
= wxWEB_NAV_ERR_SECURITY
; 
 969             case INET_E_CODE_INSTALL_BLOCKED_BY_HASH_POLICY
: 
 970                 errorCode 
= "INET_E_CODE_INSTALL_BLOCKED_BY_HASH_POLICY"; 
 971                 errorType 
= wxWEB_NAV_ERR_SECURITY
; 
 973             case INET_E_CODE_INSTALL_SUPPRESSED
: 
 974                 errorCode 
= "INET_E_CODE_INSTALL_SUPPRESSED"; 
 975                 errorType 
= wxWEB_NAV_ERR_SECURITY
; 
 979             wxString url 
= evt
[1].GetString(); 
 980             wxString target 
= evt
[2].GetString(); 
 981             wxWebViewEvent 
event(wxEVT_COMMAND_WEB_VIEW_ERROR
, GetId(), 
 983             event
.SetEventObject(this); 
 984             event
.SetInt(errorType
); 
 985             event
.SetString(errorCode
); 
 986             HandleWindowEvent(event
); 
 989         case DISPID_NEWWINDOW3
: 
 991             wxString url 
= evt
[4].GetString(); 
 993             wxWebViewEvent 
event(wxEVT_COMMAND_WEB_VIEW_NEWWINDOW
, 
 994                                  GetId(), url
, wxEmptyString
); 
 995             event
.SetEventObject(this); 
 996             HandleWindowEvent(event
); 
 998             //We always cancel this event otherwise an Internet Exporer window 
 999             //is opened for the url 
1000             wxActiveXEventNativeMSW
* nativeParams 
= evt
.GetNativeParameters(); 
1001             *V_BOOLREF(&nativeParams
->pDispParams
->rgvarg
[3]) = VARIANT_TRUE
; 
1009 VirtualProtocol::VirtualProtocol(wxSharedPtr
<wxWebViewHandler
> handler
) 
1013     m_handler 
= handler
; 
1016 VirtualProtocol::~VirtualProtocol() 
1020 ULONG 
VirtualProtocol::AddRef() 
1026 HRESULT 
VirtualProtocol::QueryInterface(REFIID riid
, void **ppvObject
) 
1028     if(riid 
== IID_IUnknown 
|| riid 
== IID_IInternetProtocolRoot 
||  
1029        riid 
== IID_IInternetProtocol
) 
1031         *ppvObject 
= (IInternetProtocol
*)this; 
1042 ULONG 
VirtualProtocol::Release() 
1056 HRESULT 
VirtualProtocol::Start(LPCWSTR szUrl
, IInternetProtocolSink 
*pOIProtSink
, 
1057                                IInternetBindInfo 
*pOIBindInfo
, DWORD grfPI
,  
1058                                HANDLE_PTR dwReserved
) 
1061     wxUnusedVar(pOIBindInfo
); 
1063     wxUnusedVar(dwReserved
); 
1064     m_protocolSink 
= pOIProtSink
; 
1066     //We get the file itself from the protocol handler 
1067     m_file 
= m_handler
->GetFile(szUrl
); 
1071         return INET_E_RESOURCE_NOT_FOUND
; 
1073     //We return the stream length for current and total size as we can always 
1074     //read the whole file from the stream 
1075     wxFileOffset length 
= m_file
->GetStream()->GetLength(); 
1076     m_protocolSink
->ReportData(BSCF_FIRSTDATANOTIFICATION 
|  
1077                                BSCF_DATAFULLYAVAILABLE 
| 
1078                                BSCF_LASTDATANOTIFICATION
, 
1083 HRESULT 
VirtualProtocol::Read(void *pv
, ULONG cb
, ULONG 
*pcbRead
) 
1085     //If the file is null we return false to indicte it is finished 
1089     wxStreamError err 
= m_file
->GetStream()->Read(pv
, cb
).GetLastError(); 
1090     *pcbRead 
= m_file
->GetStream()->LastRead(); 
1092     if(err 
== wxSTREAM_NO_ERROR
) 
1097             m_protocolSink
->ReportResult(S_OK
, 0, NULL
); 
1099         //As we are not eof there is more data 
1102     else if(err 
== wxSTREAM_EOF
) 
1105         m_protocolSink
->ReportResult(S_OK
, 0, NULL
); 
1106         //We are eof and so finished 
1109     else if(err 
==  wxSTREAM_READ_ERROR
) 
1112         return INET_E_DOWNLOAD_FAILURE
; 
1116         //Dummy return to surpress a compiler warning 
1118         return INET_E_DOWNLOAD_FAILURE
; 
1122 HRESULT 
ClassFactory::CreateInstance(IUnknown
* pUnkOuter
, REFIID riid
, 
1126         return CLASS_E_NOAGGREGATION
; 
1127     VirtualProtocol
* vp 
= new VirtualProtocol(m_handler
); 
1129     HRESULT hr 
= vp
->QueryInterface(riid
, ppvObject
); 
1135 STDMETHODIMP 
ClassFactory::LockServer(BOOL fLock
) 
1141 ULONG 
ClassFactory::AddRef(void) 
1147 HRESULT 
ClassFactory::QueryInterface(REFIID riid
, void **ppvObject
) 
1149     if ((riid 
== IID_IUnknown
) || (riid 
== IID_IClassFactory
)) 
1163 ULONG 
ClassFactory::Release(void) 
1178 #endif // wxUSE_WEBVIEW && wxUSE_WEBVIEW_IE