📄 activex.cpp
字号:
/////////////////////////////////////////////////////////////////////////////
// Name: src/msw/ole/activex.cpp
// Purpose: wxActiveXContainer implementation
// Author: Ryan Norton <wxprojects@comcast.net>, Lindsay Mathieson <???>
// Modified by:
// Created: 11/07/04
// RCS-ID: $Id: activex.cpp,v 1.23 2006/06/15 17:58:46 ABX Exp $
// Copyright: (c) 2003 Lindsay Mathieson, (c) 2005 Ryan Norton
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/dcclient.h"
#include "wx/math.h"
#endif
// I don't know why members of tagVARIANT aren't found when compiling
// with Wine
#ifndef __WINE__
#include "wx/msw/ole/activex.h"
// autointerfaces that we only use here
WX_DECLARE_AUTOOLE(wxAutoIOleInPlaceSite, IOleInPlaceSite)
WX_DECLARE_AUTOOLE(wxAutoIOleDocument, IOleDocument)
WX_DECLARE_AUTOOLE(wxAutoIPersistStreamInit, IPersistStreamInit)
WX_DECLARE_AUTOOLE(wxAutoIAdviseSink, IAdviseSink)
WX_DECLARE_AUTOOLE(wxAutoIProvideClassInfo, IProvideClassInfo)
WX_DECLARE_AUTOOLE(wxAutoITypeInfo, ITypeInfo)
WX_DECLARE_AUTOOLE(wxAutoIConnectionPoint, IConnectionPoint)
WX_DECLARE_AUTOOLE(wxAutoIConnectionPointContainer, IConnectionPointContainer)
DEFINE_EVENT_TYPE(wxEVT_ACTIVEX)
// Ole class helpers (sort of MFC-like) from wxActiveX
#define DECLARE_OLE_UNKNOWN(cls)\
private:\
class TAutoInitInt\
{\
public:\
LONG l;\
TAutoInitInt() : l(0) {}\
};\
TAutoInitInt refCount, lockCount;\
static void _GetInterface(cls *self, REFIID iid, void **_interface, const char *&desc);\
public:\
LONG GetRefCount();\
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void ** ppvObject);\
ULONG STDMETHODCALLTYPE AddRef();\
ULONG STDMETHODCALLTYPE Release();\
ULONG STDMETHODCALLTYPE AddLock();\
ULONG STDMETHODCALLTYPE ReleaseLock()
#define DEFINE_OLE_TABLE(cls)\
LONG cls::GetRefCount() {return refCount.l;}\
HRESULT STDMETHODCALLTYPE cls::QueryInterface(REFIID iid, void ** ppvObject)\
{\
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)\
{\
InterlockedDecrement(&refCount.l);\
if (refCount.l == 0)\
{\
delete this;\
return 0;\
}\
return refCount.l;\
}\
else\
return 0;\
}\
ULONG STDMETHODCALLTYPE cls::AddLock()\
{\
InterlockedIncrement(&lockCount.l);\
return lockCount.l;\
}\
ULONG STDMETHODCALLTYPE cls::ReleaseLock()\
{\
if (lockCount.l > 0)\
{\
InterlockedDecrement(&lockCount.l);\
return lockCount.l;\
}\
else\
return 0;\
}\
DEFINE_OLE_BASE(cls)
#define DEFINE_OLE_BASE(cls)\
void cls::_GetInterface(cls *self, REFIID iid, void **_interface, const char *&desc)\
{\
*_interface = NULL;\
desc = NULL;
#define OLE_INTERFACE(_iid, _type)\
if (IsEqualIID(iid, _iid))\
{\
*_interface = (IUnknown *) (_type *) self;\
desc = # _iid;\
return;\
}
#define OLE_IINTERFACE(_face) OLE_INTERFACE(IID_##_face, _face)
#define OLE_INTERFACE_CUSTOM(func)\
if (func(self, iid, _interface, desc))\
{\
return;\
}
#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,
public IOleInPlaceFrame,
public IOleItemContainer,
public IDispatch,
public IOleCommandTarget,
public IOleDocumentSite,
public IAdviseSink,
public IOleControlSite
{
private:
DECLARE_OLE_UNKNOWN(FrameSite);
public:
FrameSite(wxWindow * win, wxActiveXContainer * win2)
{
m_window = win2;
m_bSupportsWindowlessActivation = true;
m_bInPlaceLocked = false;
m_bUIActive = false;
m_bInPlaceActive = false;
m_bWindowless = false;
m_nAmbientLocale = 0;
m_clrAmbientForeColor = ::GetSysColor(COLOR_WINDOWTEXT);
m_clrAmbientBackColor = ::GetSysColor(COLOR_WINDOW);
m_bAmbientShowHatching = true;
m_bAmbientShowGrabHandles = true;
m_bAmbientAppearance = true;
m_hDCBuffer = NULL;
m_hWndParent = (HWND)win->GetHWND();
}
virtual ~FrameSite(){}
//***************************IDispatch*****************************
HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID, OLECHAR ** ,
unsigned int , LCID ,
DISPID * )
{ return E_NOTIMPL; }
STDMETHOD(GetTypeInfo)(unsigned int, LCID, ITypeInfo **)
{ return E_NOTIMPL; }
HRESULT STDMETHODCALLTYPE GetTypeInfoCount(unsigned int *)
{ return E_NOTIMPL; }
HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID, LCID,
WORD wFlags, DISPPARAMS *,
VARIANT * pVarResult, EXCEPINFO *,
unsigned int *)
{
if (!(wFlags & DISPATCH_PROPERTYGET))
return S_OK;
if (pVarResult == NULL)
return E_INVALIDARG;
//The most common case is boolean, use as an initial type
V_VT(pVarResult) = VT_BOOL;
switch (dispIdMember)
{
case DISPID_AMBIENT_MESSAGEREFLECT:
V_BOOL(pVarResult)= FALSE;
return S_OK;
case DISPID_AMBIENT_DISPLAYASDEFAULT:
V_BOOL(pVarResult)= TRUE;
return S_OK;
case DISPID_AMBIENT_OFFLINEIFNOTCONNECTED:
V_BOOL(pVarResult) = TRUE;
return S_OK;
case DISPID_AMBIENT_SILENT:
V_BOOL(pVarResult)= TRUE;
return S_OK;
case DISPID_AMBIENT_APPEARANCE:
pVarResult->vt = VT_BOOL;
pVarResult->boolVal = m_bAmbientAppearance;
break;
case DISPID_AMBIENT_FORECOLOR:
pVarResult->vt = VT_I4;
pVarResult->lVal = (long) m_clrAmbientForeColor;
break;
case DISPID_AMBIENT_BACKCOLOR:
pVarResult->vt = VT_I4;
pVarResult->lVal = (long) m_clrAmbientBackColor;
break;
case DISPID_AMBIENT_LOCALEID:
pVarResult->vt = VT_I4;
pVarResult->lVal = (long) m_nAmbientLocale;
break;
case DISPID_AMBIENT_USERMODE:
pVarResult->vt = VT_BOOL;
pVarResult->boolVal = m_window->m_bAmbientUserMode;
break;
case DISPID_AMBIENT_SHOWGRABHANDLES:
pVarResult->vt = VT_BOOL;
pVarResult->boolVal = m_bAmbientShowGrabHandles;
break;
case DISPID_AMBIENT_SHOWHATCHING:
pVarResult->vt = VT_BOOL;
pVarResult->boolVal = m_bAmbientShowHatching;
break;
default:
return DISP_E_MEMBERNOTFOUND;
}
return S_OK;
}
//**************************IOleWindow***************************
HRESULT STDMETHODCALLTYPE GetWindow(HWND * phwnd)
{
if (phwnd == NULL)
return E_INVALIDARG;
(*phwnd) = m_hWndParent;
return S_OK;
}
HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL)
{return S_OK;}
//**************************IOleInPlaceUIWindow*****************
HRESULT STDMETHODCALLTYPE GetBorder(LPRECT lprectBorder)
{
if (lprectBorder == NULL)
return E_INVALIDARG;
return INPLACE_E_NOTOOLSPACE;
}
HRESULT STDMETHODCALLTYPE RequestBorderSpace(LPCBORDERWIDTHS pborderwidths)
{
if (pborderwidths == NULL)
return E_INVALIDARG;
return INPLACE_E_NOTOOLSPACE;
}
HRESULT STDMETHODCALLTYPE SetBorderSpace(LPCBORDERWIDTHS)
{return S_OK;}
HRESULT STDMETHODCALLTYPE SetActiveObject(
IOleInPlaceActiveObject *pActiveObject, LPCOLESTR)
{
if (pActiveObject)
pActiveObject->AddRef();
m_window->m_oleInPlaceActiveObject = pActiveObject;
return S_OK;
}
//********************IOleInPlaceFrame************************
STDMETHOD(InsertMenus)(HMENU, LPOLEMENUGROUPWIDTHS){return S_OK;}
STDMETHOD(SetMenu)(HMENU, HOLEMENU, HWND){ return S_OK;}
STDMETHOD(RemoveMenus)(HMENU){return S_OK;}
STDMETHOD(SetStatusText)(LPCOLESTR){ return S_OK;}
HRESULT STDMETHODCALLTYPE EnableModeless(BOOL){return S_OK;}
HRESULT STDMETHODCALLTYPE TranslateAccelerator(LPMSG lpmsg, WORD)
{
// TODO: send an event with this id
if (m_window->m_oleInPlaceActiveObject.Ok())
m_window->m_oleInPlaceActiveObject->TranslateAccelerator(lpmsg);
return S_FALSE;
}
//*******************IOleInPlaceSite**************************
HRESULT STDMETHODCALLTYPE CanInPlaceActivate(){return S_OK;}
HRESULT STDMETHODCALLTYPE OnInPlaceActivate()
{ m_bInPlaceActive = true; return S_OK; }
HRESULT STDMETHODCALLTYPE OnUIActivate()
{ m_bUIActive = true; return S_OK; }
HRESULT STDMETHODCALLTYPE GetWindowContext(IOleInPlaceFrame **ppFrame,
IOleInPlaceUIWindow **ppDoc,
LPRECT lprcPosRect,
LPRECT lprcClipRect,
LPOLEINPLACEFRAMEINFO lpFrameInfo)
{
if (ppFrame == NULL || ppDoc == NULL || lprcPosRect == NULL ||
lprcClipRect == NULL || lpFrameInfo == NULL)
{
if (ppFrame != NULL)
(*ppFrame) = NULL;
if (ppDoc != NULL)
(*ppDoc) = NULL;
return E_INVALIDARG;
}
HRESULT hr = QueryInterface(IID_IOleInPlaceFrame, (void **) ppFrame);
if (! SUCCEEDED(hr))
{
return E_UNEXPECTED;
}
hr = QueryInterface(IID_IOleInPlaceUIWindow, (void **) ppDoc);
if (! SUCCEEDED(hr))
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -