universal.py :  » Windows » pyExcelerator » pywin32-214 » com » win32com » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Windows » pyExcelerator 
pyExcelerator » pywin32 214 » com » win32com » universal.py
# Code that packs and unpacks the Univgw structures.

# See if we have a special directory for the binaries (for developers)
import types
import pythoncom
from win32com.client import gencache

com_error = pythoncom.com_error
_univgw = pythoncom._univgw

def RegisterInterfaces(typelibGUID, lcid, major, minor, interface_names = None):
    ret = [] # return a list of (dispid, funcname for our policy's benefit
    # First see if we have makepy support.  If so, we can probably satisfy the request without loading the typelib.
    try:
        mod = gencache.GetModuleForTypelib(typelibGUID, lcid, major, minor)
    except ImportError:
        mod = None
    if mod is None:
        import win32com.client.build
        # Load up the typelib and build (but don't cache) it now
        tlb = pythoncom.LoadRegTypeLib(typelibGUID, major, minor, lcid)
        typecomp_lib = tlb.GetTypeComp()
        if interface_names is None:
          interface_names = []
          for i in range(tlb.GetTypeInfoCount()):
            info = tlb.GetTypeInfo(i)
            doc = tlb.GetDocumentation(i)
            attr = info.GetTypeAttr()
            if attr.typekind == pythoncom.TKIND_INTERFACE or \
               (attr.typekind == pythoncom.TKIND_DISPATCH and attr.wTypeFlags & pythoncom.TYPEFLAG_FDUAL):
                interface_names.append(doc[0])
        for name in interface_names:
            type_info, type_comp = typecomp_lib.BindType(name, )
            # Not sure why we don't get an exception here - BindType's C
            # impl looks correct..
            if type_info is None:
                raise ValueError("The interface '%s' can not be located" % (name,))
            # If we got back a Dispatch interface, convert to the real interface.
            attr = type_info.GetTypeAttr()
            if attr.typekind == pythoncom.TKIND_DISPATCH:
                refhtype = type_info.GetRefTypeOfImplType(-1)
                type_info = type_info.GetRefTypeInfo(refhtype)
                attr = type_info.GetTypeAttr()
            item = win32com.client.build.VTableItem(type_info, attr, type_info.GetDocumentation(-1))
            _doCreateVTable(item.clsid, item.python_name, item.bIsDispatch, item.vtableFuncs)
            for info in item.vtableFuncs:
                names, dispid, desc = info
                invkind = desc[4]
                ret.append((dispid, invkind, names[0]))
    else:
        # Cool - can used cached info.
        if not interface_names:
            interface_names = list(mod.VTablesToClassMap.values())
        for name in interface_names:
            try:
                iid = mod.NamesToIIDMap[name]
            except KeyError:
                raise ValueError("Interface '%s' does not exist in this cached typelib" % (name,))
#            print "Processing interface", name
            sub_mod = gencache.GetModuleForCLSID(iid)
            is_dispatch = getattr(sub_mod, name + "_vtables_dispatch_", None)
            method_defs = getattr(sub_mod, name + "_vtables_", None)
            if is_dispatch is None or method_defs is None:
                raise ValueError("Interface '%s' is IDispatch only" % (name,))

            # And create the univgw defn
            _doCreateVTable(iid, name, is_dispatch, method_defs)
            for info in method_defs:
                names, dispid, desc = info
                invkind = desc[4]
                ret.append((dispid, invkind, names[0]))
    return ret

def _doCreateVTable(iid, interface_name, is_dispatch, method_defs):
    defn = Definition(iid, is_dispatch, method_defs)
    vtbl = _univgw.CreateVTable(defn, is_dispatch)
    _univgw.RegisterVTable(vtbl, iid, interface_name)

