2 #include <wx/strconv.h>
5 #include <wx/listctrl.h>
6 #include <wx/mstream.h>
16 DEFINE_EVENT_TYPE(wxEVT_COMMAND_MSHTML_BEFORENAVIGATE2
);
17 DEFINE_EVENT_TYPE(wxEVT_COMMAND_MSHTML_NEWWINDOW2
);
18 DEFINE_EVENT_TYPE(wxEVT_COMMAND_MSHTML_DOCUMENTCOMPLETE
);
19 DEFINE_EVENT_TYPE(wxEVT_COMMAND_MSHTML_PROGRESSCHANGE
);
20 DEFINE_EVENT_TYPE(wxEVT_COMMAND_MSHTML_STATUSTEXTCHANGE
);
21 DEFINE_EVENT_TYPE(wxEVT_COMMAND_MSHTML_TITLECHANGE
);
23 IMPLEMENT_DYNAMIC_CLASS(wxMSHTMLEvent
, wxNotifyEvent
);
26 //////////////////////////////////////////////////////////////////////
27 BEGIN_EVENT_TABLE(wxIEHtmlWin
, wxActiveX
)
30 class FS_DWebBrowserEvents2
: public IDispatch
33 DECLARE_OLE_UNKNOWN(FS_DWebBrowserEvents2
);
39 FS_DWebBrowserEvents2(wxIEHtmlWin
*iewin
) : m_iewin(iewin
) {}
40 virtual ~FS_DWebBrowserEvents2()
45 STDMETHODIMP
GetIDsOfNames(REFIID r
, OLECHAR
** o
, unsigned int i
, LCID l
, DISPID
* d
)
50 STDMETHODIMP
GetTypeInfo(unsigned int i
, LCID l
, ITypeInfo
** t
)
55 STDMETHODIMP
GetTypeInfoCount(unsigned int* i
)
60 void Post(WXTYPE etype
, wxString text
, long l1
= 0, long l2
= 0)
62 if (! m_iewin
|| ! m_iewin
->GetParent())
66 event
.SetId(m_iewin
->GetId());
67 event
.SetEventType(etype
);
72 m_iewin
->GetParent()->AddPendingEvent(event
);
75 bool Process(WXTYPE etype
, wxString text
= wxEmptyString
, long l1
= 0, long l2
= 0)
77 if (! m_iewin
|| ! m_iewin
->GetParent())
81 event
.SetId(m_iewin
->GetId());
82 event
.SetEventType(etype
);
87 m_iewin
->GetParent()->ProcessEvent(event
);
89 return event
.IsAllowed();
92 wxString
GetStrArg(VARIANT
& v
)
94 VARTYPE vt
= v
.vt
& ~VT_BYREF
;
97 return GetStrArg(*v
.pvarVal
);
98 else if (vt
== VT_BSTR
)
101 return (v
.pbstrVal
? *v
.pbstrVal
: L
"");
106 return wxEmptyString
;
109 #define STR_ARG(arg) GetStrArg(pDispParams->rgvarg[arg])
111 #define LONG_ARG(arg)\
112 (pDispParams->rgvarg[arg].lVal)
115 STDMETHODIMP
Invoke(DISPID dispIdMember
, REFIID riid
, LCID lcid
,
116 WORD wFlags
, DISPPARAMS
* pDispParams
,
117 VARIANT
* pVarResult
, EXCEPINFO
* pExcepInfo
,
118 unsigned int * puArgErr
)
120 if (wFlags
& DISPATCH_PROPERTYGET
)
123 switch (dispIdMember
)
125 case DISPID_BEFORENAVIGATE2
:
126 if (Process(wxEVT_COMMAND_MSHTML_BEFORENAVIGATE2
, STR_ARG(5)))
127 *pDispParams
->rgvarg
->pboolVal
= VARIANT_FALSE
;
129 *pDispParams
->rgvarg
->pboolVal
= VARIANT_TRUE
;
132 case DISPID_NEWWINDOW2
:
133 if (Process(wxEVT_COMMAND_MSHTML_NEWWINDOW2
))
134 *pDispParams
->rgvarg
->pboolVal
= VARIANT_FALSE
;
136 *pDispParams
->rgvarg
->pboolVal
= VARIANT_TRUE
;
139 case DISPID_PROGRESSCHANGE
:
140 Post(wxEVT_COMMAND_MSHTML_PROGRESSCHANGE
, wxEmptyString
, LONG_ARG(1), LONG_ARG(0));
143 case DISPID_DOCUMENTCOMPLETE
:
144 Post(wxEVT_COMMAND_MSHTML_DOCUMENTCOMPLETE
, STR_ARG(0));
147 case DISPID_STATUSTEXTCHANGE
:
148 Post(wxEVT_COMMAND_MSHTML_STATUSTEXTCHANGE
, STR_ARG(0));
151 case DISPID_TITLECHANGE
:
152 Post(wxEVT_COMMAND_MSHTML_TITLECHANGE
, STR_ARG(0));
162 DEFINE_OLE_TABLE(FS_DWebBrowserEvents2
)
163 OLE_IINTERFACE(IUnknown
)
164 OLE_INTERFACE(DIID_DWebBrowserEvents2
, DWebBrowserEvents2
)
168 static const CLSID CLSID_MozillaBrowser
=
169 { 0x1339B54C, 0x3453, 0x11D2,
170 { 0x93, 0xB9, 0x00, 0x00,
171 0x00, 0x00, 0x00, 0x00 } };
174 //#define PROGID "Shell.Explorer"
175 #define PROGID CLSID_WebBrowser
176 //#define PROGID CLSID_MozillaBrowser
177 //#define PROGID CLSID_HTMLDocument
178 //#define PROGID "MSCAL.Calendar"
179 //#define PROGID "WordPad.Document.1"
180 //#define PROGID "SoftwareFX.ChartFX.20"
182 wxIEHtmlWin::wxIEHtmlWin(wxWindow
* parent
, wxWindowID id
,
186 const wxString
& name
) :
187 wxActiveX(parent
, PROGID
, id
, pos
, size
, style
, name
)
193 wxIEHtmlWin::~wxIEHtmlWin()
197 void wxIEHtmlWin::SetupBrowser()
201 // Get IWebBrowser2 Interface
202 hret
= m_webBrowser
.QueryInterface(IID_IWebBrowser2
, m_ActiveX
);
203 assert(SUCCEEDED(hret
));
205 // Web Browser Events
206 FS_DWebBrowserEvents2
*events
= new FS_DWebBrowserEvents2(this);
207 hret
= ConnectAdvise(DIID_DWebBrowserEvents2
, events
);
208 if (! SUCCEEDED(hret
))
212 m_webBrowser
->put_MenuBar(VARIANT_FALSE
);
213 m_webBrowser
->put_AddressBar(VARIANT_FALSE
);
214 m_webBrowser
->put_StatusBar(VARIANT_FALSE
);
215 m_webBrowser
->put_ToolBar(VARIANT_FALSE
);
217 m_webBrowser
->put_RegisterAsBrowser(VARIANT_TRUE
);
218 m_webBrowser
->put_RegisterAsDropTarget(VARIANT_TRUE
);
220 m_webBrowser
->Navigate( L
"about:blank", NULL
, NULL
, NULL
, NULL
);
224 void wxIEHtmlWin::SetEditMode(bool seton
)
226 m_bAmbientUserMode
= ! seton
;
227 AmbientPropertyChanged(DISPID_AMBIENT_USERMODE
);
230 bool wxIEHtmlWin::GetEditMode()
232 return ! m_bAmbientUserMode
;
236 void wxIEHtmlWin::SetCharset(wxString charset
)
239 IDispatch
*pDisp
= NULL
;
240 HRESULT hret
= m_webBrowser
->get_Document(&pDisp
);
241 wxAutoOleInterface
<IDispatch
> disp(pDisp
);
245 wxAutoOleInterface
<IHTMLDocument2
> doc(IID_IHTMLDocument2
, disp
);
247 doc
->put_charset((BSTR
) (const wchar_t *) charset
.wc_str(wxConvUTF8
));
248 //doc->put_charset((BSTR) wxConvUTF8.cMB2WC(charset).data());
253 class IStreamAdaptorBase
: public IStream
256 DECLARE_OLE_UNKNOWN(IStreamAdaptorBase
);
259 IStreamAdaptorBase() {}
260 virtual ~IStreamAdaptorBase() {}
263 HRESULT STDMETHODCALLTYPE
Read(void __RPC_FAR
*pv
, ULONG cb
, ULONG __RPC_FAR
*pcbRead
) = 0;
264 HRESULT STDMETHODCALLTYPE
Write(const void __RPC_FAR
*pv
, ULONG cb
, ULONG __RPC_FAR
*pcbWritten
) {return E_NOTIMPL
;}
267 HRESULT STDMETHODCALLTYPE
Seek(LARGE_INTEGER dlibMove
, DWORD dwOrigin
, ULARGE_INTEGER __RPC_FAR
*plibNewPosition
) {return E_NOTIMPL
;}
268 HRESULT STDMETHODCALLTYPE
SetSize(ULARGE_INTEGER libNewSize
) {return E_NOTIMPL
;}
269 HRESULT STDMETHODCALLTYPE
CopyTo(IStream __RPC_FAR
*pstm
, ULARGE_INTEGER cb
, ULARGE_INTEGER __RPC_FAR
*pcbRead
, ULARGE_INTEGER __RPC_FAR
*pcbWritten
) {return E_NOTIMPL
;}
270 HRESULT STDMETHODCALLTYPE
Commit(DWORD grfCommitFlags
) {return E_NOTIMPL
;}
271 HRESULT STDMETHODCALLTYPE
Revert(void) {return E_NOTIMPL
;}
272 HRESULT STDMETHODCALLTYPE
LockRegion(ULARGE_INTEGER libOffset
, ULARGE_INTEGER cb
, DWORD dwLockType
) {return E_NOTIMPL
;}
273 HRESULT STDMETHODCALLTYPE
UnlockRegion(ULARGE_INTEGER libOffset
, ULARGE_INTEGER cb
, DWORD dwLockType
) {return E_NOTIMPL
;}
274 HRESULT STDMETHODCALLTYPE
Stat(STATSTG __RPC_FAR
*pstatstg
, DWORD grfStatFlag
) {return E_NOTIMPL
;}
275 HRESULT STDMETHODCALLTYPE
Clone(IStream __RPC_FAR
*__RPC_FAR
*ppstm
) {return E_NOTIMPL
;}
278 DEFINE_OLE_TABLE(IStreamAdaptorBase
)
279 OLE_IINTERFACE(IUnknown
)
280 OLE_IINTERFACE(ISequentialStream
)
281 OLE_IINTERFACE(IStream
)
284 class IStreamAdaptor
: public IStreamAdaptorBase
291 IStreamAdaptor(istream
*is
) : IStreamAdaptorBase(), m_is(is
)
293 wxASSERT(m_is
!= NULL
);
301 HRESULT STDMETHODCALLTYPE
Read(void __RPC_FAR
*pv
, ULONG cb
, ULONG __RPC_FAR
*pcbRead
)
303 m_is
->read((char *) pv
, cb
);
305 *pcbRead
= m_is
->gcount();
311 class IwxStreamAdaptor
: public IStreamAdaptorBase
318 IwxStreamAdaptor(wxInputStream
*is
) : IStreamAdaptorBase(), m_is(is
)
320 wxASSERT(m_is
!= NULL
);
328 HRESULT STDMETHODCALLTYPE
Read(void __RPC_FAR
*pv
, ULONG cb
, ULONG __RPC_FAR
*pcbRead
)
330 m_is
->Read((char *) pv
, cb
);
332 *pcbRead
= m_is
->LastRead();
338 void wxIEHtmlWin::LoadUrl(const wxString
& url
)
340 VARIANTARG navFlag
, targetFrame
, postData
, headers
;
341 navFlag
.vt
= VT_EMPTY
;
343 navFlag
.iVal
= navNoReadFromCache
;
344 targetFrame
.vt
= VT_EMPTY
;
345 postData
.vt
= VT_EMPTY
;
346 headers
.vt
= VT_EMPTY
;
349 hret
= m_webBrowser
->Navigate((BSTR
) (const wchar_t *) url
.wc_str(wxConvUTF8
),
350 &navFlag
, &targetFrame
, &postData
, &headers
);
353 class wxOwnedMemInputStream
: public wxMemoryInputStream
358 wxOwnedMemInputStream(char *data
, size_t len
) :
359 wxMemoryInputStream(data
, len
), m_data(data
)
361 ~wxOwnedMemInputStream()
367 bool wxIEHtmlWin::LoadString(wxString html
)
370 size_t len
= html
.length();
374 data
= (char *) malloc(len
);
375 memcpy(data
, html
.c_str(), len
);
376 return LoadStream(new wxOwnedMemInputStream(data
, len
));
379 bool wxIEHtmlWin::LoadStream(IStreamAdaptorBase
*pstrm
)
381 wxAutoOleInterface
<IStream
> strm(pstrm
);
383 // Document Interface
384 IDispatch
*pDisp
= NULL
;
385 HRESULT hret
= m_webBrowser
->get_Document(&pDisp
);
388 wxAutoOleInterface
<IDispatch
> disp(pDisp
);
391 // get IPersistStreamInit
392 wxAutoOleInterface
<IPersistStreamInit
>
393 pPersistStreamInit(IID_IPersistStreamInit
, disp
);
395 if (pPersistStreamInit
.Ok())
397 HRESULT hr
= pPersistStreamInit
->InitNew();
399 hr
= pPersistStreamInit
->Load(strm
);
401 return SUCCEEDED(hr
);
407 bool wxIEHtmlWin::LoadStream(istream
*is
)
409 // wrap reference around stream
410 IStreamAdaptor
*pstrm
= new IStreamAdaptor(is
);
413 return LoadStream(pstrm
);
416 bool wxIEHtmlWin::LoadStream(wxInputStream
*is
)
418 // wrap reference around stream
419 IwxStreamAdaptor
*pstrm
= new IwxStreamAdaptor(is
);
422 return LoadStream(pstrm
);
426 bool wxIEHtmlWin::GoBack()
429 hret
= m_webBrowser
->GoBack();
433 bool wxIEHtmlWin::GoForward()
436 hret
= m_webBrowser
->GoForward();
440 bool wxIEHtmlWin::GoHome()
443 hret
= m_webBrowser
->GoHome();
447 bool wxIEHtmlWin::GoSearch()
450 hret
= m_webBrowser
->GoSearch();
454 bool wxIEHtmlWin::Refresh(wxIEHtmlRefreshLevel level
)
460 levelArg
.iVal
= level
;
461 hret
= m_webBrowser
->Refresh2(&levelArg
);
465 bool wxIEHtmlWin::Stop()
468 hret
= m_webBrowser
->Stop();
473 ///////////////////////////////////////////////////////////////////////////////
475 static wxAutoOleInterface
<IHTMLSelectionObject
> GetSelObject(IOleObject
*oleObject
)
477 // Query for IWebBrowser interface
478 wxAutoOleInterface
<IWebBrowser2
> wb(IID_IWebBrowser2
, oleObject
);
480 return wxAutoOleInterface
<IHTMLSelectionObject
>();
482 IDispatch
*iDisp
= NULL
;
483 HRESULT hr
= wb
->get_Document(&iDisp
);
485 return wxAutoOleInterface
<IHTMLSelectionObject
>();
487 // Query for Document Interface
488 wxAutoOleInterface
<IHTMLDocument2
> hd(IID_IHTMLDocument2
, iDisp
);
492 return wxAutoOleInterface
<IHTMLSelectionObject
>();
494 IHTMLSelectionObject
*_so
= NULL
;
495 hr
= hd
->get_selection(&_so
);
497 // take ownership of selection object
498 wxAutoOleInterface
<IHTMLSelectionObject
> so(_so
);
503 static wxAutoOleInterface
<IHTMLTxtRange
> GetSelRange(IOleObject
*oleObject
)
505 wxAutoOleInterface
<IHTMLTxtRange
> tr
;
507 wxAutoOleInterface
<IHTMLSelectionObject
> so(GetSelObject(oleObject
));
511 IDispatch
*iDisp
= NULL
;
512 HRESULT hr
= so
->createRange(&iDisp
);
516 // Query for IHTMLTxtRange interface
517 tr
.QueryInterface(IID_IHTMLTxtRange
, iDisp
);
523 wxString
wxIEHtmlWin::GetStringSelection(bool asHTML
)
525 wxAutoOleInterface
<IHTMLTxtRange
> tr(GetSelRange(m_oleObject
));
527 return wxEmptyString
;
533 hr
= tr
->get_htmlText(&text
);
535 hr
= tr
->get_text(&text
);
537 return wxEmptyString
;
545 wxString
wxIEHtmlWin::GetText(bool asHTML
)
547 if (! m_webBrowser
.Ok())
548 return wxEmptyString
;
550 // get document dispatch interface
551 IDispatch
*iDisp
= NULL
;
552 HRESULT hr
= m_webBrowser
->get_Document(&iDisp
);
554 return wxEmptyString
;
556 // Query for Document Interface
557 wxAutoOleInterface
<IHTMLDocument2
> hd(IID_IHTMLDocument2
, iDisp
);
561 return wxEmptyString
;
564 IHTMLElement
*_body
= NULL
;
565 hd
->get_body(&_body
);
567 return wxEmptyString
;
568 wxAutoOleInterface
<IHTMLElement
> body(_body
);
575 hr
= body
->get_innerHTML(&text
);
577 hr
= body
->get_innerText(&text
);
579 return wxEmptyString
;