找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1239|回复: 2

[求助] [求助]:lsp可否操纵带对话框的命令?

[复制链接]
发表于 2007-8-11 08:51:01 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

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

×
有时候,个人的小规模的lsp编程一般是把autocad系统现有的命令进行组合处理,或者是把cad下的二次开发程序的命令用lsp根据自己的需要进行引用改造;autocad下的命令一般都有对话框版和命令行版,命令行版就可以用lsp和它很好的交互,但二次开发一般不会同一个命令提供二个版本(对话框和命令行),要想用带对话框的命令就涉及到如何向对话框传递参数,lsp能做到这一点吗?请高手指点.谢谢.

个人认为,一旦对话框打开,系统的控制权就交给了windows,这时需要windows的api函数才能向对话框传递参数;Quicktool Win32Api For Lisp 可以让lsp完成在vb vc中才能完成的操作,用Quicktool Win32Api For Lisp 理论上讲可以实现以上功能,但我没有这方面的编程经验,或许大家有更好的办法.

Quicktool Win32Api For Lisp
作者:陈秋荣

    Win32Api (Windows 32Bit Application Programming Intertace)是由Microsoft公司开发的windows操作系统所提供的编写应用程序接口,包括动态链接库模块、库函数定义、常量定义和数据结构的集合,应用程序通过调用API 函数来实现操作系统提供的服务。但是Lisp可没像VB和VC那么幸运得到支持。
    在AutoCAD图形平台下进行二次开发,简便高效的开发编程工具当然首选Lisp语言,从DOS时代的AutoCAD R10版本到现在的AutoCAD 2008,Lisp程序得到很好的支持,Lisp程序几乎不需更改源代码就能实现在不同版本间轻松转移,Lisp和AutoCAD图形数据库结合得很好,操作entity非常灵活,加上Lisp可以在AutoCAD的命令行得到解释,透明命令行非常方便程序排错和调试。
    Lisp编程也有不足的地方,不能像C语言的指针一样,直接对计算机的内存进行显式操作,不能用地址来传递参数,也就不能直接调用操作系统函数,系统操作只能借用VBA,ARX程序代理执行。许多编程者认为直接调用操作系统函数是不可能的事情。   
    Quicktool Win32Api For Lisp接口由陈秋荣编写,作为独立的模块供Lisp编程者使用,未经作者许可,不得用于商业软件的开发。
    作者在研制快图设计软件的过程中,积累了大量的混合语言编程经验,解决了Lisp语言本身不能显式访问内存,无法和库模块链接,无法和Dll函数间传递参数地址等问题,成功实现了在Lisp中直接存取内存数据的方法。利用Quicktool Win32Api编程可以和VB、VC语言一样,直接调用Win32Api函数,可以读写二进制文件,可以使用操作系统的消息传递机制进行事件处理。原来需要借用VB、VBA或VC编程来完成的内容,均可以在Lisp中独立完成,解决了跨语言编程的带来的不便和困难。Quicktool Win32Api为广大的Lisp编程者打开了通往windows操作系统的大门!

    Quicktool Win32Api包括QTWin32Api.VLX和Quicktool.dll两个文件。使用前先初始化接口,假设解压缩文件置于d:\quichtool目录中:
   
    (load "d:\\quichtool\\QTWin32Api.VLX"     ;加载Lisp程序接口
    (Quicktool_Initialize "E:\\cad\\QTWin32Api\\"     ;初始化接口,参数指向Quicktool.dll文件所在目录

    接着你就可以直接调用Win32Api函数了,举些例子来说明如何使用。

1、让系统扬声器发出"嘀嘀"声:
   让扬声器发声,使用Beep函数,Beep在kernel32.dll模块中,函数调用如下:
   (win32api "kernel32" "Beep" (list 4000 60))

2、隐藏任务栏中的"开始"按钮:
   (setq hwnd (win32api "user32" "FindWindowA" (list "Shell_TrayWnd" 0))) ;获得taskbar任务栏句柄
   (setq btnhwnd (win32api "user32" "FindWindowExA" (list hwnd 0 "BUTTON" 0))) ;从任务栏中找到"开始"按钮的句柄
   (win32api "user32" "ShowWindow" (list btnhwnd 0))) ;隐藏"开始"按钮

   (win32api "user32" "ShowWindow" (list btnhwnd 1))) ;显示"开始"按钮

