本文探讨采用动态链接库(DLL)和VLisp结合的模式开发AutoCAD中Vlisp程序的启动界面、关于、历史记录等对话框显示函数和注册表、初始化文件等的操作函数。 由于采用Vlisp编程语言的限制,造成使用Vlisp开发的AutoCAD程序诸如:对话框(DCL除外)、注册表、初始化文件等操作显得力不存心! 为此,本人采用动态链接库(.DLL)的模式来新开僻一条思路,供各位编程爱好者探求混合开发模式。 动态链接库的编制已经非常的普遍,即将欲发布的通用函数,编译生成动态链接库(.DLL)即可。但是如何在VLisp下使用呢? 举例如下: 假设动态链接库名称为Ayunger.DLL,其中有一个函数,名称为 "IniSet",为写初始化文件函数,其具体在动态库中定义为: IniSet(ByVal Section As String, ByVal Key As String, ByVal Value As String, ByVal IniFileName As String, ByVal IsRecoverMode As Boolean) 其中参数为:Section-节名; Key-关键字; Value-值; IniFileName-初始化文件名称; IsRecoverMode-为写入模式: (True-删除原文件, Fasle-不删除文件) 如: C:/Test.ini文件内容为: [HWND] setupdlg=3933744 setup.exe=1443246 [SKIN] PATH=C:\Program Files\Rising\Rfw\skin\skin1\rfwmain.xml Current=1 [WINHANDLE] RfwMain=131364 RfwCfg=1967420 则用VLisp如何生成一个如下内容的键值呢? [HWND] setupdlg=3933744 setup.exe=1443246 Test=欢迎您有空了来坐坐... [SKIN] PATH=C:\Program Files\Rising\Rfw\skin\skin1\rfwmain.xml Current=1 [WINHANDLE] RfwMain=131364 RfwCfg=1967420 World=Hello, the world... [我的新节] 键1=中国.西安 键2=Ayunger Studio 编写Vlisp程序,步骤如下: 1、注册动态链接库[(startapp "regsvr32.exe /s" "AYUNGER.DLL")] 2、建立并得到动态链接库接口类[(setq vbApp (vla-GetInterfaceObject cadApp "AYUNGER.Application"))]; 3、调用函数,进行函数操作[(vlax-invoke-method vbApp 'IniSet ....]。 用Vlisp函数编写如下代码行: (vl-load-com) (startapp "regsvr32.exe /s" "AYUNGER.DLL") (setq vbApp (vla-GetInterfaceObject (vlax-get-acad-object) "AYUNGER.Application")) (vlax-invoke-method vbApp 'IniSet "HWND" "Test" "欢迎您有空了来坐坐..." "C:/Test.ini" nil) (vlax-invoke-method vbApp 'IniSet "SKIN" "World" "Hello, the world..." "C:/Test.ini" nil) (vlax-invoke-method vbApp 'IniSet "我的新节" "键1" "中国.西安" "C:/Test.ini" nil) (vlax-invoke-method vbApp 'IniSet "我的新节" "键2" "Ayunger Studio" "C:/Test.ini" nil) 即可生成上面文件内容。若要修改“[SKIN]”节的“World”键的内容为“One World, One Dream...”,则采用 (vlax-invoke-method vbApp 'IniSet "SKIN" "World" "One World, One Dream..." "C:/Test.ini" nil)即可! 生成后的C:/Test.ini文件的内容如下: [HWND] setupdlg=3933744 setup.exe=1443246 Test=欢迎您有空了来坐坐... [SKIN] PATH=C:\Program Files\Rising\Rfw\skin\skin1\rfwmain.xml Current=1 [WINHANDLE] RfwMain=131364 RfwCfg=1967420 World=One World, One Dream... <----这里时新修改的条目. [我的新节] 键1=中国.西安 键2=Ayunger Studio 同样其他函数的调用,都可以采用这种类型了! 哈哈,是不是比较好呢? 当然,上面的Vlisp举例仅仅为条目式介绍,应包含容错处理等,具体见下面的C:TestDLL()函数完整版. 【警告】动态链接库(DLL)编写需要较高的、严谨的编程约定,必须做到经严格测试,并有容错处理后方可发布, 不能出现造成系统崩溃或死机等情况的发生,否则得不偿失。 以下为本人采用动态库(ayunger.Dll)开发的部分函数,列表如下: ------------------------------------------------------ <> 【对话框操作】方法函数 ------------------------------------------------------ //1. 显示<启动屏幕(图片: 宽x高=550x300)> 函数 ShowLogo(ByVal ImgFileName As String = ") //2. 显示<关于对话框(图片: 宽x高=100x200)> 函数 ShowAbout(ByVal Title As String, ByVal Version As String, ByVal Copyright As String, ByVal UserName As String, ByVal UserPart As String, ByVal UserID As String, ByVal ImgFileName As String) //3. 显示<历史记录/更新记录对话框> 函数 ShowStory(ByVal Context As String, ByVal Title As String) //4. 显示<AYUNGER.DLL 函数帮助对话框> 函数 ShowHelp()
------------------------------------------------------ <> 【注册表操作】方法函数 ------------------------------------------------------ //1. 读取注册表关键字信息 函数 RegGet(ByVal BootHKey As String, ByVal SubKey As String, ByVal SubKeyItem As String) As String //2. 写注册表关键字信息 函数 RegSet(ByVal BootHKey As String, ByVal SubKey As String, ByVal SubKeyItem As String, ByVal ItemValue As String) As Boolean //3. 删除注册表子项中的键 函数 RegValueDel(ByVal BootHKey As String, ByVal SubKey As String, ByVal SubKeyItem As String) As Boolean //4.删除注册表中的子项 函数 RegKeyDel(BVal BootHKey As String, ByVal SubKey As String) As Boolean ------------------------------------------------------ <> 【初始化文件(.Ini)操作】方法函数 ------------------------------------------------------ //1. 读初始化文件(.INI) 函数 IniGet(ByVal Section As String, ByVal Key As String, ByVal IniFileName As String) As String //2. 写初始化文件(.INI) 过程 IniSet(ByVal Section As String, ByVal Key As String, ByVal Value As String, ByVal IniFileName As String, ByVal IsRecoverMode As Boolean ) //3. 删除初始化文件(.INI)中指定节内容 过程 IniSecDel(ByVal Section As String, ByVal IniFileName As String) //4. 删除初始化文件(.INI)中指定键值 过程 IniKeyDel(ByVal Section As String, ByVal Key As String, ByVal IniFileName As String) ------------------------------------------------------ <> 【系统信息操作】方法函数 ------------------------------------------------------ //1. 获取Windows 的系统目录。 SysDir() As String //2. 获取Windows 的系统根目录。 WinDir() As String //3. 获取Windows 当前登陆用户名 函数 getUsName() As String //4. 获取Windows 当前计算机名 函数 getComptName() As String //5. [系统信息] 过程 SysInf() ------------------------------------------------------ <> 【文件类操作】方法函数 ------------------------------------------------------ //1. 打开/运行 已注册类型文档或程序 过程 RunFile(ByVal FileName As String) //2 打印任何类型的文件 过程 PrintFile(ByVal FileName As String) //3 构造MS-DOS路径名称 函数 ShortFileName(LongFileName As String) As String //4 制作有特殊后缀标志的文件名 函数。 reSpecFileName(ByVal OldFileName As String, ByVal SpecString As String, ByVal onlyEXTname As Boolean) As String //5. 转换成AutoCAD承认或VC使用的路径 函数 PathforCAD(ByVal SourcePath As String) As String //6. 读取<AYUNGER.DLL>文件路径 函数 Path() As String ------------------------------------------------------ <> 【其他操作】方法函数 ------------------------------------------------------ //1. 获取随即数 函数 Rand(ByVal number As Single) 函数使用方法如下: ;;;************************************** ;;;Ayunger.Dll动态链接库函数调用实例. ;;; --- By Ayunger 2008.12.23 ;;;************************************** (defun C:TestDLL(/ cadApp vbApp xCatch i) (vl-load-com) (if (findfile "AYUNGER.DLL") (progn (setq cadApp (vlax-get-acad-object)) (setq xCatch (vl-catch-all-apply '(lambda () (setq vbApp (vla-GetInterfaceObject cadApp "AYUNGER.Application"))))) (if (vl-catch-all-error-p xCatch) (startapp "regsvr32.exe /s" "AYUNGER.DLL")) (setq xCatch (vl-catch-all-apply '(lambda () (setq vbApp (vla-GetInterfaceObject cadApp "AYUNGER.Application"))))) (if (and (not (vl-catch-all-error-p xCatch)) vbApp) (progn ;;实例1: 对话框. (vlax-invoke-method vbApp 'ShowLogo "C:/lu30.jpg");图片具体请修改此处. (vlax-invoke-method vbApp 'ShowAbout "一个非常好用的AutoCAD工具集" "Ver-1.000" "Copyright 2009" "Ayunger" "Ayunger Studio" "" "C:/lu32.jpg");图片具体请修改此处. (vlax-invoke-method vbApp 'ShowStory "欢迎您有空了来坐坐..." "欢迎") ;;实例2: 读写初始化文件. (setq i 1) (while (<= i 20) (vlax-invoke-method vbApp 'IniSet "First" (itoa i) (rtos (+ i 1000.0001) 2 3) "c:/test.ini" nil);写入.ini文件. (setq i (+ i 1)) );end_while (alert (strcat "c:/test.ini中First节第5条内容=" (vlax-invoke-method vbApp 'IniGet "First" "5" "c:/test.ini")));读取.ini文件. ;;实例1: AYUNGER.DLL函数帮助对话框. (vlax-invoke-method vbApp 'ShowHelp) );end_progn );end_if (setq vbApp nil) );end_progn );end_if (princ) );end_defun |