/////////////////////////////////////////////////////////////////////////////
-// Name: msw/ole/activex.cpp
+// Name: src/msw/ole/activex.cpp
// Purpose: wxActiveXContainer implementation
// Author: Ryan Norton <wxprojects@comcast.net>, Lindsay Mathieson <???>
-// Modified by:
+// Modified by:
// Created: 11/07/04
// RCS-ID: $Id$
// Copyright: (c) 2003 Lindsay Mathieson, (c) 2005 Ryan Norton
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
-//===========================================================================
-// DECLARATIONS
-//===========================================================================
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
-//---------------------------------------------------------------------------
-// WX include
-//---------------------------------------------------------------------------
#include "wx/wxprec.h"
-#include "wx/msw/ole/activex.h"
+#ifdef __BORLANDC__
+ #pragma hdrstop
+#endif
+#if wxUSE_ACTIVEX
+#ifndef WX_PRECOMP
+ #include "wx/dcclient.h"
+ #include "wx/math.h"
+#endif
+#include "wx/msw/dc.h"
-//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-//
-// wxActiveXContainer
-//
-//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+#include "wx/msw/ole/activex.h"
+#include "wx/msw/private.h" // for wxCopyRectToRECT
+
+// autointerfaces that we only use here
+typedef wxAutoOleInterface<IOleInPlaceSite> wxAutoIOleInPlaceSite;
+typedef wxAutoOleInterface<IOleDocument> wxAutoIOleDocument;
+typedef wxAutoOleInterface<IPersistStreamInit> wxAutoIPersistStreamInit;
+typedef wxAutoOleInterface<IAdviseSink> wxAutoIAdviseSink;
+typedef wxAutoOleInterface<IProvideClassInfo> wxAutoIProvideClassInfo;
+typedef wxAutoOleInterface<ITypeInfo> wxAutoITypeInfo;
+typedef wxAutoOleInterface<IConnectionPoint> wxAutoIConnectionPoint;
+typedef wxAutoOleInterface<IConnectionPointContainer> wxAutoIConnectionPointContainer;
+
+wxDEFINE_EVENT( wxEVT_ACTIVEX, wxActiveXEvent );
+// Ole class helpers (sort of MFC-like) from wxActiveX
#define DECLARE_OLE_UNKNOWN(cls)\
private:\
class TAutoInitInt\
if (! ppvObject)\
{\
return E_FAIL;\
- };\
+ }\
const char *desc = NULL;\
cls::_GetInterface(this, iid, ppvObject, desc);\
if (! *ppvObject)\
{\
return E_NOINTERFACE;\
- };\
+ }\
((IUnknown * )(*ppvObject))->AddRef();\
return S_OK;\
- };\
+ }\
ULONG STDMETHODCALLTYPE cls::AddRef()\
{\
InterlockedIncrement(&refCount.l);\
return refCount.l;\
- };\
+ }\
ULONG STDMETHODCALLTYPE cls::Release()\
{\
if (refCount.l > 0)\
{\
delete this;\
return 0;\
- };\
+ }\
return refCount.l;\
}\
else\
{\
InterlockedIncrement(&lockCount.l);\
return lockCount.l;\
- };\
+ }\
ULONG STDMETHODCALLTYPE cls::ReleaseLock()\
{\
if (lockCount.l > 0)\
#define END_OLE_TABLE\
}
+// ============================================================================
+// implementation
+// ============================================================================
+
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// PixelsToHimetric
+//
+// Utility to convert from pixels to the himetric values in some COM methods
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+
+#define HIMETRIC_PER_INCH 2540
+#define MAP_PIX_TO_LOGHIM(x,ppli) MulDiv(HIMETRIC_PER_INCH, (x), (ppli))
+
+static void PixelsToHimetric(SIZEL &sz)
+{
+ static int logX = 0;
+ static int logY = 0;
+
+ if (logY == 0)
+ {
+ // initaliase
+ HDC dc = GetDC(NULL);
+ logX = GetDeviceCaps(dc, LOGPIXELSX);
+ logY = GetDeviceCaps(dc, LOGPIXELSY);
+ ReleaseDC(NULL, dc);
+ };
+
+#define HIMETRIC_INCH 2540
+#define CONVERT(x, logpixels) wxMulDivInt32(HIMETRIC_INCH, (x), (logpixels))
+
+ sz.cx = CONVERT(sz.cx, logX);
+ sz.cy = CONVERT(sz.cy, logY);
+
+#undef CONVERT
+#undef HIMETRIC_INCH
+}
+
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//
+// FrameSite
+//
+// Handles the actual wxActiveX container implementation
+//
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class FrameSite :
public IOleClientSite,
public IOleInPlaceSiteEx,
if (! SUCCEEDED(hr))
{
return E_UNEXPECTED;
- };
+ }
hr = QueryInterface(IID_IOleInPlaceUIWindow, (void **) ppDoc);
if (! SUCCEEDED(hr))
(*ppFrame)->Release();
*ppFrame = NULL;
return E_UNEXPECTED;
- };
+ }
RECT rect;
::GetClientRect(m_hWndParent, &rect);
lprcPosRect->left = lprcPosRect->top = 0;
lprcPosRect->right = rect.right;
lprcPosRect->bottom = rect.bottom;
- };
+ }
if (lprcClipRect)
{
lprcClipRect->left = lprcClipRect->top = 0;
lprcClipRect->right = rect.right;
lprcClipRect->bottom = rect.bottom;
- };
+ }
memset(lpFrameInfo, 0, sizeof(OLEINPLACEFRAMEINFO));
lpFrameInfo->cb = sizeof(OLEINPLACEFRAMEINFO);
{
if (m_window->m_oleInPlaceObject.Ok() && lprcPosRect)
{
+ //
+ // Result of several hours and days of bug hunting -
+ // this is called by an object when it wants to resize
+ // itself to something different then our parent window -
+ // don't let it :)
+ //
+// m_window->m_oleInPlaceObject->SetObjectRects(
+// lprcPosRect, lprcPosRect);
+ RECT rcClient;
+ ::GetClientRect(m_hWndParent, &rcClient);
m_window->m_oleInPlaceObject->SetObjectRects(
- lprcPosRect, lprcPosRect);
+ &rcClient, &rcClient);
}
return S_OK;
}
//*************************IOleInPlaceSiteEx***********************
HRESULT STDMETHODCALLTYPE OnInPlaceActivateEx(BOOL * pfNoRedraw, DWORD)
{
+#ifdef __WXWINCE__
+ IRunnableObject* runnable = NULL;
+ HRESULT hr = QueryInterface(
+ IID_IRunnableObject, (void**)(& runnable));
+ if (SUCCEEDED(hr))
+ {
+ runnable->LockRunning(TRUE, FALSE);
+ }
+#else
OleLockRunning(m_window->m_ActiveX, TRUE, FALSE);
+#endif
if (pfNoRedraw)
(*pfNoRedraw) = FALSE;
return S_OK;
HRESULT STDMETHODCALLTYPE OnInPlaceDeactivateEx(BOOL)
{
+#ifdef __WXWINCE__
+ IRunnableObject* runnable = NULL;
+ HRESULT hr = QueryInterface(
+ IID_IRunnableObject, (void**)(& runnable));
+ if (SUCCEEDED(hr))
+ {
+ runnable->LockRunning(FALSE, FALSE);
+ }
+#else
OleLockRunning(m_window->m_ActiveX, FALSE, FALSE);
+#endif
return S_OK;
}
STDMETHOD(RequestUIActivate)(){ return S_OK;}
case OLEGETMONIKER_UNASSIGN : return "OLEGETMONIKER_UNASSIGN";
case OLEGETMONIKER_TEMPFORUSER : return "OLEGETMONIKER_TEMPFORUSER";
default : return "Bad Enum";
- };
- };
+ }
+ }
const char *OleGetWhicMonikerStr(DWORD dwWhichMoniker)
{
case OLEWHICHMK_OBJREL : return "OLEWHICHMK_OBJREL";
case OLEWHICHMK_OBJFULL : return "OLEWHICHMK_OBJFULL";
default : return "Bad Enum";
- };
- };
+ }
+ }
STDMETHOD(GetMoniker)(DWORD, DWORD, IMoniker **){return E_FAIL;}
HRESULT STDMETHODCALLTYPE GetContainer(LPOLECONTAINER * ppContainer)
{
HRESULT STDMETHODCALLTYPE LockContainer(BOOL){return S_OK;}
//********************IOleItemContainer***************************
HRESULT STDMETHODCALLTYPE
- #ifdef _UNICODE
+ #if 0 // defined(__WXWINCE__) && __VISUALC__ < 1400
+ GetObject
+ #elif defined(_UNICODE)
GetObjectW
#else
GetObjectA
return E_FAIL;
m_window->m_docView->SetInPlaceSite(inPlaceSite);
- };
+ }
m_window->m_docView->UIActivate(TRUE);
return S_OK;
- };
+ }
protected:
OLE_IINTERFACE(IOleDocumentSite)
OLE_IINTERFACE(IAdviseSink)
OLE_IINTERFACE(IOleControlSite)
-END_OLE_TABLE;
+END_OLE_TABLE
+
+
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//
+// wxActiveXEvents
+//
+// Handles and sends activex events received from the ActiveX control
+// to the appropriate wxEvtHandler
+//
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+class wxActiveXEvents : public IDispatch
+{
+private:
+ DECLARE_OLE_UNKNOWN(wxActiveXEvents);
+
+
+ wxActiveXContainer *m_activeX;
+ IID m_customId;
+ bool m_haveCustomId;
+
+ friend bool wxActiveXEventsInterface(wxActiveXEvents *self, REFIID iid, void **_interface, const char *&desc);
+
+public:
+
+ // a pointer to this static variable is used as an 'invalid_entry_marker'
+ // wxVariants containing a void* to this variables are 'empty' in the sense
+ // that the actual ActiveX OLE parameter has not been converted and inserted
+ // into m_params.
+ static wxVariant ms_invalidEntryMarker;
+
+ wxActiveXEvents(wxActiveXContainer *ax) : m_activeX(ax), m_haveCustomId(false) {}
+ wxActiveXEvents(wxActiveXContainer *ax, REFIID iid) : m_activeX(ax), m_customId(iid), m_haveCustomId(true) {}
+ virtual ~wxActiveXEvents()
+ {
+ }
+
+ // IDispatch
+ STDMETHODIMP GetIDsOfNames(REFIID, OLECHAR**, unsigned int, LCID, DISPID*)
+ {
+ return E_NOTIMPL;
+ }
+
+ STDMETHODIMP GetTypeInfo(unsigned int, LCID, ITypeInfo**)
+ {
+ return E_NOTIMPL;
+ }
+
+ STDMETHODIMP GetTypeInfoCount(unsigned int*)
+ {
+ return E_NOTIMPL;
+ }
+
+
+ STDMETHODIMP Invoke(DISPID dispIdMember, REFIID riid,
+ LCID lcid,
+ WORD wFlags, DISPPARAMS * pDispParams,
+ VARIANT * pVarResult, EXCEPINFO * pExcepInfo,
+ unsigned int * puArgErr)
+ {
+ if (wFlags & (DISPATCH_PROPERTYGET | DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYPUTREF))
+ return E_NOTIMPL;
+
+ wxASSERT(m_activeX);
+
+ // ActiveX Event
+
+ // Dispatch Event
+ wxActiveXEvent event;
+ event.SetEventType(wxEVT_ACTIVEX);
+ // Create an empty list of Variants
+ // Note that the event parameters use lazy evaluation
+ // They are not actually created until wxActiveXEvent::operator[] is called
+ event.m_params.NullList();
+ event.m_dispid = dispIdMember;
+
+ // save the native (MSW) event parameters for event handlers that need to access them
+ // this can be done on the stack since wxActiveXEvent is also allocated on the stack
+ wxActiveXEventNativeMSW eventParameters(dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
+ event.SetClientData(&eventParameters);
+
+ // The event parameters are not copied to event.m_params until they are actually
+ // referenced in wxActiveXEvent::operator[]
+ // This increases performance and avoids error messages and/or crashes
+ // when the event has parameters that are not (yet or never) supported
+ // by wxConvertOleToVariant
+
+ // process the events from the activex method
+ m_activeX->ProcessEvent(event);
+ for (DWORD i = 0; i < pDispParams->cArgs; i++)
+ {
+ size_t params_index = pDispParams->cArgs - i - 1;
+ if (params_index < event.m_params.GetCount()) {
+ wxVariant &vx = event.m_params[params_index];
+ // copy the result back to pDispParams only if the event has been accessed
+ // i.e. if vx != ms_invalidEntryMarker
+ if (!vx.IsType(wxActiveXEvents::ms_invalidEntryMarker.GetType()) || vx!=ms_invalidEntryMarker) {
+ VARIANTARG& va = pDispParams->rgvarg[i];
+ wxConvertVariantToOle(vx, va);
+ }
+ }
+ }
+
+ if(event.GetSkipped())
+ return DISP_E_MEMBERNOTFOUND;
+
+ return S_OK;
+ }
+};
+
+namespace
+{
+// just a unique global variable
+const int invalid_entry_marker = 0;
+}
+wxVariant wxActiveXEvents::ms_invalidEntryMarker((void*)&invalid_entry_marker);
-wxActiveXContainer::wxActiveXContainer(wxWindow * parent, REFIID iid, IUnknown* pUnk)
+size_t wxActiveXEvent::ParamCount() const
+{
+ wxActiveXEventNativeMSW *native=GetNativeParameters();
+ // 'native' will always be != if the event has been created
+ // for an actual active X event.
+ // But it may be zero if the event has been created by wx program code.
+ if (native)
+ return native->pDispParams ? native->pDispParams->cArgs : 0;
+
+ return m_params.GetCount();
+}
+
+wxVariant &wxActiveXEvent::operator [](size_t idx)
+{
+ wxASSERT(idx < ParamCount());
+ wxActiveXEventNativeMSW *native=GetNativeParameters();
+ // 'native' will always be != if the event has been created
+ // for an actual active X event.
+ // But it may be zero if the event has been created by wx program code.
+ if (native)
+ {
+ while ( m_params.GetCount()<=idx )
+ {
+ m_params.Append(wxActiveXEvents::ms_invalidEntryMarker);
+ }
+
+ wxVariant& vx = m_params[idx];
+ if ( vx.IsType(wxActiveXEvents::ms_invalidEntryMarker.GetType()) &&
+ vx == wxActiveXEvents::ms_invalidEntryMarker)
+ {
+ // copy the _real_ parameter into this one
+ // NOTE: m_params stores the parameters in *reverse* order.
+ // Whyever, but this was the case in the original implementation of
+ // wxActiveXEvents::Invoke
+ // Keep this convention.
+ VARIANTARG& va = native->pDispParams->rgvarg[ native->pDispParams->cArgs - idx - 1 ];
+ wxConvertOleToVariant(va, vx);
+ }
+ return vx;
+ }
+ return m_params[idx];
+}
+
+bool wxActiveXEventsInterface(wxActiveXEvents *self, REFIID iid, void **_interface, const char *&desc)
+{
+ if (self->m_haveCustomId && IsEqualIID(iid, self->m_customId))
+ {
+ *_interface = (IUnknown *) (IDispatch *) self;
+ desc = "Custom Dispatch Interface";
+ return true;
+ }
+
+ return false;
+}
+
+DEFINE_OLE_TABLE(wxActiveXEvents)
+ OLE_IINTERFACE(IUnknown)
+ OLE_INTERFACE(IID_IDispatch, IDispatch)
+ OLE_INTERFACE_CUSTOM(wxActiveXEventsInterface)
+END_OLE_TABLE
+
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//
+// wxActiveXContainer
+//
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+//---------------------------------------------------------------------------
+// wxActiveXContainer Constructor
+//
+// Initializes members and creates the native ActiveX container
+//---------------------------------------------------------------------------
+wxActiveXContainer::wxActiveXContainer(wxWindow * parent,
+ REFIID iid, IUnknown* pUnk)
: m_realparent(parent)
{
m_bAmbientUserMode = true;
CreateActiveX(iid, pUnk);
}
+//---------------------------------------------------------------------------
+// wxActiveXContainer Destructor
+//
+// Destroys members (the FrameSite et al. are destroyed implicitly
+// through COM ref counting)
+//---------------------------------------------------------------------------
wxActiveXContainer::~wxActiveXContainer()
{
// disconnect connection points
m_oleObject->Close(OLECLOSE_NOSAVE);
m_oleObject->SetClientSite(NULL);
}
+
+ // m_clientSite uses m_frameSite so destroy it first
+ m_clientSite.Free();
+ delete m_frameSite;
+
+ // our window doesn't belong to us, don't destroy it
+ m_hWnd = NULL;
}
+// VZ: we might want to really report an error instead of just asserting here
+#if wxDEBUG_LEVEL
+ #define CHECK_HR(hr) \
+ wxASSERT_LEVEL_2_MSG( SUCCEEDED(hr), \
+ wxString::Format("HRESULT = %X", (unsigned)(hr)) )
+#else
+ #define CHECK_HR(hr) wxUnusedVar(hr)
+#endif
+
+//---------------------------------------------------------------------------
+// wxActiveXContainer::CreateActiveX
+//
+// Actually creates the ActiveX container through the FrameSite
+// and sets up ActiveX events
+//
+// TODO: Document this more
+//---------------------------------------------------------------------------
void wxActiveXContainer::CreateActiveX(REFIID iid, IUnknown* pUnk)
{
HRESULT hret;
hret = m_ActiveX.QueryInterface(iid, pUnk);
- wxASSERT(SUCCEEDED(hret));
+ CHECK_HR(hret);
// FrameSite
- FrameSite *frame = new FrameSite(m_realparent, this);
+ m_frameSite = new FrameSite(m_realparent, this);
// oleClientSite
hret = m_clientSite.QueryInterface(
- IID_IOleClientSite, (IDispatch *) frame);
- wxASSERT(SUCCEEDED(hret));
+ IID_IOleClientSite, (IDispatch *) m_frameSite);
+ CHECK_HR(hret);
// adviseSink
- wxAutoIAdviseSink adviseSink(IID_IAdviseSink, (IDispatch *) frame);
+ wxAutoIAdviseSink adviseSink(IID_IAdviseSink, (IDispatch *) m_frameSite);
wxASSERT(adviseSink.Ok());
// Get Dispatch interface
hret = m_Dispatch.QueryInterface(IID_IDispatch, m_ActiveX);
+ CHECK_HR(hret);
+
+ //
+ // SETUP TYPEINFO AND ACTIVEX EVENTS
+ //
+
+ // get type info via class info
+ wxAutoIProvideClassInfo classInfo(IID_IProvideClassInfo, m_ActiveX);
+ wxASSERT(classInfo.Ok());
+
+ // type info
+ wxAutoITypeInfo typeInfo;
+ hret = classInfo->GetClassInfo(typeInfo.GetRef());
+ CHECK_HR(hret);
+ wxASSERT(typeInfo.Ok());
+
+ // TYPEATTR
+ TYPEATTR *ta = NULL;
+ hret = typeInfo->GetTypeAttr(&ta);
+ CHECK_HR(hret);
+
+ // this should be a TKIND_COCLASS
+ wxASSERT(ta->typekind == TKIND_COCLASS);
+
+ // iterate contained interfaces
+ for (int i = 0; i < ta->cImplTypes; i++)
+ {
+ HREFTYPE rt = 0;
+
+ // get dispatch type info handle
+ hret = typeInfo->GetRefTypeOfImplType(i, &rt);
+ if (! SUCCEEDED(hret))
+ continue;
+
+ // get dispatch type info interface
+ wxAutoITypeInfo ti;
+ hret = typeInfo->GetRefTypeInfo(rt, ti.GetRef());
+ if (! ti.Ok())
+ continue;
+
+ CHECK_HR(hret);
+
+ // check if default event sink
+ bool defEventSink = false;
+ int impTypeFlags = 0;
+ typeInfo->GetImplTypeFlags(i, &impTypeFlags);
+
+ if (impTypeFlags & IMPLTYPEFLAG_FDEFAULT)
+ {
+ if (impTypeFlags & IMPLTYPEFLAG_FSOURCE)
+ {
+ // WXOLE_TRACEOUT("Default Event Sink");
+ defEventSink = true;
+ if (impTypeFlags & IMPLTYPEFLAG_FDEFAULTVTABLE)
+ {
+ // WXOLE_TRACEOUT("*ERROR* - Default Event Sink is via vTable");
+ defEventSink = false;
+ wxFAIL_MSG(wxT("Default event sink is in vtable!"));
+ }
+ }
+ }
+
+
+ // wxAutoOleInterface<> assumes a ref has already been added
+ // TYPEATTR
+ TYPEATTR *ta = NULL;
+ hret = ti->GetTypeAttr(&ta);
+ CHECK_HR(hret);
+
+ if (ta->typekind == TKIND_DISPATCH)
+ {
+ // WXOLE_TRACEOUT("GUID = " << GetIIDName(ta->guid).c_str());
+ if (defEventSink)
+ {
+ wxAutoIConnectionPoint cp;
+ DWORD adviseCookie = 0;
+
+ wxAutoIConnectionPointContainer cpContainer(IID_IConnectionPointContainer, m_ActiveX);
+ wxASSERT( cpContainer.Ok());
+
+ HRESULT hret =
+ cpContainer->FindConnectionPoint(ta->guid, cp.GetRef());
+ CHECK_HR(hret);
+
+ if ( cp )
+ {
+ IDispatch* disp;
+ m_frameSite->QueryInterface(IID_IDispatch, (void**)&disp);
+ hret = cp->Advise(new wxActiveXEvents(this, ta->guid),
+ &adviseCookie);
+ CHECK_HR(hret);
+ }
+ }
+ }
+
+ ti->ReleaseTypeAttr(ta);
+ }
+
+ // free
+ typeInfo->ReleaseTypeAttr(ta);
+
+ //
+ // END
+ //
// Get IOleObject interface
hret = m_oleObject.QueryInterface(IID_IOleObject, m_ActiveX);
- wxASSERT(SUCCEEDED(hret));
+ CHECK_HR(hret);
// get IViewObject Interface
hret = m_viewObject.QueryInterface(IID_IViewObject, m_ActiveX);
- wxASSERT(SUCCEEDED(hret));
+ CHECK_HR(hret);
// document advise
m_docAdviseCookie = 0;
hret = m_oleObject->Advise(adviseSink, &m_docAdviseCookie);
+ CHECK_HR(hret);
+
+ // TODO:Needed?
+// hret = m_viewObject->SetAdvise(DVASPECT_CONTENT, 0, adviseSink);
m_oleObject->SetHostNames(L"wxActiveXContainer", NULL);
OleSetContainedObject(m_oleObject, TRUE);
OleRun(m_oleObject);
// Get IOleInPlaceObject interface
hret = m_oleInPlaceObject.QueryInterface(
IID_IOleInPlaceObject, m_ActiveX);
- wxASSERT(SUCCEEDED(hret));
+ CHECK_HR(hret);
// status
DWORD dwMiscStatus;
m_oleObject->GetMiscStatus(DVASPECT_CONTENT, &dwMiscStatus);
- wxASSERT(SUCCEEDED(hret));
+ CHECK_HR(hret);
// set client site first ?
if (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST)
if (pPersistStreamInit.Ok())
{
hret = pPersistStreamInit->InitNew();
+ CHECK_HR(hret);
}
if (! (dwMiscStatus & OLEMISC_SETCLIENTSITEFIRST))
m_oleObject->SetClientSite(m_clientSite);
- RECT posRect;
- ::GetClientRect((HWND)m_realparent->GetHWND(), &posRect);
-
m_oleObjectHWND = 0;
if (m_oleInPlaceObject.Ok())
if (! (dwMiscStatus & OLEMISC_INVISIBLEATRUNTIME))
{
+ RECT posRect;
+ wxCopyRectToRECT(m_realparent->GetClientSize(), posRect);
+
if (posRect.right > 0 && posRect.bottom > 0 &&
m_oleInPlaceObject.Ok())
- m_oleInPlaceObject->SetObjectRects(&posRect, &posRect);
+ {
+ m_oleInPlaceObject->SetObjectRects(&posRect, &posRect);
+ }
hret = m_oleObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL,
m_clientSite, 0, (HWND)m_realparent->GetHWND(), &posRect);
+ CHECK_HR(hret);
+
hret = m_oleObject->DoVerb(OLEIVERB_SHOW, 0, m_clientSite, 0,
(HWND)m_realparent->GetHWND(), &posRect);
+ CHECK_HR(hret);
}
if (! m_oleObjectHWND && m_oleInPlaceObject.Ok())
{
hret = m_oleInPlaceObject->GetWindow(&m_oleObjectHWND);
+ CHECK_HR(hret);
}
if (m_oleObjectHWND)
pWnd->Connect(id, wxEVT_SIZE,
wxSizeEventHandler(wxActiveXContainer::OnSize), 0, this);
+// this->Connect(GetId(), wxEVT_PAINT,
+// wxPaintEventHandler(wxActiveXContainer::OnPaint), 0, this);
pWnd->Connect(id, wxEVT_SET_FOCUS,
wxFocusEventHandler(wxActiveXContainer::OnSetFocus), 0, this);
pWnd->Connect(id, wxEVT_KILL_FOCUS,
}
}
-#define HIMETRIC_PER_INCH 2540
-#define MAP_PIX_TO_LOGHIM(x,ppli) MulDiv(HIMETRIC_PER_INCH, (x), (ppli))
-
-static void PixelsToHimetric(SIZEL &sz)
-{
- static int logX = 0;
- static int logY = 0;
-
- if (logY == 0)
- {
- // initaliase
- HDC dc = GetDC(NULL);
- logX = GetDeviceCaps(dc, LOGPIXELSX);
- logY = GetDeviceCaps(dc, LOGPIXELSY);
- ReleaseDC(NULL, dc);
- };
-
-#define HIMETRIC_INCH 2540
-#define CONVERT(x, logpixels) MulDiv(HIMETRIC_INCH, (x), (logpixels))
-
- sz.cx = CONVERT(sz.cx, logX);
- sz.cy = CONVERT(sz.cy, logY);
-
-#undef CONVERT
-#undef HIMETRIC_INCH
-}
-
-
+//---------------------------------------------------------------------------
+// wxActiveXContainer::OnSize
+//
+// Called when the parent is resized - we need to do this to actually
+// move the ActiveX control to where the parent is
+//---------------------------------------------------------------------------
void wxActiveXContainer::OnSize(wxSizeEvent& event)
{
int w, h;
// extents are in HIMETRIC units
if (m_oleObject.Ok())
{
+ m_oleObject->DoVerb(OLEIVERB_HIDE, 0, m_clientSite, 0,
+ (HWND)m_realparent->GetHWND(), &posRect);
+
SIZEL sz = {w, h};
PixelsToHimetric(sz);
m_oleObject->GetExtent(DVASPECT_CONTENT, &sz2);
if (sz2.cx != sz.cx || sz.cy != sz2.cy)
m_oleObject->SetExtent(DVASPECT_CONTENT, &sz);
- };
+
+ m_oleObject->DoVerb(OLEIVERB_SHOW, 0, m_clientSite, 0,
+ (HWND)m_realparent->GetHWND(), &posRect);
+ }
if (m_oleInPlaceObject.Ok())
m_oleInPlaceObject->SetObjectRects(&posRect, &posRect);
event.Skip();
}
+//---------------------------------------------------------------------------
+// wxActiveXContainer::OnPaint
+//
+// Called when the parent is resized - repaints the ActiveX control
+//---------------------------------------------------------------------------
void wxActiveXContainer::OnPaint(wxPaintEvent& WXUNUSED(event))
{
wxPaintDC dc(this);
// Draw only when control is windowless or deactivated
if (m_viewObject)
{
- dc.BeginDrawing();
int w, h;
GetParent()->GetSize(&w, &h);
RECT posRect;
posRect.right = w;
posRect.bottom = h;
+#if !(defined(_WIN32_WCE) && _WIN32_WCE < 400)
::RedrawWindow(m_oleObjectHWND, NULL, NULL, RDW_INTERNALPAINT);
+#else
+ ::InvalidateRect(m_oleObjectHWND, NULL, false);
+#endif
RECTL *prcBounds = (RECTL *) &posRect;
+ wxMSWDCImpl *msw = wxDynamicCast( dc.GetImpl() , wxMSWDCImpl );
m_viewObject->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL,
- (HDC)dc.GetHDC(), prcBounds, NULL, NULL, 0);
-
- dc.EndDrawing();
+ (HDC)msw->GetHDC(), prcBounds, NULL, NULL, 0);
}
-
-// We've got this one I think
-// event.Skip();
}
+//---------------------------------------------------------------------------
+// wxActiveXContainer::OnSetFocus
+//
+// Called when the focus is set on the parent - activates the activex control
+//---------------------------------------------------------------------------
void wxActiveXContainer::OnSetFocus(wxFocusEvent& event)
{
if (m_oleInPlaceActiveObject.Ok())
event.Skip();
}
+//---------------------------------------------------------------------------
+// wxActiveXContainer::OnKillFocus
+//
+// Called when the focus is killed on the parent -
+// deactivates the activex control
+//---------------------------------------------------------------------------
void wxActiveXContainer::OnKillFocus(wxFocusEvent& event)
{
if (m_oleInPlaceActiveObject.Ok())
event.Skip();
}
+
+#endif // wxUSE_ACTIVEX