编程语言
首页 > 编程语言> > MSCE C++官网一步步学习搬运7

MSCE C++官网一步步学习搬运7

作者:互联网

第七章、给MDL应用添加用户界面

我们在本系列的前一章实现了动态放置B样条曲线的功能。现在要给这个工具添加如下图形用户界面(GUI):

 

 

 增加这个界面后能帮助我们在放置曲面时指定曲面的大小和其所在的层。

 在nativeCode(本机代码)应用程序中,可以通过MDL资源(.r文件)或MFC资源(.rc文件)来添加图形用户界面。前者是Bentley应用程序所特有的,后者是微软的实现方式。虽然MDL资源不支持可视化设计,但它是通过定义数据而不用写程序代码来支持用户交互的,这一点上反而比较简单。再者,您可以将MicroStation中已有的对话条目(即俗称的控件)集成到自己的对话框中,这也是MDL资源的另一大好处。总之,MDL资源在写nativeCode程序时占有极其重要的地位,Bentley的内部代码绝大多数都是通过MDL资源来写的界面,绝少是用MFC资源写出来的(有一些是用最新的WinForm或WPF写出来的)。有关MDL资源的详细信息请参阅MicroStationApi.chm中的“Dialog Box Manager Overview(对话框管理器概述)”、“Standard dialog items(标准对话条目)”和“Hook Functions(钩函数)”等内容。

 在一篇文章中描述MDL资源的每一个细节几乎是不可能的,这个任务也不是本系列文章的要点。所以,在本例中我们将集中于以上两个对话条目。为了实现这个界面,我们要做一些设计方面的考虑:需要给每个对话框和对话条目赋一个标识(ID)以便在资源和代码中更容易地使用和引用;还需要给大多数对话条目指定“存取串(access string)”以便快速而直接地访问它们所引用的值。在本例中,所定义的条目标识和存取串如下图所示:

 

 

 

 1、在HelloWorld.h中增加如下定义内容:

#include <Bentley\Bentley.r.h>

#define ItemList_BsplineSurface       1

#define TEXTID_BaseArcRadius                1

#define COMBOBOXID_MyLevel                1

#define HOOKITEMID_MyLevelCombo       1

typedef struct helloworldinfo
{
   double       baseArcRadius;
   Utf16Char  levelName[512];
}HelloWorldInfo; 

 2、在HelloWorldCmd.r中修改CT_CREATE定义中的最后一项,增加ItemList_BsplineSurface如下:

{ 4,  CT_NONE, 	INHERIT, NONE, "BsplineSurface", CMDNAME_PlaceBsSurfaceTool, ItemList_BsplineSurface},

 3、在HelloWorld.r中添加如下内容:

#include <Mstn\MdlApi\rscdefs.r.h>
#include <Mstn\MdlApi\dlogbox.r.h>
#include "HelloWorld.h"
……
CmdItemListRsc  ItemList_BsplineSurface =
{{
   {{10*XC,   YC/2,   15*XC, 0}, Text, 	     TEXTID_BaseArcRadius,    ON, 0, "", ""},
   {{10*XC,   YC*2,   20*XC, 0}, ComboBox,  COMBOBOXID_MyLevel,  ON, 0, "", ""},
}};

DItem_TextRsc TEXTID_BaseArcRadius =
    {
    NOCMD, LCMD, NOSYNONYM, NOHELP, LHELP, NOHOOK, NOARG,
    15, "%w", "%w", "0.0", "", NOMASK, TEXT_NOCONCAT, "基准弧半径(~B):", "g_helloWorld.baseArcRadius"
   };

DItem_ComboBoxRsc COMBOBOXID_MyLevel =
{
   NOCMD, LCMD, NOSYNONYM, NOHELP, MHELP, HOOKITEMID_MyLevelCombo, NOARG,
   512, "%s", "%s", "", "", NOMASK,
   0, 18, 4, 0, 0, COMBOATTR_READONLY | COMBOATTR_FULLWIDTH | COMBOATTR_SORT,
   " 放置层(~L):", "g_helloWorld.levelName",
   {
      {0, 512, ALIGN_LEFT, ""},
   }
};
 

4、如下建立一个MicroStation类型文件HelloWorldTyp.mt:

#include    "HelloWorld.h"

