明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 10872|回复: 16

[【高飞鸟】] 【飞鸟集】AutoCAD的三大程序语言(ARX,LISP,VBA)的连接

  [复制链接]
发表于 2009-5-23 21:46:00 | 显示全部楼层 |阅读模式
定制自己的ActiveX ,实现ARX和LISP,VBA的三方通信
ActiveX技术是微软组件化开发技术的基础,AutoCAD本身就是一个ActiveX自动化服务器,它提供了一系列的activeX对象.通过这些对象的属性和方法,VBA,VisualLisp就能控制autoCAD程序。
因此我们如果在开发的OjbectARX程序中实现ActiveX自动化,就可以实现Vlisp,VBA和ARX的三方的互相通信。在某些情况下,可以为我们带来很多便利。
譬如我们的核心数据处理(数值计算,等等)由arx开发,其他容易的代码则由vlisp或者VBA实现,这样我们可以达到高效和易用性的统一。
Vlisp和VBA可以调用arx定义的类和函数,并可以得到返回值,甚至可以调用其对话框资源,等等。
下面我抛砖引玉,通过这样的一个教程,演示如何实现这样的三方通信。
这个教程的大致流程如下: 由visual C++ 开发一个MFC DLL,并在其中建立一个类,定义了两个简单的函数,生成以供lisp和VBA调用。
首先创建一个MFC DLL工程,工程名为:MyActTest:

在用向导方式创建的这步,勾选自动化(Automation)

完成文件的创建之后,记得把arx工程所需要的库文件和包含文件加入进来。
并在stdafx.h文件的末尾添加如下头文件:
#include "arxHeaders.h"  // 为objectARX应用添加
然后用向导方式创建一个MFC类。

这个类的名字叫CActTest,基类为CCmdTarget,在自动化(automation)中勾选可按类型ID创建(Createable by type ID)
然后按OK.

为这个类添加你自己定制的成员函数。我在这里定义了两个简单的函数,一个函数用对话框弹出你需要的文字(就像 Hello,world那样),另外的一个则是返回一个整数的平方。

