~brian-sidebotham/wxwidgets-cmake/wxpython-2.9.4

« back to all changes in this revision

Viewing changes to src/msw/ole/activex.cpp

  • Committer: Brian Sidebotham
  • Date: 2013-08-03 14:30:08 UTC
  • Revision ID: brian.sidebotham@gmail.com-20130803143008-c7806tkych1tp6fc
Initial import into Bazaar

Show diffs side-by-side

added added

removed removed

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