]> git.saurik.com Git - wxWidgets.git/blame - src/msw/webview_ie.cpp
Fix crash in wxFileConfig when deleting last entry of the root group.
[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
5// Id: $Id$
153530af 6// Copyright: (c) 2010 Marianne Gagnon, 2011 Steven Lamerton
61b98a2d
SL
7// Licence: wxWindows licence
8/////////////////////////////////////////////////////////////////////////////
9
384b8d9f
SL
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
8290e3cd 17#include "wx/msw/webview_ie.h"
61b98a2d 18
9d2f31db 19#if wxUSE_WEBVIEW && wxUSE_WEBVIEW_IE
61b98a2d
SL
20
21#include <olectl.h>
22#include <oleidl.h>
23#include <exdispid.h>
24#include <exdisp.h>
25#include <mshtml.h>
cd4e4673 26#include "wx/msw/registry.h"
1d7d04d7 27#include "wx/msw/missing.h"
7d3f6b4d 28#include "wx/filesys.h"
e924e848 29#include "wx/dynlib.h"
f559d1a2
VZ
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
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);
f559d1a2
VZ
41
42}
7d3f6b4d 43
cddf4541
SL
44wxIMPLEMENT_DYNAMIC_CLASS(wxWebViewIE, wxWebView);
45
61b98a2d 46BEGIN_EVENT_TABLE(wxWebViewIE, wxControl)
97ad1425
SL
47 EVT_ACTIVEX(wxID_ANY, wxWebViewIE::onActiveXEvent)
48 EVT_ERASE_BACKGROUND(wxWebViewIE::onEraseBg)
61b98a2d
SL
49END_EVENT_TABLE()
50
51bool 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;
61b98a2d 66 m_isBusy = false;
74af0b13
SL
67 m_historyLoadingFromList = false;
68 m_historyEnabled = true;
69 m_historyPosition = -1;
c5f417cb 70 m_zoomType = wxWEB_VIEW_ZOOM_TYPE_TEXT;
61b98a2d
SL
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);
61b98a2d 84
accc94d5
SL
85 m_uiHandler = new DocHostUIHandler;
86 m_uiHandler->AddRef();
87
88 m_container = new wxIEContainer(this, IID_IWebBrowser2, m_webBrowser, m_uiHandler);
61b98a2d 89
9447a0d6
SL
90 EnableControlFeature(21 /* FEATURE_DISABLE_NAVIGATION_SOUNDS */);
91
4d0dddc7 92 LoadURL(url);
61b98a2d
SL
93 return true;
94}
95
39498710
SL
96wxWebViewIE::~wxWebViewIE()
97{
98 for(unsigned int i = 0; i < m_factories.size(); i++)
99 {
100 m_factories[i]->Release();
101 }
accc94d5
SL
102
103 m_uiHandler->Release();
39498710 104}
61b98a2d 105
4d0dddc7 106void wxWebViewIE::LoadURL(const wxString& url)
61b98a2d 107{
e8d243a9 108 m_ie.CallMethod("Navigate", wxConvertStringToOle(url));
61b98a2d
SL
109}
110
442262d4 111void wxWebViewIE::SetPage(const wxString& html, const wxString& baseUrl)
61b98a2d 112{
7f98bdd6 113 BSTR bstr = SysAllocString(OLESTR(""));
61b98a2d
SL
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;
442262d4 121
7f98bdd6 122 hr = SafeArrayUnaccessData(psaStrings);
accc94d5 123
617227c3 124 IHTMLDocument2* document = GetDocument();
e81ef297
SL
125
126 if(!document)
127 return;
128
61b98a2d 129 document->write(psaStrings);
7f98bdd6 130 document->close();
442262d4 131 document->Release();
61b98a2d 132
61b98a2d 133 SafeArrayDestroy(psaStrings);
442262d4 134
7f98bdd6
SL
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();
e81ef297
SL
147
148 if(!document)
149 return;
150
7f98bdd6
SL
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 }
61b98a2d
SL
173 }
174 else
175 {
7f98bdd6 176 wxLogError("wxWebViewIE::SetPage() : psaStrings is NULL during clear");
61b98a2d 177 }
61b98a2d
SL
178}
179
e669ddde 180wxString wxWebViewIE::GetPageSource() const
61b98a2d 181{
617227c3 182 IHTMLDocument2* document = GetDocument();
e81ef297
SL
183
184 if(document)
7fbc727b 185 {
e81ef297
SL
186 IHTMLElement *bodyTag = NULL;
187 IHTMLElement *htmlTag = NULL;
188 wxString source;
189 HRESULT hr = document->get_body(&bodyTag);
7fbc727b
SL
190 if(SUCCEEDED(hr))
191 {
e81ef297
SL
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();
7fbc727b 201 }
61b98a2d 202
e81ef297
SL
203 document->Release();
204 return source;
205 }
206 else
207 {
208 return "";
209 }
61b98a2d
SL
210}
211
e669ddde 212wxWebViewZoom wxWebViewIE::GetZoom() const
61b98a2d 213{
8acbf08b
SL
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 }
423adfde
SL
223
224 //Dummy return to stop compiler warnings
225 return wxWEB_VIEW_ZOOM_MEDIUM;
1d7d04d7 226
61b98a2d 227}
c5f417cb 228
61b98a2d
SL
229void wxWebViewIE::SetZoom(wxWebViewZoom zoom)
230{
8acbf08b
SL
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 }
61b98a2d
SL
242}
243
c5f417cb 244void wxWebViewIE::SetIETextZoom(wxWebViewZoom level)
61b98a2d 245{
1d7d04d7 246 //We do not use OLECMDID_OPTICAL_GETZOOMRANGE as the docs say the range
c5f417cb
SL
247 //is 0 to 4 so the check is unnecessary, these match exactly with the
248 //enum values
61b98a2d
SL
249 VARIANT zoomVariant;
250 VariantInit (&zoomVariant);
251 V_VT(&zoomVariant) = VT_I4;
252 V_I4(&zoomVariant) = level;
253
8acbf08b
SL
254#if wxDEBUG_LEVEL
255 HRESULT result =
256#endif
257 m_webBrowser->ExecWB(OLECMDID_ZOOM,
258 OLECMDEXECOPT_DONTPROMPTUSER,
259 &zoomVariant, NULL);
c5f417cb 260 wxASSERT(result == S_OK);
61b98a2d
SL
261}
262
e669ddde 263wxWebViewZoom wxWebViewIE::GetIETextZoom() const
61b98a2d
SL
264{
265 VARIANT zoomVariant;
266 VariantInit (&zoomVariant);
267 V_VT(&zoomVariant) = VT_I4;
61b98a2d 268
8acbf08b
SL
269#if wxDEBUG_LEVEL
270 HRESULT result =
271#endif
272 m_webBrowser->ExecWB(OLECMDID_ZOOM,
273 OLECMDEXECOPT_DONTPROMPTUSER,
274 NULL, &zoomVariant);
c5f417cb 275 wxASSERT(result == S_OK);
61b98a2d 276
c5f417cb
SL
277 //We can safely cast here as we know that the range matches our enum
278 return static_cast<wxWebViewZoom>(V_I4(&zoomVariant));
61b98a2d
SL
279}
280
c5f417cb 281void wxWebViewIE::SetIEOpticalZoom(wxWebViewZoom level)
61b98a2d 282{
1d7d04d7 283 //We do not use OLECMDID_OPTICAL_GETZOOMRANGE as the docs say the range
c5f417cb 284 //is 10 to 1000 so the check is unnecessary
61b98a2d
SL
285 VARIANT zoomVariant;
286 VariantInit (&zoomVariant);
287 V_VT(&zoomVariant) = VT_I4;
c5f417cb
SL
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 }
61b98a2d 310
8acbf08b
SL
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);
c5f417cb 318 wxASSERT(result == S_OK);
61b98a2d
SL
319}
320
e669ddde 321wxWebViewZoom wxWebViewIE::GetIEOpticalZoom() const
61b98a2d 322{
61b98a2d
SL
323 VARIANT zoomVariant;
324 VariantInit (&zoomVariant);
325 V_VT(&zoomVariant) = VT_I4;
61b98a2d 326
8acbf08b
SL
327#if wxDEBUG_LEVEL
328 HRESULT result =
329#endif
330 m_webBrowser->ExecWB((OLECMDID)63 /*OLECMDID_OPTICAL_ZOOM*/,
331 OLECMDEXECOPT_DODEFAULT, NULL,
332 &zoomVariant);
c5f417cb 333 wxASSERT(result == S_OK);
61b98a2d
SL
334
335 const int zoom = V_I4(&zoomVariant);
61b98a2d 336
c5f417cb
SL
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 }
423adfde 354 else /*if (zoom > 145) */ //Using else removes a compiler warning
c5f417cb
SL
355 {
356 return wxWEB_VIEW_ZOOM_LARGEST;
357 }
61b98a2d
SL
358}
359
c5f417cb 360void wxWebViewIE::SetZoomType(wxWebViewZoomType type)
61b98a2d 361{
c5f417cb 362 m_zoomType = type;
61b98a2d
SL
363}
364
365wxWebViewZoomType wxWebViewIE::GetZoomType() const
366{
c5f417cb 367 return m_zoomType;
61b98a2d
SL
368}
369
cd4e4673 370bool wxWebViewIE::CanSetZoomType(wxWebViewZoomType type) const
61b98a2d 371{
cd4e4673
SL
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;
61b98a2d
SL
383}
384
385void wxWebViewIE::Print()
386{
387 m_webBrowser->ExecWB(OLECMDID_PRINTPREVIEW,
388 OLECMDEXECOPT_DODEFAULT, NULL, NULL);
389}
390
e669ddde 391bool wxWebViewIE::CanGoBack() const
61b98a2d 392{
74af0b13
SL
393 if(m_historyEnabled)
394 return m_historyPosition > 0;
395 else
396 return false;
397}
61b98a2d 398
e669ddde 399bool wxWebViewIE::CanGoForward() const
74af0b13
SL
400{
401 if(m_historyEnabled)
22ca10fa 402 return m_historyPosition != static_cast<int>(m_historyList.size()) - 1;
74af0b13
SL
403 else
404 return false;
61b98a2d
SL
405}
406
c13d6ac1 407void wxWebViewIE::LoadHistoryItem(wxSharedPtr<wxWebViewHistoryItem> item)
61b98a2d 408{
74af0b13
SL
409 int pos = -1;
410 for(unsigned int i = 0; i < m_historyList.size(); i++)
411 {
3e7968c2
SL
412 //We compare the actual pointers to find the correct item
413 if(m_historyList[i].get() == item.get())
74af0b13
SL
414 pos = i;
415 }
1d7d04d7 416 wxASSERT_MSG(pos != static_cast<int>(m_historyList.size()),
22ca10fa 417 "invalid history item");
74af0b13 418 m_historyLoadingFromList = true;
4d0dddc7 419 LoadURL(item->GetUrl());
74af0b13
SL
420 m_historyPosition = pos;
421}
61b98a2d 422
c13d6ac1 423wxVector<wxSharedPtr<wxWebViewHistoryItem> > wxWebViewIE::GetBackwardHistory()
5cbda74b 424{
c13d6ac1 425 wxVector<wxSharedPtr<wxWebViewHistoryItem> > backhist;
5cbda74b
SL
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
c13d6ac1 435wxVector<wxSharedPtr<wxWebViewHistoryItem> > wxWebViewIE::GetForwardHistory()
5cbda74b 436{
c13d6ac1 437 wxVector<wxSharedPtr<wxWebViewHistoryItem> > forwardhist;
5cbda74b
SL
438 //As we don't have std::copy or an iterator constructor in the wxwidgets
439 //native vector we construct it by hand
22ca10fa 440 for(int i = m_historyPosition + 1; i < static_cast<int>(m_historyList.size()); i++)
5cbda74b
SL
441 {
442 forwardhist.push_back(m_historyList[i]);
443 }
444 return forwardhist;
445}
446
74af0b13
SL
447void wxWebViewIE::GoBack()
448{
3e7968c2 449 LoadHistoryItem(m_historyList[m_historyPosition - 1]);
74af0b13
SL
450}
451
452void wxWebViewIE::GoForward()
453{
3e7968c2 454 LoadHistoryItem(m_historyList[m_historyPosition + 1]);
61b98a2d
SL
455}
456
457void wxWebViewIE::Stop()
458{
7fbc727b 459 m_ie.CallMethod("Stop");
61b98a2d
SL
460}
461
74af0b13
SL
462void wxWebViewIE::ClearHistory()
463{
464 m_historyList.clear();
465 m_historyPosition = -1;
466}
467
468void wxWebViewIE::EnableHistory(bool enable)
469{
470 m_historyEnabled = enable;
471 m_historyList.clear();
472 m_historyPosition = -1;
473}
61b98a2d
SL
474
475void wxWebViewIE::Reload(wxWebViewReloadFlags flags)
476{
7aa18fc7
SL
477 VARIANTARG level;
478 VariantInit(&level);
479 V_VT(&level) = VT_I2;
61b98a2d 480
7aa18fc7 481 switch(flags)
61b98a2d 482 {
7aa18fc7
SL
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");
61b98a2d
SL
491 }
492
7aa18fc7 493 m_webBrowser->Refresh2(&level);
61b98a2d
SL
494}
495
496bool wxWebViewIE::IsOfflineMode()
497{
498 wxVariant out = m_ie.GetProperty("Offline");
499
500 wxASSERT(out.GetType() == "bool");
501
502 return out.GetBool();
503}
504
505void wxWebViewIE::SetOfflineMode(bool offline)
506{
507 // FIXME: the wxWidgets docs do not really document what the return
508 // parameter of PutProperty is
8acbf08b
SL
509#if wxDEBUG_LEVEL
510 const bool success =
511#endif
512 m_ie.PutProperty("Offline", (offline ?
513 VARIANT_TRUE :
514 VARIANT_FALSE));
61b98a2d
SL
515 wxASSERT(success);
516}
517
e669ddde 518bool wxWebViewIE::IsBusy() const
60eabdbe 519{
61b98a2d
SL
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
e669ddde 529wxString wxWebViewIE::GetCurrentURL() const
61b98a2d
SL
530{
531 wxVariant out = m_ie.GetProperty("LocationURL");
532
533 wxASSERT(out.GetType() == "string");
534 return out.GetString();
535}
536
e669ddde 537wxString wxWebViewIE::GetCurrentTitle() const
61b98a2d 538{
617227c3 539 IHTMLDocument2* document = GetDocument();
7fbc727b 540
e81ef297
SL
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 }
61b98a2d
SL
552}
553
e669ddde 554bool wxWebViewIE::CanCut() const
4681a3ea
SL
555{
556 return CanExecCommand("Cut");
557}
558
e669ddde 559bool wxWebViewIE::CanCopy() const
4681a3ea
SL
560{
561 return CanExecCommand("Copy");
562}
34326da7 563
e669ddde 564bool wxWebViewIE::CanPaste() const
4681a3ea
SL
565{
566 return CanExecCommand("Paste");
567}
568
569void wxWebViewIE::Cut()
570{
571 ExecCommand("Cut");
572}
573
574void wxWebViewIE::Copy()
575{
576 ExecCommand("Copy");
577}
578
579void wxWebViewIE::Paste()
580{
581 ExecCommand("Paste");
582}
583
e669ddde 584bool wxWebViewIE::CanUndo() const
97e49559
SL
585{
586 return CanExecCommand("Undo");
587}
34326da7 588
e669ddde 589bool wxWebViewIE::CanRedo() const
97e49559
SL
590{
591 return CanExecCommand("Redo");
592}
593
594void wxWebViewIE::Undo()
595{
596 ExecCommand("Undo");
597}
598
599void wxWebViewIE::Redo()
600{
601 ExecCommand("Redo");
602}
603
c7cbe308
SL
604void wxWebViewIE::SetEditable(bool enable)
605{
606 IHTMLDocument2* document = GetDocument();
7fbc727b 607
e81ef297
SL
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 }
c7cbe308
SL
617}
618
e669ddde 619bool wxWebViewIE::IsEditable() const
c7cbe308
SL
620{
621 IHTMLDocument2* document = GetDocument();
e81ef297
SL
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 }
c7cbe308 633 else
e81ef297 634 {
c7cbe308 635 return false;
e81ef297 636 }
c7cbe308
SL
637}
638
63a65070
SL
639void wxWebViewIE::SelectAll()
640{
641 ExecCommand("SelectAll");
642}
643
e669ddde 644bool wxWebViewIE::HasSelection() const
63a65070
SL
645{
646 IHTMLDocument2* document = GetDocument();
e81ef297
SL
647
648 if(document)
7fbc727b 649 {
e81ef297
SL
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;
7fbc727b 666 }
63a65070
SL
667}
668
669void wxWebViewIE::DeleteSelection()
670{
671 ExecCommand("Delete");
672}
673
e669ddde 674wxString wxWebViewIE::GetSelectedText() const
c9355a3d
SL
675{
676 IHTMLDocument2* document = GetDocument();
e81ef297
SL
677
678 if(document)
c9355a3d 679 {
e81ef297
SL
680 IHTMLSelectionObject* selection;
681 wxString selected;
682 HRESULT hr = document->get_selection(&selection);
c9355a3d
SL
683 if(SUCCEEDED(hr))
684 {
e81ef297
SL
685 IDispatch* disrange;
686 hr = selection->createRange(&disrange);
c9355a3d
SL
687 if(SUCCEEDED(hr))
688 {
e81ef297
SL
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();
c9355a3d 699 }
e81ef297 700 selection->Release();
c9355a3d 701 }
e81ef297
SL
702 document->Release();
703 return selected;
704 }
705 else
706 {
707 return "";
c9355a3d 708 }
c9355a3d
SL
709}
710
e669ddde 711wxString wxWebViewIE::GetSelectedSource() const
0fe8a1b6
SL
712{
713 IHTMLDocument2* document = GetDocument();
e81ef297
SL
714
715 if(document)
0fe8a1b6 716 {
e81ef297
SL
717 IHTMLSelectionObject* selection;
718 wxString selected;
719 HRESULT hr = document->get_selection(&selection);
0fe8a1b6
SL
720 if(SUCCEEDED(hr))
721 {
e81ef297
SL
722 IDispatch* disrange;
723 hr = selection->createRange(&disrange);
0fe8a1b6
SL
724 if(SUCCEEDED(hr))
725 {
e81ef297
SL
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();
0fe8a1b6 736 }
e81ef297 737 selection->Release();
0fe8a1b6 738 }
e81ef297
SL
739 document->Release();
740 return selected;
741 }
742 else
743 {
744 return "";
0fe8a1b6 745 }
0fe8a1b6
SL
746}
747
41933aa5
SL
748void wxWebViewIE::ClearSelection()
749{
750 IHTMLDocument2* document = GetDocument();
e81ef297
SL
751
752 if(document)
41933aa5 753 {
e81ef297
SL
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();
41933aa5 763 }
41933aa5
SL
764}
765
e669ddde 766wxString wxWebViewIE::GetPageText() const
241b769f
SL
767{
768 IHTMLDocument2* document = GetDocument();
e81ef297
SL
769
770 if(document)
241b769f 771 {
e81ef297
SL
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 "";
241b769f 788 }
241b769f
SL
789}
790
c9ccc09c
SL
791void wxWebViewIE::RunScript(const wxString& javascript)
792{
793 IHTMLDocument2* document = GetDocument();
e81ef297
SL
794
795 if(document)
c9ccc09c 796 {
e81ef297
SL
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();
c9ccc09c 810 }
c9ccc09c
SL
811}
812
7d8d6163 813void wxWebViewIE::RegisterHandler(wxSharedPtr<wxWebViewHandler> handler)
29365629 814{
e924e848
SL
815 wxDynamicLibrary urlMon(wxT("urlmon.dll"));
816 if(urlMon.HasSymbol(wxT("CoInternetGetSession")))
29365629 817 {
f559d1a2 818 typedef HRESULT (WINAPI *CoInternetGetSession_t)(DWORD, wxIInternetSession**, DWORD);
e924e848
SL
819 wxDYNLIB_FUNCTION(CoInternetGetSession_t, CoInternetGetSession, urlMon);
820
821 ClassFactory* cf = new ClassFactory(handler);
f559d1a2 822 wxIInternetSession* session;
e924e848
SL
823 HRESULT res = (*pfnCoInternetGetSession)(0, &session, 0);
824 if(FAILED(res))
825 {
826 wxFAIL_MSG("Could not retrive internet session");
827 }
29365629 828
c9a828e7
VZ
829 HRESULT hr = session->RegisterNameSpace(cf, CLSID_FileProtocol,
830 handler->GetName().wc_str(),
831 0, NULL, 0);
e924e848
SL
832 if(FAILED(hr))
833 {
834 wxFAIL_MSG("Could not register protocol");
835 }
39498710 836 m_factories.push_back(cf);
e924e848
SL
837 }
838 else
29365629 839 {
e924e848 840 wxFAIL_MSG("urlmon does not contain CoInternetGetSession");
29365629
SL
841 }
842}
843
e669ddde 844bool wxWebViewIE::CanExecCommand(wxString command) const
4681a3ea 845{
617227c3 846 IHTMLDocument2* document = GetDocument();
7fbc727b 847
e81ef297
SL
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 }
4681a3ea 861
4681a3ea
SL
862}
863
864void wxWebViewIE::ExecCommand(wxString command)
865{
617227c3 866 IHTMLDocument2* document = GetDocument();
e81ef297
SL
867
868 if(document)
869 {
870 document->execCommand(SysAllocString(command.wc_str()), VARIANT_FALSE, VARIANT(), NULL);
871 document->Release();
872 }
617227c3 873}
4681a3ea 874
e669ddde 875IHTMLDocument2* wxWebViewIE::GetDocument() const
617227c3 876{
601d0ba7 877 IDispatch* dispatch = NULL;
e81ef297 878 HRESULT result = m_webBrowser->get_Document(&dispatch);
601d0ba7 879 if(dispatch && SUCCEEDED(result))
e81ef297
SL
880 {
881 IHTMLDocument2* document;
882 dispatch->QueryInterface(IID_IHTMLDocument2, (void**)&document);
601d0ba7 883 dispatch->Release();
e81ef297
SL
884 //document is set to null automatically if the interface isn't supported
885 return document;
886 }
887 else
888 {
889 return NULL;
890 }
4681a3ea
SL
891}
892
9447a0d6
SL
893bool wxWebViewIE::EnableControlFeature(long flag, bool enable)
894{
895#if wxUSE_DYNLIB_CLASS
896
897 wxDynamicLibrary urlMon(wxT("urlmon.dll"));
34326da7
SL
898 if( urlMon.IsLoaded() &&
899 urlMon.HasSymbol("CoInternetSetFeatureEnabled") &&
9447a0d6
SL
900 urlMon.HasSymbol("CoInternetIsFeatureEnabled"))
901 {
902 typedef HRESULT (WINAPI *CoInternetSetFeatureEnabled_t)(DWORD, DWORD, BOOL);
903 typedef HRESULT (WINAPI *CoInternetIsFeatureEnabled_t)(DWORD, DWORD);
904
905 wxDYNLIB_FUNCTION(CoInternetSetFeatureEnabled_t, CoInternetSetFeatureEnabled, urlMon);
906 wxDYNLIB_FUNCTION(CoInternetIsFeatureEnabled_t, CoInternetIsFeatureEnabled, urlMon);
907
908 HRESULT hr = (*pfnCoInternetIsFeatureEnabled)(flag,
909 0x2 /* SET_FEATURE_ON_PROCESS */);
910 if((hr == S_OK && enable) || (hr == S_FALSE && !enable))
911 return true;
912
913 hr = (*pfnCoInternetSetFeatureEnabled)(flag,
914 0x2/* SET_FEATURE_ON_PROCESS */,
915 (enable ? TRUE : FALSE));
916 if ( FAILED(hr) )
917 {
918 wxLogApiError(wxT("CoInternetSetFeatureEnabled"), hr);
919 return false;
920 }
921 return true;
922 }
923 return false;
924#else
925 wxUnusedVar(flag);
926 wxUnusedVar(enable);
927 return false;
928#endif // wxUSE_DYNLIB_CLASS/!wxUSE_DYNLIB_CLASS
929}
930
61b98a2d
SL
931void wxWebViewIE::onActiveXEvent(wxActiveXEvent& evt)
932{
933 if (m_webBrowser == NULL) return;
934
935 switch (evt.GetDispatchId())
936 {
937 case DISPID_BEFORENAVIGATE2:
938 {
939 m_isBusy = true;
940
941 wxString url = evt[1].GetString();
942 wxString target = evt[3].GetString();
943
04fa04d8 944 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_NAVIGATING,
3225a4b8 945 GetId(), url, target);
e11b9a6b
SL
946
947 //skip empty javascript events.
948 if(url == "javascript:\"\"" && target.IsEmpty())
949 {
950 event.Veto();
951 }
952 else
953 {
954 event.SetEventObject(this);
955 HandleWindowEvent(event);
956 }
61b98a2d 957
3225a4b8 958 if (!event.IsAllowed())
61b98a2d
SL
959 {
960 wxActiveXEventNativeMSW* nativeParams =
961 evt.GetNativeParameters();
962 *V_BOOLREF(&nativeParams->pDispParams->rgvarg[0]) = VARIANT_TRUE;
963 }
964
965 // at this point, either the navigation event has been cancelled
966 // and we're not busy, either it was accepted and IWebBrowser2's
967 // Busy property will be true; so we don't need our override
968 // flag anymore.
969 m_isBusy = false;
970
971 break;
972 }
973
974 case DISPID_NAVIGATECOMPLETE2:
975 {
976 wxString url = evt[1].GetString();
977 // TODO: set target parameter if possible
978 wxString target = wxEmptyString;
04fa04d8 979 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_NAVIGATED,
3225a4b8 980 GetId(), url, target);
61b98a2d
SL
981 event.SetEventObject(this);
982 HandleWindowEvent(event);
983 break;
984 }
985
986 case DISPID_PROGRESSCHANGE:
987 {
988 // download progress
989 break;
990 }
991
992 case DISPID_DOCUMENTCOMPLETE:
993 {
3ee442ff
SL
994 //Only send a complete even if we are actually finished, this brings
995 //the event in to line with webkit
996 READYSTATE rs;
997 m_webBrowser->get_ReadyState( &rs );
998 if(rs != READYSTATE_COMPLETE)
999 break;
1000
61b98a2d 1001 wxString url = evt[1].GetString();
113e0a92
SL
1002
1003 //As we are complete we also add to the history list, but not if the
1004 //page is not the main page, ie it is a subframe
60eabdbe 1005 //We also have to check if we are loading a file:// url, if so we
f239a200
SL
1006 //need to change the comparison as ie passes back a different style
1007 //of url
60eabdbe
VZ
1008 if(m_historyEnabled && !m_historyLoadingFromList &&
1009 (url == GetCurrentURL() ||
1010 (GetCurrentURL().substr(0, 4) == "file" &&
f239a200 1011 wxFileSystem::URLToFileName(GetCurrentURL()).GetFullPath() == url)))
74af0b13
SL
1012 {
1013 //If we are not at the end of the list, then erase everything
1014 //between us and the end before adding the new page
22ca10fa 1015 if(m_historyPosition != static_cast<int>(m_historyList.size()) - 1)
74af0b13
SL
1016 {
1017 m_historyList.erase(m_historyList.begin() + m_historyPosition + 1,
1018 m_historyList.end());
1019 }
c13d6ac1 1020 wxSharedPtr<wxWebViewHistoryItem> item(new wxWebViewHistoryItem(url, GetCurrentTitle()));
74af0b13
SL
1021 m_historyList.push_back(item);
1022 m_historyPosition++;
1023 }
1024 //Reset as we are done now
1025 m_historyLoadingFromList = false;
61b98a2d
SL
1026 // TODO: set target parameter if possible
1027 wxString target = wxEmptyString;
04fa04d8 1028 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_LOADED, GetId(),
3225a4b8 1029 url, target);
61b98a2d
SL
1030 event.SetEventObject(this);
1031 HandleWindowEvent(event);
1032 break;
1033 }
1034
1035 case DISPID_STATUSTEXTCHANGE:
1036 {
1037 break;
1038 }
1039
1040 case DISPID_TITLECHANGE:
1041 {
153530af
SL
1042 wxString title = evt[0].GetString();
1043
04fa04d8 1044 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_TITLE_CHANGED,
3225a4b8 1045 GetId(), GetCurrentURL(), "");
153530af
SL
1046 event.SetString(title);
1047 event.SetEventObject(this);
1048 HandleWindowEvent(event);
61b98a2d
SL
1049 break;
1050 }
1051
1052 case DISPID_NAVIGATEERROR:
1053 {
04fa04d8 1054 wxWebViewNavigationError errorType = wxWEB_NAV_ERR_OTHER;
61b98a2d
SL
1055 wxString errorCode = "?";
1056 switch (evt[3].GetLong())
1057 {
1058 case INET_E_INVALID_URL: // (0x800C0002L or -2146697214)
1059 errorCode = "INET_E_INVALID_URL";
1060 errorType = wxWEB_NAV_ERR_REQUEST;
1061 break;
1062 case INET_E_NO_SESSION: // (0x800C0003L or -2146697213)
1063 errorCode = "INET_E_NO_SESSION";
1064 errorType = wxWEB_NAV_ERR_CONNECTION;
1065 break;
1066 case INET_E_CANNOT_CONNECT: // (0x800C0004L or -2146697212)
1067 errorCode = "INET_E_CANNOT_CONNECT";
1068 errorType = wxWEB_NAV_ERR_CONNECTION;
1069 break;
1070 case INET_E_RESOURCE_NOT_FOUND: // (0x800C0005L or -2146697211)
1071 errorCode = "INET_E_RESOURCE_NOT_FOUND";
1072 errorType = wxWEB_NAV_ERR_NOT_FOUND;
1073 break;
1074 case INET_E_OBJECT_NOT_FOUND: // (0x800C0006L or -2146697210)
1075 errorCode = "INET_E_OBJECT_NOT_FOUND";
1076 errorType = wxWEB_NAV_ERR_NOT_FOUND;
1077 break;
1078 case INET_E_DATA_NOT_AVAILABLE: // (0x800C0007L or -2146697209)
1079 errorCode = "INET_E_DATA_NOT_AVAILABLE";
1080 errorType = wxWEB_NAV_ERR_NOT_FOUND;
1081 break;
1082 case INET_E_DOWNLOAD_FAILURE: // (0x800C0008L or -2146697208)
1083 errorCode = "INET_E_DOWNLOAD_FAILURE";
1084 errorType = wxWEB_NAV_ERR_CONNECTION;
1085 break;
1086 case INET_E_AUTHENTICATION_REQUIRED: // (0x800C0009L or -2146697207)
1087 errorCode = "INET_E_AUTHENTICATION_REQUIRED";
1088 errorType = wxWEB_NAV_ERR_AUTH;
1089 break;
1090 case INET_E_NO_VALID_MEDIA: // (0x800C000AL or -2146697206)
1091 errorCode = "INET_E_NO_VALID_MEDIA";
1092 errorType = wxWEB_NAV_ERR_REQUEST;
1093 break;
1094 case INET_E_CONNECTION_TIMEOUT: // (0x800C000BL or -2146697205)
1095 errorCode = "INET_E_CONNECTION_TIMEOUT";
1096 errorType = wxWEB_NAV_ERR_CONNECTION;
1097 break;
1098 case INET_E_INVALID_REQUEST: // (0x800C000CL or -2146697204)
1099 errorCode = "INET_E_INVALID_REQUEST";
1100 errorType = wxWEB_NAV_ERR_REQUEST;
1101 break;
1102 case INET_E_UNKNOWN_PROTOCOL: // (0x800C000DL or -2146697203)
1103 errorCode = "INET_E_UNKNOWN_PROTOCOL";
1104 errorType = wxWEB_NAV_ERR_REQUEST;
1105 break;
1106 case INET_E_SECURITY_PROBLEM: // (0x800C000EL or -2146697202)
1107 errorCode = "INET_E_SECURITY_PROBLEM";
1108 errorType = wxWEB_NAV_ERR_SECURITY;
1109 break;
1110 case INET_E_CANNOT_LOAD_DATA: // (0x800C000FL or -2146697201)
1111 errorCode = "INET_E_CANNOT_LOAD_DATA";
1112 errorType = wxWEB_NAV_ERR_OTHER;
1113 break;
1114 case INET_E_CANNOT_INSTANTIATE_OBJECT:
1115 // CoCreateInstance will return an error code if this happens,
1116 // we'll handle this above.
1117 return;
1118 break;
1119 case INET_E_REDIRECT_FAILED: // (0x800C0014L or -2146697196)
1120 errorCode = "INET_E_REDIRECT_FAILED";
1121 errorType = wxWEB_NAV_ERR_OTHER;
1122 break;
1123 case INET_E_REDIRECT_TO_DIR: // (0x800C0015L or -2146697195)
1124 errorCode = "INET_E_REDIRECT_TO_DIR";
1125 errorType = wxWEB_NAV_ERR_REQUEST;
1126 break;
1127 case INET_E_CANNOT_LOCK_REQUEST: // (0x800C0016L or -2146697194)
1128 errorCode = "INET_E_CANNOT_LOCK_REQUEST";
1129 errorType = wxWEB_NAV_ERR_OTHER;
1130 break;
1131 case INET_E_USE_EXTEND_BINDING: // (0x800C0017L or -2146697193)
1132 errorCode = "INET_E_USE_EXTEND_BINDING";
1133 errorType = wxWEB_NAV_ERR_OTHER;
1134 break;
1135 case INET_E_TERMINATED_BIND: // (0x800C0018L or -2146697192)
1136 errorCode = "INET_E_TERMINATED_BIND";
1137 errorType = wxWEB_NAV_ERR_OTHER;
1138 break;
1139 case INET_E_INVALID_CERTIFICATE: // (0x800C0019L or -2146697191)
1140 errorCode = "INET_E_INVALID_CERTIFICATE";
1141 errorType = wxWEB_NAV_ERR_CERTIFICATE;
1142 break;
1143 case INET_E_CODE_DOWNLOAD_DECLINED: // (0x800C0100L or -2146696960)
1144 errorCode = "INET_E_CODE_DOWNLOAD_DECLINED";
1145 errorType = wxWEB_NAV_ERR_USER_CANCELLED;
1146 break;
1147 case INET_E_RESULT_DISPATCHED: // (0x800C0200L or -2146696704)
1148 // cancel request cancelled...
1149 errorCode = "INET_E_RESULT_DISPATCHED";
1150 errorType = wxWEB_NAV_ERR_OTHER;
1151 break;
1152 case INET_E_CANNOT_REPLACE_SFP_FILE: // (0x800C0300L or -2146696448)
1153 errorCode = "INET_E_CANNOT_REPLACE_SFP_FILE";
1154 errorType = wxWEB_NAV_ERR_SECURITY;
1155 break;
1156 case INET_E_CODE_INSTALL_BLOCKED_BY_HASH_POLICY:
1157 errorCode = "INET_E_CODE_INSTALL_BLOCKED_BY_HASH_POLICY";
1158 errorType = wxWEB_NAV_ERR_SECURITY;
1159 break;
1160 case INET_E_CODE_INSTALL_SUPPRESSED:
1161 errorCode = "INET_E_CODE_INSTALL_SUPPRESSED";
1162 errorType = wxWEB_NAV_ERR_SECURITY;
1163 break;
1164 }
1165
1166 wxString url = evt[1].GetString();
1167 wxString target = evt[2].GetString();
04fa04d8 1168 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_ERROR, GetId(),
3225a4b8 1169 url, target);
61b98a2d
SL
1170 event.SetEventObject(this);
1171 event.SetInt(errorType);
1172 event.SetString(errorCode);
1173 HandleWindowEvent(event);
1174 break;
1175 }
853b6cd0 1176 case DISPID_NEWWINDOW3:
61b98a2d 1177 {
853b6cd0
SL
1178 wxString url = evt[4].GetString();
1179
04fa04d8 1180 wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_NEWWINDOW,
3225a4b8 1181 GetId(), url, wxEmptyString);
853b6cd0
SL
1182 event.SetEventObject(this);
1183 HandleWindowEvent(event);
1184
d676fb21
SL
1185 //We always cancel this event otherwise an Internet Exporer window
1186 //is opened for the url
1187 wxActiveXEventNativeMSW* nativeParams = evt.GetNativeParameters();
1188 *V_BOOLREF(&nativeParams->pDispParams->rgvarg[3]) = VARIANT_TRUE;
be19c556
SL
1189 break;
1190 }
61b98a2d
SL
1191 }
1192
1193 evt.Skip();
1194}
1195
7d8d6163 1196VirtualProtocol::VirtualProtocol(wxSharedPtr<wxWebViewHandler> handler)
7d3f6b4d 1197{
7d3f6b4d 1198 m_file = NULL;
29365629 1199 m_handler = handler;
7d3f6b4d
SL
1200}
1201
9f194b9d
SL
1202BEGIN_IID_TABLE(VirtualProtocol)
1203 ADD_IID(Unknown)
1204 ADD_RAW_IID(wxIID_IInternetProtocolRoot)
1205 ADD_RAW_IID(wxIID_IInternetProtocol)
1206END_IID_TABLE;
7d3f6b4d 1207
9f194b9d 1208IMPLEMENT_IUNKNOWN_METHODS(VirtualProtocol)
7d3f6b4d 1209
f559d1a2
VZ
1210HRESULT VirtualProtocol::Start(LPCWSTR szUrl, wxIInternetProtocolSink *pOIProtSink,
1211 wxIInternetBindInfo *pOIBindInfo, DWORD grfPI,
0995b9dc 1212 HANDLE_PTR dwReserved)
7d3f6b4d 1213{
0995b9dc
SL
1214 wxUnusedVar(szUrl);
1215 wxUnusedVar(pOIBindInfo);
1216 wxUnusedVar(grfPI);
1217 wxUnusedVar(dwReserved);
7d3f6b4d 1218 m_protocolSink = pOIProtSink;
60eabdbe 1219
29365629
SL
1220 //We get the file itself from the protocol handler
1221 m_file = m_handler->GetFile(szUrl);
1222
7d3f6b4d
SL
1223
1224 if(!m_file)
1225 return INET_E_RESOURCE_NOT_FOUND;
1226
1227 //We return the stream length for current and total size as we can always
1228 //read the whole file from the stream
666f73c4 1229 wxFileOffset length = m_file->GetStream()->GetLength();
f559d1a2
VZ
1230 m_protocolSink->ReportData(wxBSCF_FIRSTDATANOTIFICATION |
1231 wxBSCF_DATAFULLYAVAILABLE |
1232 wxBSCF_LASTDATANOTIFICATION,
666f73c4 1233 length, length);
60eabdbe 1234 return S_OK;
7d3f6b4d
SL
1235}
1236
1237HRESULT VirtualProtocol::Read(void *pv, ULONG cb, ULONG *pcbRead)
1238{
1239 //If the file is null we return false to indicte it is finished
60eabdbe 1240 if(!m_file)
7d3f6b4d
SL
1241 return S_FALSE;
1242
1243 wxStreamError err = m_file->GetStream()->Read(pv, cb).GetLastError();
1244 *pcbRead = m_file->GetStream()->LastRead();
1245
1246 if(err == wxSTREAM_NO_ERROR)
1247 {
1248 if(*pcbRead < cb)
1249 {
1250 wxDELETE(m_file);
1251 m_protocolSink->ReportResult(S_OK, 0, NULL);
1252 }
1253 //As we are not eof there is more data
1254 return S_OK;
1255 }
1256 else if(err == wxSTREAM_EOF)
1257 {
1258 wxDELETE(m_file);
1259 m_protocolSink->ReportResult(S_OK, 0, NULL);
1260 //We are eof and so finished
1261 return S_OK;
1262 }
1263 else if(err == wxSTREAM_READ_ERROR)
1264 {
1265 wxDELETE(m_file);
1266 return INET_E_DOWNLOAD_FAILURE;
1267 }
0995b9dc
SL
1268 else
1269 {
1270 //Dummy return to surpress a compiler warning
1271 wxFAIL;
1272 return INET_E_DOWNLOAD_FAILURE;
1273 }
7d3f6b4d
SL
1274}
1275
9f194b9d
SL
1276BEGIN_IID_TABLE(ClassFactory)
1277 ADD_IID(Unknown)
1278 ADD_IID(ClassFactory)
1279END_IID_TABLE;
1280
1281IMPLEMENT_IUNKNOWN_METHODS(ClassFactory)
1282
7d3f6b4d
SL
1283HRESULT ClassFactory::CreateInstance(IUnknown* pUnkOuter, REFIID riid,
1284 void ** ppvObject)
1285{
60eabdbe 1286 if (pUnkOuter)
7d3f6b4d 1287 return CLASS_E_NOAGGREGATION;
29365629 1288 VirtualProtocol* vp = new VirtualProtocol(m_handler);
7d3f6b4d
SL
1289 vp->AddRef();
1290 HRESULT hr = vp->QueryInterface(riid, ppvObject);
1291 vp->Release();
1292 return hr;
1293
60eabdbe 1294}
7d3f6b4d
SL
1295
1296STDMETHODIMP ClassFactory::LockServer(BOOL fLock)
1297{
0995b9dc
SL
1298 wxUnusedVar(fLock);
1299 return S_OK;
7d3f6b4d
SL
1300}
1301
34326da7 1302wxIEContainer::wxIEContainer(wxWindow *parent, REFIID iid, IUnknown *pUnk,
accc94d5
SL
1303 DocHostUIHandler* uiHandler) :
1304 wxActiveXContainer(parent,iid,pUnk)
1305{
1306 m_uiHandler = uiHandler;
1307}
1308
1309wxIEContainer::~wxIEContainer()
1310{
1311}
1312
34326da7 1313bool wxIEContainer::QueryClientSiteInterface(REFIID iid, void **_interface,
accc94d5
SL
1314 const char *&desc)
1315{
1316 if (m_uiHandler && IsEqualIID(iid, wxIID_IDocHostUIHandler))
1317 {
1318 *_interface = (IUnknown *) (wxIDocHostUIHandler *) m_uiHandler;
1319 desc = "IDocHostUIHandler";
1320 return true;
1321 }
1322 return false;
1323}
1324
34326da7
SL
1325HRESULT DocHostUIHandler::ShowContextMenu(DWORD dwID, POINT *ppt,
1326 IUnknown *pcmdtReserved,
accc94d5
SL
1327 IDispatch *pdispReserved)
1328{
1329 wxUnusedVar(dwID);
1330 wxUnusedVar(ppt);
1331 wxUnusedVar(pcmdtReserved);
1332 wxUnusedVar(pdispReserved);
1333 return E_NOTIMPL;
1334}
1335
1336HRESULT DocHostUIHandler::GetHostInfo(DOCHOSTUIINFO *pInfo)
1337{
34326da7 1338 //don't show 3d border and enable themes.
accc94d5
SL
1339 pInfo->dwFlags = pInfo->dwFlags | DOCHOSTUIFLAG_NO3DBORDER | DOCHOSTUIFLAG_THEME;
1340 return S_OK;
1341}
1342
1343HRESULT DocHostUIHandler::ShowUI(DWORD dwID,
34326da7 1344 IOleInPlaceActiveObject *pActiveObject,
accc94d5
SL
1345 IOleCommandTarget *pCommandTarget,
1346 IOleInPlaceFrame *pFrame,
1347 IOleInPlaceUIWindow *pDoc)
1348{
1349 wxUnusedVar(dwID);
1350 wxUnusedVar(pActiveObject);
1351 wxUnusedVar(pCommandTarget);
1352 wxUnusedVar(pFrame);
1353 wxUnusedVar(pDoc);
1354 return S_FALSE;
1355}
1356
1357HRESULT DocHostUIHandler::HideUI(void)
1358{
1359 return E_NOTIMPL;
1360}
1361
1362HRESULT DocHostUIHandler::UpdateUI(void)
1363{
1364 return E_NOTIMPL;
1365}
1366
1367HRESULT DocHostUIHandler::EnableModeless(BOOL fEnable)
1368{
1369 wxUnusedVar(fEnable);
1370 return E_NOTIMPL;
1371}
1372
1373HRESULT DocHostUIHandler::OnDocWindowActivate(BOOL fActivate)
1374{
1375 wxUnusedVar(fActivate);
1376 return E_NOTIMPL;
1377}
1378
1379HRESULT DocHostUIHandler::OnFrameWindowActivate(BOOL fActivate)
1380{
1381 wxUnusedVar(fActivate);
1382 return E_NOTIMPL;
1383}
1384
34326da7 1385HRESULT DocHostUIHandler::ResizeBorder(LPCRECT prcBorder,
accc94d5
SL
1386 IOleInPlaceUIWindow *pUIWindow,
1387 BOOL fFrameWindow)
1388{
1389 wxUnusedVar(prcBorder);
1390 wxUnusedVar(pUIWindow);
1391 wxUnusedVar(fFrameWindow);
1392 return E_NOTIMPL;
1393}
1394
34326da7 1395HRESULT DocHostUIHandler::TranslateAccelerator(LPMSG lpMsg,
accc94d5
SL
1396 const GUID *pguidCmdGroup,
1397 DWORD nCmdID)
1398{
1399 if(lpMsg && lpMsg->message == WM_KEYDOWN)
1400 {
1401 //control is down?
1402 if((GetKeyState(VK_CONTROL) & 0x8000 ))
1403 {
e5f9b4ae
VZ
1404 //skip the accelerators used by the control
1405 switch(lpMsg->wParam)
accc94d5 1406 {
e5f9b4ae
VZ
1407 case 'F':
1408 case 'L':
1409 case 'N':
1410 case 'O':
1411 case 'P':
1412 return S_OK;
accc94d5
SL
1413 }
1414 }
1415 //skip F5
1416 if(lpMsg->wParam == VK_F5)
1417 {
1418 return S_OK;
1419 }
1420 }
1421
1422 wxUnusedVar(pguidCmdGroup);
1423 wxUnusedVar(nCmdID);
1424 return E_NOTIMPL;
1425}
1426
1427HRESULT DocHostUIHandler::GetOptionKeyPath(LPOLESTR *pchKey,DWORD dw)
1428{
1429 wxUnusedVar(pchKey);
1430 wxUnusedVar(dw);
1431 return E_NOTIMPL;
1432}
1433
1434HRESULT DocHostUIHandler::GetDropTarget(IDropTarget *pDropTarget,
1435 IDropTarget **ppDropTarget)
1436{
1437 wxUnusedVar(pDropTarget);
1438 wxUnusedVar(ppDropTarget);
1439 return E_NOTIMPL;
1440}
1441
1442HRESULT DocHostUIHandler::GetExternal(IDispatch **ppDispatch)
1443{
1444 wxUnusedVar(ppDispatch);
1445 return E_NOTIMPL;
1446}
1447
1448HRESULT DocHostUIHandler::TranslateUrl(DWORD dwTranslate,
1449 OLECHAR *pchURLIn,
1450 OLECHAR **ppchURLOut)
1451{
1452 wxUnusedVar(dwTranslate);
1453 wxUnusedVar(pchURLIn);
1454 wxUnusedVar(ppchURLOut);
1455 return E_NOTIMPL;
1456}
1457
1458HRESULT DocHostUIHandler::FilterDataObject(IDataObject *pDO, IDataObject **ppDORet)
1459{
1460 wxUnusedVar(pDO);
1461 wxUnusedVar(ppDORet);
1462 return E_NOTIMPL;
1463}
1464
1465BEGIN_IID_TABLE(DocHostUIHandler)
1466 ADD_IID(Unknown)
1467 ADD_RAW_IID(wxIID_IDocHostUIHandler)
1468END_IID_TABLE;
1469
1470IMPLEMENT_IUNKNOWN_METHODS(DocHostUIHandler)
1471
9d2f31db 1472#endif // wxUSE_WEBVIEW && wxUSE_WEBVIEW_IE