本帖最后由 jacenhe 于 2022-2-13 04:11 编辑
方法一、aardio 创建 ActiveX 控件,在 LISP 中调用。
双击打开「aardio 范例 / COM 组件 / 创建 ActiveX EXE」示例工程:
点击「发布」生成 EXE 文件:
运行生成的 EXE,显示以下界面:
然后在 AutoCAD 中以如下 LISP 代码创建并调用 aardio 控件:
 - (setq aarObj (vlax-get-or-create-object "AardioTestControl.Sample"))(vlax-invoke aarObj 'Add 1 3)
方法二、执行以下 LISP 代码异步启动 aardio 编写的 EXE。
 - (startapp "d:/test/test.exe" (strcat "/hwnd" " " (itoa(vla-get-hwnd(vlax-get-acad-object)))))
其实这里取窗口句柄、传窗口句柄是多余的,只是做个演示。在 aardio 中用 process.getParent().getMainWindow() 直接就可以取到 AutoCAD 主窗口。
我们可以在 aardio 里生成并执行 LISP 代码,顺带把 EXE 路径也写进去。EXE 启动以后也可以执行 LISP 代码、操作 AutoCAD 对象,下面的范例里有演示。
方法三、下面示例演示的 startExe 函数阻塞启动 aardio 编写的 EXE。
EXE 文件的完整 aardio 源代码如下:
if(_STUDIO_INVOKED) error("请复制此代码到 aardio 工程的 main.aardio 内,然后生成 EXE 文件再运行",2);
import fsys.dlg;
import process;
var cmdline = io.stdin.read(); //自标准输入读取 LISP 传入的值
var parentProcess = process.getParent(); //获取父进程对象
if(! (cmdline && parentProcess) ){
import console
console.showLoading("正在为 为 AutoCAD 安装 startExe( cmdline ) 函数。");
import com.cad;
var cad = com.cad()
cad.Visible = true;
//直接添加函数
cad.SendCommand(`(defun startExe(cmdline)
(setq wsc (vlax-get-or-create-object "WScript.Shell"))
(setq handle (itoa(vla-get-hwnd(vlax-get-acad-object))))
(setq wsx (vlax-invoke wsc 'EXec <?
//将当前 EXE 路径传入 lisp 代码,模板参数放入数组可自动处理转义字符,首尾自动加双引号。
={ io._exepath }
?>))
(setq stat(vlax-get wsx 'status ))
(setq stdin(vlax-get wsx 'StdIn ))
(vlax-invoke stdin 'Write (strcat cmdline "\n"))
(setq stdout(vlax-get wsx 'StdOut ))
(setq out1 (vlax-invoke stdout 'Readall))
out1
)`)
console.log("已为 AutoCAD 安装 startExe( cmdline ) 函数");
console.pause();
return;
}
import process;
import string.cmdline;
//解析命令行参数
var argv = string.cmdline.argv(` ` + cmdline);
//获取 AutoCAD 主窗口句柄
var hwndAutoCAD = parentProcess.getMainWindow();
//注意这时候 AutoCAD 是阻塞状态,不应也不必要设置所有者窗口为 hwndAutoCAD
//请在 AutoCAD 输入命令 (startExe "/c=dlg")
if(argv.c = "dlg"){
var path = fsys.dlg.open();
//把返回值写到标准输出
if(path) io.stdout.write(path);
}
else {
io.stdout.write("暂未支持此参数");
}
在 aardio 中创建一个空白工程,复制上面的代码到 main.aardio 中然后生成 EXE 就行了。
直接双击运行 EXE 文件会自动注册 startExe( cmdline ) 函数。
然后在 LISP 里可以这样调用:  - (startExe "/c=dlg")
这种方式调用过程中是阻塞状态,此时如果将任何窗口(不一定是 LISP 弹出的窗口)的父窗口设为 AutoCAD 主窗口都会卡死,直到执行的命令返回。所以这里没必要指定父窗口(准确说是所有者窗口)
|