明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
123
返回列表 发新帖
楼主: 陨落

[函数] 我也来发一个多文件选择对话框,lisp+aardio实现

  [复制链接]
发表于 2022-2-13 04:14 | 显示全部楼层
今天改进了 aardio 标准库中的 com.cad 以及调用范例, LISP 调用 aardio 、aardio 调用 LISP 都更简单了。
前面帖子里的示例也已经更新。
发表于 2022-2-13 07:45 | 显示全部楼层
jun353835273 发表于 2021-6-1 13:05
c#的交互要方便的多
http://bbs.mjtd.com/thread-180931-1-1.html

不错,你的建议非常好。随手拿这个 C# 代码小试了一下,为了省事直接在 aardio 里编译 C# 为 DLL,然后自动并加载到 AutoCAD,然后再在 aardio 里调用 AutoCAD 再调用这个 C# 写的 DLL:
import console;
console.showLoading(
"正在编译 .Net DLL");

import dotNet;
import com.cad;

//创建 AutoCAD 对象
var cad = com.cad();
cad.Visible =
true;

//创建 C# 语言编译器
var compiler = dotNet.createCompiler("C#");
compiler.Reference(
"System.dll");
compiler.Reference(
"System.Windows.Forms.dll");
compiler.Reference(cad.Path,
"AcCui.dll");
compiler.Reference(cad.Path,
"AcDbMgd.dll");
compiler.Reference(cad.Path,
"AcMgd.dll");
compiler.Reference(cad.Path,
"AcCustomize.dll");
compiler.Reference(cad.Path,
"AcCoreMgd.dll");

compiler.Source =
/******
using System;
using System.Collections.Generic;
using System.Text;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Windows;
using Wnd = System.Windows.Forms;

public class TestFunctions
{
         [LispFunction("ListfunSelfiles")]
         public static ResultBuffer  ListfunSelfiles(ResultBuffer DataIn)
         {
             ResultBuffer Ret = new ResultBuffer();
             if (DataIn == null) return null;
             TypedValue[] Tranlisp = DataIn.AsArray();
             try
             {
                 if (Tranlisp.Length == 2)
                 {
                     string Title = Tranlisp[0].Value as string;
                     string Filter = Tranlisp[1].Value as string;
                     string FilterIn = "(*." + Filter + ")|*." + Filter;
                     Wnd.OpenFileDialog openDlg = new Wnd.OpenFileDialog();
                     openDlg.Title = Title;
                     openDlg.Filter = FilterIn;
                     openDlg.Multiselect = true;
                     Wnd.DialogResult openRes = openDlg.ShowDialog();
                     if (openRes == Wnd.DialogResult.OK)
                     {
                         string[] strNames = openDlg.FileNames;
                         for (int i = 0; i < strNames.Length; i++)
                         {
                             Ret.Add(new TypedValue((int)LispDataType.Text, strNames[ i ]));
                         }
                     }
                     else
                     {
                         return null;
                     }
                 }
             }
             catch (Autodesk.AutoCAD.Runtime.Exception)
             {
                 return null;
             }
                  return Ret;
         }
}

******/


var assembly = compiler.Compile("/ListfunSelfiles.dll"); //编译并返回程序集  
console.log(compiler.getLastError()); //查看编译器错误信息

cad.NetLoad(
"/ListfunSelfiles.dll");
cad.SendCommand(
`(ListfunSelfiles  "打开文本" "txt")`);

console.pause();





回复 支持 1 反对 0

使用道具 举报

发表于 2022-2-13 10:33 | 显示全部楼层
本帖最后由 liuyj 于 2022-2-13 10:46 编辑

我还以为只能编译为exe文件,这样就跟c#一样了。不对,还是通过exe调用dll文件与lisp交互,这样的好处是什么呢?
发表于 2022-2-13 14:26 | 显示全部楼层
本帖最后由 jacenhe 于 2022-2-13 14:32 编辑
liuyj 发表于 2022-2-13 10:33
我还以为只能编译为exe文件,这样就跟c#一样了。不对,还是通过exe调用dll文件与lisp交互,这样的好处是什 ...

