===== 定制功能 =====
XT框架中所有功能均从类[[class:application:icommand|ICommand]]继承实现。对于有对话框的功能,开发者(也可以是其他人)需提前准备好对话框的配置文件,对话框的配置文件可参考[[reference:guisys|XT Customized GUI System]]编辑完成。
==== 功能的声明 ====
新的功能类从ICommand继承,需要注意的是const char * getName() const必须在头文件中声明,XT框架依赖该函数完成功能的注册。
class CmdTest : public ICommand
{
public:
CmdForce(IMainFrame * pMain);
void initWindow(); //初始化对话框,当对话框需要根据文档的数据或者当前状态进行初始化时需要
const char * getUISettingXml() { return "test.xml"; } //指定对话框配置文件,当对话框功能时需要
void onDataExchange( const char * dxdiag = NULL); //功能参数与对话框控件状态的匹配交换
bool checkContext(); //检查参数是否满足功能执行条件
void onControlEvent(const char * ctrlName, TypeID event = Event_Any); //响应控件的事件
ErrorCode execute(); //执行功能逻辑
const char * getName() const; //必须声明
void setParam(const CmdParam *param); //设置功能参数
bool checkContextParam(const TreeNode * targetNode, const TreeNode * refNode); //从模型树菜单启动功能时通过节点上下文设置命令参数
void setContextParam(const TreeNode * targetNode, const TreeNode * refNode); //从模型树菜单启动功能时检查节点上下文是否匹配命令
void exchangeScript(ParamList * param); //记录功能脚本
CommandType getType() {return Command_Dialog;} //定义功能类型
void updateFrame(); //更新框架和视图
private:
ParamTest m_oParam; //功能参数,从CmdParam继承
TreeNode * m_pObjNode = 0; //模型树节点
};
==== 功能的注册 ====
开发者根据需要实现声明中的部分或者全部成员函数。此外,开发者需调用REGISTER_CMD宏完成功能的注册,注册时需要指定命令名以及文档ID,如下所示,其中“Test”为命令名,Document_Test()为访问文档ID的接口,它们共同构成命令的索引。
REGISTER_CMD(CmdTest, 0, "Test", Document_Test())
需要注意的是,文档ID一般通过调用接口完成,不能指定静态变量来给定,原因是功能的注册是一个静态调用,而静态变量在此静态调用执行时是否已经正确初始化是不能保证的,通过接口调用则可避免该问题。
原则上一个功能只在它所属的文档空间中使用,但是在多数情况下,功能所涉及的数据都是通过XDocument所提供的统一接口访问,在这种情况下,这个功能是可以在另外一个文档空间中使用的,开发者可以使用宏BIND[NUMBER]_DOCCMD来完成,其中[NUMBER]从1到8,即意味着最多可以注册到9个不同的文档空间中(理论上,这个数字并没有限制,只是XT只预置了这么多宏,在超出这个数字的情况下,开发者可以调用CommandManager::registerCommandToDocument完成)。
REGISTER_CMD(CmdTest, 0, "Test", Document_Test())
==== 功能的使用 ====
开发好的功能通过功能管理器CommandManager管理索引,可以在功能入口配置文件进行配置然后通过用户交互触发,也可以直接在代码中调用。
* 通过Ribbon菜单触发
* 通过工具条触发
* 通过菜单栏触发
* 通过右键菜单触发
* 在代码中调用
ParamPickByAngle param;
param.setFlag(RunCmd_GUI_Off);
param.dAngleTol = m_pCoAngle->text().toDouble();
m_pFrm->launchCommand(Command_PickByAngle, ¶m);