VB在ACADWIN中的应用方法
北京钢铁设计研究总院工业炉室 吴启明
AUTOCAD 是 一 个 常 用 工 业 绘 图 平 台, 用 户 在 使 用 时 经 常 要 用Lisp 或ADS 进 行 二 次 开 发, 但Lisp 处 理 数 据 库 能 力 差, 编 制 界 面 困 难, 计 算 慢, 而ADS 要 求 较 高 .VB 编 写 独 立 程 序 的 速 度 快, 编 制 界 面 容 易。 可 以 快 速 计 算, 可 操 作 数 据 库 等 优 点,ACADWIN 为 AUTOCAD 的WINDOWSD 版 程 序, 有 着WINDOWS 的 许 多 特 点。 利 用DDE 来 进 行VB 与ACADWIN 之 间 的 通 讯, 来 实 现 编 程 不 失 为 一 个 好 方 法。
因 为ACADWIN R12 不 支 持 如 PastLink 的 直 接DDE 方 法, 要 有 一 个 控 件 与VB 相 联 系, 利 用 该 控 件 进 行 数 据 传 递。 主 要 用 到 以 下 几 个 文 件:
1):DDEBAS.EXE 这 是VB/DDE 服 务 者, 必 须 在 运 行VB 应 用 程 序 前 调 入, 在 命 令 行 键 入:(XLOAD“DDEBAS”).
2):ACADVB.DLL,VB 应 用 程 序 的 动 态 连 接 库.
3):GLOBAL.BAS,VB 应 用 程 序 的 全 程 变 量 的 定 义 文 件.
4):ADSFUNCS.BAS,VB 应 用 程 序 对ADS 库 标 准 函 数 的 调 用.
5):ADSFUNCS.FRM, 标 准ACADWIN 的 初 始VB 窗 口。
6):NEW.FRM, 用 于 新 建 标 准 初 始VB 窗 口。
后 四 个 文 件 在ACADWIN/VB/NEW 目 录 下, 编 程 时 只 要 打 开NEWPROJ.MAK 就 都 有 了, 但NEW.FRM 可 以 不 要, 只 要 把 启 动 文 件 定 为ADSFUNC.FRM.
为 了 实 现DDE 通 讯, 先 要 在ADSFUNCS.FRM 中 增 加 一 个 用 于 通 讯 的TEXT( 文 本 框) 控 件, 并 在 特 性 表 中 将 其NAME 命 名 为ACADTEXT,TEXT 的CAPTION 置 为 空 串( 减 少 窗 体 不 必 要 的 信 息),VISIBLE 特 性 呈 为TURE。 用LINKAPP 函 数 初 始 化 以 及 关 闭 连 接:
增加一个过程 linkapp,其中代码如下: sub linkapp(link as contonl,appname as string,topic as string) link.linkmode=0 '关闭通讯 link.linktopic=appname+"|"+topic '置通讯主题 link.linkmode=2 '手工通讯 end sub 增加一个过程unlinkapp,其中代码如下: sub unlinkapp(link as contonl) link.linkmode=0 '关闭通讯 end sub 在窗体事件中,增加如下代码: sub form_load() LINKAPP ACADTEXT,"AUTOCAD.DDE","SYSTEM" end sub sub form_unload(cancel as integer) UNLINKAPP ACADTEXT end sub 如画圆“CIRCLE”,先在ADSFUNC.FRM中增加一个命令钮COMMAND1,将 其CAPTION置为“CIRCLE”,在子过程中增加以下代码: SUB COMMAND1_CLICK() ACADTEXT.LINKEXECUTE "[^3^3 CIRCLE]" END SUB
至 此 可 以 实 现 的 绘 图 命 令, 明 显 如 果 要 实 现 的 复 杂 功 能, 捕 捉 特 征 点,获 得 特 性, 参 数 化 绘 图, 这 样 就 可 复 杂 了, 能 否 让 完 成 界 面 及 计 算 功 能, 把 参 数 传 给 一 个Lisp 程 序, 然 后 再 将 程 序 调 入 环 境 中, 完 成 绘 图 呢 ? 这 是 可 以 的, 这 就 要 用 到"SendKey" 语 句。 该 语 句 功 能 是 向 具 有 焦 点 的 窗 口 发 送 字 符, 就 象 从 键 盘 中 键 入 一 样。 这 时 先 用 函 数FindACAD() 找 到ACADWIN 的 句 柄, 再 用AcadACTIVE 函 授 激 活ACADWIN, 使 其 具 有 焦 点, 这 时 就 可 以 用SendKey 了。
如 有 一 个Lisp 程 序YZ.LSP, 主 函 授 为"C:YZ()", 可 先 在ADSFUNC.FRM 中 增 加 一 个 命 令 钮COMMAND2, 将 其CAPTION 置 为“YZ”, 在 子 过 程 中 增 加 以 下 代 码:
SUB COMMAND2_CLICK()
hwndAcad%=FindAcad()
AcadActivate(hwndAcad%)
SendKeys "{(}load+'yz+'{)}", -1
SendKeys "{enter}", -1
SendKeys "yz", -1
END SUB
笔 者 运 用 此 方 法 成 功 地 编 写 程 序, 通 过VB 的 界 面 选 取 参 数, 进 行 计 算,Lisp 进 行 绘 图。 有 两 个 问 题 值 得 注 意: 一: 如 要 进 行 参 数 的 传 递, 可 以 先 用VB 写 临 时 数 据 文 件, 再 用Lisp 读 此 临 时 数 据 文 件。
使ACADWIN 和VB 应 用 程 序 两 者 同 时 都 可 见 到,Lisp 程 序 执 行 完 毕, 不 能 自 动 回VB 应 用 程 序, 这 时 可 以 通 过 调 用 的API 函 数SetWindowPos 来 使 应 用 程 序 总 浮 在 最 上 面, 避 免 了 来 回 切 换 窗 口, 这 在 本 报 已 有 介 绍.
在ADSFUNCS.BAS 中 也 定 义 了 很 多ADS 函 授, 可 供 调 用。 如ACADWIN\VB\ASVU 中 有 一 个 例 子ASVU.EXE, 就 是 应 用Ads_getvar 及Ads_setvar 函 数, 可 以 打 开SYSVARS.MAK 中intervai.bas 看 到。 但DDE 的 链 接 的 方 式 要 改 变, 在 启 动 窗 体 或 函 授 中 加 上:
DDE_TIMEOUT=-1 '等待一个DDE事件
openDDE 'ADSFUNCS.BAS中一个函数,初始化DDE链接。
( 北 京 钢 铁 设 计 研 究 总 院 工 业 炉 室 吴 启 明 100053)