Thank you for your suggestion. If I can do something like this:
v = Variant(VT_DOUBLE, (1.0, 2.0, 3.0))
ms.AddPoint(v)
That would be great! But I am not sure how to write the "Variant" class as you suggested. I bought your book "Python Programming on Win32" beause I wanted to automate windows applications, mostly AutoCAD, with python. Unfortunately the usage of InvokeTypes() was not covered in your book. Can you give a little more detailed guide on how to write this "Variant" class? Thank you. - wcc
On 1/26/06, Mark Hammond <[EMAIL PROTECTED]> wrote:
Your changes look reasonable for the job they are designed to do, but
doesn't provide a general solution I can try to adopt (which is fine!).
Ultimately though, the question is "why does autocad's typelib not match its
behaviour?". Can you find a reference to an autocad bug about this, or is
it worth contacting their support with a request for assistance? It may
turn out that both/either autocad or pywin32 are "correct", but incomplete
in some subtle way - eg, if autocad could explain why it is *not* a bug in
their typelib, it may help work out what bit of the puzzle is missing.
Another alternative would be for pywin32 to grow a way to easily indicate
exact types to be passed in Variant calls.
For example, your code could say something like:
v = Variant(VT_DOUBLE, (1.0, 2.0, 3.0))
ms.AddPoint(v)
This needn't be that hard. The "Variant" object could be a class defined in
a .py file. The IDispatch::Invoke method would grow support for detecting
this object and forming the correct Variant. The only query would be how
InvokeTypes should handle such an object - ignoring the explicitly passed
typeinfo seems wrong (but does seem practical!)
I'd be happy to assist with this, but am unlikely to actually drive it until
I personally need it. Sadly I don't think autocad will be used by me in the
near future :)
Mark
> -----Original Message-----
> From: [EMAIL PROTECTED]
> [mailto:[EMAIL PROTECTED] ]On Behalf Of Dan Glassman
> Sent: Thursday, 26 January 2006 6:29 AM
> To: python-win32@python.org
> Subject: [python-win32] Autocad automation via COM: Passing coordinates
> as arguments (suggested fix within)
>
>
> > From: wccppp <[EMAIL PROTECTED]>
> > Subject: [python-win32] question about COM again: variable type?
> >
> > [code]
> > ms.AddPoint([0.0, 0.0, 0.0]) # this line gives the problem
> > [/code]
> >
> > # Result is of type IAcadPoint
> > def AddPoint(self, Point=defaultNamedNotOptArg):
> > """Creates a Point object at a given location"""
> > ret = self._oleobj_.InvokeTypes(1562, LCID, 1, (9, 0), ((12,
> > 1),),Point)
> > if ret is not None:
> > ret = Dispatch(ret, 'AddPoint',
> > '{35AF3AB5-755E-4AC9-8BAF-31B532870751}', UnicodeToString=0)
> > return ret
> >
> Sorry for the long reply.
>
> The type library for AutoCad 2006 says that coordinates should be
> passed as variants, so makepy's output is correct. But you can change
> the makepy-generated file to process the argument as an array of doubles
> instead of a variant and it will work. I'm not sure if that's because
> the interface will also accept a 'raw' array, or if pythoncom is
> magically wrapping the array in a variant.
>
> Taking from the AddPoint method of the IAcadModelSpace class that you've
> included:
>
> [code]
> ret = self._oleobj_.InvokeTypes(1562, LCID, 1, (9, 0), ((12, 1),),Point)
> [/code]
>
> The (12, 1) part describes the Point argument as an (Variant, Input),
> roughly. This should be changed to (8197, 1), which is (Array of
> Doubles, Input):
>
> [code]
> ret = self._oleobj_.InvokeTypes(1562, LCID, 1, (9, 0),((8197,1),),Point)
> [/code]
>
> Unfortunately, this happens all over the place -- not just the AddPoint
> method. It would be very tedious to go through makepy's output and
> make the >1500 changes. (12, 1) cannot be changed globally in there. It
> also happens for more than just coordinate arguments; the Select methods
> of SelectionSet objects have filters which are also arrays wrapped in a
> variant. I haven't run across any others; the code below fixes
> everything I've found.
>
> My solution was to change build.py (does some of makepy's work; located
> in %pythoninstalldir%\lib\site-packages\win32com\client\) to apply this
> Variant -> Array change for me when processing the type library. The
> line numbers I reference are from pywin32 2.07; I tried to include
> enough context to find the right parts of build.py in case yours is
> different.
>
> My understanding of COM is not good, and these changes to build.py don't
> seem suitably robust. It does a small check to see if it's processing
> an Autocad library, but I suggest restoring build.py to its original
> state after processing your Autocad type libraries. You'll lose these
> fixes for dynamic dispatch in that case.
>
> I would be grateful if somebody could point out any red flags or suggest
> a better approach.
>
> Near the top of build.py (~line 52):
>
> [code]
> NoTranslateMap = {}
> for v in NoTranslateTypes:
> NoTranslateMap[v] = None
>
> #My addition starts here
> AutocadTranslateMap = {
> ('alignpoint','anglevertex','arccenter','arcpoint','axisdir',
> 'axispoint','basepoint','boundry','center','centerpoint',
> 'chordpoint','controlpoint','controlpoints','coordinates',
> 'definitionpoint','dimlinelocation','direction',
> 'directionvector','endpoint','endtangent','extline1point',
> 'extline1startpoint','extline2endpoint','extline2point',
> 'extline2startpoint','farchordpoint','firstendpoint','fitpoint',
> 'fitpoints','frompoint','insertionpoint','inspoint','jogpoint',
> 'knots','knotvalues','leader1point','leader2point',
> 'leaderendpoint','limits','lowerleft','lowleft','majoraxis',
> 'normal','origin','overridecenter','overridecenterpos',
> 'plotorigin','point','point1','point2','point3','point4',
> 'pointsarray','pointslist','pointsmatrix','porigin',
> 'secondendpoint','secondpoint','snapbasepoint','startpoint',
> 'starttangent','target','targetpoint','textalignmentpoint',
> 'textpoint','textpos','textposition','topoint',
> 'transformationmatrix','upperright','vertex','vertexlist',
> 'vertices','verticeslist','weights','wpt','wpt1','wpt2',
> 'xaxispoint','xline1point','xline2point','xvector',
> 'yaxispoint','yvector'): 8197,
> ('filtertype',): 8193,
> ('filterdata',): 8204
> }
> #My addition ends here
>
> class MapEntry:
> "Simple holder for named attibutes - items in a map."
> def __init__(self, desc_or_id, names=None, doc=None,
> resultCLSID=pythoncom.IID_NULL , resultDoc = None, hidden=0):
> [/code]
>
> Then, in the _AddFunc_ method of class DispatchItem (~line 175):
>
> Note that the code below has been stripped of its indentation to
> hopefully make it more readable in email. Indentation within the posted
> code is correct, but the entire code block needs to be indented to match
> its context in build.py.
>
> [code]
> fdesc.rettype = typerepr, flag, defval, resultCLSID
> # Translate any Alias or Enums in argument list.
> argList = []
>
> #Changes begin here;
> #for argDesc in fdesc.args:
> for index, argDesc in enumerate(fdesc.args):
> typerepr, flag, defval = argDesc
>
> #Catch only if reasonably sure this is Autocad
> if self.python_name[:5] == 'IAcad':
> #Catch (VT_VARIANT, FIN) and (VT_VARIANT, FIN|FOPT)
> #Outputs seem to translate into tuples just fine already
> if typerepr == 12 and (flag == 1 or flag == 17):
> if len(fdesc.args) == len(names): #???Properties???
> replace = [key for key in AutocadTranslateMap.keys() \
> if names[index].lower() in key]
> if replace:
> typerepr = AutocadTranslateMap[replace[0]]
> else: #names[0] is method name; names[1:] is arg names
> replace = [key for key in AutocadTranslateMap.keys() \
> if names[index+1].lower() in key]
> if replace:
> typerepr = AutocadTranslateMap[replace[0]]
> #Changes end here;
>
> arg_type, arg_clsid, arg_doc = _ResolveType(typerepr, typeinfo)
>
> argDesc = arg_type, flag, defval, arg_clsid
> # sys.stderr.write("%s\n" % (argDesc[0],))
> argList.append(argDesc)
> fdesc.args = tuple(argList)
> [/code]
> _______________________________________________
> Python-win32 mailing list
> Python-win32@python.org
> http://mail.python.org/mailman/listinfo/python-win32
>
_______________________________________________
Python-win32 mailing list
Python-win32@python.org
http://mail.python.org/mailman/listinfo/python-win32
--
Regards,
- wcc
_______________________________________________ Python-win32 mailing list Python-win32@python.org http://mail.python.org/mailman/listinfo/python-win32