0

0

分享

【快速入门教程二】天工CAD插件开发模板介绍

186 0
2024-10-17 15:15:37 天工开发者中心| 显示全部楼层 阅读模式
本帖最后由 天工开发者团队 于 2024-10-17 15:32 编辑

一、整体框架
4.1.png
         通过向导(天工CAD开发资源)得到一个天工CAD插件项目之后,可以得到上述几个核心类,分别有着以下作用。

TGCore:程序初始化入口
TGUIManager:Ribbon菜单UI管理类,负责创建Ribbon菜单
TGCmdManager:Cmd命令管理类,负责命令的注册和分发调度以及对话框的管理
TGEventManager:Event事件管理类,负责响应操作所产生事件的处理
TGHelper:Help类,可以调用一些辅助接口

二、业务流程
4.2.png
         业务流程可以分成三部分:
(一)创建Ribbon菜单:用户根据UI设计菜单,并完成Ribbon命令菜单的创建。
(二)实现业务功能:实现菜单命令,具体包括命令创建、功能实现、命令调度、消息事件处理、命令注册。
(三)处理消息事件:处理命令响应、文档事件等情况。
2.1 创建Ribbon菜单
         打开“当前项目//res//XXXRibbon.xml”文件,对Ribbon菜单进行编辑,具体格式如下:
  1. <ribbon>
  2.     <!-- [TGTemple]在此处添加用户自定义的TabbedContainer -->
  3.     <tab name="天工插件示例">
  4.         <!-- [TGTemple]在此处添加用户自定义的group分组-->
  5.         <group name="Welcome">
  6.             <!--  [TGTemple]在此处添加用户自定义的命令按钮 -->
  7.             <!--  [TGTemple]commandId: 自定义命令ID,必须唯一,用于标识命令 -->
  8.             <!--  [TGTemple]label: 命令显示的名称 -->
  9.             <!--  [TGTemple]imageId: 命令显示的图标ID -->
  10.             <!--  [TGTemple]buttonStyle: 命令按钮的样式 -->
  11.             <button commandId="0"  label="弹出窗口"  imageId="166" buttonStyle="5" />
  12.             <button commandId="1"  label="侧边栏"  imageId="167" buttonStyle="5" />
  13.             <button commandId="2"  label="弹窗消息事件版"  imageId="167" buttonStyle="5" />
  14.             <button commandId="3"  label="侧边栏消息事件版"  imageId="167" buttonStyle="5" />
  15.         </group>
  16.     </tab>
  17. </ribbon>
复制代码

界面效果图如下所示
4.3.png
命令按钮关键词说明:
commandId:自定义命令ID(唯一)
label:命令显示的名称
imageId:按钮位图资源ID
buttonStyle:按钮风格
“1” seButtonAutomatic:按钮样式自动确定,即UI框架会根据上下文和平台偏好自动选择合适的样式
“2” seButtonCaption:只有按钮的文字标题,没有图标
“3” seButtonIcon:只有按钮图标,没有文字标题
“4” seButtonIconAndCaption:包括按钮图标和文字标题(通常并排显示)
“5” seButtonIconAndCaptionBelow:与“4”类似,但图标位于上方,标题位于下方
“6” seCheckButton:复选按钮,用户可以选中或取消选中
“7” seCheckButtonAndIcon:结合复选按钮和图标的样式,更直观
“8” seRadionButton:单选按钮,用户在一组中选择其中一个
根据UI设计的Menu,创建Ribbon菜单,将所有的命令按钮添加完毕,对应好命令ID,以及按钮要展示的命令名称和图标,并根据需求进行命令分组,菜单创建完成后就可以进行命令的实现了。
2.2 业务功能实现

         业务的实现体现为命令按钮的功能实现,具体步骤:命令创建→功能实现→命令调度→事件处理→命令注册。代码逻辑流程如下图所示。

4.4.png
其中,创建的业务命令类型主要可分为以下三种:
弹框式命令(继承自TGCmdPopup)  :基于TGCCmdBase的二次封装,支持弹窗对话框形式的业务命令
         命令激活处理接口:Activate()   命令终止处理接口:
         Terminate()   创建并展示对话框:CreateRibbon()
         消息事件处理:MouseClick()、KeyDown()、MouseDrag()、MouseMove()、Filter()等