这样函数申明和定义完成后,不要忘记在类实现文件(ActTest.cpp)中的这段中添加函数的引用。(//那一行处为添加部分)
如:showStr,MySquare。
BEGIN_DISPATCH_MAP(CActTest, CCmdTarget)
DISP_FUNCTION(CActTest, "ShowStr", ShowStr, VT_EMPTY, VTS_BSTR)     //函数ShowStr的调用及其参数
DISP_FUNCTION(CActTest, "MySquare", MySquare, VT_I4, VTS_I4)  //函数MySquare的调用及其参数
END_DISPATCH_MAP()
然后编译它,生成DLL文件,以供调用.
VLisp中的调用:

  1. ;;; 本程序演示了如何通过Activex来调用arx中的类(class)和函数。
  2. ;;; 程序先注册ActiveX,后创建一个object,用vlax-invoke-method
  3. ;;; 来调用其中的函数的功能,也可以通过它得到返回值。
  4. ;;; 程序未加出错判断,请自行加入。
  5. ;;; highflybird      2009-5-23 Haikou
  6. (vl-load-com)
  7. (defun c:test (/ obj)
  8.   (DllRegister "F:\\ZQY\\MyProject\\MyActTest\\Debug\\MyActTest.DLL")   ; 也可以增加判断,如果注册了则无需再注册
  9.   (setq obj (vlax-create-object "MyActTest.ActTest"))   ; 创建一个实例(对象)
  10.   (vlax-invoke-method obj 'ShowStr "highflybird")   ; 调用其MyActTest中的函数
  11.   (print (vlax-invoke-method obj 'MySquare 12))    ; 得到返回值
  12.   (vlax-release-object obj)      ; 别忘记释放实例
  13.   (UnDllRegister "F:\\ZQY\\MyProject\\MyActivex\\Debug\\MyActTest.DLL") ; 反注册
  14.   (princ)
  15. )
  16. ;;; DLL 的注册
  17. (defun DLLRegister (dll)
  18.   (startapp "regsvr32.exe" (strcat "/s "" dll """))
  19. )
  20. ;;; DLL 的反注册
  21. (defun UnDLLRegister (dll)
  22.   (startapp "regsvr32.exe" (strcat "/u /s "" dll """))
  23. )
VBA中的调用:
打开VBA编辑器,选择菜单的工具--引用,弹出对话框,点击浏览,选择你生成的DLL文件的目录,找到它,打开它并按下引用对话框的确定,
这样我们就可以再VBA中引用自己定义的ActiveX了.


定义一个过程,在编辑器中输入代码:
Sub test()
    Dim obj As ActTest
    Set obj = New ActTest
    obj.ShowStr "hello,highflybird!"
    Set obj = Nothing
End Sub
运行,就看到你出现的效果了。
本程序由Visual Studio 2002 + ObjectARX2006 + AutoCAD 2006开发,在AutoCAD2006中运行通过。
如果有什么问题,请看我下面的程序包。

顺便说一句,感觉到此类话题属于objectARX编程类,如有必要,请总版主移至其相应版块。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x

评分

参与人数 1威望 +1 明经币 +1 收起 理由
mccad + 1 + 1 【好评】好程序

查看全部评分

"觉得好,就打赏"
还没有人打赏,支持一下

本帖被以下淘专辑推荐:

发表于 2020-9-29 10:48:26 | 显示全部楼层
(defun DLLRegister (dll)
  (startapp "regsvr32.exe" (strcat "/s "" dll """))
)
这个函数怕是有错误吧,我觉得应该是
(defun DLLRegister (dll)
  (startapp "regsvr32.exe" (strcat "/s \"" dll "\""))
)
发表于 2009-5-23 23:44:00 | 显示全部楼层

只有C语言简单基础,完全看不懂

ARX编程尝试过,好容易半天输入几页代码,调试始终不能通过,只好放弃

对于MFC,成员函数,DLL,,类,基类,类实现文件等术语完全没有概念

烦请版主给个基本的简单些的介绍

发表于 2009-5-24 08:56:00 | 显示全部楼层

这方面.net与LISP连接的方法会更简单一些,可以使用:
<LispFunction("changeArgs")>
来生成供LISP直接调用的函数。

 楼主| 发表于 2009-5-24 19:19:00 | 显示全部楼层
gisshow发表于2009-5-23 23:44:00只有C语言简单基础,完全看不懂ARX编程尝试过,好容易半天输入几页代码,调试始终不能通过,只好放弃对于MFC,成员函数,DLL,,类,基类,类实现文件等术语完全没有概念烦请版主给个基本的简单

这个不太好介绍。

C++语言是基于面向对象的语言,类是其基本的数据类型,封装了属性和实现方法(包括成员函数)

这就像一个零件(可能比喻不怎么恰当),举个例子来说吧:

C++这样用类来描述动物:

所有的动物是一个类: animal。

animal有自己的属性,如age,weight,color等。

animal也有自己的方法,例如getAge(),getWeight(),getColor(),speak(),move()等等;这些就是其成员函数

所以animal是一个基类

然后可以从animal派生出很多类别,如dog,cat,

dog除了有基类的一些属性,也可以有自己的一些属性,如,breed,

dog也有自己的方法,这些方法可以继承自animal,也可以覆盖animal的方法,还可以创建新的方法或者成员函数。

如,dog 会dog.speak(),dog.move(),dog.bark()等等。

C++继承了C语言的一些东西,把类型的申明放在 .h文件中(头文件)

把定义放在.cpp文件中(实现文件)

如我先申明了一个函数 

int myfunc();

然后在.cpp文件中实现 

 int myfunc()

    //下面是实现代码

   ........

   return 0 ;

}

MFC,微软基础类(Microsoft Foundation Classes),说白了就是对话框及菜单等各种资源。

什么是DLL,DLL 是一个包含可由多个程序同时使用的代码和数据的库。DLL是Dynamic Link Library的缩写,意为动态链接库,当执行某一个程序时,相应的DLL文件就会被调用。一个应用程序可有多个DLL文件,一个DLL文件也可能被几个应用程序所共用,这样的DLL文件被称为共享DLL文件.

通过使用 DLL,程序可以实现模块化,由相对独立的组件组成。例如,一个计帐程序可以按模块来销售。可以在运行时将各个模块加载到主程序中(如果安装了相应模块)。因为模块是彼此独立的,所以程序的加载速度更快,而且模块只在相应的功能被请求时才加载。

此外,可以更为容易地将更新应用于各个模块,而不会影响该程序的其他部分。例如,您可能具有一个工资计算程序,而税率每年都会更改。当这些更改被隔离到 DLL 中以后,您无需重新生成或安装整个程序就可以应用更新。

下表说明了 Windows 操作系统中的一些作为 DLL 实现的文件:

  • ActiveX 控件 (.ocx) 文件
    ActiveX 控件的一个示例是日历控件,它使您可以从日历中选择日期。
  • 控制面板 (.cpl) 文件
    .cpl 文件的一个示例是位于控制面板中的项。每个项都是一个专用 DLL。
  • 设备驱动程序 (.drv) 文件
    设备驱动程序的一个示例是控制打印到打印机的打印机驱动程序。

这些都扯远了,跟lisp扯不上关系。如果你要了解,不妨买一本C++语言的书来看看。

我这篇主要是谈如何让lisp也能利用C++的类。

发表于 2009-5-25 06:32:00 | 显示全部楼层
好。值得借鉴。
发表于 2012-4-2 13:49:53 | 显示全部楼层
好像都只能支持32位的,在64位机器上就用不了了,不知道如何解决~~~
发表于 2012-4-2 14:20:19 | 显示全部楼层
谢谢楼主分享
发表于 2012-12-6 20:58:41 | 显示全部楼层
highflybir :您好

“(DllRegister "F:\\ZQY\\MyProject\\MyActTest\\Debug\\MyActTest.DLL")   ; 也可以增加判断,如果注册了则无需再注册”

用lisp 如果判断.dll 文件是否被注册过了? 谢谢!
发表于 2012-12-6 22:43:33 | 显示全部楼层
flowerson 发表于 2012-12-6 20:58
highflybir :您好

“(DllRegister "F:\\ZQY\\MyProject\\MyActTest\\Debug\\MyActTest.DLL")   ; 也可 ...

(setq obj (vlax-create-object "MyActTest.ActTest"))
像上面的那样,如果能创建这个object ,object返回值不为nil,说明已经注册了,否则要注册。
发表于 2012-12-6 22:55:22 | 显示全部楼层
谢谢了。看明白了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-11-7 11:31 , Processed in 0.194463 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表