Handle Ctrl-O and Ctrl-L MSW wxWebView accelerators too.
[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;
878 HRESULT result = m_webBrowser->get_Document(&dispatch);
879 if(SUCCEEDED(result))
880 {
881 IHTMLDocument2* document;
882 dispatch->QueryInterface(IID_IHTMLDocument2, (void**)&document);
883 //document is set to null automatically if the interface isn't supported
884 return document;
885 }
886 else
887 {
888 return NULL;
889 }
890 }
891
892 bool wxWebViewIE::EnableControlFeature(long flag, bool enable)
893 {
894 #if wxUSE_DYNLIB_CLASS
895
896 wxDynamicLibrary urlMon(wxT("urlmon.dll"));
897 if( urlMon.IsLoaded() &&
898 urlMon.HasSymbol("CoInternetSetFeatureEnabled") &&
899 urlMon.HasSymbol("CoInternetIsFeatureEnabled"))
900 {
901 typedef HRESULT (WINAPI *CoInternetSetFeatureEnabled_t)(DWORD, DWORD, BOOL);
902 typedef HRESULT (WINAPI *CoInternetIsFeatureEnabled_t)(DWORD, DWORD);
903
904 wxDYNLIB_FUNCTION(CoInternetSetFeatureEnabled_t, CoInternetSetFeatureEnabled, urlMon);
905 wxDYNLIB_FUNCTION(CoInternetIsFeatureEnabled_t, CoInternetIsFeatureEnabled, urlMon);
906
907 HRESULT hr = (*pfnCoInternetIsFeatureEnabled)(flag,
908 0x2 /* SET_FEATURE_ON_PROCESS */);
909 if((hr == S_OK && enable) || (hr == S_FALSE && !enable))
910 return true;
911
912 hr = (*pfnCoInternetSetFeatureEnabled)(flag,
913 0x2/* SET_FEATURE_ON_PROCESS */,
914 (enable ? TRUE : FALSE));
915 if ( FAILED(hr) )
916 {
917 wxLogApiError(wxT("CoInternetSetFeatureEnabled"), hr);
918 return false;
919 }
920 return true;
921 }
922 return false;
923 #else
924 wxUnusedVar(flag);
925 wxUnusedVar(enable);
926 return false;
927 #endif // wxUSE_DYNLIB_CLASS/!wxUSE_DYNLIB_CLASS
928 }
929
930 void wxWebViewIE::onActiveXEvent(wxActiveXEvent& evt)
931 {
932 if (m_webBrowser == NULL) return;
933
934 switch (evt.GetDispatchId())
935 {
936 case DISPID_BEFORENAVIGATE2:
937 {
938 m_isBusy = true;
939
940 wxString url = evt[1].GetString();
941 wxString target = evt[3].GetString();
942
943 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_NAVIGATING,
944 GetId(), url, target);
945
946 //skip empty javascript events.
947 if(url == "javascript:\"\"" && target.IsEmpty())
948 {
949 event.Veto();
950 }
951 else
952 {
953 event.SetEventObject(this);
954 HandleWindowEvent(event);
955 }
956
957 if (!event.IsAllowed())
958 {
959 wxActiveXEventNativeMSW* nativeParams =
960 evt.GetNativeParameters();
961 *V_BOOLREF(&nativeParams->pDispParams->rgvarg[0]) = VARIANT_TRUE;
962 }
963
964 // at this point, either the navigation event has been cancelled
965 // and we're not busy, either it was accepted and IWebBrowser2's
966 // Busy property will be true; so we don't need our override
967 // flag anymore.
968 m_isBusy = false;
969
970 break;
971 }
972
973 case DISPID_NAVIGATECOMPLETE2:
974 {
975 wxString url = evt[1].GetString();
976 // TODO: set target parameter if possible
977 wxString target = wxEmptyString;
978 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_NAVIGATED,
979 GetId(), url, target);
980 event.SetEventObject(this);
981 HandleWindowEvent(event);
982 break;
983 }
984
985 case DISPID_PROGRESSCHANGE:
986 {
987 // download progress
988 break;
989 }
990
991 case DISPID_DOCUMENTCOMPLETE:
992 {
993 //Only send a complete even if we are actually finished, this brings
994 //the event in to line with webkit
995 READYSTATE rs;
996 m_webBrowser->get_ReadyState( &rs );
997 if(rs != READYSTATE_COMPLETE)
998 break;
999
1000 wxString url = evt[1].GetString();
1001
1002 //As we are complete we also add to the history list, but not if the
1003 //page is not the main page, ie it is a subframe
1004 //We also have to check if we are loading a file:// url, if so we
1005 //need to change the comparison as ie passes back a different style
1006 //of url
1007 if(m_historyEnabled && !m_historyLoadingFromList &&
1008 (url == GetCurrentURL() ||
1009 (GetCurrentURL().substr(0, 4) == "file" &&
1010 wxFileSystem::URLToFileName(GetCurrentURL()).GetFullPath() == url)))
1011 {
1012 //If we are not at the end of the list, then erase everything
1013 //between us and the end before adding the new page
1014 if(m_historyPosition != static_cast<int>(m_historyList.size()) - 1)
1015 {
1016 m_historyList.erase(m_historyList.begin() + m_historyPosition + 1,
1017 m_historyList.end());
1018 }
1019 wxSharedPtr<wxWebViewHistoryItem> item(new wxWebViewHistoryItem(url, GetCurrentTitle()));
1020 m_historyList.push_back(item);
1021 m_historyPosition++;
1022 }
1023 //Reset as we are done now
1024 m_historyLoadingFromList = false;
1025 // TODO: set target parameter if possible
1026 wxString target = wxEmptyString;
1027 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_LOADED, GetId(),
1028 url, target);
1029 event.SetEventObject(this);
1030 HandleWindowEvent(event);
1031 break;
1032 }
1033
1034 case DISPID_STATUSTEXTCHANGE:
1035 {
1036 break;
1037 }
1038
1039 case DISPID_TITLECHANGE:
1040 {
1041 wxString title = evt[0].GetString();
1042
1043 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_TITLE_CHANGED,
1044 GetId(), GetCurrentURL(), "");
1045 event.SetString(title);
1046 event.SetEventObject(this);
1047 HandleWindowEvent(event);
1048 break;
1049 }
1050
1051 case DISPID_NAVIGATEERROR:
1052 {
1053 wxWebViewNavigationError errorType = wxWEB_NAV_ERR_OTHER;
1054 wxString errorCode = "?";
1055 switch (evt[3].GetLong())
1056 {
1057 case INET_E_INVALID_URL: // (0x800C0002L or -2146697214)
1058 errorCode = "INET_E_INVALID_URL";
1059 errorType = wxWEB_NAV_ERR_REQUEST;
1060 break;
1061 case INET_E_NO_SESSION: // (0x800C0003L or -2146697213)
1062 errorCode = "INET_E_NO_SESSION";
1063 errorType = wxWEB_NAV_ERR_CONNECTION;
1064 break;
1065 case INET_E_CANNOT_CONNECT: // (0x800C0004L or -2146697212)
1066 errorCode = "INET_E_CANNOT_CONNECT";
1067 errorType = wxWEB_NAV_ERR_CONNECTION;
1068 break;
1069 case INET_E_RESOURCE_NOT_FOUND: // (0x800C0005L or -2146697211)
1070 errorCode = "INET_E_RESOURCE_NOT_FOUND";
1071 errorType = wxWEB_NAV_ERR_NOT_FOUND;
1072 break;
1073 case INET_E_OBJECT_NOT_FOUND: // (0x800C0006L or -2146697210)
1074 errorCode = "INET_E_OBJECT_NOT_FOUND";
1075 errorType = wxWEB_NAV_ERR_NOT_FOUND;
1076 break;
1077 case INET_E_DATA_NOT_AVAILABLE: // (0x800C0007L or -2146697209)
1078 errorCode = "INET_E_DATA_NOT_AVAILABLE";
1079 errorType = wxWEB_NAV_ERR_NOT_FOUND;
1080 break;
1081 case INET_E_DOWNLOAD_FAILURE: // (0x800C0008L or -2146697208)
1082 errorCode = "INET_E_DOWNLOAD_FAILURE";
1083 errorType = wxWEB_NAV_ERR_CONNECTION;
1084 break;
1085 case INET_E_AUTHENTICATION_REQUIRED: // (0x800C0009L or -2146697207)
1086 errorCode = "INET_E_AUTHENTICATION_REQUIRED";
1087 errorType = wxWEB_NAV_ERR_AUTH;
1088 break;
1089 case INET_E_NO_VALID_MEDIA: // (0x800C000AL or -2146697206)
1090 errorCode = "INET_E_NO_VALID_MEDIA";
1091 errorType = wxWEB_NAV_ERR_REQUEST;
1092 break;
1093 case INET_E_CONNECTION_TIMEOUT: // (0x800C000BL or -2146697205)
1094 errorCode = "INET_E_CONNECTION_TIMEOUT";
1095 errorType = wxWEB_NAV_ERR_CONNECTION;
1096 break;
1097 case INET_E_INVALID_REQUEST: // (0x800C000CL or -2146697204)
1098 errorCode = "INET_E_INVALID_REQUEST";
1099 errorType = wxWEB_NAV_ERR_REQUEST;
1100 break;
1101 case INET_E_UNKNOWN_PROTOCOL: // (0x800C000DL or -2146697203)
1102 errorCode = "INET_E_UNKNOWN_PROTOCOL";
1103 errorType = wxWEB_NAV_ERR_REQUEST;
1104 break;
1105 case INET_E_SECURITY_PROBLEM: // (0x800C000EL or -2146697202)
1106 errorCode = "INET_E_SECURITY_PROBLEM";
1107 errorType = wxWEB_NAV_ERR_SECURITY;
1108 break;
1109 case INET_E_CANNOT_LOAD_DATA: // (0x800C000FL or -2146697201)
1110 errorCode = "INET_E_CANNOT_LOAD_DATA";
1111 errorType = wxWEB_NAV_ERR_OTHER;
1112 break;
1113 case INET_E_CANNOT_INSTANTIATE_OBJECT:
1114 // CoCreateInstance will return an error code if this happens,
1115 // we'll handle this above.
1116 return;
1117 break;
1118 case INET_E_REDIRECT_FAILED: // (0x800C0014L or -2146697196)
1119 errorCode = "INET_E_REDIRECT_FAILED";
1120 errorType = wxWEB_NAV_ERR_OTHER;
1121 break;
1122 case INET_E_REDIRECT_TO_DIR: // (0x800C0015L or -2146697195)
1123 errorCode = "INET_E_REDIRECT_TO_DIR";
1124 errorType = wxWEB_NAV_ERR_REQUEST;
1125 break;
1126 case INET_E_CANNOT_LOCK_REQUEST: // (0x800C0016L or -2146697194)
1127 errorCode = "INET_E_CANNOT_LOCK_REQUEST";
1128 errorType = wxWEB_NAV_ERR_OTHER;
1129 break;
1130 case INET_E_USE_EXTEND_BINDING: // (0x800C0017L or -2146697193)
1131 errorCode = "INET_E_USE_EXTEND_BINDING";
1132 errorType = wxWEB_NAV_ERR_OTHER;
1133 break;
1134 case INET_E_TERMINATED_BIND: // (0x800C0018L or -2146697192)
1135 errorCode = "INET_E_TERMINATED_BIND";
1136 errorType = wxWEB_NAV_ERR_OTHER;
1137 break;
1138 case INET_E_INVALID_CERTIFICATE: // (0x800C0019L or -2146697191)
1139 errorCode = "INET_E_INVALID_CERTIFICATE";
1140 errorType = wxWEB_NAV_ERR_CERTIFICATE;
1141 break;
1142 case INET_E_CODE_DOWNLOAD_DECLINED: // (0x800C0100L or -2146696960)
1143 errorCode = "INET_E_CODE_DOWNLOAD_DECLINED";
1144 errorType = wxWEB_NAV_ERR_USER_CANCELLED;
1145 break;
1146 case INET_E_RESULT_DISPATCHED: // (0x800C0200L or -2146696704)
1147 // cancel request cancelled...
1148 errorCode = "INET_E_RESULT_DISPATCHED";
1149 errorType = wxWEB_NAV_ERR_OTHER;
1150 break;
1151 case INET_E_CANNOT_REPLACE_SFP_FILE: // (0x800C0300L or -2146696448)
1152 errorCode = "INET_E_CANNOT_REPLACE_SFP_FILE";
1153 errorType = wxWEB_NAV_ERR_SECURITY;
1154 break;
1155 case INET_E_CODE_INSTALL_BLOCKED_BY_HASH_POLICY:
1156 errorCode = "INET_E_CODE_INSTALL_BLOCKED_BY_HASH_POLICY";
1157 errorType = wxWEB_NAV_ERR_SECURITY;
1158 break;
1159 case INET_E_CODE_INSTALL_SUPPRESSED:
1160 errorCode = "INET_E_CODE_INSTALL_SUPPRESSED";
1161 errorType = wxWEB_NAV_ERR_SECURITY;
1162 break;
1163 }
1164
1165 wxString url = evt[1].GetString();
1166 wxString target = evt[2].GetString();
1167 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_ERROR, GetId(),
1168 url, target);
1169 event.SetEventObject(this);
1170 event.SetInt(errorType);
1171 event.SetString(errorCode);
1172 HandleWindowEvent(event);
1173 break;
1174 }
1175 case DISPID_NEWWINDOW3:
1176 {
1177 wxString url = evt[4].GetString();
1178
1179 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_NEWWINDOW,
1180 GetId(), url, wxEmptyString);
1181 event.SetEventObject(this);
1182 HandleWindowEvent(event);
1183
1184 //We always cancel this event otherwise an Internet Exporer window
1185 //is opened for the url
1186 wxActiveXEventNativeMSW* nativeParams = evt.GetNativeParameters();
1187 *V_BOOLREF(&nativeParams->pDispParams->rgvarg[3]) = VARIANT_TRUE;
1188 break;
1189 }
1190 }
1191
1192 evt.Skip();
1193 }
1194
1195 VirtualProtocol::VirtualProtocol(wxSharedPtr<wxWebViewHandler> handler)
1196 {
1197 m_file = NULL;
1198 m_handler = handler;
1199 }
1200
1201 BEGIN_IID_TABLE(VirtualProtocol)
1202 ADD_IID(Unknown)
1203 ADD_RAW_IID(wxIID_IInternetProtocolRoot)
1204 ADD_RAW_IID(wxIID_IInternetProtocol)
1205 END_IID_TABLE;
1206
1207 IMPLEMENT_IUNKNOWN_METHODS(VirtualProtocol)
1208
1209 HRESULT VirtualProtocol::Start(LPCWSTR szUrl, wxIInternetProtocolSink *pOIProtSink,
1210 wxIInternetBindInfo *pOIBindInfo, DWORD grfPI,
1211 HANDLE_PTR dwReserved)
1212 {
1213 wxUnusedVar(szUrl);
1214 wxUnusedVar(pOIBindInfo);
1215 wxUnusedVar(grfPI);
1216 wxUnusedVar(dwReserved);
1217 m_protocolSink = pOIProtSink;
1218
1219 //We get the file itself from the protocol handler
1220 m_file = m_handler->GetFile(szUrl);
1221
1222
1223 if(!m_file)
1224 return INET_E_RESOURCE_NOT_FOUND;
1225
1226 //We return the stream length for current and total size as we can always
1227 //read the whole file from the stream
1228 wxFileOffset length = m_file->GetStream()->GetLength();
1229 m_protocolSink->ReportData(wxBSCF_FIRSTDATANOTIFICATION |
1230 wxBSCF_DATAFULLYAVAILABLE |
1231 wxBSCF_LASTDATANOTIFICATION,
1232 length, length);
1233 return S_OK;
1234 }
1235
1236 HRESULT VirtualProtocol::Read(void *pv, ULONG cb, ULONG *pcbRead)
1237 {
1238 //If the file is null we return false to indicte it is finished
1239 if(!m_file)
1240 return S_FALSE;
1241
1242 wxStreamError err = m_file->GetStream()->Read(pv, cb).GetLastError();
1243 *pcbRead = m_file->GetStream()->LastRead();
1244
1245 if(err == wxSTREAM_NO_ERROR)
1246 {
1247 if(*pcbRead < cb)
1248 {
1249 wxDELETE(m_file);
1250 m_protocolSink->ReportResult(S_OK, 0, NULL);
1251 }
1252 //As we are not eof there is more data
1253 return S_OK;
1254 }
1255 else if(err == wxSTREAM_EOF)
1256 {
1257 wxDELETE(m_file);
1258 m_protocolSink->ReportResult(S_OK, 0, NULL);
1259 //We are eof and so finished
1260 return S_OK;
1261 }
1262 else if(err == wxSTREAM_READ_ERROR)
1263 {
1264 wxDELETE(m_file);
1265 return INET_E_DOWNLOAD_FAILURE;
1266 }
1267 else
1268 {
1269 //Dummy return to surpress a compiler warning
1270 wxFAIL;
1271 return INET_E_DOWNLOAD_FAILURE;
1272 }
1273 }
1274
1275 BEGIN_IID_TABLE(ClassFactory)
1276 ADD_IID(Unknown)
1277 ADD_IID(ClassFactory)
1278 END_IID_TABLE;
1279
1280 IMPLEMENT_IUNKNOWN_METHODS(ClassFactory)
1281
1282 HRESULT ClassFactory::CreateInstance(IUnknown* pUnkOuter, REFIID riid,
1283 void ** ppvObject)
1284 {
1285 if (pUnkOuter)
1286 return CLASS_E_NOAGGREGATION;
1287 VirtualProtocol* vp = new VirtualProtocol(m_handler);
1288 vp->AddRef();
1289 HRESULT hr = vp->QueryInterface(riid, ppvObject);
1290 vp->Release();
1291 return hr;
1292
1293 }
1294
1295 STDMETHODIMP ClassFactory::LockServer(BOOL fLock)
1296 {
1297 wxUnusedVar(fLock);
1298 return S_OK;
1299 }
1300
1301 wxIEContainer::wxIEContainer(wxWindow *parent, REFIID iid, IUnknown *pUnk,
1302 DocHostUIHandler* uiHandler) :
1303 wxActiveXContainer(parent,iid,pUnk)
1304 {
1305 m_uiHandler = uiHandler;
1306 }
1307
1308 wxIEContainer::~wxIEContainer()
1309 {
1310 }
1311
1312 bool wxIEContainer::QueryClientSiteInterface(REFIID iid, void **_interface,
1313 const char *&desc)
1314 {
1315 if (m_uiHandler && IsEqualIID(iid, wxIID_IDocHostUIHandler))
1316 {
1317 *_interface = (IUnknown *) (wxIDocHostUIHandler *) m_uiHandler;
1318 desc = "IDocHostUIHandler";
1319 return true;
1320 }
1321 return false;
1322 }
1323
1324 HRESULT DocHostUIHandler::ShowContextMenu(DWORD dwID, POINT *ppt,
1325 IUnknown *pcmdtReserved,
1326 IDispatch *pdispReserved)
1327 {
1328 wxUnusedVar(dwID);
1329 wxUnusedVar(ppt);
1330 wxUnusedVar(pcmdtReserved);
1331 wxUnusedVar(pdispReserved);
1332 return E_NOTIMPL;
1333 }
1334
1335 HRESULT DocHostUIHandler::GetHostInfo(DOCHOSTUIINFO *pInfo)
1336 {
1337 //don't show 3d border and enable themes.
1338 pInfo->dwFlags = pInfo->dwFlags | DOCHOSTUIFLAG_NO3DBORDER | DOCHOSTUIFLAG_THEME;
1339 return S_OK;
1340 }
1341
1342 HRESULT DocHostUIHandler::ShowUI(DWORD dwID,
1343 IOleInPlaceActiveObject *pActiveObject,
1344 IOleCommandTarget *pCommandTarget,
1345 IOleInPlaceFrame *pFrame,
1346 IOleInPlaceUIWindow *pDoc)
1347 {
1348 wxUnusedVar(dwID);
1349 wxUnusedVar(pActiveObject);
1350 wxUnusedVar(pCommandTarget);
1351 wxUnusedVar(pFrame);
1352 wxUnusedVar(pDoc);
1353 return S_FALSE;
1354 }
1355
1356 HRESULT DocHostUIHandler::HideUI(void)
1357 {
1358 return E_NOTIMPL;
1359 }
1360
1361 HRESULT DocHostUIHandler::UpdateUI(void)
1362 {
1363 return E_NOTIMPL;
1364 }
1365
1366 HRESULT DocHostUIHandler::EnableModeless(BOOL fEnable)
1367 {
1368 wxUnusedVar(fEnable);
1369 return E_NOTIMPL;
1370 }
1371
1372 HRESULT DocHostUIHandler::OnDocWindowActivate(BOOL fActivate)
1373 {
1374 wxUnusedVar(fActivate);
1375 return E_NOTIMPL;
1376 }
1377
1378 HRESULT DocHostUIHandler::OnFrameWindowActivate(BOOL fActivate)
1379 {
1380 wxUnusedVar(fActivate);
1381 return E_NOTIMPL;
1382 }
1383
1384 HRESULT DocHostUIHandler::ResizeBorder(LPCRECT prcBorder,
1385 IOleInPlaceUIWindow *pUIWindow,
1386 BOOL fFrameWindow)
1387 {
1388 wxUnusedVar(prcBorder);
1389 wxUnusedVar(pUIWindow);
1390 wxUnusedVar(fFrameWindow);
1391 return E_NOTIMPL;
1392 }
1393
1394 HRESULT DocHostUIHandler::TranslateAccelerator(LPMSG lpMsg,
1395 const GUID *pguidCmdGroup,
1396 DWORD nCmdID)
1397 {
1398 if(lpMsg && lpMsg->message == WM_KEYDOWN)
1399 {
1400 //control is down?
1401 if((GetKeyState(VK_CONTROL) & 0x8000 ))
1402 {
1403 //skip the accelerators used by the control
1404 switch(lpMsg->wParam)
1405 {
1406 case 'F':
1407 case 'L':
1408 case 'N':
1409 case 'O':
1410 case 'P':
1411 return S_OK;
1412 }
1413 }
1414 //skip F5
1415 if(lpMsg->wParam == VK_F5)
1416 {
1417 return S_OK;
1418 }
1419 }
1420
1421 wxUnusedVar(pguidCmdGroup);
1422 wxUnusedVar(nCmdID);
1423 return E_NOTIMPL;
1424 }
1425
1426 HRESULT DocHostUIHandler::GetOptionKeyPath(LPOLESTR *pchKey,DWORD dw)
1427 {
1428 wxUnusedVar(pchKey);
1429 wxUnusedVar(dw);
1430 return E_NOTIMPL;
1431 }
1432
1433 HRESULT DocHostUIHandler::GetDropTarget(IDropTarget *pDropTarget,
1434 IDropTarget **ppDropTarget)
1435 {
1436 wxUnusedVar(pDropTarget);
1437 wxUnusedVar(ppDropTarget);
1438 return E_NOTIMPL;
1439 }
1440
1441 HRESULT DocHostUIHandler::GetExternal(IDispatch **ppDispatch)
1442 {
1443 wxUnusedVar(ppDispatch);
1444 return E_NOTIMPL;
1445 }
1446
1447 HRESULT DocHostUIHandler::TranslateUrl(DWORD dwTranslate,
1448 OLECHAR *pchURLIn,
1449 OLECHAR **ppchURLOut)
1450 {
1451 wxUnusedVar(dwTranslate);
1452 wxUnusedVar(pchURLIn);
1453 wxUnusedVar(ppchURLOut);
1454 return E_NOTIMPL;
1455 }
1456
1457 HRESULT DocHostUIHandler::FilterDataObject(IDataObject *pDO, IDataObject **ppDORet)
1458 {
1459 wxUnusedVar(pDO);
1460 wxUnusedVar(ppDORet);
1461 return E_NOTIMPL;
1462 }
1463
1464 BEGIN_IID_TABLE(DocHostUIHandler)
1465 ADD_IID(Unknown)
1466 ADD_RAW_IID(wxIID_IDocHostUIHandler)
1467 END_IID_TABLE;
1468
1469 IMPLEMENT_IUNKNOWN_METHODS(DocHostUIHandler)
1470
1471 #endif // wxUSE_WEBVIEW && wxUSE_WEBVIEW_IE