Always check that we get a valid IDispatch* from get_Document as sometimes the call...
[wxWidgets.git] / src / msw / webview_ie.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/webview_ie.cpp
3 // Purpose: wxMSW wxWebViewIE class implementation for web view component
4 // Author: Marianne Gagnon
5 // Id: $Id$
6 // Copyright: (c) 2010 Marianne Gagnon, 2011 Steven Lamerton
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9
10 // For compilers that support precompilation, includes "wx.h".
11 #include "wx/wxprec.h"
12
13 #if defined(__BORLANDC__)
14 #pragma hdrstop
15 #endif
16
17 #include "wx/msw/webview_ie.h"
18
19 #if wxUSE_WEBVIEW && wxUSE_WEBVIEW_IE
20
21 #include <olectl.h>
22 #include <oleidl.h>
23 #include <exdispid.h>
24 #include <exdisp.h>
25 #include <mshtml.h>
26 #include "wx/msw/registry.h"
27 #include "wx/msw/missing.h"
28 #include "wx/filesys.h"
29 #include "wx/dynlib.h"
30 #include <initguid.h>
31
32 /* These GUID definitions are our own implementation to support interfaces
33 * normally in urlmon.h. See include/wx/msw/webview_ie.h
34 */
35
36 namespace {
37
38 DEFINE_GUID(wxIID_IInternetProtocolRoot,0x79eac9e3,0xbaf9,0x11ce,0x8c,0x82,0,0xaa,0,0x4b,0xa9,0xb);
39 DEFINE_GUID(wxIID_IInternetProtocol,0x79eac9e4,0xbaf9,0x11ce,0x8c,0x82,0,0xaa,0,0x4b,0xa9,0xb);
40 DEFINE_GUID(wxIID_IDocHostUIHandler, 0xbd3f23c0, 0xd43e, 0x11cf, 0x89, 0x3b, 0x00, 0xaa, 0x00, 0xbd, 0xce, 0x1a);
41
42 }
43
44 wxIMPLEMENT_DYNAMIC_CLASS(wxWebViewIE, wxWebView);
45
46 BEGIN_EVENT_TABLE(wxWebViewIE, wxControl)
47 EVT_ACTIVEX(wxID_ANY, wxWebViewIE::onActiveXEvent)
48 EVT_ERASE_BACKGROUND(wxWebViewIE::onEraseBg)
49 END_EVENT_TABLE()
50
51 bool wxWebViewIE::Create(wxWindow* parent,
52 wxWindowID id,
53 const wxString& url,
54 const wxPoint& pos,
55 const wxSize& size,
56 long style,
57 const wxString& name)
58 {
59 if (!wxControl::Create(parent, id, pos, size, style,
60 wxDefaultValidator, name))
61 {
62 return false;
63 }
64
65 m_webBrowser = NULL;
66 m_isBusy = false;
67 m_historyLoadingFromList = false;
68 m_historyEnabled = true;
69 m_historyPosition = -1;
70 m_zoomType = wxWEB_VIEW_ZOOM_TYPE_TEXT;
71
72 if (::CoCreateInstance(CLSID_WebBrowser, NULL,
73 CLSCTX_INPROC_SERVER, // CLSCTX_INPROC,
74 IID_IWebBrowser2 , (void**)&m_webBrowser) != 0)
75 {
76 wxLogError("Failed to initialize IE, CoCreateInstance returned an error");
77 return false;
78 }
79
80 m_ie.SetDispatchPtr(m_webBrowser); // wxAutomationObject will release itself
81
82 m_webBrowser->put_RegisterAsBrowser(VARIANT_TRUE);
83 m_webBrowser->put_RegisterAsDropTarget(VARIANT_TRUE);
84
85 m_uiHandler = new DocHostUIHandler;
86 m_uiHandler->AddRef();
87
88 m_container = new wxIEContainer(this, IID_IWebBrowser2, m_webBrowser, m_uiHandler);
89
90 EnableControlFeature(21 /* FEATURE_DISABLE_NAVIGATION_SOUNDS */);
91
92 LoadURL(url);
93 return true;
94 }
95
96 wxWebViewIE::~wxWebViewIE()
97 {
98 for(unsigned int i = 0; i < m_factories.size(); i++)
99 {
100 m_factories[i]->Release();
101 }
102
103 m_uiHandler->Release();
104 }
105
106 void wxWebViewIE::LoadURL(const wxString& url)
107 {
108 m_ie.CallMethod("Navigate", wxConvertStringToOle(url));
109 }
110
111 void wxWebViewIE::SetPage(const wxString& html, const wxString& baseUrl)
112 {
113 BSTR bstr = SysAllocString(OLESTR(""));
114 SAFEARRAY *psaStrings = SafeArrayCreateVector(VT_VARIANT, 0, 1);
115 if (psaStrings != NULL)
116 {
117 VARIANT *param;
118 HRESULT hr = SafeArrayAccessData(psaStrings, (LPVOID*)&param);
119 param->vt = VT_BSTR;
120 param->bstrVal = bstr;
121
122 hr = SafeArrayUnaccessData(psaStrings);
123
124 IHTMLDocument2* document = GetDocument();
125
126 if(!document)
127 return;
128
129 document->write(psaStrings);
130 document->close();
131 document->Release();
132
133 SafeArrayDestroy(psaStrings);
134
135 bstr = SysAllocString(html.wc_str());
136
137 // Creates a new one-dimensional array
138 psaStrings = SafeArrayCreateVector(VT_VARIANT, 0, 1);
139 if (psaStrings != NULL)
140 {
141 hr = SafeArrayAccessData(psaStrings, (LPVOID*)&param);
142 param->vt = VT_BSTR;
143 param->bstrVal = bstr;
144 hr = SafeArrayUnaccessData(psaStrings);
145
146 document = GetDocument();
147
148 if(!document)
149 return;
150
151 document->write(psaStrings);
152 document->Release();
153
154 // SafeArrayDestroy calls SysFreeString for each BSTR
155 SafeArrayDestroy(psaStrings);
156
157 //We send the events when we are done to mimic webkit
158 //Navigated event
159 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_NAVIGATED,
160 GetId(), baseUrl, "");
161 event.SetEventObject(this);
162 HandleWindowEvent(event);
163
164 //Document complete event
165 event.SetEventType(wxEVT_COMMAND_WEB_VIEW_LOADED);
166 event.SetEventObject(this);
167 HandleWindowEvent(event);
168 }
169 else
170 {
171 wxLogError("wxWebViewIE::SetPage() : psaStrings is NULL");
172 }
173 }
174 else
175 {
176 wxLogError("wxWebViewIE::SetPage() : psaStrings is NULL during clear");
177 }
178 }
179
180 wxString wxWebViewIE::GetPageSource() const
181 {
182 IHTMLDocument2* document = GetDocument();
183
184 if(document)
185 {
186 IHTMLElement *bodyTag = NULL;
187 IHTMLElement *htmlTag = NULL;
188 wxString source;
189 HRESULT hr = document->get_body(&bodyTag);
190 if(SUCCEEDED(hr))
191 {
192 hr = bodyTag->get_parentElement(&htmlTag);
193 if(SUCCEEDED(hr))
194 {
195 BSTR bstr;
196 htmlTag->get_outerHTML(&bstr);
197 source = wxString(bstr);
198 htmlTag->Release();
199 }
200 bodyTag->Release();
201 }
202
203 document->Release();
204 return source;
205 }
206 else
207 {
208 return "";
209 }
210 }
211
212 wxWebViewZoom wxWebViewIE::GetZoom() const
213 {
214 switch( m_zoomType )
215 {
216 case wxWEB_VIEW_ZOOM_TYPE_LAYOUT:
217 return GetIEOpticalZoom();
218 case wxWEB_VIEW_ZOOM_TYPE_TEXT:
219 return GetIETextZoom();
220 default:
221 wxFAIL;
222 }
223
224 //Dummy return to stop compiler warnings
225 return wxWEB_VIEW_ZOOM_MEDIUM;
226
227 }
228
229 void wxWebViewIE::SetZoom(wxWebViewZoom zoom)
230 {
231 switch( m_zoomType )
232 {
233 case wxWEB_VIEW_ZOOM_TYPE_LAYOUT:
234 SetIEOpticalZoom(zoom);
235 break;
236 case wxWEB_VIEW_ZOOM_TYPE_TEXT:
237 SetIETextZoom(zoom);
238 break;
239 default:
240 wxFAIL;
241 }
242 }
243
244 void wxWebViewIE::SetIETextZoom(wxWebViewZoom level)
245 {
246 //We do not use OLECMDID_OPTICAL_GETZOOMRANGE as the docs say the range
247 //is 0 to 4 so the check is unnecessary, these match exactly with the
248 //enum values
249 VARIANT zoomVariant;
250 VariantInit (&zoomVariant);
251 V_VT(&zoomVariant) = VT_I4;
252 V_I4(&zoomVariant) = level;
253
254 #if wxDEBUG_LEVEL
255 HRESULT result =
256 #endif
257 m_webBrowser->ExecWB(OLECMDID_ZOOM,
258 OLECMDEXECOPT_DONTPROMPTUSER,
259 &zoomVariant, NULL);
260 wxASSERT(result == S_OK);
261 }
262
263 wxWebViewZoom wxWebViewIE::GetIETextZoom() const
264 {
265 VARIANT zoomVariant;
266 VariantInit (&zoomVariant);
267 V_VT(&zoomVariant) = VT_I4;
268
269 #if wxDEBUG_LEVEL
270 HRESULT result =
271 #endif
272 m_webBrowser->ExecWB(OLECMDID_ZOOM,
273 OLECMDEXECOPT_DONTPROMPTUSER,
274 NULL, &zoomVariant);
275 wxASSERT(result == S_OK);
276
277 //We can safely cast here as we know that the range matches our enum
278 return static_cast<wxWebViewZoom>(V_I4(&zoomVariant));
279 }
280
281 void wxWebViewIE::SetIEOpticalZoom(wxWebViewZoom level)
282 {
283 //We do not use OLECMDID_OPTICAL_GETZOOMRANGE as the docs say the range
284 //is 10 to 1000 so the check is unnecessary
285 VARIANT zoomVariant;
286 VariantInit (&zoomVariant);
287 V_VT(&zoomVariant) = VT_I4;
288
289 //We make a somewhat arbitray map here, taken from values used by webkit
290 switch(level)
291 {
292 case wxWEB_VIEW_ZOOM_TINY:
293 V_I4(&zoomVariant) = 60;
294 break;
295 case wxWEB_VIEW_ZOOM_SMALL:
296 V_I4(&zoomVariant) = 80;
297 break;
298 case wxWEB_VIEW_ZOOM_MEDIUM:
299 V_I4(&zoomVariant) = 100;
300 break;
301 case wxWEB_VIEW_ZOOM_LARGE:
302 V_I4(&zoomVariant) = 130;
303 break;
304 case wxWEB_VIEW_ZOOM_LARGEST:
305 V_I4(&zoomVariant) = 160;
306 break;
307 default:
308 wxFAIL;
309 }
310
311 #if wxDEBUG_LEVEL
312 HRESULT result =
313 #endif
314 m_webBrowser->ExecWB((OLECMDID)63 /*OLECMDID_OPTICAL_ZOOM*/,
315 OLECMDEXECOPT_DODEFAULT,
316 &zoomVariant,
317 NULL);
318 wxASSERT(result == S_OK);
319 }
320
321 wxWebViewZoom wxWebViewIE::GetIEOpticalZoom() const
322 {
323 VARIANT zoomVariant;
324 VariantInit (&zoomVariant);
325 V_VT(&zoomVariant) = VT_I4;
326
327 #if wxDEBUG_LEVEL
328 HRESULT result =
329 #endif
330 m_webBrowser->ExecWB((OLECMDID)63 /*OLECMDID_OPTICAL_ZOOM*/,
331 OLECMDEXECOPT_DODEFAULT, NULL,
332 &zoomVariant);
333 wxASSERT(result == S_OK);
334
335 const int zoom = V_I4(&zoomVariant);
336
337 //We make a somewhat arbitray map here, taken from values used by webkit
338 if (zoom <= 65)
339 {
340 return wxWEB_VIEW_ZOOM_TINY;
341 }
342 else if (zoom > 65 && zoom <= 90)
343 {
344 return wxWEB_VIEW_ZOOM_SMALL;
345 }
346 else if (zoom > 90 && zoom <= 115)
347 {
348 return wxWEB_VIEW_ZOOM_MEDIUM;
349 }
350 else if (zoom > 115 && zoom <= 145)
351 {
352 return wxWEB_VIEW_ZOOM_LARGE;
353 }
354 else /*if (zoom > 145) */ //Using else removes a compiler warning
355 {
356 return wxWEB_VIEW_ZOOM_LARGEST;
357 }
358 }
359
360 void wxWebViewIE::SetZoomType(wxWebViewZoomType type)
361 {
362 m_zoomType = type;
363 }
364
365 wxWebViewZoomType wxWebViewIE::GetZoomType() const
366 {
367 return m_zoomType;
368 }
369
370 bool wxWebViewIE::CanSetZoomType(wxWebViewZoomType type) const
371 {
372 //IE 6 and below only support text zoom, so check the registry to see what
373 //version we actually have
374 wxRegKey key(wxRegKey::HKLM, "Software\\Microsoft\\Internet Explorer");
375 wxString value;
376 key.QueryValue("Version", value);
377
378 long version = wxAtoi(value.Left(1));
379 if(version <= 6 && type == wxWEB_VIEW_ZOOM_TYPE_LAYOUT)
380 return false;
381 else
382 return true;
383 }
384
385 void wxWebViewIE::Print()
386 {
387 m_webBrowser->ExecWB(OLECMDID_PRINTPREVIEW,
388 OLECMDEXECOPT_DODEFAULT, NULL, NULL);
389 }
390
391 bool wxWebViewIE::CanGoBack() const
392 {
393 if(m_historyEnabled)
394 return m_historyPosition > 0;
395 else
396 return false;
397 }
398
399 bool wxWebViewIE::CanGoForward() const
400 {
401 if(m_historyEnabled)
402 return m_historyPosition != static_cast<int>(m_historyList.size()) - 1;
403 else
404 return false;
405 }
406
407 void wxWebViewIE::LoadHistoryItem(wxSharedPtr<wxWebViewHistoryItem> item)
408 {
409 int pos = -1;
410 for(unsigned int i = 0; i < m_historyList.size(); i++)
411 {
412 //We compare the actual pointers to find the correct item
413 if(m_historyList[i].get() == item.get())
414 pos = i;
415 }
416 wxASSERT_MSG(pos != static_cast<int>(m_historyList.size()),
417 "invalid history item");
418 m_historyLoadingFromList = true;
419 LoadURL(item->GetUrl());
420 m_historyPosition = pos;
421 }
422
423 wxVector<wxSharedPtr<wxWebViewHistoryItem> > wxWebViewIE::GetBackwardHistory()
424 {
425 wxVector<wxSharedPtr<wxWebViewHistoryItem> > backhist;
426 //As we don't have std::copy or an iterator constructor in the wxwidgets
427 //native vector we construct it by hand
428 for(int i = 0; i < m_historyPosition; i++)
429 {
430 backhist.push_back(m_historyList[i]);
431 }
432 return backhist;
433 }
434
435 wxVector<wxSharedPtr<wxWebViewHistoryItem> > wxWebViewIE::GetForwardHistory()
436 {
437 wxVector<wxSharedPtr<wxWebViewHistoryItem> > forwardhist;
438 //As we don't have std::copy or an iterator constructor in the wxwidgets
439 //native vector we construct it by hand
440 for(int i = m_historyPosition + 1; i < static_cast<int>(m_historyList.size()); i++)
441 {
442 forwardhist.push_back(m_historyList[i]);
443 }
444 return forwardhist;
445 }
446
447 void wxWebViewIE::GoBack()
448 {
449 LoadHistoryItem(m_historyList[m_historyPosition - 1]);
450 }
451
452 void wxWebViewIE::GoForward()
453 {
454 LoadHistoryItem(m_historyList[m_historyPosition + 1]);
455 }
456
457 void wxWebViewIE::Stop()
458 {
459 m_ie.CallMethod("Stop");
460 }
461
462 void wxWebViewIE::ClearHistory()
463 {
464 m_historyList.clear();
465 m_historyPosition = -1;
466 }
467
468 void wxWebViewIE::EnableHistory(bool enable)
469 {
470 m_historyEnabled = enable;
471 m_historyList.clear();
472 m_historyPosition = -1;
473 }
474
475 void wxWebViewIE::Reload(wxWebViewReloadFlags flags)
476 {
477 VARIANTARG level;
478 VariantInit(&level);
479 V_VT(&level) = VT_I2;
480
481 switch(flags)
482 {
483 case wxWEB_VIEW_RELOAD_DEFAULT:
484 V_I2(&level) = REFRESH_NORMAL;
485 break;
486 case wxWEB_VIEW_RELOAD_NO_CACHE:
487 V_I2(&level) = REFRESH_COMPLETELY;
488 break;
489 default:
490 wxFAIL_MSG("Unexpected reload type");
491 }
492
493 m_webBrowser->Refresh2(&level);
494 }
495
496 bool wxWebViewIE::IsOfflineMode()
497 {
498 wxVariant out = m_ie.GetProperty("Offline");
499
500 wxASSERT(out.GetType() == "bool");
501
502 return out.GetBool();
503 }
504
505 void wxWebViewIE::SetOfflineMode(bool offline)
506 {
507 // FIXME: the wxWidgets docs do not really document what the return
508 // parameter of PutProperty is
509 #if wxDEBUG_LEVEL
510 const bool success =
511 #endif
512 m_ie.PutProperty("Offline", (offline ?
513 VARIANT_TRUE :
514 VARIANT_FALSE));
515 wxASSERT(success);
516 }
517
518 bool wxWebViewIE::IsBusy() const
519 {
520 if (m_isBusy) return true;
521
522 wxVariant out = m_ie.GetProperty("Busy");
523
524 wxASSERT(out.GetType() == "bool");
525
526 return out.GetBool();
527 }
528
529 wxString wxWebViewIE::GetCurrentURL() const
530 {
531 wxVariant out = m_ie.GetProperty("LocationURL");
532
533 wxASSERT(out.GetType() == "string");
534 return out.GetString();
535 }
536
537 wxString wxWebViewIE::GetCurrentTitle() const
538 {
539 IHTMLDocument2* document = GetDocument();
540
541 if(document)
542 {
543 BSTR title;
544 document->get_nameProp(&title);
545 document->Release();
546 return wxString(title);
547 }
548 else
549 {
550 return "";
551 }
552 }
553
554 bool wxWebViewIE::CanCut() const
555 {
556 return CanExecCommand("Cut");
557 }
558
559 bool wxWebViewIE::CanCopy() const
560 {
561 return CanExecCommand("Copy");
562 }
563
564 bool wxWebViewIE::CanPaste() const
565 {
566 return CanExecCommand("Paste");
567 }
568
569 void wxWebViewIE::Cut()
570 {
571 ExecCommand("Cut");
572 }
573
574 void wxWebViewIE::Copy()
575 {
576 ExecCommand("Copy");
577 }
578
579 void wxWebViewIE::Paste()
580 {
581 ExecCommand("Paste");
582 }
583
584 bool wxWebViewIE::CanUndo() const
585 {
586 return CanExecCommand("Undo");
587 }
588
589 bool wxWebViewIE::CanRedo() const
590 {
591 return CanExecCommand("Redo");
592 }
593
594 void wxWebViewIE::Undo()
595 {
596 ExecCommand("Undo");
597 }
598
599 void wxWebViewIE::Redo()
600 {
601 ExecCommand("Redo");
602 }
603
604 void wxWebViewIE::SetEditable(bool enable)
605 {
606 IHTMLDocument2* document = GetDocument();
607
608 if(document)
609 {
610 if( enable )
611 document->put_designMode(SysAllocString(L"On"));
612 else
613 document->put_designMode(SysAllocString(L"Off"));
614
615 document->Release();
616 }
617 }
618
619 bool wxWebViewIE::IsEditable() const
620 {
621 IHTMLDocument2* document = GetDocument();
622
623 if(document)
624 {
625 BSTR mode;
626 document->get_designMode(&mode);
627 document->Release();
628 if(wxString(mode) == "On")
629 return true;
630 else
631 return false;
632 }
633 else
634 {
635 return false;
636 }
637 }
638
639 void wxWebViewIE::SelectAll()
640 {
641 ExecCommand("SelectAll");
642 }
643
644 bool wxWebViewIE::HasSelection() const
645 {
646 IHTMLDocument2* document = GetDocument();
647
648 if(document)
649 {
650 IHTMLSelectionObject* selection;
651 wxString sel;
652 HRESULT hr = document->get_selection(&selection);
653 if(SUCCEEDED(hr))
654 {
655 BSTR type;
656 selection->get_type(&type);
657 sel = wxString(type);
658 selection->Release();
659 }
660 document->Release();
661 return sel != "None";
662 }
663 else
664 {
665 return false;
666 }
667 }
668
669 void wxWebViewIE::DeleteSelection()
670 {
671 ExecCommand("Delete");
672 }
673
674 wxString wxWebViewIE::GetSelectedText() const
675 {
676 IHTMLDocument2* document = GetDocument();
677
678 if(document)
679 {
680 IHTMLSelectionObject* selection;
681 wxString selected;
682 HRESULT hr = document->get_selection(&selection);
683 if(SUCCEEDED(hr))
684 {
685 IDispatch* disrange;
686 hr = selection->createRange(&disrange);
687 if(SUCCEEDED(hr))
688 {
689 IHTMLTxtRange* range;
690 hr = disrange->QueryInterface(IID_IHTMLTxtRange, (void**)&range);
691 if(SUCCEEDED(hr))
692 {
693 BSTR text;
694 range->get_text(&text);
695 selected = wxString(text);
696 range->Release();
697 }
698 disrange->Release();
699 }
700 selection->Release();
701 }
702 document->Release();
703 return selected;
704 }
705 else
706 {
707 return "";
708 }
709 }
710
711 wxString wxWebViewIE::GetSelectedSource() const
712 {
713 IHTMLDocument2* document = GetDocument();
714
715 if(document)
716 {
717 IHTMLSelectionObject* selection;
718 wxString selected;
719 HRESULT hr = document->get_selection(&selection);
720 if(SUCCEEDED(hr))
721 {
722 IDispatch* disrange;
723 hr = selection->createRange(&disrange);
724 if(SUCCEEDED(hr))
725 {
726 IHTMLTxtRange* range;
727 hr = disrange->QueryInterface(IID_IHTMLTxtRange, (void**)&range);
728 if(SUCCEEDED(hr))
729 {
730 BSTR text;
731 range->get_htmlText(&text);
732 selected = wxString(text);
733 range->Release();
734 }
735 disrange->Release();
736 }
737 selection->Release();
738 }
739 document->Release();
740 return selected;
741 }
742 else
743 {
744 return "";
745 }
746 }
747
748 void wxWebViewIE::ClearSelection()
749 {
750 IHTMLDocument2* document = GetDocument();
751
752 if(document)
753 {
754 IHTMLSelectionObject* selection;
755 wxString selected;
756 HRESULT hr = document->get_selection(&selection);
757 if(SUCCEEDED(hr))
758 {
759 selection->empty();
760 selection->Release();
761 }
762 document->Release();
763 }
764 }
765
766 wxString wxWebViewIE::GetPageText() const
767 {
768 IHTMLDocument2* document = GetDocument();
769
770 if(document)
771 {
772 wxString text;
773 IHTMLElement* body;
774 HRESULT hr = document->get_body(&body);
775 if(SUCCEEDED(hr))
776 {
777 BSTR out;
778 body->get_innerText(&out);
779 text = wxString(out);
780 body->Release();
781 }
782 document->Release();
783 return text;
784 }
785 else
786 {
787 return "";
788 }
789 }
790
791 void wxWebViewIE::RunScript(const wxString& javascript)
792 {
793 IHTMLDocument2* document = GetDocument();
794
795 if(document)
796 {
797 IHTMLWindow2* window;
798 wxString language = "javascript";
799 HRESULT hr = document->get_parentWindow(&window);
800 if(SUCCEEDED(hr))
801 {
802 VARIANT level;
803 VariantInit(&level);
804 V_VT(&level) = VT_EMPTY;
805 window->execScript(SysAllocString(javascript.wc_str()),
806 SysAllocString(language.wc_str()),
807 &level);
808 }
809 document->Release();
810 }
811 }
812
813 void wxWebViewIE::RegisterHandler(wxSharedPtr<wxWebViewHandler> handler)
814 {
815 wxDynamicLibrary urlMon(wxT("urlmon.dll"));
816 if(urlMon.HasSymbol(wxT("CoInternetGetSession")))
817 {
818 typedef HRESULT (WINAPI *CoInternetGetSession_t)(DWORD, wxIInternetSession**, DWORD);
819 wxDYNLIB_FUNCTION(CoInternetGetSession_t, CoInternetGetSession, urlMon);
820
821 ClassFactory* cf = new ClassFactory(handler);
822 wxIInternetSession* session;
823 HRESULT res = (*pfnCoInternetGetSession)(0, &session, 0);
824 if(FAILED(res))
825 {
826 wxFAIL_MSG("Could not retrive internet session");
827 }
828
829 HRESULT hr = session->RegisterNameSpace(cf, CLSID_FileProtocol,
830 handler->GetName().wc_str(),
831 0, NULL, 0);
832 if(FAILED(hr))
833 {
834 wxFAIL_MSG("Could not register protocol");
835 }
836 m_factories.push_back(cf);
837 }
838 else
839 {
840 wxFAIL_MSG("urlmon does not contain CoInternetGetSession");
841 }
842 }
843
844 bool wxWebViewIE::CanExecCommand(wxString command) const
845 {
846 IHTMLDocument2* document = GetDocument();
847
848 if(document)
849 {
850 VARIANT_BOOL enabled;
851
852 document->queryCommandEnabled(SysAllocString(command.wc_str()), &enabled);
853 document->Release();
854
855 return (enabled == VARIANT_TRUE);
856 }
857 else
858 {
859 return false;
860 }
861
862 }
863
864 void wxWebViewIE::ExecCommand(wxString command)
865 {
866 IHTMLDocument2* document = GetDocument();
867
868 if(document)
869 {
870 document->execCommand(SysAllocString(command.wc_str()), VARIANT_FALSE, VARIANT(), NULL);
871 document->Release();
872 }
873 }
874
875 IHTMLDocument2* wxWebViewIE::GetDocument() const
876 {
877 IDispatch* dispatch = NULL;
878 HRESULT result = m_webBrowser->get_Document(&dispatch);
879 if(dispatch && SUCCEEDED(result))
880 {
881 IHTMLDocument2* document;
882 dispatch->QueryInterface(IID_IHTMLDocument2, (void**)&document);
883 dispatch->Release();
884 //document is set to null automatically if the interface isn't supported
885 return document;
886 }
887 else
888 {
889 return NULL;
890 }
891 }
892
893 bool wxWebViewIE::EnableControlFeature(long flag, bool enable)
894 {
895 #if wxUSE_DYNLIB_CLASS
896
897 wxDynamicLibrary urlMon(wxT("urlmon.dll"));
898 if( urlMon.IsLoaded() &&
899 urlMon.HasSymbol("CoInternetSetFeatureEnabled") &&
900 urlMon.HasSymbol("CoInternetIsFeatureEnabled"))
901 {
902 typedef HRESULT (WINAPI *CoInternetSetFeatureEnabled_t)(DWORD, DWORD, BOOL);
903 typedef HRESULT (WINAPI *CoInternetIsFeatureEnabled_t)(DWORD, DWORD);
904
905 wxDYNLIB_FUNCTION(CoInternetSetFeatureEnabled_t, CoInternetSetFeatureEnabled, urlMon);
906 wxDYNLIB_FUNCTION(CoInternetIsFeatureEnabled_t, CoInternetIsFeatureEnabled, urlMon);
907
908 HRESULT hr = (*pfnCoInternetIsFeatureEnabled)(flag,
909 0x2 /* SET_FEATURE_ON_PROCESS */);
910 if((hr == S_OK && enable) || (hr == S_FALSE && !enable))
911 return true;
912
913 hr = (*pfnCoInternetSetFeatureEnabled)(flag,
914 0x2/* SET_FEATURE_ON_PROCESS */,
915 (enable ? TRUE : FALSE));
916 if ( FAILED(hr) )
917 {
918 wxLogApiError(wxT("CoInternetSetFeatureEnabled"), hr);
919 return false;
920 }
921 return true;
922 }
923 return false;
924 #else
925 wxUnusedVar(flag);
926 wxUnusedVar(enable);
927 return false;
928 #endif // wxUSE_DYNLIB_CLASS/!wxUSE_DYNLIB_CLASS
929 }
930
931 void wxWebViewIE::onActiveXEvent(wxActiveXEvent& evt)
932 {
933 if (m_webBrowser == NULL) return;
934
935 switch (evt.GetDispatchId())
936 {
937 case DISPID_BEFORENAVIGATE2:
938 {
939 m_isBusy = true;
940
941 wxString url = evt[1].GetString();
942 wxString target = evt[3].GetString();
943
944 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_NAVIGATING,
945 GetId(), url, target);
946
947 //skip empty javascript events.
948 if(url == "javascript:\"\"" && target.IsEmpty())
949 {
950 event.Veto();
951 }
952 else
953 {
954 event.SetEventObject(this);
955 HandleWindowEvent(event);
956 }
957
958 if (!event.IsAllowed())
959 {
960 wxActiveXEventNativeMSW* nativeParams =
961 evt.GetNativeParameters();
962 *V_BOOLREF(&nativeParams->pDispParams->rgvarg[0]) = VARIANT_TRUE;
963 }
964
965 // at this point, either the navigation event has been cancelled
966 // and we're not busy, either it was accepted and IWebBrowser2's
967 // Busy property will be true; so we don't need our override
968 // flag anymore.
969 m_isBusy = false;
970
971 break;
972 }
973
974 case DISPID_NAVIGATECOMPLETE2:
975 {
976 wxString url = evt[1].GetString();
977 // TODO: set target parameter if possible
978 wxString target = wxEmptyString;
979 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_NAVIGATED,
980 GetId(), url, target);
981 event.SetEventObject(this);
982 HandleWindowEvent(event);
983 break;
984 }
985
986 case DISPID_PROGRESSCHANGE:
987 {
988 // download progress
989 break;
990 }
991
992 case DISPID_DOCUMENTCOMPLETE:
993 {
994 //Only send a complete even if we are actually finished, this brings
995 //the event in to line with webkit
996 READYSTATE rs;
997 m_webBrowser->get_ReadyState( &rs );
998 if(rs != READYSTATE_COMPLETE)
999 break;
1000
1001 wxString url = evt[1].GetString();
1002
1003 //As we are complete we also add to the history list, but not if the
1004 //page is not the main page, ie it is a subframe
1005 //We also have to check if we are loading a file:// url, if so we
1006 //need to change the comparison as ie passes back a different style
1007 //of url
1008 if(m_historyEnabled && !m_historyLoadingFromList &&
1009 (url == GetCurrentURL() ||
1010 (GetCurrentURL().substr(0, 4) == "file" &&
1011 wxFileSystem::URLToFileName(GetCurrentURL()).GetFullPath() == url)))
1012 {
1013 //If we are not at the end of the list, then erase everything
1014 //between us and the end before adding the new page
1015 if(m_historyPosition != static_cast<int>(m_historyList.size()) - 1)
1016 {
1017 m_historyList.erase(m_historyList.begin() + m_historyPosition + 1,
1018 m_historyList.end());
1019 }
1020 wxSharedPtr<wxWebViewHistoryItem> item(new wxWebViewHistoryItem(url, GetCurrentTitle()));
1021 m_historyList.push_back(item);
1022 m_historyPosition++;
1023 }
1024 //Reset as we are done now
1025 m_historyLoadingFromList = false;
1026 // TODO: set target parameter if possible
1027 wxString target = wxEmptyString;
1028 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_LOADED, GetId(),
1029 url, target);
1030 event.SetEventObject(this);
1031 HandleWindowEvent(event);
1032 break;
1033 }
1034
1035 case DISPID_STATUSTEXTCHANGE:
1036 {
1037 break;
1038 }
1039
1040 case DISPID_TITLECHANGE:
1041 {
1042 wxString title = evt[0].GetString();
1043
1044 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_TITLE_CHANGED,
1045 GetId(), GetCurrentURL(), "");
1046 event.SetString(title);
1047 event.SetEventObject(this);
1048 HandleWindowEvent(event);
1049 break;
1050 }
1051
1052 case DISPID_NAVIGATEERROR:
1053 {
1054 wxWebViewNavigationError errorType = wxWEB_NAV_ERR_OTHER;
1055 wxString errorCode = "?";
1056 switch (evt[3].GetLong())
1057 {
1058 case INET_E_INVALID_URL: // (0x800C0002L or -2146697214)
1059 errorCode = "INET_E_INVALID_URL";
1060 errorType = wxWEB_NAV_ERR_REQUEST;
1061 break;
1062 case INET_E_NO_SESSION: // (0x800C0003L or -2146697213)
1063 errorCode = "INET_E_NO_SESSION";
1064 errorType = wxWEB_NAV_ERR_CONNECTION;
1065 break;
1066 case INET_E_CANNOT_CONNECT: // (0x800C0004L or -2146697212)
1067 errorCode = "INET_E_CANNOT_CONNECT";
1068 errorType = wxWEB_NAV_ERR_CONNECTION;
1069 break;
1070 case INET_E_RESOURCE_NOT_FOUND: // (0x800C0005L or -2146697211)
1071 errorCode = "INET_E_RESOURCE_NOT_FOUND";
1072 errorType = wxWEB_NAV_ERR_NOT_FOUND;
1073 break;
1074 case INET_E_OBJECT_NOT_FOUND: // (0x800C0006L or -2146697210)
1075 errorCode = "INET_E_OBJECT_NOT_FOUND";
1076 errorType = wxWEB_NAV_ERR_NOT_FOUND;
1077 break;
1078 case INET_E_DATA_NOT_AVAILABLE: // (0x800C0007L or -2146697209)
1079 errorCode = "INET_E_DATA_NOT_AVAILABLE";
1080 errorType = wxWEB_NAV_ERR_NOT_FOUND;
1081 break;
1082 case INET_E_DOWNLOAD_FAILURE: // (0x800C0008L or -2146697208)
1083 errorCode = "INET_E_DOWNLOAD_FAILURE";
1084 errorType = wxWEB_NAV_ERR_CONNECTION;
1085 break;
1086 case INET_E_AUTHENTICATION_REQUIRED: // (0x800C0009L or -2146697207)
1087 errorCode = "INET_E_AUTHENTICATION_REQUIRED";
1088 errorType = wxWEB_NAV_ERR_AUTH;
1089 break;
1090 case INET_E_NO_VALID_MEDIA: // (0x800C000AL or -2146697206)
1091 errorCode = "INET_E_NO_VALID_MEDIA";
1092 errorType = wxWEB_NAV_ERR_REQUEST;
1093 break;
1094 case INET_E_CONNECTION_TIMEOUT: // (0x800C000BL or -2146697205)
1095 errorCode = "INET_E_CONNECTION_TIMEOUT";
1096 errorType = wxWEB_NAV_ERR_CONNECTION;
1097 break;
1098 case INET_E_INVALID_REQUEST: // (0x800C000CL or -2146697204)
1099 errorCode = "INET_E_INVALID_REQUEST";
1100 errorType = wxWEB_NAV_ERR_REQUEST;
1101 break;
1102 case INET_E_UNKNOWN_PROTOCOL: // (0x800C000DL or -2146697203)
1103 errorCode = "INET_E_UNKNOWN_PROTOCOL";
1104 errorType = wxWEB_NAV_ERR_REQUEST;
1105 break;
1106 case INET_E_SECURITY_PROBLEM: // (0x800C000EL or -2146697202)
1107 errorCode = "INET_E_SECURITY_PROBLEM";
1108 errorType = wxWEB_NAV_ERR_SECURITY;
1109 break;
1110 case INET_E_CANNOT_LOAD_DATA: // (0x800C000FL or -2146697201)
1111 errorCode = "INET_E_CANNOT_LOAD_DATA";
1112 errorType = wxWEB_NAV_ERR_OTHER;
1113 break;
1114 case INET_E_CANNOT_INSTANTIATE_OBJECT:
1115 // CoCreateInstance will return an error code if this happens,
1116 // we'll handle this above.
1117 return;
1118 break;
1119 case INET_E_REDIRECT_FAILED: // (0x800C0014L or -2146697196)
1120 errorCode = "INET_E_REDIRECT_FAILED";
1121 errorType = wxWEB_NAV_ERR_OTHER;
1122 break;
1123 case INET_E_REDIRECT_TO_DIR: // (0x800C0015L or -2146697195)
1124 errorCode = "INET_E_REDIRECT_TO_DIR";
1125 errorType = wxWEB_NAV_ERR_REQUEST;
1126 break;
1127 case INET_E_CANNOT_LOCK_REQUEST: // (0x800C0016L or -2146697194)
1128 errorCode = "INET_E_CANNOT_LOCK_REQUEST";
1129 errorType = wxWEB_NAV_ERR_OTHER;
1130 break;
1131 case INET_E_USE_EXTEND_BINDING: // (0x800C0017L or -2146697193)
1132 errorCode = "INET_E_USE_EXTEND_BINDING";
1133 errorType = wxWEB_NAV_ERR_OTHER;
1134 break;
1135 case INET_E_TERMINATED_BIND: // (0x800C0018L or -2146697192)
1136 errorCode = "INET_E_TERMINATED_BIND";
1137 errorType = wxWEB_NAV_ERR_OTHER;
1138 break;
1139 case INET_E_INVALID_CERTIFICATE: // (0x800C0019L or -2146697191)
1140 errorCode = "INET_E_INVALID_CERTIFICATE";
1141 errorType = wxWEB_NAV_ERR_CERTIFICATE;
1142 break;
1143 case INET_E_CODE_DOWNLOAD_DECLINED: // (0x800C0100L or -2146696960)
1144 errorCode = "INET_E_CODE_DOWNLOAD_DECLINED";
1145 errorType = wxWEB_NAV_ERR_USER_CANCELLED;
1146 break;
1147 case INET_E_RESULT_DISPATCHED: // (0x800C0200L or -2146696704)
1148 // cancel request cancelled...
1149 errorCode = "INET_E_RESULT_DISPATCHED";
1150 errorType = wxWEB_NAV_ERR_OTHER;
1151 break;
1152 case INET_E_CANNOT_REPLACE_SFP_FILE: // (0x800C0300L or -2146696448)
1153 errorCode = "INET_E_CANNOT_REPLACE_SFP_FILE";
1154 errorType = wxWEB_NAV_ERR_SECURITY;
1155 break;
1156 case INET_E_CODE_INSTALL_BLOCKED_BY_HASH_POLICY:
1157 errorCode = "INET_E_CODE_INSTALL_BLOCKED_BY_HASH_POLICY";
1158 errorType = wxWEB_NAV_ERR_SECURITY;
1159 break;
1160 case INET_E_CODE_INSTALL_SUPPRESSED:
1161 errorCode = "INET_E_CODE_INSTALL_SUPPRESSED";
1162 errorType = wxWEB_NAV_ERR_SECURITY;
1163 break;
1164 }
1165
1166 wxString url = evt[1].GetString();
1167 wxString target = evt[2].GetString();
1168 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_ERROR, GetId(),
1169 url, target);
1170 event.SetEventObject(this);
1171 event.SetInt(errorType);
1172 event.SetString(errorCode);
1173 HandleWindowEvent(event);
1174 break;
1175 }
1176 case DISPID_NEWWINDOW3:
1177 {
1178 wxString url = evt[4].GetString();
1179
1180 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_NEWWINDOW,
1181 GetId(), url, wxEmptyString);
1182 event.SetEventObject(this);
1183 HandleWindowEvent(event);
1184
1185 //We always cancel this event otherwise an Internet Exporer window
1186 //is opened for the url
1187 wxActiveXEventNativeMSW* nativeParams = evt.GetNativeParameters();
1188 *V_BOOLREF(&nativeParams->pDispParams->rgvarg[3]) = VARIANT_TRUE;
1189 break;
1190 }
1191 }
1192
1193 evt.Skip();
1194 }
1195
1196 VirtualProtocol::VirtualProtocol(wxSharedPtr<wxWebViewHandler> handler)
1197 {
1198 m_file = NULL;
1199 m_handler = handler;
1200 }
1201
1202 BEGIN_IID_TABLE(VirtualProtocol)
1203 ADD_IID(Unknown)
1204 ADD_RAW_IID(wxIID_IInternetProtocolRoot)
1205 ADD_RAW_IID(wxIID_IInternetProtocol)
1206 END_IID_TABLE;
1207
1208 IMPLEMENT_IUNKNOWN_METHODS(VirtualProtocol)
1209
1210 HRESULT VirtualProtocol::Start(LPCWSTR szUrl, wxIInternetProtocolSink *pOIProtSink,
1211 wxIInternetBindInfo *pOIBindInfo, DWORD grfPI,
1212 HANDLE_PTR dwReserved)
1213 {
1214 wxUnusedVar(szUrl);
1215 wxUnusedVar(pOIBindInfo);
1216 wxUnusedVar(grfPI);
1217 wxUnusedVar(dwReserved);
1218 m_protocolSink = pOIProtSink;
1219
1220 //We get the file itself from the protocol handler
1221 m_file = m_handler->GetFile(szUrl);
1222
1223
1224 if(!m_file)
1225 return INET_E_RESOURCE_NOT_FOUND;
1226
1227 //We return the stream length for current and total size as we can always
1228 //read the whole file from the stream
1229 wxFileOffset length = m_file->GetStream()->GetLength();
1230 m_protocolSink->ReportData(wxBSCF_FIRSTDATANOTIFICATION |
1231 wxBSCF_DATAFULLYAVAILABLE |
1232 wxBSCF_LASTDATANOTIFICATION,
1233 length, length);
1234 return S_OK;
1235 }
1236
1237 HRESULT VirtualProtocol::Read(void *pv, ULONG cb, ULONG *pcbRead)
1238 {
1239 //If the file is null we return false to indicte it is finished
1240 if(!m_file)
1241 return S_FALSE;
1242
1243 wxStreamError err = m_file->GetStream()->Read(pv, cb).GetLastError();
1244 *pcbRead = m_file->GetStream()->LastRead();
1245
1246 if(err == wxSTREAM_NO_ERROR)
1247 {
1248 if(*pcbRead < cb)
1249 {
1250 wxDELETE(m_file);
1251 m_protocolSink->ReportResult(S_OK, 0, NULL);
1252 }
1253 //As we are not eof there is more data
1254 return S_OK;
1255 }
1256 else if(err == wxSTREAM_EOF)
1257 {
1258 wxDELETE(m_file);
1259 m_protocolSink->ReportResult(S_OK, 0, NULL);
1260 //We are eof and so finished
1261 return S_OK;
1262 }
1263 else if(err == wxSTREAM_READ_ERROR)
1264 {
1265 wxDELETE(m_file);
1266 return INET_E_DOWNLOAD_FAILURE;
1267 }
1268 else
1269 {
1270 //Dummy return to surpress a compiler warning
1271 wxFAIL;
1272 return INET_E_DOWNLOAD_FAILURE;
1273 }
1274 }
1275
1276 BEGIN_IID_TABLE(ClassFactory)
1277 ADD_IID(Unknown)
1278 ADD_IID(ClassFactory)
1279 END_IID_TABLE;
1280
1281 IMPLEMENT_IUNKNOWN_METHODS(ClassFactory)
1282
1283 HRESULT ClassFactory::CreateInstance(IUnknown* pUnkOuter, REFIID riid,
1284 void ** ppvObject)
1285 {
1286 if (pUnkOuter)
1287 return CLASS_E_NOAGGREGATION;
1288 VirtualProtocol* vp = new VirtualProtocol(m_handler);
1289 vp->AddRef();
1290 HRESULT hr = vp->QueryInterface(riid, ppvObject);
1291 vp->Release();
1292 return hr;
1293
1294 }
1295
1296 STDMETHODIMP ClassFactory::LockServer(BOOL fLock)
1297 {
1298 wxUnusedVar(fLock);
1299 return S_OK;
1300 }
1301
1302 wxIEContainer::wxIEContainer(wxWindow *parent, REFIID iid, IUnknown *pUnk,
1303 DocHostUIHandler* uiHandler) :
1304 wxActiveXContainer(parent,iid,pUnk)
1305 {
1306 m_uiHandler = uiHandler;
1307 }
1308
1309 wxIEContainer::~wxIEContainer()
1310 {
1311 }
1312
1313 bool wxIEContainer::QueryClientSiteInterface(REFIID iid, void **_interface,
1314 const char *&desc)
1315 {
1316 if (m_uiHandler && IsEqualIID(iid, wxIID_IDocHostUIHandler))
1317 {
1318 *_interface = (IUnknown *) (wxIDocHostUIHandler *) m_uiHandler;
1319 desc = "IDocHostUIHandler";
1320 return true;
1321 }
1322 return false;
1323 }
1324
1325 HRESULT DocHostUIHandler::ShowContextMenu(DWORD dwID, POINT *ppt,
1326 IUnknown *pcmdtReserved,
1327 IDispatch *pdispReserved)
1328 {
1329 wxUnusedVar(dwID);
1330 wxUnusedVar(ppt);
1331 wxUnusedVar(pcmdtReserved);
1332 wxUnusedVar(pdispReserved);
1333 return E_NOTIMPL;
1334 }
1335
1336 HRESULT DocHostUIHandler::GetHostInfo(DOCHOSTUIINFO *pInfo)
1337 {
1338 //don't show 3d border and enable themes.
1339 pInfo->dwFlags = pInfo->dwFlags | DOCHOSTUIFLAG_NO3DBORDER | DOCHOSTUIFLAG_THEME;
1340 return S_OK;
1341 }
1342
1343 HRESULT DocHostUIHandler::ShowUI(DWORD dwID,
1344 IOleInPlaceActiveObject *pActiveObject,
1345 IOleCommandTarget *pCommandTarget,
1346 IOleInPlaceFrame *pFrame,
1347 IOleInPlaceUIWindow *pDoc)
1348 {
1349 wxUnusedVar(dwID);
1350 wxUnusedVar(pActiveObject);
1351 wxUnusedVar(pCommandTarget);
1352 wxUnusedVar(pFrame);
1353 wxUnusedVar(pDoc);
1354 return S_FALSE;
1355 }
1356
1357 HRESULT DocHostUIHandler::HideUI(void)
1358 {
1359 return E_NOTIMPL;
1360 }
1361
1362 HRESULT DocHostUIHandler::UpdateUI(void)
1363 {
1364 return E_NOTIMPL;
1365 }
1366
1367 HRESULT DocHostUIHandler::EnableModeless(BOOL fEnable)
1368 {
1369 wxUnusedVar(fEnable);
1370 return E_NOTIMPL;
1371 }
1372
1373 HRESULT DocHostUIHandler::OnDocWindowActivate(BOOL fActivate)
1374 {
1375 wxUnusedVar(fActivate);
1376 return E_NOTIMPL;
1377 }
1378
1379 HRESULT DocHostUIHandler::OnFrameWindowActivate(BOOL fActivate)
1380 {
1381 wxUnusedVar(fActivate);
1382 return E_NOTIMPL;
1383 }
1384
1385 HRESULT DocHostUIHandler::ResizeBorder(LPCRECT prcBorder,
1386 IOleInPlaceUIWindow *pUIWindow,
1387 BOOL fFrameWindow)
1388 {
1389 wxUnusedVar(prcBorder);
1390 wxUnusedVar(pUIWindow);
1391 wxUnusedVar(fFrameWindow);
1392 return E_NOTIMPL;
1393 }
1394
1395 HRESULT DocHostUIHandler::TranslateAccelerator(LPMSG lpMsg,
1396 const GUID *pguidCmdGroup,
1397 DWORD nCmdID)
1398 {
1399 if(lpMsg && lpMsg->message == WM_KEYDOWN)
1400 {
1401 //control is down?
1402 if((GetKeyState(VK_CONTROL) & 0x8000 ))
1403 {
1404 //skip the accelerators used by the control
1405 switch(lpMsg->wParam)
1406 {
1407 case 'F':
1408 case 'L':
1409 case 'N':
1410 case 'O':
1411 case 'P':
1412 return S_OK;
1413 }
1414 }
1415 //skip F5
1416 if(lpMsg->wParam == VK_F5)
1417 {
1418 return S_OK;
1419 }
1420 }
1421
1422 wxUnusedVar(pguidCmdGroup);
1423 wxUnusedVar(nCmdID);
1424 return E_NOTIMPL;
1425 }
1426
1427 HRESULT DocHostUIHandler::GetOptionKeyPath(LPOLESTR *pchKey,DWORD dw)
1428 {
1429 wxUnusedVar(pchKey);
1430 wxUnusedVar(dw);
1431 return E_NOTIMPL;
1432 }
1433
1434 HRESULT DocHostUIHandler::GetDropTarget(IDropTarget *pDropTarget,
1435 IDropTarget **ppDropTarget)
1436 {
1437 wxUnusedVar(pDropTarget);
1438 wxUnusedVar(ppDropTarget);
1439 return E_NOTIMPL;
1440 }
1441
1442 HRESULT DocHostUIHandler::GetExternal(IDispatch **ppDispatch)
1443 {
1444 wxUnusedVar(ppDispatch);
1445 return E_NOTIMPL;
1446 }
1447
1448 HRESULT DocHostUIHandler::TranslateUrl(DWORD dwTranslate,
1449 OLECHAR *pchURLIn,
1450 OLECHAR **ppchURLOut)
1451 {
1452 wxUnusedVar(dwTranslate);
1453 wxUnusedVar(pchURLIn);
1454 wxUnusedVar(ppchURLOut);
1455 return E_NOTIMPL;
1456 }
1457
1458 HRESULT DocHostUIHandler::FilterDataObject(IDataObject *pDO, IDataObject **ppDORet)
1459 {
1460 wxUnusedVar(pDO);
1461 wxUnusedVar(ppDORet);
1462 return E_NOTIMPL;
1463 }
1464
1465 BEGIN_IID_TABLE(DocHostUIHandler)
1466 ADD_IID(Unknown)
1467 ADD_RAW_IID(wxIID_IDocHostUIHandler)
1468 END_IID_TABLE;
1469
1470 IMPLEMENT_IUNKNOWN_METHODS(DocHostUIHandler)
1471
1472 #endif // wxUSE_WEBVIEW && wxUSE_WEBVIEW_IE