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

查看:25
本文介绍了如何为 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
")
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 类型 win32com THINKS,因此请确保您至少匹配它.

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天全站免登陆