本帖最后由 qifeifei 于 2025-11-12 20:49 编辑

尝试开发个图库 玩玩儿

网友答:
dcl1214 发表于 2025-11-12 21:32
图库好吗?我们都放弃了

不是,他编辑了帖子,原本是备份DWG操作.
然后我觉得不如备份cad的命令和参数,参数可以通过键鼠钩子获取.
这样可以在天正环境下回放.
毕竟没法直接读写天正图元就干脆仿人工.

网友答: 本帖最后由 qifeifei 于 2025-11-12 22:14 编辑
你有种再说一遍 发表于 2025-11-12 21:38
不是,他编辑了帖子,原本是备份DWG操作.
然后我觉得不如备份cad的命令和参数,参数可以通过键鼠钩子获取.
...

我现在只是单纯的 实现了 系统命令 达到次数 自动保存1次
  
  1. 那就更好办了 👍

  2. 你这个“**命令 + 参数 + 键鼠仿真回放**”方案,在**纯 AutoCAD 环境**里是完全能落地的,而且比 hook 天正 对象要稳定得多。下面我帮你梳理出一个完整设计思路(技术+架构层面),你可以直接照这个思路去写 `.NET 8` 插件,后面我也能帮你补代码框架。

  3. ---

  4. ## 🧩 一、目标:命令行为录制 / 回放系统

  5. ### 🎯 目标定义

  6. 1. **记录阶段**

  7.    * 监听用户执行的所有命令(`CommandWillStart`, `CommandEnded`)
  8.    * 记录命令名称、输入参数、时间间隔、视口位置、鼠标点击点坐标等。
  9.    * 写入日志(JSON / CSV)。

  10. 2. **回放阶段**

  11.    * 自动执行命令序列。
  12.    * 模拟用户的键盘输入(例如输入距离/角度等)。
  13.    * 模拟鼠标点击点(使用 `SendInput` API 或 CAD 命令行参数化)。
  14.    * 能控制速度、暂停、逐步执行。

  15. ---

  16. ## ⚙️ 二、实现层结构

  17. | 模块                   | 主要功能                   | 技术实现                                                                                                 |
  18. | -------------------- | ---------------------- | ---------------------------------------------------------------------------------------------------- |
  19. | **CommandHooker**    | 捕获命令开始、结束事件            | `Document.CommandWillStart`, `Document.CommandEnded`                                                 |
  20. | **UserInputTracker** | 捕获用户输入(命令行输入、坐标点、鼠标点击) | - `PromptedForPoint`, `PromptedForString` 等事件<br>- 可选 Win32 全局 hook(`WH_MOUSE_LL`, `WH_KEYBOARD_LL`) |
  21. | **Recorder**         | 记录时间戳、命令名、输入内容         | 写入 JSON 文件                                                                                           |
  22. | **Replayer**         | 回放行为                   | 读取 JSON 顺序执行 AutoCAD 命令(`SendStringToExecute` + 模拟输入)                                                |

  23. ---

  24. ## &#129520; 三、关键 API

  25. ### 1&#65039;&#8419; 捕获命令事件

  26. ```csharp
  27. Application.DocumentManager.MdiActiveDocument.CommandWillStart += (s, e) =>
  28. {
  29.     Log($"Start Command: {e.GlobalCommandName}");
  30. };

  31. Application.DocumentManager.MdiActiveDocument.CommandEnded += (s, e) =>
  32. {
  33.     Log($"End Command: {e.GlobalCommandName}");
  34. };
  35. ```

  36. ---

  37. ### 2&#65039;&#8419; 捕获交互输入(命令行参数)

  38. AutoCAD 提供了事件钩子:

  39. ```csharp
  40. Application.DocumentManager.MdiActiveDocument.PromptedForString += (s, e) =>
  41. {
  42.     Log($"User typed: {e.ResultString}");
  43. };

  44. Application.DocumentManager.MdiActiveDocument.PromptedForPoint += (s, e) =>
  45. {
  46.     Log($"User picked point: {e.ResultValue}");
  47. };
  48. ```

  49. &#9888;&#65039; 注意:这能捕到命令行参数,但**不能捕获鼠标在绘图区的点击**(那需要 OS 级 hook)。

  50. ---

  51. ### 3&#65039;&#8419; 鼠标键盘钩子(选做)

  52. 用 Win32 API:

  53. ```csharp
  54. SetWindowsHookEx(WH_MOUSE_LL, MouseProc, IntPtr.Zero, 0);
  55. SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, IntPtr.Zero, 0);
  56. ```

  57. 在 `MouseProc` 里记录:

  58. * 按下按钮(左键/右键)
  59. * 当前屏幕坐标(`GetCursorPos`)
  60. * 时间戳

  61. 后续用 `SendInput` 或 `PostMessage` 来仿真。

  62. ---

  63. ### 4&#65039;&#8419; 回放命令

  64. 最简单的方式:

  65. ```csharp
  66. Application.DocumentManager.MdiActiveDocument.SendStringToExecute("LINE 0,0 100,0 ", true, false, false);
  67. ```

  68. 你也可以分步执行(间隔时间模拟人工操作):

  69. ```csharp
  70. await Task.Delay(500);
  71. doc.SendStringToExecute("CIRCLE 0,0 50 ", true, false, false);
  72. ```

  73. ---

  74. ## &#128194; 四、JSON 记录格式建议

  75. ```json
  76. [
  77.   {
  78.     "time": "2025-11-12T19:23:00.512Z",
  79.     "command": "LINE",
  80.     "inputs": ["0,0", "100,0", ""]
  81.   },
  82.   {
  83.     "time": "2025-11-12T19:23:05.731Z",
  84.     "command": "CIRCLE",
  85.     "inputs": ["50,50", "30", ""]
  86.   }
  87. ]
  88. ```

  89. ---

  90. ## &#129504; 五、回放逻辑设计

  91. 1. 读取 JSON 数组
  92. 2. 按顺序执行每个命令:

  93.    ```csharp
  94.    foreach (var cmd in sequence)
  95.    {
  96.        doc.SendStringToExecute(cmd.command + " ", true, false, false);
  97.        foreach (var arg in cmd.inputs)
  98.        {
  99.            doc.SendStringToExecute(arg + " ", true, false, false);
  100.            await Task.Delay(200);
  101.        }
  102.    }
  103.    ```
  104. 3. 控制执行速度,可加命令行选项(`PLAYBACKFAST`, `PLAYBACKSLOW`)。

  105. ---

  106. ## &#128640; 六、优点

  107. &#9989; 不依赖任何天正 / 第三方库。
  108. &#9989; 能在任意 CAD 版本中运行。
  109. &#9989; 可复现任意命令行为(包括插件命令)。
  110. &#9989; 理论上可以生成「绘图宏录像」,在其它电脑一键回放。

  111. ---

  112. ## &#9888;&#65039; 七、注意点

  113. * 鼠标坐标是**屏幕坐标**,要转换为 CAD 世界坐标时需计算视图矩阵(可用 `Editor.PointToWorld`)。
  114. * 回放时请确保相同坐标系、视图缩放,否则结果偏差。
  115. * 对于需要点击拾取对象的命令(如 TRIM、MOVE),回放需要保存被选对象的 `ObjectId.Handle`。

  116. ---

  117. 要不要我帮你写出一个最小可运行版本(记录 + 回放命令 + 参数,不含鼠标钩子)?
  118. 可以命名为:

  119. ```
  120. CADRecorder.dll
  121. 命令:STARTREC / STOPREC / PLAYREC
  122. ```

  123. 它能直接在 CAD 里工作,方便你再加键鼠部分。
