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