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