目录
一、概述
1.1 基本概念
- 界面分类:有MFC类和QT类
- 功能:在CAD中弹出对话框与用户进行交互
1.2 CAD消息对话框
- 功能:弹出有限个固定选项的对话框,见下效果图
MessageBox
写法// 消息对话框函数:获取cad主窗口句柄、对话框内容、对话框标题、标识符 int ret = MessageBox(adsw_acadMainWnd(), _T("消息对话框内容"), _T("标题栏文字"), // 标识符:对话框种类、图标(见下表) MB_OKCANCEL| MB_ICONEXCLAMATION); // 函数返回值:见下表 if (ret == IDOK) acedAlert(_T("你点选了确定按钮"));
AfxMessageBox
写法// 与MessageBox的参数通用,写法如下 if (AfxMessageBox(_T("是否关闭"), MB_YESNO) == IDYES) acedAlert(_T("你点选了确定按钮"));
- 效果(图标:三角形感叹号)
- 对话框种类标识符
标识符 释义 MB_OK 按钮:确定,返回值:IDOK MB_OKCANCEL 按钮:确定、取消,返回值:IDOK、IDCANCEL MB_ABORTRETRYIGNORE 按钮:中止、重试、忽略,返回值:IDABORT、IDRETRY、IDIGNORE MB_YESNOCANCEL 按钮:是、否、取消,返回值: IDYES、IDNO、 IDCANCEL MB_YESNO 按钮:是、否按钮,返回值:IDYES、IDNO MB_RETRYCANCEL 按钮:重试、取消,返回值: IDTRYAGAIN、IDCANCEL MB_CANCELTRYCONTINUE 按钮:取消、重试、继续,返回值:IDCANCEL、IDRETRY、IDCONTINUE - 对话框图标标识符
标识符 释义 MB_ICONHAND 叉图标 MB_ICONQUESTION 问号图标 MB_ICONEXCLAMATION 三角形感叹号 MB_ICONINFORMATION 圆形感叹号图标
二、项目初始化
- 创建arx项目(完整步骤可参见环境配置篇)
- arx项目内添加新项
- 对话框类向导设定
- acrxEntryPoint.cpp
... #include "UIFirst.h" ... class CMFCAppApp : public AcRxArxApp { ... static void ChMyGroupMyCommand () { // 防止用户定义资源与CAD系统资源冲突 CAcModuleResourceOverride resOverride; // 创建对话框对象 UIFirst dlg; // 启动模态对话框:并建立自己的消息循环 dlg.DoModal(); } ... }
- 效果
三、UI编辑
3.1 界面初识
- 主窗口
String Table:为共享的字符串键值对
- 工具箱
- 属性页
- 双击布尔值:可切换true和false
- 属性标签调出:在对话框中单击右键点属性
3.2 消息
- 消息机制:Windows是一个消息(Message)驱动系统,Windows的消息提供了应用程序之间、应用程序与Windows系统之间进行通信的手段。应用程序想要实现的功能由消息来触发,并且靠对消息的响应和处理来完成
- 消息种类
名称 释义 标准消息(窗口消息) 除WM_COMMAND
之外,所有以WM_开头的消息都是标准消息,例如鼠标单击、移动,键盘左击、右击命令消息 来自 菜单
,工具栏
按钮的消息,这类消息都以WM_COMMAND
形式呈现通告消息 来自 控件
,这类消息都以WM_COMMAND
形式呈现自定义消息 来自开发者,范围有如下:WM_USER: 0x0400-0x7FFF (定义写法: #define WM_SAFE WM_USER+10)
- 常用窗口消息
消息名 消息意图 WM_CREATE 建立对话框前触发的消息 WM_CLOSE 关闭(内存中未销毁)对话框前触发的消息 WM_DESTROY 销毁(内存中销毁)对话框前触发消息 WM_ACTIVE 对话框被激活时触发的消息 WM_SHOWWINDOW 对话框显示或隐藏时触发的消息 WM_PAINT 当窗口显示区域的部分或者全部变为“无效”,以致于必须“更新画面”时,将由这个消息通知程序 WM_SIZING 用户调整大小时触发的消息 消息回调函数:默认无回调函数,用户根据需要关联回调函数与窗口消息,实现响应效果
- 示例
- 功能:关闭窗口前弹出确认窗口
- 类向导:通过右键单击
测试对话框
,选择类向导调出
- 代码(其他默认,只修改此处)
... void UIFirst::OnClose() { // TODO: 在此添加消息处理程序代码和/或调用默认值 if (AfxMessageBox(L"是否确定关闭窗口",MB_YESNO) == IDYES) CAcUiDialog::OnClose(); } ...
- 效果
3.3 添加按钮
3.3.1 向导部分
- 按钮排版
- 类向导
3.3.2 代码部分
- UIFirst.h
#pragma once #include "acui.h" class UIFirst : public CAcUiDialog { DECLARE_DYNAMIC (UIFirst) public: UIFirst (CWnd *pParent =NULL, HINSTANCE hInstance =NULL) ; enum { IDD = IDD_UIFIRST} ; protected: virtual void DoDataExchange (CDataExchange *pDX) ; afx_msg LRESULT OnAcadKeepFocus (WPARAM, LPARAM) ; DECLARE_MESSAGE_MAP() public: // 向导创建:单击回调函数 afx_msg void OnClickedBtn1(); } ;
- UIFirst.cpp
#include "StdAfx.h" #include "resource.h" #include "UIFirst.h" IMPLEMENT_DYNAMIC (UIFirst, CAcUiDialog) BEGIN_MESSAGE_MAP(UIFirst, CAcUiDialog) ON_MESSAGE(WM_ACAD_KEEPFOCUS, OnAcadKeepFocus) // 向导创建:连接 单击回调函数 和 UI上的按钮BTN1 ON_BN_CLICKED(IDC_BTN1, &UIFirst::OnClickedBtn1) END_MESSAGE_MAP() UIFirst::UIFirst (CWnd *pParent, HINSTANCE hInstance) : CAcUiDialog (UIFirst::IDD, pParent, hInstance) { } void UIFirst::DoDataExchange (CDataExchange *pDX) { CAcUiDialog::DoDataExchange (pDX) ; } LRESULT UIFirst::OnAcadKeepFocus (WPARAM, LPARAM) { return (TRUE) ; } // 向导创建:单击回调函数 void UIFirst::OnClickedBtn1() { // 开发者此处写处理代码 acedAlert(_T("你单击了按钮1")); }
向导创建:以上三处注释必须同步,其他保持默认
- 效果
3.3.3 模态运行中选择
- 实现功能:
点击
-》隐藏对话框
-》选择成功
-》重新显示对话框
- UIFirst.cpp(替换3.3.2相应代码)
// 单击回调函数 void UIFirst::OnClickedBtn1() { // 将控制权交给用户,并隐藏当前窗口 BeginEditorCommand(); // 在屏幕上选择实体 ads_name en; ads_point pt; if (acedEntSel(_T("\n请选择一个实体"), en, pt) != RTNORM) { // 重新显示隐藏窗口,无此函数,进入假死状态 CompleteEditorCommand(); return; } // 结束对话框 CancelEditorCommand(); }
此处三个函数为类UIFirst的顶层基类CAdUiBaseDialog的公有函数
- 效果(未选中实体则返回对话框)
3.2 状态栏
-
类向导设置
-
UIFirst.cpp
// 初始化对话框处 BOOL UIFirst::OnInitDialog() { CAcUiDialog::OnInitDialog(); // TODO: 在此添加额外的初始化 // 创建状态栏:头文件public:CStatusBar m_statusBar; BOOL bRet = m_statusBar.Create(this); // 分配格子数目及索引 UINT nIds[3] = { 1001, 1002, 1003 }; // 将索引添加进状态栏对象中 bRet = m_statusBar.SetIndicators(nIds, 3); // 设置每个格子:序号、索引值、面板样式、大小(像素,需要细心调) m_statusBar.SetPaneInfo(0, nIds[0], SBPS_NORMAL, 100); m_statusBar.SetPaneInfo(1, nIds[1], SBPS_NORMAL, 200); m_statusBar.SetPaneInfo(2, nIds[2], SBPS_NORMAL, 100); // 设置序号0格子:放静态文字 m_statusBar.SetPaneText(0, _T("状态栏")); // 应用面板 RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0); return TRUE; // return TRUE unless you set the focus to a control // 异常: OCX 属性页应返回 FALSE }
-
效果
四、模态与非模态对话框
- 模态对话框:(Modal Dialogue Box,又叫做模式对话框),是指在用户想要对对话框以外的应用程序进行操作时,必须首先对该对话框进行响应,如单击【确定】或【取消】按钮等将该对话框关闭
- 非模态对话框:与之相反
- 建议:从复杂度来说,若非必须,建议都用模态对话框
4.1 模态对话框
- acrxEntryPoint.cpp
... #include "UIFirst.h" ... class CMFCAppApp : public AcRxArxApp { ... static void ChMyGroupMyCommand () { // 防止用户定义资源与CAD系统资源冲突 CAcModuleResourceOverride resOverride; // 创建对话框对象 UIFirst dlg; // 启动模态对话框:并建立自己的消息循环 // 后续代码必须等对话框关闭才可继续执行 dlg.DoModal(); } ... }
4.2 非模态对话框
- acrxEntryPoint.cpp
... #include "UIFirst.h" ... // 添加全局变量 UIFirst *g_dlgModeless = NULL; class CMFCAppApp : public AcRxArxApp { public: ... // 应用卸载时:同时验证对话框指针是否为空,销毁窗口 virtual AcRx::AppRetCode On_kUnloadAppMsg (void *pkt) { AcRx::AppRetCode retCode =AcRxArxApp::On_kUnloadAppMsg (pkt) ; // TODO: Unload dependencies here if (g_dlgModeless != NULL) { // 若指针不为空,销毁窗口 g_dlgModeless->DestroyWindow(); } return (retCode) ; } ... // 创建非模态对话框:销毁对话框在对话框类中补充 static void ChMyGroupMyCommand () { // Put your command code here // 防止用户定义资源与CAD系统资源冲突 CAcModuleResourceOverride resOverride; // 创建非模态对话框对象 if (g_dlgModeless == NULL) { // new对应的delete在非模态对话框类中补充(重点) g_dlgModeless = new UIFirst(); // 创建窗口方法:UIFirst类公有枚举变量(最终在resource.h中定义),父窗口为CAD主窗口 g_dlgModeless->Create(UIFirst::IDD, acedGetAcadFrame()); } // ShowWindow函数:显示SW_SHOW、隐藏SW_HIDE、最大化SW_MAXIMIZE 等 g_dlgModeless->ShowWindow(SW_SHOW); // 设置窗口为激活状态 g_dlgModeless->SetActiveWindow(); } } ...
- UIFirst.cpp
... // 声明全局变量:在acrxEntryPoint.cpp中定义 extern UIFirst *g_dlgModeless; ... // 类向导创建的:消息destroy // DestroyWindow函数均会调用此类函数 // 此方法为顶层基类 void UIFirst::OnDestroy() { CAcUiDialog::OnDestroy(); // TODO: 在此处添加消息处理程序代码 delete this; g_dlgModeless = NULL; } // 类向导创建的:虚函数OnOk void UIFirst::OnOK() { // TODO: 在此添加专用代码和/或调用基类 CAcUiDialog::OnOK(); DestroyWindow(); } // 类向导创建的:虚函数OnCancel void UIFirst::OnCancel() { // TODO: 在此添加专用代码和/或调用基类 CAcUiDialog::OnCancel(); DestroyWindow(); }
- 效果
- 核心方法ondestroy
研究中,后续补充