1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/webview_ie.cpp
3 // Purpose: wxMSW wxWebViewIE class implementation for web view component
4 // Author: Marianne Gagnon
5 // Copyright: (c) 2010 Marianne Gagnon, 2011 Steven Lamerton
6 // Licence: wxWindows licence
7 /////////////////////////////////////////////////////////////////////////////
8
9 // For compilers that support precompilation, includes "wx.h".
10 #include "wx/wxprec.h"
11
12
13 #include "wx/msw/webview_ie.h"
14
15 #if wxUSE_WEBVIEW && wxUSE_WEBVIEW_IE
16
17 #include "wx/msw/registry.h"
18 #include "wx/msw/ole/safearray.h"
19 #include "wx/filesys.h"
20 #include "wx/dynlib.h"
21 #include "wx/scopeguard.h"
22 #include "wx/tokenzr.h"
23
24 #include "wx/msw/missing.h"
25 #include "wx/msw/private.h"
26 #include "wx/msw/private/webview_ie.h"
27 #include "wx/private/jsscriptwrapper.h"
28
29 #include <initguid.h>
30 #include <exdispid.h>
31 #include <mshtml.h>
32
33 /* These GUID definitions are our own implementation to support interfaces
34 * normally in urlmon.h. See include/wx/msw/webview_ie.h
35 */
36
37 namespace {
38
39 DEFINE_GUID(wxIID_IInternetProtocolRoot,0x79eac9e3,0xbaf9,0x11ce,0x8c,0x82,0,0xaa,0,0x4b,0xa9,0xb);
40 DEFINE_GUID(wxIID_IInternetProtocol,0x79eac9e4,0xbaf9,0x11ce,0x8c,0x82,0,0xaa,0,0x4b,0xa9,0xb);
41 DEFINE_GUID(wxIID_IInternetProtocolInfo,0x79eac9ec,0xbaf9,0x11ce,0x8c, 0x82,0,0xaa,0,0x4b,0xa9,0x0b);
42 DEFINE_GUID(wxIID_IDocHostUIHandler, 0xbd3f23c0, 0xd43e, 0x11cf, 0x89, 0x3b, 0x00, 0xaa, 0x00, 0xbd, 0xce, 0x1a);
43 DEFINE_GUID(wxIID_IHTMLElement2,0x3050f434,0x98b5,0x11cf,0xbb,0x82,0,0xaa,0,0xbd,0xce,0x0b);
44 DEFINE_GUID(wxIID_IMarkupServices,0x3050f4a0,0x98b5,0x11cf,0xbb,0x82,0,0xaa,0,0xbd,0xce,0x0b);
45 DEFINE_GUID(wxIID_IMarkupContainer,0x3050f5f9,0x98b5,0x11cf,0xbb,0x82,0,0xaa,0,0xbd,0xce,0x0b);
46
47 enum //Internal find flags
48 {
49 wxWEBVIEW_FIND_ADD_POINTERS = 0x0001,
50 wxWEBVIEW_FIND_REMOVE_HIGHLIGHT = 0x0002
51 };
52
53 }
54
55 // wxWebViewFactoryIE
GetVersionInfo()56 wxVersionInfo wxWebViewFactoryIE::GetVersionInfo()
57 {
58 wxRegKey key(wxRegKey::HKLM, "Software\\Microsoft\\Internet Explorer");
59 wxString value;
60 key.QueryValue("Version", value);
61 long major = 0,
62 minor = 0,
63 micro = 0;
64 wxStringTokenizer tk(value, ". ");
65 // Ignore the return value because if the version component is missing
66 // or invalid (i.e. non-numeric), the only thing we can do is to ignore
67 // it anyhow.
68 tk.GetNextToken().ToLong(&major);
69 tk.GetNextToken().ToLong(&minor);
70 tk.GetNextToken().ToLong(µ);
71 return wxVersionInfo("Internet Explorer", major, minor, micro);
72 }
73
74 //Convenience function for error conversion
75 #define WX_ERROR_CASE(error, wxerror) \
76 case error: \
77 event.SetString(#error); \
78 event.SetInt(wxerror); \
79 break;
80
81 wxIMPLEMENT_DYNAMIC_CLASS(wxWebViewIE, wxWebView);
82
wxBEGIN_EVENT_TABLE(wxWebViewIE,wxControl)83 wxBEGIN_EVENT_TABLE(wxWebViewIE, wxControl)
84 EVT_ACTIVEX(wxID_ANY, wxWebViewIE::onActiveXEvent)
85 EVT_ERASE_BACKGROUND(wxWebViewIE::onEraseBg)
86 wxEND_EVENT_TABLE()
87
88 bool wxWebViewIE::Create(wxWindow* parent,
89 wxWindowID id,
90 const wxString& url,
91 const wxPoint& pos,
92 const wxSize& size,
93 long style,
94 const wxString& name)
95 {
96 if (!wxControl::Create(parent, id, pos, size, style,
97 wxDefaultValidator, name))
98 {
99 return false;
100 }
101
102 m_impl = new wxWebViewIEImpl(this);
103 if ( !m_impl->Create() )
104 return false;
105
106 // Make behaviour consistent with the other backends when loading localhost
107 // pages without any physical network connection.
108 SetOfflineMode(false);
109
110 LoadURL(url);
111 return true;
112 }
113
wxWebViewIEImpl(wxWebViewIE * webview)114 wxWebViewIEImpl::wxWebViewIEImpl(wxWebViewIE* webview)
115 : m_webview(webview)
116 {
117 }
118
Create()119 bool wxWebViewIEImpl::Create()
120 {
121 m_webBrowser = NULL;
122 m_isBusy = false;
123 m_historyLoadingFromList = false;
124 m_historyEnabled = true;
125 m_historyPosition = -1;
126 m_zoomType = wxWEBVIEW_ZOOM_TYPE_TEXT;
127 FindClear();
128
129 if (::CoCreateInstance(CLSID_WebBrowser, NULL,
130 CLSCTX_INPROC_SERVER, // CLSCTX_INPROC,
131 IID_IWebBrowser2 , (void**)&m_webBrowser) != 0)
132 {
133 wxLogError("Failed to initialize IE, CoCreateInstance returned an error");
134 return false;
135 }
136
137 m_ie.SetDispatchPtr(m_webBrowser); // wxAutomationObject will release itself
138
139 m_webBrowser->put_RegisterAsBrowser(VARIANT_TRUE);
140 m_webBrowser->put_RegisterAsDropTarget(VARIANT_TRUE);
141
142 m_uiHandler = new DocHostUIHandler(m_webview);
143
144 m_container = new wxIEContainer(m_webview, IID_IWebBrowser2, m_webBrowser, m_uiHandler);
145
146 EnableControlFeature(21 /* FEATURE_DISABLE_NAVIGATION_SOUNDS */);
147
148 return true;
149 }
150
~wxWebViewIE()151 wxWebViewIE::~wxWebViewIE()
152 {
153 delete m_impl;
154 }
155
~wxWebViewIEImpl()156 wxWebViewIEImpl::~wxWebViewIEImpl()
157 {
158 wxDynamicLibrary urlMon(wxT("urlmon.dll"));
159 if(urlMon.HasSymbol(wxT("CoInternetGetSession")))
160 {
161 typedef HRESULT (WINAPI *CoInternetGetSession_t)(DWORD,
162 wxIInternetSession**,
163 DWORD);
164 wxDYNLIB_FUNCTION(CoInternetGetSession_t, CoInternetGetSession, urlMon);
165
166 wxIInternetSession* session;
167 HRESULT res = (*pfnCoInternetGetSession)(0, &session, 0);
168 if(FAILED(res))
169 {
170 wxFAIL_MSG("Could not retrive internet session");
171 }
172
173 for(unsigned int i = 0; i < m_factories.size(); i++)
174 {
175 session->UnregisterNameSpace(m_factories[i],
176 (m_factories[i]->GetName()).wc_str());
177 m_factories[i]->Release();
178 }
179 }
180 FindClear();
181 }
182
LoadURL(const wxString & url)183 void wxWebViewIE::LoadURL(const wxString& url)
184 {
185 m_impl->m_ie.CallMethod("Navigate", wxConvertStringToOle(url));
186 }
187
188 namespace
189 {
190
191 // Helper function: wrap the given string in a SAFEARRAY<VARIANT> of size 1.
MakeOneElementVariantSafeArray(const wxString & str)192 SAFEARRAY* MakeOneElementVariantSafeArray(const wxString& str)
193 {
194 wxSafeArray<VT_VARIANT> sa;
195 if ( !sa.Create(1) )
196 {
197 wxLogLastError(wxT("SafeArrayCreateVector"));
198 return NULL;
199 }
200
201 long ind = 0;
202 if ( !sa.SetElement(&ind, str) )
203 {
204 wxLogLastError(wxT("SafeArrayPtrOfIndex"));
205 return NULL;
206 }
207
208 return sa.Detach();
209 }
210
211 } // anonymous namespace
212
DoSetPage(const wxString & html,const wxString & baseUrl)213 void wxWebViewIE::DoSetPage(const wxString& html, const wxString& baseUrl)
214 {
215 {
216 SAFEARRAY* const psaStrings = MakeOneElementVariantSafeArray(wxString());
217 if ( !psaStrings )
218 return;
219
220 wxON_BLOCK_EXIT1(SafeArrayDestroy, psaStrings);
221
222 wxCOMPtr<IHTMLDocument2> document(m_impl->GetDocument());
223
224 if(!document)
225 return;
226
227 document->write(psaStrings);
228 document->close();
229 }
230
231 {
232 SAFEARRAY* const psaStrings = MakeOneElementVariantSafeArray(html);
233
234 if ( !psaStrings )
235 return;
236
237 wxON_BLOCK_EXIT1(SafeArrayDestroy, psaStrings);
238
239 wxCOMPtr<IHTMLDocument2> document(m_impl->GetDocument());
240
241 if(!document)
242 return;
243
244 document->write(psaStrings);
245
246 //We send the events when we are done to mimic webkit
247 //Navigated event
248 wxWebViewEvent event(wxEVT_WEBVIEW_NAVIGATED,
249 GetId(), baseUrl, "");
250 event.SetEventObject(this);
251 HandleWindowEvent(event);
252
253 //Document complete event
254 event.SetEventType(wxEVT_WEBVIEW_LOADED);
255 event.SetEventObject(this);
256 HandleWindowEvent(event);
257 }
258 }
259
GetPageSource() const260 wxString wxWebViewIE::GetPageSource() const
261 {
262 wxCOMPtr<IHTMLDocument2> document(m_impl->GetDocument());
263
264 if(document)
265 {
266 wxCOMPtr<IHTMLElement> bodyTag;
267 wxCOMPtr<IHTMLElement> htmlTag;
268 wxString source;
269 HRESULT hr = document->get_body(&bodyTag);
270 if(SUCCEEDED(hr))
271 {
272 hr = bodyTag->get_parentElement(&htmlTag);
273 if(SUCCEEDED(hr))
274 {
275 wxBasicString bstr;
276 if ( htmlTag->get_outerHTML(bstr.ByRef()) == S_OK )
277 source = bstr;
278 }
279 }
280 return source;
281 }
282 else
283 {
284 return "";
285 }
286 }
287
GetZoom() const288 wxWebViewZoom wxWebViewIE::GetZoom() const
289 {
290 switch( m_impl->m_zoomType )
291 {
292 case wxWEBVIEW_ZOOM_TYPE_LAYOUT:
293 return GetIEOpticalZoom();
294 case wxWEBVIEW_ZOOM_TYPE_TEXT:
295 return GetIETextZoom();
296 default:
297 wxFAIL;
298 }
299
300 //Dummy return to stop compiler warnings
301 return wxWEBVIEW_ZOOM_MEDIUM;
302
303 }
304
GetZoomFactor() const305 float wxWebViewIE::GetZoomFactor() const
306 {
307 wxWebViewZoom level = wxWEBVIEW_ZOOM_MEDIUM;
308 float zoomFactor = 1.0;
309
310 if (m_impl->m_zoomType == wxWEBVIEW_ZOOM_TYPE_LAYOUT)
311 {
312 zoomFactor = (float)GetIEOpticalZoomFactor();
313 zoomFactor /= 100;
314 }
315 else if (m_impl->m_zoomType == wxWEBVIEW_ZOOM_TYPE_TEXT)
316 {
317 level = GetIETextZoom();
318 switch(level)
319 {
320 case wxWEBVIEW_ZOOM_TINY:
321 zoomFactor = 0.6f;
322 break;
323 case wxWEBVIEW_ZOOM_SMALL:
324 zoomFactor = 0.8f;
325 break;
326 case wxWEBVIEW_ZOOM_MEDIUM:
327 zoomFactor = 1.0f;
328 break;
329 case wxWEBVIEW_ZOOM_LARGE:
330 zoomFactor = 1.3f;
331 break;
332 case wxWEBVIEW_ZOOM_LARGEST:
333 zoomFactor = 1.6f;
334 break;
335 default:
336 wxFAIL;
337 }
338 }
339
340 return zoomFactor;
341 }
342
SetZoom(wxWebViewZoom zoom)343 void wxWebViewIE::SetZoom(wxWebViewZoom zoom)
344 {
345 switch( m_impl->m_zoomType )
346 {
347 case wxWEBVIEW_ZOOM_TYPE_LAYOUT:
348 SetIEOpticalZoom(zoom);
349 break;
350 case wxWEBVIEW_ZOOM_TYPE_TEXT:
351 SetIETextZoom(zoom);
352 break;
353 default:
354 wxFAIL;
355 }
356 }
357
SetZoomFactor(float zoom)358 void wxWebViewIE::SetZoomFactor(float zoom)
359 {
360 wxWebViewZoom level = wxWEBVIEW_ZOOM_MEDIUM;
361
362 if (m_impl->m_zoomType == wxWEBVIEW_ZOOM_TYPE_LAYOUT)
363 {
364 SetIEOpticalZoomFactor(zoom * 100);
365 }
366 else if (m_impl->m_zoomType == wxWEBVIEW_ZOOM_TYPE_TEXT)
367 {
368 //We make a somewhat arbitray map here, taken from values used by webkit
369 if (zoom <= 65)
370 {
371 level = wxWEBVIEW_ZOOM_TINY;
372 }
373 else if (zoom > 65 && zoom <= 90)
374 {
375 level = wxWEBVIEW_ZOOM_SMALL;
376 }
377 else if (zoom > 90 && zoom <= 115)
378 {
379 level = wxWEBVIEW_ZOOM_MEDIUM;
380 }
381 else if (zoom > 115 && zoom <= 145)
382 {
383 level = wxWEBVIEW_ZOOM_LARGE;
384 }
385 else
386 {
387 level = wxWEBVIEW_ZOOM_LARGEST;
388 }
389 SetIETextZoom(level);
390 }
391 }
392
SetIETextZoom(wxWebViewZoom level)393 void wxWebViewIE::SetIETextZoom(wxWebViewZoom level)
394 {
395 //We do not use OLECMDID_OPTICAL_GETZOOMRANGE as the docs say the range
396 //is 0 to 4 so the check is unnecessary, these match exactly with the
397 //enum values
398 VARIANT zoomVariant;
399 VariantInit (&zoomVariant);
400 V_VT(&zoomVariant) = VT_I4;
401 V_I4(&zoomVariant) = level;
402
403 #if wxDEBUG_LEVEL
404 HRESULT result =
405 #endif
406 m_impl->m_webBrowser->ExecWB(OLECMDID_ZOOM,
407 OLECMDEXECOPT_DONTPROMPTUSER,
408 &zoomVariant, NULL);
409 wxASSERT(result == S_OK);
410 }
411
GetIETextZoom() const412 wxWebViewZoom wxWebViewIE::GetIETextZoom() const
413 {
414 VARIANT zoomVariant;
415 VariantInit (&zoomVariant);
416 V_VT(&zoomVariant) = VT_I4;
417
418 #if wxDEBUG_LEVEL
419 HRESULT result =
420 #endif
421 m_impl->m_webBrowser->ExecWB(OLECMDID_ZOOM,
422 OLECMDEXECOPT_DONTPROMPTUSER,
423 NULL, &zoomVariant);
424 wxASSERT(result == S_OK);
425
426 //We can safely cast here as we know that the range matches our enum
427 return static_cast<wxWebViewZoom>(V_I4(&zoomVariant));
428 }
429
SetIEOpticalZoom(wxWebViewZoom level)430 void wxWebViewIE::SetIEOpticalZoom(wxWebViewZoom level)
431 {
432 int zoom = 100;
433
434 //We make a somewhat arbitray map here, taken from values used by webkit
435 switch(level)
436 {
437 case wxWEBVIEW_ZOOM_TINY:
438 zoom = 60;
439 break;
440 case wxWEBVIEW_ZOOM_SMALL:
441 zoom = 80;
442 break;
443 case wxWEBVIEW_ZOOM_MEDIUM:
444 zoom = 100;
445 break;
446 case wxWEBVIEW_ZOOM_LARGE:
447 zoom = 130;
448 break;
449 case wxWEBVIEW_ZOOM_LARGEST:
450 zoom = 160;
451 break;
452 default:
453 wxFAIL;
454 }
455 SetIEOpticalZoomFactor(zoom);
456 }
457
SetIEOpticalZoomFactor(int zoom)458 void wxWebViewIE::SetIEOpticalZoomFactor(int zoom)
459 {
460 //We do not use OLECMDID_OPTICAL_GETZOOMRANGE as the docs say the range
461 //is 10 to 1000 so the check is unnecessary
462 VARIANT zoomVariant;
463 VariantInit (&zoomVariant);
464 V_VT(&zoomVariant) = VT_I4;
465 V_I4(&zoomVariant) = zoom;
466
467 #if wxDEBUG_LEVEL
468 HRESULT result =
469 #endif
470 m_impl->m_webBrowser->ExecWB((OLECMDID)63 /*OLECMDID_OPTICAL_ZOOM*/,
471 OLECMDEXECOPT_DODEFAULT,
472 &zoomVariant,
473 NULL);
474 wxASSERT(result == S_OK);
475 }
476
GetIEOpticalZoom() const477 wxWebViewZoom wxWebViewIE::GetIEOpticalZoom() const
478 {
479 const int zoom = GetIEOpticalZoomFactor();
480
481 //We make a somewhat arbitray map here, taken from values used by webkit
482 if (zoom <= 65)
483 {
484 return wxWEBVIEW_ZOOM_TINY;
485 }
486 else if (zoom > 65 && zoom <= 90)
487 {
488 return wxWEBVIEW_ZOOM_SMALL;
489 }
490 else if (zoom > 90 && zoom <= 115)
491 {
492 return wxWEBVIEW_ZOOM_MEDIUM;
493 }
494 else if (zoom > 115 && zoom <= 145)
495 {
496 return wxWEBVIEW_ZOOM_LARGE;
497 }
498 else /*if (zoom > 145) */ //Using else removes a compiler warning
499 {
500 return wxWEBVIEW_ZOOM_LARGEST;
501 }
502 }
503
GetIEOpticalZoomFactor() const504 int wxWebViewIE::GetIEOpticalZoomFactor() const
505 {
506 VARIANT zoomVariant;
507 VariantInit (&zoomVariant);
508 V_VT(&zoomVariant) = VT_I4;
509
510 #if wxDEBUG_LEVEL
511 HRESULT result =
512 #endif
513 m_impl->m_webBrowser->ExecWB((OLECMDID)63 /*OLECMDID_OPTICAL_ZOOM*/,
514 OLECMDEXECOPT_DODEFAULT, NULL,
515 &zoomVariant);
516 wxASSERT(result == S_OK);
517
518 const int zoom = V_I4(&zoomVariant);
519
520 return zoom;
521 }
522
SetZoomType(wxWebViewZoomType type)523 void wxWebViewIE::SetZoomType(wxWebViewZoomType type)
524 {
525 m_impl->m_zoomType = type;
526 }
527
GetZoomType() const528 wxWebViewZoomType wxWebViewIE::GetZoomType() const
529 {
530 return m_impl->m_zoomType;
531 }
532
CanSetZoomType(wxWebViewZoomType type) const533 bool wxWebViewIE::CanSetZoomType(wxWebViewZoomType type) const
534 {
535 //IE 6 and below only support text zoom, so check the registry to see what
536 //version we actually have
537 wxRegKey key(wxRegKey::HKLM, "Software\\Microsoft\\Internet Explorer");
538 wxString value;
539 key.QueryValue("Version", value);
540
541 long version = wxAtoi(value.Left(1));
542 if(version <= 6 && type == wxWEBVIEW_ZOOM_TYPE_LAYOUT)
543 return false;
544 else
545 return true;
546 }
547
Print()548 void wxWebViewIE::Print()
549 {
550 m_impl->m_webBrowser->ExecWB(OLECMDID_PRINTPREVIEW,
551 OLECMDEXECOPT_DODEFAULT, NULL, NULL);
552 }
553
CanGoBack() const554 bool wxWebViewIE::CanGoBack() const
555 {
556 if(m_impl->m_historyEnabled)
557 return m_impl->m_historyPosition > 0;
558 else
559 return false;
560 }
561
CanGoForward() const562 bool wxWebViewIE::CanGoForward() const
563 {
564 if(m_impl->m_historyEnabled)
565 return m_impl->m_historyPosition !=
566 static_cast<int>(m_impl->m_historyList.size()) - 1;
567 else
568 return false;
569 }
570
LoadHistoryItem(wxSharedPtr<wxWebViewHistoryItem> item)571 void wxWebViewIE::LoadHistoryItem(wxSharedPtr<wxWebViewHistoryItem> item)
572 {
573 int pos = -1;
574 for(unsigned int i = 0; i < m_impl->m_historyList.size(); i++)
575 {
576 //We compare the actual pointers to find the correct item
577 if(m_impl->m_historyList[i].get() == item.get())
578 pos = i;
579 }
580 wxASSERT_MSG(pos != static_cast<int>(m_impl->m_historyList.size()),
581 "invalid history item");
582 m_impl->m_historyLoadingFromList = true;
583 LoadURL(item->GetUrl());
584 m_impl->m_historyPosition = pos;
585 }
586
GetBackwardHistory()587 wxVector<wxSharedPtr<wxWebViewHistoryItem> > wxWebViewIE::GetBackwardHistory()
588 {
589 wxVector<wxSharedPtr<wxWebViewHistoryItem> > backhist;
590 //As we don't have std::copy or an iterator constructor in the wxwidgets
591 //native vector we construct it by hand
592 for(int i = 0; i < m_impl->m_historyPosition; i++)
593 {
594 backhist.push_back(m_impl->m_historyList[i]);
595 }
596 return backhist;
597 }
598
GetForwardHistory()599 wxVector<wxSharedPtr<wxWebViewHistoryItem> > wxWebViewIE::GetForwardHistory()
600 {
601 wxVector<wxSharedPtr<wxWebViewHistoryItem> > forwardhist;
602 //As we don't have std::copy or an iterator constructor in the wxwidgets
603 //native vector we construct it by hand
604 for(int i = m_impl->m_historyPosition + 1; i < static_cast<int>(m_impl->m_historyList.size()); i++)
605 {
606 forwardhist.push_back(m_impl->m_historyList[i]);
607 }
608 return forwardhist;
609 }
610
GoBack()611 void wxWebViewIE::GoBack()
612 {
613 LoadHistoryItem(m_impl->m_historyList[m_impl->m_historyPosition - 1]);
614 }
615
GoForward()616 void wxWebViewIE::GoForward()
617 {
618 LoadHistoryItem(m_impl->m_historyList[m_impl->m_historyPosition + 1]);
619 }
620
Stop()621 void wxWebViewIE::Stop()
622 {
623 m_impl->m_ie.CallMethod("Stop");
624 }
625
ClearHistory()626 void wxWebViewIE::ClearHistory()
627 {
628 m_impl->m_historyList.clear();
629 m_impl->m_historyPosition = -1;
630 }
631
EnableHistory(bool enable)632 void wxWebViewIE::EnableHistory(bool enable)
633 {
634 m_impl->m_historyEnabled = enable;
635 m_impl->m_historyList.clear();
636 m_impl->m_historyPosition = -1;
637 }
638
Reload(wxWebViewReloadFlags flags)639 void wxWebViewIE::Reload(wxWebViewReloadFlags flags)
640 {
641 VARIANTARG level;
642 VariantInit(&level);
643 V_VT(&level) = VT_I2;
644
645 switch(flags)
646 {
647 case wxWEBVIEW_RELOAD_DEFAULT:
648 V_I2(&level) = REFRESH_NORMAL;
649 break;
650 case wxWEBVIEW_RELOAD_NO_CACHE:
651 V_I2(&level) = REFRESH_COMPLETELY;
652 break;
653 default:
654 wxFAIL_MSG("Unexpected reload type");
655 }
656
657 m_impl->m_webBrowser->Refresh2(&level);
658 }
659
IsOfflineMode()660 bool wxWebViewIE::IsOfflineMode()
661 {
662 wxVariant out = m_impl->m_ie.GetProperty("Offline");
663
664 wxASSERT(out.GetType() == "bool");
665
666 return out.GetBool();
667 }
668
SetOfflineMode(bool offline)669 void wxWebViewIE::SetOfflineMode(bool offline)
670 {
671 #if wxDEBUG_LEVEL
672 const HRESULT success =
673 #endif
674 m_impl->m_ie.PutProperty("Offline", (offline ?
675 VARIANT_TRUE :
676 VARIANT_FALSE));
677 wxASSERT(SUCCEEDED(success));
678 }
679
IsBusy() const680 bool wxWebViewIE::IsBusy() const
681 {
682 if (m_impl->m_isBusy) return true;
683
684 wxVariant out = m_impl->m_ie.GetProperty("Busy");
685
686 wxASSERT(out.GetType() == "bool");
687
688 return out.GetBool();
689 }
690
GetCurrentURL() const691 wxString wxWebViewIE::GetCurrentURL() const
692 {
693 wxVariant out = m_impl->m_ie.GetProperty("LocationURL");
694
695 wxASSERT(out.GetType() == "string");
696 return out.GetString();
697 }
698
GetCurrentTitle() const699 wxString wxWebViewIE::GetCurrentTitle() const
700 {
701 wxCOMPtr<IHTMLDocument2> document(m_impl->GetDocument());
702
703 wxString s;
704 if(document)
705 {
706 wxBasicString title;
707 if ( document->get_nameProp(title.ByRef()) == S_OK )
708 s = title;
709 }
710
711 return s;
712 }
713
CanCut() const714 bool wxWebViewIE::CanCut() const
715 {
716 return m_impl->CanExecCommand("Cut");
717 }
718
CanCopy() const719 bool wxWebViewIE::CanCopy() const
720 {
721 return m_impl->CanExecCommand("Copy");
722 }
723
CanPaste() const724 bool wxWebViewIE::CanPaste() const
725 {
726 return m_impl->CanExecCommand("Paste");
727 }
728
Cut()729 void wxWebViewIE::Cut()
730 {
731 m_impl->ExecCommand("Cut");
732 }
733
Copy()734 void wxWebViewIE::Copy()
735 {
736 m_impl->ExecCommand("Copy");
737 }
738
Paste()739 void wxWebViewIE::Paste()
740 {
741 m_impl->ExecCommand("Paste");
742 }
743
CanUndo() const744 bool wxWebViewIE::CanUndo() const
745 {
746 return m_impl->CanExecCommand("Undo");
747 }
748
CanRedo() const749 bool wxWebViewIE::CanRedo() const
750 {
751 return m_impl->CanExecCommand("Redo");
752 }
753
Undo()754 void wxWebViewIE::Undo()
755 {
756 m_impl->ExecCommand("Undo");
757 }
758
Redo()759 void wxWebViewIE::Redo()
760 {
761 m_impl->ExecCommand("Redo");
762 }
763
Find(const wxString & text,int flags)764 long wxWebViewIE::Find(const wxString& text, int flags)
765 {
766 return m_impl->Find(text, flags);
767 }
768
Find(const wxString & text,int flags)769 long wxWebViewIEImpl::Find(const wxString& text, int flags)
770 {
771 //If the text is empty then we clear.
772 if(text.IsEmpty())
773 {
774 m_webview->ClearSelection();
775 if(m_findFlags & wxWEBVIEW_FIND_HIGHLIGHT_RESULT)
776 {
777 FindInternal(m_findText, (m_findFlags &~ wxWEBVIEW_FIND_HIGHLIGHT_RESULT), wxWEBVIEW_FIND_REMOVE_HIGHLIGHT);
778 }
779 FindClear();
780 return wxNOT_FOUND;
781 }
782 //Have we done this search before?
783 if(m_findText == text)
784 {
785 //Just do a highlight?
786 if((flags & wxWEBVIEW_FIND_HIGHLIGHT_RESULT) != (m_findFlags & wxWEBVIEW_FIND_HIGHLIGHT_RESULT))
787 {
788 m_findFlags = flags;
789 if(!m_findPointers.empty())
790 {
791 FindInternal(m_findText, m_findFlags, ((flags & wxWEBVIEW_FIND_HIGHLIGHT_RESULT) == 0 ? wxWEBVIEW_FIND_REMOVE_HIGHLIGHT : 0));
792 }
793 return m_findPosition;
794 }
795 else if(((m_findFlags & wxWEBVIEW_FIND_ENTIRE_WORD) == (flags & wxWEBVIEW_FIND_ENTIRE_WORD)) && ((m_findFlags & wxWEBVIEW_FIND_MATCH_CASE) == (flags&wxWEBVIEW_FIND_MATCH_CASE)))
796 {
797 m_findFlags = flags;
798 return FindNext(((flags & wxWEBVIEW_FIND_BACKWARDS) ? -1 : 1));
799 }
800 }
801 //Remove old highlight if any.
802 if(m_findFlags & wxWEBVIEW_FIND_HIGHLIGHT_RESULT)
803 {
804 FindInternal(m_findText, (m_findFlags &~ wxWEBVIEW_FIND_HIGHLIGHT_RESULT), wxWEBVIEW_FIND_REMOVE_HIGHLIGHT);
805 }
806 //Reset find variables.
807 FindClear();
808 m_webview->ClearSelection();
809 m_findText = text;
810 m_findFlags = flags;
811 //find the text and return wxNOT_FOUND if there are no matches.
812 FindInternal(text, flags, wxWEBVIEW_FIND_ADD_POINTERS);
813 if(m_findPointers.empty())
814 return wxNOT_FOUND;
815
816 // Or their number if there are.
817 return m_findPointers.size();
818 }
819
SetEditable(bool enable)820 void wxWebViewIE::SetEditable(bool enable)
821 {
822 wxCOMPtr<IHTMLDocument2> document(m_impl->GetDocument());
823
824 if(document)
825 {
826 if( enable )
827 document->put_designMode(wxBasicString("On"));
828 else
829 document->put_designMode(wxBasicString("Off"));
830
831 }
832 }
833
IsEditable() const834 bool wxWebViewIE::IsEditable() const
835 {
836 wxCOMPtr<IHTMLDocument2> document(m_impl->GetDocument());
837
838 if(document)
839 {
840 wxBasicString mode;
841 if ( document->get_designMode(mode.ByRef()) == S_OK )
842 {
843 if ( wxString(mode) == "On" )
844 return true;
845 }
846 }
847 return false;
848 }
849
SelectAll()850 void wxWebViewIE::SelectAll()
851 {
852 m_impl->ExecCommand("SelectAll");
853 }
854
HasSelection() const855 bool wxWebViewIE::HasSelection() const
856 {
857 wxCOMPtr<IHTMLDocument2> document(m_impl->GetDocument());
858
859 if(document)
860 {
861 wxCOMPtr<IHTMLSelectionObject> selection;
862 wxString sel;
863 HRESULT hr = document->get_selection(&selection);
864 if(SUCCEEDED(hr))
865 {
866 wxBasicString type;
867 if ( selection->get_type(type.ByRef()) == S_OK )
868 sel = type;
869 }
870 return sel != "None";
871 }
872 else
873 {
874 return false;
875 }
876 }
877
DeleteSelection()878 void wxWebViewIE::DeleteSelection()
879 {
880 m_impl->ExecCommand("Delete");
881 }
882
GetSelectedText() const883 wxString wxWebViewIE::GetSelectedText() const
884 {
885 wxCOMPtr<IHTMLDocument2> document(m_impl->GetDocument());
886
887 if(document)
888 {
889 wxCOMPtr<IHTMLSelectionObject> selection;
890 wxString selected;
891 HRESULT hr = document->get_selection(&selection);
892 if(SUCCEEDED(hr))
893 {
894 wxCOMPtr<IDispatch> disrange;
895 hr = selection->createRange(&disrange);
896 if(SUCCEEDED(hr))
897 {
898 wxCOMPtr<IHTMLTxtRange> range;
899 hr = disrange->QueryInterface(IID_IHTMLTxtRange, (void**)&range);
900 if(SUCCEEDED(hr))
901 {
902 wxBasicString text;
903 if ( range->get_text(text.ByRef()) == S_OK )
904 selected = text;
905 }
906 }
907 }
908 return selected;
909 }
910 else
911 {
912 return "";
913 }
914 }
915
GetSelectedSource() const916 wxString wxWebViewIE::GetSelectedSource() const
917 {
918 wxCOMPtr<IHTMLDocument2> document(m_impl->GetDocument());
919
920 if(document)
921 {
922 wxCOMPtr<IHTMLSelectionObject> selection;
923 wxString selected;
924 HRESULT hr = document->get_selection(&selection);
925 if(SUCCEEDED(hr))
926 {
927 wxCOMPtr<IDispatch> disrange;
928 hr = selection->createRange(&disrange);
929 if(SUCCEEDED(hr))
930 {
931 wxCOMPtr<IHTMLTxtRange> range;
932 hr = disrange->QueryInterface(IID_IHTMLTxtRange, (void**)&range);
933 if(SUCCEEDED(hr))
934 {
935 wxBasicString text;
936 if ( range->get_htmlText(text.ByRef()) == S_OK )
937 selected = text;
938 }
939 }
940 }
941 return selected;
942 }
943 else
944 {
945 return "";
946 }
947 }
948
ClearSelection()949 void wxWebViewIE::ClearSelection()
950 {
951 wxCOMPtr<IHTMLDocument2> document(m_impl->GetDocument());
952
953 if(document)
954 {
955 wxCOMPtr<IHTMLSelectionObject> selection;
956 wxString selected;
957 HRESULT hr = document->get_selection(&selection);
958 if(SUCCEEDED(hr))
959 {
960 selection->empty();
961 }
962 }
963 }
964
GetPageText() const965 wxString wxWebViewIE::GetPageText() const
966 {
967 wxCOMPtr<IHTMLDocument2> document(m_impl->GetDocument());
968
969 if(document)
970 {
971 wxString text;
972 wxCOMPtr<IHTMLElement> body;
973 HRESULT hr = document->get_body(&body);
974 if(SUCCEEDED(hr))
975 {
976 wxBasicString out;
977 if ( body->get_innerText(out.ByRef()) == S_OK )
978 text = out;
979 }
980 return text;
981 }
982 else
983 {
984 return "";
985 }
986 }
987
MSWSetEmulationLevel(wxWebViewIE_EmulationLevel level)988 bool wxWebViewIE::MSWSetEmulationLevel(wxWebViewIE_EmulationLevel level)
989 {
990 // Registry key where emulation level for programs are set
991 static const wxChar* IE_EMULATION_KEY =
992 wxT("SOFTWARE\\Microsoft\\Internet Explorer\\Main")
993 wxT("\\FeatureControl\\FEATURE_BROWSER_EMULATION");
994
995 wxRegKey key(wxRegKey::HKCU, IE_EMULATION_KEY);
996 if ( !key.Exists() )
997 {
998 wxLogWarning(_("Failed to find web view emulation level in the registry"));
999 return false;
1000 }
1001
1002 const wxString programName = wxGetFullModuleName().AfterLast('\\');
1003 if ( level != wxWEBVIEWIE_EMU_DEFAULT )
1004 {
1005 if ( !key.SetValue(programName, level) )
1006 {
1007 wxLogWarning(_("Failed to set web view to modern emulation level"));
1008 return false;
1009 }
1010 }
1011 else
1012 {
1013 if ( !key.DeleteValue(programName) )
1014 {
1015 wxLogWarning(_("Failed to reset web view to standard emulation level"));
1016 return false;
1017 }
1018 }
1019
1020 return true;
1021 }
1022
1023 static
CallEval(const wxString & code,wxAutomationObject & scriptAO,wxVariant * varResult)1024 bool CallEval(const wxString& code,
1025 wxAutomationObject& scriptAO,
1026 wxVariant* varResult)
1027 {
1028 wxVariant varCode(code);
1029 return scriptAO.Invoke("eval", DISPATCH_METHOD, *varResult, 1, &varCode);
1030 }
1031
RunScript(const wxString & javascript,wxString * output) const1032 bool wxWebViewIE::RunScript(const wxString& javascript, wxString* output) const
1033 {
1034 wxCOMPtr<IHTMLDocument2> document(m_impl->GetDocument());
1035 if ( !document )
1036 {
1037 wxLogWarning(_("Can't run JavaScript script without a valid HTML document"));
1038 return false;
1039 }
1040
1041 IDispatch* scriptDispatch = NULL;
1042 if ( FAILED(document->get_Script(&scriptDispatch)) )
1043 {
1044 wxLogWarning(_("Can't get the JavaScript object"));
1045 return false;
1046 }
1047
1048 wxJSScriptWrapper wrapJS(javascript, &m_runScriptCount);
1049
1050 wxAutomationObject scriptAO(scriptDispatch);
1051 wxVariant varResult;
1052
1053 wxString err;
1054 if ( !CallEval(wrapJS.GetWrappedCode(), scriptAO, &varResult) )
1055 {
1056 err = _("failed to evaluate");
1057 }
1058 else if ( varResult.IsType("bool") && varResult.GetBool() )
1059 {
1060 if ( output != NULL )
1061 {
1062 if ( CallEval(wrapJS.GetOutputCode(), scriptAO, &varResult) )
1063 *output = varResult.MakeString();
1064 else
1065 err = _("failed to retrieve execution result");
1066 }
1067
1068 CallEval(wrapJS.GetCleanUpCode(), scriptAO, &varResult);
1069 }
1070 else // result available but not the expected "true"
1071 {
1072 err = varResult.MakeString();
1073 }
1074
1075 if ( !err.empty() )
1076 {
1077 wxLogWarning(_("Error running JavaScript: %s"), varResult.MakeString());
1078 return false;
1079 }
1080
1081 return true;
1082 }
1083
RegisterHandler(wxSharedPtr<wxWebViewHandler> handler)1084 void wxWebViewIE::RegisterHandler(wxSharedPtr<wxWebViewHandler> handler)
1085 {
1086 wxDynamicLibrary urlMon(wxT("urlmon.dll"));
1087 if(urlMon.HasSymbol(wxT("CoInternetGetSession")))
1088 {
1089 typedef HRESULT (WINAPI *CoInternetGetSession_t)(DWORD, wxIInternetSession**, DWORD);
1090 wxDYNLIB_FUNCTION(CoInternetGetSession_t, CoInternetGetSession, urlMon);
1091
1092 ClassFactory* cf = new ClassFactory(handler);
1093 wxIInternetSession* session;
1094 HRESULT res = (*pfnCoInternetGetSession)(0, &session, 0);
1095 if(FAILED(res))
1096 {
1097 wxFAIL_MSG("Could not retrieve internet session");
1098 }
1099
1100 HRESULT hr = session->RegisterNameSpace(cf, CLSID_FileProtocol,
1101 handler->GetName().wc_str(),
1102 0, NULL, 0);
1103 if(FAILED(hr))
1104 {
1105 wxFAIL_MSG("Could not register protocol");
1106 }
1107 m_impl->m_factories.push_back(cf);
1108 }
1109 else
1110 {
1111 wxFAIL_MSG("urlmon does not contain CoInternetGetSession");
1112 }
1113 }
1114
GetNativeBackend() const1115 void* wxWebViewIE::GetNativeBackend() const
1116 {
1117 return m_impl->m_webBrowser;
1118 }
1119
CanExecCommand(wxString command) const1120 bool wxWebViewIEImpl::CanExecCommand(wxString command) const
1121 {
1122 wxCOMPtr<IHTMLDocument2> document(GetDocument());
1123
1124 if(document)
1125 {
1126 VARIANT_BOOL enabled;
1127
1128 document->queryCommandEnabled(wxBasicString(command), &enabled);
1129
1130 return (enabled == VARIANT_TRUE);
1131 }
1132 else
1133 {
1134 return false;
1135 }
1136
1137 }
1138
ExecCommand(wxString command)1139 void wxWebViewIEImpl::ExecCommand(wxString command)
1140 {
1141 wxCOMPtr<IHTMLDocument2> document(GetDocument());
1142
1143 if(document)
1144 {
1145 document->execCommand(wxBasicString(command), VARIANT_FALSE, VARIANT(), NULL);
1146 }
1147 }
1148
GetDocument() const1149 wxCOMPtr<IHTMLDocument2> wxWebViewIEImpl::GetDocument() const
1150 {
1151 wxCOMPtr<IDispatch> dispatch;
1152 wxCOMPtr<IHTMLDocument2> document;
1153 HRESULT result = m_webBrowser->get_Document(&dispatch);
1154 if(dispatch && SUCCEEDED(result))
1155 {
1156 //document is set to null automatically if the interface isn't supported
1157 dispatch->QueryInterface(IID_IHTMLDocument2, (void**)&document);
1158 }
1159 return document;
1160 }
1161
IsElementVisible(wxCOMPtr<IHTMLElement> elm)1162 bool wxWebViewIEImpl::IsElementVisible(wxCOMPtr<IHTMLElement> elm)
1163 {
1164 wxCOMPtr<IHTMLElement> elm1 = elm;
1165 bool is_visible = true;
1166 //This method is not perfect but it does discover most of the hidden elements.
1167 //so if a better solution is found, then please do improve.
1168 while(elm1)
1169 {
1170 wxCOMPtr<wxIHTMLElement2> elm2;
1171 if(SUCCEEDED(elm1->QueryInterface(wxIID_IHTMLElement2, (void**) &elm2)))
1172 {
1173 wxCOMPtr<wxIHTMLCurrentStyle> style;
1174 if(SUCCEEDED(elm2->get_currentStyle(&style)))
1175 {
1176 wxBasicString display_bstr;
1177 wxBasicString visibility_bstr;
1178
1179 //Check if the object has the style display:none.
1180 if((style->get_display(display_bstr.ByRef()) != S_OK) ||
1181 wxString(display_bstr).IsSameAs(wxS("none"), false))
1182 {
1183 is_visible = false;
1184 }
1185 //Check if the object has the style visibility:hidden.
1186 if((is_visible && (style->get_visibility(visibility_bstr.ByRef()) != S_OK)) ||
1187 wxString(visibility_bstr).IsSameAs(wxS("hidden"), false))
1188 {
1189 is_visible = false;
1190 }
1191 style->Release();
1192 }
1193 elm2->Release();
1194 }
1195
1196 //Lets check the object's parent element.
1197 IHTMLElement* parent;
1198 if(is_visible && SUCCEEDED(elm1->get_parentElement(&parent)))
1199 {
1200 elm1 = parent;
1201 }
1202 else
1203 {
1204 elm1->Release();
1205 break;
1206 }
1207 }
1208 return is_visible;
1209 }
1210
FindInternal(const wxString & text,int flags,int internal_flag)1211 void wxWebViewIEImpl::FindInternal(const wxString& text, int flags, int internal_flag)
1212 {
1213 long find_flag = 0;
1214 wxCOMPtr<wxIMarkupServices> pIMS;
1215 wxCOMPtr<IHTMLDocument2> document = GetDocument();
1216
1217 //This function does the acutal work.
1218 if(document && SUCCEEDED(document->QueryInterface(wxIID_IMarkupServices, (void **)&pIMS)))
1219 {
1220 wxCOMPtr<wxIMarkupContainer> pIMC;
1221 if(SUCCEEDED(document->QueryInterface(wxIID_IMarkupContainer, (void **)&pIMC)))
1222 {
1223 wxCOMPtr<wxIMarkupPointer> ptrBegin, ptrEnd;
1224 wxBasicString attr_bstr(wxS("style=\"background-color:#ffff00\""));
1225 wxBasicString text_bstr(text);
1226
1227 pIMS->CreateMarkupPointer(&ptrBegin);
1228 pIMS->CreateMarkupPointer(&ptrEnd);
1229
1230 ptrBegin->SetGravity(wxPOINTER_GRAVITY_Right);
1231 ptrBegin->MoveToContainer(pIMC, TRUE);
1232 //Create the find flag from the wx one.
1233 if(flags & wxWEBVIEW_FIND_ENTIRE_WORD)
1234 {
1235 find_flag |= wxFINDTEXT_WHOLEWORD;
1236 }
1237 if(flags & wxWEBVIEW_FIND_MATCH_CASE)
1238 {
1239 find_flag |= wxFINDTEXT_MATCHCASE;
1240 }
1241
1242 //A little speed-up to avoid to re-alloc in the positions vector.
1243 if(text.Len() < 3 && m_findPointers.capacity() < 500)
1244 {
1245 m_findPointers.reserve(text.Len() == 1 ? 1000 : 500);
1246 }
1247
1248 while(ptrBegin->FindText(text_bstr, find_flag, ptrEnd, NULL) == S_OK)
1249 {
1250 wxCOMPtr<IHTMLElement> elm;
1251 if(ptrBegin->CurrentScope(&elm) == S_OK)
1252 {
1253 if(IsElementVisible(elm))
1254 {
1255 //Highlight the word if the flag was set.
1256 if(flags & wxWEBVIEW_FIND_HIGHLIGHT_RESULT)
1257 {
1258 IHTMLElement* pFontEl;
1259 pIMS->CreateElement(wxTAGID_FONT, attr_bstr, &pFontEl);
1260 pIMS->InsertElement(pFontEl, ptrBegin, ptrEnd);
1261 }
1262 if(internal_flag & wxWEBVIEW_FIND_REMOVE_HIGHLIGHT)
1263 {
1264 IHTMLElement* pFontEl;
1265 ptrBegin->CurrentScope(&pFontEl);
1266 pIMS->RemoveElement(pFontEl);
1267 pFontEl->Release();
1268 }
1269 if(internal_flag & wxWEBVIEW_FIND_ADD_POINTERS)
1270 {
1271 wxIMarkupPointer *cptrBegin, *cptrEnd;
1272 pIMS->CreateMarkupPointer(&cptrBegin);
1273 pIMS->CreateMarkupPointer(&cptrEnd);
1274 cptrBegin->MoveToPointer(ptrBegin);
1275 cptrEnd->MoveToPointer(ptrEnd);
1276 m_findPointers.push_back(wxFindPointers(cptrBegin,cptrEnd));
1277 }
1278 }
1279 }
1280 ptrBegin->MoveToPointer(ptrEnd);
1281 }
1282 }
1283 }
1284 }
1285
FindNext(int direction)1286 long wxWebViewIEImpl::FindNext(int direction)
1287 {
1288 //Don't bother if we have no pointers set.
1289 if(m_findPointers.empty())
1290 {
1291 return wxNOT_FOUND;
1292 }
1293 //Manage the find position and do some checks.
1294 if(direction > 0)
1295 {
1296 m_findPosition++;
1297 }
1298 else
1299 {
1300 m_findPosition--;
1301 }
1302
1303 if(m_findPosition >= (signed)m_findPointers.size())
1304 {
1305 if(m_findFlags & wxWEBVIEW_FIND_WRAP)
1306 {
1307 m_findPosition = 0;
1308 }
1309 else
1310 {
1311 m_findPosition--;
1312 return wxNOT_FOUND;
1313 }
1314 }
1315 else if(m_findPosition < 0)
1316 {
1317 if(m_findFlags & wxWEBVIEW_FIND_WRAP)
1318 {
1319 m_findPosition = m_findPointers.size()-1;
1320 }
1321 else
1322 {
1323 m_findPosition++;
1324 return wxNOT_FOUND;
1325 }
1326 }
1327
1328 wxCOMPtr<IHTMLDocument2> document = GetDocument();
1329 wxCOMPtr<IHTMLElement> body_element;
1330
1331 long ret = -1;
1332 //Now try to create a range from the body.
1333 if(document && SUCCEEDED(document->get_body(&body_element)))
1334 {
1335 wxCOMPtr<IHTMLBodyElement> body;
1336 if(SUCCEEDED(body_element->QueryInterface(IID_IHTMLBodyElement,(void**)&body)))
1337 {
1338 wxCOMPtr<wxIHTMLTxtRange> range;
1339 if(SUCCEEDED(body->createTextRange((IHTMLTxtRange**)(&range))))
1340 {
1341 wxCOMPtr<wxIMarkupServices> pIMS;
1342 //So far so good, now we try to position our find pointers.
1343 if(SUCCEEDED(document->QueryInterface(wxIID_IMarkupServices,(void **)&pIMS)))
1344 {
1345 wxIMarkupPointer *begin = m_findPointers[m_findPosition].begin, *end = m_findPointers[m_findPosition].end;
1346 if(pIMS->MoveRangeToPointers(begin,end,range) == S_OK && range->select() == S_OK)
1347 {
1348 ret = m_findPosition;
1349 }
1350 }
1351 }
1352 }
1353 }
1354 return ret;
1355 }
1356
FindClear()1357 void wxWebViewIEImpl::FindClear()
1358 {
1359 //Reset find variables.
1360 m_findText.Empty();
1361 m_findFlags = wxWEBVIEW_FIND_DEFAULT;
1362 m_findPosition = -1;
1363
1364 //The m_findPointers contains pointers for the found text.
1365 //Since it uses ref counting we call release on the pointers first
1366 //before we remove them from the vector. In other words do not just
1367 //remove elements from m_findPointers without calling release first
1368 //or you will get a memory leak.
1369 size_t count = m_findPointers.size();
1370 for(size_t i = 0; i < count; i++)
1371 {
1372 m_findPointers[i].begin->Release();
1373 m_findPointers[i].end->Release();
1374 }
1375 m_findPointers.clear();
1376 }
1377
EnableControlFeature(long flag,bool enable)1378 bool wxWebViewIEImpl::EnableControlFeature(long flag, bool enable)
1379 {
1380 #if wxUSE_DYNLIB_CLASS
1381
1382 wxDynamicLibrary urlMon(wxT("urlmon.dll"));
1383 if( urlMon.IsLoaded() &&
1384 urlMon.HasSymbol("CoInternetSetFeatureEnabled") &&
1385 urlMon.HasSymbol("CoInternetIsFeatureEnabled"))
1386 {
1387 typedef HRESULT (WINAPI *CoInternetSetFeatureEnabled_t)(DWORD, DWORD, BOOL);
1388 typedef HRESULT (WINAPI *CoInternetIsFeatureEnabled_t)(DWORD, DWORD);
1389
1390 wxDYNLIB_FUNCTION(CoInternetSetFeatureEnabled_t, CoInternetSetFeatureEnabled, urlMon);
1391 wxDYNLIB_FUNCTION(CoInternetIsFeatureEnabled_t, CoInternetIsFeatureEnabled, urlMon);
1392
1393 HRESULT hr = (*pfnCoInternetIsFeatureEnabled)(flag,
1394 0x2 /* SET_FEATURE_ON_PROCESS */);
1395 if((hr == S_OK && enable) || (hr == S_FALSE && !enable))
1396 return true;
1397
1398 hr = (*pfnCoInternetSetFeatureEnabled)(flag,
1399 0x2/* SET_FEATURE_ON_PROCESS */,
1400 (enable ? TRUE : FALSE));
1401 if ( FAILED(hr) )
1402 {
1403 wxLogApiError(wxT("CoInternetSetFeatureEnabled"), hr);
1404 return false;
1405 }
1406 return true;
1407 }
1408 return false;
1409 #else
1410 wxUnusedVar(flag);
1411 wxUnusedVar(enable);
1412 return false;
1413 #endif // wxUSE_DYNLIB_CLASS/!wxUSE_DYNLIB_CLASS
1414 }
1415
onActiveXEvent(wxActiveXEvent & evt)1416 void wxWebViewIE::onActiveXEvent(wxActiveXEvent& evt)
1417 {
1418 if (m_impl->m_webBrowser == NULL) return;
1419
1420 switch (evt.GetDispatchId())
1421 {
1422 case DISPID_BEFORENAVIGATE2:
1423 {
1424 m_impl->m_isBusy = true;
1425
1426 wxString url = evt[1].GetString();
1427 wxString target = evt[3].GetString();
1428
1429 wxWebViewEvent event(wxEVT_WEBVIEW_NAVIGATING,
1430 GetId(), url, target);
1431
1432 //skip empty javascript events.
1433 if(url == "javascript:\"\"" && target.IsEmpty())
1434 {
1435 event.Veto();
1436 }
1437 else
1438 {
1439 event.SetEventObject(this);
1440 HandleWindowEvent(event);
1441 }
1442
1443 if (!event.IsAllowed())
1444 {
1445 wxActiveXEventNativeMSW* nativeParams =
1446 evt.GetNativeParameters();
1447 *V_BOOLREF(&nativeParams->pDispParams->rgvarg[0]) = VARIANT_TRUE;
1448 }
1449
1450 // at this point, either the navigation event has been cancelled
1451 // and we're not busy, either it was accepted and IWebBrowser2's
1452 // Busy property will be true; so we don't need our override
1453 // flag anymore.
1454 m_impl->m_isBusy = false;
1455
1456 break;
1457 }
1458
1459 case DISPID_NAVIGATECOMPLETE2:
1460 {
1461 wxString url = evt[1].GetString();
1462 // TODO: set target parameter if possible
1463 wxString target;
1464 wxWebViewEvent event(wxEVT_WEBVIEW_NAVIGATED,
1465 GetId(), url, target);
1466 event.SetEventObject(this);
1467 HandleWindowEvent(event);
1468 break;
1469 }
1470
1471 case DISPID_PROGRESSCHANGE:
1472 {
1473 // download progress
1474 break;
1475 }
1476
1477 case DISPID_DOCUMENTCOMPLETE:
1478 {
1479 //Only send a complete even if we are actually finished, this brings
1480 //the event in to line with webkit
1481 READYSTATE rs;
1482 m_impl->m_webBrowser->get_ReadyState( &rs );
1483 if(rs != READYSTATE_COMPLETE)
1484 break;
1485
1486 wxString url = evt[1].GetString();
1487
1488 //As we are complete we also add to the history list, but not if the
1489 //page is not the main page, ie it is a subframe
1490 //We also have to check if we are loading a file:// url, if so we
1491 //need to change the comparison as ie passes back a different style
1492 //of url
1493 if(m_impl->m_historyEnabled && !m_impl->m_historyLoadingFromList &&
1494 (url == GetCurrentURL() ||
1495 (GetCurrentURL().substr(0, 4) == "file" &&
1496 wxFileName::URLToFileName(GetCurrentURL()).GetFullPath() == url)))
1497 {
1498 //If we are not at the end of the list, then erase everything
1499 //between us and the end before adding the new page
1500 if(m_impl->m_historyPosition != static_cast<int>(m_impl->m_historyList.size()) - 1)
1501 {
1502 m_impl->m_historyList.erase(m_impl->m_historyList.begin() + m_impl->m_historyPosition + 1,
1503 m_impl->m_historyList.end());
1504 }
1505 wxSharedPtr<wxWebViewHistoryItem> item(new wxWebViewHistoryItem(url, GetCurrentTitle()));
1506 m_impl->m_historyList.push_back(item);
1507 m_impl->m_historyPosition++;
1508 }
1509 //Reset as we are done now
1510 m_impl->m_historyLoadingFromList = false;
1511 //Reset the find values.
1512 m_impl->FindClear();
1513 // TODO: set target parameter if possible
1514 wxString target;
1515 wxWebViewEvent event(wxEVT_WEBVIEW_LOADED, GetId(),
1516 url, target);
1517 event.SetEventObject(this);
1518 HandleWindowEvent(event);
1519 break;
1520 }
1521
1522 case DISPID_STATUSTEXTCHANGE:
1523 {
1524 break;
1525 }
1526
1527 case DISPID_TITLECHANGE:
1528 {
1529 wxString title = evt[0].GetString();
1530
1531 wxWebViewEvent event(wxEVT_WEBVIEW_TITLE_CHANGED,
1532 GetId(), GetCurrentURL(), "");
1533 event.SetString(title);
1534 event.SetEventObject(this);
1535 HandleWindowEvent(event);
1536 break;
1537 }
1538
1539 case DISPID_NAVIGATEERROR:
1540 {
1541 wxWebViewEvent event(wxEVT_WEBVIEW_ERROR, GetId(),
1542 evt[1].GetString(), evt[2].GetString());
1543 event.SetEventObject(this);
1544
1545 switch (evt[3].GetLong())
1546 {
1547 // 400 Error codes
1548 WX_ERROR_CASE(HTTP_STATUS_BAD_REQUEST, wxWEBVIEW_NAV_ERR_REQUEST)
1549 WX_ERROR_CASE(HTTP_STATUS_DENIED, wxWEBVIEW_NAV_ERR_AUTH)
1550 WX_ERROR_CASE(HTTP_STATUS_PAYMENT_REQ, wxWEBVIEW_NAV_ERR_OTHER)
1551 WX_ERROR_CASE(HTTP_STATUS_FORBIDDEN, wxWEBVIEW_NAV_ERR_AUTH)
1552 WX_ERROR_CASE(HTTP_STATUS_NOT_FOUND, wxWEBVIEW_NAV_ERR_NOT_FOUND)
1553 WX_ERROR_CASE(HTTP_STATUS_BAD_METHOD, wxWEBVIEW_NAV_ERR_REQUEST)
1554 WX_ERROR_CASE(HTTP_STATUS_NONE_ACCEPTABLE, wxWEBVIEW_NAV_ERR_OTHER)
1555 WX_ERROR_CASE(HTTP_STATUS_PROXY_AUTH_REQ, wxWEBVIEW_NAV_ERR_AUTH)
1556 WX_ERROR_CASE(HTTP_STATUS_REQUEST_TIMEOUT, wxWEBVIEW_NAV_ERR_CONNECTION)
1557 WX_ERROR_CASE(HTTP_STATUS_CONFLICT, wxWEBVIEW_NAV_ERR_REQUEST)
1558 WX_ERROR_CASE(HTTP_STATUS_GONE, wxWEBVIEW_NAV_ERR_NOT_FOUND)
1559 WX_ERROR_CASE(HTTP_STATUS_LENGTH_REQUIRED, wxWEBVIEW_NAV_ERR_REQUEST)
1560 WX_ERROR_CASE(HTTP_STATUS_PRECOND_FAILED, wxWEBVIEW_NAV_ERR_REQUEST)
1561 WX_ERROR_CASE(HTTP_STATUS_REQUEST_TOO_LARGE, wxWEBVIEW_NAV_ERR_REQUEST)
1562 WX_ERROR_CASE(HTTP_STATUS_URI_TOO_LONG, wxWEBVIEW_NAV_ERR_REQUEST)
1563 WX_ERROR_CASE(HTTP_STATUS_UNSUPPORTED_MEDIA, wxWEBVIEW_NAV_ERR_REQUEST)
1564 WX_ERROR_CASE(HTTP_STATUS_RETRY_WITH, wxWEBVIEW_NAV_ERR_OTHER)
1565
1566 // 500 - Error codes
1567 WX_ERROR_CASE(HTTP_STATUS_SERVER_ERROR, wxWEBVIEW_NAV_ERR_CONNECTION)
1568 WX_ERROR_CASE(HTTP_STATUS_NOT_SUPPORTED, wxWEBVIEW_NAV_ERR_CONNECTION)
1569 WX_ERROR_CASE(HTTP_STATUS_BAD_GATEWAY, wxWEBVIEW_NAV_ERR_CONNECTION)
1570 WX_ERROR_CASE(HTTP_STATUS_SERVICE_UNAVAIL, wxWEBVIEW_NAV_ERR_CONNECTION)
1571 WX_ERROR_CASE(HTTP_STATUS_GATEWAY_TIMEOUT, wxWEBVIEW_NAV_ERR_CONNECTION)
1572 WX_ERROR_CASE(HTTP_STATUS_VERSION_NOT_SUP, wxWEBVIEW_NAV_ERR_REQUEST)
1573
1574 // URL Moniker error codes
1575 WX_ERROR_CASE(INET_E_INVALID_URL, wxWEBVIEW_NAV_ERR_REQUEST)
1576 WX_ERROR_CASE(INET_E_NO_SESSION, wxWEBVIEW_NAV_ERR_CONNECTION)
1577 WX_ERROR_CASE(INET_E_CANNOT_CONNECT, wxWEBVIEW_NAV_ERR_CONNECTION)
1578 WX_ERROR_CASE(INET_E_RESOURCE_NOT_FOUND, wxWEBVIEW_NAV_ERR_NOT_FOUND)
1579 WX_ERROR_CASE(INET_E_OBJECT_NOT_FOUND, wxWEBVIEW_NAV_ERR_NOT_FOUND)
1580 WX_ERROR_CASE(INET_E_DATA_NOT_AVAILABLE, wxWEBVIEW_NAV_ERR_NOT_FOUND)
1581 WX_ERROR_CASE(INET_E_DOWNLOAD_FAILURE, wxWEBVIEW_NAV_ERR_CONNECTION)
1582 WX_ERROR_CASE(INET_E_AUTHENTICATION_REQUIRED, wxWEBVIEW_NAV_ERR_AUTH)
1583 WX_ERROR_CASE(INET_E_NO_VALID_MEDIA, wxWEBVIEW_NAV_ERR_REQUEST)
1584 WX_ERROR_CASE(INET_E_CONNECTION_TIMEOUT, wxWEBVIEW_NAV_ERR_CONNECTION)
1585 WX_ERROR_CASE(INET_E_INVALID_REQUEST, wxWEBVIEW_NAV_ERR_REQUEST)
1586 WX_ERROR_CASE(INET_E_UNKNOWN_PROTOCOL, wxWEBVIEW_NAV_ERR_REQUEST)
1587 WX_ERROR_CASE(INET_E_SECURITY_PROBLEM, wxWEBVIEW_NAV_ERR_SECURITY)
1588 WX_ERROR_CASE(INET_E_CANNOT_LOAD_DATA, wxWEBVIEW_NAV_ERR_OTHER)
1589 WX_ERROR_CASE(INET_E_REDIRECT_FAILED, wxWEBVIEW_NAV_ERR_OTHER)
1590 WX_ERROR_CASE(INET_E_REDIRECT_TO_DIR, wxWEBVIEW_NAV_ERR_REQUEST)
1591 WX_ERROR_CASE(INET_E_CANNOT_LOCK_REQUEST, wxWEBVIEW_NAV_ERR_OTHER)
1592 WX_ERROR_CASE(INET_E_USE_EXTEND_BINDING, wxWEBVIEW_NAV_ERR_OTHER)
1593 WX_ERROR_CASE(INET_E_TERMINATED_BIND, wxWEBVIEW_NAV_ERR_OTHER)
1594 WX_ERROR_CASE(INET_E_INVALID_CERTIFICATE, wxWEBVIEW_NAV_ERR_CERTIFICATE)
1595 WX_ERROR_CASE(INET_E_CODE_DOWNLOAD_DECLINED, wxWEBVIEW_NAV_ERR_USER_CANCELLED)
1596 WX_ERROR_CASE(INET_E_RESULT_DISPATCHED, wxWEBVIEW_NAV_ERR_OTHER)
1597 WX_ERROR_CASE(INET_E_CANNOT_REPLACE_SFP_FILE, wxWEBVIEW_NAV_ERR_SECURITY)
1598 WX_ERROR_CASE(INET_E_CODE_INSTALL_BLOCKED_BY_HASH_POLICY, wxWEBVIEW_NAV_ERR_SECURITY)
1599 WX_ERROR_CASE(INET_E_CODE_INSTALL_SUPPRESSED, wxWEBVIEW_NAV_ERR_SECURITY)
1600 }
1601 HandleWindowEvent(event);
1602 break;
1603 }
1604 case DISPID_NEWWINDOW3:
1605 {
1606 wxString url = evt[4].GetString();
1607 long flags = evt[2].GetLong();
1608
1609 wxWebViewNavigationActionFlags navFlags = wxWEBVIEW_NAV_ACTION_OTHER;
1610
1611 if(flags & wxNWMF_USERINITED || flags & wxNWMF_USERREQUESTED)
1612 navFlags = wxWEBVIEW_NAV_ACTION_USER;
1613
1614 wxWebViewEvent event(wxEVT_WEBVIEW_NEWWINDOW,
1615 GetId(), url, wxEmptyString, navFlags);
1616 event.SetEventObject(this);
1617 HandleWindowEvent(event);
1618
1619 //We always cancel this event otherwise an Internet Exporer window
1620 //is opened for the url
1621 wxActiveXEventNativeMSW* nativeParams = evt.GetNativeParameters();
1622 *V_BOOLREF(&nativeParams->pDispParams->rgvarg[3]) = VARIANT_TRUE;
1623 break;
1624 }
1625 }
1626
1627 evt.Skip();
1628 }
1629
VirtualProtocol(wxSharedPtr<wxWebViewHandler> handler)1630 VirtualProtocol::VirtualProtocol(wxSharedPtr<wxWebViewHandler> handler)
1631 {
1632 m_file = NULL;
1633 m_handler = handler;
1634 }
1635
QueryInterface(REFIID riid,void ** ppv)1636 STDMETHODIMP VirtualProtocol::QueryInterface(REFIID riid, void **ppv)
1637 {
1638 wxLogQueryInterface(wxT("VirtualProtocol"), riid);
1639
1640 if(riid == IID_IUnknown)
1641 {
1642 wxIInternetProtocolRoot *InternetProtocolRoot = this;
1643 IUnknown *Unknown = InternetProtocolRoot;
1644 *ppv = Unknown;
1645 AddRef();
1646 return S_OK;
1647 }
1648 if(riid == wxIID_IInternetProtocolRoot)
1649 {
1650 wxIInternetProtocolRoot *InternetProtocolRoot = this;
1651 *ppv = InternetProtocolRoot;
1652 AddRef();
1653 return S_OK;
1654 }
1655 if(riid == wxIID_IInternetProtocol)
1656 {
1657 wxIInternetProtocol *InternetProtocol = this;
1658 *ppv = InternetProtocol;
1659 AddRef();
1660 return S_OK;
1661 }
1662 if(riid == wxIID_IInternetProtocolInfo)
1663 {
1664 wxIInternetProtocolInfo *InternetProtocolInfo = this;
1665 *ppv = InternetProtocolInfo;
1666 AddRef();
1667 return S_OK;
1668 }
1669
1670 *ppv = NULL;
1671 return (HRESULT) E_NOINTERFACE;
1672 }
1673
STDMETHODIMP_(ULONG)1674 STDMETHODIMP_(ULONG) VirtualProtocol::AddRef()
1675 {
1676 wxLogAddRef(wxT("VirtualProtocol"), m_cRef);
1677 return ++m_cRef;
1678 }
1679
STDMETHODIMP_(ULONG)1680 STDMETHODIMP_(ULONG) VirtualProtocol::Release()
1681 {
1682 wxLogRelease(wxT("VirtualProtocol"), m_cRef);
1683 if( --m_cRef == wxAutoULong(0))
1684 {
1685 delete this;
1686 return 0;
1687 }
1688 else
1689 return m_cRef;
1690 }
1691
Start(LPCWSTR szUrl,wxIInternetProtocolSink * pOIProtSink,wxIInternetBindInfo * pOIBindInfo,DWORD grfPI,HANDLE_PTR dwReserved)1692 HRESULT STDMETHODCALLTYPE VirtualProtocol::Start(LPCWSTR szUrl, wxIInternetProtocolSink *pOIProtSink,
1693 wxIInternetBindInfo *pOIBindInfo, DWORD grfPI,
1694 HANDLE_PTR dwReserved)
1695 {
1696 wxUnusedVar(szUrl);
1697 wxUnusedVar(pOIBindInfo);
1698 wxUnusedVar(grfPI);
1699 wxUnusedVar(dwReserved);
1700 m_protocolSink = pOIProtSink;
1701
1702 //We get the file itself from the protocol handler
1703 m_file = m_handler->GetFile(szUrl);
1704
1705
1706 if(!m_file)
1707 return INET_E_RESOURCE_NOT_FOUND;
1708
1709 //We return the stream length for current and total size as we can always
1710 //read the whole file from the stream
1711 wxFileOffset length = m_file->GetStream()->GetLength();
1712 m_protocolSink->ReportData(wxBSCF_FIRSTDATANOTIFICATION |
1713 wxBSCF_DATAFULLYAVAILABLE |
1714 wxBSCF_LASTDATANOTIFICATION,
1715 length, length);
1716 return S_OK;
1717 }
1718
Read(void * pv,ULONG cb,ULONG * pcbRead)1719 HRESULT STDMETHODCALLTYPE VirtualProtocol::Read(void *pv, ULONG cb, ULONG *pcbRead)
1720 {
1721 //If the file is null we return false to indicte it is finished
1722 if(!m_file)
1723 return S_FALSE;
1724
1725 wxStreamError err = m_file->GetStream()->Read(pv, cb).GetLastError();
1726 *pcbRead = m_file->GetStream()->LastRead();
1727
1728 if(err == wxSTREAM_NO_ERROR)
1729 {
1730 if(*pcbRead < cb)
1731 {
1732 wxDELETE(m_file);
1733 m_protocolSink->ReportResult(S_OK, 0, NULL);
1734 }
1735 //As we are not eof there is more data
1736 return S_OK;
1737 }
1738 else if(err == wxSTREAM_EOF)
1739 {
1740 wxDELETE(m_file);
1741 m_protocolSink->ReportResult(S_OK, 0, NULL);
1742 //We are eof and so finished
1743 return S_OK;
1744 }
1745 else if(err == wxSTREAM_READ_ERROR)
1746 {
1747 wxDELETE(m_file);
1748 return INET_E_DOWNLOAD_FAILURE;
1749 }
1750 else
1751 {
1752 //Dummy return to suppress a compiler warning
1753 wxFAIL;
1754 return INET_E_DOWNLOAD_FAILURE;
1755 }
1756 }
1757
CombineUrl(LPCWSTR pwzBaseUrl,LPCWSTR pwzRelativeUrl,DWORD dwCombineFlags,LPWSTR pwzResult,DWORD cchResult,DWORD * pcchResult,DWORD dwReserved)1758 HRESULT STDMETHODCALLTYPE VirtualProtocol::CombineUrl(
1759 LPCWSTR pwzBaseUrl, LPCWSTR pwzRelativeUrl,
1760 DWORD dwCombineFlags, LPWSTR pwzResult,
1761 DWORD cchResult, DWORD *pcchResult,
1762 DWORD dwReserved)
1763 {
1764 wxUnusedVar(pwzBaseUrl);
1765 wxUnusedVar(pwzRelativeUrl);
1766 wxUnusedVar(dwCombineFlags);
1767 wxUnusedVar(pwzResult);
1768 wxUnusedVar(cchResult);
1769 wxUnusedVar(pcchResult);
1770 wxUnusedVar(dwReserved);
1771
1772 return INET_E_DEFAULT_ACTION;
1773 }
1774
ParseUrl(LPCWSTR pwzUrl,wxPARSEACTION ParseAction,DWORD dwParseFlags,LPWSTR pwzResult,DWORD cchResult,DWORD * pcchResult,DWORD dwReserved)1775 HRESULT STDMETHODCALLTYPE VirtualProtocol::ParseUrl(
1776 LPCWSTR pwzUrl, wxPARSEACTION ParseAction,
1777 DWORD dwParseFlags, LPWSTR pwzResult,
1778 DWORD cchResult, DWORD *pcchResult,
1779 DWORD dwReserved)
1780 {
1781 wxUnusedVar(pwzUrl);
1782 wxUnusedVar(dwParseFlags);
1783 wxUnusedVar(dwReserved);
1784
1785 const size_t secLen = m_handler->GetSecurityURL().length();
1786 if ( secLen > 0 )
1787 {
1788 switch ( ParseAction )
1789 {
1790 case wxPARSE_SECURITY_URL:
1791 case wxPARSE_SECURITY_DOMAIN:
1792 {
1793 if ( cchResult < secLen )
1794 return S_FALSE;
1795 wcscpy(pwzResult, m_handler->GetSecurityURL().wc_str());
1796 *pcchResult = secLen;
1797 return S_OK;
1798 }
1799 }
1800 }
1801
1802 return INET_E_DEFAULT_ACTION;
1803 }
1804
CompareUrl(LPCWSTR pwzUrl1,LPCWSTR pwzUrl2,DWORD dwCompareFlags)1805 HRESULT STDMETHODCALLTYPE VirtualProtocol::CompareUrl(
1806 LPCWSTR pwzUrl1,
1807 LPCWSTR pwzUrl2,
1808 DWORD dwCompareFlags)
1809 {
1810 wxUnusedVar(pwzUrl1);
1811 wxUnusedVar(pwzUrl2);
1812 wxUnusedVar(dwCompareFlags);
1813
1814 return INET_E_DEFAULT_ACTION;
1815 }
1816
QueryInfo(LPCWSTR pwzUrl,wxQUERYOPTION OueryOption,DWORD dwQueryFlags,LPVOID pBuffer,DWORD cbBuffer,DWORD * pcbBuf,DWORD dwReserved)1817 HRESULT STDMETHODCALLTYPE VirtualProtocol::QueryInfo(
1818 LPCWSTR pwzUrl, wxQUERYOPTION OueryOption,
1819 DWORD dwQueryFlags, LPVOID pBuffer,
1820 DWORD cbBuffer, DWORD *pcbBuf,
1821 DWORD dwReserved)
1822 {
1823 wxUnusedVar(pwzUrl);
1824 wxUnusedVar(OueryOption);
1825 wxUnusedVar(dwQueryFlags);
1826 wxUnusedVar(pBuffer);
1827 wxUnusedVar(cbBuffer);
1828 wxUnusedVar(pcbBuf);
1829 wxUnusedVar(dwReserved);
1830
1831 return INET_E_DEFAULT_ACTION;
1832 }
1833
1834 BEGIN_IID_TABLE(ClassFactory)
1835 ADD_IID(Unknown)
1836 ADD_IID(ClassFactory)
1837 END_IID_TABLE;
1838
IMPLEMENT_IUNKNOWN_METHODS(ClassFactory)1839 IMPLEMENT_IUNKNOWN_METHODS(ClassFactory)
1840
1841 HRESULT STDMETHODCALLTYPE ClassFactory::CreateInstance(IUnknown* pUnkOuter, REFIID riid,
1842 void ** ppvObject)
1843 {
1844 if (pUnkOuter)
1845 return CLASS_E_NOAGGREGATION;
1846 VirtualProtocol* vp = new VirtualProtocol(m_handler);
1847 vp->AddRef();
1848 HRESULT hr = vp->QueryInterface(riid, ppvObject);
1849 vp->Release();
1850 return hr;
1851
1852 }
1853
LockServer(BOOL fLock)1854 STDMETHODIMP ClassFactory::LockServer(BOOL fLock)
1855 {
1856 wxUnusedVar(fLock);
1857 return S_OK;
1858 }
1859
wxIEContainer(wxWindow * parent,REFIID iid,IUnknown * pUnk,DocHostUIHandler * uiHandler)1860 wxIEContainer::wxIEContainer(wxWindow *parent, REFIID iid, IUnknown *pUnk,
1861 DocHostUIHandler* uiHandler) :
1862 wxActiveXContainer(parent,iid,pUnk)
1863 {
1864 m_uiHandler = uiHandler;
1865 }
1866
~wxIEContainer()1867 wxIEContainer::~wxIEContainer()
1868 {
1869 }
1870
QueryClientSiteInterface(REFIID iid,void ** _interface,const char * & desc)1871 bool wxIEContainer::QueryClientSiteInterface(REFIID iid, void **_interface,
1872 const char *&desc)
1873 {
1874 if (m_uiHandler && IsEqualIID(iid, wxIID_IDocHostUIHandler))
1875 {
1876 *_interface = (IUnknown *) (wxIDocHostUIHandler *) m_uiHandler;
1877 desc = "IDocHostUIHandler";
1878 return true;
1879 }
1880 return false;
1881 }
1882
ShowContextMenu(DWORD dwID,POINT * ppt,IUnknown * pcmdtReserved,IDispatch * pdispReserved)1883 HRESULT wxSTDCALL DocHostUIHandler::ShowContextMenu(DWORD dwID, POINT *ppt,
1884 IUnknown *pcmdtReserved,
1885 IDispatch *pdispReserved)
1886 {
1887 wxUnusedVar(dwID);
1888 wxUnusedVar(ppt);
1889 wxUnusedVar(pcmdtReserved);
1890 wxUnusedVar(pdispReserved);
1891 if(m_browser->IsContextMenuEnabled())
1892 return E_NOTIMPL;
1893 else
1894 return S_OK;
1895 }
1896
GetHostInfo(DOCHOSTUIINFO * pInfo)1897 HRESULT wxSTDCALL DocHostUIHandler::GetHostInfo(DOCHOSTUIINFO *pInfo)
1898 {
1899 // Don't show 3d border and enable themes and also enable sending redirect
1900 // notifications as otherwise we wouldn't get wxEVT_WEBVIEW_NAVIGATING when
1901 // redirected.
1902 pInfo->dwFlags |= DOCHOSTUIFLAG_NO3DBORDER |
1903 DOCHOSTUIFLAG_THEME |
1904 DOCHOSTUIFLAG_ENABLE_REDIRECT_NOTIFICATION |
1905 DOCHOSTUIFLAG_DPI_AWARE;
1906 return S_OK;
1907 }
1908
ShowUI(DWORD dwID,IOleInPlaceActiveObject * pActiveObject,IOleCommandTarget * pCommandTarget,IOleInPlaceFrame * pFrame,IOleInPlaceUIWindow * pDoc)1909 HRESULT wxSTDCALL DocHostUIHandler::ShowUI(DWORD dwID,
1910 IOleInPlaceActiveObject *pActiveObject,
1911 IOleCommandTarget *pCommandTarget,
1912 IOleInPlaceFrame *pFrame,
1913 IOleInPlaceUIWindow *pDoc)
1914 {
1915 wxUnusedVar(dwID);
1916 wxUnusedVar(pActiveObject);
1917 wxUnusedVar(pCommandTarget);
1918 wxUnusedVar(pFrame);
1919 wxUnusedVar(pDoc);
1920 return S_FALSE;
1921 }
1922
HideUI(void)1923 HRESULT wxSTDCALL DocHostUIHandler::HideUI(void)
1924 {
1925 return E_NOTIMPL;
1926 }
1927
UpdateUI(void)1928 HRESULT wxSTDCALL DocHostUIHandler::UpdateUI(void)
1929 {
1930 return E_NOTIMPL;
1931 }
1932
EnableModeless(BOOL fEnable)1933 HRESULT wxSTDCALL DocHostUIHandler::EnableModeless(BOOL fEnable)
1934 {
1935 wxUnusedVar(fEnable);
1936 return E_NOTIMPL;
1937 }
1938
OnDocWindowActivate(BOOL fActivate)1939 HRESULT wxSTDCALL DocHostUIHandler::OnDocWindowActivate(BOOL fActivate)
1940 {
1941 wxUnusedVar(fActivate);
1942 return E_NOTIMPL;
1943 }
1944
OnFrameWindowActivate(BOOL fActivate)1945 HRESULT wxSTDCALL DocHostUIHandler::OnFrameWindowActivate(BOOL fActivate)
1946 {
1947 wxUnusedVar(fActivate);
1948 return E_NOTIMPL;
1949 }
1950
ResizeBorder(LPCRECT prcBorder,IOleInPlaceUIWindow * pUIWindow,BOOL fFrameWindow)1951 HRESULT wxSTDCALL DocHostUIHandler::ResizeBorder(LPCRECT prcBorder,
1952 IOleInPlaceUIWindow *pUIWindow,
1953 BOOL fFrameWindow)
1954 {
1955 wxUnusedVar(prcBorder);
1956 wxUnusedVar(pUIWindow);
1957 wxUnusedVar(fFrameWindow);
1958 return E_NOTIMPL;
1959 }
1960
TranslateAccelerator(LPMSG lpMsg,const GUID * pguidCmdGroup,DWORD nCmdID)1961 HRESULT wxSTDCALL DocHostUIHandler::TranslateAccelerator(LPMSG lpMsg,
1962 const GUID *pguidCmdGroup,
1963 DWORD nCmdID)
1964 {
1965 if(lpMsg && lpMsg->message == WM_KEYDOWN)
1966 {
1967 // check control is down but that it isn't right-alt which is mapped to
1968 // alt + ctrl
1969 if(GetKeyState(VK_CONTROL) & 0x8000 &&
1970 !(GetKeyState(VK_MENU) & 0x8000))
1971 {
1972 //skip the accelerators used by the control
1973 switch(lpMsg->wParam)
1974 {
1975 case 'F':
1976 case 'L':
1977 case 'N':
1978 case 'O':
1979 case 'P':
1980 return S_OK;
1981 }
1982 }
1983 //skip F5
1984 if(lpMsg->wParam == VK_F5)
1985 {
1986 return S_OK;
1987 }
1988 }
1989
1990 wxUnusedVar(pguidCmdGroup);
1991 wxUnusedVar(nCmdID);
1992 return E_NOTIMPL;
1993 }
1994
GetOptionKeyPath(LPOLESTR * pchKey,DWORD dw)1995 HRESULT wxSTDCALL DocHostUIHandler::GetOptionKeyPath(LPOLESTR *pchKey,DWORD dw)
1996 {
1997 wxUnusedVar(pchKey);
1998 wxUnusedVar(dw);
1999 return E_NOTIMPL;
2000 }
2001
GetDropTarget(IDropTarget * pDropTarget,IDropTarget ** ppDropTarget)2002 HRESULT wxSTDCALL DocHostUIHandler::GetDropTarget(IDropTarget *pDropTarget,
2003 IDropTarget **ppDropTarget)
2004 {
2005 wxUnusedVar(pDropTarget);
2006 wxUnusedVar(ppDropTarget);
2007 return E_NOTIMPL;
2008 }
2009
GetExternal(IDispatch ** ppDispatch)2010 HRESULT wxSTDCALL DocHostUIHandler::GetExternal(IDispatch **ppDispatch)
2011 {
2012 wxUnusedVar(ppDispatch);
2013 return E_NOTIMPL;
2014 }
2015
TranslateUrl(DWORD dwTranslate,OLECHAR * pchURLIn,OLECHAR ** ppchURLOut)2016 HRESULT wxSTDCALL DocHostUIHandler::TranslateUrl(DWORD dwTranslate,
2017 OLECHAR *pchURLIn,
2018 OLECHAR **ppchURLOut)
2019 {
2020 wxUnusedVar(dwTranslate);
2021 wxUnusedVar(pchURLIn);
2022 wxUnusedVar(ppchURLOut);
2023 return E_NOTIMPL;
2024 }
2025
FilterDataObject(IDataObject * pDO,IDataObject ** ppDORet)2026 HRESULT wxSTDCALL DocHostUIHandler::FilterDataObject(IDataObject *pDO, IDataObject **ppDORet)
2027 {
2028 wxUnusedVar(pDO);
2029 wxUnusedVar(ppDORet);
2030 return E_NOTIMPL;
2031 }
2032
2033 BEGIN_IID_TABLE(DocHostUIHandler)
2034 ADD_IID(Unknown)
2035 ADD_RAW_IID(wxIID_IDocHostUIHandler)
2036 END_IID_TABLE;
2037
2038 IMPLEMENT_IUNKNOWN_METHODS(DocHostUIHandler)
2039
2040 #endif // wxUSE_WEBVIEW && wxUSE_WEBVIEW_IE
2041