一步步学习MDL[4]

时间:2022-04-07 03:22:20

第四章、给MDL应用添加命令

您可能已经注意到了MicroStation中存在着许多键入命令。选菜单Utilities > Key-in可打开键入命令对话框,在这里可浏览并执行当前可用的所有键入命令,

如下图所示。虽然该对话框中只列出了四栏,但实际上每个键入命令最多可由5个单词组成。

一步步学习MDL[4]

这些键入命令有许多用途。比如在交互操作中可随时键入一个命令来实现操作的一个步骤,比如可以写一个由键入命令组成的脚本文件在MicroStation中直接执行,比如执行批处理功能时需要指定一个命令文件,再比如每个菜单项或工具栏中的每个图标工具,它们后台都关联着键入命令。可以这样说,键入命令是MicroStation图形用户界面与后台执行代码的重要纽带。以上列举的键入命令的四种用途分别如下图所示:

一步步学习MDL[4]

一步步学习MDL[4]

一步步学习MDL[4]

下面我们就一步步地在现有HelloWorld项目的基础上对其增加命令功能。

1. 在Visual Studio中打开您的HelloWorld项目,在解决方案浏览器中右击Resource Files文件夹并在弹出的菜单中选择Add New Item,在出现的窗体中找到并选中Text File (.txt)并在名称栏中输入HelloWorldCmd.r后点击Add按钮为当前工程添加一个空的.r文件。如下图所示:

一步步学习MDL[4]

2. 将如下命令表内容复制并粘贴到您的HelloWorldCmd.r文件中。保存该文件。

#include <rscdefs.h>

#include <cmdclass.h>

/*----------------------------------------------------------------------+

|   Local Defines                                                       |

+----------------------------------------------------------------------*/

#define CT_NONE             0

#define CT_MAIN             1

#define CT_SUB              2

#define CT_CREATE           3

/*----------------------------------------------------------------------+

|   HelloWorld commands                                                 |

+----------------------------------------------------------------------*/

/*----------------------------------------------------------------------+

|   Table <tableId> =                                                   |

|   {                                                                   |

|       { <no.>, <subTableId>, <cmdClass>, <options>, "<cmdWord>" };    | |   };                                                                  |

+----------------------------------------------------------------------*/

Table CT_MAIN = {     { 1,  CT_SUB,              PLACEMENT,   REQ,    "HelloWorld" }, };

Table CT_SUB = {     { 1,  CT_CREATE,  INHERIT,    REQ,   "Create" }, };

Table CT_CREATE = {     { 1,  CT_NONE,  INHERIT,    NONE,   "Line" },    

                        { 2,  CT_NONE,  INHERIT,    NONE,   "ComplexShape" },    

                        { 3,  CT_NONE,  INHERIT,    NONE,   "ProjectedSolid" },    

                        { 4,  CT_NONE,  INHERIT,    NONE,   "BsplineSurface" }, };

以上命令表文件定义了如下6个键入命令,它们分别有对应的命令号。

键 入 命名号 命令号的值
HelloWorld CMD_HELLOWORLD 0x01000000
HelloWorld  Create CMD_HELLOWORLD_CREATE 0x01010000
HelloWorld  Create  Line CMD_HELLOWORLD_CREATE_LINE 0x01010100
HelloWorld  Create  ComplexShape CMD_HELLOWORLD_CREATE_COMPLEXSHAPE 0x01010200
HelloWorld  Create  ProjectedSolid CMD_HELLOWORLD_CREATE_PROJECTEDSOLID 0x01010300
HelloWorld  Create  BsplineSurface CMD_HELLOWORLD_CREATE_BSPLINESURFACE 0x01010400

有关命令表的语法和各项的含义,请参见MDLProgrammerGuide帮助中的Compiling an Application Command Table 一节。

一步步学习MDL[4]

3. 在Visual Studio中双击HelloWorld.mke打开制作文件并进行如下两处改动:

     a. 将第8行的appRscs = $(o)$(appName).rsc改为

appRscs    = $(o)$(appName).rsc   $(o)$(appName)cmd.rsc

     b. 将第48和50行前的注释符#删除。

$(baseDir)$(appName)cmd.h  : $(baseDir)$(appName)cmd.r

$(o)$(appName)cmd.rsc     : $(baseDir)$(appName)cmd.r

【注】:以上代码中含有两个很重要的空行,不能随手删掉它们。空行表示按默认规则生成目标文件。在编译过程中bmake将会到mdl.mki文件中找到.r.h和.r.rsc规则去编译并生成HelloWorldCmd.h和HelloWorldCmd.rsc。HelloWorldCmd.h文件会在HelloWorld.cpp中引用,HelloWorldCmd.rsc被加入到appRscs宏定义中,从而最终被打包到HelloWorld.ma中。

4. 下面要对HelloWorld.cpp进行多处改动:

      a. 包含HelloWorldCmd.h:

#include   <MicroStationAPI.h>

#include   <msdialog.fdf>

#include   <mselmdsc.fdf>

#include   <msbsplin.fdf>

#include   "HelloWorldCmd.h"

      b. 在MdlMain函数删除原来的一些函数调用,增加打开资源文件、装载命令表以及注册命令号等动作如下:

 extern "C" DLLEXPORT int MdlMain (int argc, char *argv[])

{    

   g_1mu = mdlModelRef_getUorPerMaster(ACTIVEMODEL);   

   RscFileHandle   rscFileH;    

   mdlResource_openFile (&rscFileH, NULL, RSC_READ);    

   mdlParse_loadCommandTable (NULL);   

   Private MdlCommandNumber  commandNumbers [] =    

 {         {createALine,  CMD_HELLOWORLD_CREATE_LINE},        

           {createAComplexShape, CMD_HELLOWORLD_CREATE_COMPLEXSHAPE},        

           {createAProjectedSolid, CMD_HELLOWORLD_CREATE_PROJECTEDSOLID},   

           {createABsplineSurface,      CMD_HELLOWORLD_CREATE_BSPLINESURFACE},        

          0  

   };   

  mdlSystem_registerCommandNumbers (commandNumbers);    

  return 0;

}

以上代码中的mdlResource_openFile会打开资源文件HelloWorld.ma,然后mdlParse_loadCommandTable从中装载命令表资源。动态数组commandNumbers中定义了命令处理函数和每个命令号的对应关系,然后由mdlSystem_registerCommandNumbers注册。我们没有像大多MDL例子中那样同时还定义一套命令名,然后用mdlSystem_registerCommandNames来注册,因为命令名的使用远没有键入命令来得方便。只有在您没有定义命令表的情况下才有必要使用命令名。命令名的使用样例可参见SDK中的cellexp.cpp、gis.cpp和toolExample.cpp。

        c. 对createALine、createAComplexShape、createAProjectedSolid和createABsplineSurface进行一些改造以满足作为命令处理函数的要求。同时,将basePt的赋值内置在每个函数中。修改后的代码如下(省略掉了未改动部分):

void createALine (char *unparsed)

{   

  MSElement myLine;   

  DPoint3d  basePt={0,0,0}, pts[2];  

 pts[0] = pts[1] = basePt;    ……

}

void createAComplexShape (char *unparsed)

{   

   MSElement        el;   

   MSElementDescrP  edP = NULL;   

   DPoint3d         basePt, pts[3], tmpPt;   

   basePt.x = 1.7*g_1mu;   basePt.y = -0.3*g_1mu;   

   basePt.z = -0.6*g_1mu;    mdlComplexChain_createHeader (&el, 1, 0);  

   mdlElmdscr_new (&edP, NULL, &el);    pts[0] = pts[1] = pts[2] = basePt;    ……

}

void createAProjectedSolid (char *unparsed)

{   

   MSElement        el;  

  MSElementDescrP  sectionEdP = NULL, solidEdP = NULL; 

  DPoint3d         basePt, pts[6], pt1, pt2;      

  basePt.x = 3.2*g_1mu;     basePt.y = -0.6*g_1mu;   

  basePt.z = -1.2*g_1mu;    pts[0] = basePt;    ……

}

void createABsplineSurface (char *unparsed)

{   

   MSElement         el;   

   MSElementDescrP   edP = NULL;   

  MSBsplineSurface  bsSurface;   

   MSBsplineCurve    bsCurves[4];   

  DPoint3d          basePt, arcPts[4][3];     

 basePt.x = 5.4*g_1mu;     basePt.y = -2.3*g_1mu;   

  basePt.z = -1.8*g_1mu;    arcPts[0][0] = arcPts[0][1] = arcPts[0][2] = basePt;    ……

}

5. 在Visual Studio中选菜单Tools > Rebuild MDL App(Debug)生成项目,然后切换到MicroStation装载HelloWorld。

6. 选MicroStation主菜单Utilities > Key-in打开键入对话框,输入HelloWorld后会看到如下图所示的命令键入树,这与我们在HelloWorldCmd.r中定义的完全对应。此时输入其中的一个命令并回车就能绘出相应的一部分图形。

一步步学习MDL[4]