侧边栏命令(继承自TGCmdEdgebar)  :基于TGCCmdBase的二次封装,支持侧边栏形式的业务命令
         命令激活处理接口:Activate()
         命令终止处理接口:Terminate()
         创建并展示侧边栏对话框:CreateRibbon()
         消息事件处理:MouseClick()、KeyDown()、MouseDrag()、MouseMove()等
直接操作命令(继承自TGCCmdBase)
         命令激活处理接口:Activate()
         命令终止处理接口:Terminate()
         消息事件处理:raw_MouseDown()、raw_MouseUp()、raw_MouseMove()、raw_MouseClick(、raw_MouseDblClick()、raw_MouseDrag()、raw_Filter()、raw_WindowProc()等)
接下来,以弹框式界面命令实现为例子进行讲解
2.2.1   命令创建
(一)基于TGCmdPopup定义自己的命令类,如TGUserCmdPopup
(二)定义命令Com的别名:typedef ComObject TGCmdUserCmdPopupObj
(三)实现Activate和Terminate接口(若无多余操作,可不重写)
(四)添加需要处理的消息事件
  1. class TGUserCmdPopup : public TGCmdPopup
  2. {
  3. public:
  4.     TGUserCmdPopup();
  5.     virtual ~TGUserCmdPopup();
  6.     STDMETHODIMP Activate();
  7.     STDMETHODIMP Terminate();
  8.     STDMETHODIMP MouseClick(short sButton,    short sShift, double dX, double dY,    double dZ, LPDISPATCH pWindowDispatch,    long lKeyPointType,    LPDISPATCH pGraphicDispatch);
  9.     STDMETHODIMP MouseMove(short sButton, short sShift, double dX, double dY, double dZ, LPDISPATCH pWindowDispatch, long lKeyPointType, LPDISPATCH pGraphicDispatch);
  10.     STDMETHOD(MouseDrag)(short sButton, short sShift, double dX, double dY, double dZ, LPDISPATCH pWindowDispatch, short DragState, long lKeyPointType, LPDISPATCH pGraphicDispatch);
  11.     STDMETHODIMP Filter(LPDISPATCH pGraphicDispatch, VARIANT_BOOL* vbValid);
  12.     STDMETHOD(KeyDown)(short* KeyCode,short Shift);  
  13. };
  14. typedef CComObject<TGUserCmdPopup> TGCmdUserCmdPopupObj;
复制代码

2.2.2 对话框创建
(一)基于CDialogEx,新建MFC类,如TGPopupDialog
(二)通过工具对话框的UI设计完成界面的布局
(三)完成业务逻辑处理
  1. class TGPopupDialog : public CDialogEx
  2. {
  3.     DECLARE_DYNAMIC(TGPopupDialog)
  4. public:
  5.     TGPopupDialog(CWnd* pParent = nullptr);   // 标准构造函数
  6.     virtual ~TGPopupDialog();
  7. // 对话框数据
  8. #ifdef AFX_DESIGN_TIME
  9.     enum { IDD = IDD_POPUPDIALOG };   
  10. #endif
  11. protected:
  12.     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
  13.     DECLARE_MESSAGE_MAP()
  14. public:
  15. // 业务逻辑处理
  16.     afx_msg void OnTestButton1();
  17.     afx_msg void OnTestButton2();
  18.     virtual void OnOK();
  19.     virtual void OnCancel();
  20. };
复制代码
4.5.png
2.2.3 命令与对话框绑定
(一)修改TGCmdDialogFactory::GetSpecificCmdDialog():添加new TGPopupDialog对象的操作
  1. //[TGTemple]此处为用户自定义命令界面类实例生成工厂,请根据自定义command对应的界面实例补充switch
  2. CDialog* TGCmdDialogFactory::GetSpecificCmdDialog()
  3. {
  4.     switch (CommandId)
  5.     {
  6.     case 0:
  7.     {
  8.         TGPopupDialog* pPopupDialog = new TGPopupDialog();
  9.         return dynamic_cast<CDialog*>(pPopupDialog);
  10.         break;
  11.     }
  12.     default:
  13.         return NULL;
  14.         break;
  15.     }
  16. }
