1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/msw/webviewie.cpp 
   3 // Purpose:     wxMSW wxWebViewIE class implementation for web view component 
   4 // Author:      Marianne Gagnon 
   6 // Copyright:   (c) 2010 Marianne Gagnon 
   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/webviewie.h" 
  19 #if wxHAVE_WEB_BACKEND_IE 
  27 // FIXME: Seems like MINGW does not have these, how to handle cleanly? 
  28 #define DISPID_COMMANDSTATECHANGE   105 
  29 typedef enum CommandStateChangeConstants 
{ 
  30     CSC_UPDATECOMMANDS 
= (int) 0xFFFFFFFF, 
  31     CSC_NAVIGATEFORWARD 
= 0x1, 
  32     CSC_NAVIGATEBACK 
= 0x2 
  33 } CommandStateChangeConstants
; 
  36 // FIXME: Seems like MINGW does not have these, how to handle cleanly? 
  37 #define DISPID_NAVIGATECOMPLETE2    252 
  38 #define DISPID_NAVIGATEERROR        271 
  39 #define OLECMDID_OPTICAL_ZOOM  63 
  40 #define INET_E_ERROR_FIRST 0x800C0002L 
  41 #define INET_E_INVALID_URL 0x800C0002L 
  42 #define INET_E_NO_SESSION 0x800C0003L 
  43 #define INET_E_CANNOT_CONNECT 0x800C0004L 
  44 #define INET_E_RESOURCE_NOT_FOUND 0x800C0005L 
  45 #define INET_E_OBJECT_NOT_FOUND 0x800C0006L 
  46 #define INET_E_DATA_NOT_AVAILABLE 0x800C0007L 
  47 #define INET_E_DOWNLOAD_FAILURE 0x800C0008L 
  48 #define INET_E_AUTHENTICATION_REQUIRED 0x800C0009L 
  49 #define INET_E_NO_VALID_MEDIA 0x800C000AL 
  50 #define INET_E_CONNECTION_TIMEOUT 0x800C000BL 
  51 #define INET_E_INVALID_REQUEST 0x800C000CL 
  52 #define INET_E_UNKNOWN_PROTOCOL 0x800C000DL 
  53 #define INET_E_SECURITY_PROBLEM 0x800C000EL 
  54 #define INET_E_CANNOT_LOAD_DATA 0x800C000FL 
  55 #define INET_E_CANNOT_INSTANTIATE_OBJECT 0x800C0010L 
  56 #define INET_E_QUERYOPTION_UNKNOWN 0x800C0013L 
  57 #define INET_E_REDIRECT_FAILED 0x800C0014L 
  58 #define INET_E_REDIRECT_TO_DIR 0x800C0015L 
  59 #define INET_E_CANNOT_LOCK_REQUEST 0x800C0016L 
  60 #define INET_E_USE_EXTEND_BINDING 0x800C0017L 
  61 #define INET_E_TERMINATED_BIND 0x800C0018L 
  62 #define INET_E_INVALID_CERTIFICATE 0x800C0019L 
  63 #define INET_E_CODE_DOWNLOAD_DECLINED 0x800C0100L 
  64 #define INET_E_RESULT_DISPATCHED 0x800C0200L 
  65 #define INET_E_CANNOT_REPLACE_SFP_FILE 0x800C0300L 
  66 #define INET_E_CODE_INSTALL_BLOCKED_BY_HASH_POLICY 0x800C0500L 
  67 #define INET_E_CODE_INSTALL_SUPPRESSED 0x800C0400L 
  69 #define REFRESH_COMPLETELY 3 
  71 BEGIN_EVENT_TABLE(wxWebViewIE
, wxControl
) 
  72 EVT_ACTIVEX(wxID_ANY
, wxWebViewIE::onActiveXEvent
) 
  73 EVT_ERASE_BACKGROUND(wxWebViewIE::onEraseBg
) 
  76 bool wxWebViewIE::Create(wxWindow
* parent
, 
  84     if (!wxControl::Create(parent
, id
, pos
, size
, style
, 
  85                            wxDefaultValidator
, name
)) 
  91     m_canNavigateBack 
= false; 
  92     m_canNavigateForward 
= false; 
  95     if (::CoCreateInstance(CLSID_WebBrowser
, NULL
, 
  96                            CLSCTX_INPROC_SERVER
, // CLSCTX_INPROC, 
  97                            IID_IWebBrowser2 
, (void**)&m_webBrowser
) != 0) 
  99         wxLogError("Failed to initialize IE, CoCreateInstance returned an error"); 
 103     m_ie
.SetDispatchPtr(m_webBrowser
); // wxAutomationObject will release itself 
 105     m_webBrowser
->put_RegisterAsBrowser(VARIANT_TRUE
); 
 106     m_webBrowser
->put_RegisterAsDropTarget(VARIANT_TRUE
); 
 107     //m_webBrowser->put_Silent(VARIANT_FALSE); 
 109     m_container 
= new wxActiveXContainer(this, IID_IWebBrowser2
, m_webBrowser
); 
 111     SetBackgroundStyle(wxBG_STYLE_PAINT
); 
 112     SetDoubleBuffered(true); 
 117 void wxWebViewIE::LoadUrl(const wxString
& url
) 
 119     wxVariant out 
= m_ie
.CallMethod("Navigate", (BSTR
) url
.wc_str(), 
 120                                     NULL
, NULL
, NULL
, NULL
); 
 122     // FIXME: why is out value null?? 
 123     //(HRESULT)(out.GetLong()) == S_OK; 
 126 void wxWebViewIE::SetPage(const wxString
& html
, const wxString
& baseUrl
) 
 128     LoadUrl("about:blank"); 
 130     // Let the wx events generated for navigation events be processed, so 
 131     // that the underlying IE component completes its Document object. 
 132     // FIXME: calling wxYield is not elegant nor very reliable probably 
 135     wxVariant documentVariant 
= m_ie
.GetProperty("Document"); 
 136     void* documentPtr 
= documentVariant
.GetVoidPtr(); 
 138     wxASSERT (documentPtr 
!= NULL
); 
 140     // TODO: consider the "baseUrl" parameter if possible 
 141     // TODO: consider encoding 
 142     BSTR bstr 
= SysAllocString(html
.wc_str()); 
 144     // Creates a new one-dimensional array 
 145     SAFEARRAY 
*psaStrings 
= SafeArrayCreateVector(VT_VARIANT
, 0, 1); 
 146     if (psaStrings 
!= NULL
) 
 149         HRESULT hr 
= SafeArrayAccessData(psaStrings
, (LPVOID
*)¶m
); 
 151         param
->bstrVal 
= bstr
; 
 153         hr 
= SafeArrayUnaccessData(psaStrings
); 
 155         IHTMLDocument2
* document 
= (IHTMLDocument2
*)documentPtr
; 
 156         document
->write(psaStrings
); 
 158         // SafeArrayDestroy calls SysFreeString for each BSTR 
 159         SafeArrayDestroy(psaStrings
); 
 163         wxLogError("wxWebViewIE::SetPage() : psaStrings is NULL"); 
 168 wxString 
wxWebViewIE::GetPageSource() 
 170     wxVariant documentVariant 
= m_ie
.GetProperty("Document"); 
 171     void* documentPtr 
= documentVariant
.GetVoidPtr(); 
 173     if (documentPtr 
== NULL
) 
 175         return wxEmptyString
; 
 178     IHTMLDocument2
* document 
= (IHTMLDocument2
*)documentPtr
; 
 180     IHTMLElement 
*bodyTag 
= NULL
; 
 181     IHTMLElement 
*htmlTag 
= NULL
; 
 182     document
->get_body(&bodyTag
); 
 183     wxASSERT(bodyTag 
!= NULL
); 
 186     bodyTag
->get_parentElement(&htmlTag
); 
 187     wxASSERT(htmlTag 
!= NULL
); 
 190     htmlTag
->get_outerHTML(&bstr
); 
 195     //wxMessageBox(wxString(bstr)); 
 197     // TODO: check encoding 
 198     return wxString(bstr
); 
 201 // FIXME? retrieve OLECMDID_GETZOOMRANGE instead of hardcoding range 0-4 
 202 wxWebViewZoom 
wxWebViewIE::GetZoom() 
 204     const int zoom 
= GetIETextZoom(); 
 209             return wxWEB_VIEW_ZOOM_TINY
; 
 212             return wxWEB_VIEW_ZOOM_SMALL
; 
 215             return wxWEB_VIEW_ZOOM_MEDIUM
; 
 218             return wxWEB_VIEW_ZOOM_LARGE
; 
 221             return wxWEB_VIEW_ZOOM_LARGEST
; 
 225             return wxWEB_VIEW_ZOOM_MEDIUM
; 
 228 void wxWebViewIE::SetZoom(wxWebViewZoom zoom
) 
 230     // I know I could cast from enum to int since wxWebViewZoom happens to 
 231     // match with IE's zoom levels, but I don't like doing that, what if enum 
 235         case wxWEB_VIEW_ZOOM_TINY
: 
 238         case wxWEB_VIEW_ZOOM_SMALL
: 
 241         case wxWEB_VIEW_ZOOM_MEDIUM
: 
 244         case wxWEB_VIEW_ZOOM_LARGE
: 
 247         case wxWEB_VIEW_ZOOM_LARGEST
: 
 255 void wxWebViewIE::SetIETextZoom(int level
) 
 258     VariantInit (&zoomVariant
); 
 259     V_VT(&zoomVariant
) = VT_I4
; 
 260     V_I4(&zoomVariant
) = level
; 
 262     HRESULT result 
= m_webBrowser
->ExecWB(OLECMDID_ZOOM
, 
 263                                           OLECMDEXECOPT_DONTPROMPTUSER
, 
 265     wxASSERT (result 
== S_OK
); 
 267     VariantClear (&zoomVariant
); 
 270 int wxWebViewIE::GetIETextZoom() 
 273     VariantInit (&zoomVariant
); 
 274     V_VT(&zoomVariant
) = VT_I4
; 
 275     V_I4(&zoomVariant
) = 4; 
 277     HRESULT result 
= m_webBrowser
->ExecWB(OLECMDID_ZOOM
, 
 278                                           OLECMDEXECOPT_DONTPROMPTUSER
, 
 280     wxASSERT (result 
== S_OK
); 
 282     int zoom 
= V_I4(&zoomVariant
); 
 283    // wxMessageBox(wxString::Format("Zoom : %i", zoom)); 
 284     VariantClear (&zoomVariant
); 
 289 void wxWebViewIE::SetIEOpticalZoom(float zoom
) 
 291     // TODO: add support for optical zoom (IE7+ only) 
 293     // TODO: get range from OLECMDID_OPTICAL_GETZOOMRANGE instead of hardcoding? 
 294     wxASSERT(zoom 
>= 10.0f
); 
 295     wxASSERT(zoom 
<= 1000.0f
); 
 298     VariantInit (&zoomVariant
); 
 299     V_VT(&zoomVariant
) = VT_I4
; 
 300     V_I4(&zoomVariant
) = (zoom 
* 100.0f
); 
 302     HRESULT result 
= m_webBrowser
->ExecWB((OLECMDID
)OLECMDID_OPTICAL_ZOOM
, 
 303                                           OLECMDEXECOPT_DODEFAULT
, 
 306     wxASSERT (result 
== S_OK
); 
 309 float wxWebViewIE::GetIEOpticalZoom() 
 311     // TODO: add support for optical zoom (IE7+ only) 
 314     VariantInit (&zoomVariant
); 
 315     V_VT(&zoomVariant
) = VT_I4
; 
 316     V_I4(&zoomVariant
) = -1; 
 318     HRESULT result 
= m_webBrowser
->ExecWB((OLECMDID
)OLECMDID_OPTICAL_ZOOM
, 
 319                                           OLECMDEXECOPT_DODEFAULT
, NULL
, 
 321     wxASSERT (result 
== S_OK
); 
 323     const int zoom 
= V_I4(&zoomVariant
); 
 324     VariantClear (&zoomVariant
); 
 326     return zoom 
/ 100.0f
; 
 329 void wxWebViewIE::SetZoomType(wxWebViewZoomType
) 
 331     // TODO: add support for optical zoom (IE7+ only) 
 335 wxWebViewZoomType 
wxWebViewIE::GetZoomType() const 
 337     // TODO: add support for optical zoom (IE7+ only) 
 338     return wxWEB_VIEW_ZOOM_TYPE_TEXT
; 
 341 bool wxWebViewIE::CanSetZoomType(wxWebViewZoomType
) const 
 343     // both are supported 
 344     // TODO: IE6 only supports text zoom, check if it's IE6 first 
 348 void wxWebViewIE::Print() 
 350     m_webBrowser
->ExecWB(OLECMDID_PRINTPREVIEW
, 
 351                          OLECMDEXECOPT_DODEFAULT
, NULL
, NULL
); 
 354 void wxWebViewIE::GoBack() 
 356     wxVariant out 
= m_ie
.CallMethod("GoBack"); 
 358     // FIXME: why is out value null?? 
 359     //return (HRESULT)(out.GetLong()) == S_OK; 
 362 void wxWebViewIE::GoForward() 
 364     wxVariant out 
= m_ie
.CallMethod("GoForward"); 
 366     // FIXME: why is out value null?? 
 367     //return (HRESULT)(out.GetLong()) == S_OK; 
 370 void wxWebViewIE::Stop() 
 372     wxVariant out 
= m_ie
.CallMethod("Stop"); 
 374     // FIXME: why is out value null?? 
 375     //return (HRESULT)(out.GetLong()) == S_OK; 
 379 void wxWebViewIE::Reload(wxWebViewReloadFlags flags
) 
 383     if (flags 
& wxWEB_VIEW_RELOAD_NO_CACHE
) 
 388         out 
= m_ie
.CallMethod("Refresh2", &level
); 
 392         out 
= m_ie
.CallMethod("Refresh"); 
 395     if (out
.GetType() != "null") 
 397         wxMessageBox("Non-null return message : " + out
.GetType()); 
 401 bool wxWebViewIE::IsOfflineMode() 
 403     wxVariant out 
= m_ie
.GetProperty("Offline"); 
 405     wxASSERT(out
.GetType() == "bool"); 
 407     return out
.GetBool(); 
 410 void wxWebViewIE::SetOfflineMode(bool offline
) 
 412     // FIXME: the wxWidgets docs do not really document what the return 
 413     //        parameter of PutProperty is 
 414     const bool success 
= m_ie
.PutProperty("Offline", (offline 
? 
 420 bool wxWebViewIE::IsBusy() 
 422     if (m_isBusy
) return true; 
 424     wxVariant out 
= m_ie
.GetProperty("Busy"); 
 426     wxASSERT(out
.GetType() == "bool"); 
 428     return out
.GetBool(); 
 431 wxString 
wxWebViewIE::GetCurrentURL() 
 433     wxVariant out 
= m_ie
.GetProperty("LocationURL"); 
 435     wxASSERT(out
.GetType() == "string"); 
 436     return out
.GetString(); 
 439 wxString 
wxWebViewIE::GetCurrentTitle() 
 441     wxVariant out 
= m_ie
.GetProperty("LocationName"); 
 443     wxASSERT(out
.GetType() == "string"); 
 444     return out
.GetString(); 
 447 void wxWebViewIE::onActiveXEvent(wxActiveXEvent
& evt
) 
 449     if (m_webBrowser 
== NULL
) return; 
 451     switch (evt
.GetDispatchId()) 
 453         case DISPID_BEFORENAVIGATE2
: 
 457             wxString url 
= evt
[1].GetString(); 
 458             wxString target 
= evt
[3].GetString(); 
 460             wxWebNavigationEvent 
event(wxEVT_COMMAND_WEB_VIEW_NAVIGATING
, 
 461                                        GetId(), url
, target
, true); 
 462             event
.SetEventObject(this); 
 463             HandleWindowEvent(event
); 
 465             if (event
.IsVetoed()) 
 467                 wxActiveXEventNativeMSW
* nativeParams 
= 
 468                     evt
.GetNativeParameters(); 
 469                 *V_BOOLREF(&nativeParams
->pDispParams
->rgvarg
[0]) = VARIANT_TRUE
; 
 472             // at this point, either the navigation event has been cancelled 
 473             // and we're not busy, either it was accepted and IWebBrowser2's 
 474             // Busy property will be true; so we don't need our override 
 481         case DISPID_NAVIGATECOMPLETE2
: 
 483             wxString url 
= evt
[1].GetString(); 
 484             // TODO: set target parameter if possible 
 485             wxString target 
= wxEmptyString
; 
 486             wxWebNavigationEvent 
event(wxEVT_COMMAND_WEB_VIEW_NAVIGATED
, 
 487                                        GetId(), url
, target
, false); 
 488             event
.SetEventObject(this); 
 489             HandleWindowEvent(event
); 
 493         case DISPID_PROGRESSCHANGE
: 
 499         case DISPID_DOCUMENTCOMPLETE
: 
 501             wxString url 
= evt
[1].GetString(); 
 502             // TODO: set target parameter if possible 
 503             wxString target 
= wxEmptyString
; 
 504             wxWebNavigationEvent 
event(wxEVT_COMMAND_WEB_VIEW_LOADED
, GetId(), 
 506             event
.SetEventObject(this); 
 507             HandleWindowEvent(event
); 
 511         case DISPID_STATUSTEXTCHANGE
: 
 516         case DISPID_TITLECHANGE
: 
 521         case DISPID_NAVIGATEERROR
: 
 523             wxWebNavigationError errorType 
= wxWEB_NAV_ERR_OTHER
; 
 524             wxString errorCode 
= "?"; 
 525             switch (evt
[3].GetLong()) 
 527             case INET_E_INVALID_URL
: // (0x800C0002L or -2146697214) 
 528                 errorCode 
= "INET_E_INVALID_URL"; 
 529                 errorType 
= wxWEB_NAV_ERR_REQUEST
; 
 531             case INET_E_NO_SESSION
: // (0x800C0003L or -2146697213) 
 532                 errorCode 
= "INET_E_NO_SESSION"; 
 533                 errorType 
= wxWEB_NAV_ERR_CONNECTION
; 
 535             case INET_E_CANNOT_CONNECT
: // (0x800C0004L or -2146697212) 
 536                 errorCode 
= "INET_E_CANNOT_CONNECT"; 
 537                 errorType 
= wxWEB_NAV_ERR_CONNECTION
; 
 539             case INET_E_RESOURCE_NOT_FOUND
: // (0x800C0005L or -2146697211) 
 540                 errorCode 
= "INET_E_RESOURCE_NOT_FOUND"; 
 541                 errorType 
= wxWEB_NAV_ERR_NOT_FOUND
; 
 543             case INET_E_OBJECT_NOT_FOUND
: // (0x800C0006L or -2146697210) 
 544                 errorCode 
= "INET_E_OBJECT_NOT_FOUND"; 
 545                 errorType 
= wxWEB_NAV_ERR_NOT_FOUND
; 
 547             case INET_E_DATA_NOT_AVAILABLE
: // (0x800C0007L or -2146697209) 
 548                 errorCode 
= "INET_E_DATA_NOT_AVAILABLE"; 
 549                 errorType 
= wxWEB_NAV_ERR_NOT_FOUND
; 
 551             case INET_E_DOWNLOAD_FAILURE
: // (0x800C0008L or -2146697208) 
 552                 errorCode 
= "INET_E_DOWNLOAD_FAILURE"; 
 553                 errorType 
= wxWEB_NAV_ERR_CONNECTION
; 
 555             case INET_E_AUTHENTICATION_REQUIRED
: // (0x800C0009L or -2146697207) 
 556                 errorCode 
= "INET_E_AUTHENTICATION_REQUIRED"; 
 557                 errorType 
= wxWEB_NAV_ERR_AUTH
; 
 559             case INET_E_NO_VALID_MEDIA
: // (0x800C000AL or -2146697206) 
 560                 errorCode 
= "INET_E_NO_VALID_MEDIA"; 
 561                 errorType 
= wxWEB_NAV_ERR_REQUEST
; 
 563             case INET_E_CONNECTION_TIMEOUT
: // (0x800C000BL or -2146697205) 
 564                 errorCode 
= "INET_E_CONNECTION_TIMEOUT"; 
 565                 errorType 
= wxWEB_NAV_ERR_CONNECTION
; 
 567             case INET_E_INVALID_REQUEST
: // (0x800C000CL or -2146697204) 
 568                 errorCode 
= "INET_E_INVALID_REQUEST"; 
 569                 errorType 
= wxWEB_NAV_ERR_REQUEST
; 
 571             case INET_E_UNKNOWN_PROTOCOL
: // (0x800C000DL or -2146697203) 
 572                 errorCode 
= "INET_E_UNKNOWN_PROTOCOL"; 
 573                 errorType 
= wxWEB_NAV_ERR_REQUEST
; 
 575             case INET_E_SECURITY_PROBLEM
: // (0x800C000EL or -2146697202) 
 576                 errorCode 
= "INET_E_SECURITY_PROBLEM"; 
 577                 errorType 
= wxWEB_NAV_ERR_SECURITY
; 
 579             case INET_E_CANNOT_LOAD_DATA
: // (0x800C000FL or -2146697201) 
 580                 errorCode 
= "INET_E_CANNOT_LOAD_DATA"; 
 581                 errorType 
= wxWEB_NAV_ERR_OTHER
; 
 583             case INET_E_CANNOT_INSTANTIATE_OBJECT
: 
 584                 // CoCreateInstance will return an error code if this happens, 
 585                 // we'll handle this above. 
 588             case INET_E_REDIRECT_FAILED
: // (0x800C0014L or -2146697196) 
 589                 errorCode 
= "INET_E_REDIRECT_FAILED"; 
 590                 errorType 
= wxWEB_NAV_ERR_OTHER
; 
 592             case INET_E_REDIRECT_TO_DIR
: // (0x800C0015L or -2146697195) 
 593                 errorCode 
= "INET_E_REDIRECT_TO_DIR"; 
 594                 errorType 
= wxWEB_NAV_ERR_REQUEST
; 
 596             case INET_E_CANNOT_LOCK_REQUEST
: // (0x800C0016L or -2146697194) 
 597                 errorCode 
= "INET_E_CANNOT_LOCK_REQUEST"; 
 598                 errorType 
= wxWEB_NAV_ERR_OTHER
; 
 600             case INET_E_USE_EXTEND_BINDING
: // (0x800C0017L or -2146697193) 
 601                 errorCode 
= "INET_E_USE_EXTEND_BINDING"; 
 602                 errorType 
= wxWEB_NAV_ERR_OTHER
; 
 604             case INET_E_TERMINATED_BIND
: // (0x800C0018L or -2146697192) 
 605                 errorCode 
= "INET_E_TERMINATED_BIND"; 
 606                 errorType 
= wxWEB_NAV_ERR_OTHER
; 
 608             case INET_E_INVALID_CERTIFICATE
: // (0x800C0019L or -2146697191) 
 609                 errorCode 
= "INET_E_INVALID_CERTIFICATE"; 
 610                 errorType 
= wxWEB_NAV_ERR_CERTIFICATE
; 
 612             case INET_E_CODE_DOWNLOAD_DECLINED
: // (0x800C0100L or -2146696960) 
 613                 errorCode 
= "INET_E_CODE_DOWNLOAD_DECLINED"; 
 614                 errorType 
= wxWEB_NAV_ERR_USER_CANCELLED
; 
 616             case INET_E_RESULT_DISPATCHED
: // (0x800C0200L or -2146696704) 
 617                 // cancel request cancelled... 
 618                 errorCode 
= "INET_E_RESULT_DISPATCHED"; 
 619                 errorType 
= wxWEB_NAV_ERR_OTHER
; 
 621             case INET_E_CANNOT_REPLACE_SFP_FILE
: // (0x800C0300L or -2146696448) 
 622                 errorCode 
= "INET_E_CANNOT_REPLACE_SFP_FILE"; 
 623                 errorType 
= wxWEB_NAV_ERR_SECURITY
; 
 625             case INET_E_CODE_INSTALL_BLOCKED_BY_HASH_POLICY
: 
 626                 errorCode 
= "INET_E_CODE_INSTALL_BLOCKED_BY_HASH_POLICY"; 
 627                 errorType 
= wxWEB_NAV_ERR_SECURITY
; 
 629             case INET_E_CODE_INSTALL_SUPPRESSED
: 
 630                 errorCode 
= "INET_E_CODE_INSTALL_SUPPRESSED"; 
 631                 errorType 
= wxWEB_NAV_ERR_SECURITY
; 
 635             wxString url 
= evt
[1].GetString(); 
 636             wxString target 
= evt
[2].GetString(); 
 637             wxWebNavigationEvent 
event(wxEVT_COMMAND_WEB_VIEW_ERROR
, GetId(), 
 639             event
.SetEventObject(this); 
 640             event
.SetInt(errorType
); 
 641             event
.SetString(errorCode
); 
 642             HandleWindowEvent(event
); 
 646         case DISPID_COMMANDSTATECHANGE
: 
 648             long commandId 
= evt
[0].GetLong(); 
 649             bool enable 
= evt
[1].GetBool(); 
 650             if (commandId 
== CSC_NAVIGATEBACK
) 
 652                 m_canNavigateBack 
= enable
; 
 654             else if (commandId 
== CSC_NAVIGATEFORWARD
) 
 656                 m_canNavigateForward 
= enable
; 
 661         case DISPID_NEWWINDOW2: 
 662         //case DISPID_NEWWINDOW3: 
 664             wxLogMessage("DISPID_NEWWINDOW2\n"); 
 665             wxActiveXEventNativeMSW* nativeParams = evt.GetNativeParameters(); 
 666             // Cancel the attempt to open a new window 
 667             *V_BOOLREF(&nativeParams->pDispParams->rgvarg[0]) = VARIANT_TRUE;