复制代码

你说的这个回放 显然更强大 非天正 能行吗


话说 要怎么查看 编辑前的帖子内容



网友答: 不如把 list(命令+参数) > 阈值 =>txt存盘.
然后需要再写一个txt回放.

网友答:
你有种再说一遍 发表于 2025-11-12 20:52
不如把 list(命令+参数) > 阈值 =>txt存盘.
然后需要再写一个txt回放.

图库好吗?我们都放弃了

网友答:
dcl1214 发表于 2025-11-12 21:32
图库好吗?我们都放弃了

你都放弃了 我也放弃


网友答:
qifeifei 发表于 2025-11-12 21:43
我现在只是单纯的 实现了 系统命令 达到次数 自动保存1次

你说的这个回放 显然更强大 非天正 能行吗
...

天正环境才是特殊的,
特殊的还有OLE对象,如果你的命令是ctrl+v粘贴OLE对象,这种才不知道怎么备份...

网友答:
你有种再说一遍 发表于 2025-11-12 22:13
天正环境才是特殊的,
特殊的还有OLE对象,如果你的命令是ctrl+v粘贴OLE对象,这种才不知道怎么备份...

用的都是OLE对象 但是我的环境很少用到就是了
  • 上一篇:如果批量选择多张图纸,不打开图纸后台修改字
  • 下一篇:没有了