找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 487|回复: 0

[ARX程序]:一个基于AutoCAD PDB对话框的综合应用程序,

[复制链接]
发表于 2002-12-28 13:02:40 | 显示全部楼层 |阅读模式

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

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

×
  1. [font=courier new]
  2. //*******************************************************************
  3. // 文件名称:Mydcl.cpp
  4. //*******************************************************************
  5. #include < stdio.h>
  6. #include "adslib.h"
  7. #include "rxdefs.h"
  8. #include "adsdlg.h"
  9. #include "string.h"
  10. #include < stdlib.h>                                                   

  11. #define ELEMENTS(array) (sizeof(array)/sizeof((array)[0]))
  12. #define Cpoint(d, s) { d[X]=s[X]; d[Y]=s[Y]; d[Z]=s[Z];}               
  13. #define Spoint(d, x,y,z) { d[X]=(x); d[Y]=(y); d[Z]=(z);}              

  14. struct func_entry { char *func_name;
  15.     int (*func) ();
  16. };

  17. int mydcl();
  18. void set_size0();   
  19. void CALLB size_list_cb(ads_callback_packet *cpkt);
  20. void CALLB size_usr_cb(ads_callback_packet *cpkt);
  21. void CALLB size_usr_accept_cb(ads_callback_packet *cpkt);
  22. void CALLB size_accept_cb(ads_callback_packet *cpkt);
  23. int draw_size(ads_point, int, int, short, short,
  24.               char, char, ads_real);
  25. int dofun();
  26. int funcload();

  27. static struct func_entry func_table[] = {
  28.     {"c:MYDCL", mydcl},
  29. };
  30. ads_real scale;  //比例值


  31. extern "C" AcRx::AppRetCode
  32. acrxEntryPoint(AcRx::AppMsgCode msg, void* ptr)
  33. {
  34.     switch(msg) {
  35.     case AcRx::kInitAppMsg:
  36.         acrxUnlockApplication(ptr);
  37.         break;
  38.     case AcRx::kInvkSubrMsg:
  39.         dofun();
  40.         break;
  41.     case AcRx::kLoadADSMsg:
  42.         funcload();
  43.     }
  44.     return AcRx::kRetOK;
  45. }

  46. static int funcload()
  47. {
  48.     int i;
  49.     for (i = 0; i <  ELEMENTS(func_table); i++) {
  50.         if (!acedDefun(func_table[i].func_name, (short)i))
  51.             return RTERROR;
  52.     }
  53.     return RTNORM;
  54. }

  55. static int dofun()
  56. {
  57.     int val;

  58.     if ((val = acedGetFunCode()) <  0 || val >= ELEMENTS(func_table))
  59.     {
  60.         acdbFail("收到不存在的函数代码.");
  61.         return RTERROR;
  62.     }

  63.     val = (*func_table[val].func)();

  64.     return val;
  65. }

  66. int mydcl()
  67. {
  68.     set_size0();
  69.     return RSRSLT;
  70. }

  71. //.................... 图7-2及图7-3的驱动程序 ....................
  72. static struct size_list {   //图幅尺寸的数据结构
  73.   char *name;   //图幅名称
  74.   int hor;      //图纸水平长度
  75.   int ver;      //图纸纵向长度
  76.   short a;      //图框到图纸左边界距离
  77.   short c;      //图框到图纸上,下,右边界距离
  78. } size_list[] = {
  79.   {"A0",1189,841,25,10},   //A0,A1,...幅面的尺寸
  80.   {"A1",841,594,25,10},
  81.   {"A2",594,420,25,10},
  82.   {"A3",420,297,25,5},
  83.   {"A4",210,297,25,5},
  84.   {"A5",210,148,25,5},
  85.   {"USR",1189,841,25,10},  //用户自定义幅面,在此借用A0,可动态修改     
  86. };
  87. #define SIZE_L 7      //常用图幅的数目
  88. static int size=0;    //A0到USR共7种图幅的序号
  89. static char style;    //图纸布置方式,1=正常(水平);0=转置(竖置)
  90. static char head;     //标题栏,1=格式A(标准格式);0=格式B
  91. ads_hdlg  hdlg,hdlg1;   //对话框handle,因需嵌套显示,故设为全局变量
  92. int dcl_id;             //对话框文件标识字,理由同上
  93. int dlg_status,dlg_status1;   //对话框显示状态标志,理由同上
  94. char tbuf[80];      //全局性的自由变量

  95. // *** 用于图幅及标题栏前置设定的主函数 ***
  96. void set_size0()   
  97. {
  98.   ads_point pt_temp1={0,0,0};   //绘制图幅外边界时,左下角点坐标
  99.   int i;
  100.   struct resbuf rb;    //供存取AutoCAD系统变量之用

  101.   if(ads_load_dialog("Mydcl.dcl", &dcl_id)!=RTNORM) {   
  102.                                  //将对话框文件Mydcl.dcl调入内存
  103.     acedAlert("装入Mydcl.dcl文件出错.");
  104.     return;
  105.   }
  106.   if(ads_new_dialog("set_size0",dcl_id,(CLIENTFUNC)0,&hdlg)!=RTNORM) {
  107.                                                 //显示对话框,图7-2
  108.     acedAlert("显示set_size0对话框时出错.");
  109.     ads_unload_dialog(dcl_id);  //卸载对话框文件
  110.     return;
  111.   }
  112.   ads_action_tile(hdlg, "list", (CLIENTFUNC)size_list_cb);  
  113.                   //将对话框中"list栏"与回调函数size_list_cb()相关联
  114.   ads_action_tile(hdlg, "accept", (CLIENTFUNC)size_accept_cb);
  115.                 //将对话框的"OK按钮"与回调函数size_accept_cb()相关联
  116.   ads_action_tile(hdlg, "usr", (CLIENTFUNC)size_usr_cb);  
  117.           //"usr"与函数size_usr_cb()相关联,实现用户自定义USR图幅尺寸
  118.   ads_start_list(hdlg, "list", LIST_NEW, 0);
  119.                              //初始化"list栏"中各项数据
  120.   for (i=0;i< SIZE_L;++i) {
  121.     sprintf(tbuf,"%s(%dX%d)",size_list[i].name,size_list[i].hor,
  122.                   size_list[i].ver);
  123.     ads_add_list(tbuf);  //向list栏加入表项
  124.   }
  125.   ads_end_list();   //表的初始化工作结束
  126.   ads_set_tile(hdlg, "edit", size_list[size].name); //为"edit"赋初值
  127.   sprintf(tbuf,"%d",size);
  128.   ads_set_tile(hdlg,"list", tbuf);     //为"list"赋初值
  129.   ads_start_dialog(hdlg, &dlg_status);   //与对话框进行交互
  130.   ads_unload_dialog(dcl_id);    //当对话框关闭后,清理内存

  131.   acedGetVar("DIASTAT",&rb);   
  132.   if(rb.resval.rint==0) {
  133.     acedRetVoid();    //直接返回AutoLISP,不回显nil
  134.     return;      //CANCEL结束对话框,返回
  135.   }
  136.   acedGetVar("userr1",&rb);  //从系统变量userr1获取当前使用的比例值
  137.   scale=rb.resval.rreal;
  138.   if(scale==0.0) scale=1.0;
  139.   acedCommand(RTSTR,"ERASE",RTSTR,"ALL",RTSTR,"",0);
  140.                          //清屏后,调draw_size()函数绘图框和标题栏等
  141.   if(draw_size(pt_temp1,size_list[size].hor,size_list[size].ver,
  142.       size_list[size].a,size_list[size].c,style,head,scale)!=RTERROR)  
  143.     acedCommand(RTSTR,"ZOOM",RTSTR,"ALL",0);
  144.   acedRetVoid();   
  145.   return;
  146. }

  147. // *** 图幅对话框"list"列表栏所对应的回调函数size_list_cb() ***
  148. void CALLB size_list_cb(ads_callback_packet *cpkt)
  149. {                                      
  150.   if (cpkt->value == NULL || cpkt->value[0] == EOS)
  151.       return ;
  152.   ads_set_tile(cpkt->dialog,"edit",size_list[atoi(cpkt->value)].name);
  153.                                     //用"list"中的比例值更新"edit"
  154. }

  155. // *** 图幅对话框"usr"所对应的回调函数size_usr_cb() ***
  156. void CALLB size_usr_cb(ads_callback_packet *cpkt)
  157. {
  158.   short sht1,sht2;      //对话框中幻灯片的尺寸
  159.   ads_set_tile(cpkt->dialog, "edit", size_list[SIZE_L-1].name);
  160.                         //首先将主对话框中的"edit"一项用"USR"更新
  161.   ads_new_dialog("set_size0_a", dcl_id, (CLIENTFUNC)0, &hdlg1);
  162.                                            //显示子对话框,图7-3
  163.   ads_action_tile(hdlg1, "accept", (CLIENTFUNC)size_usr_accept_cb);
  164.   itoa(size_list[SIZE_L-1].hor,tbuf,10);
  165.   ads_set_tile(hdlg1, "H", tbuf);
  166.   itoa(size_list[SIZE_L-1].ver,tbuf,10);
  167.   ads_set_tile(hdlg1, "V", tbuf);
  168.   itoa(size_list[SIZE_L-1].a,tbuf,10);
  169.   ads_set_tile(hdlg1, "a", tbuf);
  170.   itoa(size_list[SIZE_L-1].c,tbuf,10);
  171.   ads_set_tile(hdlg1, "c", tbuf);
  172.                           //上面几行是用USR图幅原值初始化对话框各项
  173.   ads_dimensions_tile(hdlg1,"image",&sht1,&sht2);    //显示幻灯片
  174.   ads_start_image(hdlg1,"image");
  175.   ads_slide_image(0,0,sht1,sht2,"set_size"); //幻灯片名为SET_SIZE.SLD
  176.   ads_end_image();
  177.   ads_start_dialog(hdlg1, &dlg_status1);    //与对话框进行交互
  178.   ads_start_list(hdlg, "list", LIST_CHANGE, SIZE_L-1);
  179.                             //改变主对话框"list栏"中USR图幅尺寸数字
  180.   sprintf(tbuf,"%s(%dX%d)",size_list[SIZE_L-1].name,
  181.                 size_list[SIZE_L-1].hor,size_list[SIZE_L-1].ver);
  182.   ads_add_list(tbuf);
  183.   ads_end_list();
  184.   sprintf(tbuf,"%d",SIZE_L-1);
  185.   ads_set_tile(hdlg,"list", tbuf); //将主对话框的光标置于"list"的USR
  186. }

  187. // *** 自定义图幅对话框"OK按钮"所对应的回调函数size_accept_a_cb() ***
  188. void CALLB size_usr_accept_cb(ads_callback_packet *cpkt)
  189. {            
  190.   ads_get_tile(cpkt->dialog, "H", tbuf, MAX_TILE_STR);
  191.   size_list[SIZE_L-1].hor=atoi(tbuf);
  192.   ads_get_tile(cpkt->dialog, "V", tbuf, MAX_TILE_STR);
  193.   size_list[SIZE_L-1].ver=atoi(tbuf);
  194.   ads_get_tile(cpkt->dialog, "a", tbuf, MAX_TILE_STR);
  195.   size_list[SIZE_L-1].a=atoi(tbuf);
  196.   ads_get_tile(cpkt->dialog, "c", tbuf, MAX_TILE_STR);
  197.   size_list[SIZE_L-1].c=atoi(tbuf);
  198.             //获取各控件的值,送至结构变量size_list[]
  199.   ads_done_dialog(cpkt->dialog,3);    //关闭子对话框
  200. }

  201. // *** 图幅对话框"OK按钮"所对应的回调函数size_accept_cb() ***
  202. void CALLB size_accept_cb(ads_callback_packet *cpkt)
  203. {
  204.   int i;
  205.   ads_get_tile(cpkt->dialog, "edit", tbuf, MAX_TILE_STR);
  206.   for(i=0;i< SIZE_L;i++) {    //根据图幅名称,获取用户选定的图幅的序号
  207.     if(stricmp(tbuf,size_list[i].name)==0) {
  208.       size=i;
  209.       break;
  210.     }
  211.   }
  212.   if(i!=size) size=SIZE_L-1;
  213.   if(size_list[size].hor< =25||size_list[size].ver< =10) {
  214.     acedAlert("自定义尺寸有误.");
  215.     return;
  216.   }
  217.   ads_get_tile(cpkt->dialog, "style", tbuf, MAX_TILE_STR);  
  218.   style=tbuf[0];    //图纸布置方式
  219.   ads_get_tile(cpkt->dialog, "head_a", tbuf, MAX_TILE_STR);  
  220.   head=tbuf[0];     //标题栏格式
  221.   ads_done_dialog(cpkt->dialog,1);   //正常关闭对话框
  222. }

  223. // *** 绘制图幅外边界,图框,标题栏 ***
  224. int draw_size(ads_point pt_temp1, int hor, int ver, short a, short c,
  225.               char style, char head, ads_real scale)
  226. {      //传递参数依次为: 左下角点坐标,水平长度,纵向长度,至左边界距离,
  227.        //           至其它三边的距离,图纸布置方式,标题栏格式,绘图比例
  228.   ads_point pt0,pt1,pt2,pt3;
  229.   int int1;
  230.   char head_name[12];  //DWG格式标题栏图块名称
  231.   ads_name ss,e0,e1;   //选择集和实体名称

  232.   if(style!='1') {     //图纸转置90度
  233.     int1=hor;
  234.     hor=ver;
  235.     ver=int1;
  236.   }
  237.   if(head=='1') strcpy(head_name,"head_a.dwg");   //标题栏格式A
  238.   else strcpy(head_name,"head_b.dwg");       //标题栏格式B
  239.   if(acedFindFile(head_name,tbuf)!=RTNORM) {  //在盘上查找标题栏图块
  240.     sprintf(tbuf,"file < %s> not existed.",head_name);
  241.     acedAlert(tbuf);
  242.     return RTERROR;
  243.   }
  244.   
  245.   Cpoint(pt0,pt_temp1);   //对图幅外边界四角点X,Y,Z坐标赋值
  246.   Spoint(pt1,pt0[X]+hor,pt0[Y],0);
  247.   Spoint(pt2,pt0[X]+hor,pt0[Y]+ver,0);
  248.   Spoint(pt3,pt0[X],pt0[Y]+ver,0);

  249.   acedCommand(RTSTR,"COLOR",RTSTR,"YELLOW",0);

  250.   acedCommand(RTSTR,"LINE",RTPOINT,pt0,RTPOINT,pt1,0);  //画外边界线
  251.   acdbEntLast(e0);    //为后续生成ss选择集而保存第一个实体的名称
  252.   acedCommand(RTPOINT,pt2,RTPOINT,pt3,RTSTR,"C",0);
  253.   Spoint(pt0,pt0[X]+a,pt0[Y]+c,0);
  254.   Spoint(pt1,pt1[X]-c,pt1[Y]+c,0);
  255.   Spoint(pt2,pt2[X]-c,pt2[Y]-c,0);
  256.   Spoint(pt3,pt3[X]+a,pt3[Y]-c,0);

  257.   acedCommand(RTSTR,"COLOR",RTSTR,"WHITE",0);

  258.   acedCommand(RTSTR,"LINE",RTPOINT,pt0,RTPOINT,pt1,RTPOINT,pt2,
  259.               RTPOINT,pt3,RTSTR,"C",0);        //绘图框线
  260.   acedCommand(RTSTR,"LINE",RTPOINT,pt3,RTSTR,"@40< 0",RTSTR,"@12< -90",
  261.               RTSTR,"@40< -180",RTSTR,"@12< 90",RTSTR,"",0);//绘图号区
  262.   acedCommand(RTSTR,"INSERT",RTSTR,head_name,RT3DPOINT,pt1,
  263.               RTSTR,"",RTSTR,"",RTSTR,"",0);     //插入标题栏图块
  264.   acedCommand(RTSTR,"COLOR",RTSTR,"BYLAYER",0);
  265.   acedSSAdd(NULL,NULL,ss);    //构造空的选择集ss
  266.   do {     //生成包含所有新实体(图框,标题栏等)的选择集,送ss之中
  267.     acedSSAdd(e0,ss,ss);
  268.     acdbNameSet(e0,e1);
  269.   } while(acdbEntNext(e1,e0)==RTNORM);
  270.   acedCommand(RTSTR,"SCALE",RTPICKS,ss,RTSTR,"",RTPOINT,pt_temp1,
  271.               RTREAL,1.0/scale,0);  //对图框和标题栏等进行反比例缩放
  272.   acedSSFree(ss);   //释放选择集ss
  273.   return RTNORM;
  274. }
  275. [/font]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-11-15 13:00 , Processed in 0.342696 second(s), 32 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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