publishStructures (helloworldinfo);

 回顾一下第二章中看到的那个生成ma+dll的流程图,在图的右上角显示的就是在.mt文件中包含.h头文件,.mt文件会被生成.r文件,.r文件又进一步生成.rsc,最后合并到.ma文件中。

 5、如下修改HelloWorld.mke文件:

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

 将如下四行(注意有两个重要的空行)添加到Generate resource files一节后面。这四行就是从HelloWorldTyp.mt生成HelloWorldTyp.r,从HelloWorldTyp.r生成HelloWorldTyp.rsc:

$(o)$(appName)typ.r         : $(baseDir)$(appName)typ.mt

$(o)$(appName)typ.rsc    : $(o)$(appName)typ.r 

6、对HelloWorld.cpp做多出修改:

bool CreateBsSurface(EditElementHandleR eeh, DPoint3dCP pBasePt)
{
    MSBsplineSurface bsSurface;
    MSBsplineCurve   bsCurves[4];
    DPoint3d               center[4];
    RotMatrix              rMatrix[4];
    double                  radius = g_helloWorld.baseArcRadius;
   ……
}
……
virtual bool _OnDataButton(DgnButtonEventCR ev) override
{
    EditElementHandle  eeh;
    if (CreateBsSurface(eeh, ev.GetPoint()))
    {
        WString wStr(g_helloWorld.levelName);
	    FileLevelCacheR levelCache = ISessionMgr::GetActiveDgnFile()->GetLevelCacheR();
	    LevelHandle levelHandle = levelCache.GetLevelByName(wStr.GetWCharCP());
	    ElementPropertiesSetterPtr setter = ElementPropertiesSetter::Create();
	    setter->SetLevel(levelHandle.GetLevelId());
	    setter->Apply(eeh);
	    eeh.AddToModel();
    }
    _OnReinitialize();
    return true;
}

 增加一个条目钩函数,该函数遍历当前设计文件中有效的层并将它们赋给组合框条目MyLevel:

void myLevel_comboHook (DialogItemMessage *dimP)
{
   RawItemHdr      *riP = dimP->dialogItemP->rawItemP;

   dimP->msgUnderstood	= TRUE;
   switch (dimP->messageType)
	{
	   case DITEM_MESSAGE_CREATE:
	    {
            ListModelP pListModel = mdlListModel_create(1);
		    DgnFileP   pDgnFile = ISessionMgr::GetActiveDgnFile();
		    for (LevelHandle lh : pDgnFile->GetLevelCacheR())
		    {
		        WString    lvlName;
		        lh.GetDisplayName(lvlName);
		        mdlListModel_insertString (pListModel, lvlName.GetWCharCP(), -1);
		    }
		    mdlDialog_comboBoxSetListModelP(riP, pListModel);
            break;
        }
        case DITEM_MESSAGE_DESTROY:
        {
            ListModelP   pListModel = mdlDialog_comboBoxGetListModelP (riP);
            mdlListModel_destroy (pListModel,TRUE);
            break;
        }
	    default:
	        dimP->msgUnderstood	= FALSE;
  	        break;
    }
}

 定义一个全局动态数组uHook[],并在MdlMain函数中发布它。

DialogHookInfo uHooks[] =
{
   {HOOKITEMID_MyLevelCombo,	   (PFDialogHook)myLevel_comboHook 	},
};
……
……
mdlDialog_hookPublish (sizeof(uHooks)/sizeof(DialogHookInfo), uHooks);
SymbolSet  *setP = mdlCExpression_initializeSet (VISIBILITY_DIALOG_BOX, 0, 0);
mdlDialog_publishComplexVariable (setP, "helloworldinfo", "g_helloWorld", &g_helloWorld);
g_helloWorld.baseArcRadius = 2000;
strcpy_s (g_helloWorld.levelName, 512, "Default");

7、在Visual Studio中保存所有文件,回到编译黑窗口键入bmake -a重生成该项目,然后切换到MicroStation来测试。当您装载HelloWorld应用并键入HELLOWORLD CREATE BSPLINESURFACE,您将会看到本章开头显示的第一个图片。下图是放置了三个曲面的例子,每个曲面都在不同的层上且具有不同的基本弧半径。

标签:文件,官网,MDL,helloWorld,条目,C++,HelloWorld,include,MSCE
来源: https://www.cnblogs.com/JolinZH/p/12826846.html