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