axsite.py
3.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import win32com.axscript.axscript
import winerror
from win32com.axscript import axscript
from win32com.server import exception, util
import pythoncom
class AXEngine:
def __init__(self, site, engine):
self.eScript = self.eParse = self.eSafety = None
if type(engine) == type(''):
engine = pythoncom.CoCreateInstance(engine,
None,
pythoncom.CLSCTX_SERVER,
pythoncom.IID_IUnknown)
self.eScript = engine.QueryInterface(axscript.IID_IActiveScript)
self.eParse = engine.QueryInterface(axscript.IID_IActiveScriptParse)
self.eSafety = engine.QueryInterface(axscript.IID_IObjectSafety)
self.eScript.SetScriptSite(site)
self.eParse.InitNew()
def __del__(self):
self.Close()
def GetScriptDispatch(self, name = None):
return self.eScript.GetScriptDispatch(name)
def AddNamedItem(self, item, flags):
return self.eScript.AddNamedItem(item, flags)
# Some helpers.
def AddCode(self, code, flags=0):
self.eParse.ParseScriptText(code, None, None, None, 0, 0, flags)
def EvalCode(self, code):
return self.eParse.ParseScriptText(code, None, None, None, 0, 0, axscript.SCRIPTTEXT_ISEXPRESSION)
def Start(self):
# Should maybe check state?
# Do I need to transition through?
self.eScript.SetScriptState(axscript.SCRIPTSTATE_STARTED)
# self.eScript.SetScriptState(axscript.SCRIPTSTATE_CONNECTED)
def Close(self):
if self.eScript:
self.eScript.Close()
self.eScript = self.eParse = self.eSafety = None
def SetScriptState(self, state):
self.eScript.SetScriptState(state)
IActiveScriptSite_methods = [
'GetLCID',
'GetItemInfo',
'GetDocVersionString',
'OnScriptTerminate',
'OnStateChange',
'OnScriptError',
'OnEnterScript',
'OnLeaveScript',
]
class AXSite:
"""An Active Scripting site. A Site can have exactly one engine.
"""
_public_methods_ = IActiveScriptSite_methods
_com_interfaces_ = [ axscript.IID_IActiveScriptSite ]
def __init__(self, objModel={}, engine = None, lcid=0):
self.lcid = lcid
self.objModel = { }
for name, object in objModel.iteritems():
# Gregs code did string.lower this - I think that is callers job if he wants!
self.objModel[name] = object
self.engine = None
if engine:
self._AddEngine(engine)
def AddEngine(self, engine):
"""Adds a new engine to the site.
engine can be a string, or a fully wrapped engine object.
"""
if type(engine)==type(''):
newEngine = AXEngine(util.wrap(self), engine)
else:
newEngine = engine
self.engine = newEngine
flags = axscript.SCRIPTITEM_ISVISIBLE | axscript.SCRIPTITEM_NOCODE | axscript.SCRIPTITEM_GLOBALMEMBERS | axscript.SCRIPTITEM_ISPERSISTENT
for name in self.objModel.iterkeys():
newEngine.AddNamedItem(name, flags)
newEngine.SetScriptState(axscript.SCRIPTSTATE_INITIALIZED)
return newEngine
# B/W compat
_AddEngine = AddEngine
def _Close(self):
self.engine.Close()
self.objModel = {}
def GetLCID(self):
return self.lcid
def GetItemInfo(self, name, returnMask):
if name not in self.objModel:
raise exception.Exception(scode=winerror.TYPE_E_ELEMENTNOTFOUND, desc='item not found')
### for now, we don't have any type information
if returnMask & axscript.SCRIPTINFO_IUNKNOWN:
return (self.objModel[name], None)
return (None, None)
def GetDocVersionString(self):
return 'Python AXHost version 1.0'
def OnScriptTerminate(self, result, excepInfo):
pass
def OnStateChange(self, state):
pass
def OnScriptError(self, errorInterface):
return winerror.S_FALSE
def OnEnterScript(self):
pass
def OnLeaveScript(self):
pass