def _CalcTypeSize(typeTuple):
    t = typeTuple[0]
    if t & (pythoncom.VT_BYREF | pythoncom.VT_ARRAY):
        # Its a pointer.
        cb = _univgw.SizeOfVT(pythoncom.VT_PTR)[1]
    elif t == pythoncom.VT_RECORD:
        # Just because a type library uses records doesn't mean the user
        # is trying to.  We need to better place to warn about this, but it
        # isn't here.
        #try:
        #    import warnings
        #    warnings.warn("warning: records are known to not work for vtable interfaces")
        #except ImportError:
        #    print "warning: records are known to not work for vtable interfaces"
        cb = _univgw.SizeOfVT(pythoncom.VT_PTR)[1]
        #cb = typeInfo.GetTypeAttr().cbSizeInstance
    else:
        cb = _univgw.SizeOfVT(t)[1]
    return cb

class Arg:
    def __init__(self, arg_info, name = None):
        self.name = name
        self.vt, self.inOut, self.default, self.clsid = arg_info
        self.size = _CalcTypeSize(arg_info)
        # Offset from the beginning of the arguments of the stack.
        self.offset = 0

class Method:
    def __init__(self, method_info, isEventSink=0):
        all_names, dispid, desc = method_info
        name = all_names[0]
        names = all_names[1:]
        invkind = desc[4]
        arg_defs = desc[2]
        ret_def = desc[8]
        
        self.dispid = dispid
        self.invkind = invkind
        # We dont use this ATM.
#        self.ret = Arg(ret_def)
        if isEventSink and name[:2] != "On":
            name = "On%s" % name
        self.name = name
        cbArgs = 0
        self.args = []
        for argDesc in arg_defs:
            arg = Arg(argDesc)
            arg.offset = cbArgs
            cbArgs = cbArgs + arg.size
            self.args.append(arg)
        self.cbArgs = cbArgs
        self._gw_in_args = self._GenerateInArgTuple()
        self._gw_out_args = self._GenerateOutArgTuple()

    def _GenerateInArgTuple(self):
        # Given a method, generate the in argument tuple
        l = []
        for arg in self.args:
            if arg.inOut & pythoncom.PARAMFLAG_FIN or \
                 arg.inOut == 0:
                l.append((arg.vt, arg.offset, arg.size))
        return tuple(l)

    def _GenerateOutArgTuple(self):
        # Given a method, generate the out argument tuple
        l = []
        for arg in self.args:
            if arg.inOut & pythoncom.PARAMFLAG_FOUT or \
               arg.inOut & pythoncom.PARAMFLAG_FRETVAL or \
               arg.inOut == 0:
                l.append((arg.vt, arg.offset, arg.size, arg.clsid))
        return tuple(l)

class Definition:
    def __init__(self, iid, is_dispatch, method_defs):
        self._iid = iid
        self._methods = []
        self._is_dispatch = is_dispatch
        for info in method_defs:
            entry = Method(info)
            self._methods.append(entry)
    def iid(self):
        return self._iid
    def vtbl_argsizes(self):
        return [m.cbArgs for m in self._methods]
    def dispatch(self, ob, index, argPtr,
                 ReadFromInTuple=_univgw.ReadFromInTuple,
                 WriteFromOutTuple=_univgw.WriteFromOutTuple):
        "Dispatch a call to an interface method."
        meth = self._methods[index]
        # Infer S_OK if they don't return anything bizarre.
        hr = 0 
        args = ReadFromInTuple(meth._gw_in_args, argPtr)
        # If ob is a dispatcher, ensure a policy
        ob = getattr(ob, "policy", ob)
        # Ensure the correct dispid is setup
        ob._dispid_to_func_[meth.dispid] = meth.name
        retVal = ob._InvokeEx_(meth.dispid, 0, meth.invkind, args, None, None)
        # None is an allowed return value stating that
        # the code doesn't want to touch any output arguments.
        if type(retVal) == tuple: # Like pythoncom, we special case a tuple.
            # However, if they want to return a specific HRESULT,
            # then they have to return all of the out arguments
            # AND the HRESULT.
            if len(retVal) == len(meth._gw_out_args) + 1:
                hr = retVal[0]
                retVal = retVal[1:]
            else:
                raise TypeError("Expected %s return values, got: %s" % (len(meth._gw_out_args) + 1, len(retVal)))
        else:
            retVal = [retVal]
            retVal.extend([None] * (len(meth._gw_out_args)-1))
            retVal = tuple(retVal)
        WriteFromOutTuple(retVal, meth._gw_out_args, argPtr)
        return hr
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.