复制代码
(二)修改TGCmdDialogFactory::GetSpecificCmdDialogTemplateId():添加相应对话框IDD
  1. //[TGTemple]此处为用户自定义界面类ID关联command处,请根据commandid关联所对应的界面
  2. UINT TGCmdDialogFactory::GetSpecificCmdDialogTemplateId()
  3. {
  4.     switch (CommandId)
  5.     {
  6.     case 0:
  7.         return IDD_POPUPDIALOG;
  8.         break;
  9.     default:
  10.         return NULL;
  11.         break;
  12.     }
  13. }
复制代码
2.2.4 消息事件处理
         命令激活时,会涉及到一些消息事件的处理,可以在用户自定义的类中完成对这一部分的处理,比如鼠标事件,此处也可能会涉及到一些SDK的使用,可以参照SDK的帮助文档
  1. HRESULT TGUserCmdPopup::MouseClick(short sButton, short sShift, double dX, double dY, double dZ, LPDISPATCH pWindowDispatch, long lKeyPointType, LPDISPATCH pGraphicDispatch)
  2. {
  3.     HRESULT hr = NOERROR;
  4.     AfxMessageBox(L"MouseClick");
  5.     return hr;
  6. }
复制代码
         在弹框界面中也一样,鼠标点击Button1,实现弹出"Click Button1"的功能
  1. void TGPopupDialog::OnTestButton1()
  2. {
  3.     AfxMessageBox(L"Click Button1");
  4. }
复制代码

         鼠标点击确认,实现销毁窗口并终止命令的功能
  1. void TGPopupDialog::OnOK()
  2. {
  3.     TGAddinTemplate2App::GetApplication()->AbortCommand(false);
  4. }
复制代码

2.2.5 命令注册
         在TGCmdMnager命令管理类中完成命令的注册
  1. //[TGTemple]此处为用户自定义命令实例化与实例化自定义命令和CommandID关联处
  2. //[TGTemple]1.请实例化自定义界面实例
  3. //[TGTemple]2.请将实例化自定义界面与关联的CommandID放入Map容器
  4. void TGCmdManager::InitCommandMap()
  5. {
  6.     //声明并创建命令的Com对象,并完成引用计数
  7.     TGCmdPopupObj* PopupCommand = NULL;
  8.     TGCmdPopupObj::CreateInstance(&PopupCommand);
  9.     PopupCommand->AddRef();
  10.     //插入命令集合中
  11.     InsertCommand(0, PopupCommand);//该命令ID(0)要求唯一,且需要和Ribbon菜单中的ID保持一致
  12. }
复制代码

         如需要多个弹窗式命令按钮,重复上述操作即可。
2.3 事务管理
2.3.1 命令管理的消息事件
         这类事件是在对应的派生类命令中进行处理的,可通过补充这些事件的处理方法来完成。
鼠标事件:
         sButton:鼠标按键,表示那个哪个鼠标按钮被按下。通常,1表示左键,2表示右键,4表示中间键
         sShift:按下鼠标时哪些Shift键(1)、Ctrl键(2)或Alt键(4)被按下。
         dX, dY, dZ:分别表示鼠标在X、Y、Z轴上的位置
         pWindowDispatch:指向触发事件的窗口对象的指针。这可以用来访问窗口对象的方法和属性。
         lKeyPointType:表示关键点类型,可能用于识别特定的交互点类型
         pGraphicDispatch:指向图形对象的指针,可以用来访问与绘图或图形相关的服务和操作
  1. // 鼠标点击事件
  2. STDMETHOD(MouseClick)(short sButton,short sShift,double dX,double dY,double dZ,LPDISPATCH pWindowDispatch,long lKeyPointType,LPDISPATCH pGraphicDispatch)
  3. { }
  4. // 鼠标双击事件
  5. STDMETHOD(MouseDblClick)(short sButton,short sShift,double dX,double dY,double dZ,LPDISPATCH pWindowDispatch,long lKeyPointType,LPDISPATCH pGraphicDispatch)
  6. { }
  7. // 鼠标拖拽事件
  8. STDMETHOD(MouseDrag)(short sButton,short sShift,double dX,double dY,double dZ,LPDISPATCH pWindowDispatch,long lKeyPointType,LPDISPATCH pGraphicDispatch)
  9. { }
  10. // 鼠标按下事件
  11. STDMETHOD(MouseDown)(short sButton,short sShift,double dX,double dY,double dZ,LPDISPATCH pWindowDispatch,long lKeyPointType,LPDISPATCH pGraphicDispatch)
  12. { }
  13. // 鼠标弹起事件
  14. STDMETHOD(MouseUp)(short sButton,short sShift,double dX,double dY,double dZ,LPDISPATCH pWindowDispatch,long lKeyPointType,LPDISPATCH pGraphicDispatch)
  15. { }
  16. // 鼠标移动事件
  17. STDMETHOD(MouseClick)(short sButton,short sShift,double dX,double dY,double dZ,LPDISPATCH pWindowDispatch,long lKeyPointType,LPDISPATCH pGraphicDispatch)
  18. { }
