]> git.saurik.com Git - wxWidgets.git/blob - src/msw/ole/activex.cpp
Don't use DDEExec registry key in wxMSW wxExecute() if it's empty.
[wxWidgets.git] / src / msw / ole / activex.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/ole/activex.cpp
3 // Purpose: wxActiveXContainer implementation
4 // Author: Ryan Norton <wxprojects@comcast.net>, Lindsay Mathieson <???>
5 // Modified by:
6 // Created: 11/07/04
7 // Copyright: (c) 2003 Lindsay Mathieson, (c) 2005 Ryan Norton
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // declarations
13 // ============================================================================
14
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18
19 #include "wx/wxprec.h"
20
21 #ifdef __BORLANDC__
22 #pragma hdrstop
23 #endif
24
25 #if wxUSE_ACTIVEX
26
27 #ifndef WX_PRECOMP
28 #include "wx/dcclient.h"
29 #include "wx/math.h"
30 #endif
31
32 #include "wx/msw/dc.h"
33
34 #include "wx/msw/ole/activex.h"
35 #include "wx/msw/private.h" // for wxCopyRectToRECT
36
37 // autointerfaces that we only use here
38 typedef wxAutoOleInterface<IOleInPlaceSite> wxAutoIOleInPlaceSite;
39 typedef wxAutoOleInterface<IOleDocument> wxAutoIOleDocument;
40 typedef wxAutoOleInterface<IPersistStreamInit> wxAutoIPersistStreamInit;
41 typedef wxAutoOleInterface<IAdviseSink> wxAutoIAdviseSink;
42 typedef wxAutoOleInterface<IProvideClassInfo> wxAutoIProvideClassInfo;
43 typedef wxAutoOleInterface<ITypeInfo> wxAutoITypeInfo;
44 typedef wxAutoOleInterface<IConnectionPoint> wxAutoIConnectionPoint;
45 typedef wxAutoOleInterface<IConnectionPointContainer> wxAutoIConnectionPointContainer;
46
47 wxDEFINE_EVENT( wxEVT_ACTIVEX, wxActiveXEvent );
48
49 // Ole class helpers (sort of MFC-like) from wxActiveX
50 #define DECLARE_OLE_UNKNOWN(cls)\
51 private:\
52 class TAutoInitInt\
53 {\
54 public:\
55 LONG l;\
56 TAutoInitInt() : l(1) {}\
57 };\
58 TAutoInitInt refCount, lockCount;\
59 static void _GetInterface(cls *self, REFIID iid, void **_interface, const char *&desc);\
60 public:\
61 LONG GetRefCount();\
62 HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void ** ppvObject);\
63 ULONG STDMETHODCALLTYPE AddRef();\
64 ULONG STDMETHODCALLTYPE Release();\
65 ULONG STDMETHODCALLTYPE AddLock();\
66 ULONG STDMETHODCALLTYPE ReleaseLock()
67
68 #define DEFINE_OLE_TABLE(cls)\
69 LONG cls::GetRefCount() {return refCount.l;}\
70 HRESULT STDMETHODCALLTYPE cls::QueryInterface(REFIID iid, void ** ppvObject)\
71 {\
72 if (! ppvObject)\
73 {\
74 return E_FAIL;\
75 }\
76 const char *desc = NULL;\
77 cls::_GetInterface(this, iid, ppvObject, desc);\
78 if (! *ppvObject)\
79 {\
80 return E_NOINTERFACE;\
81 }\
82 ((IUnknown * )(*ppvObject))->AddRef();\
83 return S_OK;\
84 }\
85 ULONG STDMETHODCALLTYPE cls::AddRef()\
86 {\
87 InterlockedIncrement(&refCount.l);\
88 return refCount.l;\
89 }\
90 ULONG STDMETHODCALLTYPE cls::Release()\
91 {\
92 if (refCount.l > 0)\
93 {\
94 InterlockedDecrement(&refCount.l);\
95 if (refCount.l == 0)\
96 {\
97 delete this;\
98 return 0;\
99 }\
100 return refCount.l;\
101 }\
102 else\
103 return 0;\
104 }\
105 ULONG STDMETHODCALLTYPE cls::AddLock()\
106 {\
107 InterlockedIncrement(&lockCount.l);\
108 return lockCount.l;\
109 }\
110 ULONG STDMETHODCALLTYPE cls::ReleaseLock()\
111 {\
112 if (lockCount.l > 0)\
113 {\
114 InterlockedDecrement(&lockCount.l);\
115 return lockCount.l;\
116 }\
117 else\
118 return 0;\
119 }\
120 DEFINE_OLE_BASE(cls)
121
122 #define DEFINE_OLE_BASE(cls)\
123 void cls::_GetInterface(cls *self, REFIID iid, void **_interface, const char *&desc)\
124 {\
125 *_interface = NULL;\
126 desc = NULL;
127
128 #define OLE_INTERFACE(_iid, _type)\
129 if (IsEqualIID(iid, _iid))\
130 {\
131 *_interface = (IUnknown *) (_type *) self;\
132 desc = # _iid;\
133 return;\
134 }
135
136 #define OLE_IINTERFACE(_face) OLE_INTERFACE(IID_##_face, _face)
137
138 #define OLE_INTERFACE_CUSTOM(func)\
139 if (func(self, iid, _interface, desc))\
140 {\
141 return;\
142 }
143
144 #define END_OLE_TABLE\
145 }
146
147 // ============================================================================
148 // implementation
149 // ============================================================================
150
151 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
152 // PixelsToHimetric
153 //
154 // Utility to convert from pixels to the himetric values in some COM methods
155 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
156
157
158 #define HIMETRIC_PER_INCH 2540
159 #define MAP_PIX_TO_LOGHIM(x,ppli) MulDiv(HIMETRIC_PER_INCH, (x), (ppli))
160
161 static void PixelsToHimetric(SIZEL &sz)
162 {
163 static int logX = 0;
164 static int logY = 0;
165
166 if (logY == 0)
167 {
168 // initaliase
169 HDC dc = GetDC(NULL);
170 logX = GetDeviceCaps(dc, LOGPIXELSX);
171 logY = GetDeviceCaps(dc, LOGPIXELSY);
172 ReleaseDC(NULL, dc);
173 };
174
175 #define HIMETRIC_INCH 2540
176 #define CONVERT(x, logpixels) wxMulDivInt32(HIMETRIC_INCH, (x), (logpixels))
177
178 sz.cx = CONVERT(sz.cx, logX);
179 sz.cy = CONVERT(sz.cy, logY);
180
181 #undef CONVERT
182 #undef HIMETRIC_INCH
183 }
184
185
186 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
187 //
188 // FrameSite
189 //
190 // Handles the actual wxActiveX container implementation
191 //
192 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
193 class FrameSite :
194 public IOleClientSite,
195 public IOleInPlaceSiteEx,
196 public IOleInPlaceFrame,
197 public IOleItemContainer,
198 public IDispatch,
199 public IOleCommandTarget,
200 public IOleDocumentSite,
201 public IAdviseSink,
202 public IOleControlSite
203 {
204 private:
205 DECLARE_OLE_UNKNOWN(FrameSite);
206
207 public:
208 FrameSite(wxWindow * win, wxActiveXContainer * win2)
209 {
210 m_window = win2;
211 m_bSupportsWindowlessActivation = true;
212 m_bInPlaceLocked = false;
213 m_bUIActive = false;
214 m_bInPlaceActive = false;
215 m_bWindowless = false;
216
217 m_nAmbientLocale = 0;
218 m_clrAmbientForeColor = ::GetSysColor(COLOR_WINDOWTEXT);
219 m_clrAmbientBackColor = ::GetSysColor(COLOR_WINDOW);
220 m_bAmbientShowHatching = true;
221 m_bAmbientShowGrabHandles = true;
222 m_bAmbientAppearance = true;
223
224 m_hDCBuffer = NULL;
225 m_hWndParent = (HWND)win->GetHWND();
226 }
227 virtual ~FrameSite(){}
228 //***************************IDispatch*****************************
229 HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID, OLECHAR ** ,
230 unsigned int , LCID ,
231 DISPID * )
232 { return E_NOTIMPL; }
233 STDMETHOD(GetTypeInfo)(unsigned int, LCID, ITypeInfo **)
234 { return E_NOTIMPL; }
235 HRESULT STDMETHODCALLTYPE GetTypeInfoCount(unsigned int *)
236 { return E_NOTIMPL; }
237 HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID, LCID,
238 WORD wFlags, DISPPARAMS *,
239 VARIANT * pVarResult, EXCEPINFO *,
240 unsigned int *)
241 {
242 if (!(wFlags & DISPATCH_PROPERTYGET))
243 return S_OK;
244
245 if (pVarResult == NULL)
246 return E_INVALIDARG;
247
248 //The most common case is boolean, use as an initial type
249 V_VT(pVarResult) = VT_BOOL;
250
251 switch (dispIdMember)
252 {
253 case DISPID_AMBIENT_MESSAGEREFLECT:
254 V_BOOL(pVarResult)= FALSE;
255 return S_OK;
256
257 case DISPID_AMBIENT_DISPLAYASDEFAULT:
258 V_BOOL(pVarResult)= TRUE;
259 return S_OK;
260
261 case DISPID_AMBIENT_OFFLINEIFNOTCONNECTED:
262 V_BOOL(pVarResult) = TRUE;
263 return S_OK;
264
265 case DISPID_AMBIENT_SILENT:
266 V_BOOL(pVarResult)= TRUE;
267 return S_OK;
268
269 case DISPID_AMBIENT_APPEARANCE:
270 pVarResult->vt = VT_BOOL;
271 pVarResult->boolVal = m_bAmbientAppearance;
272 break;
273
274 case DISPID_AMBIENT_FORECOLOR:
275 pVarResult->vt = VT_I4;
276 pVarResult->lVal = (long) m_clrAmbientForeColor;
277 break;
278
279 case DISPID_AMBIENT_BACKCOLOR:
280 pVarResult->vt = VT_I4;
281 pVarResult->lVal = (long) m_clrAmbientBackColor;
282 break;
283
284 case DISPID_AMBIENT_LOCALEID:
285 pVarResult->vt = VT_I4;
286 pVarResult->lVal = (long) m_nAmbientLocale;
287 break;
288
289 case DISPID_AMBIENT_USERMODE:
290 pVarResult->vt = VT_BOOL;
291 pVarResult->boolVal = m_window->m_bAmbientUserMode;
292 break;
293
294 case DISPID_AMBIENT_SHOWGRABHANDLES:
295 pVarResult->vt = VT_BOOL;
296 pVarResult->boolVal = m_bAmbientShowGrabHandles;
297 break;
298
299 case DISPID_AMBIENT_SHOWHATCHING:
300 pVarResult->vt = VT_BOOL;
301 pVarResult->boolVal = m_bAmbientShowHatching;
302 break;
303
304 default:
305 return DISP_E_MEMBERNOTFOUND;
306 }
307
308 return S_OK;
309 }
310
311 //**************************IOleWindow***************************
312 HRESULT STDMETHODCALLTYPE GetWindow(HWND * phwnd)
313 {
314 if (phwnd == NULL)
315 return E_INVALIDARG;
316 (*phwnd) = m_hWndParent;
317 return S_OK;
318 }
319 HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL)
320 {return S_OK;}
321 //**************************IOleInPlaceUIWindow*****************
322 HRESULT STDMETHODCALLTYPE GetBorder(LPRECT lprectBorder)
323 {
324 if (lprectBorder == NULL)
325 return E_INVALIDARG;
326 return INPLACE_E_NOTOOLSPACE;
327 }
328 HRESULT STDMETHODCALLTYPE RequestBorderSpace(LPCBORDERWIDTHS pborderwidths)
329 {
330 if (pborderwidths == NULL)
331 return E_INVALIDARG;
332 return INPLACE_E_NOTOOLSPACE;
333 }
334 HRESULT STDMETHODCALLTYPE SetBorderSpace(LPCBORDERWIDTHS)
335 {return S_OK;}
336 HRESULT STDMETHODCALLTYPE SetActiveObject(
337 IOleInPlaceActiveObject *pActiveObject, LPCOLESTR)
338 {
339 if (pActiveObject)
340 pActiveObject->AddRef();
341
342 m_window->m_oleInPlaceActiveObject = pActiveObject;
343 return S_OK;
344 }
345
346 //********************IOleInPlaceFrame************************
347
348 STDMETHOD(InsertMenus)(HMENU, LPOLEMENUGROUPWIDTHS){return S_OK;}
349 STDMETHOD(SetMenu)(HMENU, HOLEMENU, HWND){ return S_OK;}
350 STDMETHOD(RemoveMenus)(HMENU){return S_OK;}
351 STDMETHOD(SetStatusText)(LPCOLESTR){ return S_OK;}
352 HRESULT STDMETHODCALLTYPE EnableModeless(BOOL){return S_OK;}
353 HRESULT STDMETHODCALLTYPE TranslateAccelerator(LPMSG lpmsg, WORD)
354 {
355 // TODO: send an event with this id
356 if (m_window->m_oleInPlaceActiveObject.IsOk())
357 m_window->m_oleInPlaceActiveObject->TranslateAccelerator(lpmsg);
358 return S_FALSE;
359 }
360
361 //*******************IOleInPlaceSite**************************
362 HRESULT STDMETHODCALLTYPE CanInPlaceActivate(){return S_OK;}
363 HRESULT STDMETHODCALLTYPE OnInPlaceActivate()
364 { m_bInPlaceActive = true; return S_OK; }
365 HRESULT STDMETHODCALLTYPE OnUIActivate()
366 { m_bUIActive = true; return S_OK; }
367 HRESULT STDMETHODCALLTYPE GetWindowContext(IOleInPlaceFrame **ppFrame,
368 IOleInPlaceUIWindow **ppDoc,
369 LPRECT lprcPosRect,
370 LPRECT lprcClipRect,
371 LPOLEINPLACEFRAMEINFO lpFrameInfo)
372 {
373 if (ppFrame == NULL || ppDoc == NULL || lprcPosRect == NULL ||
374 lprcClipRect == NULL || lpFrameInfo == NULL)
375 {
376 if (ppFrame != NULL)
377 (*ppFrame) = NULL;
378 if (ppDoc != NULL)
379 (*ppDoc) = NULL;
380 return E_INVALIDARG;
381 }
382
383 HRESULT hr = QueryInterface(IID_IOleInPlaceFrame, (void **) ppFrame);
384 if (! SUCCEEDED(hr))
385 {
386 return E_UNEXPECTED;
387 }
388
389 hr = QueryInterface(IID_IOleInPlaceUIWindow, (void **) ppDoc);
390 if (! SUCCEEDED(hr))
391 {
392 (*ppFrame)->Release();
393 *ppFrame = NULL;
394 return E_UNEXPECTED;
395 }
396
397 RECT rect;
398 ::GetClientRect(m_hWndParent, &rect);
399 if (lprcPosRect)
400 {
401 lprcPosRect->left = lprcPosRect->top = 0;
402 lprcPosRect->right = rect.right;
403 lprcPosRect->bottom = rect.bottom;
404 }
405 if (lprcClipRect)
406 {
407 lprcClipRect->left = lprcClipRect->top = 0;
408 lprcClipRect->right = rect.right;
409 lprcClipRect->bottom = rect.bottom;
410 }
411
412 memset(lpFrameInfo, 0, sizeof(OLEINPLACEFRAMEINFO));
413 lpFrameInfo->cb = sizeof(OLEINPLACEFRAMEINFO);
414 lpFrameInfo->hwndFrame = m_hWndParent;
415
416 return S_OK;
417 }
418 HRESULT STDMETHODCALLTYPE Scroll(SIZE){return S_OK;}
419 HRESULT STDMETHODCALLTYPE OnUIDeactivate(BOOL)
420 { m_bUIActive = false; return S_OK; }
421 HRESULT STDMETHODCALLTYPE OnInPlaceDeactivate()
422 { m_bInPlaceActive = false; return S_OK; }
423 HRESULT STDMETHODCALLTYPE DiscardUndoState(){return S_OK;}
424 HRESULT STDMETHODCALLTYPE DeactivateAndUndo(){return S_OK; }
425 HRESULT STDMETHODCALLTYPE OnPosRectChange(LPCRECT lprcPosRect)
426 {
427 if (m_window->m_oleInPlaceObject.IsOk() && lprcPosRect)
428 {
429 //
430 // Result of several hours and days of bug hunting -
431 // this is called by an object when it wants to resize
432 // itself to something different then our parent window -
433 // don't let it :)
434 //
435 // m_window->m_oleInPlaceObject->SetObjectRects(
436 // lprcPosRect, lprcPosRect);
437 RECT rcClient;
438 ::GetClientRect(m_hWndParent, &rcClient);
439 m_window->m_oleInPlaceObject->SetObjectRects(
440 &rcClient, &rcClient);
441 }
442 return S_OK;
443 }
444 //*************************IOleInPlaceSiteEx***********************
445 HRESULT STDMETHODCALLTYPE OnInPlaceActivateEx(BOOL * pfNoRedraw, DWORD)
446 {
447 #ifdef __WXWINCE__
448 IRunnableObject* runnable = NULL;
449 HRESULT hr = QueryInterface(
450 IID_IRunnableObject, (void**)(& runnable));
451 if (SUCCEEDED(hr))
452 {
453 runnable->LockRunning(TRUE, FALSE);
454 }
455 #else
456 OleLockRunning(m_window->m_ActiveX, TRUE, FALSE);
457 #endif
458 if (pfNoRedraw)
459 (*pfNoRedraw) = FALSE;
460 return S_OK;
461 }
462
463 HRESULT STDMETHODCALLTYPE OnInPlaceDeactivateEx(BOOL)
464 {
465 #ifdef __WXWINCE__
466 IRunnableObject* runnable = NULL;
467 HRESULT hr = QueryInterface(
468 IID_IRunnableObject, (void**)(& runnable));
469 if (SUCCEEDED(hr))
470 {
471 runnable->LockRunning(FALSE, FALSE);
472 }
473 #else
474 OleLockRunning(m_window->m_ActiveX, FALSE, FALSE);
475 #endif
476 return S_OK;
477 }
478 STDMETHOD(RequestUIActivate)(){ return S_OK;}
479 //*************************IOleClientSite**************************
480 HRESULT STDMETHODCALLTYPE SaveObject(){return S_OK;}
481 const char *OleGetMonikerToStr(DWORD dwAssign)
482 {
483 switch (dwAssign)
484 {
485 case OLEGETMONIKER_ONLYIFTHERE : return "OLEGETMONIKER_ONLYIFTHERE";
486 case OLEGETMONIKER_FORCEASSIGN : return "OLEGETMONIKER_FORCEASSIGN";
487 case OLEGETMONIKER_UNASSIGN : return "OLEGETMONIKER_UNASSIGN";
488 case OLEGETMONIKER_TEMPFORUSER : return "OLEGETMONIKER_TEMPFORUSER";
489 default : return "Bad Enum";
490 }
491 }
492
493 const char *OleGetWhicMonikerStr(DWORD dwWhichMoniker)
494 {
495 switch(dwWhichMoniker)
496 {
497 case OLEWHICHMK_CONTAINER : return "OLEWHICHMK_CONTAINER";
498 case OLEWHICHMK_OBJREL : return "OLEWHICHMK_OBJREL";
499 case OLEWHICHMK_OBJFULL : return "OLEWHICHMK_OBJFULL";
500 default : return "Bad Enum";
501 }
502 }
503 STDMETHOD(GetMoniker)(DWORD, DWORD, IMoniker **){return E_FAIL;}
504 HRESULT STDMETHODCALLTYPE GetContainer(LPOLECONTAINER * ppContainer)
505 {
506 if (ppContainer == NULL)
507 return E_INVALIDARG;
508 HRESULT hr = QueryInterface(
509 IID_IOleContainer, (void**)(ppContainer));
510 wxASSERT(SUCCEEDED(hr));
511 return hr;
512 }
513 HRESULT STDMETHODCALLTYPE ShowObject()
514 {
515 if (m_window->m_oleObjectHWND)
516 ::ShowWindow(m_window->m_oleObjectHWND, SW_SHOW);
517 return S_OK;
518 }
519 STDMETHOD(OnShowWindow)(BOOL){return S_OK;}
520 STDMETHOD(RequestNewObjectLayout)(){return E_NOTIMPL;}
521 //********************IParseDisplayName***************************
522 HRESULT STDMETHODCALLTYPE ParseDisplayName(
523 IBindCtx *, LPOLESTR, ULONG *, IMoniker **){return E_NOTIMPL;}
524 //********************IOleContainer*******************************
525 STDMETHOD(EnumObjects)(DWORD, IEnumUnknown **){return E_NOTIMPL;}
526 HRESULT STDMETHODCALLTYPE LockContainer(BOOL){return S_OK;}
527 //********************IOleItemContainer***************************
528 HRESULT STDMETHODCALLTYPE
529 #if 0 // defined(__WXWINCE__) && __VISUALC__ < 1400
530 GetObject
531 #elif defined(_UNICODE)
532 GetObjectW
533 #else
534 GetObjectA
535 #endif
536 (LPOLESTR pszItem, DWORD, IBindCtx *, REFIID, void ** ppvObject)
537 {
538 if (pszItem == NULL || ppvObject == NULL)
539 return E_INVALIDARG;
540 *ppvObject = NULL;
541 return MK_E_NOOBJECT;
542 }
543 HRESULT STDMETHODCALLTYPE GetObjectStorage(
544 LPOLESTR pszItem, IBindCtx * , REFIID, void ** ppvStorage)
545 {
546 if (pszItem == NULL || ppvStorage == NULL)
547 return E_INVALIDARG;
548 *ppvStorage = NULL;
549 return MK_E_NOOBJECT;
550 }
551 HRESULT STDMETHODCALLTYPE IsRunning(LPOLESTR pszItem)
552 {
553 if (pszItem == NULL)
554 return E_INVALIDARG;
555 return MK_E_NOOBJECT;
556 }
557 //***********************IOleControlSite*****************************
558 HRESULT STDMETHODCALLTYPE OnControlInfoChanged()
559 {return S_OK;}
560 HRESULT STDMETHODCALLTYPE LockInPlaceActive(BOOL fLock)
561 {
562 m_bInPlaceLocked = (fLock) ? true : false;
563 return S_OK;
564 }
565 HRESULT STDMETHODCALLTYPE GetExtendedControl(IDispatch **)
566 {return E_NOTIMPL;}
567 HRESULT STDMETHODCALLTYPE TransformCoords(
568 POINTL * pPtlHimetric, POINTF * pPtfContainer, DWORD)
569 {
570 if (pPtlHimetric == NULL || pPtfContainer == NULL)
571 return E_INVALIDARG;
572 return E_NOTIMPL;
573 }
574 HRESULT STDMETHODCALLTYPE TranslateAccelerator(LPMSG, DWORD)
575 {return E_NOTIMPL;}
576 HRESULT STDMETHODCALLTYPE OnFocus(BOOL){return S_OK;}
577 HRESULT STDMETHODCALLTYPE ShowPropertyFrame(){return E_NOTIMPL;}
578 //**************************IOleCommandTarget***********************
579 HRESULT STDMETHODCALLTYPE QueryStatus(const GUID *, ULONG cCmds,
580 OLECMD prgCmds[], OLECMDTEXT *)
581 {
582 if (prgCmds == NULL) return E_INVALIDARG;
583 for (ULONG nCmd = 0; nCmd < cCmds; nCmd++)
584 {
585 // unsupported by default
586 prgCmds[nCmd].cmdf = 0;
587 }
588 return OLECMDERR_E_UNKNOWNGROUP;
589 }
590
591 HRESULT STDMETHODCALLTYPE Exec(const GUID *, DWORD,
592 DWORD, VARIANTARG *, VARIANTARG *)
593 {return OLECMDERR_E_NOTSUPPORTED;}
594
595 //**********************IAdviseSink************************************
596 void STDMETHODCALLTYPE OnDataChange(FORMATETC *, STGMEDIUM *) {}
597 void STDMETHODCALLTYPE OnViewChange(DWORD, LONG) {}
598 void STDMETHODCALLTYPE OnRename(IMoniker *){}
599 void STDMETHODCALLTYPE OnSave(){}
600 void STDMETHODCALLTYPE OnClose(){}
601
602 //**********************IOleDocumentSite***************************
603 HRESULT STDMETHODCALLTYPE ActivateMe(
604 IOleDocumentView __RPC_FAR *pViewToActivate)
605 {
606 wxAutoIOleInPlaceSite inPlaceSite(
607 IID_IOleInPlaceSite, (IDispatch *) this);
608 if (!inPlaceSite.IsOk())
609 return E_FAIL;
610
611 if (pViewToActivate)
612 {
613 m_window->m_docView = pViewToActivate;
614 m_window->m_docView->SetInPlaceSite(inPlaceSite);
615 }
616 else
617 {
618 wxAutoIOleDocument oleDoc(
619 IID_IOleDocument, m_window->m_oleObject);
620 if (! oleDoc.IsOk())
621 return E_FAIL;
622
623 HRESULT hr = oleDoc->CreateView(inPlaceSite, NULL,
624 0, m_window->m_docView.GetRef());
625 if (hr != S_OK)
626 return E_FAIL;
627
628 m_window->m_docView->SetInPlaceSite(inPlaceSite);
629 }
630
631 m_window->m_docView->UIActivate(TRUE);
632 return S_OK;
633 }
634
635 friend bool QueryClientSiteInterface(FrameSite *self, REFIID iid, void **_interface, const char *&desc)
636 {
637 return self->m_window->QueryClientSiteInterface(iid,_interface,desc);
638 }
639
640 protected:
641 wxActiveXContainer * m_window;
642
643 HDC m_hDCBuffer;
644 HWND m_hWndParent;
645
646 bool m_bSupportsWindowlessActivation;
647 bool m_bInPlaceLocked;
648 bool m_bInPlaceActive;
649 bool m_bUIActive;
650 bool m_bWindowless;
651
652 LCID m_nAmbientLocale;
653 COLORREF m_clrAmbientForeColor;
654 COLORREF m_clrAmbientBackColor;
655 bool m_bAmbientShowHatching;
656 bool m_bAmbientShowGrabHandles;
657 bool m_bAmbientAppearance;
658 };
659
660 DEFINE_OLE_TABLE(FrameSite)
661 OLE_INTERFACE(IID_IUnknown, IOleClientSite)
662 OLE_IINTERFACE(IOleClientSite)
663 OLE_INTERFACE(IID_IOleWindow, IOleInPlaceSite)
664 OLE_IINTERFACE(IOleInPlaceSite)
665 OLE_IINTERFACE(IOleInPlaceSiteEx)
666 OLE_IINTERFACE(IOleInPlaceUIWindow)
667 OLE_IINTERFACE(IOleInPlaceFrame)
668 OLE_IINTERFACE(IParseDisplayName)
669 OLE_IINTERFACE(IOleContainer)
670 OLE_IINTERFACE(IOleItemContainer)
671 OLE_IINTERFACE(IDispatch)
672 OLE_IINTERFACE(IOleCommandTarget)
673 OLE_IINTERFACE(IOleDocumentSite)
674 OLE_IINTERFACE(IAdviseSink)
675 OLE_IINTERFACE(IOleControlSite)
676 OLE_INTERFACE_CUSTOM(QueryClientSiteInterface)
677 END_OLE_TABLE
678
679
680 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
681 //
682 // wxActiveXEvents
683 //
684 // Handles and sends activex events received from the ActiveX control
685 // to the appropriate wxEvtHandler
686 //
687 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
688 class wxActiveXEvents : public IDispatch
689 {
690 private:
691 DECLARE_OLE_UNKNOWN(wxActiveXEvents);
692
693
694 wxActiveXContainer *m_activeX;
695 IID m_customId;
696 bool m_haveCustomId;
697
698 friend bool wxActiveXEventsInterface(wxActiveXEvents *self, REFIID iid, void **_interface, const char *&desc);
699
700 public:
701
702 // a pointer to this static variable is used as an 'invalid_entry_marker'
703 // wxVariants containing a void* to this variables are 'empty' in the sense
704 // that the actual ActiveX OLE parameter has not been converted and inserted
705 // into m_params.
706 static wxVariant ms_invalidEntryMarker;
707
708 wxActiveXEvents(wxActiveXContainer *ax) : m_activeX(ax), m_haveCustomId(false) {}
709 wxActiveXEvents(wxActiveXContainer *ax, REFIID iid) : m_activeX(ax), m_customId(iid), m_haveCustomId(true) {}
710 virtual ~wxActiveXEvents()
711 {
712 }
713
714 // IDispatch
715 STDMETHODIMP GetIDsOfNames(REFIID, OLECHAR**, unsigned int, LCID, DISPID*)
716 {
717 return E_NOTIMPL;
718 }
719
720 STDMETHODIMP GetTypeInfo(unsigned int, LCID, ITypeInfo**)
721 {
722 return E_NOTIMPL;
723 }
724
725 STDMETHODIMP GetTypeInfoCount(unsigned int*)
726 {
727 return E_NOTIMPL;
728 }
729
730
731 STDMETHODIMP Invoke(DISPID dispIdMember, REFIID riid,
732 LCID lcid,
733 WORD wFlags, DISPPARAMS * pDispParams,
734 VARIANT * pVarResult, EXCEPINFO * pExcepInfo,
735 unsigned int * puArgErr)
736 {
737 if (wFlags & (DISPATCH_PROPERTYGET | DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYPUTREF))
738 return E_NOTIMPL;
739
740 wxASSERT(m_activeX);
741
742 // ActiveX Event
743
744 // Dispatch Event
745 wxActiveXEvent event;
746 event.SetEventType(wxEVT_ACTIVEX);
747 // Create an empty list of Variants
748 // Note that the event parameters use lazy evaluation
749 // They are not actually created until wxActiveXEvent::operator[] is called
750 event.m_params.NullList();
751 event.m_dispid = dispIdMember;
752
753 // save the native (MSW) event parameters for event handlers that need to access them
754 // this can be done on the stack since wxActiveXEvent is also allocated on the stack
755 wxActiveXEventNativeMSW eventParameters(dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
756 event.SetClientData(&eventParameters);
757
758 // The event parameters are not copied to event.m_params until they are actually
759 // referenced in wxActiveXEvent::operator[]
760 // This increases performance and avoids error messages and/or crashes
761 // when the event has parameters that are not (yet or never) supported
762 // by wxConvertOleToVariant
763
764 // process the events from the activex method
765 m_activeX->ProcessEvent(event);
766 for (DWORD i = 0; i < pDispParams->cArgs; i++)
767 {
768 size_t params_index = pDispParams->cArgs - i - 1;
769 if (params_index < event.m_params.GetCount()) {
770 wxVariant &vx = event.m_params[params_index];
771 // copy the result back to pDispParams only if the event has been accessed
772 // i.e. if vx != ms_invalidEntryMarker
773 if (!vx.IsType(wxActiveXEvents::ms_invalidEntryMarker.GetType()) || vx!=ms_invalidEntryMarker) {
774 VARIANTARG& va = pDispParams->rgvarg[i];
775 wxConvertVariantToOle(vx, va);
776 }
777 }
778 }
779
780 if(event.GetSkipped())
781 return DISP_E_MEMBERNOTFOUND;
782
783 return S_OK;
784 }
785 };
786
787 namespace
788 {
789 // just a unique global variable
790 const int invalid_entry_marker = 0;
791 }
792
793 wxVariant wxActiveXEvents::ms_invalidEntryMarker((void*)&invalid_entry_marker);
794
795 size_t wxActiveXEvent::ParamCount() const
796 {
797 wxActiveXEventNativeMSW *native=GetNativeParameters();
798 // 'native' will always be != if the event has been created
799 // for an actual active X event.
800 // But it may be zero if the event has been created by wx program code.
801 if (native)
802 return native->pDispParams ? native->pDispParams->cArgs : 0;
803
804 return m_params.GetCount();
805 }
806
807 wxVariant &wxActiveXEvent::operator [](size_t idx)
808 {
809 wxASSERT(idx < ParamCount());
810 wxActiveXEventNativeMSW *native=GetNativeParameters();
811 // 'native' will always be != if the event has been created
812 // for an actual active X event.
813 // But it may be zero if the event has been created by wx program code.
814 if (native)
815 {
816 while ( m_params.GetCount()<=idx )
817 {
818 m_params.Append(wxActiveXEvents::ms_invalidEntryMarker);
819 }
820
821 wxVariant& vx = m_params[idx];
822 if ( vx.IsType(wxActiveXEvents::ms_invalidEntryMarker.GetType()) &&
823 vx == wxActiveXEvents::ms_invalidEntryMarker)
824 {
825 // copy the _real_ parameter into this one
826 // NOTE: m_params stores the parameters in *reverse* order.
827 // Whyever, but this was the case in the original implementation of
828 // wxActiveXEvents::Invoke
829 // Keep this convention.
830 VARIANTARG& va = native->pDispParams->rgvarg[ native->pDispParams->cArgs - idx - 1 ];
831 wxConvertOleToVariant(va, vx);
832 }
833 return vx;
834 }
835 return m_params[idx];
836 }
837
838 bool wxActiveXEventsInterface(wxActiveXEvents *self, REFIID iid, void **_interface, const char *&desc)
839 {
840 if (self->m_haveCustomId && IsEqualIID(iid, self->m_customId))
841 {
842 *_interface = (IUnknown *) (IDispatch *) self;
843 desc = "Custom Dispatch Interface";
844 return true;
845 }
846
847 return false;
848 }
849
850 DEFINE_OLE_TABLE(wxActiveXEvents)
851 OLE_IINTERFACE(IUnknown)
852 OLE_INTERFACE(IID_IDispatch, IDispatch)
853 OLE_INTERFACE_CUSTOM(wxActiveXEventsInterface)
854 END_OLE_TABLE
855
856 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
857 //
858 // wxActiveXContainer
859 //
860 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
861
862 //---------------------------------------------------------------------------
863 // wxActiveXContainer Constructor
864 //
865 // Initializes members and creates the native ActiveX container
866 //---------------------------------------------------------------------------
867 wxActiveXContainer::wxActiveXContainer(wxWindow * parent,
868 REFIID iid, IUnknown* pUnk)
869 : m_realparent(parent)
870 {
871 m_bAmbientUserMode = true;
872 m_docAdviseCookie = 0;
873 CreateActiveX(iid, pUnk);
874 }
875
876 //---------------------------------------------------------------------------
877 // wxActiveXContainer Destructor
878 //
879 // Destroys members (the FrameSite et al. are destroyed implicitly
880 // through COM ref counting)
881 //---------------------------------------------------------------------------
882 wxActiveXContainer::~wxActiveXContainer()
883 {
884 // disconnect connection points
885 if (m_oleInPlaceObject.IsOk())
886 {
887 m_oleInPlaceObject->InPlaceDeactivate();
888 m_oleInPlaceObject->UIDeactivate();
889 }
890
891 if (m_oleObject.IsOk())
892 {
893 if (m_docAdviseCookie != 0)
894 m_oleObject->Unadvise(m_docAdviseCookie);
895
896 m_oleObject->DoVerb(
897 OLEIVERB_HIDE, NULL, m_clientSite, 0, (HWND) GetHWND(), NULL);
898 m_oleObject->Close(OLECLOSE_NOSAVE);
899 m_oleObject->SetClientSite(NULL);
900 }
901
902 // m_clientSite uses m_frameSite so destroy it first
903 m_clientSite.Free();
904 delete m_frameSite;
905
906 // our window doesn't belong to us, don't destroy it
907 m_hWnd = NULL;
908 }
909
910 // VZ: we might want to really report an error instead of just asserting here
911 #if wxDEBUG_LEVEL
912 #define CHECK_HR(hr) \
913 wxASSERT_LEVEL_2_MSG( SUCCEEDED(hr), \
914 wxString::Format("HRESULT = %X", (unsigned)(hr)) )
915 #else
916 #define CHECK_HR(hr) wxUnusedVar(hr)
917 #endif
918
919 //---------------------------------------------------------------------------
920 // wxActiveXContainer::CreateActiveX
921 //
922 // Actually creates the ActiveX container through the FrameSite
923 // and sets up ActiveX events
924 //
925 // TODO: Document this more
926 //---------------------------------------------------------------------------
927 void wxActiveXContainer::CreateActiveX(REFIID iid, IUnknown* pUnk)
928 {
929 HRESULT hret;
930 hret = m_ActiveX.QueryInterface(iid, pUnk);
931 CHECK_HR(hret);
932
933 // FrameSite
934 m_frameSite = new FrameSite(m_realparent, this);
935 // oleClientSite
936 hret = m_clientSite.QueryInterface(
937 IID_IOleClientSite, (IDispatch *) m_frameSite);
938 CHECK_HR(hret);
939 // adviseSink
940 wxAutoIAdviseSink adviseSink(IID_IAdviseSink, (IDispatch *) m_frameSite);
941 wxASSERT(adviseSink.IsOk());
942
943 // Get Dispatch interface
944 hret = m_Dispatch.QueryInterface(IID_IDispatch, m_ActiveX);
945 CHECK_HR(hret);
946
947 //
948 // SETUP TYPEINFO AND ACTIVEX EVENTS
949 //
950
951 // get type info via class info
952 wxAutoIProvideClassInfo classInfo(IID_IProvideClassInfo, m_ActiveX);
953 wxASSERT(classInfo.IsOk());
954
955 // type info
956 wxAutoITypeInfo typeInfo;
957 hret = classInfo->GetClassInfo(typeInfo.GetRef());
958 CHECK_HR(hret);
959 wxASSERT(typeInfo.IsOk());
960
961 // TYPEATTR
962 TYPEATTR *ta = NULL;
963 hret = typeInfo->GetTypeAttr(&ta);
964 CHECK_HR(hret);
965
966 // this should be a TKIND_COCLASS
967 wxASSERT(ta->typekind == TKIND_COCLASS);
968
969 // iterate contained interfaces
970 for (int i = 0; i < ta->cImplTypes; i++)
971 {
972 HREFTYPE rt = 0;
973
974 // get dispatch type info handle
975 hret = typeInfo->GetRefTypeOfImplType(i, &rt);
976 if (! SUCCEEDED(hret))
977 continue;
978
979 // get dispatch type info interface
980 wxAutoITypeInfo ti;
981 hret = typeInfo->GetRefTypeInfo(rt, ti.GetRef());
982 if (! ti.IsOk())
983 continue;
984
985 CHECK_HR(hret);
986
987 // check if default event sink
988 bool defEventSink = false;
989 int impTypeFlags = 0;
990 typeInfo->GetImplTypeFlags(i, &impTypeFlags);
991
992 if (impTypeFlags & IMPLTYPEFLAG_FDEFAULT)
993 {
994 if (impTypeFlags & IMPLTYPEFLAG_FSOURCE)
995 {
996 // WXOLE_TRACEOUT("Default Event Sink");
997 defEventSink = true;
998 if (impTypeFlags & IMPLTYPEFLAG_FDEFAULTVTABLE)
999 {
1000 // WXOLE_TRACEOUT("*ERROR* - Default Event Sink is via vTable");
1001 defEventSink = false;
1002 wxFAIL_MSG(wxT("Default event sink is in vtable!"));
1003 }
1004 }
1005 }
1006
1007
1008 // wxAutoOleInterface<> assumes a ref has already been added
1009 // TYPEATTR
1010 TYPEATTR *ta = NULL;
1011 hret = ti->GetTypeAttr(&ta);
1012 CHECK_HR(hret);
1013
1014 if (ta->typekind == TKIND_DISPATCH)
1015 {
1016 // WXOLE_TRACEOUT("GUID = " << GetIIDName(ta->guid).c_str());
1017 if (defEventSink)
1018 {
1019 wxAutoIConnectionPoint cp;
1020 DWORD adviseCookie = 0;
1021
1022 wxAutoIConnectionPointContainer cpContainer(IID_IConnectionPointContainer, m_ActiveX);
1023 wxASSERT( cpContainer.IsOk());
1024
1025 HRESULT hret =
1026 cpContainer->FindConnectionPoint(ta->guid, cp.GetRef());
1027
1028 // Notice that the return value of CONNECT_E_NOCONNECTION is
1029 // expected if the interface doesn't support connection points.
1030 if ( hret != CONNECT_E_NOCONNECTION )
1031 {
1032 CHECK_HR(hret);
1033 }
1034
1035 if ( cp )
1036 {
1037 wxActiveXEvents * const
1038 events = new wxActiveXEvents(this, ta->guid);
1039 hret = cp->Advise(events, &adviseCookie);
1040
1041 // We don't need this object any more and cp will keep a
1042 // reference to it if it needs it, i.e. if Advise()
1043 // succeeded.
1044 events->Release();
1045
1046 CHECK_HR(hret);
1047 }
1048 }
1049 }
1050
1051 ti->ReleaseTypeAttr(ta);
1052 }
1053
1054 // free
1055 typeInfo->ReleaseTypeAttr(ta);
1056
1057 //
1058 // END
1059 //
1060
1061 // Get IOleObject interface
1062 hret = m_oleObject.QueryInterface(IID_IOleObject, m_ActiveX);
1063 CHECK_HR(hret);
1064
1065 // get IViewObject Interface
1066 hret = m_viewObject.QueryInterface(IID_IViewObject, m_ActiveX);
1067 CHECK_HR(hret);
1068
1069 // document advise
1070 m_docAdviseCookie = 0;
1071 hret = m_oleObject->Advise(adviseSink, &m_docAdviseCookie);
1072 CHECK_HR(hret);
1073
1074 // TODO:Needed?
1075 // hret = m_viewObject->SetAdvise(DVASPECT_CONTENT, 0, adviseSink);
1076 m_oleObject->SetHostNames(L"wxActiveXContainer", NULL);
1077 OleSetContainedObject(m_oleObject, TRUE);
1078 OleRun(m_oleObject);
1079
1080
1081 // Get IOleInPlaceObject interface
1082 hret = m_oleInPlaceObject.QueryInterface(
1083 IID_IOleInPlaceObject, m_ActiveX);
1084 CHECK_HR(hret);
1085
1086 // status
1087 DWORD dwMiscStatus;
1088 m_oleObject->GetMiscStatus(DVASPECT_CONTENT, &dwMiscStatus);
1089 CHECK_HR(hret);
1090
1091 // set client site first ?
1092 if (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)
1093 m_oleObject->SetClientSite(m_clientSite);
1094
1095
1096 // stream init
1097 wxAutoIPersistStreamInit
1098 pPersistStreamInit(IID_IPersistStreamInit, m_oleObject);
1099
1100 if (pPersistStreamInit.IsOk())
1101 {
1102 hret = pPersistStreamInit->InitNew();
1103 CHECK_HR(hret);
1104 }
1105
1106 if (! (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST))
1107 m_oleObject->SetClientSite(m_clientSite);
1108
1109
1110 m_oleObjectHWND = 0;
1111
1112
1113 if (! (dwMiscStatus & OLEMISC_INVISIBLEATRUNTIME))
1114 {
1115 RECT posRect;
1116 wxCopyRectToRECT(m_realparent->GetClientSize(), posRect);
1117
1118 hret = m_oleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL,
1119 m_clientSite, 0, (HWND)m_realparent->GetHWND(), &posRect);
1120 CHECK_HR(hret);
1121
1122 if (m_oleInPlaceObject.IsOk())
1123 {
1124 hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND);
1125 CHECK_HR(hret);
1126 ::SetActiveWindow(m_oleObjectHWND);
1127 }
1128
1129 if (posRect.right > 0 && posRect.bottom > 0 &&
1130 m_oleInPlaceObject.IsOk())
1131 {
1132 m_oleInPlaceObject->SetObjectRects(&posRect, &posRect);
1133 }
1134
1135 hret = m_oleObject->DoVerb(OLEIVERB_SHOW, 0, m_clientSite, 0,
1136 (HWND)m_realparent->GetHWND(), &posRect);
1137 CHECK_HR(hret);
1138 }
1139
1140 if (! m_oleObjectHWND && m_oleInPlaceObject.IsOk())
1141 {
1142 hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND);
1143 CHECK_HR(hret);
1144 }
1145
1146 if (m_oleObjectHWND)
1147 {
1148 ::SetActiveWindow(m_oleObjectHWND);
1149 ::ShowWindow(m_oleObjectHWND, SW_SHOW);
1150
1151 this->AssociateHandle(m_oleObjectHWND);
1152 this->Reparent(m_realparent);
1153
1154 wxWindow* pWnd = m_realparent;
1155 int id = m_realparent->GetId();
1156
1157 pWnd->Connect(id, wxEVT_SIZE,
1158 wxSizeEventHandler(wxActiveXContainer::OnSize), 0, this);
1159 // this->Connect(GetId(), wxEVT_PAINT,
1160 // wxPaintEventHandler(wxActiveXContainer::OnPaint), 0, this);
1161 pWnd->Connect(id, wxEVT_SET_FOCUS,
1162 wxFocusEventHandler(wxActiveXContainer::OnSetFocus), 0, this);
1163 pWnd->Connect(id, wxEVT_KILL_FOCUS,
1164 wxFocusEventHandler(wxActiveXContainer::OnKillFocus), 0, this);
1165 }
1166 }
1167
1168 //---------------------------------------------------------------------------
1169 // wxActiveXContainer::OnSize
1170 //
1171 // Called when the parent is resized - we need to do this to actually
1172 // move the ActiveX control to where the parent is
1173 //---------------------------------------------------------------------------
1174 void wxActiveXContainer::OnSize(wxSizeEvent& event)
1175 {
1176 int w, h;
1177 GetParent()->GetClientSize(&w, &h);
1178
1179 RECT posRect;
1180 posRect.left = 0;
1181 posRect.top = 0;
1182 posRect.right = w;
1183 posRect.bottom = h;
1184
1185 if (w <= 0 || h <= 0)
1186 return;
1187
1188 // extents are in HIMETRIC units
1189 if (m_oleObject.IsOk())
1190 {
1191
1192 SIZEL sz = {w, h};
1193 PixelsToHimetric(sz);
1194
1195 SIZEL sz2;
1196
1197 m_oleObject->GetExtent(DVASPECT_CONTENT, &sz2);
1198 if (sz2.cx != sz.cx || sz.cy != sz2.cy)
1199 m_oleObject->SetExtent(DVASPECT_CONTENT, &sz);
1200
1201 }
1202
1203 if (m_oleInPlaceObject.IsOk())
1204 m_oleInPlaceObject->SetObjectRects(&posRect, &posRect);
1205
1206 event.Skip();
1207 }
1208
1209 //---------------------------------------------------------------------------
1210 // wxActiveXContainer::OnPaint
1211 //
1212 // Called when the parent is resized - repaints the ActiveX control
1213 //---------------------------------------------------------------------------
1214 void wxActiveXContainer::OnPaint(wxPaintEvent& WXUNUSED(event))
1215 {
1216 wxPaintDC dc(this);
1217 // Draw only when control is windowless or deactivated
1218 if (m_viewObject)
1219 {
1220 int w, h;
1221 GetParent()->GetSize(&w, &h);
1222 RECT posRect;
1223 posRect.left = 0;
1224 posRect.top = 0;
1225 posRect.right = w;
1226 posRect.bottom = h;
1227
1228 #if !(defined(_WIN32_WCE) && _WIN32_WCE < 400)
1229 ::RedrawWindow(m_oleObjectHWND, NULL, NULL, RDW_INTERNALPAINT);
1230 #else
1231 ::InvalidateRect(m_oleObjectHWND, NULL, false);
1232 #endif
1233 RECTL *prcBounds = (RECTL *) &posRect;
1234 wxMSWDCImpl *msw = wxDynamicCast( dc.GetImpl() , wxMSWDCImpl );
1235 m_viewObject->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL,
1236 (HDC)msw->GetHDC(), prcBounds, NULL, NULL, 0);
1237 }
1238 }
1239
1240 //---------------------------------------------------------------------------
1241 // wxActiveXContainer::OnSetFocus
1242 //
1243 // Called when the focus is set on the parent - activates the activex control
1244 //---------------------------------------------------------------------------
1245 void wxActiveXContainer::OnSetFocus(wxFocusEvent& event)
1246 {
1247 if (m_oleInPlaceActiveObject.IsOk())
1248 m_oleInPlaceActiveObject->OnFrameWindowActivate(TRUE);
1249
1250 event.Skip();
1251 }
1252
1253 //---------------------------------------------------------------------------
1254 // wxActiveXContainer::OnKillFocus
1255 //
1256 // Called when the focus is killed on the parent -
1257 // deactivates the activex control
1258 //---------------------------------------------------------------------------
1259 void wxActiveXContainer::OnKillFocus(wxFocusEvent& event)
1260 {
1261 if (m_oleInPlaceActiveObject.IsOk())
1262 m_oleInPlaceActiveObject->OnFrameWindowActivate(FALSE);
1263
1264 event.Skip();
1265 }
1266
1267 //---------------------------------------------------------------------------
1268 // wxActiveXContainer::MSWTranslateMessage
1269 //
1270 // Called for every message that needs to be translated.
1271 // Some controls might need more keyboard keys to process (CTRL-C, CTRL-A etc),
1272 // In that case TranslateAccelerator should always be called first.
1273 //---------------------------------------------------------------------------
1274 bool wxActiveXContainer::MSWTranslateMessage(WXMSG* pMsg)
1275 {
1276 if(m_oleInPlaceActiveObject.IsOk() && m_oleInPlaceActiveObject->TranslateAccelerator(pMsg) == S_OK)
1277 {
1278 return true;
1279 }
1280 return wxWindow::MSWTranslateMessage(pMsg);
1281 }
1282
1283 //---------------------------------------------------------------------------
1284 // wxActiveXContainer::QueryClientSiteInterface
1285 //
1286 // Called in the host's site's query method for other interfaces.
1287 //---------------------------------------------------------------------------
1288 bool wxActiveXContainer::QueryClientSiteInterface(REFIID iid, void **_interface, const char *&desc)
1289 {
1290 wxUnusedVar(iid);
1291 wxUnusedVar(_interface);
1292 wxUnusedVar(desc);
1293 return false;
1294 }
1295
1296 #endif // wxUSE_ACTIVEX