📄 activex.i
字号:
/////////////////////////////////////////////////////////////////////////////
// Name: activex.i
// Purpose: ActiveX controls (such as Internet Explorer) in a wxWindow
//
// Author: Robin Dunn
//
// Created: 18-Mar-2004
// RCS-ID: $Id: activex.i,v 1.16 2006/05/19 01:10:46 RD Exp $
// Copyright: (c) 2004 by Total Control Software
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
%module(package="wx") activex
%{
#include "wx/wxPython/wxPython.h"
#include "wx/wxPython/pyclasses.h"
#include "wx/wxPython/pyistream.h"
#include "wxactivex.h"
%}
//---------------------------------------------------------------------------
%import core.i
%pythoncode { wx = _core }
%pythoncode { __docfilter__ = wx.__DocFilter(globals()) }
MAKE_CONST_WXSTRING_NOSWIG(PanelNameStr);
//---------------------------------------------------------------------------
typedef unsigned short USHORT;
typedef long DISPID;
typedef long MEMBERID;
typedef unsigned short VARTYPE;
%{
// Since SWIG doesn't support nested classes, we need to fool it a bit
// and make them look like global classes. These defines make the C++ code
// know what we are doing.
#define wxParamX wxActiveX::ParamX
#define wxFuncX wxActiveX::FuncX
#define wxPropX wxActiveX::PropX
#define wxParamXArray wxActiveX::ParamXArray
#define wxFuncXArray wxActiveX::FuncXArray
#define wxPropXArray wxActiveX::PropXArray
%}
%{
// Some conversion helpers
static wxVariant _PyObj2Variant(PyObject* value);
static bool _PyObj2Variant(PyObject* value, wxVariant& wv);
static PyObject* _Variant2PyObj(wxVariant& value, bool useNone=false);
static wxString _VARTYPEname(VARTYPE vt);
// Check if an exception has been raised (blocking threads)
inline bool wxPyErr_Occurred()
{
bool rval;
wxPyBlock_t blocked = wxPyBeginBlockThreads();
rval = PyErr_Occurred() != NULL;
wxPyEndBlockThreads(blocked);
return rval;
}
%}
//---------------------------------------------------------------------------
%newgroup
DocStr(CLSID,
"This class wraps the Windows CLSID structure and is used to
specify the class of the ActiveX object that is to be created. A
CLSID can be constructed from either a ProgID string, (such as
'WordPad.Document.1') or a classID string, (such as
'{CA8A9783-280D-11CF-A24D-444553540000}').", "");
class CLSID {
public:
%extend {
CLSID(const wxString& id)
{
int result;
CLSID* self = new CLSID;
memset(self, 0, sizeof(CLSID));
if (id[0] == _T('{')) {
// Looks like a classID string
result =
CLSIDFromString(
(LPOLESTR)(const wchar_t *)id.wc_str(wxConvUTF8),
self);
} else {
// Try a progID
result =
CLSIDFromProgID(
(LPOLESTR)(const wchar_t *)id.wc_str(wxConvUTF8),
self);
}
if (result != NOERROR) {
wxPyErr_SetString(PyExc_ValueError, "Not a recognized classID or progID");
delete self;
return NULL;
}
return self;
}
~CLSID() { delete self; }
wxString GetCLSIDString()
{
LPOLESTR s;
wxString str;
if (StringFromCLSID(*self, &s) == S_OK) {
str = s;
CoTaskMemFree(s);
}
else {
str = _T("Error!"); // TODO: raise exception?
}
return str;
}
wxString GetProgIDString()
{
LPOLESTR s;
wxString str;
if (ProgIDFromCLSID(*self, &s) == S_OK) {
str = s;
CoTaskMemFree(s);
}
else {
str = _T("Error!"); // TODO: raise exception?
}
return str;
}
}
%pythoncode { def __str__(self): return self.GetCLSIDString() }
};
//---------------------------------------------------------------------------
%newgroup
%define MAKE_ARRAY_WRAPPER(basetype, arrayname)
class arrayname
{
public:
%extend {
bool __nonzero__() { return self->size() > 0; }
int __len__() { return self->size(); }
const basetype& __getitem__(int idx) {
if ( idx >= 0 && idx < self->size() )
return (*self)[idx];
else {
static basetype BadVal;
wxPyErr_SetString(PyExc_IndexError, "Index out of range");
return BadVal;
}
}
// TODO __iter__??
}
};
%enddef
//---------------------------------------------------------------------------
%immutable;
class wxParamX
{
public:
USHORT flags;
bool isPtr;
bool isSafeArray;
bool isOptional;
VARTYPE vt;
wxString name;
%feature("shadow") vt_type_get "vt_type = property(_activex.ParamX_vt_type_get)";
%extend { wxString vt_type_get() { return _VARTYPEname(self->vt); } }
%feature("shadow") IsIn "isIn = property(_activex.ParamX_IsIn)";
%feature("shadow") IsOut "isOut = property(_activex.ParamX_IsOut)";
%feature("shadow") IsRetVal "isRetVal = property(_activex.ParamX_IsRetVal)";
bool IsIn() const;
bool IsOut() const;
bool IsRetVal() const;
};
class wxFuncX
{
public:
wxString name;
MEMBERID memid;
bool hasOut;
wxParamX retType;
wxParamXArray params;
};
class wxPropX
{
public:
wxString name;
MEMBERID memid;
wxParamX type;
wxParamX arg;
bool putByRef;
%feature("shadow") CanGet "canGet = property(_activex.PropX_CanGet)";
%feature("shadow") CanSet "canSet = property(_activex.PropX_CanSet)";
bool CanGet() const;
bool CanSet() const;
};
%mutable;
MAKE_ARRAY_WRAPPER(wxParamX, wxParamXArray);
MAKE_ARRAY_WRAPPER(wxFuncX, wxFuncXArray);
MAKE_ARRAY_WRAPPER(wxPropX, wxPropXArray);
//---------------------------------------------------------------------------
%newgroup
%{
// C++ version of a Python-aware wxActiveX
class wxActiveXWindow : public wxActiveX
{
private:
CLSID m_CLSID;
DECLARE_ABSTRACT_CLASS(wxActiveXWindow);
public:
wxActiveXWindow( wxWindow* parent, const CLSID& clsId, wxWindowID id = -1,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = 0,
const wxString& name = wxPyPanelNameStr)
: wxActiveX(parent, clsId, id, pos, size, style, name)
{
m_CLSID = clsId;
}
const CLSID& GetCLSID() const { return m_CLSID; }
// Renamed versions of some base class methods that delegate
// to the base where appropriate, and raise Python exceptions
// when needed.
int GetAXEventCount() const { return wxActiveX::GetEventCount(); }
int GetAXPropCount() const { return wxActiveX::GetPropCount(); }
int GetAXMethodCount() const { return wxActiveX::GetMethodCount(); }
const wxFuncX& GetAXEventDesc(int idx) const
{
static wxFuncX BadVal;
if (idx < 0 || idx >= GetAXEventCount()) {
wxPyErr_SetString(PyExc_IndexError, "Index out of range");
return BadVal;
}
return m_events[idx];
}
const wxFuncX& GetAXMethodDesc(int idx) const
{
static wxFuncX BadVal;
if (idx < 0 || idx >= GetAXMethodCount()) {
wxPyErr_SetString(PyExc_IndexError, "Index out of range");
return BadVal;
}
return m_methods[idx];
}
const wxPropX& GetAXPropDesc(int idx) const
{
static wxPropX BadVal;
if (idx < 0 || idx >= GetAXPropCount()) {
wxPyErr_SetString(PyExc_IndexError, "Index out of range");
return BadVal;
}
return m_props[idx];
}
const wxFuncX& GetAXMethodDesc(const wxString& name) const
{
NameMap::const_iterator it = m_methodNames.find(name);
if (it == m_methodNames.end()) {
wxString msg;
msg << _T("method <") << name << _T("> not found");
wxPyErr_SetString(PyExc_KeyError, msg.mb_str());
static wxFuncX BadVal;
return BadVal;
};
return GetAXMethodDesc(it->second);
}
const wxPropX& GetAXPropDesc(const wxString& name) const
{
NameMap::const_iterator it = m_propNames.find(name);
if (it == m_propNames.end()) {
wxString msg;
msg << _T("property <") << name << _T("> not found");
wxPyErr_SetString(PyExc_KeyError, msg.mb_str());
static wxPropX BadVal;
return BadVal;
};
return GetAXPropDesc(it->second);
}
// Accessors for the internal vectors of events, methods and
// proprties. Can be used as sequence like objects from
// Python.
const wxFuncXArray& GetAXEvents() { return m_events; }
const wxFuncXArray& GetAXMethods() { return m_methods; }
const wxPropXArray& GetAXProperties() { return m_props; }
// Set a property from a Python object
void SetAXProp(const wxString& name, PyObject* value)
{
const wxPropX& prop = GetAXPropDesc(name);
wxPyBlock_t blocked = wxPyBeginBlockThreads();
if (! PyErr_Occurred() ) {
if (! prop.CanSet()) {
wxString msg;
msg << _T("property <") << name << _T("> is readonly");
PyErr_SetString(PyExc_TypeError, msg.mb_str());
goto done;
} else {
wxVariant wxV = _PyObj2Variant(value);
if (PyErr_Occurred())
goto done;
VARIANT v = {prop.arg.vt};
if (!VariantToMSWVariant(wxV, v) || PyErr_Occurred()) {
wxString msg;
msg << _T("Unable to convert value to expected type: (")
<< _VARTYPEname(prop.arg.vt) << _T(") for property <")
<< name << _T(">");
PyErr_SetString(PyExc_TypeError, msg.mb_str());
goto done;
}
PyThreadState* tstate = wxPyBeginAllowThreads();
SetProp(prop.memid, v);
VariantClear(&v);
wxPyEndAllowThreads(tstate);
}
}
done:
wxPyEndBlockThreads(blocked);
}
// Get a property and convert it to a Python object
PyObject* GetAXProp(const wxString& name)
{
PyObject* rval = NULL;
const wxPropX& prop = GetAXPropDesc(name);
wxPyBlock_t blocked = wxPyBeginBlockThreads();
if (! PyErr_Occurred() ) {
if (! prop.CanGet()) {
wxString msg;
msg << _T("property <") << name << _T("> is writeonly");
PyErr_SetString(PyExc_TypeError, msg.mb_str());
goto done;
} else {
PyThreadState* tstate = wxPyBeginAllowThreads();
VARIANT v = GetPropAsVariant(prop.memid);
wxPyEndAllowThreads(tstate);
wxVariant wv;
if (!MSWVariantToVariant(v, wv) || PyErr_Occurred()) {
wxString msg;
msg << _T("Unable to convert value to expected type: (")
<< _VARTYPEname(prop.arg.vt) << _T(") for property <")
<< name << _T(">");
PyErr_SetString(PyExc_TypeError, msg.mb_str());
goto done;
}
rval = _Variant2PyObj(wv);
VariantClear(&v);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -