找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 435|回复: 1

[讨论]:使用SDS进行二次开发

[复制链接]
发表于 2005-10-20 17:46:17 | 显示全部楼层 |阅读模式

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

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

×
一.概 述        2
二.使用SDS进行二次开发        2
SDS和ADS接口的主要差异        2
编译SDS应用程序        4
三.使用AUTOLISP进行开发        5
四.使用VBA/VB进行开发        5
五.ZWCAD的定制        6
屏幕菜单及其定制        6
IMAGE菜单(图标菜单)的定制        8
PROFILE的定制        9
ZWCAD.LSP和ZWCAD.SDS文件的作用和定制        11
别名的定制        11
其他定制        12












(内部参考)
一.概 述
   在zwcad上可以通过二次开发来定制和扩展zwcad的功能.当前的zwcad提供AutoLISP,SDS以及Visual Basic for Applications (VBA,COM)开发包进行二次开发.在zwcad上,你也可以使用许多原来在autocad平台上开发的应用程序.例如使用autolisp编制的程序可以在几乎不用修改的情况下移植到zwcad平台.Zwcad还完整支持AutoCAD Dialog Control (DCL)语言,不需修改. 目前的zwcad还不支持Object ARX,DBX.
二.使用SDS进行二次开发
SDS 是一个和ADS® (AutoCAD® Development System)开发包相兼容的C/C++语言接口. 大部分ads应用程序经过再编译可以直接应用于zwcad。中望建筑就是用sds sdk开发的。下面所述内容均以ads开发包为比较对象,以ads开发程序员为讲解对象.具体的sds函数说明请参考帮助文档.
SDS和ADS接口的主要差异
SDS和ADS的接口差异可以直接从sds.h和ads.h这两个头文件的比较得出.主要差异如下.
1.Sds开发包的接口函数以sds_为前缀.
Ads 开发包的接口函数主要以ads_, acad_, and acrx_等为前缀.
在sds.h中提供了移植ads用的宏
例如        #define ads_entdel        sds_entdel
这样只需要在ads应用程序源代码中将#include “ads.h” 以#include “sds.h”替换,并将要链接的库文件改为sds.lib编译链接即可完成从ads到sds的移植.
2.sds开发包主要扩展的函数
#if defined(_WINDOWS_)
        HDC *sds_getviewhdc(void);
        int sds_getrgbvalue(int nColor);        RGB       
        HPALETTE sds_getpalette(void);
        HWND sds_getviewhwnd(void);
        HWND sds_getmainhwnd(void);
        int sds_drawLinePattern(HDC h_dc, RECT rect, struct sds_resbuf *lineParam);
#endif

int  sds_setcallbackfunc(int (*cbfnptr)(int flag,void *arg1,void *arg2,void *arg3));
// Command Start/End.
#define SDS_CBCMDBEGIN   0  
// arg1="command name"         cast as (char *)
// Callback return  RTERROR will cause command to not be called.

#define SDS_CBCMDEND          1         
// arg1="command name"         cast as (char *)
// Return code does not matter.

// Mouse movements and Mouse buttons.
#define SDS_CBMOUSEMOVE       2         // arg1=X pixel  arg2=Y pixel
#define SDS_CBLBUTTONDN       3         // arg1=X pixel  arg2=Y pixel
#define SDS_CBLBUTTONUP       4         // arg1=X pixel  arg2=Y pixel
#define SDS_CBLBUTTONDBLCLK  5         // arg1=X pixel  arg2=Y pixel
#define SDS_CBRBUTTONDN       6         // arg1=X pixel  arg2=Y pixel
#define SDS_CBRBUTTONUP       7         // arg1=X pixel  arg2=Y pixel
……etc.
//进度条的控制.
int                 sds_progresspercent(int iPercentDone);

int                sds_progressstart(void);

int                 sds_progressstop(void);

//加载别名文件--pgp文件
int                sds_readaliasfile(char *szAliasFile);

//不同于sds_printf,这个函数可以发送命令,例如”LINE”
int                sds_sendmessage(char *szCommandMsg);

//在绘制窗口和命令历史窗口间切换焦点.
int                sds_swapscreen();

//组操作
int sds_createGroup(const char* pName, const char* pDescription, int selectable, int unnamed, sds_name sdsGroupName);
int sds_modifyGroup(const char* pNewName, const char* pNewDescription, int selectable, sds_name sdsGroupName);
int sds_addSSToGroup(sds_name ss, sds_name sdsGroupName);
int sds_removeSSFromGroup(sds_name ss, sds_name sdsGroupName);
int sds_getSSFromGroup(sds_name ss, sds_name sdsGroupName);
int sds_findGroup(const char* pName, sds_name sdsGroupName);
int sds_findGroupByEnt(sds_name entity, sds_name ssGroups);

//求实体交点
int sds_intersect(sds_name entFirst, sds_name entSecond, struct sds_resbuf **ptList);
//实体所占矩形空间
void sds_entextent(sds_name ename,  sds_point minPoint, sds_point maxPoint);

SDS不支持的ads函数主要有以下几个
int            ads_ssGetKwordCallbackPtr(struct resbuf* (**pFunc)(const char*));
int            ads_ssSetKwordCallbackPtr(struct resbuf* (*pFunc)(const char*));
int            ads_ssGetOtherCallbackPtr(struct resbuf* (**pFunc)(const char*));
int            ads_ssSetOtherCallbackPtr(struct resbuf* (*pFunc)(const char*));


adsw_acadMainWnd,                 //sds中使用 HWND sds_getmainhwnd(void);
and adsw_acadDocWnd.                //sds中使用  HWND sds_getviewhwnd(void);



注意一个函数
SDS:   int        sds_dictdel(const sds_name nmDict, const char *szDelThis);
ADS:  int    ads_dictremove (const ads_name dictname, const char* symname);

编译SDS应用程序
一般使用VC编译环境
主要做好sds头文件和库文件的路径设置,然后
#include “sds.h”
#pragma comment( lib,sds ) 或设置链接引用到sds.lib
OK
三.使用AutoLISP进行开发
zwcad提供了调用Autolisp程序的接口,可以将大部分的lisp程序正常执行,但需要注意以下事项
1. 最为重要的一点。Zwcad中的        LISP无法进行 COM调用,无法使用VLA开头的函数。因此,在ZWCAD中,你就不能通过lisp使用ACTICEX方式产生图元并用变量储存该图元的指针以进行以后的修改查询等操作,你只能使用COMMAND和ENTMAKE的方式进行产生图元,同时你只能使用图元名间接对图元进行操作。(VLISP 提供的 AutoLISP 扩展函数由曲线测量函数、数据转换函数、对象处理函数、特性处理函数、集合操作函数和词典函数组成。函数名以 vlax- 为前缀。这些函数和 ActiveX 方法都提供 vla-* 函数。有些 vlax-* 函数在使用 ActiveX 命令时是必需的。)
2.        无实现如VLISP中的反应器及其机制。
3.        Zwcad也并没有提供一个如acad中的visual lisp的编译环境,只能直接使用写好的的lisp程序。
4.        ZWCAD能加载未经加密的*.LSP文件或以“AutoCAD PROTECTED LISP file”方式加密的*.LSP文件。ZWCAD的LISP中能使用DCL文件。
5.        ZWCAD不能加载经AUTOCAD的VISUAL LISP编译集成的VISUAL LISP 可执行文件vax(一个或多个 LSP 文件和/或对话框控制语言 (DCL) 文件的编译集合。)
ZWCAD不能加载FAS 文件 (.fas) - 一个 LSP 程序文件的二进制编译版本。


四.使用VBA/VB进行开发
zwcad可以提供vba/vb支持,但是在一般的版本里没有提供.
重要区别:Automation对象不同.
使用支持vba版本的zwcad,最重要的是理解,zwcad里面的对象和acad的对象是不相同的.zwcad的对象和acad的对象可能在使用上和名字上有很多相似的地方,但是他们是不同的对象,有自己的唯一标识id.以前基于acad开发的vba/vb应用引用到的acad对象,其对象实现在acad里,不在zwcad里,所以不能把这些应用直接拿到zwcad上使用。另外,Acad中关于界面的对象如MenuBar,PopMenu,MenuGroup(s),Toolbar(s),PopMenuItem,ToolbarItem等对象在中望CAD中还没有实现.



五.ZWCAD的定制
屏幕菜单及其定制
zwcad提供一个和ACAD2000及以后版本类似的屏幕菜单.中望建筑软件使用了该功能,如右图所示.
功能详解:
1.样式如 的浅蓝色底,实心箭头朝下的按钮表明了当前激活的菜单.图中所示,尺寸标注为当前激活的菜单.除了顶级菜单按钮(这里是“中望建筑”)外,可以右键点击当前激活的菜单按钮,可以弹出其下的所有级别的菜单及菜单项.
2.带有  的按钮,左键点击可以进入的下一层菜单.右键点击可以弹出其下的所有级别的菜单及菜单项.
3.带有  的按钮是当前激活菜单的上级菜单.左键点击可以直接回到该菜单。右键点击可以弹出其下的所有级别的菜单及菜单项.
4.没有箭头的按钮是菜单命令项.左键点击执行命令。
   