3、获得AutoCAD程序的窗口标题
   要获得窗口标题,使用GetWindowText函数,GetWindowText在user32.dll模块中,函数名为GetWindowTextA。该函数需要3个参数,第1个参数为欲取得标题的窗口句柄hwnd,第2个参数用于存放标题字符串的变量的内存地址,第3个参数为字符串的变量的字节长度。
(AcadApphwnd)取得AutoCAD程序的句柄,需要准备一个字符串变量str来传回函数执行后的结果,将str的内存地址作为参数,变量前面加个单引号', MAX_STRING_LENGTH定义为常量256。函数表达式如下:
   (win32api "user32" "GetWindowTextA" (list (AcadApphwnd) 'str MAX_STRING_LENGTH))
   函数执行后,变量str的值为AutoCAD程序窗口标题的字符串。

4、重新设置AutoCAD程序的窗口标题
   (win32api "user32" "SetWindowTextA" (list (AcadApphwnd) "新标题:Win32Api")

5、在AutoCAD程序的窗口中挖个圆洞,透过洞口可以看到windows桌面 ;)
   (setq hwnd (acadapphwnd)) ;取得AutoCAD程序的句柄
   (win32api "user32" "GetWindowRect" (list hwnd 'rt)) ;得到AutoCAD程序窗口的区域
   (setq hframeRgn (win32api "gdi32" "CreateRectRgnIndirect" (list 'rt))) ;将矩形重建区域
   (setq hholeRgn (win32api "gdi32" "CreateEllipticRgn" (list 100 100 300 300))) ;创建圆洞区域
   (win32api "gdi32" "CombineRgn" (list hframeRgn hframeRgn hholeRgn 4))   ;将矩形区域减去圆洞区域,赋值给hframeRgn
   (win32api "user32" "SetWindowRgn" (list hwnd hframeRgn 1))  ;将hframeRgn区域重新设置给AutoCAD程序窗口
   呵呵,试着移动AutoCAD程序窗口,透过洞口可以看到windows桌面!很神秘吧!
   

体验了有趣的Win32Api函数,这里作个小结:

    在Lisp中可以直接调用Win32Api函数,比VBA简单,调用前不需要事先申明函数,常量的定义以及数据类型和数据结构。Quicktool Win32Api函数分为四个部分:Api接口、库模块名、函数名和参数列表,Quicktool Win32Apia函数调用格式:

    (Win32Api "库模块名" "函数名" (list 参数1 参数2……))

    Win32Api---为所有windows Api函数的接口入口点,在左括号的一个位置出现
    "库模块名"---函数所在的DLL动态链接库文件名,大部分的函数包含在user32.dll、gdi32.dll、kernel32.dll、shell32.dll这几个模块中,文件的后缀名.dll可以省略,文件名大小写无关。
    "函数名"---函数别名必须区分大小写。对于含字符串操作的函数分为ANSI和Unicode两种版本,对应的函数为"函数A"与"函数W",需要显式说明。
     (list 参数1 参数2……)---传递给函数的参数列表,每个函数传递的参数不尽相同,参考相关章节中的函数详解。

    说明:
       1、如果函数不带任何参数,用nil
       2、如果需要取回处理后的参数,将内存地址作为参数,变量前面加个单引号'
       3、大部分的函数的返回值说明调用函数执行的成功与否的结果,0表示失败,其他的值表示调用函数执行成功

    想了解更多的API编程知识,可以参考《Programming Windows》一书,作者:Charles Petzold
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 2个

财富等级: 恭喜发财

发表于 2007-8-11 09:11:31 | 显示全部楼层
理论上可行,但问题是:有必要这样做吗?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-8-11 10:35:05 | 显示全部楼层
最初由 zml84 发布
[B]理论上可行,但问题是:有必要这样做吗? [/B]

主要是探讨一下,如果很容易实现,那么就有实用价值,如何很麻烦,就失去了实际意义.
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-11-17 06:43 , Processed in 0.336490 second(s), 35 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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