如何为COM构建对象列表? [英] How to construct an objectlist for COM?

查看:137
本文介绍了如何为COM构建对象列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是以前用VBA编写的真实项目。

This is a real project written in VBA before.

我想将其移至Python,并使用带有Python的AutoCAD ActiveX自动化脚本方法。这是我的代码:

I want to move it to Python and use 'ActiveX Automation scripts for AutoCAD with Python' method. This is my code:

# -*- coding: utf-8 -*-

from pyautocad import Autocad, APoint, aDouble


acad = Autocad(False,  True)
acad.prompt("Hello, Autocad from Python\n")
print acad.doc.Name

xx = acad.model.AddCircle(APoint(0, 0),  10)
print(xx)
yy = acad.model.Add3Dpoly(aDouble([0,  0,  0,  10,  10,  10,  30,  20,  30,  0,  0,  0]))
print(yy.ObjectName)
print(yy.PlotStyleName)

# How to contruct an objectlist for AddRegion?
#regions = acad.model.AddRegion([yy])
#acad.model.AddExtrudedSolid(regions[0], 20, 0)

我的问题是,如何为 AddRegion 构造对象列表?也许 comtypes 有一些关于VARINT的主题。我真的没有COM方面的经验,等等。

My question is, how to construct an object list for AddRegion? Maybe comtypes have some topic about VARINT. I really have no experience about COM and so on...

推荐答案

让所有功能正常工作可能比它还重要。似乎应该如此。使用python读取数据;还不错写数据,有点棘手。休闲用户/初学者;

Getting it all to work right can be more work than it seems like it should be. Reading data using python; not so bad. Writing data, bit trickier. Casual user / Beginners; be warned of what your getting into.

如果您对autolisp熟悉,它将非常有用,因为它工作得更好(在这种情况下),被更好地记录了并且集成得更好,...您可能需要用它来未知/隐藏/未记录 'python没有告诉您的信息。 (请参阅 vlax- vla-系列lisp函数)。

It helps tremendously if you are familiar with autolisp, because it just works better (in this case), is documented better, and integrates better,... and you will likely need it to milk 'unknown/hidden/undocumented' information that python isn't telling you. (see the vlax- and vla- series of lisp functions).

下一步,您需要 win32com 命令行中的make_py和gen_py脚本,或者您可以使用 win32com.client.gencode ,而主要使用python。

Next you need win32com make_py and gen_py scripts from the command line, or you can use win32com.client.gencode while staying mostly in python.

准备好以视觉方式解析非常丑陋的文本(我什至没有在谈论lisp =])。准备失败,并为找到原因感到兴奋。

Be prepared to visually parse very ugly text (and I wasn't even talking about lisp =] ). Be prepared to fail, and get excited to find out why.

其中大部分与COM变量有关。然后您会得到诸如Variant-Variant-Arrays之类的怪异东西。如果签出 win32com.client.pythoncom ,您会注意到所有数据类型都映射为整数。 (例如,VT_BOOL是11)。

Most of it has to do with COM-Variants. And then you get wierd stuff like Variant-Variant-Arrays. If you check out win32com.client.pythoncom, you will notice all of the datatypes are mapped to integers. (VT_BOOL is 11 for example).

下次尝试ModelSpace时.AddCircle,注意获得的调试输出;
传递给InvokeTypes的所有参数都是您需要的要注意的...(这是从我的Autocad注册接口的make-py输出中提取的

Next time you attempt a ModelSpace.AddCircle, pay attention to the debug output you get; All of the parameters passed to InvokeTypes are what you need to watch for... (this is taken from my make-py output for the Autocad Registered Interfaces

def AddLine(self, StartPoint=defaultNamedNotOptArg, EndPoint=defaultNamedNotOptArg):       
    ret = self._oleobj_.InvokeTypes(
                        1581, LCID, 1, (9, 0), ((12, 1), (12, 1)),StartPoint, EndPoint)
    if ret is not None:
        ret = Dispatch(ret, u'AddLine', '{DF524ECB-D59E-464B-89B6-D32822282778}'

这完全可以告诉您哪个COM

This tells you exactly which COM types win32com THINKS it wants, so make sure you are at least matching that.

我发现实际上已经记录并调用了许多输入函数,因此请确保至少要匹配它。是错误的(我是通过AutoLisp来回学习的。)我们上面看到的内容在外部具有 1581 值(类似于类名,而不是真正的数据类型),并且然后是基本表示(DISPATCH,EMPTY) :( 9,0)的元组,然后是VT_VARIANTS:((12,1),(12,1))的数组。

I have found that many input functions are actually documented and invoked wrong (I learned this after much back and forth with AutoLisp). What we see above has a value of 1581 on the outside (which is something like a class name, not really a datatype), and then tuple that basically says (DISPATCH, EMPTY):(9,0), and then an array of VT_VARIANTS:((12,1),(12,1)).

COM通常期望缺少一个外部包装程序,由于某种原因,make-py无法意识到这一点。如果您经过大量的AutoLisp vlax-废话,您会发现它们是该包装的附加包装。我相信它要么是一个VARIANT_ARRAY,要么从字面上看,是一个VARIANT-VARIANT-ARRAY(四重指针或诸如此类)。为此的代码是(vt_array = 8192,vt_variant = 12)。

There is usually a missing outer wrapper that COM was expecting, and for some reason make-py does not realize this. if you go through extensive AutoLisp vlax- nonsense, you will notice their is an additional wrapper around that one. I believe it is either a VARIANT_ARRAY, or quite literally, a VARIANT-VARIANT-ARRAY (quadruple pointer or something). The codes for this are (vt_array=8192, vt_variant=12).

很抱歉,我不记得具体信息,但我相信读为((12,1),(12,1))的部分,应变为(8192,12,(((12,1),(12,1)))或类似名称。即使您确定了它应该是什么,我也不确定它们是否是快速解决方案。对于AutoCAD 2010,对我来说,这意味着要遍历不合时宜的gen_py输出,找到我真正想要的功能,并手动更改InvokeTypes()调用以匹配COM的期望。

Im sorry I don't remember specifics, but I believe the portion reading ((12,1),(12,1)), should become (8192, 12, ((12,1),(12,1))), or something like that. Even once you do figure out what it should be, Im not sure if their is a quick fix. As of AutoCAD 2010, for me, this meant going through the ungodly large gen_py output, finding the functions I really wanted, and manually changing the InvokeTypes() call to match what COM was expecting.

此后,一切都按预期进行。

Everything worked simply as expected after that.

COM很丑。如果您是python的新手,但在AutoCAD中却是半经验的(这意味着您想做一些相当繁琐的自动化操作),请远离 python-> win32com-> AutoCAD 管道。使用LISP。令我难以忍受的是,您最终将编写大量LISP测试用例和调试器来伴随python的烦恼,您不妨提交。

COM is ugly. If you are new to python, but semi-experienced in AutoCAD (meaning you want to do some fairly hefty automation), stay away from the python->win32com->AutoCAD pipeline. Use LISP. As much as that pains me to say, your gonna end up writing so many LISP test cases and debuggers to accompany your python pains, you might as well just commit.


  • Ironpython和.NET

    • 我相信这个接口比一般的COM都支持更多


    • 我从未使用过官方的VS-Pro工具(我使用过PythonWIN和MINGW),我不确定是否提供了任何其他魔术,这些魔术将改变win32com处理AutoCAD的方式。我知道官方的AutoCAD ARX扩展在Studio项目中提供了它们的源代码。最坏的情况是,您将近有实际的文档,这将使python-AutoCAD的整个主题受到污染。

    这篇关于如何为COM构建对象列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