复制代码
键盘事件:
         KeyAscii:当用户按下键盘上的一个键时,对应的ASCII**被传递给KeyAscii
         KeyCode:表示用户释放的虚拟键码。虚拟键码是一个整数,代表了键盘上的一个键
         Shift:表示在释放按键时哪些键(Shift=1、Ctrl=2、Alt=4)被按下
  1. // 键盘按键事件
  2. STDMETHOD(KeyPress)   (short* KeyAscii){ }
  3. // 键盘按下事件
  4. STDMETHOD(KeyDown)(short* KeyCode,short Shift){ }
  5. // 键盘弹起事件
  6. STDMETHOD(KeyUp)(short* KeyCode,short Shift){ }
复制代码

2.3.2 EventManage管理的消息事件
4.6.png
         这类事件是在TGEventManager管理类中对应的事件实现里去补充。
命令事件:
基于不同版本会有不同的事件类负责处理,如XAddInEvents、XAddInEventsEx、XAddInEventsEx2。
         nCmdID:绑定的命令标识符,即命令ID。
         hFrameWnd:应用程序主框架窗口的句柄。
         uHelpCommand:请求帮助的类型或命令。
  1. // 相应UI界面中的命令事件,比如菜单按钮的点击
  2. STDMETHOD(raw_OnCommand)(long nCmdID){}
  3. // 相应UI界面中的帮助命令事件
  4. STDMETHOD(raw_OnCommandHelp)(long hFrameWnd,long uHelpCommand,long nCmdID){}
复制代码

侧边栏事件:
         theDocument:指向文档对象的指针。
         EnvironmentCatID:表示一个环境类别ID,用于分类或描述页面展示环境的一个字符串标识符。
         vbIsPageDisplayable:传出参数,表示页面是否在给定的环境类别下可以显示。
  1. // 添加侧边栏
  2. STDMETHOD(raw_AddPage)(LPDISPATCH theDocument){}
  3. // 删除侧边栏
  4. STDMETHOD(raw_RemovePage)(LPDISPATCH theDocument){}
  5. // 用于判断一个页面是否可以在特定环境下显示
  6. STDMETHOD(raw_IsPageDisplayable)(IDispatch* theDocument,BSTR EnvironmentCatID,VARIANT_BOOL* vbIsPageDisplayable);
  7. { }
复制代码
文档事件:
  1. // 激活文档切换事件
  2. STDMETHOD(raw_AfterActiveDocumentChange) (LPDISPATCH theDocument){}
  3. // 命令运行之后的事件,命令执行完之后,无论成功失败都会触发该事件
  4. STDMETHOD(raw_AfterCommandRun) (long theCommandID){}
  5. // 文档打开之后的事件
  6. STDMETHOD(raw_AfterDocumentOpen) (LPDISPATCH theDocument){}
  7. // 文档保存完成后的事件处理
  8. STDMETHOD(raw_AfterDocumentSave) (LPDISPATCH theDocument){}
  9. // 新建文档并打开后的事件处理
  10. STDMETHOD(raw_AfterNewDocumentOpen) (LPDISPATCH theDocument){}
  11. // 命令激活之前的事件
  12. STDMETHOD(raw_BeforeCommandRun) (long theCommandID){}
  13. // 文档关闭之前的事件
  14. STDMETHOD(raw_BeforeDocumentClose) (LPDISPATCH theDocument){}
  15. // 文档保存之前的操作
  16. STDMETHOD(raw_BeforeDocumentSave) (LPDISPATCH theDocument){}
复制代码



评论(0)

您需要登录后才可以回复 登录

客服 意见反馈
返回顶部
快速回复 返回顶部 返回列表