Correctly use QueryInterface in GetDocument to ensure that we only return an IHTMLDoc...
[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 bool wxWebViewIE::CanPaste() const
564 {
565 return CanExecCommand("Paste");
566 }
567
568 void wxWebViewIE::Cut()
569 {
570 ExecCommand("Cut");
571 }
572
573 void wxWebViewIE::Copy()
574 {
575 ExecCommand("Copy");
576 }
577
578 void wxWebViewIE::Paste()
579 {
580 ExecCommand("Paste");
581 }
582
583 bool wxWebViewIE::CanUndo() const
584 {
585 return CanExecCommand("Undo");
586 }
587 bool wxWebViewIE::CanRedo() const
588 {
589 return CanExecCommand("Redo");
590 }
591
592 void wxWebViewIE::Undo()
593 {
594 ExecCommand("Undo");
595 }
596
597 void wxWebViewIE::Redo()
598 {
599 ExecCommand("Redo");
600 }
601
602 void wxWebViewIE::SetEditable(bool enable)
603 {
604 IHTMLDocument2* document = GetDocument();
605
606 if(document)
607 {
608 if( enable )
609 document->put_designMode(SysAllocString(L"On"));
610 else
611 document->put_designMode(SysAllocString(L"Off"));
612
613 document->Release();
614 }
615 }
616
617 bool wxWebViewIE::IsEditable() const
618 {
619 IHTMLDocument2* document = GetDocument();
620
621 if(document)
622 {
623 BSTR mode;
624 document->get_designMode(&mode);
625 document->Release();
626 if(wxString(mode) == "On")
627 return true;
628 else
629 return false;
630 }
631 else
632 {
633 return false;
634 }
635 }
636
637 void wxWebViewIE::SelectAll()
638 {
639 ExecCommand("SelectAll");
640 }
641
642 bool wxWebViewIE::HasSelection() const
643 {
644 IHTMLDocument2* document = GetDocument();
645
646 if(document)
647 {
648 IHTMLSelectionObject* selection;
649 wxString sel;
650 HRESULT hr = document->get_selection(&selection);
651 if(SUCCEEDED(hr))
652 {
653 BSTR type;
654 selection->get_type(&type);
655 sel = wxString(type);
656 selection->Release();
657 }
658 document->Release();
659 return sel != "None";
660 }
661 else
662 {
663 return false;
664 }
665 }
666
667 void wxWebViewIE::DeleteSelection()
668 {
669 ExecCommand("Delete");
670 }
671
672 wxString wxWebViewIE::GetSelectedText() const
673 {
674 IHTMLDocument2* document = GetDocument();
675
676 if(document)
677 {
678 IHTMLSelectionObject* selection;
679 wxString selected;
680 HRESULT hr = document->get_selection(&selection);
681 if(SUCCEEDED(hr))
682 {
683 IDispatch* disrange;
684 hr = selection->createRange(&disrange);
685 if(SUCCEEDED(hr))
686 {
687 IHTMLTxtRange* range;
688 hr = disrange->QueryInterface(IID_IHTMLTxtRange, (void**)&range);
689 if(SUCCEEDED(hr))
690 {
691 BSTR text;
692 range->get_text(&text);
693 selected = wxString(text);
694 range->Release();
695 }
696 disrange->Release();
697 }
698 selection->Release();
699 }
700 document->Release();
701 return selected;
702 }
703 else
704 {
705 return "";
706 }
707 }
708
709 wxString wxWebViewIE::GetSelectedSource() const
710 {
711 IHTMLDocument2* document = GetDocument();
712
713 if(document)
714 {
715 IHTMLSelectionObject* selection;
716 wxString selected;
717 HRESULT hr = document->get_selection(&selection);
718 if(SUCCEEDED(hr))
719 {
720 IDispatch* disrange;
721 hr = selection->createRange(&disrange);
722 if(SUCCEEDED(hr))
723 {
724 IHTMLTxtRange* range;
725 hr = disrange->QueryInterface(IID_IHTMLTxtRange, (void**)&range);
726 if(SUCCEEDED(hr))
727 {
728 BSTR text;
729 range->get_htmlText(&text);
730 selected = wxString(text);
731 range->Release();
732 }
733 disrange->Release();
734 }
735 selection->Release();
736 }
737 document->Release();
738 return selected;
739 }
740 else
741 {
742 return "";
743 }
744 }
745
746 void wxWebViewIE::ClearSelection()
747 {
748 IHTMLDocument2* document = GetDocument();
749
750 if(document)
751 {
752 IHTMLSelectionObject* selection;
753 wxString selected;
754 HRESULT hr = document->get_selection(&selection);
755 if(SUCCEEDED(hr))
756 {
757 selection->empty();
758 selection->Release();
759 }
760 document->Release();
761 }
762 }
763
764 wxString wxWebViewIE::GetPageText() const
765 {
766 IHTMLDocument2* document = GetDocument();
767
768 if(document)
769 {
770 wxString text;
771 IHTMLElement* body;
772 HRESULT hr = document->get_body(&body);
773 if(SUCCEEDED(hr))
774 {
775 BSTR out;
776 body->get_innerText(&out);
777 text = wxString(out);
778 body->Release();
779 }
780 document->Release();
781 return text;
782 }
783 else
784 {
785 return "";
786 }
787 }
788
789 void wxWebViewIE::RunScript(const wxString& javascript)
790 {
791 IHTMLDocument2* document = GetDocument();
792
793 if(document)
794 {
795 IHTMLWindow2* window;
796 wxString language = "javascript";
797 HRESULT hr = document->get_parentWindow(&window);
798 if(SUCCEEDED(hr))
799 {
800 VARIANT level;
801 VariantInit(&level);
802 V_VT(&level) = VT_EMPTY;
803 window->execScript(SysAllocString(javascript.wc_str()),
804 SysAllocString(language.wc_str()),
805 &level);
806 }
807 document->Release();
808 }
809 }
810
811 void wxWebViewIE::RegisterHandler(wxSharedPtr<wxWebViewHandler> handler)
812 {
813 wxDynamicLibrary urlMon(wxT("urlmon.dll"));
814 if(urlMon.HasSymbol(wxT("CoInternetGetSession")))
815 {
816 typedef HRESULT (WINAPI *CoInternetGetSession_t)(DWORD, wxIInternetSession**, DWORD);
817 wxDYNLIB_FUNCTION(CoInternetGetSession_t, CoInternetGetSession, urlMon);
818
819 ClassFactory* cf = new ClassFactory(handler);
820 wxIInternetSession* session;
821 HRESULT res = (*pfnCoInternetGetSession)(0, &session, 0);
822 if(FAILED(res))
823 {
824 wxFAIL_MSG("Could not retrive internet session");
825 }
826
827 HRESULT hr = session->RegisterNameSpace(cf, CLSID_FileProtocol,
828 handler->GetName().wc_str(),
829 0, NULL, 0);
830 if(FAILED(hr))
831 {
832 wxFAIL_MSG("Could not register protocol");
833 }
834 m_factories.push_back(cf);
835 }
836 else
837 {
838 wxFAIL_MSG("urlmon does not contain CoInternetGetSession");
839 }
840 }
841
842 bool wxWebViewIE::CanExecCommand(wxString command) const
843 {
844 IHTMLDocument2* document = GetDocument();
845
846 if(document)
847 {
848 VARIANT_BOOL enabled;
849
850 document->queryCommandEnabled(SysAllocString(command.wc_str()), &enabled);
851 document->Release();
852
853 return (enabled == VARIANT_TRUE);
854 }
855 else
856 {
857 return false;
858 }
859
860 }
861
862 void wxWebViewIE::ExecCommand(wxString command)
863 {
864 IHTMLDocument2* document = GetDocument();
865
866 if(document)
867 {
868 document->execCommand(SysAllocString(command.wc_str()), VARIANT_FALSE, VARIANT(), NULL);
869 document->Release();
870 }
871 }
872
873 IHTMLDocument2* wxWebViewIE::GetDocument() const
874 {
875 IDispatch* dispatch;
876 HRESULT result = m_webBrowser->get_Document(&dispatch);
877 if(SUCCEEDED(result))
878 {
879 IHTMLDocument2* document;
880 dispatch->QueryInterface(IID_IHTMLDocument2, (void**)&document);
881 //document is set to null automatically if the interface isn't supported
882 return document;
883 }
884 else
885 {
886 return NULL;
887 }
888 }
889
890 bool wxWebViewIE::EnableControlFeature(long flag, bool enable)
891 {
892 #if wxUSE_DYNLIB_CLASS
893
894 wxDynamicLibrary urlMon(wxT("urlmon.dll"));
895 if( urlMon.IsLoaded() &&
896 urlMon.HasSymbol("CoInternetSetFeatureEnabled") &&
897 urlMon.HasSymbol("CoInternetIsFeatureEnabled"))
898 {
899 typedef HRESULT (WINAPI *CoInternetSetFeatureEnabled_t)(DWORD, DWORD, BOOL);
900 typedef HRESULT (WINAPI *CoInternetIsFeatureEnabled_t)(DWORD, DWORD);
901
902 wxDYNLIB_FUNCTION(CoInternetSetFeatureEnabled_t, CoInternetSetFeatureEnabled, urlMon);
903 wxDYNLIB_FUNCTION(CoInternetIsFeatureEnabled_t, CoInternetIsFeatureEnabled, urlMon);
904
905 HRESULT hr = (*pfnCoInternetIsFeatureEnabled)(flag,
906 0x2 /* SET_FEATURE_ON_PROCESS */);
907 if((hr == S_OK && enable) || (hr == S_FALSE && !enable))
908 return true;
909
910 hr = (*pfnCoInternetSetFeatureEnabled)(flag,
911 0x2/* SET_FEATURE_ON_PROCESS */,
912 (enable ? TRUE : FALSE));
913 if ( FAILED(hr) )
914 {
915 wxLogApiError(wxT("CoInternetSetFeatureEnabled"), hr);
916 return false;
917 }
918 return true;
919 }
920 return false;
921 #else
922 wxUnusedVar(flag);
923 wxUnusedVar(enable);
924 return false;
925 #endif // wxUSE_DYNLIB_CLASS/!wxUSE_DYNLIB_CLASS
926 }
927
928 void wxWebViewIE::onActiveXEvent(wxActiveXEvent& evt)
929 {
930 if (m_webBrowser == NULL) return;
931
932 switch (evt.GetDispatchId())
933 {
934 case DISPID_BEFORENAVIGATE2:
935 {
936 m_isBusy = true;
937
938 wxString url = evt[1].GetString();
939 wxString target = evt[3].GetString();
940
941 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_NAVIGATING,
942 GetId(), url, target);
943
944 //skip empty javascript events.
945 if(url == "javascript:\"\"" && target.IsEmpty())
946 {
947 event.Veto();
948 }
949 else
950 {
951 event.SetEventObject(this);
952 HandleWindowEvent(event);
953 }
954
955 if (!event.IsAllowed())
956 {
957 wxActiveXEventNativeMSW* nativeParams =
958 evt.GetNativeParameters();
959 *V_BOOLREF(&nativeParams->pDispParams->rgvarg[0]) = VARIANT_TRUE;
960 }
961
962 // at this point, either the navigation event has been cancelled
963 // and we're not busy, either it was accepted and IWebBrowser2's
964 // Busy property will be true; so we don't need our override
965 // flag anymore.
966 m_isBusy = false;
967
968 break;
969 }
970
971 case DISPID_NAVIGATECOMPLETE2:
972 {
973 wxString url = evt[1].GetString();
974 // TODO: set target parameter if possible
975 wxString target = wxEmptyString;
976 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_NAVIGATED,
977 GetId(), url, target);
978 event.SetEventObject(this);
979 HandleWindowEvent(event);
980 break;
981 }
982
983 case DISPID_PROGRESSCHANGE:
984 {
985 // download progress
986 break;
987 }
988
989 case DISPID_DOCUMENTCOMPLETE:
990 {
991 //Only send a complete even if we are actually finished, this brings
992 //the event in to line with webkit
993 READYSTATE rs;
994 m_webBrowser->get_ReadyState( &rs );
995 if(rs != READYSTATE_COMPLETE)
996 break;
997
998 wxString url = evt[1].GetString();
999
1000 //As we are complete we also add to the history list, but not if the
1001 //page is not the main page, ie it is a subframe
1002 //We also have to check if we are loading a file:// url, if so we
1003 //need to change the comparison as ie passes back a different style
1004 //of url
1005 if(m_historyEnabled && !m_historyLoadingFromList &&
1006 (url == GetCurrentURL() ||
1007 (GetCurrentURL().substr(0, 4) == "file" &&
1008 wxFileSystem::URLToFileName(GetCurrentURL()).GetFullPath() == url)))
1009 {
1010 //If we are not at the end of the list, then erase everything
1011 //between us and the end before adding the new page
1012 if(m_historyPosition != static_cast<int>(m_historyList.size()) - 1)
1013 {
1014 m_historyList.erase(m_historyList.begin() + m_historyPosition + 1,
1015 m_historyList.end());
1016 }
1017 wxSharedPtr<wxWebViewHistoryItem> item(new wxWebViewHistoryItem(url, GetCurrentTitle()));
1018 m_historyList.push_back(item);
1019 m_historyPosition++;
1020 }
1021 //Reset as we are done now
1022 m_historyLoadingFromList = false;
1023 // TODO: set target parameter if possible
1024 wxString target = wxEmptyString;
1025 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_LOADED, GetId(),
1026 url, target);
1027 event.SetEventObject(this);
1028 HandleWindowEvent(event);
1029 break;
1030 }
1031
1032 case DISPID_STATUSTEXTCHANGE:
1033 {
1034 break;
1035 }
1036
1037 case DISPID_TITLECHANGE:
1038 {
1039 wxString title = evt[0].GetString();
1040
1041 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_TITLE_CHANGED,
1042 GetId(), GetCurrentURL(), "");
1043 event.SetString(title);
1044 event.SetEventObject(this);
1045 HandleWindowEvent(event);
1046 break;
1047 }
1048
1049 case DISPID_NAVIGATEERROR:
1050 {
1051 wxWebViewNavigationError errorType = wxWEB_NAV_ERR_OTHER;
1052 wxString errorCode = "?";
1053 switch (evt[3].GetLong())
1054 {
1055 case INET_E_INVALID_URL: // (0x800C0002L or -2146697214)
1056 errorCode = "INET_E_INVALID_URL";
1057 errorType = wxWEB_NAV_ERR_REQUEST;
1058 break;
1059 case INET_E_NO_SESSION: // (0x800C0003L or -2146697213)
1060 errorCode = "INET_E_NO_SESSION";
1061 errorType = wxWEB_NAV_ERR_CONNECTION;
1062 break;
1063 case INET_E_CANNOT_CONNECT: // (0x800C0004L or -2146697212)
1064 errorCode = "INET_E_CANNOT_CONNECT";
1065 errorType = wxWEB_NAV_ERR_CONNECTION;
1066 break;
1067 case INET_E_RESOURCE_NOT_FOUND: // (0x800C0005L or -2146697211)
1068 errorCode = "INET_E_RESOURCE_NOT_FOUND";
1069 errorType = wxWEB_NAV_ERR_NOT_FOUND;
1070 break;
1071 case INET_E_OBJECT_NOT_FOUND: // (0x800C0006L or -2146697210)
1072 errorCode = "INET_E_OBJECT_NOT_FOUND";
1073 errorType = wxWEB_NAV_ERR_NOT_FOUND;
1074 break;
1075 case INET_E_DATA_NOT_AVAILABLE: // (0x800C0007L or -2146697209)
1076 errorCode = "INET_E_DATA_NOT_AVAILABLE";
1077 errorType = wxWEB_NAV_ERR_NOT_FOUND;
1078 break;
1079 case INET_E_DOWNLOAD_FAILURE: // (0x800C0008L or -2146697208)
1080 errorCode = "INET_E_DOWNLOAD_FAILURE";
1081 errorType = wxWEB_NAV_ERR_CONNECTION;
1082 break;
1083 case INET_E_AUTHENTICATION_REQUIRED: // (0x800C0009L or -2146697207)
1084 errorCode = "INET_E_AUTHENTICATION_REQUIRED";
1085 errorType = wxWEB_NAV_ERR_AUTH;
1086 break;
1087 case INET_E_NO_VALID_MEDIA: // (0x800C000AL or -2146697206)
1088 errorCode = "INET_E_NO_VALID_MEDIA";
1089 errorType = wxWEB_NAV_ERR_REQUEST;
1090 break;
1091 case INET_E_CONNECTION_TIMEOUT: // (0x800C000BL or -2146697205)
1092 errorCode = "INET_E_CONNECTION_TIMEOUT";
1093 errorType = wxWEB_NAV_ERR_CONNECTION;
1094 break;
1095 case INET_E_INVALID_REQUEST: // (0x800C000CL or -2146697204)
1096 errorCode = "INET_E_INVALID_REQUEST";
1097 errorType = wxWEB_NAV_ERR_REQUEST;
1098 break;
1099 case INET_E_UNKNOWN_PROTOCOL: // (0x800C000DL or -2146697203)
1100 errorCode = "INET_E_UNKNOWN_PROTOCOL";
1101 errorType = wxWEB_NAV_ERR_REQUEST;
1102 break;
1103 case INET_E_SECURITY_PROBLEM: // (0x800C000EL or -2146697202)
1104 errorCode = "INET_E_SECURITY_PROBLEM";
1105 errorType = wxWEB_NAV_ERR_SECURITY;
1106 break;
1107 case INET_E_CANNOT_LOAD_DATA: // (0x800C000FL or -2146697201)
1108 errorCode = "INET_E_CANNOT_LOAD_DATA";
1109 errorType = wxWEB_NAV_ERR_OTHER;
1110 break;
1111 case INET_E_CANNOT_INSTANTIATE_OBJECT:
1112 // CoCreateInstance will return an error code if this happens,
1113 // we'll handle this above.
1114 return;
1115 break;
1116 case INET_E_REDIRECT_FAILED: // (0x800C0014L or -2146697196)
1117 errorCode = "INET_E_REDIRECT_FAILED";
1118 errorType = wxWEB_NAV_ERR_OTHER;
1119 break;
1120 case INET_E_REDIRECT_TO_DIR: // (0x800C0015L or -2146697195)
1121 errorCode = "INET_E_REDIRECT_TO_DIR";
1122 errorType = wxWEB_NAV_ERR_REQUEST;
1123 break;
1124 case INET_E_CANNOT_LOCK_REQUEST: // (0x800C0016L or -2146697194)
1125 errorCode = "INET_E_CANNOT_LOCK_REQUEST";
1126 errorType = wxWEB_NAV_ERR_OTHER;
1127 break;
1128 case INET_E_USE_EXTEND_BINDING: // (0x800C0017L or -2146697193)
1129 errorCode = "INET_E_USE_EXTEND_BINDING";
1130 errorType = wxWEB_NAV_ERR_OTHER;
1131 break;
1132 case INET_E_TERMINATED_BIND: // (0x800C0018L or -2146697192)
1133 errorCode = "INET_E_TERMINATED_BIND";
1134 errorType = wxWEB_NAV_ERR_OTHER;
1135 break;
1136 case INET_E_INVALID_CERTIFICATE: // (0x800C0019L or -2146697191)
1137 errorCode = "INET_E_INVALID_CERTIFICATE";
1138 errorType = wxWEB_NAV_ERR_CERTIFICATE;
1139 break;
1140 case INET_E_CODE_DOWNLOAD_DECLINED: // (0x800C0100L or -2146696960)
1141 errorCode = "INET_E_CODE_DOWNLOAD_DECLINED";
1142 errorType = wxWEB_NAV_ERR_USER_CANCELLED;
1143 break;
1144 case INET_E_RESULT_DISPATCHED: // (0x800C0200L or -2146696704)
1145 // cancel request cancelled...
1146 errorCode = "INET_E_RESULT_DISPATCHED";
1147 errorType = wxWEB_NAV_ERR_OTHER;
1148 break;
1149 case INET_E_CANNOT_REPLACE_SFP_FILE: // (0x800C0300L or -2146696448)
1150 errorCode = "INET_E_CANNOT_REPLACE_SFP_FILE";
1151 errorType = wxWEB_NAV_ERR_SECURITY;
1152 break;
1153 case INET_E_CODE_INSTALL_BLOCKED_BY_HASH_POLICY:
1154 errorCode = "INET_E_CODE_INSTALL_BLOCKED_BY_HASH_POLICY";
1155 errorType = wxWEB_NAV_ERR_SECURITY;
1156 break;
1157 case INET_E_CODE_INSTALL_SUPPRESSED:
1158 errorCode = "INET_E_CODE_INSTALL_SUPPRESSED";
1159 errorType = wxWEB_NAV_ERR_SECURITY;
1160 break;
1161 }
1162
1163 wxString url = evt[1].GetString();
1164 wxString target = evt[2].GetString();
1165 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_ERROR, GetId(),
1166 url, target);
1167 event.SetEventObject(this);
1168 event.SetInt(errorType);
1169 event.SetString(errorCode);
1170 HandleWindowEvent(event);
1171 break;
1172 }
1173 case DISPID_NEWWINDOW3:
1174 {
1175 wxString url = evt[4].GetString();
1176
1177 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_NEWWINDOW,
1178 GetId(), url, wxEmptyString);
1179 event.SetEventObject(this);
1180 HandleWindowEvent(event);
1181
1182 //We always cancel this event otherwise an Internet Exporer window
1183 //is opened for the url
1184 wxActiveXEventNativeMSW* nativeParams = evt.GetNativeParameters();
1185 *V_BOOLREF(&nativeParams->pDispParams->rgvarg[3]) = VARIANT_TRUE;
1186 break;
1187 }
1188 }
1189
1190 evt.Skip();
1191 }
1192
1193 VirtualProtocol::VirtualProtocol(wxSharedPtr<wxWebViewHandler> handler)
1194 {
1195 m_file = NULL;
1196 m_handler = handler;
1197 }
1198
1199 BEGIN_IID_TABLE(VirtualProtocol)
1200 ADD_IID(Unknown)
1201 ADD_RAW_IID(wxIID_IInternetProtocolRoot)
1202 ADD_RAW_IID(wxIID_IInternetProtocol)
1203 END_IID_TABLE;
1204
1205 IMPLEMENT_IUNKNOWN_METHODS(VirtualProtocol)
1206
1207 HRESULT VirtualProtocol::Start(LPCWSTR szUrl, wxIInternetProtocolSink *pOIProtSink,
1208 wxIInternetBindInfo *pOIBindInfo, DWORD grfPI,
1209 HANDLE_PTR dwReserved)
1210 {
1211 wxUnusedVar(szUrl);
1212 wxUnusedVar(pOIBindInfo);
1213 wxUnusedVar(grfPI);
1214 wxUnusedVar(dwReserved);
1215 m_protocolSink = pOIProtSink;
1216
1217 //We get the file itself from the protocol handler
1218 m_file = m_handler->GetFile(szUrl);
1219
1220
1221 if(!m_file)
1222 return INET_E_RESOURCE_NOT_FOUND;
1223
1224 //We return the stream length for current and total size as we can always
1225 //read the whole file from the stream
1226 wxFileOffset length = m_file->GetStream()->GetLength();
1227 m_protocolSink->ReportData(wxBSCF_FIRSTDATANOTIFICATION |
1228 wxBSCF_DATAFULLYAVAILABLE |
1229 wxBSCF_LASTDATANOTIFICATION,
1230 length, length);
1231 return S_OK;
1232 }
1233
1234 HRESULT VirtualProtocol::Read(void *pv, ULONG cb, ULONG *pcbRead)
1235 {
1236 //If the file is null we return false to indicte it is finished
1237 if(!m_file)
1238 return S_FALSE;
1239
1240 wxStreamError err = m_file->GetStream()->Read(pv, cb).GetLastError();
1241 *pcbRead = m_file->GetStream()->LastRead();
1242
1243 if(err == wxSTREAM_NO_ERROR)
1244 {
1245 if(*pcbRead < cb)
1246 {
1247 wxDELETE(m_file);
1248 m_protocolSink->ReportResult(S_OK, 0, NULL);
1249 }
1250 //As we are not eof there is more data
1251 return S_OK;
1252 }
1253 else if(err == wxSTREAM_EOF)
1254 {
1255 wxDELETE(m_file);
1256 m_protocolSink->ReportResult(S_OK, 0, NULL);
1257 //We are eof and so finished
1258 return S_OK;
1259 }
1260 else if(err == wxSTREAM_READ_ERROR)
1261 {
1262 wxDELETE(m_file);
1263 return INET_E_DOWNLOAD_FAILURE;
1264 }
1265 else
1266 {
1267 //Dummy return to surpress a compiler warning
1268 wxFAIL;
1269 return INET_E_DOWNLOAD_FAILURE;
1270 }
1271 }
1272
1273 BEGIN_IID_TABLE(ClassFactory)
1274 ADD_IID(Unknown)
1275 ADD_IID(ClassFactory)
1276 END_IID_TABLE;
1277
1278 IMPLEMENT_IUNKNOWN_METHODS(ClassFactory)
1279
1280 HRESULT ClassFactory::CreateInstance(IUnknown* pUnkOuter, REFIID riid,
1281 void ** ppvObject)
1282 {
1283 if (pUnkOuter)
1284 return CLASS_E_NOAGGREGATION;
1285 VirtualProtocol* vp = new VirtualProtocol(m_handler);
1286 vp->AddRef();
1287 HRESULT hr = vp->QueryInterface(riid, ppvObject);
1288 vp->Release();
1289 return hr;
1290
1291 }
1292
1293 STDMETHODIMP ClassFactory::LockServer(BOOL fLock)
1294 {
1295 wxUnusedVar(fLock);
1296 return S_OK;
1297 }
1298
1299 wxIEContainer::wxIEContainer(wxWindow *parent, REFIID iid, IUnknown *pUnk,
1300 DocHostUIHandler* uiHandler) :
1301 wxActiveXContainer(parent,iid,pUnk)
1302 {
1303 m_uiHandler = uiHandler;
1304 }
1305
1306 wxIEContainer::~wxIEContainer()
1307 {
1308 }
1309
1310 bool wxIEContainer::QueryClientSiteInterface(REFIID iid, void **_interface,
1311 const char *&desc)
1312 {
1313 if (m_uiHandler && IsEqualIID(iid, wxIID_IDocHostUIHandler))
1314 {
1315 *_interface = (IUnknown *) (wxIDocHostUIHandler *) m_uiHandler;
1316 desc = "IDocHostUIHandler";
1317 return true;
1318 }
1319 return false;
1320 }
1321
1322 HRESULT DocHostUIHandler::ShowContextMenu(DWORD dwID, POINT *ppt,
1323 IUnknown *pcmdtReserved,
1324 IDispatch *pdispReserved)
1325 {
1326 wxUnusedVar(dwID);
1327 wxUnusedVar(ppt);
1328 wxUnusedVar(pcmdtReserved);
1329 wxUnusedVar(pdispReserved);
1330 return E_NOTIMPL;
1331 }
1332
1333 HRESULT DocHostUIHandler::GetHostInfo(DOCHOSTUIINFO *pInfo)
1334 {
1335 //don't show 3d border and ebales themes.
1336 pInfo->dwFlags = pInfo->dwFlags | DOCHOSTUIFLAG_NO3DBORDER | DOCHOSTUIFLAG_THEME;
1337 return S_OK;
1338 }
1339
1340 HRESULT DocHostUIHandler::ShowUI(DWORD dwID,
1341 IOleInPlaceActiveObject *pActiveObject,
1342 IOleCommandTarget *pCommandTarget,
1343 IOleInPlaceFrame *pFrame,
1344 IOleInPlaceUIWindow *pDoc)
1345 {
1346 wxUnusedVar(dwID);
1347 wxUnusedVar(pActiveObject);
1348 wxUnusedVar(pCommandTarget);
1349 wxUnusedVar(pFrame);
1350 wxUnusedVar(pDoc);
1351 return S_FALSE;
1352 }
1353
1354 HRESULT DocHostUIHandler::HideUI(void)
1355 {
1356 return E_NOTIMPL;
1357 }
1358
1359 HRESULT DocHostUIHandler::UpdateUI(void)
1360 {
1361 return E_NOTIMPL;
1362 }
1363
1364 HRESULT DocHostUIHandler::EnableModeless(BOOL fEnable)
1365 {
1366 wxUnusedVar(fEnable);
1367 return E_NOTIMPL;
1368 }
1369
1370 HRESULT DocHostUIHandler::OnDocWindowActivate(BOOL fActivate)
1371 {
1372 wxUnusedVar(fActivate);
1373 return E_NOTIMPL;
1374 }
1375
1376 HRESULT DocHostUIHandler::OnFrameWindowActivate(BOOL fActivate)
1377 {
1378 wxUnusedVar(fActivate);
1379 return E_NOTIMPL;
1380 }
1381
1382 HRESULT DocHostUIHandler::ResizeBorder(LPCRECT prcBorder,
1383 IOleInPlaceUIWindow *pUIWindow,
1384 BOOL fFrameWindow)
1385 {
1386 wxUnusedVar(prcBorder);
1387 wxUnusedVar(pUIWindow);
1388 wxUnusedVar(fFrameWindow);
1389 return E_NOTIMPL;
1390 }
1391
1392 HRESULT DocHostUIHandler::TranslateAccelerator(LPMSG lpMsg,
1393 const GUID *pguidCmdGroup,
1394 DWORD nCmdID)
1395 {
1396 if(lpMsg && lpMsg->message == WM_KEYDOWN)
1397 {
1398 //control is down?
1399 if((GetKeyState(VK_CONTROL) & 0x8000 ))
1400 {
1401 //skip CTRL-N, CTRL-F and CTRL-P
1402 if(lpMsg->wParam == 'N' || lpMsg->wParam == 'P' || lpMsg->wParam == 'F')
1403 {
1404 return S_OK;
1405 }
1406 }
1407 //skip F5
1408 if(lpMsg->wParam == VK_F5)
1409 {
1410 return S_OK;
1411 }
1412 }
1413
1414 wxUnusedVar(pguidCmdGroup);
1415 wxUnusedVar(nCmdID);
1416 return E_NOTIMPL;
1417 }
1418
1419 HRESULT DocHostUIHandler::GetOptionKeyPath(LPOLESTR *pchKey,DWORD dw)
1420 {
1421 wxUnusedVar(pchKey);
1422 wxUnusedVar(dw);
1423 return E_NOTIMPL;
1424 }
1425
1426 HRESULT DocHostUIHandler::GetDropTarget(IDropTarget *pDropTarget,
1427 IDropTarget **ppDropTarget)
1428 {
1429 wxUnusedVar(pDropTarget);
1430 wxUnusedVar(ppDropTarget);
1431 return E_NOTIMPL;
1432 }
1433
1434 HRESULT DocHostUIHandler::GetExternal(IDispatch **ppDispatch)
1435 {
1436 wxUnusedVar(ppDispatch);
1437 return E_NOTIMPL;
1438 }
1439
1440 HRESULT DocHostUIHandler::TranslateUrl(DWORD dwTranslate,
1441 OLECHAR *pchURLIn,
1442 OLECHAR **ppchURLOut)
1443 {
1444 wxUnusedVar(dwTranslate);
1445 wxUnusedVar(pchURLIn);
1446 wxUnusedVar(ppchURLOut);
1447 return E_NOTIMPL;
1448 }
1449
1450 HRESULT DocHostUIHandler::FilterDataObject(IDataObject *pDO, IDataObject **ppDORet)
1451 {
1452 wxUnusedVar(pDO);
1453 wxUnusedVar(ppDORet);
1454 return E_NOTIMPL;
1455 }
1456
1457 BEGIN_IID_TABLE(DocHostUIHandler)
1458 ADD_IID(Unknown)
1459 ADD_RAW_IID(wxIID_IDocHostUIHandler)
1460 END_IID_TABLE;
1461
1462 IMPLEMENT_IUNKNOWN_METHODS(DocHostUIHandler)
1463
1464 #endif // wxUSE_WEBVIEW && wxUSE_WEBVIEW_IE