DLL在AutoCAD开发中的应用
XX
(天津市测绘院)
摘要:
本文介绍了动态链接库在AutoCAD二次开发中的应用。同时讨论了AutoCAD二次开发软件系统的管理与保密方法
关键词: AutoCAD    DLL

引言

    目前AutoCAD的二次开发工具主要包括:ARX、VB/VBA、AutoLISP/VisualLISP以及Auto
Desk最新推出的.NET API。几种开发语言各有各的优点。其中AutoLISP是AutoCAD在早期的版本中就引入的脚本语言。语法简单、调试方便,运行风险小、程序安全性高,它在编写专业CAD程序方面具有很大的优势。VBA是AutoCAD从2000版本开始集成的开发环境,具有丰富的开发能力,但它偏重于面向对象处理,在与AutoCAD交互响应和集成方面明显不足。VBA的一个重要的特点是可以很容易地使用Windows系统资源,使AutoCAD能更容易地与其他Windows下用应用软件交互。VBA的面向对象的特点使我们的开发方式更加多样化了。在目前的AutoCAD的二次开发中,我们可以综合运用多种开发手段,发挥各自的优势,使软件的功能更高效。在这些开发语言当中,VBA的代码保密性最差,但我们可以用VB或其它编译器将一些重要系统函数编译成DLL来供VisualLISP调用,这样做到了代码保密,也极大地丰富了VisualLISP的功能。
VB ActiveX DLL
1、常规函数调用
图片编辑器app    用VB编写DLL供VisualLISP调用的方法比较简单,方法如下:
第一步:启动Visual Basic 6.0;
第二步:在新建工程中选择“ActiveX DLL”;
第三步:在Class1模块中添加以下测试函数:
Public Sub Hello()
    MsgBox "Hello"
End Sub
Public Function Sum(ByVal a As Double, ByVal b As Double) As Double
    MySum = a + b
End Function
其中“Hello”是类模块的方法,“Sum”是求和函数,即返回参数a和b的和。
第四步:编译工程为Project1.dll。
第五步:在VisualLISP中调用该动态库。
(defun c:test ( / obj sum)
  (vlax-import-type-library
    :tlb-filename "c:\\Project1.dll"
    :methods-prefix "msw-"
    :properties-prefix "msw-"
    :constants-prefix "mswc-")
  (setq obj (vlax-create-object
          "Project1.Class1"))
  ;调用Hello方法
  (vlax-invoke-method obj 'Hello)
  ;调用Sum函数
  (setq sum (vlax-invoke obj 'Sum 3.0 5.0))
)
运行的结果为:
由Hello方法弹出信息框:
然后Sum函数的返回值8.0打印在AutoCAD命令行。
2、对话框调用
如果要通过这种方法调用对话框是不是也可以呢?当然可以。方法如下:
首先,在VB工程Project1中添加一个窗体Form1,然后在类模块Class1中添加函数:
Public Sub ShowDlg1()
    Form1.Show
End Sub
Public Sub ShowDlg2()
    Form1.Show 1
End Sub重新编译后,在VisualLISP中调用显示窗体函数:
(vlax-invoke-method obj 'ShowDlg1)
(vlax-invoke-method obj 'ShowDlg2)
结果为:
需要注意的一点是,函数ShowDlg1显示得窗体不是模态窗体,并且在状态栏显示最小化窗口,如下图所示:
而使用函数ShowDlg2,显示的窗体显示的是模态窗体,与AutoCAD中一般的对话框没多大区别,这样的结果正是我们需要的。
3、ActiveX对象操作
    我们讨论的落脚点还要归结到如何进行ActiveX对象操作。AutoCAD对象模型如下图:
以前使用VB开发AutoCAD时通常使用GetObject或CreateObject方法:
Set acadApp =
GetObject(, "AutoCAD.Application.16")
Set acadApp =
CreateObject("AutoCAD.Application.16")
这样做的一个明显的缺点就是当我们同时打开多个AutoCAD实例时,GetObject方法不能区分不同的实例,仅能取得最先打开的一个。显然,我们在DLL中不能这么做,因为谁都不想在当前AutoCAD实例中调用的程序却在别的AutoCAD窗口执行。
    在前面我们看到,VisualLISP调用的DLL可以返回值,也可以传入值。想要使VisualLISP调用的DLL程序在当前AutOCAD窗口执行,我们可以将AutoCAD对象通过VisualLISP传给DLL,然后其它的处理操作就交由DLL取完成。实现的步骤为:
    第一步:在DLL的“工程”->“引用”中添加“AutoCAD 2004 Type Library”类型库。
    第二步:在工程中添加全局模块Module1,并声明一个全局变量:
Public acadApp As
AutoCAD.AcadApplication
    第三步:VisualLISP与DLL通信的函数为:
Public Sub GetAcad(ByVal app As AutoCAD.AcadApplication)
    Set acadApp = app
End Sub
Public Sub ReleaseAcad()
    Set acadApp = Nothing
End Sub
Public Sub MyAlert(ByVal mes As String)
    Dim doc As AutoCAD.AcadDocument
    Set doc = acadApp.ActiveDocument