admin 发表于 2012-3-25 22:17:43

CAD的API编程指南(上)--DynamicWrapperX

可以看下这个:http://bbs.mjtd.com/thread-85724-1-1.html
是一个类似的插件使用方法


越飞越高讲堂(2)

CAD中如何利用API 编程呢?
对于arx来说,这点根本就不是问题,直接用api函数,因为它已经成了C++的内部函数了。对于VBA来说,也不太成问题。利用VBIDE中插入模块,申明API函数,就可以用了。对于VLISP来说,就需要借助其他工具了,譬如调用编译好的dll, 或者调用其他的例如EXCEL的VBA,或者调用CAD的VBA,都需要用读写文件的方式或者暂时写入VBIDE的方式,这方面的研究nonsmall和aroom等都发表了帖子,研究得很详细了。下面我要用另外一种方式来实现它。

(上部)DynWrapX和VLISP中的API

首先申明:此文属于首创,如需转载请说明来源和作者!
不用OpenDCL,不用VB和VBA,不用ARX,下面的一些你能做到吗?
你想使得你的对话框(我这里特指DCL)添加菜单吗?你想在你的DCL中添加真彩色图片或者做成各种特效,譬如渐变的背景?你想运用各种API函数为你的程序锦上添花吗?甚至完成以前不敢想象的事情?你想函数对参数传址使用么?你想得到比grread还强大的效果吗?你想创建一个非模态的DCL吗?甚至你想在LISP中嵌入汇编语言吗?等等。

如果你有了DynamicWrapperX这个插件,你什么都可以做了。

DynamicWrapperX 是一个ActiveX部件,它允许调用DLL库里面的函数,特别是API 的函数。可用于 Jscript和VBscript。它由汇编语言写成。短小精悍,才 13Kb,压缩后才5kb,比OpenDCL.arx甚至自己做的.dll文件都小很多,你甚至可以将它打包到vlx文件中。虽然它很小,但是很给力。
它可以极大程度地扩展LISP的编程范围,赋予DCL和VLISP更多功能。它可以适应不同的CAD版本,兼容windows98~windows 7。

首先给出这个插件的英文帮助和下载地址:
http://www.script-coding.com/dynwrapx_eng.html

我这里另贴上:
DynWrapX.dll 文件这个是DynamicWrapperX 插件
Win32API.txt  文件这个不是必需的,是api 函数的查看文件,api viewer用的WIN32API.TXT -- Win32 API Declarations for Visual Basic


如何在系统中注册:
在windows下有两种方法:
1.运行 regsvr32.exe  插件路径\dynwrapx.dll, 注册给所有用户;
2.运行 regsvr32.exe  /i  插件路径\dynwrapx.dll, 注册给当前用户;
如果你把它拷贝到system32目录下,直接运行 regsvr32.exe  dynwrapx.dll就可了。
反注册用 regsvr32.exe /u插件路径\dynwrapx.dll和 regsvr32.exe /u /i 插件路径\dynwrapx.dll。
在windows 7 下,读者应该注意这点:需要以管理员身份注册运行。建议拷贝到其他目录注册运行。
http://support.microsoft.com/kb/827659

内部函数简介:
1.        Register( DllName, FuncName [, i=ParamTypes] [, r=RetValType] )
注册一个DLL中的函数,dllName,dll文件名,funcName,dll里面的函数名,i参数类型,r返回值类型。
2.        RegisterCallback( FuncRef [, i=ParamTypes] [, r=RetValType] )
注册一个回调函数,FuncRef按址引用的函数名,i参数类型,r返回值类型。
3.        NumGet( Address [, Offset] [, Type] )
得到某个指针的内容,Address指针地址,Offset偏移值,Type数值类型。
4.        NumPut( Var, Address [, Offset] [, Type] )
改变某个指针的内容,Var,要赋值的变量,Address指针地址,Offset偏移值,Type数值类型。
5.        StrPtr( Var [, Type] )
得到一个字符串的指针(实际也是创见一个指针的方法),var 字符串,type是类型
6.        StrGet( Address [, Type] )
读取某个指针的值,Address地址,type类型。
7.        Space( Count [, Char] )
创建指定长度和指定字符的字符串。Count,字符串长度,char指定的字符