我没说 aardio 是通过 DLL 文件与 LISP 交互.
我只是发了个 aardio 调用 C# 生成并调用 DLL 的例子,能这样做 -  不等于必须这样做,能理解吧?!
关于你说的通过 EXE 交互,我写了 3 个例子,都是使用 EXE( 并不是你说的  DLL )。

至于你说的 "好处是什么 ?"
你的问题就是让我 ”多发几个 aardio 与 LISP 交互的例子“
所以,我”多发了几个 aardio 与 与 LISP 交互的例子“,按你的要求多发几个例子,多几个选择有什么不好吗?
更多语言、更多方案可以支持 AutoCAD 总的来说都是好事,你选择适合你的方案就可以。



发表于 2022-2-13 14:31 | 显示全部楼层

LISP 调用 aardio 的三种方法

发表于 2022-2-14 09:06 | 显示全部楼层
本帖最后由 jun353835273 于 2022-2-14 09:07 编辑
jacenhe 发表于 2022-2-13 07:45
不错,你的建议非常好。随手拿这个 C# 代码小试了一下,为了省事直接在 aardio 里编译 C# 为 DLL,然后自 ...

这玩意还可以这样调用命令cad.SendCommand,感觉比调用控件方便些,控件win10有些不能注册
发表于 2022-2-14 12:36 | 显示全部楼层
jun353835273 发表于 2022-2-14 09:06
这玩意还可以这样调用命令cad.SendCommand,感觉比调用控件方便些,控件win10有些不能注册

aardio 里注册 COM 控件比较简单,不需要管理权限,可以用代码自动注册。
一般不会出现不能注册控件的问题,而且很多 COM 控件在 aardio 里都可以免注册调用。

发表于 2022-2-14 12:43 | 显示全部楼层

aardio 提供的 cad.SendCommand() ,cad.LoadLisp()  可以执行 LISP 代码,还能支持 aardio 的模板语法,
也就是可以将 LISP 代码与 aardio 代码混写,这有一点像 PHP 与 HTML 可以混写。例如:

cad.SendCommand(`
(setq c:hello nil)
(defun c:hello(/ name)
(set 'name (getstring "What's your name? "))
(set 'msg (strcat "Hello, " name <?=
time(),"这是 aardio 对象" ?>))
(write-line msg))
hello`
)


上面蓝色部分就是 aardio 代码,用这个方法就可以做很多事了,例如把 EXE 自身路径传给 LISP,就不再需要用 LISP 编码解码 EXE 的二进制数据了,速度可以大幅提升。


EXE 启动时就可以做太多事了,例如用 cad.LoadLisp() 加载 LISP 代码或 LISP 文件。可以用 cad.NetLoad 加载 C# 写的 DLL。都能自动识别版本,在需要时设置 SECURELOAD 开启并恢复权限、静默加载,不会弹出警告。


aardio 可以非常方便地打包外部文件生成独立 EXE 文件。
外部文件可以直接放到工程资源目录下 —— 通过 string.load("/res/xxxx") 函数加载。
也可以在文件路径前加一个 $ 将文件的二进制数据直接编译到程序里 —— 例如:$"/xxx/xxx.dll"。并且可以用  io.appData("xxx/xxx.dll", $"/xxx/xxx.dll") 运行时释放到 AppData 目录返回路径。

当然如果只是使用  cad.SendCommand() 这些 COM 接口,那外部文件也可以省了。





回复 支持 1 反对 0

使用道具 举报

发表于 2023-12-10 21:33 | 显示全部楼层
jacenhe 发表于 2022-2-12 12:08
@liuyj
这里说的是在 lisp 里调用 EXE ,如果你没传参数,直接双击运行 EXE,就会出现你那个错误。


import io;
import win;
//自标准输入读取 LISP 传入的值
var hwnd = io.stdin.read("%d");
win.msgbox(hwnd);
/////////////////////////////////
以上代码生成exe后执行【(startapp "D:/CAD.exe" (strcat "/hwnd" " " (itoa(vla-get-hwnd(vlax-get-acad-object)))))】
并没有把CAD窗口句柄传递给exe

本帖子中包含更多资源

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

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

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-5-7 22:36 , Processed in 0.667783 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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