126 lines
3.7 KiB
Python
126 lines
3.7 KiB
Python
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.items():
|
|
# 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.keys():
|
|
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
|