创建、释放和注册函数:
创建:(setq wrap (vlax-create-object "DynamicWrapperX"))
释放:(vlax-release-object  wrap)
注册函数: (vlax-invoke  wrap  'Register  "user32.dll"  "MessageBoxW"  "i=hwwu" "r=l")
可以看出,这个甚至比VB中API函数的引用更简单。
;; 关于MessgeBox函数参见 http://baike.baidu.com/view/927800.htm

先创建几个下面用得着的对象
http://hiphotos.baidu.com/zcx1357/pic/item/496bf7dda144ad343d7160ced0a20cf430ad8572.jpg
[*]  (setq *APP (vlax-get-acad-object))
[*]  (setq *DOC (vla-get-ActiveDocument *APP))
[*]  (setq hCAD (vla-get-hwnd *APP))
[*]  (setq hDOC (vla-get-hwnd *DOC))
[*]  (setq wrap (vlax-create-object "DynamicWrapperX"))
[*]

普通浏览复制代码保存代码打印代码

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  (setq *APP (vlax-get-acad-object))

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  (setq *DOC (vla-get-ActiveDocument *APP))

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  (setq hCAD (vla-get-hwnd *APP))

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  (setq hDOC (vla-get-hwnd *DOC))

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  (setq wrap (vlax-create-object "DynamicWrapperX"))

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif


  (setq *APP (vlax-get-acad-object))<br />   (setq *DOC (vla-get-ActiveDocument *APP))<br />   (setq hCAD (vla-get-hwnd *APP))<br />   (setq hDOC (vla-get-hwnd *DOC))<br />   (setq wrap (vlax-create-object "DynamicWrapperX"))<br />



几个简单的例子:
http://hiphotos.baidu.com/zcx1357/pic/item/5d7d85dde71190eff72e7596ce1b9d16fcfa606f.jpg
[*]  ;; 例如一个简单的消息框
[*]  (vlax-invoke wrap 'Register "user32.dll" "MessageBoxW" "i=hwwu" "r=l")
[*]  ;; 'Register 注册;
[*]  ;; "User32.dll",可以省略为"USER32",也可以是自己的dll,例如"MyLib.dll";
[*]  ;; "MessageBoxW" ,API函数名字,功能是弹出一个消息框;
[*]  ;; "i=hwwu",是参数列表,见函数原型:
[*]  ;; int MessageBox(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT UType);
[*]  ;; h,父窗口句柄,w,宽字符,消息内容,w宽字符,标题文字,u,无符号整数,指的是消息框的类型
[*]  ;; "r=l"代表返回数值是整数。
[*]  (vlax-invoke wrap 'MessageBoxW hCAD "Hello,DynWrap" "Test for API" 2)
[*]  ;; 返回值代表如下:
[*]  ;; IDOK 1                    按下"OK"
[*]  ;; IDCANCEL 2                按下"取消"
[*]  ;; IDABORT 3          按下"放弃"
[*]  ;; IDRETRY 4           按下"重试"
[*]  ;; IDIGNORE 5           按下"忽略"
[*]  ;; IDYES 6                按下"是"
[*]  ;; IDNO 7           按下"否"
[*]  ;; IDCLOSE 8          按下"关闭"
[*]  ;; IDHELP 9                按下"帮助"
[*]
[*]  ;; 获得当前进程的命令行
[*]  (vlax-invoke wrap 'Register "kernel32" "GetCommandLine" "r=s")
[*]  ;; 这个函数没有参数,故而没有"i="
[*]  (vlax-invoke wrap 'GetCommandLine)
[*]  ;; 譬如返回:"C:\\Program Files\\AutoCAD 2006\\acad.exe\" 这样,我们就知道程序的所在目录和名称。
[*]
[*]  ;; 发出蜂鸣声
[*]  (vlax-invoke wrap 'Register "kernel32" "Beep" "i=uu")             ;蜂鸣声有返回值但可以不需要.
[*]  (vlax-invoke wrap 'Beep 800 1000)                              ;通过喇叭发出声音.
[*]

普通浏览复制代码保存代码打印代码

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  ;; 例如一个简单的消息框

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  (vlax-invoke wrap 'Register "user32.dll" "MessageBoxW" "i=hwwu" "r=l")

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  ;; 'Register 注册;

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  ;; "User32.dll",可以省略为"USER32",也可以是自己的dll,例如"MyLib.dll";

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  ;; "MessageBoxW" ,API函数名字,功能是弹出一个消息框;

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  ;; "i=hwwu",是参数列表,见函数原型:

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  ;; int MessageBox(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT UType);

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  ;; h,父窗口句柄,w,宽字符,消息内容,w宽字符,标题文字,u,无符号整数,指的是消息框的类型

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  ;; "r=l"代表返回数值是整数。

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  (vlax-invoke wrap 'MessageBoxW hCAD "Hello,DynWrap" "Test for API" 2)

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  ;; 返回值代表如下:

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  ;; IDOK 1                    按下"OK"

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  ;; IDCANCEL 2                按下"取消"

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  ;; IDABORT 3          按下"放弃"

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  ;; IDRETRY 4           按下"重试"

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  ;; IDIGNORE 5           按下"忽略"

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  ;; IDYES 6                按下"是"

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  ;; IDNO 7           按下"否"

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  ;; IDCLOSE 8          按下"关闭"

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  ;; IDHELP 9                按下"帮助"

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  ;; 获得当前进程的命令行

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  (vlax-invoke wrap 'Register "kernel32" "GetCommandLine" "r=s")

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  ;; 这个函数没有参数,故而没有"i="

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  (vlax-invoke wrap 'GetCommandLine)

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  ;; 譬如返回:"C:\\Program Files\\AutoCAD 2006\\acad.exe\" 这样,我们就知道程序的所在目录和名称。

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  ;; 发出蜂鸣声

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  (vlax-invoke wrap 'Register "kernel32" "Beep" "i=uu")             ;蜂鸣声有返回值但可以不需要.

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  (vlax-invoke wrap 'Beep 800 1000)                              ;通过喇叭发出声音.

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif


  ;; 例如一个简单的消息框<br />   (vlax-invoke wrap 'Register "user32.dll" "MessageBoxW" "i=hwwu" "r=l")<br />   ;; 'Register 注册;<br />   ;; "User32.dll",可以省略为"USER32",也可以是自己的dll,例如"MyLib.dll";<br />   ;; "MessageBoxW" ,API函数名字,功能是弹出一个消息框;<br />   ;; "i=hwwu",是参数列表,见函数原型:<br />   ;; int MessageBox(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT UType);<br />   ;; h,父窗口句柄,w,宽字符,消息内容,w宽字符,标题文字,u,无符号整数,指的是消息框的类型<br />   ;; "r=l"代表返回数值是整数。<br />   (vlax-invoke wrap 'MessageBoxW hCAD "Hello,DynWrap" "Test for API" 2)<br />   ;; 返回值代表如下: <br />   ;; IDOK 1                    按下"OK"<br />   ;; IDCANCEL 2                按下"取消"<br />   ;; IDABORT 3          按下"放弃"<br />   ;; IDRETRY 4           按下"重试"<br />   ;; IDIGNORE 5           按下"忽略"<br />   ;; IDYES 6                按下"是"<br />   ;; IDNO 7           按下"否"<br />   ;; IDCLOSE 8          按下"关闭"<br />   ;; IDHELP 9                按下"帮助"<br /> <br />  ;; 获得当前进程的命令行<br />   (vlax-invoke wrap 'Register "kernel32" "GetCommandLine" "r=s")<br />   ;; 这个函数没有参数,故而没有"i="<br />   (vlax-invoke wrap 'GetCommandLine)<br />   ;; 譬如返回:"C:\\Program Files\\AutoCAD 2006\\acad.exe\" 这样,我们就知道程序的所在目录和名称。<br /> <br />  ;; 发出蜂鸣声<br />   (vlax-invoke wrap 'Register "kernel32" "Beep" "i=uu")             ;蜂鸣声有返回值但可以不需要.<br />   (vlax-invoke wrap 'Beep 800 1000)                              ;通过喇叭发出声音.<br />



参数符号代表的类型:
l -  32位整数 - LONG, INT, LPARAM, LRESULT, etc, 范围: -2147483648 ... 2147483647;
u - 无符号32位整数 - ULONG, UINT, DWORD, WPARAM, ... , 范围: 0 ... 4294967295;
注意,在lisp中,无符号的整数如果超出2147483647 会溢出,例如(+ 2147483647 1)
返回-2147483648
h - 句柄 - HANDLE, HWND, HMODULE, HINSTANCE, HICON, ... , 范围: -2147483648 ... 4294967295;
p - 指针; 就是一个数值,对象或者字符串的地址。
n - 16位整数- 短整数, 范围: -32768 ... 32767;
t - 无符号16位整数- USHORT, WORD, WCHAR, OLECHAR, ... , 范围: 0 ... 65535;
c - 8位整数- CHAR, 范围: -128 ... 127;
b - 无符号8位整数- UCHAR, BYTE, ... , 范围: 0 ... 255;
f – 浮点数 - FLOAT;
d – 双精度数 - DOUBLE;
w - Unicode 字符串 - BSTR, LPWSTR, LPOLESTR, OLECHAR *, WCHAR *, ...;
s - ANSI/Windows 字符 (默认代码页) - LPSTR, LPCSTR, CHAR *, ...;
z - OEM/DOS字符(默认代码页) - LPSTR, LPCSTR, CHAR *, ...

返回值也是如此。但是我们在lisp中用到最多的是l数值型,可以代表指针,也可以代表长整数,短整数,甚至布尔值等等。
关于字符串的宽字符和ASCII字符,请读者自行参考相关资料。

RegisterCallBack方法:
鉴于LISP对于函数的地址取得的方式和对参数的保护模式,所以这个函数对LISP意义不大,略去。

其他方法:
NumGet( Address [, Offset] [, Type] )
从一个地址中获取数值。Address,基址,Offset偏移量,能用于循环读写一系列的数值。Type,数值类型,默认”l”,即长整数,只能小写字母。返回值就是这个地址中的内容。
NumPut( Var, Address [, Offset] [, Type] )
写入数值到内存中。Var,要写入的变量,剩下的几个参数跟NumGet相同。返回值是写入的字节数。
上面两个函数,允许你在基址占用的内存中存取数据(结构,数组等)。
StrPtr( Var [, Type] )
创建一个字符串指针,然后你可以在这个字符串占用的内存中存取数据(结构,数组等)。Var,是字符串变量或者常量,type是字符串类型,可以是”w”(默认方式),”s”,”z”。返回一个指针(即一个长整数)。
StrGet( Address [, Type] )
从指定地址中,读取字符串,并返回其拷贝。Address可以是数值变量的地址,也可以是字符串的首址,type 同StrPtr。
Space( Count [, Char] )
创建指定长度指定字符的字符串。Count,数量,Char,指定字符,如果没这个参数,指定字符就是空格。

下面是其用法例子:
http://hiphotos.baidu.com/zcx1357/pic/item/3d95871190ef76c625071c629d16fdfaae51676f.jpg
[*]  ;; 取得某个地址的内容,例如读取字符串的ASCII代码
[*]  ;; 其实就是(vl-string->list "Hello, world! It's me.")
[*]  ;l 举这个例子仅仅是说明其用法。
[*]  (setq str "Hello, world! It's me.")
[*]  (setq sLen (strlen str))
[*]  (setq codes "")
[*]  (setq i 0)
[*]  (repeat sLen
[*]    (setq code (vlax-invoke wrap 'NumGet Str (* i 2) "t"))        ;乘以2是因为偏移必须是两个字节"t"
[*]    (setq codes (strcat codes (itoa code) " "))
[*]    (setq i (1+ i))
[*]  )
[*]  (alert codes)
[*]
[*]
[*]  ;; 读取并写入内存,例如反转字符串.
[*]  ;; 这个例子就是反转字符串。
[*]  ;; 对中文字符串要复杂些
[*]
[*]  (setq buf (vlax-invoke wrap 'Space sLen))
[*]  (setq pBuf (vlax-invoke wrap 'StrPtr Buf "s"))                ;获得缓冲区地址,用来读写
[*]  (setq i 0)
[*]  (setq j (1- sLen))                                                ;最后一个下标要字符串长度减1
[*]  (repeat sLen
[*]    (setq code (vlax-invoke wrap 'NumGet Str (* i 2) "t"))        ;从左到右读
[*]    (vlax-invoke wrap 'NumPut code pBuf (* j 2) "t")            ;从右到左写入缓冲区
[*]    (setq j (1- j))                                                ;偏移地址增加
[*]    (setq i (1+ i))                                                ;偏移地址减少
[*]  )
[*]  (alert (vlax-invoke wrap 'StrGet pBuf))                        ;最后读取缓冲区内容
[*]

普通浏览复制代码保存代码打印代码

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  ;; 取得某个地址的内容,例如读取字符串的ASCII代码

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  ;; 其实就是(vl-string->list "Hello, world! It's me.")

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  ;l 举这个例子仅仅是说明其用法。

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  (setq str "Hello, world! It's me.")

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  (setq sLen (strlen str))

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  (setq codes "")

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  (setq i 0)

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  (repeat sLen

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif    (setq code (vlax-invoke wrap 'NumGet Str (* i 2) "t"))        ;乘以2是因为偏移必须是两个字节"t"

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif    (setq codes (strcat codes (itoa code) " "))

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif    (setq i (1+ i))

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  )

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  (alert codes)                                

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif                                          

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif   

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  ;; 读取并写入内存,例如反转字符串.

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  ;; 这个例子就是反转字符串。

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  ;; 对中文字符串要复杂些

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  (setq buf (vlax-invoke wrap 'Space sLen))                        

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  (setq pBuf (vlax-invoke wrap 'StrPtr Buf "s"))                ;获得缓冲区地址,用来读写

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  (setq i 0)

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  (setq j (1- sLen))                                                ;最后一个下标要字符串长度减1

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  (repeat sLen

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif    (setq code (vlax-invoke wrap 'NumGet Str (* i 2) "t"))        ;从左到右读

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif    (vlax-invoke wrap 'NumPut code pBuf (* j 2) "t")            ;从右到左写入缓冲区

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif    (setq j (1- j))                                                ;偏移地址增加

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif    (setq i (1+ i))                                                ;偏移地址减少

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  )        

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif  (alert (vlax-invoke wrap 'StrGet pBuf))                        ;最后读取缓冲区内容

[*]http://bbs.mjtd.com/source/plugin/mc_colorcode/images/jssc_none.gif


  ;; 取得某个地址的内容,例如读取字符串的ASCII代码<br />   ;; 其实就是(vl-string->list "Hello, world! It's me.")<br />   ;l 举这个例子仅仅是说明其用法。<br />   (setq str "Hello, world! It's me.")<br />   (setq sLen (strlen str))<br />   (setq codes "")<br />  (setq i 0)<br />   (repeat sLen<br />     (setq code (vlax-invoke wrap 'NumGet Str (* i 2) "t"))        ;乘以2是因为偏移必须是两个字节"t"<br />     (setq codes (strcat codes (itoa code) " "))<br />     (setq i (1+ i))<br />  )<br />   (alert codes)                                <br />                                           <br />    <br />  ;; 读取并写入内存,例如反转字符串.<br />   ;; 这个例子就是反转字符串。<br />  ;; 对中文字符串要复杂些<br /> <br />   (setq buf (vlax-invoke wrap 'Space sLen))                        <br />   (setq pBuf (vlax-invoke wrap 'StrPtr Buf "s"))                ;获得缓冲区地址,用来读写<br />   (setq i 0)<br />   (setq j (1- sLen))                                                ;最后一个下标要字符串长度减1<br />   (repeat sLen<br />     (setq code (vlax-invoke wrap 'NumGet Str (* i 2) "t"))        ;从左到右读<br />     (vlax-invoke wrap 'NumPut code pBuf (* j 2) "t")            ;从右到左写入缓冲区<br />     (setq j (1- j))                                                ;偏移地址增加<br />     (setq i (1+ i))                                                ;偏移地址减少<br />   )        <br />   (alert (vlax-invoke wrap 'StrGet pBuf))                        ;最后读取缓冲区内容<br />



运用上面方法也可以用来通过改变地址内容改变变量值,即对函数参数的传址使用。

更精彩的在后面:

具体运用和实例剖析:
请见下面的完整的例子:其中已经有注释,包含了详细的解释。


在此特别感谢nonsmall,在编写这个程序过程中得到了他的很多帮助及其建议。

另外一些关于用LISP调用API的链接:
http://bbs.mjtd.com/forum.php?mod=viewthread&tid=72145&highlight=API
http://bbs.mjtd.com/forum.php?mod=viewthread&tid=74063&highlight=API
http://bbs.mjtd.com/forum.php?mod=viewthread&tid=60155&highlight=API
http://bbs.mjtd.com/forum.php?mod=viewthread&tid=60884&highlight=API
http://bbs.mjtd.com/forum.php?mod=viewthread&tid=84651&highlight=API

提醒:因为用到了API,可能会对内存有读写,所以编程前应保存工程。注意对内存的释放和存取可操作性。

多谢Caiqs的建议,"如果你有了DynamicWrapperX这个插件,你什么都可以做了。"这句话我夸大其词了,具体有哪些不能做的,请参考70楼。


http://bbs.waibc.com/xwb/images/bgimg/icon_logo.png 该贴已经同步到 admin的微博
页: [1]
查看完整版本: CAD的API编程指南(上)--DynamicWrapperX