]> git.saurik.com Git - wxWidgets.git/blob - wxPython/contrib/activex/wxie/wxactivex.cpp
fixed wxVsnprintf() to write as much as it can if the output buffer is too short
[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 = (wxChar) *va.pbVal;
626 else
627 vx = (wxChar) 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 = (wxChar) vx;
761 else
762 va.bVal = (wxChar) 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 int i;
1176 for (i = 0; i < ta->cVars; i++) {
1177 VARDESC FAR *vd = NULL;
1178
1179 typeInfo->GetVarDesc(i, &vd) ;
1180 BSTR bstrProperty = NULL;
1181 typeInfo->GetDocumentation(vd->memid, &bstrProperty,
1182 NULL, NULL, NULL);
1183 wxString propName(bstrProperty);
1184 m_props.push_back(PropX());
1185 int idx = m_props.size() - 1;
1186 m_propNames[propName] = idx;
1187 m_props[idx].name = propName;
1188 m_props[idx].memid = vd->memid;
1189
1190 ParamX param;
1191 param.isSafeArray = false;
1192 param.isPtr = false;
1193 param.flags = vd->elemdescVar.idldesc.wIDLFlags;
1194 param.vt = vd->elemdescVar.tdesc.vt;
1195
1196 m_props[idx].arg = param;
1197 m_props[idx].type = param;
1198 }
1199
1200 // Get Function Names
1201 for (i = 0; i < ta->cFuncs; i++)
1202 {
1203 FUNCDESC FAR *fd = NULL;
1204
1205 hret = typeInfo->GetFuncDesc(i, &fd);
1206 if (! fd)
1207 continue;
1208
1209 BSTR anames[1] = {NULL};
1210 unsigned int n = 0;
1211
1212 hret = typeInfo->GetNames(fd->memid, anames, 1, &n);
1213
1214 if (anames[0])
1215 {
1216 wxString name = anames[0];
1217
1218 WXOLE_TRACEOUT("Name " << i << " = " << name.c_str());
1219 SysFreeString(anames[0]);
1220
1221 if (defInterface || defEventSink)
1222 {
1223 FuncX func;
1224 func.name = name;
1225 func.memid = fd->memid;
1226 func.hasOut = false;
1227
1228 // get Param Names
1229 unsigned int maxPNames = fd->cParams + 1;
1230 unsigned int nPNames = 0;
1231 BSTR *pnames = new BSTR[maxPNames];
1232
1233 hret = typeInfo->GetNames(fd->memid, pnames, maxPNames, &nPNames);
1234
1235 int pbase = 0;
1236 if (fd->cParams < int(nPNames))
1237 {
1238 pbase++;
1239 SysFreeString(pnames[0]);
1240 };
1241
1242 // params
1243 ElemDescToParam(fd->elemdescFunc, func.retType);
1244 for (int p = 0; p < fd->cParams; p++)
1245 {
1246 ParamX param;
1247
1248 ElemDescToParam(fd->lprgelemdescParam[p], param);
1249
1250 param.name = pnames[pbase + p];
1251 SysFreeString(pnames[pbase + p]);
1252
1253 param.isOptional = (p > fd->cParams - fd->cParamsOpt);
1254
1255 func.hasOut |= (param.IsOut() || param.isPtr);
1256 func.params.push_back(param);
1257 };
1258 delete [] pnames;
1259
1260 if (defEventSink)
1261 {
1262 m_events.push_back(func);
1263 m_eventMemberIds[fd->memid] = m_events.size() - 1;
1264 }
1265 else
1266 {
1267 if (fd->invkind == INVOKE_FUNC)
1268 {
1269 m_methods.push_back(func);
1270 m_methodNames[func.name] = m_methods.size() - 1;
1271 }
1272 else
1273 {
1274 NameMap::iterator it = m_propNames.find(func.name);
1275 int idx = -1;
1276 if (it == m_propNames.end())
1277 {
1278 m_props.push_back(PropX());
1279 idx = m_props.size() - 1;
1280 m_propNames[func.name] = idx;
1281 m_props[idx].name = func.name;
1282 m_props[idx].memid = func.memid;
1283
1284 }
1285 else
1286 idx = it->second;
1287
1288 if (fd->invkind == INVOKE_PROPERTYGET)
1289 m_props[idx].type = func.retType;
1290 else if (func.params.size() > 0)
1291 {
1292 m_props[idx].arg = func.params[0];
1293 m_props[idx].putByRef = (fd->invkind == INVOKE_PROPERTYPUTREF);
1294 };
1295 };
1296 };
1297 };
1298 };
1299
1300 typeInfo->ReleaseFuncDesc(fd);
1301 };
1302 }
1303
1304 typeInfo->ReleaseTypeAttr(ta);
1305 };
1306
1307 ///////////////////////////////////////////////
1308 // Type Info exposure
1309 const wxActiveX::FuncX& wxActiveX::GetEventDesc(int idx) const
1310 {
1311 wxASSERT(idx >= 0 && idx < GetEventCount());
1312
1313 return m_events[idx];
1314 };
1315
1316 const wxActiveX::PropX& wxActiveX::GetPropDesc(int idx) const
1317 {
1318 if (idx < 0 || idx >= GetPropCount())
1319 throw exception("Property index out of bounds");
1320
1321 return m_props[idx];
1322 };
1323
1324 const wxActiveX::PropX& wxActiveX::GetPropDesc(const wxString& name) const
1325 {
1326 NameMap::const_iterator it = m_propNames.find(name);
1327 if (it == m_propNames.end())
1328 {
1329 wxString s;
1330 s << _T("property <") << name << _T("> not found");
1331 throw exception(s.mb_str());
1332 };
1333
1334 return GetPropDesc(it->second);
1335 };
1336
1337 const wxActiveX::FuncX& wxActiveX::GetMethodDesc(int idx) const
1338 {
1339 if (idx < 0 || idx >= GetMethodCount())
1340 throw exception("Method index out of bounds");
1341
1342
1343 return m_methods[idx];
1344 };
1345
1346
1347 const wxActiveX::FuncX& wxActiveX::GetMethodDesc(const wxString& name) const
1348 {
1349 NameMap::const_iterator it = m_methodNames.find(name);
1350 if (it == m_methodNames.end())
1351 {
1352 wxString s;
1353 s << _T("method <") << name << _T("> not found");
1354 throw exception(s.mb_str());
1355 };
1356
1357 return GetMethodDesc(it->second);
1358 };
1359
1360
1361 void wxActiveX::SetProp(MEMBERID name, VARIANTARG& value)
1362 {
1363 DISPID pids[1] = {DISPID_PROPERTYPUT};
1364 DISPPARAMS params = {&value, pids, 1, 1};
1365
1366 EXCEPINFO x;
1367 memset(&x, 0, sizeof(x));
1368 unsigned int argErr = 0;
1369
1370 HRESULT hr = m_Dispatch->Invoke(
1371 name,
1372 IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT,
1373 &params, NULL, &x, &argErr);
1374
1375 WXOLE_WARN(hr, "Invoke Prop(...)");
1376 };
1377
1378 void wxActiveX::SetProp(const wxString &name, const wxVariant &value)
1379 {
1380 const PropX& prop = GetPropDesc(name);
1381 if (! prop.CanSet())
1382 {
1383 wxString s;
1384 s << _T("property <") << name << _T("> is readonly");
1385 throw exception(s.mb_str());
1386 };
1387
1388 VARIANT v = {prop.arg.vt};
1389 VariantToMSWVariant(value, v);
1390 SetProp(prop.memid, v);
1391 VariantClear(&v); // this releases any BSTR's etc
1392 };
1393
1394 VARIANT wxActiveX::GetPropAsVariant(MEMBERID name)
1395 {
1396 VARIANT v;
1397 VariantInit(&v);
1398
1399 DISPPARAMS params = {NULL, NULL, 0, 0};
1400
1401 EXCEPINFO x;
1402 memset(&x, 0, sizeof(x));
1403 unsigned int argErr = 0;
1404
1405 HRESULT hr = m_Dispatch->Invoke(
1406 name,
1407 IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET,
1408 &params, &v, &x, &argErr);
1409
1410 WXOLE_WARN(hr, "Invoke Prop(...)");
1411
1412 return v;
1413 };
1414
1415 VARIANT wxActiveX::GetPropAsVariant(const wxString& name)
1416 {
1417 const PropX& prop = GetPropDesc(name);
1418 if (! prop.CanGet())
1419 {
1420 wxString s;
1421 s << _T("property <") << name << _T("> is writeonly");
1422 throw exception(s.mb_str());
1423 };
1424
1425 return GetPropAsVariant(prop.memid);
1426 };
1427
1428 wxVariant wxActiveX::GetPropAsWxVariant(const wxString& name)
1429 {
1430 VARIANT v = GetPropAsVariant(name);
1431 HRESULT hr = VariantChangeType(&v, &v, 0, VT_BSTR);
1432 if (! SUCCEEDED(hr))
1433 throw exception("Unable to convert variant");
1434
1435 wxVariant wv;
1436 MSWVariantToVariant(v, wv);
1437
1438 VariantClear(&v);
1439
1440 return wv;
1441 };
1442
1443 wxString wxActiveX::GetPropAsString(const wxString& name)
1444 {
1445 VARIANT v = GetPropAsVariant(name);
1446 HRESULT hr = VariantChangeType(&v, &v, 0, VT_BSTR);
1447 if (! SUCCEEDED(hr))
1448 throw exception("Unable to convert variant");
1449
1450 wxString s = v.bstrVal;
1451 VariantClear(&v);
1452
1453 return s;
1454 };
1455
1456 char wxActiveX::GetPropAsChar(const wxString& name)
1457 {
1458 VARIANT v = GetPropAsVariant(name);
1459 HRESULT hr = VariantChangeType(&v, &v, 0, VT_I1);
1460 if (! SUCCEEDED(hr))
1461 throw exception("Unable to convert variant");
1462
1463 return v.cVal;
1464 };
1465
1466 long wxActiveX::GetPropAsLong(const wxString& name)
1467 {
1468 VARIANT v = GetPropAsVariant(name);
1469 HRESULT hr = VariantChangeType(&v, &v, 0, VT_I4);
1470 if (! SUCCEEDED(hr))
1471 throw exception("Unable to convert variant");
1472
1473 return v.iVal;
1474 };
1475
1476 bool wxActiveX::GetPropAsBool(const wxString& name)
1477 {
1478 VARIANT v = GetPropAsVariant(name);
1479 HRESULT hr = VariantChangeType(&v, &v, 0, VT_BOOL);
1480 if (! SUCCEEDED(hr))
1481 throw exception("Unable to convert variant");
1482
1483 return v.boolVal != 0;
1484 };
1485
1486 double wxActiveX::GetPropAsDouble(const wxString& name)
1487 {
1488 VARIANT v = GetPropAsVariant(name);
1489 HRESULT hr = VariantChangeType(&v, &v, 0, VT_R8);
1490 if (! SUCCEEDED(hr))
1491 throw exception("Unable to convert variant");
1492
1493 return v.dblVal;
1494 };
1495
1496 wxDateTime wxActiveX::GetPropAsDateTime(const wxString& name)
1497 {
1498 wxDateTime dt;
1499 VARIANT v = GetPropAsVariant(name);
1500
1501 if (! VariantToWxDateTime(v, dt))
1502 throw exception("Unable to convert variant to wxDateTime");
1503
1504 return dt;
1505 };
1506
1507 void *wxActiveX::GetPropAsPointer(const wxString& name)
1508 {
1509 VARIANT v = GetPropAsVariant(name);
1510 HRESULT hr = VariantChangeType(&v, &v, 0, VT_BYREF);
1511 if (! SUCCEEDED(hr))
1512 throw exception("Unable to convert variant");
1513
1514 return v.byref;
1515 };
1516
1517
1518
1519 // call methods
1520 VARIANT wxActiveX::CallMethod(MEMBERID name, VARIANTARG args[], int argc)
1521 {
1522 DISPPARAMS pargs = {args, NULL, argc, 0};
1523 VARIANT retVal;
1524 VariantInit(&retVal);
1525
1526 EXCEPINFO x;
1527 memset(&x, 0, sizeof(x));
1528 unsigned int argErr = 0;
1529
1530 HRESULT hr = m_Dispatch->Invoke(
1531 name,
1532 IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD,
1533 &pargs, &retVal, &x, &argErr);
1534
1535 WXOLE_WARN(hr, "Invoke Method(...)");
1536 return retVal;
1537 };
1538
1539 VARIANT wxActiveX::CallMethod(const wxString& name, VARIANTARG args[], int argc)
1540 {
1541 const FuncX& func = GetMethodDesc(name);
1542 if (argc < 0)
1543 argc = func.params.size();
1544
1545 return CallMethod(func.memid, args, argc);
1546 };
1547
1548
1549 wxVariant wxActiveX::CallMethod(const wxString& name, wxVariant args[], int nargs)
1550 {
1551 const FuncX& func = GetMethodDesc(name);
1552
1553 if (args == NULL)
1554 nargs = 0;
1555
1556 VARIANTARG *vargs = NULL;
1557 if (nargs < 0)
1558 nargs = func.params.size();
1559
1560 if (nargs > 0)
1561 vargs = new VARIANTARG[nargs];
1562
1563 if (vargs)
1564 {
1565 // init type of vargs
1566 for (int i = 0; i < nargs; i++)
1567 vargs[nargs - i - 1].vt = func.params[i].vt;
1568
1569 // put data
1570 for (i = 0; i < nargs; i++)
1571 VariantToMSWVariant(args[i], vargs[nargs - i - 1]);
1572 };
1573
1574 VARIANT rv = CallMethod(func.memid, vargs, nargs);
1575
1576 // process any by ref params
1577 if (func.hasOut)
1578 {
1579 for (int i = 0; i < nargs; i++)
1580 {
1581 VARIANTARG& va = vargs[nargs - i - 1];
1582 const wxActiveX::ParamX &px = func.params[i];
1583
1584 if (px.IsOut())
1585 {
1586 wxVariant& vx = args[i];
1587
1588 MSWVariantToVariant(va, vx);
1589 };
1590 };
1591 }
1592
1593 if (vargs)
1594 {
1595 for (int i = 0; i < nargs; i++)
1596 VariantClear(&vargs[i]);
1597 delete [] vargs;
1598 };
1599
1600 wxVariant ret;
1601
1602 MSWVariantToVariant(rv, ret);
1603 VariantClear(&rv);
1604
1605 return ret;
1606 };
1607
1608
1609 ///////////////////////////////////////////////
1610
1611 HRESULT wxActiveX::ConnectAdvise(REFIID riid, IUnknown *events)
1612 {
1613 wxOleConnectionPoint cp;
1614 DWORD adviseCookie = 0;
1615
1616 wxAutoOleInterface<IConnectionPointContainer> cpContainer(IID_IConnectionPointContainer, m_ActiveX);
1617 if (! cpContainer.Ok())
1618 return E_FAIL;
1619
1620 HRESULT hret = cpContainer->FindConnectionPoint(riid, cp.GetRef());
1621 if (! SUCCEEDED(hret))
1622 return hret;
1623
1624 hret = cp->Advise(events, &adviseCookie);
1625
1626 if (SUCCEEDED(hret))
1627 m_connections.push_back(wxOleConnection(cp, adviseCookie));
1628 else
1629 {
1630 WXOLE_WARN(hret, "ConnectAdvise");
1631 };
1632
1633 return hret;
1634 };
1635
1636 HRESULT wxActiveX::AmbientPropertyChanged(DISPID dispid)
1637 {
1638 wxAutoOleInterface<IOleControl> oleControl(IID_IOleControl, m_oleObject);
1639
1640 if (oleControl.Ok())
1641 return oleControl->OnAmbientPropertyChange(dispid);
1642 else
1643 return S_FALSE;
1644 };
1645
1646 #define HIMETRIC_PER_INCH 2540
1647 #define MAP_PIX_TO_LOGHIM(x,ppli) MulDiv(HIMETRIC_PER_INCH, (x), (ppli))
1648
1649 static void PixelsToHimetric(SIZEL &sz)
1650 {
1651 static int logX = 0;
1652 static int logY = 0;
1653
1654 if (logY == 0)
1655 {
1656 // initaliase
1657 HDC dc = GetDC(NULL);
1658 logX = GetDeviceCaps(dc, LOGPIXELSX);
1659 logY = GetDeviceCaps(dc, LOGPIXELSY);
1660 ReleaseDC(NULL, dc);
1661 };
1662
1663 #define HIMETRIC_INCH 2540
1664 #define CONVERT(x, logpixels) MulDiv(HIMETRIC_INCH, (x), (logpixels))
1665
1666 sz.cx = CONVERT(sz.cx, logX);
1667 sz.cy = CONVERT(sz.cy, logY);
1668
1669 #undef CONVERT
1670 #undef HIMETRIC_INCH
1671 }
1672
1673
1674 void wxActiveX::OnSize(wxSizeEvent& event)
1675 {
1676 int w, h;
1677 GetClientSize(&w, &h);
1678
1679 RECT posRect;
1680 posRect.left = 0;
1681 posRect.top = 0;
1682 posRect.right = w;
1683 posRect.bottom = h;
1684
1685 if (w <= 0 && h <= 0)
1686 return;
1687
1688 // extents are in HIMETRIC units
1689 if (m_oleObject.Ok())
1690 {
1691 SIZEL sz = {w, h};
1692 PixelsToHimetric(sz);
1693
1694 SIZEL sz2;
1695
1696 m_oleObject->GetExtent(DVASPECT_CONTENT, &sz2);
1697 if (sz2.cx != sz.cx || sz.cy != sz2.cy)
1698 m_oleObject->SetExtent(DVASPECT_CONTENT, &sz);
1699 };
1700
1701 if (m_oleInPlaceObject.Ok())
1702 m_oleInPlaceObject->SetObjectRects(&posRect, &posRect);
1703 }
1704
1705 void wxActiveX::OnPaint(wxPaintEvent& event)
1706 {
1707 wxLogTrace(wxT(""),wxT("repainting activex win"));
1708 wxPaintDC dc(this);
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 }
1734
1735
1736 void wxActiveX::OnMouse(wxMouseEvent& event)
1737 {
1738 if (m_oleObjectHWND == NULL)
1739 {
1740 wxLogTrace(wxT(""),wxT("no oleInPlaceObject"));
1741 event.Skip();
1742 return;
1743 }
1744
1745 wxLogTrace(wxT(""),wxT("mouse event"));
1746 UINT msg = 0;
1747 WPARAM wParam = 0;
1748 LPARAM lParam = 0;
1749 LRESULT lResult = 0;
1750
1751 if (event.m_metaDown)
1752 wParam |= MK_CONTROL;
1753 if (event.m_shiftDown)
1754 wParam |= MK_SHIFT;
1755 if (event.m_leftDown)
1756 wParam |= MK_LBUTTON;
1757 if (event.m_middleDown)
1758 wParam |= MK_MBUTTON;
1759 if (event.m_rightDown)
1760 wParam |= MK_RBUTTON;
1761 lParam = event.m_x << 16;
1762 lParam |= event.m_y;
1763
1764 if (event.LeftDown())
1765 msg = WM_LBUTTONDOWN;
1766 else if (event.LeftDClick())
1767 msg = WM_LBUTTONDBLCLK;
1768 else if (event.LeftUp())
1769 msg = WM_LBUTTONUP;
1770 else if (event.MiddleDown())
1771 msg = WM_MBUTTONDOWN;
1772 else if (event.MiddleDClick())
1773 msg = WM_MBUTTONDBLCLK;
1774 else if (event.MiddleUp())
1775 msg = WM_MBUTTONUP;
1776 else if (event.RightDown())
1777 msg = WM_RBUTTONDOWN;
1778 else if (event.RightDClick())
1779 msg = WM_RBUTTONDBLCLK;
1780 else if (event.RightUp())
1781 msg = WM_RBUTTONUP;
1782 else if (event.Moving() || event.Dragging())
1783 msg = WM_MOUSEMOVE;
1784
1785 wxString log;
1786 if (msg == 0)
1787 {
1788 wxLogTrace(wxT(""),wxT("no message"));
1789 event.Skip(); return;
1790 };
1791
1792 if (!::SendMessage(m_oleObjectHWND, msg, wParam, lParam))
1793 {
1794 wxLogTrace(wxT(""),wxT("msg not delivered"));
1795 event.Skip();
1796 return;
1797 };
1798
1799 wxLogTrace(wxT(""),wxT("msg sent"));
1800 }
1801
1802 bool wxActiveX::MSWTranslateMessage(WXMSG *msg){
1803
1804 if (msg->message == WM_KEYDOWN){
1805 HRESULT result = m_oleInPlaceActiveObject->TranslateAccelerator(msg);
1806 return (result == S_OK);
1807 }
1808
1809 return wxWindow::MSWTranslateMessage(msg);
1810 }
1811
1812 long wxActiveX::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
1813 {
1814 if (m_oleObjectHWND == NULL)
1815 return wxWindow::MSWWindowProc(nMsg, wParam, lParam);
1816
1817 switch(nMsg)
1818 {
1819 case WM_CHAR:
1820 case WM_DEADCHAR:
1821 case WM_KEYDOWN:
1822 case WM_KEYUP:
1823 case WM_SYSCHAR:
1824 case WM_SYSDEADCHAR:
1825 case WM_SYSKEYDOWN:
1826 case WM_SYSKEYUP:
1827 PostMessage(m_oleObjectHWND, nMsg, wParam, lParam);
1828
1829 default:
1830 return wxWindow::MSWWindowProc(nMsg, wParam, lParam);
1831 };
1832 };
1833
1834 void wxActiveX::OnSetFocus(wxFocusEvent& event)
1835 {
1836 if (m_oleInPlaceActiveObject.Ok())
1837 m_oleInPlaceActiveObject->OnFrameWindowActivate(TRUE);
1838 }
1839
1840 void wxActiveX::OnKillFocus(wxFocusEvent& event)
1841 {
1842 if (m_oleInPlaceActiveObject.Ok())
1843 m_oleInPlaceActiveObject->OnFrameWindowActivate(FALSE);
1844 }
1845
1846
1847 FrameSite::FrameSite(wxActiveX * win)
1848 {
1849 m_window = win;
1850 m_bSupportsWindowlessActivation = true;
1851 m_bInPlaceLocked = false;
1852 m_bUIActive = false;
1853 m_bInPlaceActive = false;
1854 m_bWindowless = false;
1855
1856 m_nAmbientLocale = 0;
1857 m_clrAmbientForeColor = ::GetSysColor(COLOR_WINDOWTEXT);
1858 m_clrAmbientBackColor = ::GetSysColor(COLOR_WINDOW);
1859 m_bAmbientShowHatching = true;
1860 m_bAmbientShowGrabHandles = true;
1861 m_bAmbientAppearance = true;
1862
1863 m_hDCBuffer = NULL;
1864 m_hWndParent = (HWND)m_window->GetHWND();
1865 }
1866
1867 FrameSite::~FrameSite()
1868 {
1869 }
1870
1871
1872 //IDispatch
1873
1874 HRESULT FrameSite::GetIDsOfNames(REFIID riid, OLECHAR ** rgszNames, unsigned int cNames,
1875 LCID lcid, DISPID * rgDispId)
1876 {
1877 WXOLE_TRACE("IDispatch::GetIDsOfNames");
1878 return E_NOTIMPL;
1879 }
1880
1881 HRESULT FrameSite::GetTypeInfo(unsigned int iTInfo, LCID lcid, ITypeInfo ** ppTInfo)
1882 {
1883 WXOLE_TRACE("IDispatch::GetTypeInfo");
1884 return E_NOTIMPL;
1885 }
1886
1887 HRESULT FrameSite::GetTypeInfoCount(unsigned int * pcTInfo)
1888 {
1889 WXOLE_TRACE("IDispatch::GetTypeInfoCount");
1890 return E_NOTIMPL;
1891 }
1892
1893 HRESULT FrameSite::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
1894 WORD wFlags, DISPPARAMS * pDispParams,
1895 VARIANT * pVarResult, EXCEPINFO * pExcepInfo,
1896 unsigned int * puArgErr)
1897 {
1898 WXOLE_TRACE("IDispatch::Invoke");
1899
1900 if (!(wFlags & DISPATCH_PROPERTYGET))
1901 return S_OK;
1902
1903 HRESULT hr;
1904
1905 if (pVarResult == NULL)
1906 return E_INVALIDARG;
1907
1908 //The most common case is boolean, use as an initial type
1909 V_VT(pVarResult) = VT_BOOL;
1910
1911 switch (dispIdMember)
1912 {
1913 case DISPID_AMBIENT_MESSAGEREFLECT:
1914 WXOLE_TRACE("Invoke::DISPID_AMBIENT_MESSAGEREFLECT");
1915 V_BOOL(pVarResult)= FALSE;
1916 return S_OK;
1917
1918 case DISPID_AMBIENT_DISPLAYASDEFAULT:
1919 WXOLE_TRACE("Invoke::DISPID_AMBIENT_DISPLAYASDEFAULT");
1920 V_BOOL(pVarResult)= TRUE;
1921 return S_OK;
1922
1923 case DISPID_AMBIENT_OFFLINEIFNOTCONNECTED:
1924 WXOLE_TRACE("Invoke::DISPID_AMBIENT_OFFLINEIFNOTCONNECTED");
1925 V_BOOL(pVarResult) = TRUE;
1926 return S_OK;
1927
1928
1929 case DISPID_AMBIENT_SILENT:
1930 WXOLE_TRACE("Invoke::DISPID_AMBIENT_SILENT");
1931 V_BOOL(pVarResult)= TRUE;
1932 return S_OK;
1933
1934 case DISPID_AMBIENT_APPEARANCE:
1935 pVarResult->vt = VT_BOOL;
1936 pVarResult->boolVal = m_bAmbientAppearance;
1937 break;
1938
1939 case DISPID_AMBIENT_FORECOLOR:
1940 pVarResult->vt = VT_I4;
1941 pVarResult->lVal = (long) m_clrAmbientForeColor;
1942 break;
1943
1944 case DISPID_AMBIENT_BACKCOLOR:
1945 pVarResult->vt = VT_I4;
1946 pVarResult->lVal = (long) m_clrAmbientBackColor;
1947 break;
1948
1949 case DISPID_AMBIENT_LOCALEID:
1950 pVarResult->vt = VT_I4;
1951 pVarResult->lVal = (long) m_nAmbientLocale;
1952 break;
1953
1954 case DISPID_AMBIENT_USERMODE:
1955 pVarResult->vt = VT_BOOL;
1956 pVarResult->boolVal = m_window->m_bAmbientUserMode;
1957 break;
1958
1959 case DISPID_AMBIENT_SHOWGRABHANDLES:
1960 pVarResult->vt = VT_BOOL;
1961 pVarResult->boolVal = m_bAmbientShowGrabHandles;
1962 break;
1963
1964 case DISPID_AMBIENT_SHOWHATCHING:
1965 pVarResult->vt = VT_BOOL;
1966 pVarResult->boolVal = m_bAmbientShowHatching;
1967 break;
1968
1969 default:
1970 return DISP_E_MEMBERNOTFOUND;
1971 }
1972
1973 return S_OK;
1974 }
1975
1976 //IOleWindow
1977
1978 HRESULT FrameSite::GetWindow(HWND * phwnd)
1979 {
1980 WXOLE_TRACE("IOleWindow::GetWindow");
1981 if (phwnd == NULL)
1982 return E_INVALIDARG;
1983 (*phwnd) = m_hWndParent;
1984 return S_OK;
1985 }
1986
1987 HRESULT FrameSite::ContextSensitiveHelp(BOOL fEnterMode)
1988 {
1989 WXOLE_TRACE("IOleWindow::ContextSensitiveHelp");
1990 return S_OK;
1991 }
1992
1993 //IOleInPlaceUIWindow
1994
1995 HRESULT FrameSite::GetBorder(LPRECT lprectBorder)
1996 {
1997 WXOLE_TRACE("IOleInPlaceUIWindow::GetBorder");
1998 if (lprectBorder == NULL)
1999 return E_INVALIDARG;
2000 return INPLACE_E_NOTOOLSPACE;
2001 }
2002
2003 HRESULT FrameSite::RequestBorderSpace(LPCBORDERWIDTHS pborderwidths)
2004 {
2005 WXOLE_TRACE("IOleInPlaceUIWindow::RequestBorderSpace");
2006 if (pborderwidths == NULL)
2007 return E_INVALIDARG;
2008 return INPLACE_E_NOTOOLSPACE;
2009 }
2010
2011 HRESULT FrameSite::SetBorderSpace(LPCBORDERWIDTHS pborderwidths)
2012 {
2013 WXOLE_TRACE("IOleInPlaceUIWindow::SetBorderSpace");
2014 return S_OK;
2015 }
2016
2017 HRESULT FrameSite::SetActiveObject(IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName)
2018 {
2019 WXOLE_TRACE("IOleInPlaceUIWindow::SetActiveObject");
2020
2021 if (pActiveObject)
2022 pActiveObject->AddRef();
2023
2024 m_window->m_oleInPlaceActiveObject = pActiveObject;
2025 return S_OK;
2026 }
2027
2028 //IOleInPlaceFrame
2029
2030 HRESULT FrameSite::InsertMenus(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths)
2031 {
2032 WXOLE_TRACE("IOleInPlaceFrame::InsertMenus");
2033 return S_OK;
2034 }
2035
2036 HRESULT FrameSite::SetMenu(HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject)
2037 {
2038 WXOLE_TRACE("IOleInPlaceFrame::SetMenu");
2039 return S_OK;
2040 }
2041
2042 HRESULT FrameSite::RemoveMenus(HMENU hmenuShared)
2043 {
2044 WXOLE_TRACE("IOleInPlaceFrame::RemoveMenus");
2045 return S_OK;
2046 }
2047
2048 HRESULT FrameSite::SetStatusText(LPCOLESTR pszStatusText)
2049 {
2050 WXOLE_TRACE("IOleInPlaceFrame::SetStatusText");
2051 //((wxFrame*)wxGetApp().GetTopWindow())->GetStatusBar()->SetStatusText(pszStatusText);
2052 return S_OK;
2053 }
2054
2055 HRESULT FrameSite::EnableModeless(BOOL fEnable)
2056 {
2057 WXOLE_TRACE("IOleInPlaceFrame::EnableModeless");
2058 return S_OK;
2059 }
2060
2061 HRESULT FrameSite::TranslateAccelerator(LPMSG lpmsg, WORD wID)
2062 {
2063 WXOLE_TRACE("IOleInPlaceFrame::TranslateAccelerator");
2064 // TODO: send an event with this id
2065 if (m_window->m_oleInPlaceActiveObject.Ok())
2066 m_window->m_oleInPlaceActiveObject->TranslateAccelerator(lpmsg);
2067
2068 return S_FALSE;
2069 }
2070
2071 //IOleInPlaceSite
2072
2073 HRESULT FrameSite::CanInPlaceActivate()
2074 {
2075 WXOLE_TRACE("IOleInPlaceSite::CanInPlaceActivate");
2076 return S_OK;
2077 }
2078
2079 HRESULT FrameSite::OnInPlaceActivate()
2080 {
2081 WXOLE_TRACE("IOleInPlaceSite::OnInPlaceActivate");
2082 m_bInPlaceActive = true;
2083 return S_OK;
2084 }
2085
2086 HRESULT FrameSite::OnUIActivate()
2087 {
2088 WXOLE_TRACE("IOleInPlaceSite::OnUIActivate");
2089 m_bUIActive = true;
2090 return S_OK;
2091 }
2092
2093 HRESULT FrameSite::GetWindowContext(IOleInPlaceFrame **ppFrame,
2094 IOleInPlaceUIWindow **ppDoc,
2095 LPRECT lprcPosRect,
2096 LPRECT lprcClipRect,
2097 LPOLEINPLACEFRAMEINFO lpFrameInfo)
2098 {
2099 WXOLE_TRACE("IOleInPlaceSite::GetWindowContext");
2100 if (ppFrame == NULL || ppDoc == NULL || lprcPosRect == NULL ||
2101 lprcClipRect == NULL || lpFrameInfo == NULL)
2102 {
2103 if (ppFrame != NULL)
2104 (*ppFrame) = NULL;
2105 if (ppDoc != NULL)
2106 (*ppDoc) = NULL;
2107 return E_INVALIDARG;
2108 }
2109
2110 HRESULT hr = QueryInterface(IID_IOleInPlaceFrame, (void **) ppFrame);
2111 if (! SUCCEEDED(hr))
2112 {
2113 WXOLE_TRACE("IOleInPlaceSite::IOleInPlaceFrame Error !");
2114 return E_UNEXPECTED;
2115 };
2116
2117 hr = QueryInterface(IID_IOleInPlaceUIWindow, (void **) ppDoc);
2118 if (! SUCCEEDED(hr))
2119 {
2120 WXOLE_TRACE("IOleInPlaceSite::IOleInPlaceUIWindow Error !");
2121 (*ppFrame)->Release();
2122 *ppFrame = NULL;
2123 return E_UNEXPECTED;
2124 };
2125
2126 int w, h;
2127 m_window->GetClientSize(&w, &h);
2128 if (lprcPosRect)
2129 {
2130 lprcPosRect->left = lprcPosRect->top = 0;
2131 lprcPosRect->right = w;
2132 lprcPosRect->bottom = h;
2133 };
2134 if (lprcClipRect)
2135 {
2136 lprcClipRect->left = lprcClipRect->top = 0;
2137 lprcClipRect->right = w;
2138 lprcClipRect->bottom = h;
2139 };
2140
2141 memset(lpFrameInfo, 0, sizeof(OLEINPLACEFRAMEINFO));
2142 lpFrameInfo->cb = sizeof(OLEINPLACEFRAMEINFO);
2143 lpFrameInfo->hwndFrame = m_hWndParent;
2144
2145 return S_OK;
2146 }
2147
2148 HRESULT FrameSite::Scroll(SIZE scrollExtent)
2149 {
2150 WXOLE_TRACE("IOleInPlaceSite::Scroll");
2151 return S_OK;
2152 }
2153
2154 HRESULT FrameSite::OnUIDeactivate(BOOL fUndoable)
2155 {
2156 WXOLE_TRACE("IOleInPlaceSite::OnUIDeactivate");
2157 m_bUIActive = false;
2158 return S_OK;
2159 }
2160
2161 HRESULT FrameSite::OnInPlaceDeactivate()
2162 {
2163 WXOLE_TRACE("IOleInPlaceSite::OnInPlaceDeactivate");
2164 m_bInPlaceActive = false;
2165 return S_OK;
2166 }
2167
2168 HRESULT FrameSite::DiscardUndoState()
2169 {
2170 WXOLE_TRACE("IOleInPlaceSite::DiscardUndoState");
2171 return S_OK;
2172 }
2173
2174 HRESULT FrameSite::DeactivateAndUndo()
2175 {
2176 WXOLE_TRACE("IOleInPlaceSite::DeactivateAndUndo");
2177 return S_OK;
2178 }
2179
2180 HRESULT FrameSite::OnPosRectChange(LPCRECT lprcPosRect)
2181 {
2182 WXOLE_TRACE("IOleInPlaceSite::OnPosRectChange");
2183 if (m_window->m_oleInPlaceObject.Ok() && lprcPosRect)
2184 m_window->m_oleInPlaceObject->SetObjectRects(lprcPosRect, lprcPosRect);
2185
2186 return S_OK;
2187 }
2188
2189 //IOleInPlaceSiteEx
2190
2191 HRESULT FrameSite::OnInPlaceActivateEx(BOOL * pfNoRedraw, DWORD dwFlags)
2192 {
2193 WXOLE_TRACE("IOleInPlaceSiteEx::OnInPlaceActivateEx");
2194 OleLockRunning(m_window->m_ActiveX, TRUE, FALSE);
2195 if (pfNoRedraw)
2196 (*pfNoRedraw) = FALSE;
2197 return S_OK;
2198 }
2199
2200 HRESULT FrameSite::OnInPlaceDeactivateEx(BOOL fNoRedraw)
2201 {
2202 WXOLE_TRACE("IOleInPlaceSiteEx::OnInPlaceDeactivateEx");
2203 OleLockRunning(m_window->m_ActiveX, FALSE, FALSE);
2204 return S_OK;
2205 }
2206
2207 HRESULT FrameSite::RequestUIActivate()
2208 {
2209 WXOLE_TRACE("IOleInPlaceSiteEx::RequestUIActivate");
2210 return S_OK;
2211 }
2212
2213
2214 //IOleClientSite
2215
2216 HRESULT FrameSite::SaveObject()
2217 {
2218 WXOLE_TRACE("IOleClientSite::SaveObject");
2219 return S_OK;
2220 }
2221
2222 const char *OleGetMonikerToStr(DWORD dwAssign)
2223 {
2224 switch (dwAssign)
2225 {
2226 case OLEGETMONIKER_ONLYIFTHERE : return "OLEGETMONIKER_ONLYIFTHERE";
2227 case OLEGETMONIKER_FORCEASSIGN : return "OLEGETMONIKER_FORCEASSIGN";
2228 case OLEGETMONIKER_UNASSIGN : return "OLEGETMONIKER_UNASSIGN";
2229 case OLEGETMONIKER_TEMPFORUSER : return "OLEGETMONIKER_TEMPFORUSER";
2230 default : return "Bad Enum";
2231 };
2232 };
2233
2234 const char *OleGetWhicMonikerStr(DWORD dwWhichMoniker)
2235 {
2236 switch(dwWhichMoniker)
2237 {
2238 case OLEWHICHMK_CONTAINER : return "OLEWHICHMK_CONTAINER";
2239 case OLEWHICHMK_OBJREL : return "OLEWHICHMK_OBJREL";
2240 case OLEWHICHMK_OBJFULL : return "OLEWHICHMK_OBJFULL";
2241 default : return "Bad Enum";
2242 };
2243 };
2244
2245 HRESULT FrameSite::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker,
2246 IMoniker ** ppmk)
2247 {
2248 WXOLE_TRACEOUT("IOleClientSite::GetMoniker(" << OleGetMonikerToStr(dwAssign) << ", " << OleGetWhicMonikerStr(dwWhichMoniker) << ")");
2249
2250
2251 if (! ppmk)
2252 return E_FAIL;
2253
2254 /*
2255 HRESULT hr = CreateFileMoniker(L"e:\\dev\\wxie\\bug-zap.swf", ppmk);
2256 if (SUCCEEDED(hr))
2257 return S_OK;
2258 */
2259 *ppmk = NULL;
2260
2261 return E_FAIL ;
2262 }
2263
2264 HRESULT FrameSite::GetContainer(LPOLECONTAINER * ppContainer)
2265 {
2266 WXOLE_TRACE("IOleClientSite::GetContainer");
2267 if (ppContainer == NULL)
2268 return E_INVALIDARG;
2269
2270 HRESULT hr = QueryInterface(IID_IOleContainer, (void**)(ppContainer));
2271 wxASSERT(SUCCEEDED(hr));
2272
2273 return hr;
2274 }
2275
2276 HRESULT FrameSite::ShowObject()
2277 {
2278 WXOLE_TRACE("IOleClientSite::ShowObject");
2279 if (m_window->m_oleObjectHWND)
2280 ::ShowWindow(m_window->m_oleObjectHWND, SW_SHOW);
2281 return S_OK;
2282 }
2283
2284 HRESULT FrameSite::OnShowWindow(BOOL fShow)
2285 {
2286 WXOLE_TRACE("IOleClientSite::OnShowWindow");
2287 return S_OK;
2288 }
2289
2290 HRESULT FrameSite::RequestNewObjectLayout()
2291 {
2292 WXOLE_TRACE("IOleClientSite::RequestNewObjectLayout");
2293 return E_NOTIMPL;
2294 }
2295
2296 // IParseDisplayName
2297
2298 HRESULT FrameSite::ParseDisplayName(IBindCtx *pbc, LPOLESTR pszDisplayName,
2299 ULONG *pchEaten, IMoniker **ppmkOut)
2300 {
2301 WXOLE_TRACE("IParseDisplayName::ParseDisplayName");
2302 return E_NOTIMPL;
2303 }
2304
2305 //IOleContainer
2306
2307 HRESULT FrameSite::EnumObjects(DWORD grfFlags, IEnumUnknown **ppenum)
2308 {
2309 WXOLE_TRACE("IOleContainer::EnumObjects");
2310 return E_NOTIMPL;
2311 }
2312
2313 HRESULT FrameSite::LockContainer(BOOL fLock)
2314 {
2315 WXOLE_TRACE("IOleContainer::LockContainer");
2316 // TODO
2317 return S_OK;
2318 }
2319
2320 //IOleItemContainer
2321
2322 HRESULT FrameSite::GetObject(LPOLESTR pszItem, DWORD dwSpeedNeeded,
2323 IBindCtx * pbc, REFIID riid, void ** ppvObject)
2324 {
2325 WXOLE_TRACE("IOleItemContainer::GetObject");
2326 if (pszItem == NULL)
2327 return E_INVALIDARG;
2328 if (ppvObject == NULL)
2329 return E_INVALIDARG;
2330
2331 *ppvObject = NULL;
2332 return MK_E_NOOBJECT;
2333 }
2334
2335 HRESULT FrameSite::GetObjectStorage(LPOLESTR pszItem, IBindCtx * pbc,
2336 REFIID riid, void ** ppvStorage)
2337 {
2338 WXOLE_TRACE("IOleItemContainer::GetObjectStorage");
2339 if (pszItem == NULL)
2340 return E_INVALIDARG;
2341 if (ppvStorage == NULL)
2342 return E_INVALIDARG;
2343
2344 *ppvStorage = NULL;
2345 return MK_E_NOOBJECT;
2346 }
2347
2348 HRESULT FrameSite::IsRunning(LPOLESTR pszItem)
2349 {
2350 WXOLE_TRACE("IOleItemContainer::IsRunning");
2351 if (pszItem == NULL)
2352 return E_INVALIDARG;
2353
2354 return MK_E_NOOBJECT;
2355 }
2356
2357
2358
2359 //IOleControlSite
2360
2361 HRESULT FrameSite::OnControlInfoChanged()
2362 {
2363 WXOLE_TRACE("IOleControlSite::OnControlInfoChanged");
2364 return S_OK;
2365 }
2366
2367 HRESULT FrameSite::LockInPlaceActive(BOOL fLock)
2368 {
2369 WXOLE_TRACE("IOleControlSite::LockInPlaceActive");
2370 m_bInPlaceLocked = (fLock) ? true : false;
2371 return S_OK;
2372 }
2373
2374 HRESULT FrameSite::GetExtendedControl(IDispatch ** ppDisp)
2375 {
2376 WXOLE_TRACE("IOleControlSite::GetExtendedControl");
2377 return E_NOTIMPL;
2378 }
2379
2380 HRESULT FrameSite::TransformCoords(POINTL * pPtlHimetric, POINTF * pPtfContainer, DWORD dwFlags)
2381 {
2382 WXOLE_TRACE("IOleControlSite::TransformCoords");
2383 HRESULT hr = S_OK;
2384
2385 if (pPtlHimetric == NULL)
2386 return E_INVALIDARG;
2387
2388 if (pPtfContainer == NULL)
2389 return E_INVALIDARG;
2390
2391 return E_NOTIMPL;
2392
2393 }
2394
2395 HRESULT FrameSite::TranslateAccelerator(LPMSG pMsg, DWORD grfModifiers)
2396 {
2397 WXOLE_TRACE("IOleControlSite::TranslateAccelerator");
2398 // TODO: send an event with this id
2399 return E_NOTIMPL;
2400 }
2401
2402 HRESULT FrameSite::OnFocus(BOOL fGotFocus)
2403 {
2404 WXOLE_TRACE("IOleControlSite::OnFocus");
2405 return S_OK;
2406 }
2407
2408 HRESULT FrameSite::ShowPropertyFrame()
2409 {
2410 WXOLE_TRACE("IOleControlSite::ShowPropertyFrame");
2411 return E_NOTIMPL;
2412 }
2413
2414 //IOleCommandTarget
2415
2416 HRESULT FrameSite::QueryStatus(const GUID * pguidCmdGroup, ULONG cCmds,
2417 OLECMD * prgCmds, OLECMDTEXT * pCmdTet)
2418 {
2419 WXOLE_TRACE("IOleCommandTarget::QueryStatus");
2420 if (prgCmds == NULL) return E_INVALIDARG;
2421 bool bCmdGroupFound = false;
2422
2423 for (ULONG nCmd = 0; nCmd < cCmds; nCmd++)
2424 {
2425 // unsupported by default
2426 prgCmds[nCmd].cmdf = 0;
2427
2428 // TODO
2429 }
2430
2431 if (!bCmdGroupFound) { OLECMDERR_E_UNKNOWNGROUP; }
2432 return S_OK;
2433 }
2434
2435 HRESULT FrameSite::Exec(const GUID * pguidCmdGroup, DWORD nCmdID,
2436 DWORD nCmdExecOpt, VARIANTARG * pVaIn,
2437 VARIANTARG * pVaOut)
2438 {
2439 WXOLE_TRACE("IOleCommandTarget::Exec");
2440 bool bCmdGroupFound = false;
2441
2442 if (!bCmdGroupFound) { OLECMDERR_E_UNKNOWNGROUP; }
2443 return OLECMDERR_E_NOTSUPPORTED;
2444 }
2445
2446 //IAdviseSink
2447
2448 void STDMETHODCALLTYPE FrameSite::OnDataChange(FORMATETC * pFormatEtc, STGMEDIUM * pgStgMed)
2449 {
2450 WXOLE_TRACE("IAdviseSink::OnDataChange");
2451 }
2452
2453 void STDMETHODCALLTYPE FrameSite::OnViewChange(DWORD dwAspect, LONG lIndex)
2454 {
2455 WXOLE_TRACE("IAdviseSink::OnViewChange");
2456 // redraw the control
2457 }
2458
2459 void STDMETHODCALLTYPE FrameSite::OnRename(IMoniker * pmk)
2460 {
2461 WXOLE_TRACE("IAdviseSink::OnRename");
2462 }
2463
2464 void STDMETHODCALLTYPE FrameSite::OnSave()
2465 {
2466 WXOLE_TRACE("IAdviseSink::OnSave");
2467 }
2468
2469 void STDMETHODCALLTYPE FrameSite::OnClose()
2470 {
2471 WXOLE_TRACE("IAdviseSink::OnClose");
2472 }
2473
2474 /////////////////////////////////////////////
2475 // IOleDocumentSite
2476 HRESULT STDMETHODCALLTYPE FrameSite::ActivateMe(
2477 /* [in] */ IOleDocumentView __RPC_FAR *pViewToActivate)
2478 {
2479 wxAutoOleInterface<IOleInPlaceSite> inPlaceSite(IID_IOleInPlaceSite, (IDispatch *) this);
2480 if (!inPlaceSite.Ok())
2481 return E_FAIL;
2482
2483 if (pViewToActivate)
2484 {
2485 m_window->m_docView = pViewToActivate;
2486 m_window->m_docView->SetInPlaceSite(inPlaceSite);
2487 }
2488 else
2489 {
2490 wxAutoOleInterface<IOleDocument> oleDoc(IID_IOleDocument, m_window->m_oleObject);
2491 if (! oleDoc.Ok())
2492 return E_FAIL;
2493
2494 HRESULT hr = oleDoc->CreateView(inPlaceSite, NULL, 0, m_window->m_docView.GetRef());
2495 if (hr != S_OK)
2496 return E_FAIL;
2497
2498 m_window->m_docView->SetInPlaceSite(inPlaceSite);
2499 };
2500
2501 m_window->m_docView->UIActivate(TRUE);
2502
2503 return S_OK;
2504 };
2505
2506
2507 static IMalloc *iMalloc = NULL;
2508
2509 IMalloc *wxOleInit::GetIMalloc()
2510 {
2511 assert(iMalloc);
2512 return iMalloc;
2513 };
2514
2515 wxOleInit::wxOleInit()
2516 {
2517 if (OleInitialize(NULL) == S_OK && iMalloc == NULL)
2518 CoGetMalloc(1, &iMalloc);
2519 else if (iMalloc)
2520 iMalloc->AddRef();
2521 };
2522
2523 wxOleInit::~wxOleInit()
2524 {
2525 if (iMalloc)
2526 {
2527 if (iMalloc->Release() == 0)
2528 iMalloc = NULL;
2529 };
2530
2531 OleUninitialize();
2532 }
2533
2534 bool GetSysErrMessage(int err, wxString& s)
2535 {
2536 wxChar buf[256];
2537 if (FormatMessage(
2538 FORMAT_MESSAGE_FROM_SYSTEM, NULL,
2539 err,0, buf, sizeof(buf), NULL) == 0)
2540 return false;
2541
2542 buf[sizeof(buf) - 1] = 0;
2543 s = buf;
2544 return true;
2545 };
2546
2547 wxString OLEHResultToString(HRESULT hr)
2548 {
2549 // try formatmessage
2550 wxString err;
2551 if (GetSysErrMessage(hr, err))
2552 return err;
2553
2554 switch (hr)
2555 {
2556 case S_OK:
2557 return wxEmptyString;
2558
2559 case CONNECT_E_CANNOTCONNECT:
2560 return _T("Cannot connect to event interface (maybe not there ?) - see MSDN");
2561
2562 case DISP_E_MEMBERNOTFOUND:
2563 return _T("The requested member does not exist, or the call to Invoke tried to set the value of a read-only property.");
2564
2565 case DISP_E_BADVARTYPE:
2566 return _T("One of the parameters in rgvarg is not a valid variant type.");
2567
2568 case DISP_E_BADPARAMCOUNT:
2569 return _T("The number of elements provided to DISPPARAMS is different from the number of parameters accepted by the method or property");
2570
2571 case DISP_E_EXCEPTION:
2572 return _T("The application needs to raise an exception. In this case, the structure passed in pExcepInfo should be filled in.");
2573
2574 case DISP_E_TYPEMISMATCH:
2575 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.");
2576
2577 case DISP_E_PARAMNOTOPTIONAL:
2578 return _T("A required parameter was omitted.");
2579
2580 case DISP_E_PARAMNOTFOUND:
2581 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.");
2582
2583 case OLECMDERR_E_UNKNOWNGROUP:
2584 return _T("The pguidCmdGroup parameter is not NULL but does not specify a recognized command group.");
2585
2586 case OLECMDERR_E_NOTSUPPORTED:
2587 return _T("The nCmdID parameter is not a valid command in the group identified by pguidCmdGroup.");
2588
2589 case OLECMDERR_E_DISABLED:
2590 return _T("The command identified by nCmdID is currently disabled and cannot be executed.");
2591
2592 case OLECMDERR_E_NOHELP:
2593 return _T("The caller has asked for help on the command identified by nCmdID, but no help is available.");
2594
2595 case OLECMDERR_E_CANCELED:
2596 return _T("The user canceled the execution of the command.");
2597
2598 case E_INVALIDARG:
2599 return _T("E_INVALIDARG");
2600
2601 case E_OUTOFMEMORY:
2602 return _T("E_OUTOFMEMORY");
2603
2604 case E_NOINTERFACE:
2605 return _T("E_NOINTERFACE");
2606
2607 case E_UNEXPECTED:
2608 return _T("E_UNEXPECTED");
2609
2610 case STG_E_INVALIDFLAG:
2611 return _T("STG_E_INVALIDFLAG");
2612
2613 case E_FAIL:
2614 return _T("E_FAIL");
2615
2616 case E_NOTIMPL:
2617 return _T("E_NOTIMPL");
2618
2619 default:
2620 {
2621 wxString buf;
2622 buf.Printf(_T("Unknown - 0x%X"), hr);
2623 return buf;
2624 }
2625 };
2626 };
2627
2628 // borrowed from src/msw/ole/oleutils.cpp
2629 wxString GetIIDName(REFIID riid)
2630 {
2631 // an association between symbolic name and numeric value of an IID
2632 struct KNOWN_IID
2633 {
2634 const IID *pIid;
2635 const wxChar *szName;
2636 };
2637
2638 // construct the table containing all known interfaces
2639 #define ADD_KNOWN_IID(name) { &IID_I##name, _T(#name) }
2640 #define ADD_KNOWN_GUID(name) { &name, _T(#name) }
2641
2642 static const KNOWN_IID aKnownIids[] =
2643 {
2644 ADD_KNOWN_IID(ServiceProvider),
2645 ADD_KNOWN_IID(AdviseSink),
2646 ADD_KNOWN_IID(AdviseSink2),
2647 ADD_KNOWN_IID(BindCtx),
2648 ADD_KNOWN_IID(ClassFactory),
2649 #if ( !defined( __VISUALC__) || (__VISUALC__!=1010) ) && !defined(__MWERKS__)
2650 ADD_KNOWN_IID(ContinueCallback),
2651 ADD_KNOWN_IID(EnumOleDocumentViews),
2652 ADD_KNOWN_IID(OleCommandTarget),
2653 ADD_KNOWN_IID(OleDocument),
2654 ADD_KNOWN_IID(OleDocumentSite),
2655 ADD_KNOWN_IID(OleDocumentView),
2656 ADD_KNOWN_IID(Print),
2657 #endif
2658 ADD_KNOWN_IID(DataAdviseHolder),
2659 ADD_KNOWN_IID(DataObject),
2660 ADD_KNOWN_IID(Debug),
2661 ADD_KNOWN_IID(DebugStream),
2662 ADD_KNOWN_IID(DfReserved1),
2663 ADD_KNOWN_IID(DfReserved2),
2664 ADD_KNOWN_IID(DfReserved3),
2665 ADD_KNOWN_IID(Dispatch),
2666 ADD_KNOWN_IID(DropSource),
2667 ADD_KNOWN_IID(DropTarget),
2668 ADD_KNOWN_IID(EnumCallback),
2669 ADD_KNOWN_IID(EnumFORMATETC),
2670 ADD_KNOWN_IID(EnumGeneric),
2671 ADD_KNOWN_IID(EnumHolder),
2672 ADD_KNOWN_IID(EnumMoniker),
2673 ADD_KNOWN_IID(EnumOLEVERB),
2674 ADD_KNOWN_IID(EnumSTATDATA),
2675 ADD_KNOWN_IID(EnumSTATSTG),
2676 ADD_KNOWN_IID(EnumString),
2677 ADD_KNOWN_IID(EnumUnknown),
2678 ADD_KNOWN_IID(EnumVARIANT),
2679 ADD_KNOWN_IID(ExternalConnection),
2680 ADD_KNOWN_IID(InternalMoniker),
2681 ADD_KNOWN_IID(LockBytes),
2682 ADD_KNOWN_IID(Malloc),
2683 ADD_KNOWN_IID(Marshal),
2684 ADD_KNOWN_IID(MessageFilter),
2685 ADD_KNOWN_IID(Moniker),
2686 ADD_KNOWN_IID(OleAdviseHolder),
2687 ADD_KNOWN_IID(OleCache),
2688 ADD_KNOWN_IID(OleCache2),
2689 ADD_KNOWN_IID(OleCacheControl),
2690 ADD_KNOWN_IID(OleClientSite),
2691 ADD_KNOWN_IID(OleContainer),
2692 ADD_KNOWN_IID(OleInPlaceActiveObject),
2693 ADD_KNOWN_IID(OleInPlaceFrame),
2694 ADD_KNOWN_IID(OleInPlaceObject),
2695 ADD_KNOWN_IID(OleInPlaceSite),
2696 ADD_KNOWN_IID(OleInPlaceUIWindow),
2697 ADD_KNOWN_IID(OleItemContainer),
2698 ADD_KNOWN_IID(OleLink),
2699 ADD_KNOWN_IID(OleManager),
2700 ADD_KNOWN_IID(OleObject),
2701 ADD_KNOWN_IID(OlePresObj),
2702 ADD_KNOWN_IID(OleWindow),
2703 ADD_KNOWN_IID(PSFactory),
2704 ADD_KNOWN_IID(ParseDisplayName),
2705 ADD_KNOWN_IID(Persist),
2706 ADD_KNOWN_IID(PersistFile),
2707 ADD_KNOWN_IID(PersistStorage),
2708 ADD_KNOWN_IID(PersistStream),
2709 ADD_KNOWN_IID(ProxyManager),
2710 ADD_KNOWN_IID(RootStorage),
2711 ADD_KNOWN_IID(RpcChannel),
2712 ADD_KNOWN_IID(RpcProxy),
2713 ADD_KNOWN_IID(RpcStub),
2714 ADD_KNOWN_IID(RunnableObject),
2715 ADD_KNOWN_IID(RunningObjectTable),
2716 ADD_KNOWN_IID(StdMarshalInfo),
2717 ADD_KNOWN_IID(Storage),
2718 ADD_KNOWN_IID(Stream),
2719 ADD_KNOWN_IID(StubManager),
2720 ADD_KNOWN_IID(Unknown),
2721 ADD_KNOWN_IID(ViewObject),
2722 ADD_KNOWN_IID(ViewObject2),
2723 ADD_KNOWN_GUID(IID_IDispatch),
2724 ADD_KNOWN_GUID(IID_IWebBrowser),
2725 ADD_KNOWN_GUID(IID_IWebBrowserApp),
2726 ADD_KNOWN_GUID(IID_IWebBrowser2),
2727 ADD_KNOWN_GUID(IID_IWebBrowser),
2728 ADD_KNOWN_GUID(DIID_DWebBrowserEvents2),
2729 ADD_KNOWN_GUID(DIID_DWebBrowserEvents),
2730 };
2731
2732 // don't clobber preprocessor name space
2733 #undef ADD_KNOWN_IID
2734 #undef ADD_KNOWN_GUID
2735
2736 // try to find the interface in the table
2737 for ( size_t ui = 0; ui < WXSIZEOF(aKnownIids); ui++ )
2738 {
2739 if ( riid == *aKnownIids[ui].pIid )
2740 {
2741 return aKnownIids[ui].szName;
2742 }
2743 }
2744
2745 // unknown IID, just transform to string
2746 LPOLESTR str = NULL;
2747 StringFromIID(riid, &str);
2748 if (str)
2749 {
2750 wxString s = str;
2751 CoTaskMemFree(str);
2752 return s;
2753 }
2754 else
2755 return _T("StringFromIID() error");
2756 }