中望CAD开始运行时,会检测当前目录下是否存在ScreenMnu.mnu文件,如果存在就会加载该菜单文件.
定制该文件主要注意事项
1.        可以使用/*…*/及//来注释内容
2.        MENU_TITLE指出该屏幕菜单的顶级文字,如中望建筑中为MENU_TITLE="中望建筑".
3.        ***SCREEN行下开始定义菜单
菜单项定义如下.
MENUITEM_ID       [MenuItemName]CommandString
MenuItemName是显示在屏幕菜单上的名称
CommandString是发送给命令行窗口的命令
如ID_Desaxis           [直线轴网]^C^C^Czhxzhw
如果要指明当前的项有子菜单可以使用->符号表明菜单进入点.如
ID_Axis           [->轴    网]
使用<-表明该菜单项为子菜单最后一项,如
ID_axin           [<-取消外偏]^C^C^Cqxwp
又如
ID_DELMDBT           [<-<-删除窗套]^C^C^Cshchcht
返回两级菜单.
子菜单可以嵌套但不可以交叉.
4.        ***RESOURCE行下开始定义图标
图标定义如下
MENUITEM_ID        ="MenuItemBmp.bmp"
只需要求菜单项定义中的ID和图标定义中的ID一致即可把图标和命令项联系起来.可以不给菜单项指定图标.
注意,位图必须位于当前目录下的子目录icon中.
5.        [--]行指明一个分割条
Image菜单(图标菜单)的定制
在***IMAGE行下开始定义图标菜单,格式同acad菜单文件.
例如一个简单的screenmnu.mnu文件如下

MENU_TITLE="Image Test"

// 屏幕菜单
***SCREEN
ID_TEST    [->Test]
ID_SCREENMENUITEM     [Item1]$I=JZD $i=*
ID_SCREENMENUITEM     [<-Item2]$I=WTBZ $i=*

***IMAGE
**JZD
[界址相关符号]
[cass2(jzd1,界址线)]^C^C^Pjzline;^P
[cass2(jzd2,街道线)]^C^C^Pdd;300010;^P
[cass2(jzd3,街坊线)]^C^C^Pdd;300020;^P
**WTBZ
[图标菜单项调用图标菜单]
[cass3(bz1,Test)]$i=JZD $i=*

***RESOURCE
ID_SCREENMENUITEM    ="1.bmp","欢迎"


点击Item1的效果如下


profile的定制
通过profile的定制可以在zwcad上指定菜单以及工具栏和指定支持路径(搜索路径). 定制profile的方法是:
1.        在程序图标的“目标”项加命令参数 “/p 配置项”( 配置项是字符串,如zwarch、zwfur等)和“起始位置”项加程序的工作路径(如右图),这样以“/p 配置项”来启动ZWCAD,ZWCAD会在注册表里的[HKEY_CURRENT_USER\Software\中望龙腾\ZWCAD]建立一个为“配置项” 的配置。
2.        在注册表里的[HKEY_CURRENT_USER\Software\中望龙腾\ZWCAD\配置项\Config]的"Menu File"项指定菜单位置(路径和名称不包括菜单的扩展名)和"Drawing"、"Font"、"Help"、"Xref"、"HatchPat"、"Blocks"指定相应的支持路径(搜索路径)路径间用分号连接。
下面以中望建筑软件为例说明:
“配置项”为ZWARCH
ZWCAD的安装路径为: “D:\Program Files\中望CAD\zwcad.exe”
中望建筑软件安装路径为: “D:\Program Files\中望建筑软件1.0”,要加载的菜单为ZWARCH.mnu。
1.程序图标项设置:
如:
目标:"D:\Program Files\中望CAD\zwcad.exe" /P ZWARCH
起始位置:"D:\Program Files\中望建筑软件1.0"
2.注册表项设置:
需在注册表里写以下注册项
[HKEY_CURRENT_USER\Software\中望龙腾\ZWCAD\ZWARCH\Config]
//菜单:
"Menu File"="D:\Program Files\中望建筑软件1.0\ZWARCH"  //菜单文件目录和文件名(不要加扩展名)"
//支持路径:
[HKEY_CURRENT_USER\Software\中望龙腾\ZWCAD\ZWARCH\Config]
"Drawings"="path1;path2..."
"Font"="path3;path4..."
"Help"="path3;path4..."
"Xrefs"="path5;path6..."
"Hatch patterns"="path7;path8..."
"Blocks"="path9;path10..."

zwcad.lsp和zwcad.sds文件的作用和定制
zwcad在每次打开或新建文件的时候,都会在当前路径搜索zwcad.lsp和zwcad.sds这两个文件,如果找到文件就加载.
对于zwcad.lsp,你可以用autolisp语言在里面作一些初始化的工作.
对于zwcad.sds,该文件其实是一个文本文件,每行是一个需要加载的sds应用程序的名称.例如目前中望建筑中使用的zwcad.sds内容如下:
extend.dll
archinit.dll

表明中望建筑中任何打开或新建文档都会先加载这两个应用程序.

发现的问题:
其实这些应用程序只需加载一次就可以了,如果打开或新建多个文档,后面的重复加载实际上是失败的也是多余的.
别名的定制
目前我还找不到一个仅仅使用pgp文件就能在zwcad开始运行时就加载的方式.
不过在sds中可以使用int sds_readaliasfile (char *filename)这个函数帮助加载.

其他定制
菜单(除了屏幕菜单和image菜单外),工具栏和快捷键的程序定制.
若前面的profile功能中使用acad菜单文件能正确识别里面的相关信息即可.目前还有待改善.
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
发表于 2005-10-21 00:49:15 | 显示全部楼层
看着眼熟...
不知道在那里见过~ 嘿嘿
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-9-23 00:26 , Processed in 0.339277 second(s), 34 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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