自实现模态对话框-DoModal函数
参考CDialog::DoModal函数的实现方式,自己实现了模态框相关功能。
ModalBase.h头文件
1 #include <afxwin.h>
2
3 #define ID_NULL 0
4 #define ID_OK 1
5 #define ID_CANCEL 2
6 #define ID_ABORT 3
7 #define ID_RETRY 4
8 #define ID_IGNORE 5
9 #define ID_YES 6
10 #define ID_NO 7
11 #define ID_CLOSE 8
12
13
14 //模态窗基类
15 class ModalBase : public CWnd
16 {
17 public:
18 ModalBase();
19 ~ModalBase();
20
21 virtual int DoModal(HWND hParent = NULL);
22
23 void SetWindowSize(int nWidth, int nHeight);
24
25 protected:
26 virtual void EndDialog(int nExitCode);
27
28 virtual void UpdateLayout();
29
30 virtual CRect GetTitleRect(); //获取标题栏矩形
31
32 virtual CRect GetWndRect(); //获取整个窗口的矩形【忽略了边框】
33
34 BOOL Create(CWnd* pParent);
35
36 //消息循环
37 protected:
38 DECLARE_MESSAGE_MAP()
39 afx_msg void OnMouseMove(UINT nFlags, CPoint point);
40 afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
41 afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
42
43 private:
44 bool m_bMouseMove = false;
45 CPoint m_ptOrigin;
46 int m_nRetCode = ID_NULL; //模态窗退出码
47 int m_nWidth = 0; //窗口的宽度
48 int m_nHeight = 0; //窗口的高度
49 };
ModalBase.cpp源文件
1 #include "stdafx.h"
2 #include <afxpriv.h>
3 #include "ModalBase.h"
4
5 BEGIN_MESSAGE_MAP(ModalBase, CWnd)
6 ON_WM_SIZE()
7 ON_WM_PAINT()
8 ON_WM_LBUTTONDOWN()
9 ON_WM_MOUSEMOVE()
10 ON_WM_LBUTTONUP()
11 END_MESSAGE_MAP()
12
13 ModalBase::ModalBase(){ }
14
15
16 ModalBase::~ModalBase(){ }
17
18 int ModalBase::DoModal(HWND hParent /*= NULL*/)
19 {
20 CWinApp* pApp = AfxGetApp();
21 if (pApp) pApp->EnableModeless(FALSE); //禁用所有非模态窗
22
23 if (!hParent)
24 hParent = ::GetActiveWindow(); //获取当前焦点窗口
25
26 BOOL bEnableParent = FALSE;
27 BOOL bEnableMainWnd = FALSE;
28 CWnd* pMainWnd = NULL;
29 if (hParent && hParent != ::GetDesktopWindow() && ::IsWindowEnabled(hParent)) //判断窗口是否禁用
30 {
31 ::EnableWindow(hParent, FALSE); //禁用父窗口
32 bEnableParent = TRUE;
33
34 pMainWnd = AfxGetMainWnd();
35 if (pMainWnd && pMainWnd->IsFrameWnd() && pMainWnd->IsWindowEnabled()) //禁用框架窗口
36 {
37 pMainWnd->EnableWindow(FALSE);
38 bEnableMainWnd = TRUE;
39 }
40 }
41
42 BOOL bRet = Create(CWnd::FromHandle(hParent)); //创建窗口
43 if (!bRet)
44 {
45 if (bEnableParent) ::EnableWindow(hParent, TRUE);
46
47 if (bEnableMainWnd) pMainWnd->EnableWindow(TRUE);
48
49 return 0;
50 }
51
52 HWND hWndLastActive = ::SetActiveWindow(m_hWnd); //激活当前窗口
53
54 //显示当前窗口
55 SetWindowPos(CWnd::FromHandle(HWND_TOPMOST), 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE);
56 CenterWindow(CWnd::FromHandle(hParent));
57
58 DWORD dwFlags = MLF_SHOWONIDLE;
59 if (GetStyle() & DS_NOIDLEMSG) dwFlags |= MLF_NOIDLEMSG;
60
61 int nResult = RunModalLoop(dwFlags); //进入消息循环
62
63 ASSERT(m_nRetCode != ID_NULL); //从消息循环退出,应该已经设置了其他值
64
65 if (IsWindow(m_hWnd))
66 SetWindowPos(NULL, 0, 0, 0, 0, SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
67
68 if (bEnableMainWnd) pMainWnd->EnableWindow(TRUE); //激活框架窗口
69 if (bEnableParent) ::EnableWindow(hParent, TRUE); //激活父窗口
70
71 ::SetActiveWindow(hWndLastActive); //还原
72 ::DestroyWindow(m_hWnd); //销毁当前窗口
73
74 if (pApp) pApp->EnableModeless(TRUE); //启用所有非模态窗
75 }
76
77 void ModalBase::SetWindowSize(int nWidth, int nHeight)
78 {
79 m_nWidth = nWidth;
80 m_nHeight = nHeight;
81 }
82
83 BOOL ModalBase::Create(CWnd* pParent)
84 {
85 CString strWndClass = AfxRegisterWndClass(CS_VREDRAW | CS_HREDRAW, ::LoadCursor(NULL, IDC_ARROW), NULL, NULL);
86 BOOL bResult = CreateEx(NULL, strWndClass, _T(""), WS_POPUP, CRect(0, 0, m_nWidth, m_nHeight), pParent, NULL);
87 return bResult;
88 }
89
90 void ModalBase::OnMouseMove(UINT nFlags, CPoint point)
91 {
92 if (m_bMouseMove)
93 {
94 CRect rcWindow;
95 GetWindowRect(rcWindow);
96 CPoint pt = point - m_ptOrigin + rcWindow.TopLeft();
97 SetWindowPos(NULL, pt.x, pt.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOREDRAW);
98 }
99 __super::OnMouseMove(nFlags, point);
100 }
101
102 void ModalBase::OnLButtonDown(UINT nFlags, CPoint point)
103 {
104 SetFocus();
105 if (nFlags == MK_LBUTTON && GetTitleRect().PtInRect(point))
106 {
107 SetCapture();
108 m_bMouseMove = true;
109 m_ptOrigin = point;
110 }
111 __super::OnLButtonDown(nFlags, point);
112 }
113
114 void ModalBase::OnLButtonUp(UINT nFlags, CPoint point)
115 {
116 if (m_bMouseMove)
117 {
118 ReleaseCapture();
119 m_bMouseMove = false;
120 }
121 }
122
123 void ModalBase::EndDialog(int nExitCode)
124 {
125 ASSERT(nExitCode != ID_NULL);
126 if (m_nRetCode == ID_NULL)
127 {
128 m_nRetCode = nExitCode;
129 if (m_nFlags & (WF_MODALLOOP | WF_CONTINUEMODAL))
130 EndModalLoop(m_nRetCode);
131
132 ::EndDialog(m_hWnd, m_nRetCode);
133 }
134 }
135
136 void ModalBase::UpdateLayout()
137 {
138
139 }
140
141 CRect ModalBase::GetTitleRect()
142 {
143 CRect rcTitle = GetWndRect();
144 rcTitle.bottom = rcTitle.top + 28;
145 return rcTitle;
146 }
147
148 CRect ModalBase::GetWndRect()
149 {
150 CRect rcClient;
151 GetClientRect(rcClient);
152 rcClient.DeflateRect(2, 2, 2, 2);
153 return rcClient;
154 }
上面只提供了基类代码,有需要的,可以自己派生相关的类。
自实现模态对话框-DoModal函数的更多相关文章
- 模态对话框 DoModal的用法 (vs2008)与非模态对话框
Windows对话框分为两类:模态对话框和非模态对话框. 模态对话框,当它弹出后,本应用程序其他窗口将不再接受用户输入,只有该对话框响应用户输入,在对它进行相应操作退出后,其他窗口才能继续与用户交互. ...
- vc创建模态和非模态对话框
模态对话框的创建 创建模态对话框需要调用CDialog类的成员函数:DoModal,该函数的功能就是创建并显示一个模 态对话框,关闭模态对话框的函数是EndDialog,该函数需要一个参数,这个参数就 ...
- Qt按ESC关闭模态对话框不触发closeEvent()问题解析(ESC默认调用的是reject()函数,所以必须覆盖这个函数才会有效果)good
事情是这样的:今天调试窗体,突然发现按ESC键居然跳过closeEvent()关闭了对话框!我的关闭判断都在closeEvent()里,这直接导致非正常关闭了正在进行的工作.先重建下场景: 调用处: ...
- MFC编程入门之十一(对话框:模态对话框及其弹出过程)
加法计算器对话框程序大家照着做一遍后,相信对基于对话框的程序有了些解了,有个好的开始对于以后的学习大有裨益.趁热打铁,这一节讲讲什么是对话框和非模态对话框,以及模态对话框怎样弹出. 一.模态对话框和非 ...
- MFC学习笔记(一)向模态对话框传递数据
声明构造函数为2个参数,具有默认参数的参数须放在后面. CDialogDimmer::CDialogDimmer(CString name,CWnd* pParent /*=NULL*/) : CDi ...
- VC++模态对话框和非模态对话框
MFC中有两种类型的对话框:模态对话框和非模态对话框. 模态对话框是指当其显示时,程序会暂停执行,直到关闭这个模态对话框后,才能继续执行程序中其他任务.非模态对话框是指当其显示时,允许转而执行程序中 ...
- mfc模态对话框
Mfc模态对话框: 创建模态对话框: [模态对话框:具有独占行为,必须由用户完成对当前对话框的响应,才能对本对话框所属的进程进行其他操作] 例如: 我们创建一个加法计算器.点击计算之后,弹出一个对话框 ...
- VS2010/MFC对话框:非模态对话框的创建及显示
非模态对话框的创建及显示 上一节讲了模态对话框及其弹出过程,本节接着讲另一种对话框--非模态对话框的创建及显示. 已经说过,非模态对话框显示后,程序其他窗口仍能正常运行,可以响应用户输入,还可以相互切 ...
- VS2010/MFC:模态对话框及其弹出过程
模态对话框及其弹出过程 加法计算器对话框程序大家照着做一遍后,相信对基于对话框的程序有些了解了,有个好的开始对于以后的学习大有裨益.趁热打铁,这一节讲讲什么是模态对话框和非模态对话框,以及模态对话框怎 ...
- MFC模态和非模态对话框编程
MFC中对话框有两种形式,一个是模态对话框(model dialog box),一个是非模态对话框(modeless dialog box). 一.模态对话框(model dialog box) 在程 ...
随机推荐
- Linux服务器部署SpringBoot项目教程
1. 服务器配置1.1 购买服务器1.2 配置安全组1.3 登录实例1.4 安装宝塔面板2. 配置宝塔2.1 创建数据库3. 打包部署项目3.1 修改项目配置3.2 打包3.3 部署3.4 放行端口3 ...
- 数字先锋 | 天翼云xDeepSeek,赋能东莞开启智慧政务新篇章!
人工智能浪潮奔涌 DeepSeek堪称"全能战士" 在各行各业疯狂"上分" 特别是在政务领域 其以强大的智能问答 公文写作.数据分析等能力 为政务服务按下了&q ...
- zabbix - [03] 安装部署
参考:https://www.yuque.com/fenghuo-tbnd9/ffmkvs zabbix6要求操作系统为Centos8,所以一开始安装部署的时候发现少了zabbix-server-my ...
- 【忍者算法】从快慢指针到倒数查找:优雅解决链表倒数问题|LeetCode第19题"删除链表的倒数第N个结点"
从快慢指针到倒数查找:优雅解决链表倒数问题 从生活场景说起 想象你在一个漫长的队伍中,想知道自己距离队尾还有多少人.一个巧妙的方法是:让你的朋友从你所在位置往后数N步,然后你和朋友一起向后走.当朋友走 ...
- 读论文-基于序列模式的电子商务推荐系统综述(A Survey of Sequential Pattern Based E-Commerce Recommendation Systems)
前言 今天读的论文为一篇于2023年10月3日发表在<算法>(Algorithms)的论文,这篇文章综述了基于序列模式的电子商务推荐系统,强调了通过整合用户购买和点击行为的序列模式来提高推 ...
- BUGKU_PWN_OVERFLOW2_WP
WP_OVERFLOW2 拿到程序,首先放到我们的kali里面看看是多少位的程序,然后在看看有没有什么安全属性 64位程序,并且开启了RELRO,NX 也就是说,这道题我们需要使用ROP绕过 使用id ...
- 【面试题】实现 queryParse 函数,完成解析 URL 参数的功能
问题:实现 queryParse 函数,完成解析 URL 参数的功能 /** * 问题:实现 queryParse 函数,完成解析 URL 参数的功能 * * 用法: * ```js * const ...
- windows 稀疏文件 (sparse file) 的一个实用场景——解决 SetEndOfFile 占据磁盘空间引入的性能问题
前言 之前写过一篇文章说明文件空洞:<[apue] 文件中的空洞>,其中提到了 windows 稀疏文件是制造空洞的一种方式,但似乎没什么用处,如果仅仅处理占用磁盘空间的场景,使用SetE ...
- oracle的各版本的名称
我最早接触的是oracle的版本8那个时候是8i i是internet后来是9i然后到10,就是版本10g g是grid的意思然后是11g然后12就变成了C,就是12c c是cloud的意思然后后面的 ...
- SSH远程神器—Termius
简介 Termius是一款非常好用而且漂亮的SSH客户端,能快速远程控制服务器,可以定制自己喜欢的主题.Termius不仅涵盖了PC端的Windows.Linux.Mac,还支持手机端的Android ...