]> git.saurik.com Git - wxWidgets.git/blob - wxPython/contrib/activex/wxie/wxactivex.cpp
merge #4 from 2.6 branch
[wxWidgets.git] / wxPython / contrib / activex / wxie / wxactivex.cpp
1 /*
2 wxActiveX Library Licence, Version 3
3 ====================================
4
5 Copyright (C) 2003 Lindsay Mathieson [, ...]
6
7 Everyone is permitted to copy and distribute verbatim copies
8 of this licence document, but changing it is not allowed.
9
10 wxActiveX LIBRARY LICENCE
11 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
12
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.
17
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.
22
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.
27
28 EXCEPTION NOTICE
29
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
35 Licence document.
36
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
39 on the Library.
40
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
47 accordingly.
48
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.
53 */
54
55 #include "wxActiveX.h"
56 #include <wx/strconv.h>
57 #include <wx/event.h>
58 #include <wx/string.h>
59 #include <wx/datetime.h>
60 #include <wx/log.h>
61 #include <oleidl.h>
62 #include <winerror.h>
63 #include <idispids.h>
64 #include <olectl.h>
65 using namespace std;
66
67 // Depending on compilation mode, the wx headers may have undef'd
68 // this, but in this case we need it so the virtual method in
69 // FrameSite will match what is in oleidl.h.
70 #ifndef GetObject
71 #ifdef _UNICODE
72 #define GetObject GetObjectW
73 #else
74 #define GetObject GetObjectA
75 #endif
76 #endif
77
78
79 //////////////////////////////////////////////////////////////////////
80 BEGIN_EVENT_TABLE(wxActiveX, wxWindow)
81 EVT_SIZE(wxActiveX::OnSize)
82 EVT_PAINT(wxActiveX::OnPaint)
83 EVT_MOUSE_EVENTS(wxActiveX::OnMouse)
84 EVT_SET_FOCUS(wxActiveX::OnSetFocus)
85 EVT_KILL_FOCUS(wxActiveX::OnKillFocus)
86 END_EVENT_TABLE()
87
88 IMPLEMENT_CLASS(wxActiveX, wxWindow)
89
90 class wxActiveX;
91
92 class FrameSite :
93 public IOleClientSite,
94 public IOleInPlaceSiteEx,
95 public IOleInPlaceFrame,
96 public IOleItemContainer,
97 public IDispatch,
98 public IOleCommandTarget,
99 public IOleDocumentSite,
100 public IAdviseSink,
101 public IOleControlSite
102 {
103 private:
104 DECLARE_OLE_UNKNOWN(FrameSite);
105
106 public:
107 FrameSite(wxActiveX * win);
108 virtual ~FrameSite();
109
110 //IOleWindow
111 STDMETHODIMP GetWindow(HWND*);
112 STDMETHODIMP ContextSensitiveHelp(BOOL);
113
114 //IOleInPlaceUIWindow
115 STDMETHODIMP GetBorder(LPRECT);
116 STDMETHODIMP RequestBorderSpace(LPCBORDERWIDTHS);
117 STDMETHODIMP SetBorderSpace(LPCBORDERWIDTHS);
118 STDMETHODIMP SetActiveObject(IOleInPlaceActiveObject*, LPCOLESTR);
119
120 //IOleInPlaceFrame
121 STDMETHODIMP InsertMenus(HMENU, LPOLEMENUGROUPWIDTHS);
122 STDMETHODIMP SetMenu(HMENU, HOLEMENU, HWND);
123 STDMETHODIMP RemoveMenus(HMENU);
124 STDMETHODIMP SetStatusText(LPCOLESTR);
125 STDMETHODIMP EnableModeless(BOOL);
126 STDMETHODIMP TranslateAccelerator(LPMSG, WORD);
127
128 //IOleInPlaceSite
129 STDMETHODIMP CanInPlaceActivate();
130 STDMETHODIMP OnInPlaceActivate();
131 STDMETHODIMP OnUIActivate();
132 STDMETHODIMP GetWindowContext(IOleInPlaceFrame**, IOleInPlaceUIWindow**,
133 LPRECT, LPRECT, LPOLEINPLACEFRAMEINFO);
134 STDMETHODIMP Scroll(SIZE);
135 STDMETHODIMP OnUIDeactivate(BOOL);
136 STDMETHODIMP OnInPlaceDeactivate();
137 STDMETHODIMP DiscardUndoState();
138 STDMETHODIMP DeactivateAndUndo();
139 STDMETHODIMP OnPosRectChange(LPCRECT);
140
141 //IOleInPlaceSiteEx
142 STDMETHODIMP OnInPlaceActivateEx(BOOL*, DWORD);
143 STDMETHODIMP OnInPlaceDeactivateEx(BOOL);
144 STDMETHODIMP RequestUIActivate();
145
146 //IOleClientSite
147 STDMETHODIMP SaveObject();
148 STDMETHODIMP GetMoniker(DWORD, DWORD, IMoniker**);
149 STDMETHODIMP GetContainer(LPOLECONTAINER FAR*);
150 STDMETHODIMP ShowObject();
151 STDMETHODIMP OnShowWindow(BOOL);
152 STDMETHODIMP RequestNewObjectLayout();
153
154 //IOleControlSite
155 STDMETHODIMP OnControlInfoChanged();
156 STDMETHODIMP LockInPlaceActive(BOOL);
157 STDMETHODIMP GetExtendedControl(IDispatch**);
158 STDMETHODIMP TransformCoords(POINTL*, POINTF*, DWORD);
159 STDMETHODIMP TranslateAccelerator(LPMSG, DWORD);
160 STDMETHODIMP OnFocus(BOOL);
161 STDMETHODIMP ShowPropertyFrame();
162
163 //IOleCommandTarget
164 STDMETHODIMP QueryStatus(const GUID*, ULONG, OLECMD[], OLECMDTEXT*);
165 STDMETHODIMP Exec(const GUID*, DWORD, DWORD, VARIANTARG*, VARIANTARG*);
166
167 //IParseDisplayName
168 STDMETHODIMP ParseDisplayName(IBindCtx*, LPOLESTR, ULONG*, IMoniker**);
169
170 //IOleContainer
171 STDMETHODIMP EnumObjects(DWORD, IEnumUnknown**);
172 STDMETHODIMP LockContainer(BOOL);
173
174 //IOleItemContainer
175 STDMETHODIMP GetObject(LPOLESTR, DWORD, IBindCtx*, REFIID, void**);
176 STDMETHODIMP GetObjectStorage(LPOLESTR, IBindCtx*, REFIID, void**);
177 STDMETHODIMP IsRunning(LPOLESTR);
178
179 //IDispatch
180 STDMETHODIMP GetIDsOfNames(REFIID, OLECHAR**, unsigned int, LCID, DISPID*);
181 STDMETHODIMP GetTypeInfo(unsigned int, LCID, ITypeInfo**);
182 STDMETHODIMP GetTypeInfoCount(unsigned int*);
183 STDMETHODIMP Invoke(DISPID, REFIID, LCID, WORD, DISPPARAMS*, VARIANT*, EXCEPINFO*, UINT*);
184
185 //IAdviseSink
186 void STDMETHODCALLTYPE OnDataChange(FORMATETC*, STGMEDIUM*);
187 void STDMETHODCALLTYPE OnViewChange(DWORD, LONG);
188 void STDMETHODCALLTYPE OnRename(IMoniker*);
189 void STDMETHODCALLTYPE OnSave();
190 void STDMETHODCALLTYPE OnClose();
191
192 // IOleDocumentSite
193 HRESULT STDMETHODCALLTYPE ActivateMe(IOleDocumentView __RPC_FAR *pViewToActivate);
194
195 protected:
196
197 wxActiveX * m_window;
198
199 HDC m_hDCBuffer;
200 HWND m_hWndParent;
201
202 bool m_bSupportsWindowlessActivation;
203 bool m_bInPlaceLocked;
204 bool m_bInPlaceActive;
205 bool m_bUIActive;
206 bool m_bWindowless;
207
208
209
210 LCID m_nAmbientLocale;
211 COLORREF m_clrAmbientForeColor;
212 COLORREF m_clrAmbientBackColor;
213 bool m_bAmbientShowHatching;
214 bool m_bAmbientShowGrabHandles;
215 bool m_bAmbientAppearance;
216 };
217
218 DEFINE_OLE_TABLE(FrameSite)
219 OLE_INTERFACE(IID_IUnknown, IOleClientSite)
220
221 OLE_IINTERFACE(IOleClientSite)
222
223 OLE_INTERFACE(IID_IOleWindow, IOleInPlaceSite)
224 OLE_IINTERFACE(IOleInPlaceSite)
225 OLE_IINTERFACE(IOleInPlaceSiteEx)
226
227 //OLE_IINTERFACE(IOleWindow)
228 OLE_IINTERFACE(IOleInPlaceUIWindow)
229 OLE_IINTERFACE(IOleInPlaceFrame)
230
231 OLE_IINTERFACE(IParseDisplayName)
232 OLE_IINTERFACE(IOleContainer)
233 OLE_IINTERFACE(IOleItemContainer)
234
235 OLE_IINTERFACE(IDispatch)
236
237 OLE_IINTERFACE(IOleCommandTarget)
238
239 OLE_IINTERFACE(IOleDocumentSite)
240
241 OLE_IINTERFACE(IAdviseSink)
242
243 OLE_IINTERFACE(IOleControlSite)
244
245 END_OLE_TABLE;
246
247
248 wxActiveX::wxActiveX(wxWindow * parent, REFCLSID clsid, wxWindowID id,
249 const wxPoint& pos,
250 const wxSize& size,
251 long style,
252 const wxString& name) :
253 wxWindow(parent, id, pos, size, style, name)
254 {
255 m_bAmbientUserMode = true;
256 m_docAdviseCookie = 0;
257 CreateActiveX(clsid);
258 }
259
260 wxActiveX::wxActiveX(wxWindow * parent, const wxString& progId, wxWindowID id,
261 const wxPoint& pos,
262 const wxSize& size,
263 long style,
264 const wxString& name) :
265 wxWindow(parent, id, pos, size, style, name)
266 {
267 m_bAmbientUserMode = true;
268 m_docAdviseCookie = 0;
269 CreateActiveX((LPOLESTR) (const wchar_t *) progId.wc_str(wxConvUTF8));
270 }
271
272 wxActiveX::~wxActiveX()
273 {
274 // disconnect connection points
275 wxOleConnectionArray::iterator it = m_connections.begin();
276 while (it != m_connections.end())
277 {
278 wxOleConnectionPoint& cp = it->first;
279 cp->Unadvise(it->second);
280
281 it++;
282 };
283 m_connections.clear();
284
285 if (m_oleInPlaceObject.Ok())
286 {
287 m_oleInPlaceObject->InPlaceDeactivate();
288 m_oleInPlaceObject->UIDeactivate();
289 }
290
291
292 if (m_oleObject.Ok())
293 {
294 if (m_docAdviseCookie != 0)
295 m_oleObject->Unadvise(m_docAdviseCookie);
296
297 m_oleObject->DoVerb(OLEIVERB_HIDE, NULL, m_clientSite, 0, (HWND) GetHWND(), NULL);
298 m_oleObject->Close(OLECLOSE_NOSAVE);
299 m_oleObject->SetClientSite(NULL);
300 }
301
302 // Unregister object as active
303 RevokeActiveObject(m_pdwRegister, NULL);
304 }
305
306 void wxActiveX::CreateActiveX(REFCLSID clsid)
307 {
308 HRESULT hret;
309
310 ////////////////////////////////////////////////////////
311 // FrameSite
312 FrameSite *frame = new FrameSite(this);
313 // oleClientSite
314 hret = m_clientSite.QueryInterface(IID_IOleClientSite, (IDispatch *) frame);
315 wxCHECK_RET(SUCCEEDED(hret), _T("m_clientSite.QueryInterface failed"));
316 // adviseSink
317 wxAutoOleInterface<IAdviseSink> adviseSink(IID_IAdviseSink, (IDispatch *) frame);
318 wxCHECK_RET(adviseSink.Ok(), _T("adviseSink not Ok"));
319
320
321 // Create Object, get IUnknown interface
322 m_ActiveX.CreateInstance(clsid, IID_IUnknown);
323 wxCHECK_RET(m_ActiveX.Ok(), _T("m_ActiveX.CreateInstance failed"));
324
325 // Register object as active
326 unsigned long pdwRegister;
327 hret = RegisterActiveObject(m_ActiveX, clsid, ACTIVEOBJECT_WEAK, &m_pdwRegister);
328 WXOLE_WARN(hret, "Unable to register object as active");
329
330 // Get Dispatch interface
331 hret = m_Dispatch.QueryInterface(IID_IDispatch, m_ActiveX);
332 WXOLE_WARN(hret, "Unable to get dispatch interface");
333
334 // Type Info
335 GetTypeInfo();
336
337 // Get IOleObject interface
338 hret = m_oleObject.QueryInterface(IID_IOleObject, m_ActiveX);
339 wxCHECK_RET(SUCCEEDED(hret), _("Unable to get IOleObject interface"));
340
341 // get IViewObject Interface
342 hret = m_viewObject.QueryInterface(IID_IViewObject, m_ActiveX);
343 wxCHECK_RET(SUCCEEDED(hret), _T("Unable to get IViewObject Interface"));
344
345 // document advise
346 m_docAdviseCookie = 0;
347 hret = m_oleObject->Advise(adviseSink, &m_docAdviseCookie);
348 WXOLE_WARN(hret, "m_oleObject->Advise(adviseSink, &m_docAdviseCookie),\"Advise\")");
349 m_oleObject->SetHostNames(L"wxActiveXContainer", NULL);
350 OleSetContainedObject(m_oleObject, TRUE);
351 OleRun(m_oleObject);
352
353
354 // Get IOleInPlaceObject interface
355 hret = m_oleInPlaceObject.QueryInterface(IID_IOleInPlaceObject, m_ActiveX);
356 wxCHECK_RET(SUCCEEDED(hret), _T("Unable to get IOleInPlaceObject interface"));
357
358 // status
359 DWORD dwMiscStatus;
360 m_oleObject->GetMiscStatus(DVASPECT_CONTENT, &dwMiscStatus);
361 wxCHECK_RET(SUCCEEDED(hret), _T("Unable to get oleObject status"));
362
363 // set client site first ?
364 if (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)
365 m_oleObject->SetClientSite(m_clientSite);
366
367
368 // stream init
369 wxAutoOleInterface<IPersistStreamInit>
370 pPersistStreamInit(IID_IPersistStreamInit, m_oleObject);
371
372 if (pPersistStreamInit.Ok())
373 {
374 hret = pPersistStreamInit->InitNew();
375 WXOLE_WARN(hret, "CreateActiveX::pPersistStreamInit->InitNew()");
376 };
377
378 if (! (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST))
379 m_oleObject->SetClientSite(m_clientSite);
380
381
382 int w, h;
383 GetClientSize(&w, &h);
384 RECT posRect;
385 posRect.left = 0;
386 posRect.top = 0;
387 posRect.right = w;
388 posRect.bottom = h;
389
390 m_oleObjectHWND = 0;
391
392 if (m_oleInPlaceObject.Ok())
393 {
394 hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND);
395 WXOLE_WARN(hret, "m_oleInPlaceObject->GetWindow(&m_oleObjectHWND)");
396 if (SUCCEEDED(hret))
397 ::SetActiveWindow(m_oleObjectHWND);
398 };
399
400
401 if (! (dwMiscStatus & OLEMISC_INVISIBLEATRUNTIME))
402 {
403 if (w > 0 && h > 0 && m_oleInPlaceObject.Ok())
404 m_oleInPlaceObject->SetObjectRects(&posRect, &posRect);
405
406 hret = m_oleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, m_clientSite, 0, (HWND)GetHWND(), &posRect);
407 hret = m_oleObject->DoVerb(OLEIVERB_SHOW, 0, m_clientSite, 0, (HWND)GetHWND(), &posRect);
408 };
409
410 if (! m_oleObjectHWND && m_oleInPlaceObject.Ok())
411 {
412 hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND);
413 WXOLE_WARN(hret, "m_oleInPlaceObject->GetWindow(&m_oleObjectHWND)");
414 };
415
416 if (m_oleObjectHWND)
417 {
418 ::SetActiveWindow(m_oleObjectHWND);
419 ::ShowWindow(m_oleObjectHWND, SW_SHOW);
420
421 // Update by GBR to resize older controls
422 wxSizeEvent szEvent;
423 szEvent.m_size = wxSize(w, h) ;
424 GetEventHandler()->AddPendingEvent(szEvent);
425 };
426 }
427
428 void wxActiveX::CreateActiveX(LPOLESTR progId)
429 {
430 CLSID clsid;
431 if (CLSIDFromProgID(progId, &clsid) != S_OK)
432 return;
433
434 CreateActiveX(clsid);
435 };
436
437 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
438 // Case Insensitive Map of Event names to eventTypes
439 // created dynamically at run time in:
440 // EVT_ACTIVEX(eventName, id, fn)
441 // we map the pointer to them so that:
442 // const wxEventType& RegisterActiveXEvent(wxString eventName);
443 // can return a const reference, which is neccessary for event tables
444 // probably should use a wxWindows hash table here, but I'm lazy ...
445 typedef map<wxString, wxEventType *, NS_wxActiveX::less_wxStringI> ActiveXNamedEventMap;
446 static ActiveXNamedEventMap sg_NamedEventMap;
447
448 const wxEventType& RegisterActiveXEvent(const wxChar *eventName)
449 {
450 wxString ev = eventName;
451 ActiveXNamedEventMap::iterator it = sg_NamedEventMap.find(ev);
452 if (it == sg_NamedEventMap.end())
453 {
454 wxEventType *et = new wxEventType(wxNewEventType());
455 sg_NamedEventMap[ev] = et;
456
457 return *et;
458 };
459
460 return *(it->second);
461 };
462
463
464 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
465 // Map of Event DISPID's to eventTypes
466 // created dynamically at run time in:
467 // EVT_ACTIVEX(eventName, id, fn)
468 // we map the pointer to them so that:
469 // const wxEventType& RegisterActiveXEvent(wxString eventName);
470 // can return a const reference, which is neccessary for event tables
471
472 typedef map<DISPID, wxEventType *> ActiveXDISPIDEventMap;
473 static ActiveXDISPIDEventMap sg_dispIdEventMap;
474
475 const wxEventType& RegisterActiveXEvent(DISPID event)
476 {
477 ActiveXDISPIDEventMap::iterator it = sg_dispIdEventMap.find(event);
478 if (it == sg_dispIdEventMap.end())
479 {
480 wxEventType *et = new wxEventType(wxNewEventType());
481 sg_dispIdEventMap[event] = et;
482
483 return *et;
484 };
485
486 return *(it->second);
487 };
488
489 // one off class for automatic freeing of activeX eventtypes
490 class ActiveXEventMapFlusher
491 {
492 public:
493 ~ActiveXEventMapFlusher()
494 {
495 // Named events
496 ActiveXNamedEventMap::iterator it = sg_NamedEventMap.end();
497 while (it != sg_NamedEventMap.end())
498 {
499 delete it->second;
500 it++;
501 };
502 sg_NamedEventMap.clear();
503
504 // DISPID events
505 ActiveXDISPIDEventMap::iterator dit = sg_dispIdEventMap.end();
506 while (dit != sg_dispIdEventMap.end())
507 {
508 delete dit->second;
509 dit++;
510 };
511 sg_dispIdEventMap.clear();
512 };
513 };
514
515 static ActiveXEventMapFlusher s_dummyActiveXEventMapFlusher;
516
517
518 //////////////////////////////////////////////////////
519 VARTYPE wxTypeToVType(const wxVariant& v)
520 {
521 wxString type = v.GetType();
522 if (type == wxT("bool"))
523 return VT_BOOL;
524 else if (type == wxT("char"))
525 return VT_I1;
526 else if (type == wxT("datetime"))
527 return VT_DATE;
528 else if (type == wxT("double"))
529 return VT_R8;
530 else if (type == wxT("list"))
531 return VT_ARRAY;
532 else if (type == wxT("long"))
533 return VT_I4;
534 else if (type == wxT("string"))
535 return VT_BSTR;
536 else if (type == wxT("stringlist"))
537 return VT_ARRAY;
538 else if (type == wxT("date"))
539 return VT_DATE;
540 else if (type == wxT("time"))
541 return VT_DATE;
542 else if (type == wxT("void*"))
543 return VT_VOID | VT_BYREF;
544 else
545 return VT_NULL;
546 };
547
548 bool wxDateTimeToDATE(wxDateTime dt, DATE& d)
549 {
550 SYSTEMTIME st;
551 memset(&st, 0, sizeof(st));
552
553 st.wYear = dt.GetYear();
554 st.wMonth = dt.GetMonth() + 1;
555 st.wDay = dt.GetDay();
556 st.wHour = dt.GetHour();
557 st.wMinute = dt.GetMinute();
558 st.wSecond = dt.GetSecond();
559 st.wMilliseconds = dt.GetMillisecond();
560 return SystemTimeToVariantTime(&st, &d) != FALSE;
561 };
562
563 bool wxDateTimeToVariant(wxDateTime dt, VARIANTARG& va)
564 {
565 return wxDateTimeToDATE(dt, va.date);
566 };
567
568 bool DATEToWxDateTime(DATE date, wxDateTime& dt)
569 {
570 SYSTEMTIME st;
571 if (! VariantTimeToSystemTime(date, &st))
572 return false;
573
574 dt = wxDateTime(
575 st.wDay,
576 wxDateTime::Month(int(wxDateTime::Jan) + st.wMonth - 1),
577 st.wYear,
578 st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
579
580 return true;
581 };
582
583 bool VariantToWxDateTime(VARIANTARG va, wxDateTime& dt)
584 {
585 HRESULT hr = VariantChangeType(&va, &va, 0, VT_DATE);
586 if (! SUCCEEDED(hr))
587 return false;
588
589 return DATEToWxDateTime(va.date, dt);
590 };
591
592 bool MSWVariantToVariant(VARIANTARG& va, wxVariant& vx)
593 {
594 bool byRef = false;
595 VARTYPE vt = va.vt;
596
597 if (vt & VT_ARRAY)
598 return false; // don't support arrays yet
599
600 if (vt & VT_BYREF)
601 {
602 byRef = true;
603 vt &= ~(VT_BYREF);
604 };
605
606
607 switch(vt)
608 {
609 case VT_VARIANT:
610 if (byRef)
611 return MSWVariantToVariant(*va.pvarVal, vx);
612 else
613 {
614 VARIANT tmp = va;
615 VariantChangeType(&tmp, &tmp, 0, wxTypeToVType(vx));
616 bool rc = MSWVariantToVariant(tmp, vx);
617 VariantClear(&tmp);
618 return rc;
619 };
620
621 // 1 byte chars
622 case VT_I1:
623 case VT_UI1:
624 if (byRef)
625 vx = (char) *va.pbVal;
626 else
627 vx = (char) va.bVal;
628 return true;
629
630 // 2 byte shorts
631 case VT_I2:
632 case VT_UI2:
633 if (byRef)
634 vx = (long) *va.puiVal;
635 else
636 vx = (long) va.uiVal;
637 return true;
638
639 // 4 bytes longs
640 case VT_I4:
641 case VT_UI4:
642 case VT_INT:
643 case VT_UINT:
644 case VT_ERROR:
645 if (byRef)
646 vx = (long) *va.pulVal;
647 else
648 vx = (long) va.ulVal;
649 return true;
650
651
652 // 4 byte floats
653 case VT_R4:
654 if (byRef)
655 vx = *va.pfltVal;
656 else
657 vx = va.fltVal;
658 return true;
659
660 // 8 byte doubles
661 case VT_R8:
662 if (byRef)
663 vx = *va.pdblVal;
664 else
665 vx = va.dblVal;
666 return true;
667
668 case VT_BOOL:
669 if (byRef)
670 vx = (*va.pboolVal ? true : false);
671 else
672 vx = (va.boolVal ? true : false);
673 return true;
674
675 case VT_CY:
676 vx.MakeNull();
677 return false; // what the hell is a CY ?
678
679 case VT_DECIMAL:
680 {
681 double d = 0;
682 HRESULT hr;
683 if (byRef)
684 hr = VarR8FromDec(va.pdecVal, &d);
685 else
686 hr = VarR8FromDec(&va.decVal, &d);
687
688 vx = d;
689 return SUCCEEDED(hr);
690 };
691
692 case VT_DATE:
693 {
694 wxDateTime dt;
695 bool rc = false;
696 if (byRef)
697 rc = DATEToWxDateTime(*va.pdate, dt);
698 else
699 rc = VariantToWxDateTime(va, dt);
700 vx = dt;
701 return rc;
702 };
703
704 case VT_BSTR:
705 if (byRef)
706 vx = wxString(*va.pbstrVal);
707 else
708 vx = wxString(va.bstrVal);
709 return true;
710
711 case VT_UNKNOWN: // should do a custom wxVariantData for this
712 if (byRef)
713 vx = (void *) *va.ppunkVal;
714 else
715 vx = (void *) va.punkVal;
716 return false;
717
718 case VT_DISPATCH: // should do a custom wxVariantData for this
719 if (byRef)
720 vx = (void *) *va.ppdispVal;
721 else
722 vx = (void *) va.pdispVal;
723 return false;
724
725 default:
726 vx.MakeNull();
727 return false;
728 };
729 };
730
731 bool VariantToMSWVariant(const wxVariant& vx, VARIANTARG& va)
732 {
733 bool byRef = false;
734 VARTYPE vt = va.vt;
735
736 if (vt & VT_ARRAY)
737 return false; // don't support arrays yet
738
739 if (vt & VT_BYREF)
740 {
741 byRef = true;
742 vt &= ~(VT_BYREF);
743 };
744
745 switch(vt)
746 {
747 case VT_VARIANT:
748 if (byRef)
749 return VariantToMSWVariant(vx, *va.pvarVal);
750 else
751 {
752 va.vt = wxTypeToVType(vx);
753 return VariantToMSWVariant(vx, va);
754 };
755
756 // 1 byte chars
757 case VT_I1:
758 case VT_UI1:
759 if (byRef)
760 *va.pbVal = (char) vx;
761 else
762 va.bVal = (char) vx;
763 return true;
764
765 // 2 byte shorts
766 case VT_I2:
767 case VT_UI2:
768 if (byRef)
769 *va.puiVal = (long) vx;
770 else
771 va.uiVal = (long) vx;
772 return true;
773
774 // 4 bytes longs
775 case VT_I4:
776 case VT_UI4:
777 case VT_INT:
778 case VT_UINT:
779 case VT_ERROR:
780 if (byRef)
781 *va.pulVal = (long) vx;
782 else
783 va.ulVal = (long) vx;
784 return true;
785
786
787 // 4 byte floats
788 case VT_R4:
789 if (byRef)
790 *va.pfltVal = (double) vx;
791 else
792 va.fltVal = (double) vx;
793 return true;
794
795 // 8 byte doubles
796 case VT_R8:
797 if (byRef)
798 *va.pdblVal = (double) vx;
799 else
800 va.dblVal = (double) vx;
801 return true;
802
803 case VT_BOOL:
804 if (byRef)
805 *va.pboolVal = ((bool) vx) ? TRUE : FALSE;
806 else
807 va.boolVal = ((bool) vx) ? TRUE : FALSE;
808 return true;
809
810 case VT_CY:
811 return false; // what the hell is a CY ?
812
813 case VT_DECIMAL:
814 if (byRef)
815 return SUCCEEDED(VarDecFromR8(vx, va.pdecVal));
816 else
817 return SUCCEEDED(VarDecFromR8(vx, &va.decVal));
818
819 case VT_DATE:
820 if (byRef)
821 return wxDateTimeToDATE(vx, *va.pdate);
822 else
823 return wxDateTimeToVariant(vx,va);
824
825 case VT_BSTR:
826 if (byRef)
827 *va.pbstrVal = SysAllocString(vx.GetString().wc_str(wxConvUTF8));
828 else
829 va.bstrVal = SysAllocString(vx.GetString().wc_str(wxConvUTF8));
830 return true;
831
832 case VT_UNKNOWN: // should do a custom wxVariantData for this
833 if (byRef)
834 *va.ppunkVal = (IUnknown *) (void *) vx;
835 else
836 va.punkVal = (IUnknown *) (void *) vx;
837 return false;
838
839 case VT_DISPATCH: // should do a custom wxVariantData for this
840 if (byRef)
841 *va.ppdispVal = (IDispatch *) (void *) vx;
842 else
843 va.pdispVal = (IDispatch *) (void *) vx;
844 return false;
845
846 default:
847 return false;
848 };
849 };
850
851 IMPLEMENT_CLASS(wxActiveXEvent, wxCommandEvent)
852
853 class wxActiveXEvents : public IDispatch
854 {
855 private:
856 DECLARE_OLE_UNKNOWN(wxActiveXEvents);
857
858
859 wxActiveX *m_activeX;
860 IID m_customId;
861 bool m_haveCustomId;
862
863 friend bool wxActiveXEventsInterface(wxActiveXEvents *self, REFIID iid, void **_interface, const char *&desc);
864
865 public:
866 wxActiveXEvents(wxActiveX *ax) : m_activeX(ax), m_haveCustomId(false) {}
867 wxActiveXEvents(wxActiveX *ax, REFIID iid) : m_activeX(ax), m_haveCustomId(true), m_customId(iid) {}
868 virtual ~wxActiveXEvents()
869 {
870 }
871
872 //IDispatch
873 STDMETHODIMP GetIDsOfNames(REFIID r, OLECHAR** o, unsigned int i, LCID l, DISPID* d)
874 {
875 return E_NOTIMPL;
876 };
877
878 STDMETHODIMP GetTypeInfo(unsigned int i, LCID l, ITypeInfo** t)
879 {
880 return E_NOTIMPL;
881 };
882
883 STDMETHODIMP GetTypeInfoCount(unsigned int* i)
884 {
885 return E_NOTIMPL;
886 };
887
888
889 void DispatchEvent(wxActiveX::FuncX &func, const wxEventType& eventType, DISPPARAMS * pDispParams)
890 {
891 wxActiveXEvent event;
892 event.SetId(m_activeX->GetId());
893 event.SetEventType(eventType);
894 event.m_params.NullList();
895 event.m_params.SetName(func.name);
896
897 // arguments
898 if (pDispParams)
899 {
900 // cdecl call
901 // sometimes the pDispParams does not match the param info for a activex control
902 int nArg = wxMin(func.params.size(), pDispParams->cArgs);
903 for (int i = nArg - 1; i >= 0; i--)
904 {
905 VARIANTARG& va = pDispParams->rgvarg[i];
906 wxActiveX::ParamX &px = func.params[nArg - i - 1];
907 wxVariant vx;
908
909 vx.SetName(px.name);
910 MSWVariantToVariant(va, vx);
911 event.m_params.Append(vx);
912 };
913 };
914
915 if (func.hasOut)
916 {
917 int nArg = wxMin(func.params.size(), pDispParams->cArgs);
918 m_activeX->GetEventHandler()->ProcessEvent(event);
919 for (int i = 0; i < nArg; i++)
920 {
921 VARIANTARG& va = pDispParams->rgvarg[i];
922 wxActiveX::ParamX &px = func.params[nArg - i - 1];
923
924 if (px.IsOut())
925 {
926 wxVariant& vx = event.m_params[nArg - i - 1];
927
928 VariantToMSWVariant(vx, va);
929 };
930 };
931 }
932 else
933 m_activeX->GetEventHandler()->AddPendingEvent(event);
934
935 };
936
937 STDMETHODIMP Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
938 WORD wFlags, DISPPARAMS * pDispParams,
939 VARIANT * pVarResult, EXCEPINFO * pExcepInfo,
940 unsigned int * puArgErr)
941 {
942 if (wFlags & (DISPATCH_PROPERTYGET | DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYPUTREF))
943 return E_NOTIMPL;
944
945 wxASSERT(m_activeX);
946
947 // find event for dispid
948 wxActiveX::MemberIdMap::iterator mit = m_activeX->m_eventMemberIds.find((MEMBERID) dispIdMember);
949 if (mit == m_activeX->m_eventMemberIds.end())
950 return S_OK;
951
952 // sanity check
953 int midx = mit->second;
954 if (midx < 0 || midx >= m_activeX->GetEventCount())
955 return S_OK;
956
957 wxActiveX::FuncX &func = m_activeX->m_events[midx];
958
959
960 // try to find dispid event
961 ActiveXDISPIDEventMap::iterator dit = sg_dispIdEventMap.find(dispIdMember);
962 if (dit != sg_dispIdEventMap.end())
963 {
964 // Dispatch Event
965 DispatchEvent(func, *(dit->second), pDispParams);
966 return S_OK;
967 };
968
969 // try named event
970 ActiveXNamedEventMap::iterator nit = sg_NamedEventMap.find(func.name);
971 if (nit == sg_NamedEventMap.end())
972 return S_OK;
973
974 // Dispatch Event
975 DispatchEvent(func, *(nit->second), pDispParams);
976 return S_OK;
977 }
978 };
979
980 bool wxActiveXEventsInterface(wxActiveXEvents *self, REFIID iid, void **_interface, const char *&desc)
981 {
982 if (self->m_haveCustomId && IsEqualIID(iid, self->m_customId))
983 {
984 WXOLE_TRACE("Found Custom Dispatch Interface");
985 *_interface = (IUnknown *) (IDispatch *) self;
986 desc = "Custom Dispatch Interface";
987 return true;
988 };
989
990 return false;
991 };
992
993 DEFINE_OLE_TABLE(wxActiveXEvents)
994 OLE_IINTERFACE(IUnknown)
995 OLE_INTERFACE(IID_IDispatch, IDispatch)
996 OLE_INTERFACE_CUSTOM(wxActiveXEventsInterface)
997 END_OLE_TABLE;
998
999 wxString wxActiveXEvent::EventName()
1000 {
1001 return m_params.GetName();
1002 };
1003
1004 int wxActiveXEvent::ParamCount() const
1005 {
1006 return m_params.GetCount();
1007 };
1008
1009 wxString wxActiveXEvent::ParamType(int idx)
1010 {
1011 wxASSERT(idx >= 0 && idx < m_params.GetCount());
1012
1013 return m_params[idx].GetType();
1014 };
1015
1016 wxString wxActiveXEvent::ParamName(int idx)
1017 {
1018 wxASSERT(idx >= 0 && idx < m_params.GetCount());
1019
1020 return m_params[idx].GetName();
1021 };
1022
1023 static wxVariant nullVar;
1024
1025 wxVariant& wxActiveXEvent::operator[] (int idx)
1026 {
1027 wxASSERT(idx >= 0 && idx < ParamCount());
1028
1029 return m_params[idx];
1030 };
1031
1032 wxVariant& wxActiveXEvent::operator[] (wxString name)
1033 {
1034 for (int i = 0; i < m_params.GetCount(); i++)
1035 {
1036 if (name.CmpNoCase(m_params[i].GetName()) == 0)
1037 return m_params[i];
1038 };
1039
1040 wxString err = _T("wxActiveXEvent::operator[] invalid name <") + name + _T(">");
1041 err += _T("\r\nValid Names = :\r\n");
1042 for (i = 0; i < m_params.GetCount(); i++)
1043 {
1044 err += m_params[i].GetName();
1045 err += _T("\r\n");
1046 };
1047
1048 wxASSERT_MSG(false, err);
1049
1050 return nullVar;
1051 };
1052
1053 void wxActiveX::GetTypeInfo()
1054 {
1055 /*
1056 We are currently only interested in the IDispatch interface
1057 to the control. For dual interfaces (TypeKind = TKIND_INTERFACE)
1058 we should drill down through the inheritance
1059 (using TYPEATTR->cImplTypes) and GetRefTypeOfImplType(n)
1060 and retrieve all the func names etc that way, then generate a C++
1061 header file for it.
1062
1063 But we don't do this and probably never will, so if we have a DUAL
1064 interface then we query for the IDispatch
1065 via GetRefTypeOfImplType(-1).
1066 */
1067
1068 HRESULT hret = 0;
1069
1070 // get type info via class info
1071 wxAutoOleInterface<IProvideClassInfo> classInfo(IID_IProvideClassInfo, m_ActiveX);
1072 if (! classInfo.Ok())
1073 return;
1074
1075 // type info
1076 wxAutoOleInterface<ITypeInfo> typeInfo;
1077 hret = classInfo->GetClassInfo(typeInfo.GetRef());
1078 if (! typeInfo.Ok())
1079 return;
1080
1081 // TYPEATTR
1082 TYPEATTR *ta = NULL;
1083 hret = typeInfo->GetTypeAttr(&ta);
1084 if (! ta)
1085 return;
1086
1087 // this should be a TKIND_COCLASS
1088 wxASSERT(ta->typekind == TKIND_COCLASS);
1089
1090 // iterate contained interfaces
1091 for (int i = 0; i < ta->cImplTypes; i++)
1092 {
1093 HREFTYPE rt = 0;
1094
1095 // get dispatch type info handle
1096 hret = typeInfo->GetRefTypeOfImplType(i, &rt);
1097 if (! SUCCEEDED(hret))
1098 continue;
1099
1100 // get dispatch type info interface
1101 wxAutoOleInterface<ITypeInfo> ti;
1102 hret = typeInfo->GetRefTypeInfo(rt, ti.GetRef());
1103 if (! ti.Ok())
1104 continue;
1105
1106 // check if default event sink
1107 bool defInterface = false;
1108 bool defEventSink = false;
1109 int impTypeFlags = 0;
1110 typeInfo->GetImplTypeFlags(i, &impTypeFlags);
1111
1112 if (impTypeFlags & IMPLTYPEFLAG_FDEFAULT)
1113 {
1114 if (impTypeFlags & IMPLTYPEFLAG_FSOURCE)
1115 {
1116 WXOLE_TRACEOUT("Default Event Sink");
1117 defEventSink = true;
1118 if (impTypeFlags & IMPLTYPEFLAG_FDEFAULTVTABLE)
1119 {
1120 WXOLE_TRACEOUT("*ERROR* - Default Event Sink is via vTable");
1121 defEventSink = false;
1122 };
1123 }
1124 else
1125 {
1126 WXOLE_TRACEOUT("Default Interface");
1127 defInterface = true;
1128 }
1129 };
1130
1131
1132 // process
1133 GetTypeInfo(ti, defInterface, defEventSink);
1134 };
1135
1136
1137 // free
1138 typeInfo->ReleaseTypeAttr(ta);
1139 };
1140
1141 void ElemDescToParam(const ELEMDESC& ed, wxActiveX::ParamX& param)
1142 {
1143 param.flags = ed.idldesc.wIDLFlags;
1144 param.vt = ed.tdesc.vt;
1145 param.isPtr = (param.vt == VT_PTR);
1146 param.isSafeArray = (param.vt == VT_SAFEARRAY);
1147 if (param.isPtr || param.isSafeArray)
1148 param.vt = ed.tdesc.lptdesc->vt;
1149 };
1150
1151 void wxActiveX::GetTypeInfo(ITypeInfo *ti, bool defInterface, bool defEventSink)
1152 {
1153 // wxAutoOleInterface<> assumes a ref has already been added
1154 ti->AddRef();
1155 wxAutoOleInterface<ITypeInfo> typeInfo(ti);
1156
1157 // TYPEATTR
1158 TYPEATTR *ta = NULL;
1159 HRESULT hret = typeInfo->GetTypeAttr(&ta);
1160 if (! ta)
1161 return;
1162
1163 if (ta->typekind == TKIND_DISPATCH)
1164 {
1165 WXOLE_TRACEOUT("GUID = " << GetIIDName(ta->guid).c_str());
1166
1167 if (defEventSink)
1168 {
1169 wxActiveXEvents *disp = new wxActiveXEvents(this, ta->guid);
1170 ConnectAdvise(ta->guid, disp);
1171 };
1172
1173 // Get properties
1174 // See bug #1280715 in the wxActiveX SF project
1175 for (int i = 0; i < ta->cVars; i++) {
1176 VARDESC FAR *vd = NULL;
1177
1178 typeInfo->GetVarDesc(i, &vd) ;
1179 BSTR bstrProperty = NULL;
1180 typeInfo->GetDocumentation(vd->memid, &bstrProperty,
1181 NULL, NULL, NULL);
1182 wxString propName(bstrProperty);
1183 m_props.push_back(PropX());
1184 int idx = m_props.size() - 1;
1185 m_propNames[propName] = idx;
1186 m_props[idx].name = propName;
1187 m_props[idx].memid = vd->memid;
1188
1189 ParamX param;
1190 param.isSafeArray = false;
1191 param.isPtr = false;
1192 param.flags = vd->elemdescVar.idldesc.wIDLFlags;
1193 param.vt = vd->elemdescVar.tdesc.vt;
1194
1195 m_props[idx].arg = param;
1196 m_props[idx].type = param;
1197 }
1198
1199 // Get Function Names
1200 for (int i = 0; i < ta->cFuncs; i++)
1201 {
1202 FUNCDESC FAR *fd = NULL;
1203
1204 hret = typeInfo->GetFuncDesc(i, &fd);
1205 if (! fd)
1206 continue;
1207
1208 BSTR anames[1] = {NULL};
1209 unsigned int n = 0;
1210
1211 hret = typeInfo->GetNames(fd->memid, anames, 1, &n);
1212
1213 if (anames[0])
1214 {
1215 wxString name = anames[0];
1216
1217 WXOLE_TRACEOUT("Name " << i << " = " << name.c_str());
1218 SysFreeString(anames[0]);
1219
1220 if (defInterface || defEventSink)
1221 {
1222 FuncX func;
1223 func.name = name;
1224 func.memid = fd->memid;
1225 func.hasOut = false;
1226
1227 // get Param Names
1228 unsigned int maxPNames = fd->cParams + 1;
1229 unsigned int nPNames = 0;
1230 BSTR *pnames = new BSTR[maxPNames];
1231
1232 hret = typeInfo->GetNames(fd->memid, pnames, maxPNames, &nPNames);
1233
1234 int pbase = 0;
1235 if (fd->cParams < int(nPNames))
1236 {
1237 pbase++;
1238 SysFreeString(pnames[0]);
1239 };
1240
1241 // params
1242 ElemDescToParam(fd->elemdescFunc, func.retType);
1243 for (int p = 0; p < fd->cParams; p++)
1244 {
1245 ParamX param;
1246
1247 ElemDescToParam(fd->lprgelemdescParam[p], param);
1248
1249 param.name = pnames[pbase + p];
1250 SysFreeString(pnames[pbase + p]);
1251
1252 param.isOptional = (p > fd->cParams - fd->cParamsOpt);
1253
1254 func.hasOut |= (param.IsOut() || param.isPtr);
1255 func.params.push_back(param);
1256 };
1257 delete [] pnames;
1258
1259 if (defEventSink)
1260 {
1261 m_events.push_back(func);
1262 m_eventMemberIds[fd->memid] = m_events.size() - 1;
1263 }
1264 else
1265 {
1266 if (fd->invkind == INVOKE_FUNC)
1267 {
1268 m_methods.push_back(func);
1269 m_methodNames[func.name] = m_methods.size() - 1;
1270 }
1271 else
1272 {
1273 NameMap::iterator it = m_propNames.find(func.name);
1274 int idx = -1;
1275 if (it == m_propNames.end())
1276 {
1277 m_props.push_back(PropX());
1278 idx = m_props.size() - 1;
1279 m_propNames[func.name] = idx;
1280 m_props[idx].name = func.name;
1281 m_props[idx].memid = func.memid;
1282
1283 }
1284 else
1285 idx = it->second;
1286
1287 if (fd->invkind == INVOKE_PROPERTYGET)
1288 m_props[idx].type = func.retType;
1289 else if (func.params.size() > 0)
1290 {
1291 m_props[idx].arg = func.params[0];
1292 m_props[idx].putByRef = (fd->invkind == INVOKE_PROPERTYPUTREF);
1293 };
1294 };
1295 };
1296 };
1297 };
1298
1299 typeInfo->ReleaseFuncDesc(fd);
1300 };
1301 }
1302
1303 typeInfo->ReleaseTypeAttr(ta);
1304 };
1305
1306 ///////////////////////////////////////////////
1307 // Type Info exposure
1308 const wxActiveX::FuncX& wxActiveX::GetEventDesc(int idx) const
1309 {
1310 wxASSERT(idx >= 0 && idx < GetEventCount());
1311
1312 return m_events[idx];
1313 };
1314
1315 const wxActiveX::PropX& wxActiveX::GetPropDesc(int idx) const
1316 {
1317 if (idx < 0 || idx >= GetPropCount())
1318 throw exception("Property index out of bounds");
1319
1320 return m_props[idx];
1321 };
1322
1323 const wxActiveX::PropX& wxActiveX::GetPropDesc(const wxString& name) const
1324 {
1325 NameMap::const_iterator it = m_propNames.find(name);
1326 if (it == m_propNames.end())
1327 {
1328 wxString s;
1329 s << _T("property <") << name << _T("> not found");
1330 throw exception(s.mb_str());
1331 };
1332
1333 return GetPropDesc(it->second);
1334 };
1335
1336 const wxActiveX::FuncX& wxActiveX::GetMethodDesc(int idx) const
1337 {
1338 if (idx < 0 || idx >= GetMethodCount())
1339 throw exception("Method index out of bounds");
1340
1341
1342 return m_methods[idx];
1343 };
1344
1345
1346 const wxActiveX::FuncX& wxActiveX::GetMethodDesc(const wxString& name) const
1347 {
1348 NameMap::const_iterator it = m_methodNames.find(name);
1349 if (it == m_methodNames.end())
1350 {
1351 wxString s;
1352 s << _T("method <") << name << _T("> not found");
1353 throw exception(s.mb_str());
1354 };
1355
1356 return GetMethodDesc(it->second);
1357 };
1358
1359
1360 void wxActiveX::SetProp(MEMBERID name, VARIANTARG& value)
1361 {
1362 DISPID pids[1] = {DISPID_PROPERTYPUT};
1363 DISPPARAMS params = {&value, pids, 1, 1};
1364
1365 EXCEPINFO x;
1366 memset(&x, 0, sizeof(x));
1367 unsigned int argErr = 0;
1368
1369 HRESULT hr = m_Dispatch->Invoke(
1370 name,
1371 IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT,
1372 &params, NULL, &x, &argErr);
1373
1374 WXOLE_WARN(hr, "Invoke Prop(...)");
1375 };
1376
1377 void wxActiveX::SetProp(const wxString &name, const wxVariant &value)
1378 {
1379 const PropX& prop = GetPropDesc(name);
1380 if (! prop.CanSet())
1381 {
1382 wxString s;
1383 s << _T("property <") << name << _T("> is readonly");
1384 throw exception(s.mb_str());
1385 };
1386
1387 VARIANT v = {prop.arg.vt};
1388 VariantToMSWVariant(value, v);
1389 SetProp(prop.memid, v);
1390 VariantClear(&v); // this releases any BSTR's etc
1391 };
1392
1393 VARIANT wxActiveX::GetPropAsVariant(MEMBERID name)
1394 {
1395 VARIANT v;
1396 VariantInit(&v);
1397
1398 DISPPARAMS params = {NULL, NULL, 0, 0};
1399
1400 EXCEPINFO x;
1401 memset(&x, 0, sizeof(x));
1402 unsigned int argErr = 0;
1403
1404 HRESULT hr = m_Dispatch->Invoke(
1405 name,
1406 IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET,
1407 &params, &v, &x, &argErr);
1408
1409 WXOLE_WARN(hr, "Invoke Prop(...)");
1410
1411 return v;
1412 };
1413
1414 VARIANT wxActiveX::GetPropAsVariant(const wxString& name)
1415 {
1416 const PropX& prop = GetPropDesc(name);
1417 if (! prop.CanGet())
1418 {
1419 wxString s;
1420 s << _T("property <") << name << _T("> is writeonly");
1421 throw exception(s.mb_str());
1422 };
1423
1424 return GetPropAsVariant(prop.memid);
1425 };
1426
1427 wxVariant wxActiveX::GetPropAsWxVariant(const wxString& name)
1428 {
1429 VARIANT v = GetPropAsVariant(name);
1430 HRESULT hr = VariantChangeType(&v, &v, 0, VT_BSTR);
1431 if (! SUCCEEDED(hr))
1432 throw exception("Unable to convert variant");
1433
1434 wxVariant wv;
1435 MSWVariantToVariant(v, wv);
1436
1437 VariantClear(&v);
1438
1439 return wv;
1440 };
1441
1442 wxString wxActiveX::GetPropAsString(const wxString& name)
1443 {
1444 VARIANT v = GetPropAsVariant(name);
1445 HRESULT hr = VariantChangeType(&v, &v, 0, VT_BSTR);
1446 if (! SUCCEEDED(hr))
1447 throw exception("Unable to convert variant");
1448
1449 wxString s = v.bstrVal;
1450 VariantClear(&v);
1451
1452 return s;
1453 };
1454
1455 char wxActiveX::GetPropAsChar(const wxString& name)
1456 {
1457 VARIANT v = GetPropAsVariant(name);
1458 HRESULT hr = VariantChangeType(&v, &v, 0, VT_I1);
1459 if (! SUCCEEDED(hr))
1460 throw exception("Unable to convert variant");
1461
1462 return v.cVal;
1463 };
1464
1465 long wxActiveX::GetPropAsLong(const wxString& name)
1466 {
1467 VARIANT v = GetPropAsVariant(name);
1468 HRESULT hr = VariantChangeType(&v, &v, 0, VT_I4);
1469 if (! SUCCEEDED(hr))
1470 throw exception("Unable to convert variant");
1471
1472 return v.iVal;
1473 };
1474
1475 bool wxActiveX::GetPropAsBool(const wxString& name)
1476 {
1477 VARIANT v = GetPropAsVariant(name);
1478 HRESULT hr = VariantChangeType(&v, &v, 0, VT_BOOL);
1479 if (! SUCCEEDED(hr))
1480 throw exception("Unable to convert variant");
1481
1482 return v.boolVal != 0;
1483 };
1484
1485 double wxActiveX::GetPropAsDouble(const wxString& name)
1486 {
1487 VARIANT v = GetPropAsVariant(name);
1488 HRESULT hr = VariantChangeType(&v, &v, 0, VT_R8);
1489 if (! SUCCEEDED(hr))
1490 throw exception("Unable to convert variant");
1491
1492 return v.dblVal;
1493 };
1494
1495 wxDateTime wxActiveX::GetPropAsDateTime(const wxString& name)
1496 {
1497 wxDateTime dt;
1498 VARIANT v = GetPropAsVariant(name);
1499
1500 if (! VariantToWxDateTime(v, dt))
1501 throw exception("Unable to convert variant to wxDateTime");
1502
1503 return dt;
1504 };
1505
1506 void *wxActiveX::GetPropAsPointer(const wxString& name)
1507 {
1508 VARIANT v = GetPropAsVariant(name);
1509 HRESULT hr = VariantChangeType(&v, &v, 0, VT_BYREF);
1510 if (! SUCCEEDED(hr))
1511 throw exception("Unable to convert variant");
1512
1513 return v.byref;
1514 };
1515
1516
1517
1518 // call methods
1519 VARIANT wxActiveX::CallMethod(MEMBERID name, VARIANTARG args[], int argc)
1520 {
1521 DISPPARAMS pargs = {args, NULL, argc, 0};
1522 VARIANT retVal;
1523 VariantInit(&retVal);
1524
1525 EXCEPINFO x;
1526 memset(&x, 0, sizeof(x));
1527 unsigned int argErr = 0;
1528
1529 HRESULT hr = m_Dispatch->Invoke(
1530 name,
1531 IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD,
1532 &pargs, &retVal, &x, &argErr);
1533
1534 WXOLE_WARN(hr, "Invoke Method(...)");
1535 return retVal;
1536 };
1537
1538 VARIANT wxActiveX::CallMethod(const wxString& name, VARIANTARG args[], int argc)
1539 {
1540 const FuncX& func = GetMethodDesc(name);
1541 if (argc < 0)
1542 argc = func.params.size();
1543
1544 return CallMethod(func.memid, args, argc);
1545 };
1546
1547
1548 wxVariant wxActiveX::CallMethod(const wxString& name, wxVariant args[], int nargs)
1549 {
1550 const FuncX& func = GetMethodDesc(name);
1551
1552 if (args == NULL)
1553 nargs = 0;
1554
1555 VARIANTARG *vargs = NULL;
1556 if (nargs < 0)
1557 nargs = func.params.size();
1558
1559 if (nargs > 0)
1560 vargs = new VARIANTARG[nargs];
1561
1562 if (vargs)
1563 {
1564 // init type of vargs
1565 for (int i = 0; i < nargs; i++)
1566 vargs[nargs - i - 1].vt = func.params[i].vt;
1567
1568 // put data
1569 for (i = 0; i < nargs; i++)
1570 VariantToMSWVariant(args[i], vargs[nargs - i - 1]);
1571 };
1572
1573 VARIANT rv = CallMethod(func.memid, vargs, nargs);
1574
1575 // process any by ref params
1576 if (func.hasOut)
1577 {
1578 for (int i = 0; i < nargs; i++)
1579 {
1580 VARIANTARG& va = vargs[nargs - i - 1];
1581 const wxActiveX::ParamX &px = func.params[i];
1582
1583 if (px.IsOut())
1584 {
1585 wxVariant& vx = args[i];
1586
1587 MSWVariantToVariant(va, vx);
1588 };
1589 };
1590 }
1591
1592 if (vargs)
1593 {
1594 for (int i = 0; i < nargs; i++)
1595 VariantClear(&vargs[i]);
1596 delete [] vargs;
1597 };
1598
1599 wxVariant ret;
1600
1601 MSWVariantToVariant(rv, ret);
1602 VariantClear(&rv);
1603
1604 return ret;
1605 };
1606
1607
1608 ///////////////////////////////////////////////
1609
1610 HRESULT wxActiveX::ConnectAdvise(REFIID riid, IUnknown *events)
1611 {
1612 wxOleConnectionPoint cp;
1613 DWORD adviseCookie = 0;
1614
1615 wxAutoOleInterface<IConnectionPointContainer> cpContainer(IID_IConnectionPointContainer, m_ActiveX);
1616 if (! cpContainer.Ok())
1617 return E_FAIL;
1618
1619 HRESULT hret = cpContainer->FindConnectionPoint(riid, cp.GetRef());
1620 if (! SUCCEEDED(hret))
1621 return hret;
1622
1623 hret = cp->Advise(events, &adviseCookie);
1624
1625 if (SUCCEEDED(hret))
1626 m_connections.push_back(wxOleConnection(cp, adviseCookie));
1627 else
1628 {
1629 WXOLE_WARN(hret, "ConnectAdvise");
1630 };
1631
1632 return hret;
1633 };
1634
1635 HRESULT wxActiveX::AmbientPropertyChanged(DISPID dispid)
1636 {
1637 wxAutoOleInterface<IOleControl> oleControl(IID_IOleControl, m_oleObject);
1638
1639 if (oleControl.Ok())
1640 return oleControl->OnAmbientPropertyChange(dispid);
1641 else
1642 return S_FALSE;
1643 };
1644
1645 #define HIMETRIC_PER_INCH 2540
1646 #define MAP_PIX_TO_LOGHIM(x,ppli) MulDiv(HIMETRIC_PER_INCH, (x), (ppli))
1647
1648 static void PixelsToHimetric(SIZEL &sz)
1649 {
1650 static int logX = 0;
1651 static int logY = 0;
1652
1653 if (logY == 0)
1654 {
1655 // initaliase
1656 HDC dc = GetDC(NULL);
1657 logX = GetDeviceCaps(dc, LOGPIXELSX);
1658 logY = GetDeviceCaps(dc, LOGPIXELSY);
1659 ReleaseDC(NULL, dc);
1660 };
1661
1662 #define HIMETRIC_INCH 2540
1663 #define CONVERT(x, logpixels) MulDiv(HIMETRIC_INCH, (x), (logpixels))
1664
1665 sz.cx = CONVERT(sz.cx, logX);
1666 sz.cy = CONVERT(sz.cy, logY);
1667
1668 #undef CONVERT
1669 #undef HIMETRIC_INCH
1670 }
1671
1672
1673 void wxActiveX::OnSize(wxSizeEvent& event)
1674 {
1675 int w, h;
1676 GetClientSize(&w, &h);
1677
1678 RECT posRect;
1679 posRect.left = 0;
1680 posRect.top = 0;
1681 posRect.right = w;
1682 posRect.bottom = h;
1683
1684 if (w <= 0 && h <= 0)
1685 return;
1686
1687 // extents are in HIMETRIC units
1688 if (m_oleObject.Ok())
1689 {
1690 SIZEL sz = {w, h};
1691 PixelsToHimetric(sz);
1692
1693 SIZEL sz2;
1694
1695 m_oleObject->GetExtent(DVASPECT_CONTENT, &sz2);
1696 if (sz2.cx != sz.cx || sz.cy != sz2.cy)
1697 m_oleObject->SetExtent(DVASPECT_CONTENT, &sz);
1698 };
1699
1700 if (m_oleInPlaceObject.Ok())
1701 m_oleInPlaceObject->SetObjectRects(&posRect, &posRect);
1702 }
1703
1704 void wxActiveX::OnPaint(wxPaintEvent& event)
1705 {
1706 wxLogTrace(wxT(""),wxT("repainting activex win"));
1707 wxPaintDC dc(this);
1708 dc.BeginDrawing();
1709 int w, h;
1710 GetSize(&w, &h);
1711 RECT posRect;
1712 posRect.left = 0;
1713 posRect.top = 0;
1714 posRect.right = w;
1715 posRect.bottom = h;
1716
1717 // Draw only when control is windowless or deactivated
1718 if (m_viewObject)
1719 {
1720 ::RedrawWindow(m_oleObjectHWND, NULL, NULL, RDW_INTERNALPAINT);
1721 {
1722 RECTL *prcBounds = (RECTL *) &posRect;
1723 m_viewObject->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL,
1724 (HDC)dc.GetHDC(), prcBounds, NULL, NULL, 0);
1725 }
1726 }
1727 else
1728 {
1729 dc.SetBrush(*wxRED_BRUSH);
1730 dc.DrawRectangle(0, 0, w, h);
1731 dc.SetBrush(wxNullBrush);
1732 }
1733 dc.EndDrawing();
1734 }
1735
1736
1737 void wxActiveX::OnMouse(wxMouseEvent& event)
1738 {
1739 if (m_oleObjectHWND == NULL)
1740 {
1741 wxLogTrace(wxT(""),wxT("no oleInPlaceObject"));
1742 event.Skip();
1743 return;
1744 }
1745
1746 wxLogTrace(wxT(""),wxT("mouse event"));
1747 UINT msg = 0;
1748 WPARAM wParam = 0;
1749 LPARAM lParam = 0;
1750 LRESULT lResult = 0;
1751
1752 if (event.m_metaDown)
1753 wParam |= MK_CONTROL;
1754 if (event.m_shiftDown)
1755 wParam |= MK_SHIFT;
1756 if (event.m_leftDown)
1757 wParam |= MK_LBUTTON;
1758 if (event.m_middleDown)
1759 wParam |= MK_MBUTTON;
1760 if (event.m_rightDown)
1761 wParam |= MK_RBUTTON;
1762 lParam = event.m_x << 16;
1763 lParam |= event.m_y;
1764
1765 if (event.LeftDown())
1766 msg = WM_LBUTTONDOWN;
1767 else if (event.LeftDClick())
1768 msg = WM_LBUTTONDBLCLK;
1769 else if (event.LeftUp())
1770 msg = WM_LBUTTONUP;
1771 else if (event.MiddleDown())
1772 msg = WM_MBUTTONDOWN;
1773 else if (event.MiddleDClick())
1774 msg = WM_MBUTTONDBLCLK;
1775 else if (event.MiddleUp())
1776 msg = WM_MBUTTONUP;
1777 else if (event.RightDown())
1778 msg = WM_RBUTTONDOWN;
1779 else if (event.RightDClick())
1780 msg = WM_RBUTTONDBLCLK;
1781 else if (event.RightUp())
1782 msg = WM_RBUTTONUP;
1783 else if (event.Moving() || event.Dragging())
1784 msg = WM_MOUSEMOVE;
1785
1786 wxString log;
1787 if (msg == 0)
1788 {
1789 wxLogTrace(wxT(""),wxT("no message"));
1790 event.Skip(); return;
1791 };
1792
1793 if (!::SendMessage(m_oleObjectHWND, msg, wParam, lParam))
1794 {
1795 wxLogTrace(wxT(""),wxT("msg not delivered"));
1796 event.Skip();
1797 return;
1798 };
1799
1800 wxLogTrace(wxT(""),wxT("msg sent"));
1801 }
1802
1803 bool wxActiveX::MSWTranslateMessage(WXMSG *msg){
1804
1805 if (msg->message == WM_KEYDOWN){
1806 HRESULT result = m_oleInPlaceActiveObject->TranslateAccelerator(msg);
1807 return (result == S_OK);
1808 }
1809
1810 return wxWindow::MSWTranslateMessage(msg);
1811 }
1812
1813 long wxActiveX::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
1814 {
1815 if (m_oleObjectHWND == NULL)
1816 return wxWindow::MSWWindowProc(nMsg, wParam, lParam);
1817
1818 switch(nMsg)
1819 {
1820 case WM_CHAR:
1821 case WM_DEADCHAR:
1822 case WM_KEYDOWN:
1823 case WM_KEYUP:
1824 case WM_SYSCHAR:
1825 case WM_SYSDEADCHAR:
1826 case WM_SYSKEYDOWN:
1827 case WM_SYSKEYUP:
1828 PostMessage(m_oleObjectHWND, nMsg, wParam, lParam);
1829
1830 default:
1831 return wxWindow::MSWWindowProc(nMsg, wParam, lParam);
1832 };
1833 };
1834
1835 void wxActiveX::OnSetFocus(wxFocusEvent& event)
1836 {
1837 if (m_oleInPlaceActiveObject.Ok())
1838 m_oleInPlaceActiveObject->OnFrameWindowActivate(TRUE);
1839 }
1840
1841 void wxActiveX::OnKillFocus(wxFocusEvent& event)
1842 {
1843 if (m_oleInPlaceActiveObject.Ok())
1844 m_oleInPlaceActiveObject->OnFrameWindowActivate(FALSE);
1845 }
1846
1847
1848 FrameSite::FrameSite(wxActiveX * win)
1849 {
1850 m_window = win;
1851 m_bSupportsWindowlessActivation = true;
1852 m_bInPlaceLocked = false;
1853 m_bUIActive = false;
1854 m_bInPlaceActive = false;
1855 m_bWindowless = false;
1856
1857 m_nAmbientLocale = 0;
1858 m_clrAmbientForeColor = ::GetSysColor(COLOR_WINDOWTEXT);
1859 m_clrAmbientBackColor = ::GetSysColor(COLOR_WINDOW);
1860 m_bAmbientShowHatching = true;
1861 m_bAmbientShowGrabHandles = true;
1862 m_bAmbientAppearance = true;
1863
1864 m_hDCBuffer = NULL;
1865 m_hWndParent = (HWND)m_window->GetHWND();
1866 }
1867
1868 FrameSite::~FrameSite()
1869 {
1870 }
1871
1872
1873 //IDispatch
1874
1875 HRESULT FrameSite::GetIDsOfNames(REFIID riid, OLECHAR ** rgszNames, unsigned int cNames,
1876 LCID lcid, DISPID * rgDispId)
1877 {
1878 WXOLE_TRACE("IDispatch::GetIDsOfNames");
1879 return E_NOTIMPL;
1880 }
1881
1882 HRESULT FrameSite::GetTypeInfo(unsigned int iTInfo, LCID lcid, ITypeInfo ** ppTInfo)
1883 {
1884 WXOLE_TRACE("IDispatch::GetTypeInfo");
1885 return E_NOTIMPL;
1886 }
1887
1888 HRESULT FrameSite::GetTypeInfoCount(unsigned int * pcTInfo)
1889 {
1890 WXOLE_TRACE("IDispatch::GetTypeInfoCount");
1891 return E_NOTIMPL;
1892 }
1893
1894 HRESULT FrameSite::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
1895 WORD wFlags, DISPPARAMS * pDispParams,
1896 VARIANT * pVarResult, EXCEPINFO * pExcepInfo,
1897 unsigned int * puArgErr)
1898 {
1899 WXOLE_TRACE("IDispatch::Invoke");
1900
1901 if (!(wFlags & DISPATCH_PROPERTYGET))
1902 return S_OK;
1903
1904 HRESULT hr;
1905
1906 if (pVarResult == NULL)
1907 return E_INVALIDARG;
1908
1909 //The most common case is boolean, use as an initial type
1910 V_VT(pVarResult) = VT_BOOL;
1911
1912 switch (dispIdMember)
1913 {
1914 case DISPID_AMBIENT_MESSAGEREFLECT:
1915 WXOLE_TRACE("Invoke::DISPID_AMBIENT_MESSAGEREFLECT");
1916 V_BOOL(pVarResult)= FALSE;
1917 return S_OK;
1918
1919 case DISPID_AMBIENT_DISPLAYASDEFAULT:
1920 WXOLE_TRACE("Invoke::DISPID_AMBIENT_DISPLAYASDEFAULT");
1921 V_BOOL(pVarResult)= TRUE;
1922 return S_OK;
1923
1924 case DISPID_AMBIENT_OFFLINEIFNOTCONNECTED:
1925 WXOLE_TRACE("Invoke::DISPID_AMBIENT_OFFLINEIFNOTCONNECTED");
1926 V_BOOL(pVarResult) = TRUE;
1927 return S_OK;
1928
1929
1930 case DISPID_AMBIENT_SILENT:
1931 WXOLE_TRACE("Invoke::DISPID_AMBIENT_SILENT");
1932 V_BOOL(pVarResult)= TRUE;
1933 return S_OK;
1934
1935 case DISPID_AMBIENT_APPEARANCE:
1936 pVarResult->vt = VT_BOOL;
1937 pVarResult->boolVal = m_bAmbientAppearance;
1938 break;
1939
1940 case DISPID_AMBIENT_FORECOLOR:
1941 pVarResult->vt = VT_I4;
1942 pVarResult->lVal = (long) m_clrAmbientForeColor;
1943 break;
1944
1945 case DISPID_AMBIENT_BACKCOLOR:
1946 pVarResult->vt = VT_I4;
1947 pVarResult->lVal = (long) m_clrAmbientBackColor;
1948 break;
1949
1950 case DISPID_AMBIENT_LOCALEID:
1951 pVarResult->vt = VT_I4;
1952 pVarResult->lVal = (long) m_nAmbientLocale;
1953 break;
1954
1955 case DISPID_AMBIENT_USERMODE:
1956 pVarResult->vt = VT_BOOL;
1957 pVarResult->boolVal = m_window->m_bAmbientUserMode;
1958 break;
1959
1960 case DISPID_AMBIENT_SHOWGRABHANDLES:
1961 pVarResult->vt = VT_BOOL;
1962 pVarResult->boolVal = m_bAmbientShowGrabHandles;
1963 break;
1964
1965 case DISPID_AMBIENT_SHOWHATCHING:
1966 pVarResult->vt = VT_BOOL;
1967 pVarResult->boolVal = m_bAmbientShowHatching;
1968 break;
1969
1970 default:
1971 return DISP_E_MEMBERNOTFOUND;
1972 }
1973
1974 return S_OK;
1975 }
1976
1977 //IOleWindow
1978
1979 HRESULT FrameSite::GetWindow(HWND * phwnd)
1980 {
1981 WXOLE_TRACE("IOleWindow::GetWindow");
1982 if (phwnd == NULL)
1983 return E_INVALIDARG;
1984 (*phwnd) = m_hWndParent;
1985 return S_OK;
1986 }
1987
1988 HRESULT FrameSite::ContextSensitiveHelp(BOOL fEnterMode)
1989 {
1990 WXOLE_TRACE("IOleWindow::ContextSensitiveHelp");
1991 return S_OK;
1992 }
1993
1994 //IOleInPlaceUIWindow
1995
1996 HRESULT FrameSite::GetBorder(LPRECT lprectBorder)
1997 {
1998 WXOLE_TRACE("IOleInPlaceUIWindow::GetBorder");
1999 if (lprectBorder == NULL)
2000 return E_INVALIDARG;
2001 return INPLACE_E_NOTOOLSPACE;
2002 }
2003
2004 HRESULT FrameSite::RequestBorderSpace(LPCBORDERWIDTHS pborderwidths)
2005 {
2006 WXOLE_TRACE("IOleInPlaceUIWindow::RequestBorderSpace");
2007 if (pborderwidths == NULL)
2008 return E_INVALIDARG;
2009 return INPLACE_E_NOTOOLSPACE;
2010 }
2011
2012 HRESULT FrameSite::SetBorderSpace(LPCBORDERWIDTHS pborderwidths)
2013 {
2014 WXOLE_TRACE("IOleInPlaceUIWindow::SetBorderSpace");
2015 return S_OK;
2016 }
2017
2018 HRESULT FrameSite::SetActiveObject(IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName)
2019 {
2020 WXOLE_TRACE("IOleInPlaceUIWindow::SetActiveObject");
2021
2022 if (pActiveObject)
2023 pActiveObject->AddRef();
2024
2025 m_window->m_oleInPlaceActiveObject = pActiveObject;
2026 return S_OK;
2027 }
2028
2029 //IOleInPlaceFrame
2030
2031 HRESULT FrameSite::InsertMenus(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths)
2032 {
2033 WXOLE_TRACE("IOleInPlaceFrame::InsertMenus");
2034 return S_OK;
2035 }
2036
2037 HRESULT FrameSite::SetMenu(HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject)
2038 {
2039 WXOLE_TRACE("IOleInPlaceFrame::SetMenu");
2040 return S_OK;
2041 }
2042
2043 HRESULT FrameSite::RemoveMenus(HMENU hmenuShared)
2044 {
2045 WXOLE_TRACE("IOleInPlaceFrame::RemoveMenus");
2046 return S_OK;
2047 }
2048
2049 HRESULT FrameSite::SetStatusText(LPCOLESTR pszStatusText)
2050 {
2051 WXOLE_TRACE("IOleInPlaceFrame::SetStatusText");
2052 //((wxFrame*)wxGetApp().GetTopWindow())->GetStatusBar()->SetStatusText(pszStatusText);
2053 return S_OK;
2054 }
2055
2056 HRESULT FrameSite::EnableModeless(BOOL fEnable)
2057 {
2058 WXOLE_TRACE("IOleInPlaceFrame::EnableModeless");
2059 return S_OK;
2060 }
2061
2062 HRESULT FrameSite::TranslateAccelerator(LPMSG lpmsg, WORD wID)
2063 {
2064 WXOLE_TRACE("IOleInPlaceFrame::TranslateAccelerator");
2065 // TODO: send an event with this id
2066 if (m_window->m_oleInPlaceActiveObject.Ok())
2067 m_window->m_oleInPlaceActiveObject->TranslateAccelerator(lpmsg);
2068
2069 return S_FALSE;
2070 }
2071
2072 //IOleInPlaceSite
2073
2074 HRESULT FrameSite::CanInPlaceActivate()
2075 {
2076 WXOLE_TRACE("IOleInPlaceSite::CanInPlaceActivate");
2077 return S_OK;
2078 }
2079
2080 HRESULT FrameSite::OnInPlaceActivate()
2081 {
2082 WXOLE_TRACE("IOleInPlaceSite::OnInPlaceActivate");
2083 m_bInPlaceActive = true;
2084 return S_OK;
2085 }
2086
2087 HRESULT FrameSite::OnUIActivate()
2088 {
2089 WXOLE_TRACE("IOleInPlaceSite::OnUIActivate");
2090 m_bUIActive = true;
2091 return S_OK;
2092 }
2093
2094 HRESULT FrameSite::GetWindowContext(IOleInPlaceFrame **ppFrame,
2095 IOleInPlaceUIWindow **ppDoc,
2096 LPRECT lprcPosRect,
2097 LPRECT lprcClipRect,
2098 LPOLEINPLACEFRAMEINFO lpFrameInfo)
2099 {
2100 WXOLE_TRACE("IOleInPlaceSite::GetWindowContext");
2101 if (ppFrame == NULL || ppDoc == NULL || lprcPosRect == NULL ||
2102 lprcClipRect == NULL || lpFrameInfo == NULL)
2103 {
2104 if (ppFrame != NULL)
2105 (*ppFrame) = NULL;
2106 if (ppDoc != NULL)
2107 (*ppDoc) = NULL;
2108 return E_INVALIDARG;
2109 }
2110
2111 HRESULT hr = QueryInterface(IID_IOleInPlaceFrame, (void **) ppFrame);
2112 if (! SUCCEEDED(hr))
2113 {
2114 WXOLE_TRACE("IOleInPlaceSite::IOleInPlaceFrame Error !");
2115 return E_UNEXPECTED;
2116 };
2117
2118 hr = QueryInterface(IID_IOleInPlaceUIWindow, (void **) ppDoc);
2119 if (! SUCCEEDED(hr))
2120 {
2121 WXOLE_TRACE("IOleInPlaceSite::IOleInPlaceUIWindow Error !");
2122 (*ppFrame)->Release();
2123 *ppFrame = NULL;
2124 return E_UNEXPECTED;
2125 };
2126
2127 int w, h;
2128 m_window->GetClientSize(&w, &h);
2129 if (lprcPosRect)
2130 {
2131 lprcPosRect->left = lprcPosRect->top = 0;
2132 lprcPosRect->right = w;
2133 lprcPosRect->bottom = h;
2134 };
2135 if (lprcClipRect)
2136 {
2137 lprcClipRect->left = lprcClipRect->top = 0;
2138 lprcClipRect->right = w;
2139 lprcClipRect->bottom = h;
2140 };
2141
2142 memset(lpFrameInfo, 0, sizeof(OLEINPLACEFRAMEINFO));
2143 lpFrameInfo->cb = sizeof(OLEINPLACEFRAMEINFO);
2144 lpFrameInfo->hwndFrame = m_hWndParent;
2145
2146 return S_OK;
2147 }
2148
2149 HRESULT FrameSite::Scroll(SIZE scrollExtent)
2150 {
2151 WXOLE_TRACE("IOleInPlaceSite::Scroll");
2152 return S_OK;
2153 }
2154
2155 HRESULT FrameSite::OnUIDeactivate(BOOL fUndoable)
2156 {
2157 WXOLE_TRACE("IOleInPlaceSite::OnUIDeactivate");
2158 m_bUIActive = false;
2159 return S_OK;
2160 }
2161
2162 HRESULT FrameSite::OnInPlaceDeactivate()
2163 {
2164 WXOLE_TRACE("IOleInPlaceSite::OnInPlaceDeactivate");
2165 m_bInPlaceActive = false;
2166 return S_OK;
2167 }
2168
2169 HRESULT FrameSite::DiscardUndoState()
2170 {
2171 WXOLE_TRACE("IOleInPlaceSite::DiscardUndoState");
2172 return S_OK;
2173 }
2174
2175 HRESULT FrameSite::DeactivateAndUndo()
2176 {
2177 WXOLE_TRACE("IOleInPlaceSite::DeactivateAndUndo");
2178 return S_OK;
2179 }
2180
2181 HRESULT FrameSite::OnPosRectChange(LPCRECT lprcPosRect)
2182 {
2183 WXOLE_TRACE("IOleInPlaceSite::OnPosRectChange");
2184 if (m_window->m_oleInPlaceObject.Ok() && lprcPosRect)
2185 m_window->m_oleInPlaceObject->SetObjectRects(lprcPosRect, lprcPosRect);
2186
2187 return S_OK;
2188 }
2189
2190 //IOleInPlaceSiteEx
2191
2192 HRESULT FrameSite::OnInPlaceActivateEx(BOOL * pfNoRedraw, DWORD dwFlags)
2193 {
2194 WXOLE_TRACE("IOleInPlaceSiteEx::OnInPlaceActivateEx");
2195 OleLockRunning(m_window->m_ActiveX, TRUE, FALSE);
2196 if (pfNoRedraw)
2197 (*pfNoRedraw) = FALSE;
2198 return S_OK;
2199 }
2200
2201 HRESULT FrameSite::OnInPlaceDeactivateEx(BOOL fNoRedraw)
2202 {
2203 WXOLE_TRACE("IOleInPlaceSiteEx::OnInPlaceDeactivateEx");
2204 OleLockRunning(m_window->m_ActiveX, FALSE, FALSE);
2205 return S_OK;
2206 }
2207
2208 HRESULT FrameSite::RequestUIActivate()
2209 {
2210 WXOLE_TRACE("IOleInPlaceSiteEx::RequestUIActivate");
2211 return S_OK;
2212 }
2213
2214
2215 //IOleClientSite
2216
2217 HRESULT FrameSite::SaveObject()
2218 {
2219 WXOLE_TRACE("IOleClientSite::SaveObject");
2220 return S_OK;
2221 }
2222
2223 const char *OleGetMonikerToStr(DWORD dwAssign)
2224 {
2225 switch (dwAssign)
2226 {
2227 case OLEGETMONIKER_ONLYIFTHERE : return "OLEGETMONIKER_ONLYIFTHERE";
2228 case OLEGETMONIKER_FORCEASSIGN : return "OLEGETMONIKER_FORCEASSIGN";
2229 case OLEGETMONIKER_UNASSIGN : return "OLEGETMONIKER_UNASSIGN";
2230 case OLEGETMONIKER_TEMPFORUSER : return "OLEGETMONIKER_TEMPFORUSER";
2231 default : return "Bad Enum";
2232 };
2233 };
2234
2235 const char *OleGetWhicMonikerStr(DWORD dwWhichMoniker)
2236 {
2237 switch(dwWhichMoniker)
2238 {
2239 case OLEWHICHMK_CONTAINER : return "OLEWHICHMK_CONTAINER";
2240 case OLEWHICHMK_OBJREL : return "OLEWHICHMK_OBJREL";
2241 case OLEWHICHMK_OBJFULL : return "OLEWHICHMK_OBJFULL";
2242 default : return "Bad Enum";
2243 };
2244 };
2245
2246 HRESULT FrameSite::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker,
2247 IMoniker ** ppmk)
2248 {
2249 WXOLE_TRACEOUT("IOleClientSite::GetMoniker(" << OleGetMonikerToStr(dwAssign) << ", " << OleGetWhicMonikerStr(dwWhichMoniker) << ")");
2250
2251
2252 if (! ppmk)
2253 return E_FAIL;
2254
2255 /*
2256 HRESULT hr = CreateFileMoniker(L"e:\\dev\\wxie\\bug-zap.swf", ppmk);
2257 if (SUCCEEDED(hr))
2258 return S_OK;
2259 */
2260 *ppmk = NULL;
2261
2262 return E_FAIL ;
2263 }
2264
2265 HRESULT FrameSite::GetContainer(LPOLECONTAINER * ppContainer)
2266 {
2267 WXOLE_TRACE("IOleClientSite::GetContainer");
2268 if (ppContainer == NULL)
2269 return E_INVALIDARG;
2270
2271 HRESULT hr = QueryInterface(IID_IOleContainer, (void**)(ppContainer));
2272 wxASSERT(SUCCEEDED(hr));
2273
2274 return hr;
2275 }
2276
2277 HRESULT FrameSite::ShowObject()
2278 {
2279 WXOLE_TRACE("IOleClientSite::ShowObject");
2280 if (m_window->m_oleObjectHWND)
2281 ::ShowWindow(m_window->m_oleObjectHWND, SW_SHOW);
2282 return S_OK;
2283 }
2284
2285 HRESULT FrameSite::OnShowWindow(BOOL fShow)
2286 {
2287 WXOLE_TRACE("IOleClientSite::OnShowWindow");
2288 return S_OK;
2289 }
2290
2291 HRESULT FrameSite::RequestNewObjectLayout()
2292 {
2293 WXOLE_TRACE("IOleClientSite::RequestNewObjectLayout");
2294 return E_NOTIMPL;
2295 }
2296
2297 // IParseDisplayName
2298
2299 HRESULT FrameSite::ParseDisplayName(IBindCtx *pbc, LPOLESTR pszDisplayName,
2300 ULONG *pchEaten, IMoniker **ppmkOut)
2301 {
2302 WXOLE_TRACE("IParseDisplayName::ParseDisplayName");
2303 return E_NOTIMPL;
2304 }
2305
2306 //IOleContainer
2307
2308 HRESULT FrameSite::EnumObjects(DWORD grfFlags, IEnumUnknown **ppenum)
2309 {
2310 WXOLE_TRACE("IOleContainer::EnumObjects");
2311 return E_NOTIMPL;
2312 }
2313
2314 HRESULT FrameSite::LockContainer(BOOL fLock)
2315 {
2316 WXOLE_TRACE("IOleContainer::LockContainer");
2317 // TODO
2318 return S_OK;
2319 }
2320
2321 //IOleItemContainer
2322
2323 HRESULT FrameSite::GetObject(LPOLESTR pszItem, DWORD dwSpeedNeeded,
2324 IBindCtx * pbc, REFIID riid, void ** ppvObject)
2325 {
2326 WXOLE_TRACE("IOleItemContainer::GetObject");
2327 if (pszItem == NULL)
2328 return E_INVALIDARG;
2329 if (ppvObject == NULL)
2330 return E_INVALIDARG;
2331
2332 *ppvObject = NULL;
2333 return MK_E_NOOBJECT;
2334 }
2335
2336 HRESULT FrameSite::GetObjectStorage(LPOLESTR pszItem, IBindCtx * pbc,
2337 REFIID riid, void ** ppvStorage)
2338 {
2339 WXOLE_TRACE("IOleItemContainer::GetObjectStorage");
2340 if (pszItem == NULL)
2341 return E_INVALIDARG;
2342 if (ppvStorage == NULL)
2343 return E_INVALIDARG;
2344
2345 *ppvStorage = NULL;
2346 return MK_E_NOOBJECT;
2347 }
2348
2349 HRESULT FrameSite::IsRunning(LPOLESTR pszItem)
2350 {
2351 WXOLE_TRACE("IOleItemContainer::IsRunning");
2352 if (pszItem == NULL)
2353 return E_INVALIDARG;
2354
2355 return MK_E_NOOBJECT;
2356 }
2357
2358
2359
2360 //IOleControlSite
2361
2362 HRESULT FrameSite::OnControlInfoChanged()
2363 {
2364 WXOLE_TRACE("IOleControlSite::OnControlInfoChanged");
2365 return S_OK;
2366 }
2367
2368 HRESULT FrameSite::LockInPlaceActive(BOOL fLock)
2369 {
2370 WXOLE_TRACE("IOleControlSite::LockInPlaceActive");
2371 m_bInPlaceLocked = (fLock) ? true : false;
2372 return S_OK;
2373 }
2374
2375 HRESULT FrameSite::GetExtendedControl(IDispatch ** ppDisp)
2376 {
2377 WXOLE_TRACE("IOleControlSite::GetExtendedControl");
2378 return E_NOTIMPL;
2379 }
2380
2381 HRESULT FrameSite::TransformCoords(POINTL * pPtlHimetric, POINTF * pPtfContainer, DWORD dwFlags)
2382 {
2383 WXOLE_TRACE("IOleControlSite::TransformCoords");
2384 HRESULT hr = S_OK;
2385
2386 if (pPtlHimetric == NULL)
2387 return E_INVALIDARG;
2388
2389 if (pPtfContainer == NULL)
2390 return E_INVALIDARG;
2391
2392 return E_NOTIMPL;
2393
2394 }
2395
2396 HRESULT FrameSite::TranslateAccelerator(LPMSG pMsg, DWORD grfModifiers)
2397 {
2398 WXOLE_TRACE("IOleControlSite::TranslateAccelerator");
2399 // TODO: send an event with this id
2400 return E_NOTIMPL;
2401 }
2402
2403 HRESULT FrameSite::OnFocus(BOOL fGotFocus)
2404 {
2405 WXOLE_TRACE("IOleControlSite::OnFocus");
2406 return S_OK;
2407 }
2408
2409 HRESULT FrameSite::ShowPropertyFrame()
2410 {
2411 WXOLE_TRACE("IOleControlSite::ShowPropertyFrame");
2412 return E_NOTIMPL;
2413 }
2414
2415 //IOleCommandTarget
2416
2417 HRESULT FrameSite::QueryStatus(const GUID * pguidCmdGroup, ULONG cCmds,
2418 OLECMD * prgCmds, OLECMDTEXT * pCmdTet)
2419 {
2420 WXOLE_TRACE("IOleCommandTarget::QueryStatus");
2421 if (prgCmds == NULL) return E_INVALIDARG;
2422 bool bCmdGroupFound = false;
2423
2424 for (ULONG nCmd = 0; nCmd < cCmds; nCmd++)
2425 {
2426 // unsupported by default
2427 prgCmds[nCmd].cmdf = 0;
2428
2429 // TODO
2430 }
2431
2432 if (!bCmdGroupFound) { OLECMDERR_E_UNKNOWNGROUP; }
2433 return S_OK;
2434 }
2435
2436 HRESULT FrameSite::Exec(const GUID * pguidCmdGroup, DWORD nCmdID,
2437 DWORD nCmdExecOpt, VARIANTARG * pVaIn,
2438 VARIANTARG * pVaOut)
2439 {
2440 WXOLE_TRACE("IOleCommandTarget::Exec");
2441 bool bCmdGroupFound = false;
2442
2443 if (!bCmdGroupFound) { OLECMDERR_E_UNKNOWNGROUP; }
2444 return OLECMDERR_E_NOTSUPPORTED;
2445 }
2446
2447 //IAdviseSink
2448
2449 void STDMETHODCALLTYPE FrameSite::OnDataChange(FORMATETC * pFormatEtc, STGMEDIUM * pgStgMed)
2450 {
2451 WXOLE_TRACE("IAdviseSink::OnDataChange");
2452 }
2453
2454 void STDMETHODCALLTYPE FrameSite::OnViewChange(DWORD dwAspect, LONG lIndex)
2455 {
2456 WXOLE_TRACE("IAdviseSink::OnViewChange");
2457 // redraw the control
2458 }
2459
2460 void STDMETHODCALLTYPE FrameSite::OnRename(IMoniker * pmk)
2461 {
2462 WXOLE_TRACE("IAdviseSink::OnRename");
2463 }
2464
2465 void STDMETHODCALLTYPE FrameSite::OnSave()
2466 {
2467 WXOLE_TRACE("IAdviseSink::OnSave");
2468 }
2469
2470 void STDMETHODCALLTYPE FrameSite::OnClose()
2471 {
2472 WXOLE_TRACE("IAdviseSink::OnClose");
2473 }
2474
2475 /////////////////////////////////////////////
2476 // IOleDocumentSite
2477 HRESULT STDMETHODCALLTYPE FrameSite::ActivateMe(
2478 /* [in] */ IOleDocumentView __RPC_FAR *pViewToActivate)
2479 {
2480 wxAutoOleInterface<IOleInPlaceSite> inPlaceSite(IID_IOleInPlaceSite, (IDispatch *) this);
2481 if (!inPlaceSite.Ok())
2482 return E_FAIL;
2483
2484 if (pViewToActivate)
2485 {
2486 m_window->m_docView = pViewToActivate;
2487 m_window->m_docView->SetInPlaceSite(inPlaceSite);
2488 }
2489 else
2490 {
2491 wxAutoOleInterface<IOleDocument> oleDoc(IID_IOleDocument, m_window->m_oleObject);
2492 if (! oleDoc.Ok())
2493 return E_FAIL;
2494
2495 HRESULT hr = oleDoc->CreateView(inPlaceSite, NULL, 0, m_window->m_docView.GetRef());
2496 if (hr != S_OK)
2497 return E_FAIL;
2498
2499 m_window->m_docView->SetInPlaceSite(inPlaceSite);
2500 };
2501
2502 m_window->m_docView->UIActivate(TRUE);
2503
2504 return S_OK;
2505 };
2506
2507
2508 static IMalloc *iMalloc = NULL;
2509
2510 IMalloc *wxOleInit::GetIMalloc()
2511 {
2512 assert(iMalloc);
2513 return iMalloc;
2514 };
2515
2516 wxOleInit::wxOleInit()
2517 {
2518 if (OleInitialize(NULL) == S_OK && iMalloc == NULL)
2519 CoGetMalloc(1, &iMalloc);
2520 else if (iMalloc)
2521 iMalloc->AddRef();
2522 };
2523
2524 wxOleInit::~wxOleInit()
2525 {
2526 if (iMalloc)
2527 {
2528 if (iMalloc->Release() == 0)
2529 iMalloc = NULL;
2530 };
2531
2532 OleUninitialize();
2533 }
2534
2535 bool GetSysErrMessage(int err, wxString& s)
2536 {
2537 wxChar buf[256];
2538 if (FormatMessage(
2539 FORMAT_MESSAGE_FROM_SYSTEM, NULL,
2540 err,0, buf, sizeof(buf), NULL) == 0)
2541 return false;
2542
2543 buf[sizeof(buf) - 1] = 0;
2544 s = buf;
2545 return true;
2546 };
2547
2548 wxString OLEHResultToString(HRESULT hr)
2549 {
2550 // try formatmessage
2551 wxString err;
2552 if (GetSysErrMessage(hr, err))
2553 return err;
2554
2555 switch (hr)
2556 {
2557 case S_OK:
2558 return wxEmptyString;
2559
2560 case CONNECT_E_CANNOTCONNECT:
2561 return _T("Cannot connect to event interface (maybe not there ?) - see MSDN");
2562
2563 case DISP_E_MEMBERNOTFOUND:
2564 return _T("The requested member does not exist, or the call to Invoke tried to set the value of a read-only property.");
2565
2566 case DISP_E_BADVARTYPE:
2567 return _T("One of the parameters in rgvarg is not a valid variant type.");
2568
2569 case DISP_E_BADPARAMCOUNT:
2570 return _T("The number of elements provided to DISPPARAMS is different from the number of parameters accepted by the method or property");
2571
2572 case DISP_E_EXCEPTION:
2573 return _T("The application needs to raise an exception. In this case, the structure passed in pExcepInfo should be filled in.");
2574
2575 case DISP_E_TYPEMISMATCH:
2576 return _T("One or more of the parameters could not be coerced. The index within rgvarg of the first parameter with the incorrect type is returned in the puArgErr parameter.");
2577
2578 case DISP_E_PARAMNOTOPTIONAL:
2579 return _T("A required parameter was omitted.");
2580
2581 case DISP_E_PARAMNOTFOUND:
2582 return _T("One of the parameter DISPIDs does not correspond to a parameter on the method. In this case, puArgErr should be set to the first parameter that contains the error.");
2583
2584 case OLECMDERR_E_UNKNOWNGROUP:
2585 return _T("The pguidCmdGroup parameter is not NULL but does not specify a recognized command group.");
2586
2587 case OLECMDERR_E_NOTSUPPORTED:
2588 return _T("The nCmdID parameter is not a valid command in the group identified by pguidCmdGroup.");
2589
2590 case OLECMDERR_E_DISABLED:
2591 return _T("The command identified by nCmdID is currently disabled and cannot be executed.");
2592
2593 case OLECMDERR_E_NOHELP:
2594 return _T("The caller has asked for help on the command identified by nCmdID, but no help is available.");
2595
2596 case OLECMDERR_E_CANCELED:
2597 return _T("The user canceled the execution of the command.");
2598
2599 case E_INVALIDARG:
2600 return _T("E_INVALIDARG");
2601
2602 case E_OUTOFMEMORY:
2603 return _T("E_OUTOFMEMORY");
2604
2605 case E_NOINTERFACE:
2606 return _T("E_NOINTERFACE");
2607
2608 case E_UNEXPECTED:
2609 return _T("E_UNEXPECTED");
2610
2611 case STG_E_INVALIDFLAG:
2612 return _T("STG_E_INVALIDFLAG");
2613
2614 case E_FAIL:
2615 return _T("E_FAIL");
2616
2617 case E_NOTIMPL:
2618 return _T("E_NOTIMPL");
2619
2620 default:
2621 {
2622 wxString buf;
2623 buf.Printf(_T("Unknown - 0x%X"), hr);
2624 return buf;
2625 }
2626 };
2627 };
2628
2629 // borrowed from src/msw/ole/oleutils.cpp
2630 wxString GetIIDName(REFIID riid)
2631 {
2632 // an association between symbolic name and numeric value of an IID
2633 struct KNOWN_IID
2634 {
2635 const IID *pIid;
2636 const wxChar *szName;
2637 };
2638
2639 // construct the table containing all known interfaces
2640 #define ADD_KNOWN_IID(name) { &IID_I##name, _T(#name) }
2641 #define ADD_KNOWN_GUID(name) { &name, _T(#name) }
2642
2643 static const KNOWN_IID aKnownIids[] =
2644 {
2645 ADD_KNOWN_IID(ServiceProvider),
2646 ADD_KNOWN_IID(AdviseSink),
2647 ADD_KNOWN_IID(AdviseSink2),
2648 ADD_KNOWN_IID(BindCtx),
2649 ADD_KNOWN_IID(ClassFactory),
2650 #if ( !defined( __VISUALC__) || (__VISUALC__!=1010) ) && !defined(__MWERKS__)
2651 ADD_KNOWN_IID(ContinueCallback),
2652 ADD_KNOWN_IID(EnumOleDocumentViews),
2653 ADD_KNOWN_IID(OleCommandTarget),
2654 ADD_KNOWN_IID(OleDocument),
2655 ADD_KNOWN_IID(OleDocumentSite),
2656 ADD_KNOWN_IID(OleDocumentView),
2657 ADD_KNOWN_IID(Print),
2658 #endif
2659 ADD_KNOWN_IID(DataAdviseHolder),
2660 ADD_KNOWN_IID(DataObject),
2661 ADD_KNOWN_IID(Debug),
2662 ADD_KNOWN_IID(DebugStream),
2663 ADD_KNOWN_IID(DfReserved1),
2664 ADD_KNOWN_IID(DfReserved2),
2665 ADD_KNOWN_IID(DfReserved3),
2666 ADD_KNOWN_IID(Dispatch),
2667 ADD_KNOWN_IID(DropSource),
2668 ADD_KNOWN_IID(DropTarget),
2669 ADD_KNOWN_IID(EnumCallback),
2670 ADD_KNOWN_IID(EnumFORMATETC),
2671 ADD_KNOWN_IID(EnumGeneric),
2672 ADD_KNOWN_IID(EnumHolder),
2673 ADD_KNOWN_IID(EnumMoniker),
2674 ADD_KNOWN_IID(EnumOLEVERB),
2675 ADD_KNOWN_IID(EnumSTATDATA),
2676 ADD_KNOWN_IID(EnumSTATSTG),
2677 ADD_KNOWN_IID(EnumString),
2678 ADD_KNOWN_IID(EnumUnknown),
2679 ADD_KNOWN_IID(EnumVARIANT),
2680 ADD_KNOWN_IID(ExternalConnection),
2681 ADD_KNOWN_IID(InternalMoniker),
2682 ADD_KNOWN_IID(LockBytes),
2683 ADD_KNOWN_IID(Malloc),
2684 ADD_KNOWN_IID(Marshal),
2685 ADD_KNOWN_IID(MessageFilter),
2686 ADD_KNOWN_IID(Moniker),
2687 ADD_KNOWN_IID(OleAdviseHolder),
2688 ADD_KNOWN_IID(OleCache),
2689 ADD_KNOWN_IID(OleCache2),
2690 ADD_KNOWN_IID(OleCacheControl),
2691 ADD_KNOWN_IID(OleClientSite),
2692 ADD_KNOWN_IID(OleContainer),
2693 ADD_KNOWN_IID(OleInPlaceActiveObject),
2694 ADD_KNOWN_IID(OleInPlaceFrame),
2695 ADD_KNOWN_IID(OleInPlaceObject),
2696 ADD_KNOWN_IID(OleInPlaceSite),
2697 ADD_KNOWN_IID(OleInPlaceUIWindow),
2698 ADD_KNOWN_IID(OleItemContainer),
2699 ADD_KNOWN_IID(OleLink),
2700 ADD_KNOWN_IID(OleManager),
2701 ADD_KNOWN_IID(OleObject),
2702 ADD_KNOWN_IID(OlePresObj),
2703 ADD_KNOWN_IID(OleWindow),
2704 ADD_KNOWN_IID(PSFactory),
2705 ADD_KNOWN_IID(ParseDisplayName),
2706 ADD_KNOWN_IID(Persist),
2707 ADD_KNOWN_IID(PersistFile),
2708 ADD_KNOWN_IID(PersistStorage),
2709 ADD_KNOWN_IID(PersistStream),
2710 ADD_KNOWN_IID(ProxyManager),
2711 ADD_KNOWN_IID(RootStorage),
2712 ADD_KNOWN_IID(RpcChannel),
2713 ADD_KNOWN_IID(RpcProxy),
2714 ADD_KNOWN_IID(RpcStub),
2715 ADD_KNOWN_IID(RunnableObject),
2716 ADD_KNOWN_IID(RunningObjectTable),
2717 ADD_KNOWN_IID(StdMarshalInfo),
2718 ADD_KNOWN_IID(Storage),
2719 ADD_KNOWN_IID(Stream),
2720 ADD_KNOWN_IID(StubManager),
2721 ADD_KNOWN_IID(Unknown),
2722 ADD_KNOWN_IID(ViewObject),
2723 ADD_KNOWN_IID(ViewObject2),
2724 ADD_KNOWN_GUID(IID_IDispatch),
2725 ADD_KNOWN_GUID(IID_IWebBrowser),
2726 ADD_KNOWN_GUID(IID_IWebBrowserApp),
2727 ADD_KNOWN_GUID(IID_IWebBrowser2),
2728 ADD_KNOWN_GUID(IID_IWebBrowser),
2729 ADD_KNOWN_GUID(DIID_DWebBrowserEvents2),
2730 ADD_KNOWN_GUID(DIID_DWebBrowserEvents),
2731 };
2732
2733 // don't clobber preprocessor name space
2734 #undef ADD_KNOWN_IID
2735 #undef ADD_KNOWN_GUID
2736
2737 // try to find the interface in the table
2738 for ( size_t ui = 0; ui < WXSIZEOF(aKnownIids); ui++ )
2739 {
2740 if ( riid == *aKnownIids[ui].pIid )
2741 {
2742 return aKnownIids[ui].szName;
2743 }
2744 }
2745
2746 // unknown IID, just transform to string
2747 LPOLESTR str = NULL;
2748 StringFromIID(riid, &str);
2749 if (str)
2750 {
2751 wxString s = str;
2752 CoTaskMemFree(str);
2753 return s;
2754 }
2755 else
2756 return _T("StringFromIID() error");
2757 }