1 #include "wxActiveX.h"
2 #include <wx/strconv.h>
3 #include <wx/event.h>
4 #include <oleidl.h>
5 #include <winerror.h>
6 #include <idispids.h>
7 #include <exdispid.h>
8 #include <olectl.h>
9 #include <Mshtml.h>
10 #include <sstream>
11 using namespace std;
12
13 // Depending on compilation mode, the wx headers may have undef'd
14 // this, but in this case we need it so the virtual method in
15 // FrameSite will match what is in oleidl.h.
16 #ifndef GetObject
17 #ifdef _UNICODE
18 #define GetObject GetObjectW
19 #else
20 #define GetObject GetObjectA
21 #endif
22 #endif
23
24
25 //////////////////////////////////////////////////////////////////////
26 BEGIN_EVENT_TABLE(wxActiveX, wxWindow)
27 EVT_SIZE(wxActiveX::OnSize)
28 EVT_PAINT(wxActiveX::OnPaint)
29 EVT_MOUSE_EVENTS(wxActiveX::OnMouse)
30 EVT_SET_FOCUS(wxActiveX::OnSetFocus)
31 EVT_KILL_FOCUS(wxActiveX::OnKillFocus)
32
33 END_EVENT_TABLE()
34
35 class wxActiveX;
36
37 class FrameSite :
38 public IOleClientSite,
39 public IOleInPlaceSiteEx,
40 public IOleInPlaceFrame,
41 public IOleItemContainer,
42 public IDispatch,
43 public IOleCommandTarget,
44 public IOleDocumentSite,
45 public IAdviseSink,
46 public IOleControlSite
47 {
48 private:
49 DECLARE_OLE_UNKNOWN(FrameSite);
50
51 public:
52 FrameSite(wxActiveX * win);
53 virtual ~FrameSite();
54
55 //IOleWindow
56 STDMETHODIMP GetWindow(HWND*);
57 STDMETHODIMP ContextSensitiveHelp(BOOL);
58
59 //IOleInPlaceUIWindow
60 STDMETHODIMP GetBorder(LPRECT);
61 STDMETHODIMP RequestBorderSpace(LPCBORDERWIDTHS);
62 STDMETHODIMP SetBorderSpace(LPCBORDERWIDTHS);
63 STDMETHODIMP SetActiveObject(IOleInPlaceActiveObject*, LPCOLESTR);
64
65 //IOleInPlaceFrame
66 STDMETHODIMP InsertMenus(HMENU, LPOLEMENUGROUPWIDTHS);
67 STDMETHODIMP SetMenu(HMENU, HOLEMENU, HWND);
68 STDMETHODIMP RemoveMenus(HMENU);
69 STDMETHODIMP SetStatusText(LPCOLESTR);
70 STDMETHODIMP EnableModeless(BOOL);
71 STDMETHODIMP TranslateAccelerator(LPMSG, WORD);
72
73 //IOleInPlaceSite
74 STDMETHODIMP CanInPlaceActivate();
75 STDMETHODIMP OnInPlaceActivate();
76 STDMETHODIMP OnUIActivate();
77 STDMETHODIMP GetWindowContext(IOleInPlaceFrame**, IOleInPlaceUIWindow**,
78 LPRECT, LPRECT, LPOLEINPLACEFRAMEINFO);
79 STDMETHODIMP Scroll(SIZE);
80 STDMETHODIMP OnUIDeactivate(BOOL);
81 STDMETHODIMP OnInPlaceDeactivate();
82 STDMETHODIMP DiscardUndoState();
83 STDMETHODIMP DeactivateAndUndo();
84 STDMETHODIMP OnPosRectChange(LPCRECT);
85
86 //IOleInPlaceSiteEx
87 STDMETHODIMP OnInPlaceActivateEx(BOOL*, DWORD);
88 STDMETHODIMP OnInPlaceDeactivateEx(BOOL);
89 STDMETHODIMP RequestUIActivate();
90
91 //IOleClientSite
92 STDMETHODIMP SaveObject();
93 STDMETHODIMP GetMoniker(DWORD, DWORD, IMoniker**);
94 STDMETHODIMP GetContainer(LPOLECONTAINER FAR*);
95 STDMETHODIMP ShowObject();
96 STDMETHODIMP OnShowWindow(BOOL);
97 STDMETHODIMP RequestNewObjectLayout();
98
99 //IOleControlSite
100 STDMETHODIMP OnControlInfoChanged();
101 STDMETHODIMP LockInPlaceActive(BOOL);
102 STDMETHODIMP GetExtendedControl(IDispatch**);
103 STDMETHODIMP TransformCoords(POINTL*, POINTF*, DWORD);
104 STDMETHODIMP TranslateAccelerator(LPMSG, DWORD);
105 STDMETHODIMP OnFocus(BOOL);
106 STDMETHODIMP ShowPropertyFrame();
107
108 //IOleCommandTarget
109 STDMETHODIMP QueryStatus(const GUID*, ULONG, OLECMD[], OLECMDTEXT*);
110 STDMETHODIMP Exec(const GUID*, DWORD, DWORD, VARIANTARG*, VARIANTARG*);
111
112 //IParseDisplayName
113 STDMETHODIMP ParseDisplayName(IBindCtx*, LPOLESTR, ULONG*, IMoniker**);
114
115 //IOleContainer
116 STDMETHODIMP EnumObjects(DWORD, IEnumUnknown**);
117 STDMETHODIMP LockContainer(BOOL);
118
119 //IOleItemContainer
120 STDMETHODIMP GetObject(LPOLESTR, DWORD, IBindCtx*, REFIID, void**);
121 STDMETHODIMP GetObjectStorage(LPOLESTR, IBindCtx*, REFIID, void**);
122 STDMETHODIMP IsRunning(LPOLESTR);
123
124 //IDispatch
125 STDMETHODIMP GetIDsOfNames(REFIID, OLECHAR**, unsigned int, LCID, DISPID*);
126 STDMETHODIMP GetTypeInfo(unsigned int, LCID, ITypeInfo**);
127 STDMETHODIMP GetTypeInfoCount(unsigned int*);
128 STDMETHODIMP Invoke(DISPID, REFIID, LCID, WORD, DISPPARAMS*, VARIANT*, EXCEPINFO*, UINT*);
129
130 //IAdviseSink
131 void STDMETHODCALLTYPE OnDataChange(FORMATETC*, STGMEDIUM*);
132 void STDMETHODCALLTYPE OnViewChange(DWORD, LONG);
133 void STDMETHODCALLTYPE OnRename(IMoniker*);
134 void STDMETHODCALLTYPE OnSave();
135 void STDMETHODCALLTYPE OnClose();
136
137 // IOleDocumentSite
138 HRESULT STDMETHODCALLTYPE ActivateMe(IOleDocumentView __RPC_FAR *pViewToActivate);
139
140 protected:
141
142 wxActiveX * m_window;
143
144 HDC m_hDCBuffer;
145 HWND m_hWndParent;
146
147 bool m_bSupportsWindowlessActivation;
148 bool m_bInPlaceLocked;
149 bool m_bInPlaceActive;
150 bool m_bUIActive;
151 bool m_bWindowless;
152
153
154
155 LCID m_nAmbientLocale;
156 COLORREF m_clrAmbientForeColor;
157 COLORREF m_clrAmbientBackColor;
158 bool m_bAmbientShowHatching;
159 bool m_bAmbientShowGrabHandles;
160 bool m_bAmbientAppearance;
161 };
162
163 DEFINE_OLE_TABLE(FrameSite)
164 OLE_INTERFACE(IID_IUnknown, IOleClientSite)
165
166 OLE_IINTERFACE(IOleClientSite)
167
168 OLE_INTERFACE(IID_IOleWindow, IOleInPlaceSite)
169 OLE_IINTERFACE(IOleInPlaceSite)
170 OLE_IINTERFACE(IOleInPlaceSiteEx)
171
172 //OLE_IINTERFACE(IOleWindow)
173 OLE_IINTERFACE(IOleInPlaceUIWindow)
174 OLE_IINTERFACE(IOleInPlaceFrame)
175
176 OLE_IINTERFACE(IParseDisplayName)
177 OLE_IINTERFACE(IOleContainer)
178 OLE_IINTERFACE(IOleItemContainer)
179
180 OLE_IINTERFACE(IDispatch)
181
182 OLE_IINTERFACE(IOleCommandTarget)
183
184 OLE_IINTERFACE(IOleDocumentSite)
185
186 OLE_IINTERFACE(IAdviseSink)
187
188 OLE_IINTERFACE(IOleControlSite)
189 END_OLE_TABLE;
190
191
wxActiveX(wxWindow * parent,REFCLSID clsid,wxWindowID id,const wxPoint & pos,const wxSize & size,long style,const wxString & name)192 wxActiveX::wxActiveX(wxWindow * parent, REFCLSID clsid, wxWindowID id,
193 const wxPoint& pos,
194 const wxSize& size,
195 long style,
196 const wxString& name) :
197 wxWindow(parent, id, pos, size, style, name)
198 {
199 m_bAmbientUserMode = true;
200 m_docAdviseCookie = 0;
201 CreateActiveX(clsid);
202 }
203
wxActiveX(wxWindow * parent,wxString progId,wxWindowID id,const wxPoint & pos,const wxSize & size,long style,const wxString & name)204 wxActiveX::wxActiveX(wxWindow * parent, wxString progId, wxWindowID id,
205 const wxPoint& pos,
206 const wxSize& size,
207 long style,
208 const wxString& name) :
209 wxWindow(parent, id, pos, size, style, name)
210 {
211 m_bAmbientUserMode = true;
212 m_docAdviseCookie = 0;
213 CreateActiveX((LPOLESTR) (const wchar_t *) progId.wc_str(wxConvUTF8));
214 }
215
~wxActiveX()216 wxActiveX::~wxActiveX()
217 {
218 // disconnect connection points
219 wxOleConnectionArray::iterator it = m_connections.begin();
220 while (it != m_connections.end())
221 {
222 wxOleConnectionPoint& cp = it->first;
223 cp->Unadvise(it->second);
224
225 it++;
226 };
227 m_connections.clear();
228
229 if (m_oleInPlaceObject.Ok())
230 {
231 m_oleInPlaceObject->InPlaceDeactivate();
232 m_oleInPlaceObject->UIDeactivate();
233 }
234
235
236 if (m_oleObject.Ok())
237 {
238 if (m_docAdviseCookie != 0)
239 m_oleObject->Unadvise(m_docAdviseCookie);
240
241 m_oleObject->DoVerb(OLEIVERB_HIDE, NULL, m_clientSite, 0, (HWND) GetHWND(), NULL);
242 m_oleObject->Close(OLECLOSE_NOSAVE);
243 m_oleObject->SetClientSite(NULL);
244 }
245 }
246
CreateActiveX(REFCLSID clsid)247 void wxActiveX::CreateActiveX(REFCLSID clsid)
248 {
249 //SetTransparent();
250
251 HRESULT hret;
252
253 ////////////////////////////////////////////////////////
254 // FrameSite
255 FrameSite *frame = new FrameSite(this);
256 // oleClientSite
257 hret = m_clientSite.QueryInterface(IID_IOleClientSite, (IDispatch *) frame);
258 wxASSERT(SUCCEEDED(hret));
259 // adviseSink
260 wxAutoOleInterface<IAdviseSink> adviseSink(IID_IAdviseSink, (IDispatch *) frame);
261 wxASSERT(adviseSink.Ok());
262
263
264 // // Create Object, get IUnknown interface
265 m_ActiveX.CreateInstance(clsid, IID_IUnknown);
266 wxASSERT(m_ActiveX.Ok());
267
268 // Type Info
269 GetTypeInfo();
270
271 // Get IOleObject interface
272 hret = m_oleObject.QueryInterface(IID_IOleObject, m_ActiveX);
273 wxASSERT(SUCCEEDED(hret));
274
275 // get IViewObject Interface
276 hret = m_viewObject.QueryInterface(IID_IViewObject, m_ActiveX);
277 wxASSERT(SUCCEEDED(hret));
278
279 // document advise
280 m_docAdviseCookie = 0;
281 hret = m_oleObject->Advise(adviseSink, &m_docAdviseCookie);
282 WXOLE_WARN(hret, "m_oleObject->Advise(adviseSink, &m_docAdviseCookie),\"Advise\")");
283 m_oleObject->SetHostNames(L"wxActiveXContainer", NULL);
284 OleSetContainedObject(m_oleObject, TRUE);
285 OleRun(m_oleObject);
286
287
288 // Get IOleInPlaceObject interface
289 hret = m_oleInPlaceObject.QueryInterface(IID_IOleInPlaceObject, m_ActiveX);
290 wxASSERT(SUCCEEDED(hret));
291
292 // status
293 DWORD dwMiscStatus;
294 m_oleObject->GetMiscStatus(DVASPECT_CONTENT, &dwMiscStatus);
295 wxASSERT(SUCCEEDED(hret));
296
297 // set client site first ?
298 if (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)
299 m_oleObject->SetClientSite(m_clientSite);
300
301
302 // stream init
303 wxAutoOleInterface<IPersistStreamInit>
304 pPersistStreamInit(IID_IPersistStreamInit, m_oleObject);
305
306 if (pPersistStreamInit.Ok())
307 {
308 hret = pPersistStreamInit->InitNew();
309 WXOLE_WARN(hret, "CreateActiveX::pPersistStreamInit->InitNew()");
310 };
311
312 if (! (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST))
313 m_oleObject->SetClientSite(m_clientSite);
314
315
316 int w, h;
317 GetClientSize(&w, &h);
318 RECT posRect;
319 posRect.left = 0;
320 posRect.top = 0;
321 posRect.right = w;
322 posRect.bottom = h;
323
324 m_oleObjectHWND = 0;
325
326 if (m_oleInPlaceObject.Ok())
327 {
328 hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND);
329 WXOLE_WARN(hret, "m_oleInPlaceObject->GetWindow(&m_oleObjectHWND)");
330 if (SUCCEEDED(hret))
331 ::SetActiveWindow(m_oleObjectHWND);
332 };
333
334
335 if (! (dwMiscStatus & OLEMISC_INVISIBLEATRUNTIME))
336 {
337 if (w > 0 && h > 0 && m_oleInPlaceObject.Ok())
338 m_oleInPlaceObject->SetObjectRects(&posRect, &posRect);
339
340 hret = m_oleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, m_clientSite, 0, (HWND)GetHWND(), &posRect);
341 hret = m_oleObject->DoVerb(OLEIVERB_SHOW, 0, m_clientSite, 0, (HWND)GetHWND(), &posRect);
342 };
343
344 if (! m_oleObjectHWND && m_oleInPlaceObject.Ok())
345 {
346 hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND);
347 WXOLE_WARN(hret, "m_oleInPlaceObject->GetWindow(&m_oleObjectHWND)");
348 };
349
350 if (m_oleObjectHWND)
351 {
352 ::SetActiveWindow(m_oleObjectHWND);
353 ::ShowWindow(m_oleObjectHWND, SW_SHOW);
354
355 // Update by GBR to resize older controls
356 wxSizeEvent szEvent;
357 szEvent.m_size = wxSize(w, h) ;
358 AddPendingEvent(szEvent);
359 };
360 }
361
CreateActiveX(LPOLESTR progId)362 void wxActiveX::CreateActiveX(LPOLESTR progId)
363 {
364 CLSID clsid;
365 if (CLSIDFromProgID(progId, &clsid) != S_OK)
366 return;
367
368 CreateActiveX(clsid);
369 };
370
371 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
372 // Case Insensitive Map of Event names to eventTypes
373 // created dynamically at run time in:
374 // EVT_ACTIVEX(eventName, id, fn)
375 // we map the pointer to them so that:
376 // const wxEventType& RegisterActiveXEvent(wxString eventName);
377 // can return a const reference, which is neccessary for event tables
378 // probably should use a wxWindows hash table here, but I'm lazy ...
379 struct less_wxStringI
380 {
operator ()less_wxStringI381 bool operator()(const wxString& x, const wxString& y) const
382 {
383 return x.CmpNoCase(y) < 0;
384 };
385 };
386
387 typedef map<wxString, wxEventType *, less_wxStringI> ActiveXNamedEventMap;
388 static ActiveXNamedEventMap sg_NamedEventMap;
389
RegisterActiveXEvent(const wxChar * eventName)390 const wxEventType& RegisterActiveXEvent(const wxChar *eventName)
391 {
392 wxString ev = eventName;
393 ActiveXNamedEventMap::iterator it = sg_NamedEventMap.find(ev);
394 if (it == sg_NamedEventMap.end())
395 {
396 wxEventType *et = new wxEventType(wxNewEventType());
397 sg_NamedEventMap[ev] = et;
398
399 return *et;
400 };
401
402 return *(it->second);
403 };
404
405
406 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
407 // Map of Event DISPID's to eventTypes
408 // created dynamically at run time in:
409 // EVT_ACTIVEX(eventName, id, fn)
410 // we map the pointer to them so that:
411 // const wxEventType& RegisterActiveXEvent(wxString eventName);
412 // can return a const reference, which is neccessary for event tables
413
414 typedef map<DISPID, wxEventType *> ActiveXDISPIDEventMap;
415 static ActiveXDISPIDEventMap sg_dispIdEventMap;
416
RegisterActiveXEvent(DISPID event)417 const wxEventType& RegisterActiveXEvent(DISPID event)
418 {
419 ActiveXDISPIDEventMap::iterator it = sg_dispIdEventMap.find(event);
420 if (it == sg_dispIdEventMap.end())
421 {
422 wxEventType *et = new wxEventType(wxNewEventType());
423 sg_dispIdEventMap[event] = et;
424
425 return *et;
426 };
427
428 return *(it->second);
429 };
430
431 // one off class for automatic freeing of activeX eventtypes
432 class ActiveXEventMapFlusher
433 {
434 public:
~ActiveXEventMapFlusher()435 ~ActiveXEventMapFlusher()
436 {
437 // Named events
438 ActiveXNamedEventMap::iterator it = sg_NamedEventMap.end();
439 while (it != sg_NamedEventMap.end())
440 {
441 delete it->second;
442 it++;
443 };
444
445 // DISPID events
446 ActiveXDISPIDEventMap::iterator dit = sg_dispIdEventMap.end();
447 while (dit != sg_dispIdEventMap.end())
448 {
449 delete dit->second;
450 dit++;
451 };
452 };
453 };
454
455 static ActiveXEventMapFlusher s_dummyActiveXEventMapFlusher;
456
457
458 //////////////////////////////////////////////////////
MSWVariantToVariant(VARIANTARG & va,wxVariant & vx)459 bool MSWVariantToVariant(VARIANTARG& va, wxVariant& vx)
460 {
461 switch(va.vt)
462 {
463 case VT_VARIANT | VT_BYREF:
464 return MSWVariantToVariant(*va.pvarVal, vx);
465
466 case VT_I2:
467 case VT_I4:
468 vx = (long) va.iVal;
469 return true;
470
471 case VT_I2 | VT_BYREF:
472 case VT_I4 | VT_BYREF:
473 vx = (long) *va.piVal;
474 return true;
475
476 case VT_BSTR:
477 vx = wxString(va.bstrVal);
478 return true;
479
480 case VT_BSTR | VT_BYREF:
481 vx = wxString(*va.pbstrVal);
482 return true;
483
484 case VT_BOOL:
485 vx = (va.boolVal != FALSE);
486 return true;
487
488 case VT_BOOL | VT_BYREF:
489 vx = (*va.pboolVal != FALSE);
490 return true;
491
492 default:
493 vx.MakeNull();
494 return false;
495 };
496 };
497
VariantToMSWVariant(wxVariant & vx,VARIANTARG & va)498 bool VariantToMSWVariant(wxVariant& vx, VARIANTARG& va)
499 {
500 switch(va.vt)
501 {
502 case VT_VARIANT | VT_BYREF:
503 return VariantToMSWVariant(vx, va);
504
505 case VT_I2:
506 case VT_I4:
507 va.iVal = (long) vx;
508 return true;
509
510 case VT_I2 | VT_BYREF:
511 case VT_I4 | VT_BYREF:
512 *va.piVal = (long) vx;
513 return true;
514
515 case VT_BOOL:
516 va.boolVal = ((bool) vx) ? TRUE : FALSE;
517 return true;
518
519 case VT_BOOL | VT_BYREF:
520 *va.pboolVal = ((bool) vx) ? TRUE : FALSE;
521 return true;
522
523 default:
524 return false;
525 };
526 };
527
528 class wxActiveXEvents : public IDispatch
529 {
530 private:
531 DECLARE_OLE_UNKNOWN(wxActiveXEvents);
532
533
534 wxActiveX *m_activeX;
535
536 public:
wxActiveXEvents(wxActiveX * ax)537 wxActiveXEvents(wxActiveX *ax) : m_activeX(ax) {}
~wxActiveXEvents()538 virtual ~wxActiveXEvents()
539 {
540 }
541
542 //IDispatch
GetIDsOfNames(REFIID r,OLECHAR ** o,unsigned int i,LCID l,DISPID * d)543 STDMETHODIMP GetIDsOfNames(REFIID r, OLECHAR** o, unsigned int i, LCID l, DISPID* d)
544 {
545 return E_NOTIMPL;
546 };
547
GetTypeInfo(unsigned int i,LCID l,ITypeInfo ** t)548 STDMETHODIMP GetTypeInfo(unsigned int i, LCID l, ITypeInfo** t)
549 {
550 return E_NOTIMPL;
551 };
552
GetTypeInfoCount(unsigned int * i)553 STDMETHODIMP GetTypeInfoCount(unsigned int* i)
554 {
555 return E_NOTIMPL;
556 };
557
558
DispatchEvent(int eventIdx,const wxEventType & eventType,DISPPARAMS * pDispParams)559 void DispatchEvent(int eventIdx, const wxEventType& eventType, DISPPARAMS * pDispParams)
560 {
561 wxASSERT(eventIdx >= 0 && eventIdx < int(m_activeX->m_events.size()));
562 wxActiveX::FuncX &func = m_activeX->m_events[eventIdx];
563
564 wxActiveXEvent event;
565 event.SetId(m_activeX->GetId());
566 event.SetEventType(eventType);
567 event.m_params.NullList();
568 event.m_params.SetName(func.name);
569
570 // arguments
571 if (pDispParams)
572 {
573 // cdecl call
574 // sometimes the pDispParams does not match the param info for a activex control
575 int nArg = min(func.params.size(), pDispParams->cArgs);
576 for (int i = nArg - 1; i >= 0; i--)
577 {
578 VARIANTARG& va = pDispParams->rgvarg[i];
579 wxActiveX::ParamX &px = func.params[nArg - i - 1];
580 wxVariant vx;
581
582 vx.SetName(px.name);
583 MSWVariantToVariant(va, vx);
584 event.m_params.Append(vx);
585 };
586 };
587
588 if (func.hasOut)
589 {
590 int nArg = min(func.params.size(), pDispParams->cArgs);
591 m_activeX->GetParent()->ProcessEvent(event);
592 for (int i = 0; i < nArg; i++)
593 {
594 VARIANTARG& va = pDispParams->rgvarg[i];
595 wxActiveX::ParamX &px = func.params[nArg - i - 1];
596
597 if (px.IsOut())
598 {
599 wxVariant& vx = event.m_params[nArg - i - 1];
600
601 VariantToMSWVariant(vx, va);
602 };
603 };
604 }
605 else
606 m_activeX->GetParent()->AddPendingEvent(event);
607
608 };
609
Invoke(DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS * pDispParams,VARIANT * pVarResult,EXCEPINFO * pExcepInfo,unsigned int * puArgErr)610 STDMETHODIMP Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
611 WORD wFlags, DISPPARAMS * pDispParams,
612 VARIANT * pVarResult, EXCEPINFO * pExcepInfo,
613 unsigned int * puArgErr)
614 {
615 if (wFlags & (DISPATCH_PROPERTYGET | DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYPUTREF))
616 return E_NOTIMPL;
617
618 wxASSERT(m_activeX);
619
620 // map dispid to m_eventsIdx
621 wxActiveX::MemberIdList::iterator mid = m_activeX->m_eventsIdx.find((MEMBERID) dispIdMember);
622 if (mid == m_activeX->m_eventsIdx.end())
623 return S_OK;
624
625 int funcIdx = mid->second;
626 wxActiveX::FuncX &func = m_activeX->m_events[funcIdx];
627
628
629 // try to find dispid event
630 ActiveXDISPIDEventMap::iterator dit = sg_dispIdEventMap.find(dispIdMember);
631 if (dit != sg_dispIdEventMap.end())
632 {
633 // Dispatch Event
634 DispatchEvent(funcIdx, *(dit->second), pDispParams);
635 return S_OK;
636 };
637
638 // try named event
639 ActiveXNamedEventMap::iterator nit = sg_NamedEventMap.find(func.name);
640 if (nit == sg_NamedEventMap.end())
641 return S_OK;
642
643 // Dispatch Event
644 DispatchEvent(funcIdx, *(nit->second), pDispParams);
645 return S_OK;
646 }
647 };
648
649
650 DEFINE_OLE_TABLE(wxActiveXEvents)
651 OLE_IINTERFACE(IUnknown)
652 OLE_INTERFACE(IID_IDispatch, IDispatch)
653 END_OLE_TABLE;
654
EventName()655 wxString wxActiveXEvent::EventName()
656 {
657 return m_params.GetName();
658 };
659
ParamCount() const660 int wxActiveXEvent::ParamCount() const
661 {
662 return m_params.GetCount();
663 };
664
ParamType(int idx)665 wxString wxActiveXEvent::ParamType(int idx)
666 {
667 wxASSERT(idx >= 0 && idx < m_params.GetCount());
668
669 return m_params[idx].GetType();
670 };
671
ParamName(int idx)672 wxString wxActiveXEvent::ParamName(int idx)
673 {
674 wxASSERT(idx >= 0 && idx < m_params.GetCount());
675
676 return m_params[idx].GetName();
677 };
678
679 static wxVariant nullVar;
680
operator [](int idx)681 wxVariant& wxActiveXEvent::operator[] (int idx)
682 {
683 wxASSERT(idx >= 0 && idx < ParamCount());
684
685 return m_params[idx];
686 };
687
operator [](wxString name)688 wxVariant& wxActiveXEvent::operator[] (wxString name)
689 {
690 for (int i = 0; i < m_params.GetCount(); i++)
691 {
692 if (name.CmpNoCase(m_params[i].GetName()) == 0)
693 return m_params[i];
694 };
695
696 wxString err = _T("wxActiveXEvent::operator[] invalid name <") + name + _T(">");
697 err += _T("\r\nValid Names = :\r\n");
698 for (int i = 0; i < m_params.GetCount(); i++)
699 {
700 err += m_params[i].GetName();
701 err += _T("\r\n");
702 };
703
704 wxASSERT_MSG(false, err);
705
706 return nullVar;
707 };
708
GetTypeInfo()709 void wxActiveX::GetTypeInfo()
710 {
711 /*
712 We are currently only interested in the IDispatch interface
713 to the control. For dual interfaces (TypeKind = TKIND_INTERFACE)
714 we should drill down through the inheritance
715 (using TYPEATTR->cImplTypes) and GetRefTypeOfImplType(n)
716 and retrieve all the func names etc that way, then generate a C++
717 header file for it.
718
719 But we don't do this and probably never will, so if we have a DUAL
720 interface then we query for the IDispatch
721 via GetRefTypeOfImplType(-1).
722 */
723
724 HRESULT hret = 0;
725
726 // get type info via class info
727 wxAutoOleInterface<IProvideClassInfo> classInfo(IID_IProvideClassInfo, m_ActiveX);
728 if (! classInfo.Ok())
729 return;
730
731 // type info
732 wxAutoOleInterface<ITypeInfo> typeInfo;
733 hret = classInfo->GetClassInfo(typeInfo.GetRef());
734 if (! typeInfo.Ok())
735 return;
736
737 // TYPEATTR
738 TYPEATTR *ta = NULL;
739 hret = typeInfo->GetTypeAttr(&ta);
740 if (! ta)
741 return;
742
743 // this should be a TKIND_COCLASS
744 wxASSERT(ta->typekind == TKIND_COCLASS);
745
746 // iterate contained interfaces
747 for (int i = 0; i < ta->cImplTypes; i++)
748 {
749 HREFTYPE rt = 0;
750
751 // get dispatch type info handle
752 hret = typeInfo->GetRefTypeOfImplType(i, &rt);
753 if (! SUCCEEDED(hret))
754 continue;
755
756 // get dispatch type info interface
757 wxAutoOleInterface<ITypeInfo> ti;
758 hret = typeInfo->GetRefTypeInfo(rt, ti.GetRef());
759 if (! ti.Ok())
760 continue;
761
762 // check if default event sink
763 bool defEventSink = false;
764 int impTypeFlags = 0;
765 typeInfo->GetImplTypeFlags(i, &impTypeFlags);
766
767 if (impTypeFlags & IMPLTYPEFLAG_FDEFAULT)
768 {
769 if (impTypeFlags & IMPLTYPEFLAG_FSOURCE)
770 {
771 WXOLE_TRACEOUT("Default Event Sink");
772 defEventSink = true;
773 }
774 else
775 {
776 WXOLE_TRACEOUT("Default Interface");
777 }
778 };
779
780
781 // process
782 GetTypeInfo(ti, defEventSink);
783 };
784
785
786 // free
787 typeInfo->ReleaseTypeAttr(ta);
788 };
789
GetTypeInfo(ITypeInfo * ti,bool defEventSink)790 void wxActiveX::GetTypeInfo(ITypeInfo *ti, bool defEventSink)
791 {
792 ti->AddRef();
793 wxAutoOleInterface<ITypeInfo> typeInfo(ti);
794
795 // TYPEATTR
796 TYPEATTR *ta = NULL;
797 HRESULT hret = typeInfo->GetTypeAttr(&ta);
798 if (! ta)
799 return;
800
801 if (ta->typekind == TKIND_DISPATCH)
802 {
803 WXOLE_TRACEOUT("GUID = " << GetIIDName(ta->guid).c_str());
804
805 if (defEventSink)
806 {
807 wxActiveXEvents *disp = new wxActiveXEvents(this);
808 ConnectAdvise(ta->guid, disp);
809 };
810
811
812 // Get Function Names
813 for (int i = 0; i < ta->cFuncs; i++)
814 {
815 FUNCDESC FAR *fd = NULL;
816
817 hret = typeInfo->GetFuncDesc(i, &fd);
818 if (! fd)
819 continue;
820
821 BSTR anames[1] = {NULL};
822 unsigned int n = 0;
823
824 hret = typeInfo->GetNames(fd->memid, anames, 1, &n);
825
826 if (anames[0])
827 {
828 wxString name = anames[0];
829
830 WXOLE_TRACEOUT("Name " << i << " = " << name.c_str());
831 SysFreeString(anames[0]);
832
833 if (defEventSink)
834 {
835 FuncX func;
836 func.name = name;
837 func.memid = fd->memid;
838 func.hasOut = false;
839
840 // get Param Names
841 unsigned int maxPNames = fd->cParams + 1;
842 unsigned int nPNames = 0;
843 BSTR *pnames = new BSTR[maxPNames];
844
845 hret = typeInfo->GetNames(fd->memid, pnames, maxPNames, &nPNames);
846 wxASSERT(int(nPNames) >= fd->cParams + 1);
847
848 SysFreeString(pnames[0]);
849 // params
850 for (int p = 0; p < fd->cParams; p++)
851 {
852 ParamX param;
853
854 param.flags = fd->lprgelemdescParam[p].idldesc.wIDLFlags;
855 param.vt = fd->lprgelemdescParam[p].tdesc.vt;
856 param.isPtr = (param.vt == VT_PTR);
857 param.isSafeArray = (param.vt == VT_SAFEARRAY);
858 if (param.isPtr || param.isSafeArray)
859 param.vt = fd->lprgelemdescParam[p].tdesc.lptdesc->vt;
860
861 param.name = pnames[p + 1];
862 SysFreeString(pnames[p + 1]);
863
864 func.hasOut |= (param.IsOut() || param.isPtr);
865 func.params.push_back(param);
866 };
867 delete [] pnames;
868
869 m_events.push_back(func);
870 m_eventsIdx[fd->memid] = m_events.size() - 1;
871 };
872 };
873
874 typeInfo->ReleaseFuncDesc(fd);
875 };
876 }
877
878 typeInfo->ReleaseTypeAttr(ta);
879 };
880
881 ///////////////////////////////////////////////
882 // Type Info exposure
GetEvent(int idx) const883 const wxActiveX::FuncX& wxActiveX::GetEvent(int idx) const
884 {
885 wxASSERT(idx >= 0 && idx < GetEventCount());
886
887 return m_events[idx];
888 };
889
890 ///////////////////////////////////////////////
891
ConnectAdvise(REFIID riid,IUnknown * events)892 HRESULT wxActiveX::ConnectAdvise(REFIID riid, IUnknown *events)
893 {
894 wxOleConnectionPoint cp;
895 DWORD adviseCookie = 0;
896
897 wxAutoOleInterface<IConnectionPointContainer> cpContainer(IID_IConnectionPointContainer, m_ActiveX);
898 if (! cpContainer.Ok())
899 return E_FAIL;
900
901 HRESULT hret = cpContainer->FindConnectionPoint(riid, cp.GetRef());
902 if (! SUCCEEDED(hret))
903 return hret;
904
905 hret = cp->Advise(events, &adviseCookie);
906
907 if (SUCCEEDED(hret))
908 m_connections.push_back(wxOleConnection(cp, adviseCookie));
909
910 return hret;
911 };
912
AmbientPropertyChanged(DISPID dispid)913 HRESULT wxActiveX::AmbientPropertyChanged(DISPID dispid)
914 {
915 wxAutoOleInterface<IOleControl> oleControl(IID_IOleControl, m_oleObject);
916
917 if (oleControl.Ok())
918 return oleControl->OnAmbientPropertyChange(dispid);
919 else
920 return S_FALSE;
921 };
922
923 #define HIMETRIC_PER_INCH 2540
924 #define MAP_PIX_TO_LOGHIM(x,ppli) MulDiv(HIMETRIC_PER_INCH, (x), (ppli))
925
PixelsToHimetric(SIZEL & sz)926 static void PixelsToHimetric(SIZEL &sz)
927 {
928 static int logX = 0;
929 static int logY = 0;
930
931 if (logY == 0)
932 {
933 // initaliase
934 HDC dc = GetDC(NULL);
935 logX = GetDeviceCaps(dc, LOGPIXELSX);
936 logY = GetDeviceCaps(dc, LOGPIXELSY);
937 ReleaseDC(NULL, dc);
938 };
939
940 #define HIMETRIC_INCH 2540
941 #define CONVERT(x, logpixels) MulDiv(HIMETRIC_INCH, (x), (logpixels))
942
943 sz.cx = CONVERT(sz.cx, logX);
944 sz.cy = CONVERT(sz.cy, logY);
945
946 #undef CONVERT
947 #undef HIMETRIC_INCH
948 }
949
950
OnSize(wxSizeEvent & event)951 void wxActiveX::OnSize(wxSizeEvent& event)
952 {
953 int w, h;
954 GetClientSize(&w, &h);
955
956 RECT posRect;
957 posRect.left = 0;
958 posRect.top = 0;
959 posRect.right = w;
960 posRect.bottom = h;
961
962 if (w <= 0 && h <= 0)
963 return;
964
965 // extents are in HIMETRIC units
966 if (m_oleObject.Ok())
967 {
968 SIZEL sz = {w, h};
969 PixelsToHimetric(sz);
970
971 SIZEL sz2;
972
973 m_oleObject->GetExtent(DVASPECT_CONTENT, &sz2);
974 if (sz2.cx != sz.cx || sz.cy != sz2.cy)
975 m_oleObject->SetExtent(DVASPECT_CONTENT, &sz);
976 };
977
978 if (m_oleInPlaceObject.Ok())
979 m_oleInPlaceObject->SetObjectRects(&posRect, &posRect);
980 }
981
OnPaint(wxPaintEvent & event)982 void wxActiveX::OnPaint(wxPaintEvent& event)
983 {
984 //wxLogTrace(wxT("repainting activex win"));
985 wxPaintDC dc(this);
986 //dc.BeginDrawing();
987 int w, h;
988 GetSize(&w, &h);
989 RECT posRect;
990 posRect.left = 0;
991 posRect.top = 0;
992 posRect.right = w;
993 posRect.bottom = h;
994
995 // Draw only when control is windowless or deactivated
996 if (m_viewObject)
997 {
998 ::RedrawWindow(m_oleObjectHWND, NULL, NULL, RDW_INTERNALPAINT);
999 {
1000 RECTL *prcBounds = (RECTL *) &posRect;
1001 m_viewObject->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL,
1002 (HDC)dc.GetHDC(), prcBounds, NULL, NULL, 0);
1003 }
1004 }
1005 else
1006 {
1007 dc.SetBrush(*wxRED_BRUSH);
1008 dc.DrawRectangle(0, 0, w, h);
1009 dc.SetBrush(wxNullBrush);
1010 }
1011 //dc.EndDrawing();
1012 }
1013
OnMouse(wxMouseEvent & event)1014 void wxActiveX::OnMouse(wxMouseEvent& event)
1015 {
1016 if (m_oleObjectHWND == NULL)
1017 {
1018 //wxLogTrace(wxT("no oleInPlaceObject"));
1019 event.Skip();
1020 return;
1021 }
1022
1023 //wxLogTrace(wxT("mouse event"));
1024 UINT msg = 0;
1025 WPARAM wParam = 0;
1026 LPARAM lParam = 0;
1027 LRESULT lResult = 0;
1028
1029 if (event.m_metaDown)
1030 wParam |= MK_CONTROL;
1031 if (event.m_shiftDown)
1032 wParam |= MK_SHIFT;
1033 if (event.m_leftDown)
1034 wParam |= MK_LBUTTON;
1035 if (event.m_middleDown)
1036 wParam |= MK_MBUTTON;
1037 if (event.m_rightDown)
1038 wParam |= MK_RBUTTON;
1039 lParam = event.m_x << 16;
1040 lParam |= event.m_y;
1041
1042 if (event.LeftDown())
1043 msg = WM_LBUTTONDOWN;
1044 else if (event.LeftDClick())
1045 msg = WM_LBUTTONDBLCLK;
1046 else if (event.LeftUp())
1047 msg = WM_LBUTTONUP;
1048 else if (event.MiddleDown())
1049 msg = WM_MBUTTONDOWN;
1050 else if (event.MiddleDClick())
1051 msg = WM_MBUTTONDBLCLK;
1052 else if (event.MiddleUp())
1053 msg = WM_MBUTTONUP;
1054 else if (event.RightDown())
1055 msg = WM_RBUTTONDOWN;
1056 else if (event.RightDClick())
1057 msg = WM_RBUTTONDBLCLK;
1058 else if (event.RightUp())
1059 msg = WM_RBUTTONUP;
1060 else if (event.Moving() || event.Dragging())
1061 msg = WM_MOUSEMOVE;
1062
1063 wxString log;
1064 if (msg == 0)
1065 {
1066 //wxLogTrace(wxT("no message"));
1067 event.Skip(); return;
1068 };
1069
1070 if (!::SendMessage(m_oleObjectHWND, msg, wParam, lParam))
1071 {
1072 //wxLogTrace(wxT("msg not delivered"));
1073 event.Skip();
1074 return;
1075 };
1076
1077 //wxLogTrace(wxT("msg sent"));
1078 }
1079
MSWWindowProc(WXUINT nMsg,WXWPARAM wParam,WXLPARAM lParam)1080 long wxActiveX::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
1081 {
1082 if (m_oleObjectHWND == NULL)
1083 return wxWindow::MSWWindowProc(nMsg, wParam, lParam);
1084
1085 switch(nMsg)
1086 {
1087 case WM_SYSKEYDOWN:
1088 case WM_SYSKEYUP:
1089 case WM_CHAR:
1090 case WM_DEADCHAR:
1091 case WM_KEYDOWN:
1092 case WM_KEYUP:
1093 case WM_SYSCHAR:
1094 case WM_SYSDEADCHAR:
1095 PostMessage(m_oleObjectHWND, nMsg, wParam, lParam);
1096
1097 default:
1098 return wxWindow::MSWWindowProc(nMsg, wParam, lParam);
1099 };
1100 };
1101
OnSetFocus(wxFocusEvent & event)1102 void wxActiveX::OnSetFocus(wxFocusEvent& event)
1103 {
1104 if (m_oleInPlaceActiveObject.Ok())
1105 m_oleInPlaceActiveObject->OnFrameWindowActivate(TRUE);
1106 }
1107
OnKillFocus(wxFocusEvent & event)1108 void wxActiveX::OnKillFocus(wxFocusEvent& event)
1109 {
1110 if (m_oleInPlaceActiveObject.Ok())
1111 m_oleInPlaceActiveObject->OnFrameWindowActivate(FALSE);
1112 }
1113
1114
FrameSite(wxActiveX * win)1115 FrameSite::FrameSite(wxActiveX * win)
1116 {
1117 m_window = win;
1118 m_bSupportsWindowlessActivation = true;
1119 m_bInPlaceLocked = false;
1120 m_bUIActive = false;
1121 m_bInPlaceActive = false;
1122 m_bWindowless = false;
1123
1124 m_nAmbientLocale = 0;
1125 m_clrAmbientForeColor = ::GetSysColor(COLOR_WINDOWTEXT);
1126 m_clrAmbientBackColor = ::GetSysColor(COLOR_WINDOW);
1127 m_bAmbientShowHatching = true;
1128 m_bAmbientShowGrabHandles = true;
1129 m_bAmbientAppearance = true;
1130
1131 m_hDCBuffer = NULL;
1132 m_hWndParent = (HWND)m_window->GetHWND();
1133 }
1134
~FrameSite()1135 FrameSite::~FrameSite()
1136 {
1137 }
1138
1139
1140 //IDispatch
1141
GetIDsOfNames(REFIID riid,OLECHAR ** rgszNames,unsigned int cNames,LCID lcid,DISPID * rgDispId)1142 HRESULT FrameSite::GetIDsOfNames(REFIID riid, OLECHAR ** rgszNames, unsigned int cNames,
1143 LCID lcid, DISPID * rgDispId)
1144 {
1145 WXOLE_TRACE("IDispatch::GetIDsOfNames");
1146 return E_NOTIMPL;
1147 }
1148
GetTypeInfo(unsigned int iTInfo,LCID lcid,ITypeInfo ** ppTInfo)1149 HRESULT FrameSite::GetTypeInfo(unsigned int iTInfo, LCID lcid, ITypeInfo ** ppTInfo)
1150 {
1151 WXOLE_TRACE("IDispatch::GetTypeInfo");
1152 return E_NOTIMPL;
1153 }
1154
GetTypeInfoCount(unsigned int * pcTInfo)1155 HRESULT FrameSite::GetTypeInfoCount(unsigned int * pcTInfo)
1156 {
1157 WXOLE_TRACE("IDispatch::GetTypeInfoCount");
1158 return E_NOTIMPL;
1159 }
1160
Invoke(DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS * pDispParams,VARIANT * pVarResult,EXCEPINFO * pExcepInfo,unsigned int * puArgErr)1161 HRESULT FrameSite::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
1162 WORD wFlags, DISPPARAMS * pDispParams,
1163 VARIANT * pVarResult, EXCEPINFO * pExcepInfo,
1164 unsigned int * puArgErr)
1165 {
1166 WXOLE_TRACE("IDispatch::Invoke");
1167
1168 if (!(wFlags & DISPATCH_PROPERTYGET))
1169 return S_OK;
1170
1171 HRESULT hr;
1172
1173 if (pVarResult == NULL)
1174 return E_INVALIDARG;
1175
1176 //The most common case is boolean, use as an initial type
1177 V_VT(pVarResult) = VT_BOOL;
1178
1179 switch (dispIdMember)
1180 {
1181 case DISPID_AMBIENT_MESSAGEREFLECT:
1182 WXOLE_TRACE("Invoke::DISPID_AMBIENT_MESSAGEREFLECT");
1183 V_BOOL(pVarResult)= FALSE;
1184 return S_OK;
1185
1186 case DISPID_AMBIENT_DISPLAYASDEFAULT:
1187 WXOLE_TRACE("Invoke::DISPID_AMBIENT_DISPLAYASDEFAULT");
1188 V_BOOL(pVarResult)= TRUE;
1189 return S_OK;
1190
1191 case DISPID_AMBIENT_OFFLINEIFNOTCONNECTED:
1192 WXOLE_TRACE("Invoke::DISPID_AMBIENT_OFFLINEIFNOTCONNECTED");
1193 V_BOOL(pVarResult) = TRUE;
1194 return S_OK;
1195
1196
1197 case DISPID_AMBIENT_SILENT:
1198 WXOLE_TRACE("Invoke::DISPID_AMBIENT_SILENT");
1199 V_BOOL(pVarResult)= TRUE;
1200 return S_OK;
1201
1202 case DISPID_AMBIENT_APPEARANCE:
1203 pVarResult->vt = VT_BOOL;
1204 pVarResult->boolVal = m_bAmbientAppearance;
1205 break;
1206
1207 case DISPID_AMBIENT_FORECOLOR:
1208 pVarResult->vt = VT_I4;
1209 pVarResult->lVal = (long) m_clrAmbientForeColor;
1210 break;
1211
1212 case DISPID_AMBIENT_BACKCOLOR:
1213 pVarResult->vt = VT_I4;
1214 pVarResult->lVal = (long) m_clrAmbientBackColor;
1215 break;
1216
1217 case DISPID_AMBIENT_LOCALEID:
1218 pVarResult->vt = VT_I4;
1219 pVarResult->lVal = (long) m_nAmbientLocale;
1220 break;
1221
1222 case DISPID_AMBIENT_USERMODE:
1223 pVarResult->vt = VT_BOOL;
1224 pVarResult->boolVal = m_window->m_bAmbientUserMode;
1225 break;
1226
1227 case DISPID_AMBIENT_SHOWGRABHANDLES:
1228 pVarResult->vt = VT_BOOL;
1229 pVarResult->boolVal = m_bAmbientShowGrabHandles;
1230 break;
1231
1232 case DISPID_AMBIENT_SHOWHATCHING:
1233 pVarResult->vt = VT_BOOL;
1234 pVarResult->boolVal = m_bAmbientShowHatching;
1235 break;
1236
1237 default:
1238 return DISP_E_MEMBERNOTFOUND;
1239 }
1240
1241 return S_OK;
1242 }
1243
1244 //IOleWindow
1245
GetWindow(HWND * phwnd)1246 HRESULT FrameSite::GetWindow(HWND * phwnd)
1247 {
1248 WXOLE_TRACE("IOleWindow::GetWindow");
1249 if (phwnd == NULL)
1250 return E_INVALIDARG;
1251 (*phwnd) = m_hWndParent;
1252 return S_OK;
1253 }
1254
ContextSensitiveHelp(BOOL fEnterMode)1255 HRESULT FrameSite::ContextSensitiveHelp(BOOL fEnterMode)
1256 {
1257 WXOLE_TRACE("IOleWindow::ContextSensitiveHelp");
1258 return S_OK;
1259 }
1260
1261 //IOleInPlaceUIWindow
1262
GetBorder(LPRECT lprectBorder)1263 HRESULT FrameSite::GetBorder(LPRECT lprectBorder)
1264 {
1265 WXOLE_TRACE("IOleInPlaceUIWindow::GetBorder");
1266 if (lprectBorder == NULL)
1267 return E_INVALIDARG;
1268 return INPLACE_E_NOTOOLSPACE;
1269 }
1270
RequestBorderSpace(LPCBORDERWIDTHS pborderwidths)1271 HRESULT FrameSite::RequestBorderSpace(LPCBORDERWIDTHS pborderwidths)
1272 {
1273 WXOLE_TRACE("IOleInPlaceUIWindow::RequestBorderSpace");
1274 if (pborderwidths == NULL)
1275 return E_INVALIDARG;
1276 return INPLACE_E_NOTOOLSPACE;
1277 }
1278
SetBorderSpace(LPCBORDERWIDTHS pborderwidths)1279 HRESULT FrameSite::SetBorderSpace(LPCBORDERWIDTHS pborderwidths)
1280 {
1281 WXOLE_TRACE("IOleInPlaceUIWindow::SetBorderSpace");
1282 return S_OK;
1283 }
1284
SetActiveObject(IOleInPlaceActiveObject * pActiveObject,LPCOLESTR pszObjName)1285 HRESULT FrameSite::SetActiveObject(IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName)
1286 {
1287 WXOLE_TRACE("IOleInPlaceUIWindow::SetActiveObject");
1288
1289 if (pActiveObject)
1290 pActiveObject->AddRef();
1291
1292 m_window->m_oleInPlaceActiveObject = pActiveObject;
1293 return S_OK;
1294 }
1295
1296 //IOleInPlaceFrame
1297
InsertMenus(HMENU hmenuShared,LPOLEMENUGROUPWIDTHS lpMenuWidths)1298 HRESULT FrameSite::InsertMenus(HMENU hmenuShared, LPOLEMENUGROUPWIDTHS lpMenuWidths)
1299 {
1300 WXOLE_TRACE("IOleInPlaceFrame::InsertMenus");
1301 return S_OK;
1302 }
1303
SetMenu(HMENU hmenuShared,HOLEMENU holemenu,HWND hwndActiveObject)1304 HRESULT FrameSite::SetMenu(HMENU hmenuShared, HOLEMENU holemenu, HWND hwndActiveObject)
1305 {
1306 WXOLE_TRACE("IOleInPlaceFrame::SetMenu");
1307 return S_OK;
1308 }
1309
RemoveMenus(HMENU hmenuShared)1310 HRESULT FrameSite::RemoveMenus(HMENU hmenuShared)
1311 {
1312 WXOLE_TRACE("IOleInPlaceFrame::RemoveMenus");
1313 return S_OK;
1314 }
1315
SetStatusText(LPCOLESTR pszStatusText)1316 HRESULT FrameSite::SetStatusText(LPCOLESTR pszStatusText)
1317 {
1318 WXOLE_TRACE("IOleInPlaceFrame::SetStatusText");
1319 //((wxFrame*)wxGetApp().GetTopWindow())->GetStatusBar()->SetStatusText(pszStatusText);
1320 return S_OK;
1321 }
1322
EnableModeless(BOOL fEnable)1323 HRESULT FrameSite::EnableModeless(BOOL fEnable)
1324 {
1325 WXOLE_TRACE("IOleInPlaceFrame::EnableModeless");
1326 return S_OK;
1327 }
1328
TranslateAccelerator(LPMSG lpmsg,WORD wID)1329 HRESULT FrameSite::TranslateAccelerator(LPMSG lpmsg, WORD wID)
1330 {
1331 WXOLE_TRACE("IOleInPlaceFrame::TranslateAccelerator");
1332 // TODO: send an event with this id
1333 if (m_window->m_oleInPlaceActiveObject.Ok())
1334 m_window->m_oleInPlaceActiveObject->TranslateAccelerator(lpmsg);
1335
1336 return S_FALSE;
1337 }
1338
1339 //IOleInPlaceSite
1340
CanInPlaceActivate()1341 HRESULT FrameSite::CanInPlaceActivate()
1342 {
1343 WXOLE_TRACE("IOleInPlaceSite::CanInPlaceActivate");
1344 return S_OK;
1345 }
1346
OnInPlaceActivate()1347 HRESULT FrameSite::OnInPlaceActivate()
1348 {
1349 WXOLE_TRACE("IOleInPlaceSite::OnInPlaceActivate");
1350 m_bInPlaceActive = true;
1351 return S_OK;
1352 }
1353
OnUIActivate()1354 HRESULT FrameSite::OnUIActivate()
1355 {
1356 WXOLE_TRACE("IOleInPlaceSite::OnUIActivate");
1357 m_bUIActive = true;
1358 return S_OK;
1359 }
1360
GetWindowContext(IOleInPlaceFrame ** ppFrame,IOleInPlaceUIWindow ** ppDoc,LPRECT lprcPosRect,LPRECT lprcClipRect,LPOLEINPLACEFRAMEINFO lpFrameInfo)1361 HRESULT FrameSite::GetWindowContext(IOleInPlaceFrame **ppFrame,
1362 IOleInPlaceUIWindow **ppDoc,
1363 LPRECT lprcPosRect,
1364 LPRECT lprcClipRect,
1365 LPOLEINPLACEFRAMEINFO lpFrameInfo)
1366 {
1367 WXOLE_TRACE("IOleInPlaceSite::GetWindowContext");
1368 if (ppFrame == NULL || ppDoc == NULL || lprcPosRect == NULL ||
1369 lprcClipRect == NULL || lpFrameInfo == NULL)
1370 {
1371 if (ppFrame != NULL)
1372 (*ppFrame) = NULL;
1373 if (ppDoc != NULL)
1374 (*ppDoc) = NULL;
1375 return E_INVALIDARG;
1376 }
1377
1378 HRESULT hr = QueryInterface(IID_IOleInPlaceFrame, (void **) ppFrame);
1379 if (! SUCCEEDED(hr))
1380 {
1381 WXOLE_TRACE("IOleInPlaceSite::IOleInPlaceFrame Error !");
1382 return E_UNEXPECTED;
1383 };
1384
1385 hr = QueryInterface(IID_IOleInPlaceUIWindow, (void **) ppDoc);
1386 if (! SUCCEEDED(hr))
1387 {
1388 WXOLE_TRACE("IOleInPlaceSite::IOleInPlaceUIWindow Error !");
1389 (*ppFrame)->Release();
1390 *ppFrame = NULL;
1391 return E_UNEXPECTED;
1392 };
1393
1394 int w, h;
1395 m_window->GetClientSize(&w, &h);
1396 if (lprcPosRect)
1397 {
1398 lprcPosRect->left = lprcPosRect->top = 0;
1399 lprcPosRect->right = w;
1400 lprcPosRect->bottom = h;
1401 };
1402 if (lprcClipRect)
1403 {
1404 lprcClipRect->left = lprcClipRect->top = 0;
1405 lprcClipRect->right = w;
1406 lprcClipRect->bottom = h;
1407 };
1408
1409 memset(lpFrameInfo, 0, sizeof(OLEINPLACEFRAMEINFO));
1410 lpFrameInfo->cb = sizeof(OLEINPLACEFRAMEINFO);
1411 lpFrameInfo->hwndFrame = m_hWndParent;
1412
1413 return S_OK;
1414 }
1415
Scroll(SIZE scrollExtent)1416 HRESULT FrameSite::Scroll(SIZE scrollExtent)
1417 {
1418 WXOLE_TRACE("IOleInPlaceSite::Scroll");
1419 return S_OK;
1420 }
1421
OnUIDeactivate(BOOL fUndoable)1422 HRESULT FrameSite::OnUIDeactivate(BOOL fUndoable)
1423 {
1424 WXOLE_TRACE("IOleInPlaceSite::OnUIDeactivate");
1425 m_bUIActive = false;
1426 return S_OK;
1427 }
1428
OnInPlaceDeactivate()1429 HRESULT FrameSite::OnInPlaceDeactivate()
1430 {
1431 WXOLE_TRACE("IOleInPlaceSite::OnInPlaceDeactivate");
1432 m_bInPlaceActive = false;
1433 return S_OK;
1434 }
1435
DiscardUndoState()1436 HRESULT FrameSite::DiscardUndoState()
1437 {
1438 WXOLE_TRACE("IOleInPlaceSite::DiscardUndoState");
1439 return S_OK;
1440 }
1441
DeactivateAndUndo()1442 HRESULT FrameSite::DeactivateAndUndo()
1443 {
1444 WXOLE_TRACE("IOleInPlaceSite::DeactivateAndUndo");
1445 return S_OK;
1446 }
1447
OnPosRectChange(LPCRECT lprcPosRect)1448 HRESULT FrameSite::OnPosRectChange(LPCRECT lprcPosRect)
1449 {
1450 WXOLE_TRACE("IOleInPlaceSite::OnPosRectChange");
1451 if (m_window->m_oleInPlaceObject.Ok() && lprcPosRect)
1452 m_window->m_oleInPlaceObject->SetObjectRects(lprcPosRect, lprcPosRect);
1453
1454 return S_OK;
1455 }
1456
1457 //IOleInPlaceSiteEx
1458
OnInPlaceActivateEx(BOOL * pfNoRedraw,DWORD dwFlags)1459 HRESULT FrameSite::OnInPlaceActivateEx(BOOL * pfNoRedraw, DWORD dwFlags)
1460 {
1461 WXOLE_TRACE("IOleInPlaceSiteEx::OnInPlaceActivateEx");
1462 OleLockRunning(m_window->m_ActiveX, TRUE, FALSE);
1463 if (pfNoRedraw)
1464 (*pfNoRedraw) = FALSE;
1465 return S_OK;
1466 }
1467
OnInPlaceDeactivateEx(BOOL fNoRedraw)1468 HRESULT FrameSite::OnInPlaceDeactivateEx(BOOL fNoRedraw)
1469 {
1470 WXOLE_TRACE("IOleInPlaceSiteEx::OnInPlaceDeactivateEx");
1471 OleLockRunning(m_window->m_ActiveX, FALSE, FALSE);
1472 return S_OK;
1473 }
1474
RequestUIActivate()1475 HRESULT FrameSite::RequestUIActivate()
1476 {
1477 WXOLE_TRACE("IOleInPlaceSiteEx::RequestUIActivate");
1478 return S_OK;
1479 }
1480
1481
1482 //IOleClientSite
1483
SaveObject()1484 HRESULT FrameSite::SaveObject()
1485 {
1486 WXOLE_TRACE("IOleClientSite::SaveObject");
1487 return S_OK;
1488 }
1489
GetMoniker(DWORD dwAssign,DWORD dwWhichMoniker,IMoniker ** ppmk)1490 HRESULT FrameSite::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker,
1491 IMoniker ** ppmk)
1492 {
1493 WXOLE_TRACE("IOleClientSite::GetMoniker");
1494 return E_NOTIMPL;
1495 }
1496
GetContainer(LPOLECONTAINER * ppContainer)1497 HRESULT FrameSite::GetContainer(LPOLECONTAINER * ppContainer)
1498 {
1499 WXOLE_TRACE("IOleClientSite::GetContainer");
1500 if (ppContainer == NULL)
1501 return E_INVALIDARG;
1502
1503 HRESULT hr = QueryInterface(IID_IOleContainer, (void**)(ppContainer));
1504 wxASSERT(SUCCEEDED(hr));
1505
1506 return hr;
1507 }
1508
ShowObject()1509 HRESULT FrameSite::ShowObject()
1510 {
1511 WXOLE_TRACE("IOleClientSite::ShowObject");
1512 if (m_window->m_oleObjectHWND)
1513 ::ShowWindow(m_window->m_oleObjectHWND, SW_SHOW);
1514 return S_OK;
1515 }
1516
OnShowWindow(BOOL fShow)1517 HRESULT FrameSite::OnShowWindow(BOOL fShow)
1518 {
1519 WXOLE_TRACE("IOleClientSite::OnShowWindow");
1520 return S_OK;
1521 }
1522
RequestNewObjectLayout()1523 HRESULT FrameSite::RequestNewObjectLayout()
1524 {
1525 WXOLE_TRACE("IOleClientSite::RequestNewObjectLayout");
1526 return E_NOTIMPL;
1527 }
1528
1529 // IParseDisplayName
1530
ParseDisplayName(IBindCtx * pbc,LPOLESTR pszDisplayName,ULONG * pchEaten,IMoniker ** ppmkOut)1531 HRESULT FrameSite::ParseDisplayName(IBindCtx *pbc, LPOLESTR pszDisplayName,
1532 ULONG *pchEaten, IMoniker **ppmkOut)
1533 {
1534 WXOLE_TRACE("IParseDisplayName::ParseDisplayName");
1535 return E_NOTIMPL;
1536 }
1537
1538 //IOleContainer
1539
EnumObjects(DWORD grfFlags,IEnumUnknown ** ppenum)1540 HRESULT FrameSite::EnumObjects(DWORD grfFlags, IEnumUnknown **ppenum)
1541 {
1542 WXOLE_TRACE("IOleContainer::EnumObjects");
1543 return E_NOTIMPL;
1544 }
1545
LockContainer(BOOL fLock)1546 HRESULT FrameSite::LockContainer(BOOL fLock)
1547 {
1548 WXOLE_TRACE("IOleContainer::LockContainer");
1549 // TODO
1550 return S_OK;
1551 }
1552
1553 //IOleItemContainer
1554
GetObject(LPOLESTR pszItem,DWORD dwSpeedNeeded,IBindCtx * pbc,REFIID riid,void ** ppvObject)1555 HRESULT FrameSite::GetObject(LPOLESTR pszItem, DWORD dwSpeedNeeded,
1556 IBindCtx * pbc, REFIID riid, void ** ppvObject)
1557 {
1558 WXOLE_TRACE("IOleItemContainer::GetObject");
1559 if (pszItem == NULL)
1560 return E_INVALIDARG;
1561 if (ppvObject == NULL)
1562 return E_INVALIDARG;
1563
1564 *ppvObject = NULL;
1565 return MK_E_NOOBJECT;
1566 }
1567
GetObjectStorage(LPOLESTR pszItem,IBindCtx * pbc,REFIID riid,void ** ppvStorage)1568 HRESULT FrameSite::GetObjectStorage(LPOLESTR pszItem, IBindCtx * pbc,
1569 REFIID riid, void ** ppvStorage)
1570 {
1571 WXOLE_TRACE("IOleItemContainer::GetObjectStorage");
1572 if (pszItem == NULL)
1573 return E_INVALIDARG;
1574 if (ppvStorage == NULL)
1575 return E_INVALIDARG;
1576
1577 *ppvStorage = NULL;
1578 return MK_E_NOOBJECT;
1579 }
1580
IsRunning(LPOLESTR pszItem)1581 HRESULT FrameSite::IsRunning(LPOLESTR pszItem)
1582 {
1583 WXOLE_TRACE("IOleItemContainer::IsRunning");
1584 if (pszItem == NULL)
1585 return E_INVALIDARG;
1586
1587 return MK_E_NOOBJECT;
1588 }
1589
1590
1591
1592 //IOleControlSite
1593
OnControlInfoChanged()1594 HRESULT FrameSite::OnControlInfoChanged()
1595 {
1596 WXOLE_TRACE("IOleControlSite::OnControlInfoChanged");
1597 return S_OK;
1598 }
1599
LockInPlaceActive(BOOL fLock)1600 HRESULT FrameSite::LockInPlaceActive(BOOL fLock)
1601 {
1602 WXOLE_TRACE("IOleControlSite::LockInPlaceActive");
1603 m_bInPlaceLocked = (fLock) ? true : false;
1604 return S_OK;
1605 }
1606
GetExtendedControl(IDispatch ** ppDisp)1607 HRESULT FrameSite::GetExtendedControl(IDispatch ** ppDisp)
1608 {
1609 WXOLE_TRACE("IOleControlSite::GetExtendedControl");
1610 return E_NOTIMPL;
1611 }
1612
TransformCoords(POINTL * pPtlHimetric,POINTF * pPtfContainer,DWORD dwFlags)1613 HRESULT FrameSite::TransformCoords(POINTL * pPtlHimetric, POINTF * pPtfContainer, DWORD dwFlags)
1614 {
1615 WXOLE_TRACE("IOleControlSite::TransformCoords");
1616 HRESULT hr = S_OK;
1617
1618 if (pPtlHimetric == NULL)
1619 return E_INVALIDARG;
1620
1621 if (pPtfContainer == NULL)
1622 return E_INVALIDARG;
1623
1624 return E_NOTIMPL;
1625
1626 }
1627
TranslateAccelerator(LPMSG pMsg,DWORD grfModifiers)1628 HRESULT FrameSite::TranslateAccelerator(LPMSG pMsg, DWORD grfModifiers)
1629 {
1630 WXOLE_TRACE("IOleControlSite::TranslateAccelerator");
1631 // TODO: send an event with this id
1632 return E_NOTIMPL;
1633 }
1634
OnFocus(BOOL fGotFocus)1635 HRESULT FrameSite::OnFocus(BOOL fGotFocus)
1636 {
1637 WXOLE_TRACE("IOleControlSite::OnFocus");
1638 return S_OK;
1639 }
1640
ShowPropertyFrame()1641 HRESULT FrameSite::ShowPropertyFrame()
1642 {
1643 WXOLE_TRACE("IOleControlSite::ShowPropertyFrame");
1644 return E_NOTIMPL;
1645 }
1646
1647 //IOleCommandTarget
1648
QueryStatus(const GUID * pguidCmdGroup,ULONG cCmds,OLECMD * prgCmds,OLECMDTEXT * pCmdTet)1649 HRESULT FrameSite::QueryStatus(const GUID * pguidCmdGroup, ULONG cCmds,
1650 OLECMD * prgCmds, OLECMDTEXT * pCmdTet)
1651 {
1652 WXOLE_TRACE("IOleCommandTarget::QueryStatus");
1653 if (prgCmds == NULL) return E_INVALIDARG;
1654 bool bCmdGroupFound = false;
1655
1656 for (ULONG nCmd = 0; nCmd < cCmds; nCmd++)
1657 {
1658 // unsupported by default
1659 prgCmds[nCmd].cmdf = 0;
1660
1661 // TODO
1662 }
1663
1664 if (!bCmdGroupFound) { OLECMDERR_E_UNKNOWNGROUP; }
1665 return S_OK;
1666 }
1667
Exec(const GUID * pguidCmdGroup,DWORD nCmdID,DWORD nCmdExecOpt,VARIANTARG * pVaIn,VARIANTARG * pVaOut)1668 HRESULT FrameSite::Exec(const GUID * pguidCmdGroup, DWORD nCmdID,
1669 DWORD nCmdExecOpt, VARIANTARG * pVaIn,
1670 VARIANTARG * pVaOut)
1671 {
1672 WXOLE_TRACE("IOleCommandTarget::Exec");
1673 bool bCmdGroupFound = false;
1674
1675 if (!bCmdGroupFound) { OLECMDERR_E_UNKNOWNGROUP; }
1676 return OLECMDERR_E_NOTSUPPORTED;
1677 }
1678
1679 //IAdviseSink
1680
OnDataChange(FORMATETC * pFormatEtc,STGMEDIUM * pgStgMed)1681 void STDMETHODCALLTYPE FrameSite::OnDataChange(FORMATETC * pFormatEtc, STGMEDIUM * pgStgMed)
1682 {
1683 WXOLE_TRACE("IAdviseSink::OnDataChange");
1684 }
1685
OnViewChange(DWORD dwAspect,LONG lIndex)1686 void STDMETHODCALLTYPE FrameSite::OnViewChange(DWORD dwAspect, LONG lIndex)
1687 {
1688 WXOLE_TRACE("IAdviseSink::OnViewChange");
1689 // redraw the control
1690 }
1691
OnRename(IMoniker * pmk)1692 void STDMETHODCALLTYPE FrameSite::OnRename(IMoniker * pmk)
1693 {
1694 WXOLE_TRACE("IAdviseSink::OnRename");
1695 }
1696
OnSave()1697 void STDMETHODCALLTYPE FrameSite::OnSave()
1698 {
1699 WXOLE_TRACE("IAdviseSink::OnSave");
1700 }
1701
OnClose()1702 void STDMETHODCALLTYPE FrameSite::OnClose()
1703 {
1704 WXOLE_TRACE("IAdviseSink::OnClose");
1705 }
1706
1707 /////////////////////////////////////////////
1708 // IOleDocumentSite
ActivateMe(IOleDocumentView __RPC_FAR * pViewToActivate)1709 HRESULT STDMETHODCALLTYPE FrameSite::ActivateMe(
1710 /* [in] */ IOleDocumentView __RPC_FAR *pViewToActivate)
1711 {
1712 wxAutoOleInterface<IOleInPlaceSite> inPlaceSite(IID_IOleInPlaceSite, (IDispatch *) this);
1713 if (!inPlaceSite.Ok())
1714 return E_FAIL;
1715
1716 if (pViewToActivate)
1717 {
1718 m_window->m_docView = pViewToActivate;
1719 m_window->m_docView->SetInPlaceSite(inPlaceSite);
1720 }
1721 else
1722 {
1723 wxAutoOleInterface<IOleDocument> oleDoc(IID_IOleDocument, m_window->m_oleObject);
1724 if (! oleDoc.Ok())
1725 return E_FAIL;
1726
1727 HRESULT hr = oleDoc->CreateView(inPlaceSite, NULL, 0, m_window->m_docView.GetRef());
1728 if (hr != S_OK)
1729 return E_FAIL;
1730
1731 m_window->m_docView->SetInPlaceSite(inPlaceSite);
1732 };
1733
1734 m_window->m_docView->UIActivate(TRUE);
1735
1736 return S_OK;
1737 };
1738
1739
1740
1741 static IMalloc *iMalloc = NULL;
1742
GetIMalloc()1743 IMalloc *wxOleInit::GetIMalloc()
1744 {
1745 assert(iMalloc);
1746 return iMalloc;
1747 };
1748
wxOleInit()1749 wxOleInit::wxOleInit()
1750 {
1751 if (OleInitialize(NULL) == S_OK && iMalloc == NULL)
1752 CoGetMalloc(1, &iMalloc);
1753 else if (iMalloc)
1754 iMalloc->AddRef();
1755 };
1756
~wxOleInit()1757 wxOleInit::~wxOleInit()
1758 {
1759 if (iMalloc)
1760 {
1761 if (iMalloc->Release() == 0)
1762 iMalloc = NULL;
1763 };
1764
1765 OleUninitialize();
1766 }
1767
OLEHResultToString(HRESULT hr)1768 wxString OLEHResultToString(HRESULT hr)
1769 {
1770 switch (hr)
1771 {
1772 case S_OK:
1773 return _T("");
1774
1775 case OLECMDERR_E_UNKNOWNGROUP:
1776 return _T("The pguidCmdGroup parameter is not NULL but does not specify a recognized command group.");
1777
1778 case OLECMDERR_E_NOTSUPPORTED:
1779 return _T("The nCmdID parameter is not a valid command in the group identified by pguidCmdGroup.");
1780
1781 case OLECMDERR_E_DISABLED:
1782 return _T("The command identified by nCmdID is currently disabled and cannot be executed.");
1783
1784 case OLECMDERR_E_NOHELP:
1785 return _T("The caller has asked for help on the command identified by nCmdID, but no help is available.");
1786
1787 case OLECMDERR_E_CANCELED:
1788 return _T("The user canceled the execution of the command.");
1789
1790 case E_INVALIDARG:
1791 return _T("E_INVALIDARG");
1792
1793 case E_OUTOFMEMORY:
1794 return _T("E_OUTOFMEMORY");
1795
1796 case E_NOINTERFACE:
1797 return _T("E_NOINTERFACE");
1798
1799 case E_UNEXPECTED:
1800 return _T("E_UNEXPECTED");
1801
1802 case STG_E_INVALIDFLAG:
1803 return _T("STG_E_INVALIDFLAG");
1804
1805 case E_FAIL:
1806 return _T("E_FAIL");
1807
1808 case E_NOTIMPL:
1809 return _T("E_NOTIMPL");
1810
1811 default:
1812 {
1813 wxString s;
1814 s.Printf(_T("Unknown - 0x%X"), hr);
1815 return s;
1816 }
1817 };
1818 };
1819
1820 // borrowed from src/msw/ole/oleutils.cpp
GetIIDName(REFIID riid)1821 wxString GetIIDName(REFIID riid)
1822 {
1823 // an association between symbolic name and numeric value of an IID
1824 struct KNOWN_IID
1825 {
1826 const IID *pIid;
1827 const wxChar *szName;
1828 };
1829
1830 // construct the table containing all known interfaces
1831 #define ADD_KNOWN_IID(name) { &IID_I##name, _T(#name) }
1832 #define ADD_KNOWN_GUID(name) { &name, _T(#name) }
1833
1834 static const KNOWN_IID aKnownIids[] =
1835 {
1836 ADD_KNOWN_IID(AdviseSink),
1837 ADD_KNOWN_IID(AdviseSink2),
1838 ADD_KNOWN_IID(BindCtx),
1839 ADD_KNOWN_IID(ClassFactory),
1840 #if ( !defined( __VISUALC__) || (__VISUALC__!=1010) ) && !defined(__MWERKS__)
1841 ADD_KNOWN_IID(ContinueCallback),
1842 ADD_KNOWN_IID(EnumOleDocumentViews),
1843 ADD_KNOWN_IID(OleCommandTarget),
1844 ADD_KNOWN_IID(OleDocument),
1845 ADD_KNOWN_IID(OleDocumentSite),
1846 ADD_KNOWN_IID(OleDocumentView),
1847 ADD_KNOWN_IID(Print),
1848 #endif
1849 ADD_KNOWN_IID(DataAdviseHolder),
1850 ADD_KNOWN_IID(DataObject),
1851 ADD_KNOWN_IID(Debug),
1852 ADD_KNOWN_IID(DebugStream),
1853 ADD_KNOWN_IID(DfReserved1),
1854 ADD_KNOWN_IID(DfReserved2),
1855 ADD_KNOWN_IID(DfReserved3),
1856 ADD_KNOWN_IID(Dispatch),
1857 ADD_KNOWN_IID(DropSource),
1858 ADD_KNOWN_IID(DropTarget),
1859 ADD_KNOWN_IID(EnumCallback),
1860 ADD_KNOWN_IID(EnumFORMATETC),
1861 ADD_KNOWN_IID(EnumGeneric),
1862 ADD_KNOWN_IID(EnumHolder),
1863 ADD_KNOWN_IID(EnumMoniker),
1864 ADD_KNOWN_IID(EnumOLEVERB),
1865 ADD_KNOWN_IID(EnumSTATDATA),
1866 ADD_KNOWN_IID(EnumSTATSTG),
1867 ADD_KNOWN_IID(EnumString),
1868 ADD_KNOWN_IID(EnumUnknown),
1869 ADD_KNOWN_IID(EnumVARIANT),
1870 ADD_KNOWN_IID(ExternalConnection),
1871 ADD_KNOWN_IID(InternalMoniker),
1872 ADD_KNOWN_IID(LockBytes),
1873 ADD_KNOWN_IID(Malloc),
1874 ADD_KNOWN_IID(Marshal),
1875 ADD_KNOWN_IID(MessageFilter),
1876 ADD_KNOWN_IID(Moniker),
1877 ADD_KNOWN_IID(OleAdviseHolder),
1878 ADD_KNOWN_IID(OleCache),
1879 ADD_KNOWN_IID(OleCache2),
1880 ADD_KNOWN_IID(OleCacheControl),
1881 ADD_KNOWN_IID(OleClientSite),
1882 ADD_KNOWN_IID(OleContainer),
1883 ADD_KNOWN_IID(OleInPlaceActiveObject),
1884 ADD_KNOWN_IID(OleInPlaceFrame),
1885 ADD_KNOWN_IID(OleInPlaceObject),
1886 ADD_KNOWN_IID(OleInPlaceSite),
1887 ADD_KNOWN_IID(OleInPlaceUIWindow),
1888 ADD_KNOWN_IID(OleItemContainer),
1889 ADD_KNOWN_IID(OleLink),
1890 ADD_KNOWN_IID(OleManager),
1891 ADD_KNOWN_IID(OleObject),
1892 ADD_KNOWN_IID(OlePresObj),
1893 ADD_KNOWN_IID(OleWindow),
1894 ADD_KNOWN_IID(PSFactory),
1895 ADD_KNOWN_IID(ParseDisplayName),
1896 ADD_KNOWN_IID(Persist),
1897 ADD_KNOWN_IID(PersistFile),
1898 ADD_KNOWN_IID(PersistStorage),
1899 ADD_KNOWN_IID(PersistStream),
1900 ADD_KNOWN_IID(ProxyManager),
1901 ADD_KNOWN_IID(RootStorage),
1902 ADD_KNOWN_IID(RpcChannel),
1903 ADD_KNOWN_IID(RpcProxy),
1904 ADD_KNOWN_IID(RpcStub),
1905 ADD_KNOWN_IID(RunnableObject),
1906 ADD_KNOWN_IID(RunningObjectTable),
1907 ADD_KNOWN_IID(StdMarshalInfo),
1908 ADD_KNOWN_IID(Storage),
1909 ADD_KNOWN_IID(Stream),
1910 ADD_KNOWN_IID(StubManager),
1911 ADD_KNOWN_IID(Unknown),
1912 ADD_KNOWN_IID(ViewObject),
1913 ADD_KNOWN_IID(ViewObject2),
1914 ADD_KNOWN_GUID(IID_IDispatch),
1915 ADD_KNOWN_GUID(IID_IWebBrowser),
1916 ADD_KNOWN_GUID(IID_IWebBrowserApp),
1917 ADD_KNOWN_GUID(IID_IWebBrowser2),
1918 ADD_KNOWN_GUID(IID_IWebBrowser),
1919 ADD_KNOWN_GUID(DIID_DWebBrowserEvents2),
1920 ADD_KNOWN_GUID(DIID_DWebBrowserEvents),
1921 };
1922
1923 // don't clobber preprocessor name space
1924 #undef ADD_KNOWN_IID
1925 #undef ADD_KNOWN_GUID
1926
1927 // try to find the interface in the table
1928 for ( size_t ui = 0; ui < WXSIZEOF(aKnownIids); ui++ )
1929 {
1930 if ( riid == *aKnownIids[ui].pIid )
1931 {
1932 return aKnownIids[ui].szName;
1933 }
1934 }
1935
1936 // unknown IID, just transform to string
1937 LPOLESTR str = NULL;
1938 StringFromIID(riid, &str);
1939 if (str)
1940 {
1941 wxString s = str;
1942 CoTaskMemFree(str);
1943 return s;
1944 }
1945 else
1946 return _T("StringFromIID() error");
1947 }
1948