123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- """dynamic dispatch objects for AX Script.
- This is an IDispatch object that a scripting host may use to
- query and invoke methods on the main script. Not may hosts use
- this yet, so it is not well tested!
- """
- import winerror
- import types
- from win32com.server.exception import COMException
- import win32com.server.policy
- import win32com.server.util
- from win32com.client import Dispatch
- import pythoncom
- from win32com.axscript import axscript
- debugging = 0
- PyIDispatchType = pythoncom.TypeIIDs[pythoncom.IID_IDispatch]
- def _is_callable(obj):
- return type(obj) in [types.FunctionType, types.MethodType]
- # ignore hasattr(obj, "__call__") as this means all COM objects!
- class ScriptDispatch:
- _public_methods_ = []
- def __init__(self, engine, scriptNamespace):
- self.engine = engine
- self.scriptNamespace = scriptNamespace
- def _dynamic_(self, name, lcid, wFlags, args):
- # Ensure any newly added items are available.
- self.engine.RegisterNewNamedItems()
- self.engine.ProcessNewNamedItemsConnections()
- if wFlags & pythoncom.INVOKE_FUNC:
- # attempt to call a function
- try:
- func = getattr(self.scriptNamespace, name)
- if not _is_callable(func):
- raise AttributeError(name) # Not a function.
- realArgs = []
- for arg in args:
- if type(arg)==PyIDispatchType:
- realArgs.append(Dispatch(arg))
- else:
- realArgs.append(arg)
- # xxx - todo - work out what code block to pass???
- return self.engine.ApplyInScriptedSection(None, func, tuple(realArgs))
- except AttributeError:
- if not wFlags & pythoncom.DISPATCH_PROPERTYGET:
- raise COMException(scode=winerror.DISP_E_MEMBERNOTFOUND)
- if wFlags & pythoncom.DISPATCH_PROPERTYGET:
- # attempt to get a property
- try:
- ret = getattr(self.scriptNamespace, name)
- if _is_callable(ret):
- raise AttributeError(name) # Not a property.
- except AttributeError:
- raise COMException(scode=winerror.DISP_E_MEMBERNOTFOUND)
- except COMException as instance:
- raise
- except:
- ret = self.engine.HandleException()
- return ret
- raise COMException(scode=winerror.DISP_E_MEMBERNOTFOUND)
- class StrictDynamicPolicy(win32com.server.policy.DynamicPolicy):
- def _wrap_(self, object):
- win32com.server.policy.DynamicPolicy._wrap_(self, object)
- if hasattr(self._obj_, 'scriptNamespace'):
- for name in dir(self._obj_.scriptNamespace):
- self._dyn_dispid_to_name_[self._getdispid_(name,0)] = name
- def _getmembername_(self, dispid):
- try:
- return str(self._dyn_dispid_to_name_[dispid])
- except KeyError:
- raise COMException(scode=winerror.DISP_E_UNKNOWNNAME, desc="Name not found")
- def _getdispid_(self, name, fdex):
- try:
- func = getattr(self._obj_.scriptNamespace, str(name))
- except AttributeError:
- raise COMException(scode=winerror.DISP_E_MEMBERNOTFOUND)
- # if not _is_callable(func):
- return win32com.server.policy.DynamicPolicy._getdispid_(self, name, fdex)
- def _wrap_debug(obj):
- return win32com.server.util.wrap(obj, usePolicy=StrictDynamicPolicy, useDispatcher=win32com.server.policy.DispatcherWin32trace)
- def _wrap_nodebug(obj):
- return win32com.server.util.wrap(obj, usePolicy=StrictDynamicPolicy)
- if debugging:
- _wrap = _wrap_debug
- else:
- _wrap = _wrap_nodebug
- def MakeScriptDispatch(engine, namespace):
- return _wrap(ScriptDispatch(engine, namespace))
|