最近在wxpython中嵌入Office Activex 可以用ActivexWarper来实现
不过py2exe打包的时候很麻烦,因为引用了mfc的dll,经常是RunTime Error
只好换成ActiveXCtrl
BaseViewer就是一个wxPanel
这个Office控件里面有很多的事件 需要用到,下面是控件的makepy的导出片段
class _DEDOfficeEvents:
'Event interface for Edraw Office Viewer Component'
CLSID = CLSID_Sink = IID('{321F8EAC-5B6C-40FD-8B04-289FEF4C28A5}')
coclass_clsid = IID('{7677E74E-5831-4C9E-A2DD-9B1EF9DF2DB4}')
_public_methods_ = [] # For COM Server support
_dispid_to_func_ = {
27 : "OnSlideSelectionChanged",
28 : "OnColorSchemeChanged",
14 : "OnDownloadFileComplete",
26 : "OnSlideShowNextSlide",
3 : "OnBeforeDocumentOpened",
17 : "OnSheetActivate",
5 : "OnBeforeDocumentClosed",
20 : "OnSheetChange",
8 : "OnWindowBeforeDoubleClick",
7 : "OnWindowBeforeRightClick",
16 : "OnIESecurityReminder",
23 : "OnSlideShowBegin",
13 : "OnBeforeDownloadFile",
4 : "OnDocumentOpened",
24 : "OnSlideShowEnd",
19 : "OnSheetCalculate",
18 : "OnSheetDeactivate",
12 : "OnWindowDeactivate",
1 : "OnNotifyCtrlReady",
25 : "OnSlideShowNextBuild",
10 : "OnDocumentBeforePrint",
22 : "OnPresentationNewSlide",
2 : "OnNewDocument",
29 : "OnSlideShowNextClick",
6 : "OnBeforeDocumentSaved",
11 : "OnWindowActivate",
21 : "OnWorkbookNewSheet",
15 : "OnUploadComplete",
9 : "OnWindowSelectionChange",
}
def __init__(self, oobj = None):
if oobj is None:
self._olecp = None
else:
import win32com.server.util
from win32com.server.policy import EventHandlerPolicy
cpc=oobj._oleobj_.QueryInterface(pythoncom.IID_IConnectionPointContainer)
cp=cpc.FindConnectionPoint(self.CLSID_Sink)
cookie=cp.Advise(win32com.server.util.wrap(self, usePolicy=EventHandlerPolicy))
self._olecp,self._olecp_cookie = cp,cookie
def __del__(self):
try:
self.close()
except pythoncom.com_error:
pass
def close(self):
if self._olecp is not None:
cp,cookie,self._olecp,self._olecp_cookie = self._olecp,self._olecp_cookie,None,None
cp.Unadvise(cookie)
def _query_interface_(self, iid):
import win32com.server.util
if iid==self.CLSID_Sink: return win32com.server.util.wrap(self)
如果我们要监听OnBeforeDocuemtnOpened
下面是我的的窗口的代码,BaseViewer就是一个wxPanel,定义一个BeforeDocuemtnOpened
那么在文档打开前就会执行BeforeDocuemtnOpened方法,
ActievxCtrl初始化源代码里面有 self.AddEventSink(self) ,所以控件会在OfficeViewer里找对应的Event调用
########################################################################
class OfficeViewer(BaseViewer):
def __init__(self,parent=None,filename='',dir=BaseViewer.EDITOR_DIR):
BaseViewer.__init__(self,dir,parent)
sizer = wx.BoxSizer(wx.VERTICAL)
self.officeAtx=ActiveXCtrl(self,'EDOFFICE.EDOfficeCtrl.1',-1)
sizer.Add(self.officeAtx, 1, wx.EXPAND)
self.SetSizer(sizer)
self.officeAtx.AddEventSink(self)
self.officeAtx=self.officeAtx.ctrl
self.temp=''
self.filename=filename
self.dir=dir
def BeforeDocumentOpened(self):
"""禁止打印命令"""
MessageBox('Before Open')
self.officeAtx.DisableFileCommand(0x00000200,True)