自实现模态对话框-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) 在程 ...
随机推荐
- CF895C Square Subsets 题解
看到 \(a_i\le 70\) 后,发现 \(n\) 啥用没有,因为只需要枚举 \(1-70\) 选几个即可. 看到求完全平方数后,想到分解质因数,由于 \(a_i\le 70\),所以只有 \(1 ...
- Typecho 博客文章评论添加显示 UserAgent(UA)的功能
本篇文章实现了为 Typecho 博客文章评论添加显示 UserAgent(UA)的功能 本功能可替代 UserAgent 插件,更美观.简洁且好看 效果显示 大概就是这样了,实际效果请看我的评论! ...
- 傻妞PLUS机器人教程——安装
特性 简单易用的消息搬运功能. 简单强大的自定义回复功能. 完整支持 ECMAScript 5.1 的插件系统,基于 otto. 支持通过内置的阉割版 Express / fetch ,接入互联网. ...
- Hive - [01] 概述
一.Hive是什么 是Facebook开源,用于解决海量结构化日志的数据统计工具. 是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并提供类SQL查询功能. Hive处理的数 ...
- AI与.NET技术实操系列 - 开篇
引言 在当今技术飞速发展的时代,人工智能(Artificial Intelligence, AI)已成为推动创新和变革的核心力量.从智能助手到自动化决策系统,AI的应用无处不在,深刻影响着我们的生活和 ...
- 仓储层当前有接口 IRepository<T> 抽象类 BaseRepository<T> 业务逻辑层有抽象类 BaseBusiness<M, E> 接口 IBusiness<M, E> 请用C# 给出一个案例,支持不同表对应不同的业务逻辑层,然后不同仓储实例。
以下是一个简单的C#示例,展示了如何实现不同表对应不同的业务逻辑层和不同的仓储实例: // 仓储层 public interface IRepository<T> { void Add(T ...
- SSH登录:WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
错误信息: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICAT ...
- Ubuntu 下查看 ip
博客地址:https://www.cnblogs.com/zylyehuo/ ip a
- Windows核心编程 进程与线程
进程 Windows作为多任务操作系统,允许多个程序同时在系统中运行.这些程序被称为进程,进程运行在一片独立的空间中,受到操作系统保护,操作系统的很多资源都是围绕着进程来进行分配,可以理解为操作系统维 ...
- Oracle12c 数据库 警告日志
目录 一:查看警告日志文件的位置 二:警告日志内容 三:告警日志监控: 方案1: 方案2: 方案3: 正文 回到顶部 一:查看警告日志文件的位置 Oracle 12c环境下查询,alert日志并不在b ...