]> git.saurik.com Git - wxWidgets.git/blame - wxPython/contrib/iewin/IEHtmlWin.cpp
compilation error fix (trailing comma in an enum)
[wxWidgets.git] / wxPython / contrib / iewin / IEHtmlWin.cpp
CommitLineData
c731eb47
RD
1#include "IEHtmlWin.h"
2#include <wx/strconv.h>
3#include <wx/event.h>
4#include <wx/listctrl.h>
5#include <oleidl.h>
6#include <winerror.h>
7#include <exdispid.h>
8#include <exdisp.h>
9#include <olectl.h>
10#include <Mshtml.h>
11#include <sstream>
12using namespace std;
13
14DEFINE_EVENT_TYPE(wxEVT_COMMAND_MSHTML_BEFORENAVIGATE2);
15DEFINE_EVENT_TYPE(wxEVT_COMMAND_MSHTML_NEWWINDOW2);
16DEFINE_EVENT_TYPE(wxEVT_COMMAND_MSHTML_DOCUMENTCOMPLETE);
17DEFINE_EVENT_TYPE(wxEVT_COMMAND_MSHTML_PROGRESSCHANGE);
18DEFINE_EVENT_TYPE(wxEVT_COMMAND_MSHTML_STATUSTEXTCHANGE);
19DEFINE_EVENT_TYPE(wxEVT_COMMAND_MSHTML_TITLECHANGE);
20
21IMPLEMENT_DYNAMIC_CLASS(wxMSHTMLEvent, wxNotifyEvent);
22
23
24//////////////////////////////////////////////////////////////////////
25BEGIN_EVENT_TABLE(wxIEHtmlWin, wxActiveX)
26END_EVENT_TABLE()
27
28class FS_DWebBrowserEvents2 : public IDispatch
29{
30private:
31 DECLARE_OLE_UNKNOWN(FS_DWebBrowserEvents2);
32
33
34 wxIEHtmlWin *m_iewin;
35
36public:
37 FS_DWebBrowserEvents2(wxIEHtmlWin *iewin) : m_iewin(iewin) {}
38 ~FS_DWebBrowserEvents2()
39 {
40 }
41
42 //IDispatch
43 STDMETHODIMP GetIDsOfNames(REFIID r, OLECHAR** o, unsigned int i, LCID l, DISPID* d)
44 {
45 return E_NOTIMPL;
46 };
47
48 STDMETHODIMP GetTypeInfo(unsigned int i, LCID l, ITypeInfo** t)
49 {
50 return E_NOTIMPL;
51 };
52
53 STDMETHODIMP GetTypeInfoCount(unsigned int* i)
54 {
55 return E_NOTIMPL;
56 };
57
58 void Post(WXTYPE etype, wxString text, long l1 = 0, long l2 = 0)
59 {
60 if (! m_iewin || ! m_iewin->GetParent())
61 return;
62
63 wxMSHTMLEvent event;
64 event.SetId(m_iewin->GetId());
65 event.SetEventType(etype);
66 event.m_text1 = text;
67 event.m_long1 = l1;
68 event.m_long2 = l2;
69
70 m_iewin->GetParent()->AddPendingEvent(event);
71 };
72
73 bool Process(WXTYPE etype, wxString text = "", long l1 = 0, long l2 = 0)
74 {
75 if (! m_iewin || ! m_iewin->GetParent())
76 return true;
77
78 wxMSHTMLEvent event;
79 event.SetId(m_iewin->GetId());
80 event.SetEventType(etype);
81 event.m_text1 = text;
82 event.m_long1 = l1;
83 event.m_long2 = l2;
84
85 m_iewin->GetParent()->ProcessEvent(event);
86
87 return event.IsAllowed();
88 };
89
90 wxString GetStrArg(VARIANT& v)
91 {
92 VARTYPE vt = v.vt & ~VT_BYREF;
93
94 if (vt == VT_VARIANT)
95 return GetStrArg(*v.pvarVal);
96 else if (vt == VT_BSTR)
97 {
98 if (v.vt & VT_BYREF)
99 return (v.pbstrVal ? *v.pbstrVal : L"");
100 else
101 return v.bstrVal;
102 }
103 else
104 return "";
105 };
106
107#define STR_ARG(arg) GetStrArg(pDispParams->rgvarg[arg])
108
109#define LONG_ARG(arg)\
110 (pDispParams->rgvarg[arg].lVal)
111
112
113 STDMETHODIMP Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
114 WORD wFlags, DISPPARAMS * pDispParams,
115 VARIANT * pVarResult, EXCEPINFO * pExcepInfo,
116 unsigned int * puArgErr)
117 {
118 if (wFlags & DISPATCH_PROPERTYGET)
119 return E_NOTIMPL;
120
121 switch (dispIdMember)
122 {
123 case DISPID_BEFORENAVIGATE2:
124 if (Process(wxEVT_COMMAND_MSHTML_BEFORENAVIGATE2, STR_ARG(5)))
125 *pDispParams->rgvarg->pboolVal = VARIANT_FALSE;
126 else
127 *pDispParams->rgvarg->pboolVal = VARIANT_TRUE;
128 break;
129
130 case DISPID_NEWWINDOW2:
131 if (Process(wxEVT_COMMAND_MSHTML_NEWWINDOW2))
132 *pDispParams->rgvarg->pboolVal = VARIANT_FALSE;
133 else
134 *pDispParams->rgvarg->pboolVal = VARIANT_TRUE;
135 break;
136
137 case DISPID_PROGRESSCHANGE:
138 Post(wxEVT_COMMAND_MSHTML_PROGRESSCHANGE, "", LONG_ARG(1), LONG_ARG(0));
139 break;
140
141 case DISPID_DOCUMENTCOMPLETE:
142 Post(wxEVT_COMMAND_MSHTML_DOCUMENTCOMPLETE, STR_ARG(0));
143 break;
144
145 case DISPID_STATUSTEXTCHANGE:
146 Post(wxEVT_COMMAND_MSHTML_STATUSTEXTCHANGE, STR_ARG(0));
147 break;
148
149 case DISPID_TITLECHANGE:
150 Post(wxEVT_COMMAND_MSHTML_TITLECHANGE, STR_ARG(0));
151 break;
152 }
153
154 return S_OK;
155 }
156};
157
158#undef STR_ARG
159
160DEFINE_OLE_TABLE(FS_DWebBrowserEvents2)
161 OLE_IINTERFACE(IUnknown)
162 OLE_INTERFACE(DIID_DWebBrowserEvents2, DWebBrowserEvents2)
163END_OLE_TABLE;
164
165
166static const CLSID CLSID_MozillaBrowser =
167{ 0x1339B54C, 0x3453, 0x11D2,
168 { 0x93, 0xB9, 0x00, 0x00,
169 0x00, 0x00, 0x00, 0x00 } };
170
171
172//#define PROGID L"Shell.Explorer"
173#define PROGID CLSID_WebBrowser
174//#define PROGID CLSID_HTMLDocument
175//#define PROGID L"MSCAL.Calendar"
176//#define PROGID L"WordPad.Document.1"
177//#define PROGID L"SoftwareFX.ChartFX.20"
178
179
180wxIEHtmlWin::wxIEHtmlWin(wxWindow * parent, wxWindowID id)
181 : wxActiveX(parent, PROGID, id)
182{
183 SetupBrowser();
184}
185
186wxIEHtmlWin::~wxIEHtmlWin()
187{
188}
189
190void wxIEHtmlWin::SetupBrowser()
191{
192 HRESULT hret;
193
194 // Get IWebBrowser2 Interface
195 hret = m_webBrowser.QueryInterface(IID_IWebBrowser2, m_ActiveX);
196 assert(SUCCEEDED(hret));
197
198 // Web Browser Events
199 FS_DWebBrowserEvents2 *events = new FS_DWebBrowserEvents2(this);
200 hret = ConnectAdvise(DIID_DWebBrowserEvents2, events);
201 if (! SUCCEEDED(hret))
202 delete events;
203
204 // web browser setup
205 m_webBrowser->put_MenuBar(VARIANT_FALSE);
206 m_webBrowser->put_AddressBar(VARIANT_FALSE);
207 m_webBrowser->put_StatusBar(VARIANT_FALSE);
208 m_webBrowser->put_ToolBar(VARIANT_FALSE);
209
210 m_webBrowser->put_RegisterAsBrowser(VARIANT_TRUE);
211 m_webBrowser->put_RegisterAsDropTarget(VARIANT_TRUE);
212
213 m_webBrowser->Navigate( L"about:blank", NULL, NULL, NULL, NULL );
214}
215
216
217void wxIEHtmlWin::SetEditMode(bool seton)
218{
219 m_bAmbientUserMode = ! seton;
220 AmbientPropertyChanged(DISPID_AMBIENT_USERMODE);
221};
222
223bool wxIEHtmlWin::GetEditMode()
224{
225 return ! m_bAmbientUserMode;
226};
227
228
229void wxIEHtmlWin::SetCharset(wxString charset)
230{
231 // HTML Document ?
232 IDispatch *pDisp = NULL;
233 HRESULT hret = m_webBrowser->get_Document(&pDisp);
234 wxAutoOleInterface<IDispatch> disp(pDisp);
235
236 if (disp.Ok())
237 {
238 wxAutoOleInterface<IHTMLDocument2> doc(IID_IHTMLDocument2, disp);
239 if (doc.Ok())
240 doc->put_charset((BSTR) wxConvUTF8.cMB2WC(charset).data());
241 };
242};
243
244
245class IStreamAdaptorBase : public IStream
246{
247private:
248 DECLARE_OLE_UNKNOWN(IStreamAdaptorBase);
249
250public:
251 IStreamAdaptorBase() {}
252 virtual ~IStreamAdaptorBase() {}
253
254 // ISequentialStream
255 HRESULT STDMETHODCALLTYPE Read(void __RPC_FAR *pv, ULONG cb, ULONG __RPC_FAR *pcbRead) = 0;
256 HRESULT STDMETHODCALLTYPE Write(const void __RPC_FAR *pv, ULONG cb, ULONG __RPC_FAR *pcbWritten) {return E_NOTIMPL;}
257
258 // IStream
259 HRESULT STDMETHODCALLTYPE Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER __RPC_FAR *plibNewPosition) {return E_NOTIMPL;}
260 HRESULT STDMETHODCALLTYPE SetSize(ULARGE_INTEGER libNewSize) {return E_NOTIMPL;}
261 HRESULT STDMETHODCALLTYPE CopyTo(IStream __RPC_FAR *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER __RPC_FAR *pcbRead, ULARGE_INTEGER __RPC_FAR *pcbWritten) {return E_NOTIMPL;}
262 HRESULT STDMETHODCALLTYPE Commit(DWORD grfCommitFlags) {return E_NOTIMPL;}
263 HRESULT STDMETHODCALLTYPE Revert(void) {return E_NOTIMPL;}
264 HRESULT STDMETHODCALLTYPE LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) {return E_NOTIMPL;}
265 HRESULT STDMETHODCALLTYPE UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) {return E_NOTIMPL;}
266 HRESULT STDMETHODCALLTYPE Stat(STATSTG __RPC_FAR *pstatstg, DWORD grfStatFlag) {return E_NOTIMPL;}
267 HRESULT STDMETHODCALLTYPE Clone(IStream __RPC_FAR *__RPC_FAR *ppstm) {return E_NOTIMPL;}
268};
269
270DEFINE_OLE_TABLE(IStreamAdaptorBase)
271 OLE_IINTERFACE(IUnknown)
272 OLE_IINTERFACE(ISequentialStream)
273 OLE_IINTERFACE(IStream)
274END_OLE_TABLE;
275
276class IStreamAdaptor : public IStreamAdaptorBase
277{
278private:
279 istream *m_is;
280
281public:
282
283 IStreamAdaptor(istream *is) : IStreamAdaptorBase(), m_is(is)
284 {
285 wxASSERT(m_is != NULL);
286 }
287 ~IStreamAdaptor()
288 {
289 delete m_is;
290 }
291
292 // ISequentialStream
293 HRESULT STDMETHODCALLTYPE Read(void __RPC_FAR *pv, ULONG cb, ULONG __RPC_FAR *pcbRead)
294 {
295 m_is->read((char *) pv, cb);
296 if (pcbRead)
297 *pcbRead = m_is->gcount();
298
299 return S_OK;
300 };
301};
302
303
304void wxIEHtmlWin::LoadUrl(const wxString& url)
305{
306 VARIANTARG navFlag, targetFrame, postData, headers;
307 navFlag.vt = VT_EMPTY;
308 navFlag.vt = VT_I2;
309 navFlag.iVal = navNoReadFromCache;
310 targetFrame.vt = VT_EMPTY;
311 postData.vt = VT_EMPTY;
312 headers.vt = VT_EMPTY;
313
314 HRESULT hret = 0;
315 hret = m_webBrowser->Navigate((BSTR) wxConvUTF8.cMB2WC(url).data(),
316 &navFlag, &targetFrame, &postData, &headers);
317};
318
319
320bool wxIEHtmlWin::LoadString(wxString html)
321{
322 string s = html.c_str();
323 istringstream *is = new istringstream(s);
324 return LoadStream(is);
325};
326
327bool wxIEHtmlWin::LoadStream(istream *is)
328{
329 // wrap refernce around stream
330 IStreamAdaptor *pstrm = new IStreamAdaptor(is);
331 pstrm->AddRef();
332
333 wxAutoOleInterface<IStream> strm(pstrm);
334
335 // Document Interface
336 IDispatch *pDisp = NULL;
337 HRESULT hret = m_webBrowser->get_Document(&pDisp);
338 if (! pDisp)
339 return false;
340 wxAutoOleInterface<IDispatch> disp(pDisp);
341
342
343 // get IPersistStreamInit
344 wxAutoOleInterface<IPersistStreamInit>
345 pPersistStreamInit(IID_IPersistStreamInit, disp);
346
347 if (pPersistStreamInit.Ok())
348 {
349 HRESULT hr = pPersistStreamInit->InitNew();
350 if (SUCCEEDED(hr))
351 hr = pPersistStreamInit->Load(strm);
352 };
353
354 return true;
355};
356
357bool wxIEHtmlWin::GoBack()
358{
359 HRESULT hret = 0;
360 hret = m_webBrowser->GoBack();
361 return hret == S_OK;
362}
363
364bool wxIEHtmlWin::GoForward()
365{
366 HRESULT hret = 0;
367 hret = m_webBrowser->GoForward();
368 return hret == S_OK;
369}
370
371bool wxIEHtmlWin::GoHome()
372{
373 HRESULT hret = 0;
374 hret = m_webBrowser->GoHome();
375 return hret == S_OK;
376}
377
378bool wxIEHtmlWin::GoSearch()
379{
380 HRESULT hret = 0;
381 hret = m_webBrowser->GoSearch();
382 return hret == S_OK;
383}
384
385bool wxIEHtmlWin::Refresh(wxIEHtmlRefreshLevel level)
386{
387 VARIANTARG levelArg;
388 HRESULT hret = 0;
389
390 levelArg.vt = VT_I2;
391 levelArg.iVal = level;
392 hret = m_webBrowser->Refresh2(&levelArg);
393 return hret == S_OK;
394}
395
396bool wxIEHtmlWin::Stop()
397{
398 HRESULT hret = 0;
399 hret = m_webBrowser->Stop();
400 return hret == S_OK;
401}
402
403///////////////////////////////////////////////////////////////////////////////
404
405static wxAutoOleInterface<IHTMLSelectionObject> GetSelObject(IOleObject *oleObject)
406{
407 // Query for IWebBrowser interface
408 wxAutoOleInterface<IWebBrowser2> wb(IID_IWebBrowser2, oleObject);
409 if (! wb.Ok())
410 return wxAutoOleInterface<IHTMLSelectionObject>();
411
412 IDispatch *iDisp = NULL;
413 HRESULT hr = wb->get_Document(&iDisp);
414 if (hr != S_OK)
415 return wxAutoOleInterface<IHTMLSelectionObject>();
416
417 // Query for Document Interface
418 wxAutoOleInterface<IHTMLDocument2> hd(IID_IHTMLDocument2, iDisp);
419 iDisp->Release();
420
421 if (! hd.Ok())
422 return wxAutoOleInterface<IHTMLSelectionObject>();
423
424 IHTMLSelectionObject *_so = NULL;
425 hr = hd->get_selection(&_so);
426
427 // take ownership of selection object
428 wxAutoOleInterface<IHTMLSelectionObject> so(_so);
429
430 return so;
431};
432
433static wxAutoOleInterface<IHTMLTxtRange> GetSelRange(IOleObject *oleObject)
434{
435 wxAutoOleInterface<IHTMLTxtRange> tr;
436
437 wxAutoOleInterface<IHTMLSelectionObject> so(GetSelObject(oleObject));
438 if (! so)
439 return tr;
440
441 IDispatch *iDisp = NULL;
442 HRESULT hr = so->createRange(&iDisp);
443 if (hr != S_OK)
444 return tr;
445
446 // Query for IHTMLTxtRange interface
447 tr.QueryInterface(IID_IHTMLTxtRange, iDisp);
448 iDisp->Release();
449 return tr;
450};
451
452
453wxString wxIEHtmlWin::GetStringSelection(bool asHTML)
454{
455 wxAutoOleInterface<IHTMLTxtRange> tr(GetSelRange(m_oleObject));
456 if (! tr)
457 return "";
458
459 BSTR text = NULL;
460 HRESULT hr = E_FAIL;
461
462 if (asHTML)
463 hr = tr->get_htmlText(&text);
464 else
465 hr = tr->get_text(&text);
466 if (hr != S_OK)
467 return "";
468
469 wxString s = text;
470 SysFreeString(text);
471
472 return s;
473};
474
475wxString wxIEHtmlWin::GetText(bool asHTML)
476{
477 if (! m_webBrowser.Ok())
478 return "";
479
480 // get document dispatch interface
481 IDispatch *iDisp = NULL;
482 HRESULT hr = m_webBrowser->get_Document(&iDisp);
483 if (hr != S_OK)
484 return "";
485
486 // Query for Document Interface
487 wxAutoOleInterface<IHTMLDocument2> hd(IID_IHTMLDocument2, iDisp);
488 iDisp->Release();
489
490 if (! hd.Ok())
491 return "";
492
493 // get body element
494 IHTMLElement *_body = NULL;
495 hd->get_body(&_body);
496 if (! _body)
497 return "";
498 wxAutoOleInterface<IHTMLElement> body(_body);
499
500 // get inner text
501 BSTR text = NULL;
502 hr = E_FAIL;
503
504 if (asHTML)
505 hr = body->get_innerHTML(&text);
506 else
507 hr = body->get_innerText(&text);
508 if (hr != S_OK)
509 return "";
510
511 wxString s = text;
512 SysFreeString(text);
513
514 return s;
515};