2
wxActiveX Library Licence, Version 3
3
====================================
5
Copyright (C) 2003 Lindsay Mathieson [, ...]
7
Everyone is permitted to copy and distribute verbatim copies
8
of this licence document, but changing it is not allowed.
10
wxActiveX LIBRARY LICENCE
11
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
13
This library is free software; you can redistribute it and/or modify it
14
under the terms of the GNU Library General Public Licence as published by
15
the Free Software Foundation; either version 2 of the Licence, or (at
16
your option) any later version.
18
This library is distributed in the hope that it will be useful, but
19
WITHOUT ANY WARRANTY; without even the implied warranty of
20
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library
21
General Public Licence for more details.
23
You should have received a copy of the GNU Library General Public Licence
24
along with this software, usually in a file named COPYING.LIB. If not,
25
write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
26
Boston, MA 02111-1307 USA.
30
1. As a special exception, the copyright holders of this library give
31
permission for additional uses of the text contained in this release of
32
the library as licenced under the wxActiveX Library Licence, applying
33
either version 3 of the Licence, or (at your option) any later version of
34
the Licence as published by the copyright holders of version 3 of the
37
2. The exception is that you may use, copy, link, modify and distribute
38
under the user's own terms, binary object code versions of works based
41
3. If you copy code from files distributed under the terms of the GNU
42
General Public Licence or the GNU Library General Public Licence into a
43
copy of this library, as this licence permits, the exception does not
44
apply to the code that you add in this way. To avoid misleading anyone as
45
to the status of such modified files, you must delete this exception
46
notice from such code and/or adjust the licensing conditions notice
49
4. If you write modifications of your own for this library, it is your
50
choice whether to permit this exception to apply to your modifications.
51
If you do not wish that, you must delete the exception notice from such
52
code and/or adjust the licensing conditions notice accordingly.
56
\brief implements wxActiveX window class and OLE tools
61
#pragma warning( disable : 4101 4786)
62
#pragma warning( disable : 4786)
67
#include <wx/variant.h>
68
#include <wx/datetime.h>
77
/// \brief wxActiveX Namespace for stuff I want to keep out of other tools way.
78
namespace NS_wxActiveX
81
/// specific to wxActiveX, for creating
82
/// case insenstive maps etc
85
bool operator()(const wxString& x, const wxString& y) const
87
return x.CmpNoCase(y) < 0;
93
//////////////////////////////////////////
94
/// Template class for smart interface handling.
95
/// - Automatically dereferences ole interfaces
96
/// - Smart Copy Semantics
97
/// - Can Create Interfaces
98
/// - Can query for other interfaces
99
template <class I> class wxAutoOleInterface
105
/// takes ownership of an existing interface
106
/// Assumed to already have a AddRef() applied
107
explicit wxAutoOleInterface(I *pInterface = NULL) : m_interface(pInterface) {}
109
/// queries for an interface
110
wxAutoOleInterface(REFIID riid, IUnknown *pUnk) : m_interface(NULL)
112
QueryInterface(riid, pUnk);
114
/// queries for an interface
115
wxAutoOleInterface(REFIID riid, IDispatch *pDispatch) : m_interface(NULL)
117
QueryInterface(riid, pDispatch);
120
/// Creates an Interface
121
wxAutoOleInterface(REFCLSID clsid, REFIID riid) : m_interface(NULL)
123
CreateInstance(clsid, riid);
127
wxAutoOleInterface(const wxAutoOleInterface<I>& ti) : m_interface(NULL)
132
/// assignment operator
133
wxAutoOleInterface<I>& operator = (const wxAutoOleInterface<I>& ti)
136
ti.m_interface->AddRef();
138
m_interface = ti.m_interface;
142
/// takes ownership of an existing interface
143
/// Assumed to already have a AddRef() applied
144
wxAutoOleInterface<I>& operator = (I *&ti)
152
~wxAutoOleInterface()
158
/// Releases interface (i.e decrements refCount)
162
m_interface->Release();
166
/// queries for an interface
167
HRESULT QueryInterface(REFIID riid, IUnknown *pUnk)
170
wxCHECK(pUnk != NULL, -1);
171
return pUnk->QueryInterface(riid, (void **) &m_interface);
174
/// Create a Interface instance
175
HRESULT CreateInstance(REFCLSID clsid, REFIID riid)
178
return CoCreateInstance(clsid, NULL, CLSCTX_ALL, riid, (void **) &m_interface);
182
/// returns the interface pointer
183
inline operator I *() const {return m_interface;}
185
/// returns the dereferenced interface pointer
186
inline I* operator ->() {return m_interface;}
187
/// returns a pointer to the interface pointer
188
inline I** GetRef() {return &m_interface;}
189
/// returns true if we have a valid interface pointer
190
inline bool Ok() const {return m_interface != NULL;}
194
/// \brief Converts a std HRESULT to its error code.
195
/// Hardcoded, by no means a definitive list.
196
wxString OLEHResultToString(HRESULT hr);
197
/// \brief Returns the string description of a IID.
198
/// Hardcoded, by no means a definitive list.
199
wxString GetIIDName(REFIID riid);
201
//#define __WXOLEDEBUG
205
#define WXOLE_TRACE(str) {OutputDebugString(str);OutputDebugString("\r\n");}
206
#define WXOLE_TRACEOUT(stuff)\
209
os << stuff << "\r\n";\
210
WXOLE_TRACE(os.mb_str());\
213
#define WXOLE_WARN(__hr,msg)\
217
wxString s = "*** ";\
219
s += " : "+ OLEHResultToString(__hr);\
220
WXOLE_TRACE(s.c_str());\
224
#define WXOLE_TRACE(str)
225
#define WXOLE_TRACEOUT(stuff)
226
#define WXOLE_WARN(_proc,msg) {_proc;}
232
static IMalloc *GetIMalloc();
238
#define DECLARE_OLE_UNKNOWN(cls)\
244
TAutoInitInt() : l(0) {}\
246
TAutoInitInt refCount, lockCount;\
248
static void _GetInterface(cls *self, REFIID iid, void **_interface, const char *&desc);\
251
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void ** ppvObject);\
252
ULONG STDMETHODCALLTYPE AddRef();\
253
ULONG STDMETHODCALLTYPE Release();\
254
ULONG STDMETHODCALLTYPE AddLock();\
255
ULONG STDMETHODCALLTYPE ReleaseLock()
257
#define DEFINE_OLE_TABLE(cls)\
258
LONG cls::GetRefCount() {return refCount.l;}\
259
HRESULT STDMETHODCALLTYPE cls::QueryInterface(REFIID iid, void ** ppvObject)\
263
WXOLE_TRACE("*** NULL POINTER ***");\
266
const char *desc = NULL;\
267
cls::_GetInterface(this, iid, ppvObject, desc);\
270
WXOLE_TRACEOUT("<" << GetIIDName(iid).c_str() << "> Not Found");\
271
return E_NOINTERFACE;\
273
WXOLE_TRACEOUT("QI : <" << desc <<">");\
274
((IUnknown * )(*ppvObject))->AddRef();\
277
ULONG STDMETHODCALLTYPE cls::AddRef()\
279
WXOLE_TRACEOUT(# cls << "::Add ref(" << refCount.l << ")");\
280
InterlockedIncrement(&refCount.l);\
283
ULONG STDMETHODCALLTYPE cls::Release()\
287
InterlockedDecrement(&refCount.l);\
288
WXOLE_TRACEOUT(# cls << "::Del ref(" << refCount.l << ")");\
289
if (refCount.l == 0)\
299
ULONG STDMETHODCALLTYPE cls::AddLock()\
301
WXOLE_TRACEOUT(# cls << "::Add Lock(" << lockCount.l << ")");\
302
InterlockedIncrement(&lockCount.l);\
305
ULONG STDMETHODCALLTYPE cls::ReleaseLock()\
307
if (lockCount.l > 0)\
309
InterlockedDecrement(&lockCount.l);\
310
WXOLE_TRACEOUT(# cls << "::Del Lock(" << lockCount.l << ")");\
318
#define DEFINE_OLE_BASE(cls)\
319
void cls::_GetInterface(cls *self, REFIID iid, void **_interface, const char *&desc)\
324
#define OLE_INTERFACE(_iid, _type)\
325
if (IsEqualIID(iid, _iid))\
327
WXOLE_TRACE("Found Interface <" # _type ">");\
328
*_interface = (IUnknown *) (_type *) self;\
333
#define OLE_IINTERFACE(_face) OLE_INTERFACE(IID_##_face, _face)
335
#define OLE_INTERFACE_CUSTOM(func)\
336
if (func(self, iid, _interface, desc))\
341
#define END_OLE_TABLE\
345
/// Main class for embedding a ActiveX control.
346
/// Use by itself or derive from it
347
/// \note The utility program (wxie) can generate a list of events, methods & properties
349
/// First display the control (File|Display),
350
/// then get the type info (ActiveX|Get Type Info) - these are copied to the clipboard.
351
/// Eventually this will be expanded to autogenerate
352
/// wxWindows source files for a control with all methods etc encapsulated.
354
/// construct using a ProgId or class id
355
/// \code new wxActiveX(parent, CLSID_WebBrowser, id, pos, size, style, name)\endcode
356
/// \code new wxActiveX(parent, "ShockwaveFlash.ShockwaveFlash", id, pos, size, style, name)\endcode
358
/// Properties can be set using \c SetProp() and set/retrieved using \c Prop()
359
/// \code SetProp(name, wxVariant(x)) \endcode or
360
/// \code wxString Prop("<name>") = x\endcode
361
/// \code wxString result = Prop("<name>")\endcode
362
/// \code flash_ctl.Prop("movie") = "file:///movies/test.swf";\endcode
363
/// \code flash_ctl.Prop("Playing") = false;\endcode
364
/// \code wxString current_movie = flash_ctl.Prop("movie");\endcode
366
/// Methods are invoked with \c CallMethod()
367
/// \code wxVariant result = CallMethod("<name>", args, nargs = -1)\endcode
368
/// \code wxVariant args[] = {0L, "file:///e:/dev/wxie/bug-zap.swf"};
369
/// wxVariant result = X->CallMethod("LoadMovie", args);\endcode
371
/// respond to events with the
372
/// \c EVT_ACTIVEX(controlId, eventName, handler) &
373
/// \c EVT_ACTIVEX_DISPID(controlId, eventDispId, handler) macros
375
/// BEGIN_EVENT_TABLE(wxIEFrame, wxFrame)
376
/// EVT_ACTIVEX_DISPID(ID_MSHTML, DISPID_STATUSTEXTCHANGE, OnMSHTMLStatusTextChangeX)
377
/// EVT_ACTIVEX(ID_MSHTML, "BeforeNavigate2", OnMSHTMLBeforeNavigate2X)
378
/// EVT_ACTIVEX(ID_MSHTML, "TitleChange", OnMSHTMLTitleChangeX)
379
/// EVT_ACTIVEX(ID_MSHTML, "NewWindow2", OnMSHTMLNewWindow2X)
380
/// EVT_ACTIVEX(ID_MSHTML, "ProgressChange", OnMSHTMLProgressChangeX)
381
/// END_EVENT_TABLE()\endcode
382
class wxActiveX : public wxWindow {
384
/// General parameter and return type infoformation for Events, Properties and Methods.
385
/// refer to ELEMDESC, IDLDESC in MSDN
396
ParamX() : isOptional(false), vt(VT_EMPTY) {}
397
inline bool IsIn() const {return (flags & IDLFLAG_FIN) != 0;}
398
inline bool IsOut() const {return (flags & IDLFLAG_FOUT) != 0;}
399
inline bool IsRetVal() const {return (flags & IDLFLAG_FRETVAL) != 0;}
401
typedef vector<ParamX> ParamXArray;
404
/// Type & Parameter info for Events and Methods.
405
/// refer to FUNCDESC in MSDN
416
typedef vector<FuncX> FuncXArray;
419
/// Type info for properties.
429
PropX() : putByRef (false) {}
430
inline bool CanGet() const {return type.vt != VT_EMPTY;}
431
inline bool CanSet() const {return arg.vt != VT_EMPTY;}
433
typedef vector<PropX> PropXArray;
436
/// Create using clsid.
437
wxActiveX(wxWindow * parent, REFCLSID clsid, wxWindowID id = -1,
438
const wxPoint& pos = wxDefaultPosition,
439
const wxSize& size = wxDefaultSize,
441
const wxString& name = wxPanelNameStr);
442
/// create using progid.
443
wxActiveX(wxWindow * parent, const wxString& progId, wxWindowID id = -1,
444
const wxPoint& pos = wxDefaultPosition,
445
const wxSize& size = wxDefaultSize,
447
const wxString& name = wxPanelNameStr);
448
virtual ~wxActiveX();
450
/// Number of events defined for this control.
451
inline int GetEventCount() const {return m_events.size();}
452
/// returns event description by index.
453
/// throws exception for invalid index
454
const FuncX& GetEventDesc(int idx) const;
456
/// Number of properties defined for this control.
457
inline int GetPropCount() const {return m_props.size();}
458
/// returns property description by index.
459
/// throws exception for invalid index
460
const PropX& GetPropDesc(int idx) const;
461
/// returns property description by name.
462
/// throws exception for invalid name
463
const PropX& GetPropDesc(const wxString& name) const;
465
/// Number of methods defined for this control.
466
inline int GetMethodCount() const {return m_methods.size();}
467
/// returns method description by name.
468
/// throws exception for invalid index
469
const FuncX& GetMethodDesc(int idx) const;
470
/// returns method description by name.
471
/// throws exception for invalid name
472
const FuncX& GetMethodDesc(const wxString& name) const;
474
/// Set property VARIANTARG value by MEMBERID.
475
void SetProp(MEMBERID name, VARIANTARG& value);
476
/// Set property using wxVariant by name.
477
void SetProp(const wxString &name, const wxVariant &value);
479
class wxPropertySetter
485
wxPropertySetter(wxActiveX *ctl, const wxString& propName) :
486
m_ctl(ctl), m_propName(propName) {}
488
inline const wxPropertySetter& operator = (wxVariant v) const
490
m_ctl->SetProp(m_propName, v);
494
inline operator wxVariant() const {return m_ctl->GetPropAsWxVariant(m_propName);};
495
inline operator wxString() const {return m_ctl->GetPropAsString(m_propName);};
496
inline operator char() const {return m_ctl->GetPropAsChar(m_propName);};
497
inline operator long() const {return m_ctl->GetPropAsLong(m_propName);};
498
inline operator bool() const {return m_ctl->GetPropAsBool(m_propName);};
499
inline operator double() const {return m_ctl->GetPropAsDouble(m_propName);};
500
inline operator wxDateTime() const {return m_ctl->GetPropAsDateTime(m_propName);};
501
inline operator void *() const {return m_ctl->GetPropAsPointer(m_propName);};
504
/// \fn inline wxPropertySetter Prop(wxString name) {return wxPropertySetter(this, name);}
505
/// \param name Property name to read/set
506
/// \return wxPropertySetter, which has overloads for setting/getting the property
507
/// \brief Generic Get/Set Property by name.
508
/// Automatically handles most types
510
/// - Prop("\<name\>") = \<value\>
511
/// - var = Prop("\<name\>")
513
/// - \code flash_ctl.Prop("movie") = "file:///movies/test.swf";\endcode
514
/// - \code flash_ctl.Prop("Playing") = false;\endcode
515
/// - \code wxString current_movie = flash_ctl.Prop("movie");\endcode
516
/// \exception raises exception if \<name\> is invalid
517
/// \note Have to add a few more type conversions yet ...
518
inline wxPropertySetter Prop(wxString name) {return wxPropertySetter(this, name);}
520
VARIANT GetPropAsVariant(MEMBERID name);
521
VARIANT GetPropAsVariant(const wxString& name);
522
wxVariant GetPropAsWxVariant(const wxString& name);
523
wxString GetPropAsString(const wxString& name);
524
char GetPropAsChar(const wxString& name);
525
long GetPropAsLong(const wxString& name);
526
bool GetPropAsBool(const wxString& name);
527
double GetPropAsDouble(const wxString& name);
528
wxDateTime GetPropAsDateTime(const wxString& name);
529
void *GetPropAsPointer(const wxString& name);
532
// VARIANTARG form is passed straight to Invoke,
533
// so args in *REVERSE* order
534
VARIANT CallMethod(MEMBERID name, VARIANTARG args[], int argc);
535
VARIANT CallMethod(const wxString& name, VARIANTARG args[] = NULL, int argc = -1);
536
// args are in *NORMAL* order
537
// args can be a single wxVariant or an array
538
/// \fn wxVariant CallMethod(wxString name, wxVariant args[], int nargs = -1);
539
/// \param name name of method to call
540
/// \param args array of wxVariant's, defaults to NULL (no args)
541
/// \param nargs number of arguments passed via args. Defaults to actual number of args for the method
542
/// \return wxVariant
543
/// \brief Call a method of the ActiveX control.
544
/// Automatically handles most types
546
/// - result = CallMethod("\<name\>", args, nargs)
549
/// wxVariant args[] = {0L, "file:///e:/dev/wxie/bug-zap.swf"};
550
/// wxVariant result = X->CallMethod("LoadMovie", args);\endcode
551
/// \exception raises exception if \<name\> is invalid
552
/// \note Since wxVariant has built in type conversion, most the std types can be passed easily
553
wxVariant CallMethod(const wxString& name, wxVariant args[], int nargs = -1);
555
HRESULT ConnectAdvise(REFIID riid, IUnknown *eventSink);
557
void OnSize(wxSizeEvent&);
558
void OnPaint(wxPaintEvent& event);
559
void OnMouse(wxMouseEvent& event);
560
void OnSetFocus(wxFocusEvent&);
561
void OnKillFocus(wxFocusEvent&);
563
DECLARE_EVENT_TABLE();
566
friend class FrameSite;
567
friend class wxActiveXEvents;
569
unsigned long m_pdwRegister;
571
typedef map<MEMBERID, int> MemberIdMap;
572
typedef map<wxString, int, NS_wxActiveX::less_wxStringI> NameMap;
574
typedef wxAutoOleInterface<IConnectionPoint> wxOleConnectionPoint;
575
typedef pair<wxOleConnectionPoint, DWORD> wxOleConnection;
576
typedef vector<wxOleConnection> wxOleConnectionArray;
578
wxAutoOleInterface<IDispatch> m_Dispatch;
579
wxAutoOleInterface<IOleClientSite> m_clientSite;
580
wxAutoOleInterface<IUnknown> m_ActiveX;
581
wxAutoOleInterface<IOleObject> m_oleObject;
582
wxAutoOleInterface<IOleInPlaceObject> m_oleInPlaceObject;
583
wxAutoOleInterface<IOleInPlaceActiveObject>
585
m_oleInPlaceActiveObject;
586
wxAutoOleInterface<IOleDocumentView> m_docView;
587
wxAutoOleInterface<IViewObject> m_viewObject;
588
HWND m_oleObjectHWND;
589
bool m_bAmbientUserMode;
590
DWORD m_docAdviseCookie;
591
wxOleConnectionArray m_connections;
593
void CreateActiveX(REFCLSID clsid);
594
void CreateActiveX(LPOLESTR progId);
595
HRESULT AmbientPropertyChanged(DISPID dispid);
598
void GetTypeInfo(ITypeInfo *ti, bool defInterface, bool defEventSink);
603
MemberIdMap m_eventMemberIds;
610
FuncXArray m_methods;
611
NameMap m_methodNames;
613
virtual bool MSWTranslateMessage(WXMSG* pMsg);
614
WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
616
DECLARE_CLASS(wxActiveX)
620
class wxActiveXEvent : public wxCommandEvent
623
friend class wxActiveXEvents;
629
virtual wxEvent *Clone() const { return new wxActiveXEvent(*this); }
631
wxString EventName();
632
int ParamCount() const;
633
wxString ParamType(int idx);
634
wxString ParamName(int idx);
635
wxVariant& operator[] (int idx);
636
wxVariant& operator[] (wxString name);
639
DECLARE_CLASS(wxActiveXEvent)
642
const wxEventType& RegisterActiveXEvent(const wxString& eventName);
643
const wxEventType& RegisterActiveXEvent(DISPID event);
645
typedef void (wxEvtHandler::*wxActiveXEventFunction)(wxActiveXEvent&);
647
/// \def EVT_ACTIVEX(id, eventName, fn)
648
/// \brief Event handle for events by name
649
#define EVT_ACTIVEX(id, eventName, fn) DECLARE_EVENT_TABLE_ENTRY(RegisterActiveXEvent(wxT(eventName)), id, -1, (wxObjectEventFunction) (wxEventFunction) (wxActiveXEventFunction) & fn, (wxObject *) NULL ),
650
/// \def EVT_ACTIVEX_DISPID(id, eventDispId, fn)
651
/// \brief Event handle for events by DISPID (dispath id)
652
#define EVT_ACTIVEX_DISPID(id, eventDispId, fn) DECLARE_EVENT_TABLE_ENTRY(RegisterActiveXEvent(eventDispId), id, -1, (wxObjectEventFunction) (wxEventFunction) (wxActiveXEventFunction) & fn, (wxObject *) NULL ),
655
bool wxDateTimeToVariant(wxDateTime dt, VARIANTARG& va);
656
bool VariantToWxDateTime(VARIANTARG va, wxDateTime& dt);
657
/// \relates wxActiveX
658
/// \fn bool MSWVariantToVariant(VARIANTARG& va, wxVariant& vx);
659
/// \param va VARAIANTARG to convert from
660
/// \param vx Destination wxVariant
661
/// \return success/failure (true/false)
662
/// \brief Convert MSW VARIANTARG to wxVariant.
663
/// Handles basic types, need to add:
664
/// - VT_ARRAY | VT_*
665
/// - better support for VT_UNKNOWN (currently treated as void *)
666
/// - better support for VT_DISPATCH (currently treated as void *)
667
bool MSWVariantToVariant(VARIANTARG& va, wxVariant& vx);
668
/// \relates wxActiveX
669
/// \fn bool VariantToMSWVariant(const wxVariant& vx, VARIANTARG& va);
670
/// \param vx wxVariant to convert from
671
/// \param va Destination VARIANTARG
672
/// \return success/failure (true/false)
673
/// \brief Convert wxVariant to MSW VARIANTARG.
674
/// Handles basic types, need to add:
675
/// - VT_ARRAY | VT_*
676
/// - better support for VT_UNKNOWN (currently treated as void *)
677
/// - better support for VT_DISPATCH (currently treated as void *)
678
bool VariantToMSWVariant(const wxVariant& vx, VARIANTARG& va);
680
#endif /* _IEHTMLWIN_H_ */