]> git.saurik.com Git - wxWidgets.git/blob - wxPython/contrib/activex/wxie/wxactivex.cpp
Fix for MSVC 6 compile error
[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 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 dc.BeginDrawing();
1710 int w, h;
1711 GetSize(&w, &h);
1712 RECT posRect;
1713 posRect.left = 0;
1714 posRect.top = 0;
1715 posRect.right = w;
1716 posRect.bottom = h;
1717
1718 // Draw only when control is windowless or deactivated
1719 if (m_viewObject)
1720 {
1721 ::RedrawWindow(m_oleObjectHWND, NULL, NULL, RDW_INTERNALPAINT);
1722 {
1723 RECTL *prcBounds = (RECTL *) &posRect;
1724 m_viewObject->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL,
1725 (HDC)dc.GetHDC(), prcBounds, NULL, NULL, 0);
1726 }
1727 }
1728 else
1729 {
1730 dc.SetBrush(*wxRED_BRUSH);
1731 dc.DrawRectangle(0, 0, w, h);
1732 dc.SetBrush(wxNullBrush);
1733 }
1734 dc.EndDrawing();
1735 }
1736
1737
1738 void wxActiveX::OnMouse(wxMouseEvent& event)
1739 {
1740 if (m_oleObjectHWND == NULL)
1741 {
1742 wxLogTrace(wxT(""),wxT("no oleInPlaceObject"));
1743 event.Skip();
1744 return;
1745 }
1746
1747 wxLogTrace(wxT(""),wxT("mouse event"));
1748 UINT msg = 0;
1749 WPARAM wParam = 0;
1750 LPARAM lParam = 0;
1751 LRESULT lResult = 0;
1752
1753 if (event.m_metaDown)
1754 wParam |= MK_CONTROL;
1755 if (event.m_shiftDown)
1756 wParam |= MK_SHIFT;
1757 if (event.m_leftDown)
1758 wParam |= MK_LBUTTON;
1759 if (event.m_middleDown)
1760 wParam |= MK_MBUTTON;
1761 if (event.m_rightDown)
1762 wParam |= MK_RBUTTON;
1763 lParam = event.m_x << 16;
1764 lParam |= event.m_y;
1765
1766 if (event.LeftDown())
1767 msg = WM_LBUTTONDOWN;
1768 else if (event.LeftDClick())
1769 msg = WM_LBUTTONDBLCLK;
1770 else if (event.LeftUp())
1771 msg = WM_LBUTTONUP;
1772 else if (event.MiddleDown())
1773 msg = WM_MBUTTONDOWN;
1774 else if (event.MiddleDClick())
1775 msg = WM_MBUTTONDBLCLK;
1776 else if (event.MiddleUp())
1777 msg = WM_MBUTTONUP;
1778 else if (event.RightDown())
1779 msg = WM_RBUTTONDOWN;
1780 else if (event.RightDClick())
1781 msg = WM_RBUTTONDBLCLK;
1782 else if (event.RightUp())
1783 msg = WM_RBUTTONUP;
1784 else if (event.Moving() || event.Dragging())
1785 msg = WM_MOUSEMOVE;
1786
1787 wxString log;
1788 if (msg == 0)
1789 {
1790 wxLogTrace(wxT(""),wxT("no message"));
1791 event.Skip(); return;
1792 };
1793
1794 if (!::SendMessage(m_oleObjectHWND, msg, wParam, lParam))
1795 {
1796 wxLogTrace(wxT(""),wxT("msg not delivered"));
1797 event.Skip();
1798 return;
1799 };
1800
1801 wxLogTrace(wxT(""),wxT("msg sent"));
1802 }
1803
1804 bool wxActiveX::MSWTranslateMessage(WXMSG *msg){
1805
1806 if (msg->message == WM_KEYDOWN){
1807 HRESULT result = m_oleInPlaceActiveObject->TranslateAccelerator(msg);
1808 return (result == S_OK);
1809 }
1810
1811 return wxWindow::MSWTranslateMessage(msg);
1812 }
1813
1814 long wxActiveX::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
1815 {
1816 if (m_oleObjectHWND == NULL)
1817 return wxWindow::MSWWindowProc(nMsg, wParam, lParam);
1818
1819 switch(nMsg)
1820 {
1821 case WM_CHAR:
1822 case WM_DEADCHAR:
1823 case WM_KEYDOWN:
1824 case WM_KEYUP:
1825 case WM_SYSCHAR:
1826 case WM_SYSDEADCHAR:
1827 case WM_SYSKEYDOWN:
1828 case WM_SYSKEYUP:
1829 PostMessage(m_oleObjectHWND, nMsg, wParam, lParam);
1830
1831 default:
1832 return wxWindow::MSWWindowProc(nMsg, wParam, lParam);
1833 };
1834 };
1835
1836 void wxActiveX::OnSetFocus(wxFocusEvent& event)
1837 {
1838 if (m_oleInPlaceActiveObject.Ok())
1839 m_oleInPlaceActiveObject->OnFrameWindowActivate(TRUE);
1840 }
1841
1842 void wxActiveX::OnKillFocus(wxFocusEvent& event)
1843 {
1844 if (m_oleInPlaceActiveObject.Ok())
1845 m_oleInPlaceActiveObject->OnFrameWindowActivate(FALSE);
1846 }
1847
1848
1849 FrameSite::FrameSite(wxActiveX * win)
1850 {
1851 m_window = win;
1852 m_bSupportsWindowlessActivation = true;
1853 m_bInPlaceLocked = false;
1854 m_bUIActive = false;
1855 m_bInPlaceActive = false;
1856 m_bWindowless = false;
1857
1858 m_nAmbientLocale = 0;
1859 m_clrAmbientForeColor = ::GetSysColor(COLOR_WINDOWTEXT);
1860 m_clrAmbientBackColor = ::GetSysColor(COLOR_WINDOW);
1861 m_bAmbientShowHatching = true;
1862 m_bAmbientShowGrabHandles = true;
1863 m_bAmbientAppearance = true;
1864
1865 m_hDCBuffer = NULL;
1866 m_hWndParent = (HWND)m_window->GetHWND();
1867 }
1868
1869 FrameSite::~FrameSite()
1870 {
1871 }
1872
1873
1874 //IDispatch
1875
1876 HRESULT FrameSite::GetIDsOfNames(REFIID riid, OLECHAR ** rgszNames, unsigned int cNames,
1877 LCID lcid, DISPID * rgDispId)
1878 {
1879 WXOLE_TRACE("IDispatch::GetIDsOfNames");
1880 return E_NOTIMPL;
1881 }
1882
1883 HRESULT FrameSite::GetTypeInfo(unsigned int iTInfo, LCID lcid, ITypeInfo ** ppTInfo)
1884 {
1885 WXOLE_TRACE("IDispatch::GetTypeInfo");
1886 return E_NOTIMPL;
1887 }
1888
1889 HRESULT FrameSite::GetTypeInfoCount(unsigned int * pcTInfo)
1890 {
1891 WXOLE_TRACE("IDispatch::GetTypeInfoCount");
1892 return E_NOTIMPL;
1893 }
1894
1895 HRESULT FrameSite::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
1896 WORD wFlags, DISPPARAMS * pDispParams,
1897 VARIANT * pVarResult, EXCEPINFO * pExcepInfo,
1898 unsigned int * puArgErr)
1899 {
1900 WXOLE_TRACE("IDispatch::Invoke");
1901
1902 if (!(wFlags & DISPATCH_PROPERTYGET))
1903 return S_OK;
1904
1905 HRESULT hr;
1906
1907 if (pVarResult == NULL)
1908 return E_INVALIDARG;
1909
1910 //The most common case is boolean, use as an initial type
1911 V_VT(pVarResult) = VT_BOOL;
1912
1913 switch (dispIdMember)
1914 {
1915 case DISPID_AMBIENT_MESSAGEREFLECT:
1916 WXOLE_TRACE("Invoke::DISPID_AMBIENT_MESSAGEREFLECT");
1917 V_BOOL(pVarResult)= FALSE;
1918 return S_OK;
1919
1920 case DISPID_AMBIENT_DISPLAYASDEFAULT:
1921 WXOLE_TRACE("Invoke::DISPID_AMBIENT_DISPLAYASDEFAULT");
1922 V_BOOL(pVarResult)= TRUE;
1923 return S_OK;
1924
1925 case DISPID_AMBIENT_OFFLINEIFNOTCONNECTED:
1926 WXOLE_TRACE("Invoke::DISPID_AMBIENT_OFFLINEIFNOTCONNECTED");
1927 V_BOOL(pVarResult) = TRUE;
1928 return S_OK;
1929
1930
1931 case DISPID_AMBIENT_SILENT:
1932 WXOLE_TRACE("Invoke::DISPID_AMBIENT_SILENT");
1933 V_BOOL(pVarResult)= TRUE;
1934 return S_OK;
1935
1936 case DISPID_AMBIENT_APPEARANCE:
1937 pVarResult->vt = VT_BOOL;
1938 pVarResult->boolVal = m_bAmbientAppearance;
1939 break;
1940
1941 case DISPID_AMBIENT_FORECOLOR:
1942 pVarResult->vt = VT_I4;
1943 pVarResult->lVal = (long) m_clrAmbientForeColor;
1944 break;
1945
1946 case DISPID_AMBIENT_BACKCOLOR:
1947 pVarResult->vt = VT_I4;
1948 pVarResult->lVal = (long) m_clrAmbientBackColor;
1949 break;
1950
1951 case DISPID_AMBIENT_LOCALEID:
1952 pVarResult->vt = VT_I4;
1953 pVarResult->lVal = (long) m_nAmbientLocale;
1954 break;
1955
1956 case DISPID_AMBIENT_USERMODE:
1957 pVarResult->vt = VT_BOOL;
1958 pVarResult->boolVal = m_window->m_bAmbientUserMode;
1959 break;
1960
1961 case DISPID_AMBIENT_SHOWGRABHANDLES:
1962 pVarResult->vt = VT_BOOL;
1963 pVarResult->boolVal = m_bAmbientShowGrabHandles;
1964 break;
1965
1966 case DISPID_AMBIENT_SHOWHATCHING:
1967 pVarResult->vt = VT_BOOL;
1968 pVarResult->boolVal = m_bAmbientShowHatching;
1969 break;
1970
1971 default:
1972 return DISP_E_MEMBERNOTFOUND;
1973 }
1974
1975 return S_OK;
1976 }
1977
1978 //IOleWindow
1979
1980 HRESULT FrameSite::GetWindow(HWND * phwnd)
1981 {
1982 WXOLE_TRACE("IOleWindow::GetWindow");
1983 if (phwnd == NULL)
1984 return E_INVALIDARG;
1985 (*phwnd) = m_hWndParent;
1986 return S_OK;
1987 }
1988
1989 HRESULT FrameSite::ContextSensitiveHelp(BOOL fEnterMode)
1990 {
1991 WXOLE_TRACE("IOleWindow::ContextSensitiveHelp");
1992 return S_OK;
1993 }
1994
1995 //IOleInPlaceUIWindow
1996
1997 HRESULT FrameSite::GetBorder(LPRECT lprectBorder)
1998 {
1999 WXOLE_TRACE("IOleInPlaceUIWindow::GetBorder");
2000 if (lprectBorder == NULL)
2001 return E_INVALIDARG;
2002 return INPLACE_E_NOTOOLSPACE;
2003 }
2004
2005 HRESULT FrameSite::RequestBorderSpace(LPCBORDERWIDTHS pborderwidths)
2006 {
2007 WXOLE_TRACE("IOleInPlaceUIWindow::RequestBorderSpace");
2008 if (pborderwidths == NULL)
2009 return E_INVALIDARG;
2010 return INPLACE_E_NOTOOLSPACE;
2011 }
2012
2013 HRESULT FrameSite::SetBorderSpace(LPCBORDERWIDTHS pborderwidths)
2014 {
2015 WXOLE_TRACE("IOleInPlaceUIWindow::SetBorderSpace");
2016 return S_OK;
2017 }
2018
2019 HRESULT FrameSite::SetActiveObject(IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName)
2020 {
2021 WXOLE_TRACE("IOleInPlaceUIWindow::SetActiveObject");
2022
2023 if (pActiveObject)
2024 pActiveObject->AddRef();
2025
2026 m_window->m_oleInPlaceActiveObject = pActiveObject;
2027 return S_OK;
2028 }
2029
2030 //IOleInPlaceFrame
2031
2032 HRESULT FrameSite::InsertMenus(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths)
2033 {
2034 WXOLE_TRACE("IOleInPlaceFrame::InsertMenus");
2035 return S_OK;
2036 }
2037
2038 HRESULT FrameSite::SetMenu(HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject)
2039 {
2040 WXOLE_TRACE("IOleInPlaceFrame::SetMenu");
2041 return S_OK;
2042 }
2043
2044 HRESULT FrameSite::RemoveMenus(HMENU hmenuShared)
2045 {
2046 WXOLE_TRACE("IOleInPlaceFrame::RemoveMenus");
2047 return S_OK;
2048 }
2049
2050 HRESULT FrameSite::SetStatusText(LPCOLESTR pszStatusText)
2051 {
2052 WXOLE_TRACE("IOleInPlaceFrame::SetStatusText");
2053 //((wxFrame*)wxGetApp().GetTopWindow())->GetStatusBar()->SetStatusText(pszStatusText);
2054 return S_OK;
2055 }
2056
2057 HRESULT FrameSite::EnableModeless(BOOL fEnable)
2058 {
2059 WXOLE_TRACE("IOleInPlaceFrame::EnableModeless");
2060 return S_OK;
2061 }
2062
2063 HRESULT FrameSite::TranslateAccelerator(LPMSG lpmsg, WORD wID)
2064 {
2065 WXOLE_TRACE("IOleInPlaceFrame::TranslateAccelerator");
2066 // TODO: send an event with this id
2067 if (m_window->m_oleInPlaceActiveObject.Ok())
2068 m_window->m_oleInPlaceActiveObject->TranslateAccelerator(lpmsg);
2069
2070 return S_FALSE;
2071 }
2072
2073 //IOleInPlaceSite
2074
2075 HRESULT FrameSite::CanInPlaceActivate()
2076 {
2077 WXOLE_TRACE("IOleInPlaceSite::CanInPlaceActivate");
2078 return S_OK;
2079 }
2080
2081 HRESULT FrameSite::OnInPlaceActivate()
2082 {
2083 WXOLE_TRACE("IOleInPlaceSite::OnInPlaceActivate");
2084 m_bInPlaceActive = true;
2085 return S_OK;
2086 }
2087
2088 HRESULT FrameSite::OnUIActivate()
2089 {
2090 WXOLE_TRACE("IOleInPlaceSite::OnUIActivate");
2091 m_bUIActive = true;
2092 return S_OK;
2093 }
2094
2095 HRESULT FrameSite::GetWindowContext(IOleInPlaceFrame **ppFrame,
2096 IOleInPlaceUIWindow **ppDoc,
2097 LPRECT lprcPosRect,
2098 LPRECT lprcClipRect,
2099 LPOLEINPLACEFRAMEINFO lpFrameInfo)
2100 {
2101 WXOLE_TRACE("IOleInPlaceSite::GetWindowContext");
2102 if (ppFrame == NULL || ppDoc == NULL || lprcPosRect == NULL ||
2103 lprcClipRect == NULL || lpFrameInfo == NULL)
2104 {
2105 if (ppFrame != NULL)
2106 (*ppFrame) = NULL;
2107 if (ppDoc != NULL)
2108 (*ppDoc) = NULL;
2109 return E_INVALIDARG;
2110 }
2111
2112 HRESULT hr = QueryInterface(IID_IOleInPlaceFrame, (void **) ppFrame);
2113 if (! SUCCEEDED(hr))
2114 {
2115 WXOLE_TRACE("IOleInPlaceSite::IOleInPlaceFrame Error !");
2116 return E_UNEXPECTED;
2117 };
2118
2119 hr = QueryInterface(IID_IOleInPlaceUIWindow, (void **) ppDoc);
2120 if (! SUCCEEDED(hr))
2121 {
2122 WXOLE_TRACE("IOleInPlaceSite::IOleInPlaceUIWindow Error !");
2123 (*ppFrame)->Release();
2124 *ppFrame = NULL;
2125 return E_UNEXPECTED;
2126 };
2127
2128 int w, h;
2129 m_window->GetClientSize(&w, &h);
2130 if (lprcPosRect)
2131 {
2132 lprcPosRect->left = lprcPosRect->top = 0;
2133 lprcPosRect->right = w;
2134 lprcPosRect->bottom = h;
2135 };
2136 if (lprcClipRect)
2137 {
2138 lprcClipRect->left = lprcClipRect->top = 0;
2139 lprcClipRect->right = w;
2140 lprcClipRect->bottom = h;
2141 };
2142
2143 memset(lpFrameInfo, 0, sizeof(OLEINPLACEFRAMEINFO));
2144 lpFrameInfo->cb = sizeof(OLEINPLACEFRAMEINFO);
2145 lpFrameInfo->hwndFrame = m_hWndParent;
2146
2147 return S_OK;
2148 }
2149
2150 HRESULT FrameSite::Scroll(SIZE scrollExtent)
2151 {
2152 WXOLE_TRACE("IOleInPlaceSite::Scroll");
2153 return S_OK;
2154 }
2155
2156 HRESULT FrameSite::OnUIDeactivate(BOOL fUndoable)
2157 {
2158 WXOLE_TRACE("IOleInPlaceSite::OnUIDeactivate");
2159 m_bUIActive = false;
2160 return S_OK;
2161 }
2162
2163 HRESULT FrameSite::OnInPlaceDeactivate()
2164 {
2165 WXOLE_TRACE("IOleInPlaceSite::OnInPlaceDeactivate");
2166 m_bInPlaceActive = false;
2167 return S_OK;
2168 }
2169
2170 HRESULT FrameSite::DiscardUndoState()
2171 {
2172 WXOLE_TRACE("IOleInPlaceSite::DiscardUndoState");
2173 return S_OK;
2174 }
2175
2176 HRESULT FrameSite::DeactivateAndUndo()
2177 {
2178 WXOLE_TRACE("IOleInPlaceSite::DeactivateAndUndo");
2179 return S_OK;
2180 }
2181
2182 HRESULT FrameSite::OnPosRectChange(LPCRECT lprcPosRect)
2183 {
2184 WXOLE_TRACE("IOleInPlaceSite::OnPosRectChange");
2185 if (m_window->m_oleInPlaceObject.Ok() && lprcPosRect)
2186 m_window->m_oleInPlaceObject->SetObjectRects(lprcPosRect, lprcPosRect);
2187
2188 return S_OK;
2189 }
2190
2191 //IOleInPlaceSiteEx
2192
2193 HRESULT FrameSite::OnInPlaceActivateEx(BOOL * pfNoRedraw, DWORD dwFlags)
2194 {
2195 WXOLE_TRACE("IOleInPlaceSiteEx::OnInPlaceActivateEx");
2196 OleLockRunning(m_window->m_ActiveX, TRUE, FALSE);
2197 if (pfNoRedraw)
2198 (*pfNoRedraw) = FALSE;
2199 return S_OK;
2200 }
2201
2202 HRESULT FrameSite::OnInPlaceDeactivateEx(BOOL fNoRedraw)
2203 {
2204 WXOLE_TRACE("IOleInPlaceSiteEx::OnInPlaceDeactivateEx");
2205 OleLockRunning(m_window->m_ActiveX, FALSE, FALSE);
2206 return S_OK;
2207 }
2208
2209 HRESULT FrameSite::RequestUIActivate()
2210 {
2211 WXOLE_TRACE("IOleInPlaceSiteEx::RequestUIActivate");
2212 return S_OK;
2213 }
2214
2215
2216 //IOleClientSite
2217
2218 HRESULT FrameSite::SaveObject()
2219 {
2220 WXOLE_TRACE("IOleClientSite::SaveObject");
2221 return S_OK;
2222 }
2223
2224 const char *OleGetMonikerToStr(DWORD dwAssign)
2225 {
2226 switch (dwAssign)
2227 {
2228 case OLEGETMONIKER_ONLYIFTHERE : return "OLEGETMONIKER_ONLYIFTHERE";
2229 case OLEGETMONIKER_FORCEASSIGN : return "OLEGETMONIKER_FORCEASSIGN";
2230 case OLEGETMONIKER_UNASSIGN : return "OLEGETMONIKER_UNASSIGN";
2231 case OLEGETMONIKER_TEMPFORUSER : return "OLEGETMONIKER_TEMPFORUSER";
2232 default : return "Bad Enum";
2233 };
2234 };
2235
2236 const char *OleGetWhicMonikerStr(DWORD dwWhichMoniker)
2237 {
2238 switch(dwWhichMoniker)
2239 {
2240 case OLEWHICHMK_CONTAINER : return "OLEWHICHMK_CONTAINER";
2241 case OLEWHICHMK_OBJREL : return "OLEWHICHMK_OBJREL";
2242 case OLEWHICHMK_OBJFULL : return "OLEWHICHMK_OBJFULL";
2243 default : return "Bad Enum";
2244 };
2245 };
2246
2247 HRESULT FrameSite::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker,
2248 IMoniker ** ppmk)
2249 {
2250 WXOLE_TRACEOUT("IOleClientSite::GetMoniker(" << OleGetMonikerToStr(dwAssign) << ", " << OleGetWhicMonikerStr(dwWhichMoniker) << ")");
2251
2252
2253 if (! ppmk)
2254 return E_FAIL;
2255
2256 /*
2257 HRESULT hr = CreateFileMoniker(L"e:\\dev\\wxie\\bug-zap.swf", ppmk);
2258 if (SUCCEEDED(hr))
2259 return S_OK;
2260 */
2261 *ppmk = NULL;
2262
2263 return E_FAIL ;
2264 }
2265
2266 HRESULT FrameSite::GetContainer(LPOLECONTAINER * ppContainer)
2267 {
2268 WXOLE_TRACE("IOleClientSite::GetContainer");
2269 if (ppContainer == NULL)
2270 return E_INVALIDARG;
2271
2272 HRESULT hr = QueryInterface(IID_IOleContainer, (void**)(ppContainer));
2273 wxASSERT(SUCCEEDED(hr));
2274
2275 return hr;
2276 }
2277
2278 HRESULT FrameSite::ShowObject()
2279 {
2280 WXOLE_TRACE("IOleClientSite::ShowObject");
2281 if (m_window->m_oleObjectHWND)
2282 ::ShowWindow(m_window->m_oleObjectHWND, SW_SHOW);
2283 return S_OK;
2284 }
2285
2286 HRESULT FrameSite::OnShowWindow(BOOL fShow)
2287 {
2288 WXOLE_TRACE("IOleClientSite::OnShowWindow");
2289 return S_OK;
2290 }
2291
2292 HRESULT FrameSite::RequestNewObjectLayout()
2293 {
2294 WXOLE_TRACE("IOleClientSite::RequestNewObjectLayout");
2295 return E_NOTIMPL;
2296 }
2297
2298 // IParseDisplayName
2299
2300 HRESULT FrameSite::ParseDisplayName(IBindCtx *pbc, LPOLESTR pszDisplayName,
2301 ULONG *pchEaten, IMoniker **ppmkOut)
2302 {
2303 WXOLE_TRACE("IParseDisplayName::ParseDisplayName");
2304 return E_NOTIMPL;
2305 }
2306
2307 //IOleContainer
2308
2309 HRESULT FrameSite::EnumObjects(DWORD grfFlags, IEnumUnknown **ppenum)
2310 {
2311 WXOLE_TRACE("IOleContainer::EnumObjects");
2312 return E_NOTIMPL;
2313 }
2314
2315 HRESULT FrameSite::LockContainer(BOOL fLock)
2316 {
2317 WXOLE_TRACE("IOleContainer::LockContainer");
2318 // TODO
2319 return S_OK;
2320 }
2321
2322 //IOleItemContainer
2323
2324 HRESULT FrameSite::GetObject(LPOLESTR pszItem, DWORD dwSpeedNeeded,
2325 IBindCtx * pbc, REFIID riid, void ** ppvObject)
2326 {
2327 WXOLE_TRACE("IOleItemContainer::GetObject");
2328 if (pszItem == NULL)
2329 return E_INVALIDARG;
2330 if (ppvObject == NULL)
2331 return E_INVALIDARG;
2332
2333 *ppvObject = NULL;
2334 return MK_E_NOOBJECT;
2335 }
2336
2337 HRESULT FrameSite::GetObjectStorage(LPOLESTR pszItem, IBindCtx * pbc,
2338 REFIID riid, void ** ppvStorage)
2339 {
2340 WXOLE_TRACE("IOleItemContainer::GetObjectStorage");
2341 if (pszItem == NULL)
2342 return E_INVALIDARG;
2343 if (ppvStorage == NULL)
2344 return E_INVALIDARG;
2345
2346 *ppvStorage = NULL;
2347 return MK_E_NOOBJECT;
2348 }
2349
2350 HRESULT FrameSite::IsRunning(LPOLESTR pszItem)
2351 {
2352 WXOLE_TRACE("IOleItemContainer::IsRunning");
2353 if (pszItem == NULL)
2354 return E_INVALIDARG;
2355
2356 return MK_E_NOOBJECT;
2357 }
2358
2359
2360
2361 //IOleControlSite
2362
2363 HRESULT FrameSite::OnControlInfoChanged()
2364 {
2365 WXOLE_TRACE("IOleControlSite::OnControlInfoChanged");
2366 return S_OK;
2367 }
2368
2369 HRESULT FrameSite::LockInPlaceActive(BOOL fLock)
2370 {
2371 WXOLE_TRACE("IOleControlSite::LockInPlaceActive");
2372 m_bInPlaceLocked = (fLock) ? true : false;
2373 return S_OK;
2374 }
2375
2376 HRESULT FrameSite::GetExtendedControl(IDispatch ** ppDisp)
2377 {
2378 WXOLE_TRACE("IOleControlSite::GetExtendedControl");
2379 return E_NOTIMPL;
2380 }
2381
2382 HRESULT FrameSite::TransformCoords(POINTL * pPtlHimetric, POINTF * pPtfContainer, DWORD dwFlags)
2383 {
2384 WXOLE_TRACE("IOleControlSite::TransformCoords");
2385 HRESULT hr = S_OK;
2386
2387 if (pPtlHimetric == NULL)
2388 return E_INVALIDARG;
2389
2390 if (pPtfContainer == NULL)
2391 return E_INVALIDARG;
2392
2393 return E_NOTIMPL;
2394
2395 }
2396
2397 HRESULT FrameSite::TranslateAccelerator(LPMSG pMsg, DWORD grfModifiers)
2398 {
2399 WXOLE_TRACE("IOleControlSite::TranslateAccelerator");
2400 // TODO: send an event with this id
2401 return E_NOTIMPL;
2402 }
2403
2404 HRESULT FrameSite::OnFocus(BOOL fGotFocus)
2405 {
2406 WXOLE_TRACE("IOleControlSite::OnFocus");
2407 return S_OK;
2408 }
2409
2410 HRESULT FrameSite::ShowPropertyFrame()
2411 {
2412 WXOLE_TRACE("IOleControlSite::ShowPropertyFrame");
2413 return E_NOTIMPL;
2414 }
2415
2416 //IOleCommandTarget
2417
2418 HRESULT FrameSite::QueryStatus(const GUID * pguidCmdGroup, ULONG cCmds,
2419 OLECMD * prgCmds, OLECMDTEXT * pCmdTet)
2420 {
2421 WXOLE_TRACE("IOleCommandTarget::QueryStatus");
2422 if (prgCmds == NULL) return E_INVALIDARG;
2423 bool bCmdGroupFound = false;
2424
2425 for (ULONG nCmd = 0; nCmd < cCmds; nCmd++)
2426 {
2427 // unsupported by default
2428 prgCmds[nCmd].cmdf = 0;
2429
2430 // TODO
2431 }
2432
2433 if (!bCmdGroupFound) { OLECMDERR_E_UNKNOWNGROUP; }
2434 return S_OK;
2435 }
2436
2437 HRESULT FrameSite::Exec(const GUID * pguidCmdGroup, DWORD nCmdID,
2438 DWORD nCmdExecOpt, VARIANTARG * pVaIn,
2439 VARIANTARG * pVaOut)
2440 {
2441 WXOLE_TRACE("IOleCommandTarget::Exec");
2442 bool bCmdGroupFound = false;
2443
2444 if (!bCmdGroupFound) { OLECMDERR_E_UNKNOWNGROUP; }
2445 return OLECMDERR_E_NOTSUPPORTED;
2446 }
2447
2448 //IAdviseSink
2449
2450 void STDMETHODCALLTYPE FrameSite::OnDataChange(FORMATETC * pFormatEtc, STGMEDIUM * pgStgMed)
2451 {
2452 WXOLE_TRACE("IAdviseSink::OnDataChange");
2453 }
2454
2455 void STDMETHODCALLTYPE FrameSite::OnViewChange(DWORD dwAspect, LONG lIndex)
2456 {
2457 WXOLE_TRACE("IAdviseSink::OnViewChange");
2458 // redraw the control
2459 }
2460
2461 void STDMETHODCALLTYPE FrameSite::OnRename(IMoniker * pmk)
2462 {
2463 WXOLE_TRACE("IAdviseSink::OnRename");
2464 }
2465
2466 void STDMETHODCALLTYPE FrameSite::OnSave()
2467 {
2468 WXOLE_TRACE("IAdviseSink::OnSave");
2469 }
2470
2471 void STDMETHODCALLTYPE FrameSite::OnClose()
2472 {
2473 WXOLE_TRACE("IAdviseSink::OnClose");
2474 }
2475
2476 /////////////////////////////////////////////
2477 // IOleDocumentSite
2478 HRESULT STDMETHODCALLTYPE FrameSite::ActivateMe(
2479 /* [in] */ IOleDocumentView __RPC_FAR *pViewToActivate)
2480 {
2481 wxAutoOleInterface<IOleInPlaceSite> inPlaceSite(IID_IOleInPlaceSite, (IDispatch *) this);
2482 if (!inPlaceSite.Ok())
2483 return E_FAIL;
2484
2485 if (pViewToActivate)
2486 {
2487 m_window->m_docView = pViewToActivate;
2488 m_window->m_docView->SetInPlaceSite(inPlaceSite);
2489 }
2490 else
2491 {
2492 wxAutoOleInterface<IOleDocument> oleDoc(IID_IOleDocument, m_window->m_oleObject);
2493 if (! oleDoc.Ok())
2494 return E_FAIL;
2495
2496 HRESULT hr = oleDoc->CreateView(inPlaceSite, NULL, 0, m_window->m_docView.GetRef());
2497 if (hr != S_OK)
2498 return E_FAIL;
2499
2500 m_window->m_docView->SetInPlaceSite(inPlaceSite);
2501 };
2502
2503 m_window->m_docView->UIActivate(TRUE);
2504
2505 return S_OK;
2506 };
2507
2508
2509 static IMalloc *iMalloc = NULL;
2510
2511 IMalloc *wxOleInit::GetIMalloc()
2512 {
2513 assert(iMalloc);
2514 return iMalloc;
2515 };
2516
2517 wxOleInit::wxOleInit()
2518 {
2519 if (OleInitialize(NULL) == S_OK && iMalloc == NULL)
2520 CoGetMalloc(1, &iMalloc);
2521 else if (iMalloc)
2522 iMalloc->AddRef();
2523 };
2524
2525 wxOleInit::~wxOleInit()
2526 {
2527 if (iMalloc)
2528 {
2529 if (iMalloc->Release() == 0)
2530 iMalloc = NULL;
2531 };
2532
2533 OleUninitialize();
2534 }
2535
2536 bool GetSysErrMessage(int err, wxString& s)
2537 {
2538 wxChar buf[256];
2539 if (FormatMessage(
2540 FORMAT_MESSAGE_FROM_SYSTEM, NULL,
2541 err,0, buf, sizeof(buf), NULL) == 0)
2542 return false;
2543
2544 buf[sizeof(buf) - 1] = 0;
2545 s = buf;
2546 return true;
2547 };
2548
2549 wxString OLEHResultToString(HRESULT hr)
2550 {
2551 // try formatmessage
2552 wxString err;
2553 if (GetSysErrMessage(hr, err))
2554 return err;
2555
2556 switch (hr)
2557 {
2558 case S_OK:
2559 return wxEmptyString;
2560
2561 case CONNECT_E_CANNOTCONNECT:
2562 return _T("Cannot connect to event interface (maybe not there ?) - see MSDN");
2563
2564 case DISP_E_MEMBERNOTFOUND:
2565 return _T("The requested member does not exist, or the call to Invoke tried to set the value of a read-only property.");
2566
2567 case DISP_E_BADVARTYPE:
2568 return _T("One of the parameters in rgvarg is not a valid variant type.");
2569
2570 case DISP_E_BADPARAMCOUNT:
2571 return _T("The number of elements provided to DISPPARAMS is different from the number of parameters accepted by the method or property");
2572
2573 case DISP_E_EXCEPTION:
2574 return _T("The application needs to raise an exception. In this case, the structure passed in pExcepInfo should be filled in.");
2575
2576 case DISP_E_TYPEMISMATCH:
2577 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.");
2578
2579 case DISP_E_PARAMNOTOPTIONAL:
2580 return _T("A required parameter was omitted.");
2581
2582 case DISP_E_PARAMNOTFOUND:
2583 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.");
2584
2585 case OLECMDERR_E_UNKNOWNGROUP:
2586 return _T("The pguidCmdGroup parameter is not NULL but does not specify a recognized command group.");
2587
2588 case OLECMDERR_E_NOTSUPPORTED:
2589 return _T("The nCmdID parameter is not a valid command in the group identified by pguidCmdGroup.");
2590
2591 case OLECMDERR_E_DISABLED:
2592 return _T("The command identified by nCmdID is currently disabled and cannot be executed.");
2593
2594 case OLECMDERR_E_NOHELP:
2595 return _T("The caller has asked for help on the command identified by nCmdID, but no help is available.");
2596
2597 case OLECMDERR_E_CANCELED:
2598 return _T("The user canceled the execution of the command.");
2599
2600 case E_INVALIDARG:
2601 return _T("E_INVALIDARG");
2602
2603 case E_OUTOFMEMORY:
2604 return _T("E_OUTOFMEMORY");
2605
2606 case E_NOINTERFACE:
2607 return _T("E_NOINTERFACE");
2608
2609 case E_UNEXPECTED:
2610 return _T("E_UNEXPECTED");
2611
2612 case STG_E_INVALIDFLAG:
2613 return _T("STG_E_INVALIDFLAG");
2614
2615 case E_FAIL:
2616 return _T("E_FAIL");
2617
2618 case E_NOTIMPL:
2619 return _T("E_NOTIMPL");
2620
2621 default:
2622 {
2623 wxString buf;
2624 buf.Printf(_T("Unknown - 0x%X"), hr);
2625 return buf;
2626 }
2627 };
2628 };
2629
2630 // borrowed from src/msw/ole/oleutils.cpp
2631 wxString GetIIDName(REFIID riid)
2632 {
2633 // an association between symbolic name and numeric value of an IID
2634 struct KNOWN_IID
2635 {
2636 const IID *pIid;
2637 const wxChar *szName;
2638 };
2639
2640 // construct the table containing all known interfaces
2641 #define ADD_KNOWN_IID(name) { &IID_I##name, _T(#name) }
2642 #define ADD_KNOWN_GUID(name) { &name, _T(#name) }
2643
2644 static const KNOWN_IID aKnownIids[] =
2645 {
2646 ADD_KNOWN_IID(ServiceProvider),
2647 ADD_KNOWN_IID(AdviseSink),
2648 ADD_KNOWN_IID(AdviseSink2),
2649 ADD_KNOWN_IID(BindCtx),
2650 ADD_KNOWN_IID(ClassFactory),
2651 #if ( !defined( __VISUALC__) || (__VISUALC__!=1010) ) && !defined(__MWERKS__)
2652 ADD_KNOWN_IID(ContinueCallback),
2653 ADD_KNOWN_IID(EnumOleDocumentViews),
2654 ADD_KNOWN_IID(OleCommandTarget),
2655 ADD_KNOWN_IID(OleDocument),
2656 ADD_KNOWN_IID(OleDocumentSite),
2657 ADD_KNOWN_IID(OleDocumentView),
2658 ADD_KNOWN_IID(Print),
2659 #endif
2660 ADD_KNOWN_IID(DataAdviseHolder),
2661 ADD_KNOWN_IID(DataObject),
2662 ADD_KNOWN_IID(Debug),
2663 ADD_KNOWN_IID(DebugStream),
2664 ADD_KNOWN_IID(DfReserved1),
2665 ADD_KNOWN_IID(DfReserved2),
2666 ADD_KNOWN_IID(DfReserved3),
2667 ADD_KNOWN_IID(Dispatch),
2668 ADD_KNOWN_IID(DropSource),
2669 ADD_KNOWN_IID(DropTarget),
2670 ADD_KNOWN_IID(EnumCallback),
2671 ADD_KNOWN_IID(EnumFORMATETC),
2672 ADD_KNOWN_IID(EnumGeneric),
2673 ADD_KNOWN_IID(EnumHolder),
2674 ADD_KNOWN_IID(EnumMoniker),
2675 ADD_KNOWN_IID(EnumOLEVERB),
2676 ADD_KNOWN_IID(EnumSTATDATA),
2677 ADD_KNOWN_IID(EnumSTATSTG),
2678 ADD_KNOWN_IID(EnumString),
2679 ADD_KNOWN_IID(EnumUnknown),
2680 ADD_KNOWN_IID(EnumVARIANT),
2681 ADD_KNOWN_IID(ExternalConnection),
2682 ADD_KNOWN_IID(InternalMoniker),
2683 ADD_KNOWN_IID(LockBytes),
2684 ADD_KNOWN_IID(Malloc),
2685 ADD_KNOWN_IID(Marshal),
2686 ADD_KNOWN_IID(MessageFilter),
2687 ADD_KNOWN_IID(Moniker),
2688 ADD_KNOWN_IID(OleAdviseHolder),
2689 ADD_KNOWN_IID(OleCache),
2690 ADD_KNOWN_IID(OleCache2),
2691 ADD_KNOWN_IID(OleCacheControl),
2692 ADD_KNOWN_IID(OleClientSite),
2693 ADD_KNOWN_IID(OleContainer),
2694 ADD_KNOWN_IID(OleInPlaceActiveObject),
2695 ADD_KNOWN_IID(OleInPlaceFrame),
2696 ADD_KNOWN_IID(OleInPlaceObject),
2697 ADD_KNOWN_IID(OleInPlaceSite),
2698 ADD_KNOWN_IID(OleInPlaceUIWindow),
2699 ADD_KNOWN_IID(OleItemContainer),
2700 ADD_KNOWN_IID(OleLink),
2701 ADD_KNOWN_IID(OleManager),
2702 ADD_KNOWN_IID(OleObject),
2703 ADD_KNOWN_IID(OlePresObj),
2704 ADD_KNOWN_IID(OleWindow),
2705 ADD_KNOWN_IID(PSFactory),
2706 ADD_KNOWN_IID(ParseDisplayName),
2707 ADD_KNOWN_IID(Persist),
2708 ADD_KNOWN_IID(PersistFile),
2709 ADD_KNOWN_IID(PersistStorage),
2710 ADD_KNOWN_IID(PersistStream),
2711 ADD_KNOWN_IID(ProxyManager),
2712 ADD_KNOWN_IID(RootStorage),
2713 ADD_KNOWN_IID(RpcChannel),
2714 ADD_KNOWN_IID(RpcProxy),
2715 ADD_KNOWN_IID(RpcStub),
2716 ADD_KNOWN_IID(RunnableObject),
2717 ADD_KNOWN_IID(RunningObjectTable),
2718 ADD_KNOWN_IID(StdMarshalInfo),
2719 ADD_KNOWN_IID(Storage),
2720 ADD_KNOWN_IID(Stream),
2721 ADD_KNOWN_IID(StubManager),
2722 ADD_KNOWN_IID(Unknown),
2723 ADD_KNOWN_IID(ViewObject),
2724 ADD_KNOWN_IID(ViewObject2),
2725 ADD_KNOWN_GUID(IID_IDispatch),
2726 ADD_KNOWN_GUID(IID_IWebBrowser),
2727 ADD_KNOWN_GUID(IID_IWebBrowserApp),
2728 ADD_KNOWN_GUID(IID_IWebBrowser2),
2729 ADD_KNOWN_GUID(IID_IWebBrowser),
2730 ADD_KNOWN_GUID(DIID_DWebBrowserEvents2),
2731 ADD_KNOWN_GUID(DIID_DWebBrowserEvents),
2732 };
2733
2734 // don't clobber preprocessor name space
2735 #undef ADD_KNOWN_IID
2736 #undef ADD_KNOWN_GUID
2737
2738 // try to find the interface in the table
2739 for ( size_t ui = 0; ui < WXSIZEOF(aKnownIids); ui++ )
2740 {
2741 if ( riid == *aKnownIids[ui].pIid )
2742 {
2743 return aKnownIids[ui].szName;
2744 }
2745 }
2746
2747 // unknown IID, just transform to string
2748 LPOLESTR str = NULL;
2749 StringFromIID(riid, &str);
2750 if (str)
2751 {
2752 wxString s = str;
2753 CoTaskMemFree(str);
2754 return s;
2755 }
2756 else
2757 return _T("StringFromIID() error");
2758 }