]> git.saurik.com Git - wxWidgets.git/blame - src/msw/webview_ie.cpp
Don't use any icon for items inserted without one in wxMSW wxListCtrl.
[wxWidgets.git] / src / msw / webview_ie.cpp
CommitLineData
61b98a2d 1/////////////////////////////////////////////////////////////////////////////
8290e3cd 2// Name: src/msw/webview_ie.cpp
61b98a2d
SL
3// Purpose: wxMSW wxWebViewIE class implementation for web view component
4// Author: Marianne Gagnon
153530af 5// Copyright: (c) 2010 Marianne Gagnon, 2011 Steven Lamerton
61b98a2d
SL
6// Licence: wxWindows licence
7/////////////////////////////////////////////////////////////////////////////
8
384b8d9f
SL
9// For compilers that support precompilation, includes "wx.h".
10#include "wx/wxprec.h"
11
12#if defined(__BORLANDC__)
13 #pragma hdrstop
14#endif
15
8290e3cd 16#include "wx/msw/webview_ie.h"
61b98a2d 17
9d2f31db 18#if wxUSE_WEBVIEW && wxUSE_WEBVIEW_IE
61b98a2d
SL
19
20#include <olectl.h>
21#include <oleidl.h>
22#include <exdispid.h>
23#include <exdisp.h>
24#include <mshtml.h>
cd4e4673 25#include "wx/msw/registry.h"
1d7d04d7 26#include "wx/msw/missing.h"
7d3f6b4d 27#include "wx/filesys.h"
e924e848 28#include "wx/dynlib.h"
f559d1a2 29#include <initguid.h>
c1381581 30#include <wininet.h>
f559d1a2
VZ
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
36namespace {
37
38DEFINE_GUID(wxIID_IInternetProtocolRoot,0x79eac9e3,0xbaf9,0x11ce,0x8c,0x82,0,0xaa,0,0x4b,0xa9,0xb);
39DEFINE_GUID(wxIID_IInternetProtocol,0x79eac9e4,0xbaf9,0x11ce,0x8c,0x82,0,0xaa,0,0x4b,0xa9,0xb);
accc94d5 40DEFINE_GUID(wxIID_IDocHostUIHandler, 0xbd3f23c0, 0xd43e, 0x11cf, 0x89, 0x3b, 0x00, 0xaa, 0x00, 0xbd, 0xce, 0x1a);
e52aec97
SL
41DEFINE_GUID(wxIID_IHTMLElement2,0x3050f434,0x98b5,0x11cf,0xbb,0x82,0,0xaa,0,0xbd,0xce,0x0b);
42DEFINE_GUID(wxIID_IMarkupServices,0x3050f4a0,0x98b5,0x11cf,0xbb,0x82,0,0xaa,0,0xbd,0xce,0x0b);
43DEFINE_GUID(wxIID_IMarkupContainer,0x3050f5f9,0x98b5,0x11cf,0xbb,0x82,0,0xaa,0,0xbd,0xce,0x0b);
f559d1a2 44
66ac0400
SL
45enum //Internal find flags
46{
236cff73
SL
47 wxWEBVIEW_FIND_ADD_POINTERS = 0x0001,
48 wxWEBVIEW_FIND_REMOVE_HIGHLIGHT = 0x0002
66ac0400
SL
49};
50
f559d1a2 51}
7d3f6b4d 52
c1381581
SL
53//Convenience function for error conversion
54#define WX_ERROR_CASE(error, wxerror) \
55 case error: \
56 event.SetString(#error); \
57 event.SetInt(wxerror); \
58 break;
59
cddf4541
SL
60wxIMPLEMENT_DYNAMIC_CLASS(wxWebViewIE, wxWebView);
61
61b98a2d 62BEGIN_EVENT_TABLE(wxWebViewIE, wxControl)
97ad1425
SL
63 EVT_ACTIVEX(wxID_ANY, wxWebViewIE::onActiveXEvent)
64 EVT_ERASE_BACKGROUND(wxWebViewIE::onEraseBg)
61b98a2d
SL
65END_EVENT_TABLE()
66
67bool wxWebViewIE::Create(wxWindow* parent,
68 wxWindowID id,
69 const wxString& url,
70 const wxPoint& pos,
71 const wxSize& size,
72 long style,
73 const wxString& name)
74{
75 if (!wxControl::Create(parent, id, pos, size, style,
76 wxDefaultValidator, name))
77 {
78 return false;
79 }
80
81 m_webBrowser = NULL;
61b98a2d 82 m_isBusy = false;
74af0b13
SL
83 m_historyLoadingFromList = false;
84 m_historyEnabled = true;
85 m_historyPosition = -1;
236cff73 86 m_zoomType = wxWEBVIEW_ZOOM_TYPE_TEXT;
66ac0400 87 FindClear();
61b98a2d
SL
88
89 if (::CoCreateInstance(CLSID_WebBrowser, NULL,
90 CLSCTX_INPROC_SERVER, // CLSCTX_INPROC,
91 IID_IWebBrowser2 , (void**)&m_webBrowser) != 0)
92 {
93 wxLogError("Failed to initialize IE, CoCreateInstance returned an error");
94 return false;
95 }
96
97 m_ie.SetDispatchPtr(m_webBrowser); // wxAutomationObject will release itself
98
99 m_webBrowser->put_RegisterAsBrowser(VARIANT_TRUE);
100 m_webBrowser->put_RegisterAsDropTarget(VARIANT_TRUE);
61b98a2d 101
c420d57b 102 m_uiHandler = new DocHostUIHandler(this);
accc94d5
SL
103
104 m_container = new wxIEContainer(this, IID_IWebBrowser2, m_webBrowser, m_uiHandler);
61b98a2d 105
9447a0d6
SL
106 EnableControlFeature(21 /* FEATURE_DISABLE_NAVIGATION_SOUNDS */);
107
4d0dddc7 108 LoadURL(url);
61b98a2d
SL
109 return true;
110}
111
39498710
SL
112wxWebViewIE::~wxWebViewIE()
113{
8626e0b7
SL
114 wxDynamicLibrary urlMon(wxT("urlmon.dll"));
115 if(urlMon.HasSymbol(wxT("CoInternetGetSession")))
39498710 116 {
8626e0b7
SL
117 typedef HRESULT (WINAPI *CoInternetGetSession_t)(DWORD,
118 wxIInternetSession**,
119 DWORD);
120 wxDYNLIB_FUNCTION(CoInternetGetSession_t, CoInternetGetSession, urlMon);
121
122 wxIInternetSession* session;
123 HRESULT res = (*pfnCoInternetGetSession)(0, &session, 0);
124 if(FAILED(res))
125 {
126 wxFAIL_MSG("Could not retrive internet session");
127 }
128
129 for(unsigned int i = 0; i < m_factories.size(); i++)
130 {
131 session->UnregisterNameSpace(m_factories[i],
132 (m_factories[i]->GetName()).wc_str());
133 m_factories[i]->Release();
134 }
39498710 135 }
66ac0400 136 FindClear();
39498710 137}
61b98a2d 138
4d0dddc7 139void wxWebViewIE::LoadURL(const wxString& url)
61b98a2d 140{
e8d243a9 141 m_ie.CallMethod("Navigate", wxConvertStringToOle(url));
61b98a2d
SL
142}
143
a977376a 144void wxWebViewIE::DoSetPage(const wxString& html, const wxString& baseUrl)
61b98a2d 145{
7f98bdd6 146 BSTR bstr = SysAllocString(OLESTR(""));
61b98a2d
SL
147 SAFEARRAY *psaStrings = SafeArrayCreateVector(VT_VARIANT, 0, 1);
148 if (psaStrings != NULL)
149 {
150 VARIANT *param;
151 HRESULT hr = SafeArrayAccessData(psaStrings, (LPVOID*)&param);
152 param->vt = VT_BSTR;
153 param->bstrVal = bstr;
442262d4 154
7f98bdd6 155 hr = SafeArrayUnaccessData(psaStrings);
accc94d5 156
f40f8e17 157 wxCOMPtr<IHTMLDocument2> document(GetDocument());
e81ef297
SL
158
159 if(!document)
160 return;
161
61b98a2d 162 document->write(psaStrings);
7f98bdd6 163 document->close();
61b98a2d 164
61b98a2d 165 SafeArrayDestroy(psaStrings);
442262d4 166
7f98bdd6
SL
167 bstr = SysAllocString(html.wc_str());
168
169 // Creates a new one-dimensional array
170 psaStrings = SafeArrayCreateVector(VT_VARIANT, 0, 1);
171 if (psaStrings != NULL)
172 {
173 hr = SafeArrayAccessData(psaStrings, (LPVOID*)&param);
174 param->vt = VT_BSTR;
175 param->bstrVal = bstr;
176 hr = SafeArrayUnaccessData(psaStrings);
177
178 document = GetDocument();
e81ef297
SL
179
180 if(!document)
181 return;
182
7f98bdd6 183 document->write(psaStrings);
7f98bdd6
SL
184
185 // SafeArrayDestroy calls SysFreeString for each BSTR
186 SafeArrayDestroy(psaStrings);
187
188 //We send the events when we are done to mimic webkit
189 //Navigated event
ce7fe42e 190 wxWebViewEvent event(wxEVT_WEBVIEW_NAVIGATED,
7f98bdd6
SL
191 GetId(), baseUrl, "");
192 event.SetEventObject(this);
193 HandleWindowEvent(event);
194
195 //Document complete event
ce7fe42e 196 event.SetEventType(wxEVT_WEBVIEW_LOADED);
7f98bdd6
SL
197 event.SetEventObject(this);
198 HandleWindowEvent(event);
199 }
200 else
201 {
202 wxLogError("wxWebViewIE::SetPage() : psaStrings is NULL");
203 }
61b98a2d
SL
204 }
205 else
206 {
7f98bdd6 207 wxLogError("wxWebViewIE::SetPage() : psaStrings is NULL during clear");
61b98a2d 208 }
61b98a2d
SL
209}
210
e669ddde 211wxString wxWebViewIE::GetPageSource() const
61b98a2d 212{
f40f8e17 213 wxCOMPtr<IHTMLDocument2> document(GetDocument());
e81ef297
SL
214
215 if(document)
7fbc727b 216 {
f40f8e17
SL
217 wxCOMPtr<IHTMLElement> bodyTag;
218 wxCOMPtr<IHTMLElement> htmlTag;
e81ef297
SL
219 wxString source;
220 HRESULT hr = document->get_body(&bodyTag);
7fbc727b
SL
221 if(SUCCEEDED(hr))
222 {
e81ef297
SL
223 hr = bodyTag->get_parentElement(&htmlTag);
224 if(SUCCEEDED(hr))
225 {
226 BSTR bstr;
227 htmlTag->get_outerHTML(&bstr);
228 source = wxString(bstr);
e81ef297 229 }
7fbc727b 230 }
e81ef297
SL
231 return source;
232 }
233 else
234 {
235 return "";
236 }
61b98a2d
SL
237}
238
e669ddde 239wxWebViewZoom wxWebViewIE::GetZoom() const
61b98a2d 240{
8acbf08b
SL
241 switch( m_zoomType )
242 {
236cff73 243 case wxWEBVIEW_ZOOM_TYPE_LAYOUT:
8acbf08b 244 return GetIEOpticalZoom();
236cff73 245 case wxWEBVIEW_ZOOM_TYPE_TEXT:
8acbf08b
SL
246 return GetIETextZoom();
247 default:
248 wxFAIL;
249 }
423adfde
SL
250
251 //Dummy return to stop compiler warnings
236cff73 252 return wxWEBVIEW_ZOOM_MEDIUM;
1d7d04d7 253
61b98a2d 254}
c5f417cb 255
61b98a2d
SL
256void wxWebViewIE::SetZoom(wxWebViewZoom zoom)
257{
8acbf08b
SL
258 switch( m_zoomType )
259 {
236cff73 260 case wxWEBVIEW_ZOOM_TYPE_LAYOUT:
8acbf08b
SL
261 SetIEOpticalZoom(zoom);
262 break;
236cff73 263 case wxWEBVIEW_ZOOM_TYPE_TEXT:
8acbf08b
SL
264 SetIETextZoom(zoom);
265 break;
266 default:
267 wxFAIL;
268 }
61b98a2d
SL
269}
270
c5f417cb 271void wxWebViewIE::SetIETextZoom(wxWebViewZoom level)
61b98a2d 272{
1d7d04d7 273 //We do not use OLECMDID_OPTICAL_GETZOOMRANGE as the docs say the range
c5f417cb
SL
274 //is 0 to 4 so the check is unnecessary, these match exactly with the
275 //enum values
61b98a2d
SL
276 VARIANT zoomVariant;
277 VariantInit (&zoomVariant);
278 V_VT(&zoomVariant) = VT_I4;
279 V_I4(&zoomVariant) = level;
280
8acbf08b
SL
281#if wxDEBUG_LEVEL
282 HRESULT result =
283#endif
284 m_webBrowser->ExecWB(OLECMDID_ZOOM,
285 OLECMDEXECOPT_DONTPROMPTUSER,
286 &zoomVariant, NULL);
c5f417cb 287 wxASSERT(result == S_OK);
61b98a2d
SL
288}
289
e669ddde 290wxWebViewZoom wxWebViewIE::GetIETextZoom() const
61b98a2d
SL
291{
292 VARIANT zoomVariant;
293 VariantInit (&zoomVariant);
294 V_VT(&zoomVariant) = VT_I4;
61b98a2d 295
8acbf08b
SL
296#if wxDEBUG_LEVEL
297 HRESULT result =
298#endif
299 m_webBrowser->ExecWB(OLECMDID_ZOOM,
300 OLECMDEXECOPT_DONTPROMPTUSER,
301 NULL, &zoomVariant);
c5f417cb 302 wxASSERT(result == S_OK);
61b98a2d 303
c5f417cb
SL
304 //We can safely cast here as we know that the range matches our enum
305 return static_cast<wxWebViewZoom>(V_I4(&zoomVariant));
61b98a2d
SL
306}
307
c5f417cb 308void wxWebViewIE::SetIEOpticalZoom(wxWebViewZoom level)
61b98a2d 309{
1d7d04d7 310 //We do not use OLECMDID_OPTICAL_GETZOOMRANGE as the docs say the range
c5f417cb 311 //is 10 to 1000 so the check is unnecessary
61b98a2d
SL
312 VARIANT zoomVariant;
313 VariantInit (&zoomVariant);
314 V_VT(&zoomVariant) = VT_I4;
c5f417cb
SL
315
316 //We make a somewhat arbitray map here, taken from values used by webkit
317 switch(level)
318 {
236cff73 319 case wxWEBVIEW_ZOOM_TINY:
c5f417cb
SL
320 V_I4(&zoomVariant) = 60;
321 break;
236cff73 322 case wxWEBVIEW_ZOOM_SMALL:
c5f417cb
SL
323 V_I4(&zoomVariant) = 80;
324 break;
236cff73 325 case wxWEBVIEW_ZOOM_MEDIUM:
c5f417cb
SL
326 V_I4(&zoomVariant) = 100;
327 break;
236cff73 328 case wxWEBVIEW_ZOOM_LARGE:
c5f417cb
SL
329 V_I4(&zoomVariant) = 130;
330 break;
236cff73 331 case wxWEBVIEW_ZOOM_LARGEST:
c5f417cb
SL
332 V_I4(&zoomVariant) = 160;
333 break;
334 default:
335 wxFAIL;
336 }
61b98a2d 337
8acbf08b
SL
338#if wxDEBUG_LEVEL
339 HRESULT result =
340#endif
341 m_webBrowser->ExecWB((OLECMDID)63 /*OLECMDID_OPTICAL_ZOOM*/,
342 OLECMDEXECOPT_DODEFAULT,
343 &zoomVariant,
344 NULL);
c5f417cb 345 wxASSERT(result == S_OK);
61b98a2d
SL
346}
347
e669ddde 348wxWebViewZoom wxWebViewIE::GetIEOpticalZoom() const
61b98a2d 349{
61b98a2d
SL
350 VARIANT zoomVariant;
351 VariantInit (&zoomVariant);
352 V_VT(&zoomVariant) = VT_I4;
61b98a2d 353
8acbf08b
SL
354#if wxDEBUG_LEVEL
355 HRESULT result =
356#endif
357 m_webBrowser->ExecWB((OLECMDID)63 /*OLECMDID_OPTICAL_ZOOM*/,
358 OLECMDEXECOPT_DODEFAULT, NULL,
359 &zoomVariant);
c5f417cb 360 wxASSERT(result == S_OK);
61b98a2d
SL
361
362 const int zoom = V_I4(&zoomVariant);
61b98a2d 363
c5f417cb
SL
364 //We make a somewhat arbitray map here, taken from values used by webkit
365 if (zoom <= 65)
366 {
236cff73 367 return wxWEBVIEW_ZOOM_TINY;
c5f417cb
SL
368 }
369 else if (zoom > 65 && zoom <= 90)
370 {
236cff73 371 return wxWEBVIEW_ZOOM_SMALL;
c5f417cb
SL
372 }
373 else if (zoom > 90 && zoom <= 115)
374 {
236cff73 375 return wxWEBVIEW_ZOOM_MEDIUM;
c5f417cb
SL
376 }
377 else if (zoom > 115 && zoom <= 145)
378 {
236cff73 379 return wxWEBVIEW_ZOOM_LARGE;
c5f417cb 380 }
423adfde 381 else /*if (zoom > 145) */ //Using else removes a compiler warning
c5f417cb 382 {
236cff73 383 return wxWEBVIEW_ZOOM_LARGEST;
c5f417cb 384 }
61b98a2d
SL
385}
386
c5f417cb 387void wxWebViewIE::SetZoomType(wxWebViewZoomType type)
61b98a2d 388{
c5f417cb 389 m_zoomType = type;
61b98a2d
SL
390}
391
392wxWebViewZoomType wxWebViewIE::GetZoomType() const
393{
c5f417cb 394 return m_zoomType;
61b98a2d
SL
395}
396
cd4e4673 397bool wxWebViewIE::CanSetZoomType(wxWebViewZoomType type) const
61b98a2d 398{
cd4e4673
SL
399 //IE 6 and below only support text zoom, so check the registry to see what
400 //version we actually have
401 wxRegKey key(wxRegKey::HKLM, "Software\\Microsoft\\Internet Explorer");
402 wxString value;
403 key.QueryValue("Version", value);
404
405 long version = wxAtoi(value.Left(1));
236cff73 406 if(version <= 6 && type == wxWEBVIEW_ZOOM_TYPE_LAYOUT)
cd4e4673
SL
407 return false;
408 else
409 return true;
61b98a2d
SL
410}
411
412void wxWebViewIE::Print()
413{
414 m_webBrowser->ExecWB(OLECMDID_PRINTPREVIEW,
415 OLECMDEXECOPT_DODEFAULT, NULL, NULL);
416}
417
e669ddde 418bool wxWebViewIE::CanGoBack() const
61b98a2d 419{
74af0b13
SL
420 if(m_historyEnabled)
421 return m_historyPosition > 0;
422 else
423 return false;
424}
61b98a2d 425
e669ddde 426bool wxWebViewIE::CanGoForward() const
74af0b13
SL
427{
428 if(m_historyEnabled)
22ca10fa 429 return m_historyPosition != static_cast<int>(m_historyList.size()) - 1;
74af0b13
SL
430 else
431 return false;
61b98a2d
SL
432}
433
c13d6ac1 434void wxWebViewIE::LoadHistoryItem(wxSharedPtr<wxWebViewHistoryItem> item)
61b98a2d 435{
74af0b13
SL
436 int pos = -1;
437 for(unsigned int i = 0; i < m_historyList.size(); i++)
438 {
3e7968c2
SL
439 //We compare the actual pointers to find the correct item
440 if(m_historyList[i].get() == item.get())
74af0b13
SL
441 pos = i;
442 }
1d7d04d7 443 wxASSERT_MSG(pos != static_cast<int>(m_historyList.size()),
22ca10fa 444 "invalid history item");
74af0b13 445 m_historyLoadingFromList = true;
4d0dddc7 446 LoadURL(item->GetUrl());
74af0b13
SL
447 m_historyPosition = pos;
448}
61b98a2d 449
c13d6ac1 450wxVector<wxSharedPtr<wxWebViewHistoryItem> > wxWebViewIE::GetBackwardHistory()
5cbda74b 451{
c13d6ac1 452 wxVector<wxSharedPtr<wxWebViewHistoryItem> > backhist;
5cbda74b
SL
453 //As we don't have std::copy or an iterator constructor in the wxwidgets
454 //native vector we construct it by hand
455 for(int i = 0; i < m_historyPosition; i++)
456 {
457 backhist.push_back(m_historyList[i]);
458 }
459 return backhist;
460}
461
c13d6ac1 462wxVector<wxSharedPtr<wxWebViewHistoryItem> > wxWebViewIE::GetForwardHistory()
5cbda74b 463{
c13d6ac1 464 wxVector<wxSharedPtr<wxWebViewHistoryItem> > forwardhist;
5cbda74b
SL
465 //As we don't have std::copy or an iterator constructor in the wxwidgets
466 //native vector we construct it by hand
22ca10fa 467 for(int i = m_historyPosition + 1; i < static_cast<int>(m_historyList.size()); i++)
5cbda74b
SL
468 {
469 forwardhist.push_back(m_historyList[i]);
470 }
471 return forwardhist;
472}
473
74af0b13
SL
474void wxWebViewIE::GoBack()
475{
3e7968c2 476 LoadHistoryItem(m_historyList[m_historyPosition - 1]);
74af0b13
SL
477}
478
479void wxWebViewIE::GoForward()
480{
3e7968c2 481 LoadHistoryItem(m_historyList[m_historyPosition + 1]);
61b98a2d
SL
482}
483
484void wxWebViewIE::Stop()
485{
7fbc727b 486 m_ie.CallMethod("Stop");
61b98a2d
SL
487}
488
74af0b13
SL
489void wxWebViewIE::ClearHistory()
490{
491 m_historyList.clear();
492 m_historyPosition = -1;
493}
494
495void wxWebViewIE::EnableHistory(bool enable)
496{
497 m_historyEnabled = enable;
498 m_historyList.clear();
499 m_historyPosition = -1;
500}
61b98a2d
SL
501
502void wxWebViewIE::Reload(wxWebViewReloadFlags flags)
503{
7aa18fc7
SL
504 VARIANTARG level;
505 VariantInit(&level);
506 V_VT(&level) = VT_I2;
61b98a2d 507
7aa18fc7 508 switch(flags)
61b98a2d 509 {
236cff73 510 case wxWEBVIEW_RELOAD_DEFAULT:
7aa18fc7
SL
511 V_I2(&level) = REFRESH_NORMAL;
512 break;
236cff73 513 case wxWEBVIEW_RELOAD_NO_CACHE:
7aa18fc7
SL
514 V_I2(&level) = REFRESH_COMPLETELY;
515 break;
516 default:
517 wxFAIL_MSG("Unexpected reload type");
61b98a2d
SL
518 }
519
7aa18fc7 520 m_webBrowser->Refresh2(&level);
61b98a2d
SL
521}
522
523bool wxWebViewIE::IsOfflineMode()
524{
525 wxVariant out = m_ie.GetProperty("Offline");
526
527 wxASSERT(out.GetType() == "bool");
528
529 return out.GetBool();
530}
531
532void wxWebViewIE::SetOfflineMode(bool offline)
533{
534 // FIXME: the wxWidgets docs do not really document what the return
535 // parameter of PutProperty is
8acbf08b
SL
536#if wxDEBUG_LEVEL
537 const bool success =
538#endif
539 m_ie.PutProperty("Offline", (offline ?
540 VARIANT_TRUE :
541 VARIANT_FALSE));
61b98a2d
SL
542 wxASSERT(success);
543}
544
e669ddde 545bool wxWebViewIE::IsBusy() const
60eabdbe 546{
61b98a2d
SL
547 if (m_isBusy) return true;
548
549 wxVariant out = m_ie.GetProperty("Busy");
550
551 wxASSERT(out.GetType() == "bool");
552
553 return out.GetBool();
554}
555
e669ddde 556wxString wxWebViewIE::GetCurrentURL() const
61b98a2d
SL
557{
558 wxVariant out = m_ie.GetProperty("LocationURL");
559
560 wxASSERT(out.GetType() == "string");
561 return out.GetString();
562}
563
e669ddde 564wxString wxWebViewIE::GetCurrentTitle() const
61b98a2d 565{
f40f8e17 566 wxCOMPtr<IHTMLDocument2> document(GetDocument());
7fbc727b 567
e81ef297
SL
568 if(document)
569 {
570 BSTR title;
571 document->get_nameProp(&title);
e81ef297
SL
572 return wxString(title);
573 }
574 else
575 {
576 return "";
577 }
61b98a2d
SL
578}
579
e669ddde 580bool wxWebViewIE::CanCut() const
4681a3ea
SL
581{
582 return CanExecCommand("Cut");
583}
584
e669ddde 585bool wxWebViewIE::CanCopy() const
4681a3ea
SL
586{
587 return CanExecCommand("Copy");
588}
34326da7 589
e669ddde 590bool wxWebViewIE::CanPaste() const
4681a3ea
SL
591{
592 return CanExecCommand("Paste");
593}
594
595void wxWebViewIE::Cut()
596{
597 ExecCommand("Cut");
598}
599
600void wxWebViewIE::Copy()
601{
602 ExecCommand("Copy");
603}
604
605void wxWebViewIE::Paste()
606{
607 ExecCommand("Paste");
608}
609
e669ddde 610bool wxWebViewIE::CanUndo() const
97e49559
SL
611{
612 return CanExecCommand("Undo");
613}
34326da7 614
e669ddde 615bool wxWebViewIE::CanRedo() const
97e49559
SL
616{
617 return CanExecCommand("Redo");
618}
619
620void wxWebViewIE::Undo()
621{
622 ExecCommand("Undo");
623}
624
625void wxWebViewIE::Redo()
626{
627 ExecCommand("Redo");
628}
629
66ac0400
SL
630long wxWebViewIE::Find(const wxString& text, int flags)
631{
632 //If the text is empty then we clear.
633 if(text.IsEmpty())
634 {
635 ClearSelection();
236cff73 636 if(m_findFlags & wxWEBVIEW_FIND_HIGHLIGHT_RESULT)
66ac0400 637 {
236cff73 638 FindInternal(m_findText, (m_findFlags &~ wxWEBVIEW_FIND_HIGHLIGHT_RESULT), wxWEBVIEW_FIND_REMOVE_HIGHLIGHT);
66ac0400
SL
639 }
640 FindClear();
641 return wxNOT_FOUND;
642 }
643 //Have we done this search before?
644 if(m_findText == text)
645 {
646 //Just do a highlight?
236cff73 647 if((flags & wxWEBVIEW_FIND_HIGHLIGHT_RESULT) != (m_findFlags & wxWEBVIEW_FIND_HIGHLIGHT_RESULT))
66ac0400
SL
648 {
649 m_findFlags = flags;
650 if(!m_findPointers.empty())
651 {
236cff73 652 FindInternal(m_findText, m_findFlags, ((flags & wxWEBVIEW_FIND_HIGHLIGHT_RESULT) == 0 ? wxWEBVIEW_FIND_REMOVE_HIGHLIGHT : 0));
66ac0400
SL
653 }
654 return m_findPosition;
655 }
236cff73 656 else if(((m_findFlags & wxWEBVIEW_FIND_ENTIRE_WORD) == (flags & wxWEBVIEW_FIND_ENTIRE_WORD)) && ((m_findFlags & wxWEBVIEW_FIND_MATCH_CASE) == (flags&wxWEBVIEW_FIND_MATCH_CASE)))
66ac0400
SL
657 {
658 m_findFlags = flags;
236cff73 659 return FindNext(((flags & wxWEBVIEW_FIND_BACKWARDS) ? -1 : 1));
66ac0400
SL
660 }
661 }
662 //Remove old highlight if any.
236cff73 663 if(m_findFlags & wxWEBVIEW_FIND_HIGHLIGHT_RESULT)
66ac0400 664 {
236cff73 665 FindInternal(m_findText, (m_findFlags &~ wxWEBVIEW_FIND_HIGHLIGHT_RESULT), wxWEBVIEW_FIND_REMOVE_HIGHLIGHT);
66ac0400
SL
666 }
667 //Reset find variables.
668 FindClear();
669 ClearSelection();
670 m_findText = text;
671 m_findFlags = flags;
1b48beaa 672 //find the text and return wxNOT_FOUND if there are no matches.
236cff73 673 FindInternal(text, flags, wxWEBVIEW_FIND_ADD_POINTERS);
1b48beaa
VZ
674 if(m_findPointers.empty())
675 return wxNOT_FOUND;
676
677 // Or their number if there are.
678 return m_findPointers.size();
66ac0400
SL
679}
680
c7cbe308
SL
681void wxWebViewIE::SetEditable(bool enable)
682{
f40f8e17 683 wxCOMPtr<IHTMLDocument2> document(GetDocument());
7fbc727b 684
e81ef297
SL
685 if(document)
686 {
687 if( enable )
688 document->put_designMode(SysAllocString(L"On"));
689 else
690 document->put_designMode(SysAllocString(L"Off"));
691
e81ef297 692 }
c7cbe308
SL
693}
694
e669ddde 695bool wxWebViewIE::IsEditable() const
c7cbe308 696{
f40f8e17 697 wxCOMPtr<IHTMLDocument2> document(GetDocument());
e81ef297
SL
698
699 if(document)
700 {
701 BSTR mode;
702 document->get_designMode(&mode);
e81ef297
SL
703 if(wxString(mode) == "On")
704 return true;
705 else
706 return false;
707 }
c7cbe308 708 else
e81ef297 709 {
c7cbe308 710 return false;
e81ef297 711 }
c7cbe308
SL
712}
713
63a65070
SL
714void wxWebViewIE::SelectAll()
715{
716 ExecCommand("SelectAll");
717}
718
e669ddde 719bool wxWebViewIE::HasSelection() const
63a65070 720{
f40f8e17 721 wxCOMPtr<IHTMLDocument2> document(GetDocument());
e81ef297
SL
722
723 if(document)
7fbc727b 724 {
f40f8e17 725 wxCOMPtr<IHTMLSelectionObject> selection;
e81ef297
SL
726 wxString sel;
727 HRESULT hr = document->get_selection(&selection);
728 if(SUCCEEDED(hr))
729 {
730 BSTR type;
731 selection->get_type(&type);
732 sel = wxString(type);
e81ef297 733 }
e81ef297
SL
734 return sel != "None";
735 }
736 else
737 {
738 return false;
7fbc727b 739 }
63a65070
SL
740}
741
742void wxWebViewIE::DeleteSelection()
743{
744 ExecCommand("Delete");
745}
746
e669ddde 747wxString wxWebViewIE::GetSelectedText() const
c9355a3d 748{
f40f8e17 749 wxCOMPtr<IHTMLDocument2> document(GetDocument());
e81ef297
SL
750
751 if(document)
c9355a3d 752 {
f40f8e17 753 wxCOMPtr<IHTMLSelectionObject> selection;
e81ef297
SL
754 wxString selected;
755 HRESULT hr = document->get_selection(&selection);
c9355a3d
SL
756 if(SUCCEEDED(hr))
757 {
f40f8e17 758 wxCOMPtr<IDispatch> disrange;
e81ef297 759 hr = selection->createRange(&disrange);
c9355a3d
SL
760 if(SUCCEEDED(hr))
761 {
f40f8e17 762 wxCOMPtr<IHTMLTxtRange> range;
e81ef297
SL
763 hr = disrange->QueryInterface(IID_IHTMLTxtRange, (void**)&range);
764 if(SUCCEEDED(hr))
765 {
766 BSTR text;
767 range->get_text(&text);
768 selected = wxString(text);
e81ef297 769 }
c9355a3d 770 }
c9355a3d 771 }
e81ef297
SL
772 return selected;
773 }
774 else
775 {
776 return "";
c9355a3d 777 }
c9355a3d
SL
778}
779
e669ddde 780wxString wxWebViewIE::GetSelectedSource() const
0fe8a1b6 781{
f40f8e17 782 wxCOMPtr<IHTMLDocument2> document(GetDocument());
e81ef297
SL
783
784 if(document)
0fe8a1b6 785 {
f40f8e17 786 wxCOMPtr<IHTMLSelectionObject> selection;
e81ef297
SL
787 wxString selected;
788 HRESULT hr = document->get_selection(&selection);
0fe8a1b6
SL
789 if(SUCCEEDED(hr))
790 {
f40f8e17 791 wxCOMPtr<IDispatch> disrange;
e81ef297 792 hr = selection->createRange(&disrange);
0fe8a1b6
SL
793 if(SUCCEEDED(hr))
794 {
f40f8e17 795 wxCOMPtr<IHTMLTxtRange> range;
e81ef297
SL
796 hr = disrange->QueryInterface(IID_IHTMLTxtRange, (void**)&range);
797 if(SUCCEEDED(hr))
798 {
799 BSTR text;
800 range->get_htmlText(&text);
801 selected = wxString(text);
e81ef297 802 }
0fe8a1b6 803 }
0fe8a1b6 804 }
e81ef297
SL
805 return selected;
806 }
807 else
808 {
809 return "";
0fe8a1b6 810 }
0fe8a1b6
SL
811}
812
41933aa5
SL
813void wxWebViewIE::ClearSelection()
814{
f40f8e17 815 wxCOMPtr<IHTMLDocument2> document(GetDocument());
e81ef297
SL
816
817 if(document)
41933aa5 818 {
f40f8e17 819 wxCOMPtr<IHTMLSelectionObject> selection;
e81ef297
SL
820 wxString selected;
821 HRESULT hr = document->get_selection(&selection);
822 if(SUCCEEDED(hr))
823 {
824 selection->empty();
e81ef297 825 }
41933aa5 826 }
41933aa5
SL
827}
828
e669ddde 829wxString wxWebViewIE::GetPageText() const
241b769f 830{
f40f8e17 831 wxCOMPtr<IHTMLDocument2> document(GetDocument());
e81ef297
SL
832
833 if(document)
241b769f 834 {
e81ef297 835 wxString text;
f40f8e17 836 wxCOMPtr<IHTMLElement> body;
e81ef297
SL
837 HRESULT hr = document->get_body(&body);
838 if(SUCCEEDED(hr))
839 {
840 BSTR out;
841 body->get_innerText(&out);
842 text = wxString(out);
e81ef297 843 }
e81ef297
SL
844 return text;
845 }
846 else
847 {
848 return "";
241b769f 849 }
241b769f
SL
850}
851
c9ccc09c
SL
852void wxWebViewIE::RunScript(const wxString& javascript)
853{
f40f8e17 854 wxCOMPtr<IHTMLDocument2> document(GetDocument());
e81ef297
SL
855
856 if(document)
c9ccc09c 857 {
f40f8e17 858 wxCOMPtr<IHTMLWindow2> window;
e81ef297
SL
859 wxString language = "javascript";
860 HRESULT hr = document->get_parentWindow(&window);
861 if(SUCCEEDED(hr))
862 {
863 VARIANT level;
864 VariantInit(&level);
865 V_VT(&level) = VT_EMPTY;
866 window->execScript(SysAllocString(javascript.wc_str()),
867 SysAllocString(language.wc_str()),
868 &level);
869 }
c9ccc09c 870 }
c9ccc09c
SL
871}
872
7d8d6163 873void wxWebViewIE::RegisterHandler(wxSharedPtr<wxWebViewHandler> handler)
29365629 874{
e924e848
SL
875 wxDynamicLibrary urlMon(wxT("urlmon.dll"));
876 if(urlMon.HasSymbol(wxT("CoInternetGetSession")))
29365629 877 {
f559d1a2 878 typedef HRESULT (WINAPI *CoInternetGetSession_t)(DWORD, wxIInternetSession**, DWORD);
e924e848
SL
879 wxDYNLIB_FUNCTION(CoInternetGetSession_t, CoInternetGetSession, urlMon);
880
881 ClassFactory* cf = new ClassFactory(handler);
f559d1a2 882 wxIInternetSession* session;
e924e848
SL
883 HRESULT res = (*pfnCoInternetGetSession)(0, &session, 0);
884 if(FAILED(res))
885 {
886 wxFAIL_MSG("Could not retrive internet session");
887 }
29365629 888
c9a828e7
VZ
889 HRESULT hr = session->RegisterNameSpace(cf, CLSID_FileProtocol,
890 handler->GetName().wc_str(),
891 0, NULL, 0);
e924e848
SL
892 if(FAILED(hr))
893 {
894 wxFAIL_MSG("Could not register protocol");
895 }
39498710 896 m_factories.push_back(cf);
e924e848
SL
897 }
898 else
29365629 899 {
e924e848 900 wxFAIL_MSG("urlmon does not contain CoInternetGetSession");
29365629
SL
901 }
902}
903
e669ddde 904bool wxWebViewIE::CanExecCommand(wxString command) const
4681a3ea 905{
f40f8e17 906 wxCOMPtr<IHTMLDocument2> document(GetDocument());
7fbc727b 907
e81ef297
SL
908 if(document)
909 {
910 VARIANT_BOOL enabled;
911
912 document->queryCommandEnabled(SysAllocString(command.wc_str()), &enabled);
e81ef297
SL
913
914 return (enabled == VARIANT_TRUE);
915 }
916 else
917 {
918 return false;
919 }
4681a3ea 920
4681a3ea
SL
921}
922
923void wxWebViewIE::ExecCommand(wxString command)
924{
f40f8e17 925 wxCOMPtr<IHTMLDocument2> document(GetDocument());
e81ef297
SL
926
927 if(document)
928 {
929 document->execCommand(SysAllocString(command.wc_str()), VARIANT_FALSE, VARIANT(), NULL);
e81ef297 930 }
617227c3 931}
4681a3ea 932
f40f8e17 933wxCOMPtr<IHTMLDocument2> wxWebViewIE::GetDocument() const
617227c3 934{
f40f8e17
SL
935 wxCOMPtr<IDispatch> dispatch;
936 wxCOMPtr<IHTMLDocument2> document;
e81ef297 937 HRESULT result = m_webBrowser->get_Document(&dispatch);
601d0ba7 938 if(dispatch && SUCCEEDED(result))
e81ef297 939 {
e81ef297 940 //document is set to null automatically if the interface isn't supported
f40f8e17 941 dispatch->QueryInterface(IID_IHTMLDocument2, (void**)&document);
e81ef297 942 }
f40f8e17 943 return document;
4681a3ea
SL
944}
945
938506b1 946bool wxWebViewIE::IsElementVisible(wxCOMPtr<IHTMLElement> elm)
66ac0400 947{
938506b1 948 wxCOMPtr<IHTMLElement> elm1 = elm;
66ac0400
SL
949 BSTR tmp_bstr;
950 bool is_visible = true;
951 //This method is not perfect but it does discover most of the hidden elements.
952 //so if a better solution is found, then please do improve.
953 while(elm1)
954 {
938506b1 955 wxCOMPtr<wxIHTMLElement2> elm2;
e52aec97 956 if(SUCCEEDED(elm1->QueryInterface(wxIID_IHTMLElement2, (void**) &elm2)))
66ac0400 957 {
938506b1 958 wxCOMPtr<wxIHTMLCurrentStyle> style;
66ac0400
SL
959 if(SUCCEEDED(elm2->get_currentStyle(&style)))
960 {
961 //Check if the object has the style display:none.
962 if((style->get_display(&tmp_bstr) != S_OK) ||
963 (tmp_bstr != NULL && (_wcsicmp(tmp_bstr, L"none") == 0)))
964 {
965 is_visible = false;
966 }
967 //Check if the object has the style visibility:hidden.
79fdb1d1 968 if((is_visible && (style->get_visibility(&tmp_bstr) != S_OK)) ||
66ac0400
SL
969 (tmp_bstr != NULL && _wcsicmp(tmp_bstr, L"hidden") == 0))
970 {
971 is_visible = false;
972 }
973 style->Release();
974 }
975 elm2->Release();
976 }
977
978 //Lets check the object's parent element.
979 IHTMLElement* parent;
980 if(is_visible && SUCCEEDED(elm1->get_parentElement(&parent)))
981 {
66ac0400
SL
982 elm1 = parent;
983 }
984 else
985 {
986 elm1->Release();
987 break;
988 }
989 }
990 return is_visible;
991}
992
993void wxWebViewIE::FindInternal(const wxString& text, int flags, int internal_flag)
994{
66ac0400 995 long find_flag = 0;
938506b1
SL
996 wxCOMPtr<wxIMarkupServices> pIMS;
997 wxCOMPtr<IHTMLDocument2> document = GetDocument();
998
66ac0400 999 //This function does the acutal work.
938506b1 1000 if(document && SUCCEEDED(document->QueryInterface(wxIID_IMarkupServices, (void **)&pIMS)))
66ac0400 1001 {
938506b1 1002 wxCOMPtr<wxIMarkupContainer> pIMC;
e52aec97 1003 if(SUCCEEDED(document->QueryInterface(wxIID_IMarkupContainer, (void **)&pIMC)))
66ac0400 1004 {
938506b1 1005 wxCOMPtr<wxIMarkupPointer> ptrBegin, ptrEnd;
66ac0400
SL
1006 BSTR attr_bstr = SysAllocString(L"style=\"background-color:#ffff00\"");
1007 BSTR text_bstr = SysAllocString(text.wc_str());
1008 pIMS->CreateMarkupPointer(&ptrBegin);
1009 pIMS->CreateMarkupPointer(&ptrEnd);
1010
a8da90b8 1011 ptrBegin->SetGravity(wxPOINTER_GRAVITY_Right);
66ac0400
SL
1012 ptrBegin->MoveToContainer(pIMC, TRUE);
1013 //Create the find flag from the wx one.
236cff73 1014 if(flags & wxWEBVIEW_FIND_ENTIRE_WORD)
66ac0400 1015 {
a8da90b8 1016 find_flag |= wxFINDTEXT_WHOLEWORD;
66ac0400 1017 }
236cff73 1018 if(flags & wxWEBVIEW_FIND_MATCH_CASE)
66ac0400 1019 {
a8da90b8 1020 find_flag |= wxFINDTEXT_MATCHCASE;
66ac0400
SL
1021 }
1022
1023 //A little speed-up to avoid to re-alloc in the positions vector.
1024 if(text.Len() < 3 && m_findPointers.capacity() < 500)
1025 {
1026 m_findPointers.reserve(text.Len() == 1 ? 1000 : 500);
1027 }
1028
1029 while(ptrBegin->FindText(text_bstr, find_flag, ptrEnd, NULL) == S_OK)
1030 {
938506b1 1031 wxCOMPtr<IHTMLElement> elm;
66ac0400
SL
1032 if(ptrBegin->CurrentScope(&elm) == S_OK)
1033 {
1034 if(IsElementVisible(elm))
1035 {
1036 //Highlight the word if the flag was set.
236cff73 1037 if(flags & wxWEBVIEW_FIND_HIGHLIGHT_RESULT)
66ac0400
SL
1038 {
1039 IHTMLElement* pFontEl;
a8da90b8 1040 pIMS->CreateElement(wxTAGID_FONT, attr_bstr, &pFontEl);
66ac0400
SL
1041 pIMS->InsertElement(pFontEl, ptrBegin, ptrEnd);
1042 }
236cff73 1043 if(internal_flag & wxWEBVIEW_FIND_REMOVE_HIGHLIGHT)
66ac0400
SL
1044 {
1045 IHTMLElement* pFontEl;
1046 ptrBegin->CurrentScope(&pFontEl);
1047 pIMS->RemoveElement(pFontEl);
1048 pFontEl->Release();
1049 }
236cff73 1050 if(internal_flag & wxWEBVIEW_FIND_ADD_POINTERS)
66ac0400 1051 {
e52aec97 1052 wxIMarkupPointer *cptrBegin, *cptrEnd;
66ac0400
SL
1053 pIMS->CreateMarkupPointer(&cptrBegin);
1054 pIMS->CreateMarkupPointer(&cptrEnd);
1055 cptrBegin->MoveToPointer(ptrBegin);
1056 cptrEnd->MoveToPointer(ptrEnd);
1057 m_findPointers.push_back(wxFindPointers(cptrBegin,cptrEnd));
1058 }
1059 }
66ac0400
SL
1060 }
1061 ptrBegin->MoveToPointer(ptrEnd);
1062 }
1063 //Clean up.
1064 SysFreeString(text_bstr);
1065 SysFreeString(attr_bstr);
66ac0400 1066 }
66ac0400 1067 }
66ac0400
SL
1068}
1069
1070long wxWebViewIE::FindNext(int direction)
1071{
1072 //Don't bother if we have no pointers set.
1073 if(m_findPointers.empty())
1074 {
1075 return wxNOT_FOUND;
1076 }
1077 //Manage the find position and do some checks.
1078 if(direction > 0)
1079 {
1080 m_findPosition++;
1081 }
1082 else
1083 {
1084 m_findPosition--;
1085 }
1086
1087 if(m_findPosition >= (signed)m_findPointers.size())
1088 {
236cff73 1089 if(m_findFlags & wxWEBVIEW_FIND_WRAP)
66ac0400
SL
1090 {
1091 m_findPosition = 0;
1092 }
1093 else
1094 {
1095 m_findPosition--;
1096 return wxNOT_FOUND;
1097 }
1098 }
1099 else if(m_findPosition < 0)
1100 {
236cff73 1101 if(m_findFlags & wxWEBVIEW_FIND_WRAP)
66ac0400
SL
1102 {
1103 m_findPosition = m_findPointers.size()-1;
1104 }
1105 else
1106 {
1107 m_findPosition++;
1108 return wxNOT_FOUND;
1109 }
1110 }
938506b1
SL
1111
1112 wxCOMPtr<IHTMLDocument2> document = GetDocument();
1113 wxCOMPtr<IHTMLElement> body_element;
1114
66ac0400
SL
1115 long ret = -1;
1116 //Now try to create a range from the body.
938506b1 1117 if(document && SUCCEEDED(document->get_body(&body_element)))
66ac0400 1118 {
938506b1 1119 wxCOMPtr<IHTMLBodyElement> body;
66ac0400
SL
1120 if(SUCCEEDED(body_element->QueryInterface(IID_IHTMLBodyElement,(void**)&body)))
1121 {
938506b1 1122 wxCOMPtr<wxIHTMLTxtRange> range;
e52aec97 1123 if(SUCCEEDED(body->createTextRange((IHTMLTxtRange**)(&range))))
66ac0400 1124 {
938506b1 1125 wxCOMPtr<wxIMarkupServices> pIMS;
66ac0400 1126 //So far so good, now we try to position our find pointers.
e52aec97 1127 if(SUCCEEDED(document->QueryInterface(wxIID_IMarkupServices,(void **)&pIMS)))
66ac0400 1128 {
e52aec97 1129 wxIMarkupPointer *begin = m_findPointers[m_findPosition].begin, *end = m_findPointers[m_findPosition].end;
66ac0400
SL
1130 if(pIMS->MoveRangeToPointers(begin,end,range) == S_OK && range->select() == S_OK)
1131 {
1132 ret = m_findPosition;
1133 }
66ac0400 1134 }
66ac0400 1135 }
66ac0400 1136 }
66ac0400 1137 }
66ac0400
SL
1138 return ret;
1139}
1140
1141void wxWebViewIE::FindClear()
1142{
1143 //Reset find variables.
1144 m_findText.Empty();
236cff73 1145 m_findFlags = wxWEBVIEW_FIND_DEFAULT;
66ac0400
SL
1146 m_findPosition = -1;
1147
1148 //The m_findPointers contains pointers for the found text.
1149 //Since it uses ref counting we call release on the pointers first
1150 //before we remove them from the vector. In other words do not just
1151 //remove elements from m_findPointers without calling release first
1152 //or you will get a memory leak.
1153 size_t count = m_findPointers.size();
1154 for(size_t i = 0; i < count; i++)
1155 {
1156 m_findPointers[i].begin->Release();
1157 m_findPointers[i].end->Release();
1158 }
1159 m_findPointers.clear();
1160}
1161
9447a0d6
SL
1162bool wxWebViewIE::EnableControlFeature(long flag, bool enable)
1163{
1164#if wxUSE_DYNLIB_CLASS
1165
1166 wxDynamicLibrary urlMon(wxT("urlmon.dll"));
34326da7
SL
1167 if( urlMon.IsLoaded() &&
1168 urlMon.HasSymbol("CoInternetSetFeatureEnabled") &&
9447a0d6
SL
1169 urlMon.HasSymbol("CoInternetIsFeatureEnabled"))
1170 {
1171 typedef HRESULT (WINAPI *CoInternetSetFeatureEnabled_t)(DWORD, DWORD, BOOL);
1172 typedef HRESULT (WINAPI *CoInternetIsFeatureEnabled_t)(DWORD, DWORD);
1173
1174 wxDYNLIB_FUNCTION(CoInternetSetFeatureEnabled_t, CoInternetSetFeatureEnabled, urlMon);
1175 wxDYNLIB_FUNCTION(CoInternetIsFeatureEnabled_t, CoInternetIsFeatureEnabled, urlMon);
1176
1177 HRESULT hr = (*pfnCoInternetIsFeatureEnabled)(flag,
1178 0x2 /* SET_FEATURE_ON_PROCESS */);
1179 if((hr == S_OK && enable) || (hr == S_FALSE && !enable))
1180 return true;
1181
1182 hr = (*pfnCoInternetSetFeatureEnabled)(flag,
1183 0x2/* SET_FEATURE_ON_PROCESS */,
1184 (enable ? TRUE : FALSE));
1185 if ( FAILED(hr) )
1186 {
1187 wxLogApiError(wxT("CoInternetSetFeatureEnabled"), hr);
1188 return false;
1189 }
1190 return true;
1191 }
1192 return false;
1193#else
1194 wxUnusedVar(flag);
1195 wxUnusedVar(enable);
1196 return false;
1197#endif // wxUSE_DYNLIB_CLASS/!wxUSE_DYNLIB_CLASS
1198}
1199
61b98a2d
SL
1200void wxWebViewIE::onActiveXEvent(wxActiveXEvent& evt)
1201{
1202 if (m_webBrowser == NULL) return;
1203
1204 switch (evt.GetDispatchId())
1205 {
1206 case DISPID_BEFORENAVIGATE2:
1207 {
1208 m_isBusy = true;
1209
1210 wxString url = evt[1].GetString();
1211 wxString target = evt[3].GetString();
1212
ce7fe42e 1213 wxWebViewEvent event(wxEVT_WEBVIEW_NAVIGATING,
3225a4b8 1214 GetId(), url, target);
e11b9a6b
SL
1215
1216 //skip empty javascript events.
1217 if(url == "javascript:\"\"" && target.IsEmpty())
1218 {
1219 event.Veto();
1220 }
1221 else
1222 {
1223 event.SetEventObject(this);
1224 HandleWindowEvent(event);
1225 }
61b98a2d 1226
3225a4b8 1227 if (!event.IsAllowed())
61b98a2d
SL
1228 {
1229 wxActiveXEventNativeMSW* nativeParams =
1230 evt.GetNativeParameters();
1231 *V_BOOLREF(&nativeParams->pDispParams->rgvarg[0]) = VARIANT_TRUE;
1232 }
1233
1234 // at this point, either the navigation event has been cancelled
1235 // and we're not busy, either it was accepted and IWebBrowser2's
1236 // Busy property will be true; so we don't need our override
1237 // flag anymore.
1238 m_isBusy = false;
1239
1240 break;
1241 }
1242
1243 case DISPID_NAVIGATECOMPLETE2:
1244 {
1245 wxString url = evt[1].GetString();
1246 // TODO: set target parameter if possible
1247 wxString target = wxEmptyString;
ce7fe42e 1248 wxWebViewEvent event(wxEVT_WEBVIEW_NAVIGATED,
3225a4b8 1249 GetId(), url, target);
61b98a2d
SL
1250 event.SetEventObject(this);
1251 HandleWindowEvent(event);
1252 break;
1253 }
1254
1255 case DISPID_PROGRESSCHANGE:
1256 {
1257 // download progress
1258 break;
1259 }
1260
1261 case DISPID_DOCUMENTCOMPLETE:
1262 {
3ee442ff
SL
1263 //Only send a complete even if we are actually finished, this brings
1264 //the event in to line with webkit
1265 READYSTATE rs;
1266 m_webBrowser->get_ReadyState( &rs );
1267 if(rs != READYSTATE_COMPLETE)
1268 break;
1269
61b98a2d 1270 wxString url = evt[1].GetString();
113e0a92
SL
1271
1272 //As we are complete we also add to the history list, but not if the
1273 //page is not the main page, ie it is a subframe
60eabdbe 1274 //We also have to check if we are loading a file:// url, if so we
f239a200
SL
1275 //need to change the comparison as ie passes back a different style
1276 //of url
60eabdbe
VZ
1277 if(m_historyEnabled && !m_historyLoadingFromList &&
1278 (url == GetCurrentURL() ||
1279 (GetCurrentURL().substr(0, 4) == "file" &&
f239a200 1280 wxFileSystem::URLToFileName(GetCurrentURL()).GetFullPath() == url)))
74af0b13
SL
1281 {
1282 //If we are not at the end of the list, then erase everything
1283 //between us and the end before adding the new page
22ca10fa 1284 if(m_historyPosition != static_cast<int>(m_historyList.size()) - 1)
74af0b13
SL
1285 {
1286 m_historyList.erase(m_historyList.begin() + m_historyPosition + 1,
1287 m_historyList.end());
1288 }
c13d6ac1 1289 wxSharedPtr<wxWebViewHistoryItem> item(new wxWebViewHistoryItem(url, GetCurrentTitle()));
74af0b13
SL
1290 m_historyList.push_back(item);
1291 m_historyPosition++;
1292 }
1293 //Reset as we are done now
1294 m_historyLoadingFromList = false;
66ac0400
SL
1295 //Reset the find values.
1296 FindClear();
61b98a2d
SL
1297 // TODO: set target parameter if possible
1298 wxString target = wxEmptyString;
ce7fe42e 1299 wxWebViewEvent event(wxEVT_WEBVIEW_LOADED, GetId(),
3225a4b8 1300 url, target);
61b98a2d
SL
1301 event.SetEventObject(this);
1302 HandleWindowEvent(event);
1303 break;
1304 }
1305
1306 case DISPID_STATUSTEXTCHANGE:
1307 {
1308 break;
1309 }
1310
1311 case DISPID_TITLECHANGE:
1312 {
153530af
SL
1313 wxString title = evt[0].GetString();
1314
ce7fe42e 1315 wxWebViewEvent event(wxEVT_WEBVIEW_TITLE_CHANGED,
3225a4b8 1316 GetId(), GetCurrentURL(), "");
153530af
SL
1317 event.SetString(title);
1318 event.SetEventObject(this);
1319 HandleWindowEvent(event);
61b98a2d
SL
1320 break;
1321 }
1322
1323 case DISPID_NAVIGATEERROR:
1324 {
ce7fe42e 1325 wxWebViewEvent event(wxEVT_WEBVIEW_ERROR, GetId(),
c1381581
SL
1326 evt[1].GetString(), evt[2].GetString());
1327 event.SetEventObject(this);
1328
61b98a2d
SL
1329 switch (evt[3].GetLong())
1330 {
c1381581 1331 // 400 Error codes
236cff73
SL
1332 WX_ERROR_CASE(HTTP_STATUS_BAD_REQUEST, wxWEBVIEW_NAV_ERR_REQUEST)
1333 WX_ERROR_CASE(HTTP_STATUS_DENIED, wxWEBVIEW_NAV_ERR_AUTH)
1334 WX_ERROR_CASE(HTTP_STATUS_PAYMENT_REQ, wxWEBVIEW_NAV_ERR_OTHER)
1335 WX_ERROR_CASE(HTTP_STATUS_FORBIDDEN, wxWEBVIEW_NAV_ERR_AUTH)
1336 WX_ERROR_CASE(HTTP_STATUS_NOT_FOUND, wxWEBVIEW_NAV_ERR_NOT_FOUND)
1337 WX_ERROR_CASE(HTTP_STATUS_BAD_METHOD, wxWEBVIEW_NAV_ERR_REQUEST)
1338 WX_ERROR_CASE(HTTP_STATUS_NONE_ACCEPTABLE, wxWEBVIEW_NAV_ERR_OTHER)
1339 WX_ERROR_CASE(HTTP_STATUS_PROXY_AUTH_REQ, wxWEBVIEW_NAV_ERR_AUTH)
1340 WX_ERROR_CASE(HTTP_STATUS_REQUEST_TIMEOUT, wxWEBVIEW_NAV_ERR_CONNECTION)
1341 WX_ERROR_CASE(HTTP_STATUS_CONFLICT, wxWEBVIEW_NAV_ERR_REQUEST)
1342 WX_ERROR_CASE(HTTP_STATUS_GONE, wxWEBVIEW_NAV_ERR_NOT_FOUND)
1343 WX_ERROR_CASE(HTTP_STATUS_LENGTH_REQUIRED, wxWEBVIEW_NAV_ERR_REQUEST)
1344 WX_ERROR_CASE(HTTP_STATUS_PRECOND_FAILED, wxWEBVIEW_NAV_ERR_REQUEST)
1345 WX_ERROR_CASE(HTTP_STATUS_REQUEST_TOO_LARGE, wxWEBVIEW_NAV_ERR_REQUEST)
1346 WX_ERROR_CASE(HTTP_STATUS_URI_TOO_LONG, wxWEBVIEW_NAV_ERR_REQUEST)
1347 WX_ERROR_CASE(HTTP_STATUS_UNSUPPORTED_MEDIA, wxWEBVIEW_NAV_ERR_REQUEST)
1348 WX_ERROR_CASE(HTTP_STATUS_RETRY_WITH, wxWEBVIEW_NAV_ERR_OTHER)
c1381581
SL
1349
1350 // 500 - Error codes
236cff73
SL
1351 WX_ERROR_CASE(HTTP_STATUS_SERVER_ERROR, wxWEBVIEW_NAV_ERR_CONNECTION)
1352 WX_ERROR_CASE(HTTP_STATUS_NOT_SUPPORTED, wxWEBVIEW_NAV_ERR_CONNECTION)
1353 WX_ERROR_CASE(HTTP_STATUS_BAD_GATEWAY, wxWEBVIEW_NAV_ERR_CONNECTION)
1354 WX_ERROR_CASE(HTTP_STATUS_SERVICE_UNAVAIL, wxWEBVIEW_NAV_ERR_CONNECTION)
1355 WX_ERROR_CASE(HTTP_STATUS_GATEWAY_TIMEOUT, wxWEBVIEW_NAV_ERR_CONNECTION)
1356 WX_ERROR_CASE(HTTP_STATUS_VERSION_NOT_SUP, wxWEBVIEW_NAV_ERR_REQUEST)
c1381581
SL
1357
1358 // URL Moniker error codes
236cff73
SL
1359 WX_ERROR_CASE(INET_E_INVALID_URL, wxWEBVIEW_NAV_ERR_REQUEST)
1360 WX_ERROR_CASE(INET_E_NO_SESSION, wxWEBVIEW_NAV_ERR_CONNECTION)
1361 WX_ERROR_CASE(INET_E_CANNOT_CONNECT, wxWEBVIEW_NAV_ERR_CONNECTION)
1362 WX_ERROR_CASE(INET_E_RESOURCE_NOT_FOUND, wxWEBVIEW_NAV_ERR_NOT_FOUND)
1363 WX_ERROR_CASE(INET_E_OBJECT_NOT_FOUND, wxWEBVIEW_NAV_ERR_NOT_FOUND)
1364 WX_ERROR_CASE(INET_E_DATA_NOT_AVAILABLE, wxWEBVIEW_NAV_ERR_NOT_FOUND)
1365 WX_ERROR_CASE(INET_E_DOWNLOAD_FAILURE, wxWEBVIEW_NAV_ERR_CONNECTION)
1366 WX_ERROR_CASE(INET_E_AUTHENTICATION_REQUIRED, wxWEBVIEW_NAV_ERR_AUTH)
1367 WX_ERROR_CASE(INET_E_NO_VALID_MEDIA, wxWEBVIEW_NAV_ERR_REQUEST)
1368 WX_ERROR_CASE(INET_E_CONNECTION_TIMEOUT, wxWEBVIEW_NAV_ERR_CONNECTION)
1369 WX_ERROR_CASE(INET_E_INVALID_REQUEST, wxWEBVIEW_NAV_ERR_REQUEST)
1370 WX_ERROR_CASE(INET_E_UNKNOWN_PROTOCOL, wxWEBVIEW_NAV_ERR_REQUEST)
1371 WX_ERROR_CASE(INET_E_SECURITY_PROBLEM, wxWEBVIEW_NAV_ERR_SECURITY)
1372 WX_ERROR_CASE(INET_E_CANNOT_LOAD_DATA, wxWEBVIEW_NAV_ERR_OTHER)
1373 WX_ERROR_CASE(INET_E_REDIRECT_FAILED, wxWEBVIEW_NAV_ERR_OTHER)
1374 WX_ERROR_CASE(INET_E_REDIRECT_TO_DIR, wxWEBVIEW_NAV_ERR_REQUEST)
1375 WX_ERROR_CASE(INET_E_CANNOT_LOCK_REQUEST, wxWEBVIEW_NAV_ERR_OTHER)
1376 WX_ERROR_CASE(INET_E_USE_EXTEND_BINDING, wxWEBVIEW_NAV_ERR_OTHER)
1377 WX_ERROR_CASE(INET_E_TERMINATED_BIND, wxWEBVIEW_NAV_ERR_OTHER)
1378 WX_ERROR_CASE(INET_E_INVALID_CERTIFICATE, wxWEBVIEW_NAV_ERR_CERTIFICATE)
1379 WX_ERROR_CASE(INET_E_CODE_DOWNLOAD_DECLINED, wxWEBVIEW_NAV_ERR_USER_CANCELLED)
1380 WX_ERROR_CASE(INET_E_RESULT_DISPATCHED, wxWEBVIEW_NAV_ERR_OTHER)
1381 WX_ERROR_CASE(INET_E_CANNOT_REPLACE_SFP_FILE, wxWEBVIEW_NAV_ERR_SECURITY)
1382 WX_ERROR_CASE(INET_E_CODE_INSTALL_BLOCKED_BY_HASH_POLICY, wxWEBVIEW_NAV_ERR_SECURITY)
1383 WX_ERROR_CASE(INET_E_CODE_INSTALL_SUPPRESSED, wxWEBVIEW_NAV_ERR_SECURITY)
61b98a2d 1384 }
61b98a2d
SL
1385 HandleWindowEvent(event);
1386 break;
1387 }
853b6cd0 1388 case DISPID_NEWWINDOW3:
61b98a2d 1389 {
853b6cd0
SL
1390 wxString url = evt[4].GetString();
1391
ce7fe42e 1392 wxWebViewEvent event(wxEVT_WEBVIEW_NEWWINDOW,
3225a4b8 1393 GetId(), url, wxEmptyString);
853b6cd0
SL
1394 event.SetEventObject(this);
1395 HandleWindowEvent(event);
1396
d676fb21
SL
1397 //We always cancel this event otherwise an Internet Exporer window
1398 //is opened for the url
1399 wxActiveXEventNativeMSW* nativeParams = evt.GetNativeParameters();
1400 *V_BOOLREF(&nativeParams->pDispParams->rgvarg[3]) = VARIANT_TRUE;
be19c556
SL
1401 break;
1402 }
61b98a2d
SL
1403 }
1404
1405 evt.Skip();
1406}
1407
7d8d6163 1408VirtualProtocol::VirtualProtocol(wxSharedPtr<wxWebViewHandler> handler)
7d3f6b4d 1409{
7d3f6b4d 1410 m_file = NULL;
29365629 1411 m_handler = handler;
7d3f6b4d
SL
1412}
1413
9f194b9d
SL
1414BEGIN_IID_TABLE(VirtualProtocol)
1415 ADD_IID(Unknown)
1416 ADD_RAW_IID(wxIID_IInternetProtocolRoot)
1417 ADD_RAW_IID(wxIID_IInternetProtocol)
1418END_IID_TABLE;
7d3f6b4d 1419
9f194b9d 1420IMPLEMENT_IUNKNOWN_METHODS(VirtualProtocol)
7d3f6b4d 1421
a9c5eac9 1422HRESULT STDMETHODCALLTYPE VirtualProtocol::Start(LPCWSTR szUrl, wxIInternetProtocolSink *pOIProtSink,
f559d1a2 1423 wxIInternetBindInfo *pOIBindInfo, DWORD grfPI,
0995b9dc 1424 HANDLE_PTR dwReserved)
7d3f6b4d 1425{
0995b9dc
SL
1426 wxUnusedVar(szUrl);
1427 wxUnusedVar(pOIBindInfo);
1428 wxUnusedVar(grfPI);
1429 wxUnusedVar(dwReserved);
7d3f6b4d 1430 m_protocolSink = pOIProtSink;
60eabdbe 1431
29365629
SL
1432 //We get the file itself from the protocol handler
1433 m_file = m_handler->GetFile(szUrl);
1434
7d3f6b4d
SL
1435
1436 if(!m_file)
1437 return INET_E_RESOURCE_NOT_FOUND;
1438
1439 //We return the stream length for current and total size as we can always
1440 //read the whole file from the stream
666f73c4 1441 wxFileOffset length = m_file->GetStream()->GetLength();
f559d1a2
VZ
1442 m_protocolSink->ReportData(wxBSCF_FIRSTDATANOTIFICATION |
1443 wxBSCF_DATAFULLYAVAILABLE |
1444 wxBSCF_LASTDATANOTIFICATION,
666f73c4 1445 length, length);
60eabdbe 1446 return S_OK;
7d3f6b4d
SL
1447}
1448
a9c5eac9 1449HRESULT STDMETHODCALLTYPE VirtualProtocol::Read(void *pv, ULONG cb, ULONG *pcbRead)
7d3f6b4d
SL
1450{
1451 //If the file is null we return false to indicte it is finished
60eabdbe 1452 if(!m_file)
7d3f6b4d
SL
1453 return S_FALSE;
1454
1455 wxStreamError err = m_file->GetStream()->Read(pv, cb).GetLastError();
1456 *pcbRead = m_file->GetStream()->LastRead();
1457
1458 if(err == wxSTREAM_NO_ERROR)
1459 {
1460 if(*pcbRead < cb)
1461 {
1462 wxDELETE(m_file);
1463 m_protocolSink->ReportResult(S_OK, 0, NULL);
1464 }
1465 //As we are not eof there is more data
1466 return S_OK;
1467 }
1468 else if(err == wxSTREAM_EOF)
1469 {
1470 wxDELETE(m_file);
1471 m_protocolSink->ReportResult(S_OK, 0, NULL);
1472 //We are eof and so finished
1473 return S_OK;
1474 }
1475 else if(err == wxSTREAM_READ_ERROR)
1476 {
1477 wxDELETE(m_file);
1478 return INET_E_DOWNLOAD_FAILURE;
1479 }
0995b9dc
SL
1480 else
1481 {
070d6391 1482 //Dummy return to suppress a compiler warning
0995b9dc
SL
1483 wxFAIL;
1484 return INET_E_DOWNLOAD_FAILURE;
1485 }
7d3f6b4d
SL
1486}
1487
9f194b9d
SL
1488BEGIN_IID_TABLE(ClassFactory)
1489 ADD_IID(Unknown)
1490 ADD_IID(ClassFactory)
1491END_IID_TABLE;
1492
1493IMPLEMENT_IUNKNOWN_METHODS(ClassFactory)
1494
a9c5eac9 1495HRESULT STDMETHODCALLTYPE ClassFactory::CreateInstance(IUnknown* pUnkOuter, REFIID riid,
7d3f6b4d
SL
1496 void ** ppvObject)
1497{
60eabdbe 1498 if (pUnkOuter)
7d3f6b4d 1499 return CLASS_E_NOAGGREGATION;
29365629 1500 VirtualProtocol* vp = new VirtualProtocol(m_handler);
7d3f6b4d
SL
1501 vp->AddRef();
1502 HRESULT hr = vp->QueryInterface(riid, ppvObject);
1503 vp->Release();
1504 return hr;
1505
60eabdbe 1506}
7d3f6b4d
SL
1507
1508STDMETHODIMP ClassFactory::LockServer(BOOL fLock)
1509{
0995b9dc
SL
1510 wxUnusedVar(fLock);
1511 return S_OK;
7d3f6b4d
SL
1512}
1513
34326da7 1514wxIEContainer::wxIEContainer(wxWindow *parent, REFIID iid, IUnknown *pUnk,
accc94d5
SL
1515 DocHostUIHandler* uiHandler) :
1516 wxActiveXContainer(parent,iid,pUnk)
1517{
1518 m_uiHandler = uiHandler;
1519}
1520
1521wxIEContainer::~wxIEContainer()
1522{
1523}
1524
34326da7 1525bool wxIEContainer::QueryClientSiteInterface(REFIID iid, void **_interface,
accc94d5
SL
1526 const char *&desc)
1527{
1528 if (m_uiHandler && IsEqualIID(iid, wxIID_IDocHostUIHandler))
1529 {
1530 *_interface = (IUnknown *) (wxIDocHostUIHandler *) m_uiHandler;
1531 desc = "IDocHostUIHandler";
1532 return true;
1533 }
1534 return false;
1535}
1536
a9c5eac9 1537HRESULT wxSTDCALL DocHostUIHandler::ShowContextMenu(DWORD dwID, POINT *ppt,
34326da7 1538 IUnknown *pcmdtReserved,
accc94d5
SL
1539 IDispatch *pdispReserved)
1540{
1541 wxUnusedVar(dwID);
1542 wxUnusedVar(ppt);
1543 wxUnusedVar(pcmdtReserved);
1544 wxUnusedVar(pdispReserved);
c420d57b
SL
1545 if(m_browser->IsContextMenuEnabled())
1546 return E_NOTIMPL;
1547 else
1548 return S_OK;
accc94d5
SL
1549}
1550
a9c5eac9 1551HRESULT wxSTDCALL DocHostUIHandler::GetHostInfo(DOCHOSTUIINFO *pInfo)
accc94d5 1552{
34326da7 1553 //don't show 3d border and enable themes.
accc94d5
SL
1554 pInfo->dwFlags = pInfo->dwFlags | DOCHOSTUIFLAG_NO3DBORDER | DOCHOSTUIFLAG_THEME;
1555 return S_OK;
1556}
1557
a9c5eac9 1558HRESULT wxSTDCALL DocHostUIHandler::ShowUI(DWORD dwID,
34326da7 1559 IOleInPlaceActiveObject *pActiveObject,
accc94d5
SL
1560 IOleCommandTarget *pCommandTarget,
1561 IOleInPlaceFrame *pFrame,
1562 IOleInPlaceUIWindow *pDoc)
1563{
1564 wxUnusedVar(dwID);
1565 wxUnusedVar(pActiveObject);
1566 wxUnusedVar(pCommandTarget);
1567 wxUnusedVar(pFrame);
1568 wxUnusedVar(pDoc);
1569 return S_FALSE;
1570}
1571
a9c5eac9 1572HRESULT wxSTDCALL DocHostUIHandler::HideUI(void)
accc94d5
SL
1573{
1574 return E_NOTIMPL;
1575}
1576
a9c5eac9 1577HRESULT wxSTDCALL DocHostUIHandler::UpdateUI(void)
accc94d5
SL
1578{
1579 return E_NOTIMPL;
1580}
1581
a9c5eac9 1582HRESULT wxSTDCALL DocHostUIHandler::EnableModeless(BOOL fEnable)
accc94d5
SL
1583{
1584 wxUnusedVar(fEnable);
1585 return E_NOTIMPL;
1586}
1587
a9c5eac9 1588HRESULT wxSTDCALL DocHostUIHandler::OnDocWindowActivate(BOOL fActivate)
accc94d5
SL
1589{
1590 wxUnusedVar(fActivate);
1591 return E_NOTIMPL;
1592}
1593
a9c5eac9 1594HRESULT wxSTDCALL DocHostUIHandler::OnFrameWindowActivate(BOOL fActivate)
accc94d5
SL
1595{
1596 wxUnusedVar(fActivate);
1597 return E_NOTIMPL;
1598}
1599
a9c5eac9 1600HRESULT wxSTDCALL DocHostUIHandler::ResizeBorder(LPCRECT prcBorder,
accc94d5
SL
1601 IOleInPlaceUIWindow *pUIWindow,
1602 BOOL fFrameWindow)
1603{
1604 wxUnusedVar(prcBorder);
1605 wxUnusedVar(pUIWindow);
1606 wxUnusedVar(fFrameWindow);
1607 return E_NOTIMPL;
1608}
1609
a9c5eac9 1610HRESULT wxSTDCALL DocHostUIHandler::TranslateAccelerator(LPMSG lpMsg,
accc94d5
SL
1611 const GUID *pguidCmdGroup,
1612 DWORD nCmdID)
1613{
1614 if(lpMsg && lpMsg->message == WM_KEYDOWN)
1615 {
4ed85025
SL
1616 // check control is down but that it isn't right-alt which is mapped to
1617 // alt + ctrl
1618 if(GetKeyState(VK_CONTROL) & 0x8000 &&
1619 !(GetKeyState(VK_MENU) & 0x8000))
accc94d5 1620 {
e5f9b4ae
VZ
1621 //skip the accelerators used by the control
1622 switch(lpMsg->wParam)
accc94d5 1623 {
e5f9b4ae
VZ
1624 case 'F':
1625 case 'L':
1626 case 'N':
1627 case 'O':
1628 case 'P':
1629 return S_OK;
accc94d5
SL
1630 }
1631 }
1632 //skip F5
1633 if(lpMsg->wParam == VK_F5)
1634 {
1635 return S_OK;
1636 }
1637 }
1638
1639 wxUnusedVar(pguidCmdGroup);
1640 wxUnusedVar(nCmdID);
1641 return E_NOTIMPL;
1642}
1643
a9c5eac9 1644HRESULT wxSTDCALL DocHostUIHandler::GetOptionKeyPath(LPOLESTR *pchKey,DWORD dw)
accc94d5
SL
1645{
1646 wxUnusedVar(pchKey);
1647 wxUnusedVar(dw);
1648 return E_NOTIMPL;
1649}
1650
a9c5eac9 1651HRESULT wxSTDCALL DocHostUIHandler::GetDropTarget(IDropTarget *pDropTarget,
accc94d5
SL
1652 IDropTarget **ppDropTarget)
1653{
1654 wxUnusedVar(pDropTarget);
1655 wxUnusedVar(ppDropTarget);
1656 return E_NOTIMPL;
1657}
1658
a9c5eac9 1659HRESULT wxSTDCALL DocHostUIHandler::GetExternal(IDispatch **ppDispatch)
accc94d5
SL
1660{
1661 wxUnusedVar(ppDispatch);
1662 return E_NOTIMPL;
1663}
1664
a9c5eac9 1665HRESULT wxSTDCALL DocHostUIHandler::TranslateUrl(DWORD dwTranslate,
accc94d5
SL
1666 OLECHAR *pchURLIn,
1667 OLECHAR **ppchURLOut)
1668{
1669 wxUnusedVar(dwTranslate);
1670 wxUnusedVar(pchURLIn);
1671 wxUnusedVar(ppchURLOut);
1672 return E_NOTIMPL;
1673}
1674
a9c5eac9 1675HRESULT wxSTDCALL DocHostUIHandler::FilterDataObject(IDataObject *pDO, IDataObject **ppDORet)
accc94d5
SL
1676{
1677 wxUnusedVar(pDO);
1678 wxUnusedVar(ppDORet);
1679 return E_NOTIMPL;
1680}
1681
1682BEGIN_IID_TABLE(DocHostUIHandler)
1683 ADD_IID(Unknown)
1684 ADD_RAW_IID(wxIID_IDocHostUIHandler)
1685END_IID_TABLE;
1686
1687IMPLEMENT_IUNKNOWN_METHODS(DocHostUIHandler)
1688
9d2f31db 1689#endif // wxUSE_WEBVIEW && wxUSE_WEBVIEW_IE