[MSCE C++]在.r对话框中实现对话框部分控件的展开和收起


我们在使用MicroStation软件时会遇到类似选择工具和放置单元这样的对话框,就是在右下角有一个小的冲下的箭头,点击该箭头能展开更多的内容。展开后这个小箭头变成了冲上的了,再次点击该冲上的箭头又能将这些内容收起来。如下图所示:

那么如何通过编程实现这种效果呢?下面以我自己的一个对话框为例为您描述实现的详细过程。最后实现的效果请看如下视频:

基本原理就是给这个小箭头挂上钩函数,在钩函数中显示或隐藏相关的控件(MDL的.r中叫做item,也被翻译成条目)即可。

1、在头文件(.h)中定义相关控件和钩函数的ID如下:

#define DIALOGID_DemoExtend      6

#define COMBOBOXID_States       1

#define LISTBOXID_DialogDemo    1

#define ICONID_MyShowExtended	  20010
#define ICONID_MyHideExtended	  20011

#define HOOKITEMID_ExpandTool    6

2、在资源文件(.r)中定义如下资源:

DialogBoxRsc DIALOGID_DemoExtend =
{
    DIALOGATTR_DEFAULT,
    51*XC, 17*YC, NOHELP, LHELP, NOHOOK, NOPARENTID, "Demo Extend Tool",
    {
    {{ 5*XC, 0.5*YC, 20*XC, 0}, ComboBox, COMBOBOXID_States,       ON, 0, "", ""},
    {{47*XC, 0.5*YC, 0,     0}, IconCmdX, ICONID_MyShowExtended,   ON, 0, "", ""},
    {{47*XC, 0.5*YC, 0,     0}, IconCmdX, ICONID_MyHideExtended,   ON|HIDDEN, 0, "", ""},
    {{   0,  4.5*YC, 49*XC, 0}, ListBox,  LISTBOXID_DialogDemo,    ON|HIDDEN, 0, "", ""},
    }}
    extendedIntAttributes
    {{
    {EXTINTATTR_DLOGATTRS, DIALOGATTRX_NOMINIMIZEBOX}
    }
};
DItem_IconCmdXRsc       ICONID_MyShowExtended =
    {
    NOHELP, MHELP, HOOKITEMID_ExpandTool, NOARG, 0,
    ICONID_MyShowExtended, "",
    ""
    };
DItem_IconCmdRsc        ICONID_MyShowExtended =
    {
    NOHELP, MHELP, ICONCMDATTR_DONTSINGLESHOT,
    NOCMD, OTASKID, "", ""
    }
    extendedAttributes
    {{
    {EXTATTR_FLYTEXT, "展开更多属性"},
    {EXTATTR_BALLOON, "展开更多属性"},
    }};
IconCmdSmallRsc ICONID_MyShowExtended =
    {
    11, 11, ICONFORMAT_WINDOWS, BLACK_INDEX, "", "ShowOptions"
    };
IconCmdLargeRsc ICONID_MyShowExtended =
    {
    11, 11, ICONFORMAT_WINDOWS, BLACK_INDEX, "", "ShowOptions"
    };

DItem_IconCmdXRsc       ICONID_MyHideExtended =
    {
    NOHELP, MHELP, HOOKITEMID_ExpandTool, NOARG, 0,
    ICONID_MyHideExtended, "", ""
    };
DItem_IconCmdRsc        ICONID_MyHideExtended =
    {
    NOHELP, MHELP, ICONCMDATTR_DONTSINGLESHOT,
    NOCMD, OTASKID, "",
    ""
    }
    extendedAttributes
    {{
    {EXTATTR_FLYTEXT, "收起更多属性"},
    {EXTATTR_BALLOON, "收起更多属性"}
    }};
IconCmdSmallRsc ICONID_MyHideExtended =
    {
    11, 11, ICONFORMAT_WINDOWS, BLACK_INDEX, "", "HideOptions"
    };
IconCmdLargeRsc ICONID_MyHideExtended =
    {
    11, 11, ICONFORMAT_WINDOWS, BLACK_INDEX, "", "HideOptions"
    };

【说明】:

3、在源代码文件(.cpp)的MdlMain函数中关联钩函数ID和具体的钩函数:

DialogHookInfo uHooks[] =
    {
        ......
		{ HOOKITEMID_ExpandTool,         (PFDialogHook)extendTool_IconCmdXHook},
    };
extern "C" DLLEXPORT void MdlMain(int, WCharCP[])
{
   mdlResource_openFile (&g_rscFileH, NULL, RSC_READONLY);
   
   mdlSystem_registerCommandNumbers (cmdNumbers);
   mdlParse_loadCommandTable(NULL);
   
   mdlDialog_hookPublish(sizeof(uHooks) / sizeof(DialogHookInfo), uHooks);
   ......
}

4、在源代码文件中编写核心函数extendTool_IconCmdXHook如下:

/*--------------------------------------------------------
| demoExtend
+-------------------------------------------------------*/
void demoExtend(WCharCP unparsed)
{
	MSDialog::Open(NULL, DIALOGID_DemoExtend);
}
bool bExtendState = false;
void hideShowItems(MSDialogP pDb, bool bShowItems)
{
	DialogItemP showDiP = pDb->GetItemByTypeAndId(RTYPE_IconCmdX, ICONID_MyShowExtended, 0);
	DialogItemP hideDiP = pDb->GetItemByTypeAndId(RTYPE_IconCmdX, ICONID_MyHideExtended, 0);
	DialogItemP myListDiP = pDb->GetItemByTypeAndId(RTYPE_ListBox, LISTBOXID_DialogDemo, 0);
	if (bShowItems)
	{
		showDiP->Hide();
		hideDiP->Show();
		myListDiP->Show();
	}
	else {
		myListDiP->Hide();
		hideDiP->Hide();
		showDiP->Show();
	}
	mdlDialog_adjustPopDownHeight(pDb);
}
void extendTool_IconCmdXHook(DialogItemMessageP dimP)
{
	dimP->msgUnderstood = true;
	switch (dimP->messageType)
	{
	case DITEM_MESSAGE_ALLCREATED:
	{
		if (dimP->dialogItemP->id == ICONID_MyShowExtended)
			break;
		hideShowItems(dimP->db, bExtendState);
		break;
	}
	case DITEM_MESSAGE_QUEUECOMMAND:
	{
		bExtendState = !bExtendState;
		hideShowItems(dimP->db, bExtendState);
		dimP->u.queueCommand.hookHandled = true;
		break;
	}
	default:
		dimP->msgUnderstood = false;
	}
}

【说明】: