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