MFC 对话框架构

目录

Win32对话框回顾

对话框架构

无模式对话框架构程序执行过程


Win32对话框回顾

MFC框架中都是无模式对话框,不会阻塞,先回顾一下无模式对话框的创建:

  1. 添加对话框资源
  2. 查找资源,FindResource
  3. 加载资源,LoadResource
  4. 锁定资源,LockResource
  5. 创建无模式对话框,CreateDialogIndirect

Win32创建对话框代码如下:

cpp 复制代码
#include <windows.h>
#include "resource.h"

HINSTANCE g_hInstance = 0;

INT CALLBACK DlgProc( HWND hwndlg, UINT msgID, WPARAM wParam, LPARAM lParam ){
	switch( msgID ){
	case WM_DESTROY:
		MessageBox( NULL, "我要死了", "Infor", MB_OK );
		break;
	case WM_SYSCOMMAND:
		if( wParam == SC_CLOSE ){
			HWND hWnd = GetParent( hwndlg );  // 通过子窗口拿到父窗口的句柄
			EnableWindow(  hWnd ,TRUE );
			DestroyWindow( hwndlg );//销毁无模式对话框, 切忌不能EndDialog 
//			EndDialog( hwndlg, 1001 );//只能隐藏无模式对话框, 可以销毁模式对话框
		}
		break;
	}
	return FALSE;//对话框的消息交给真正对话框窗口处理函数处理。
}
void OnNoModel( HWND hWnd ){
	//	HWND hDlg = CreateDialog( g_hInstance, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, DlgProc );//直接创建
	//  ShowWindow( hDlg, SW_SHOW );
}

void OnCommand( HWND hWnd, WPARAM wParam ){
	switch(LOWORD(wParam)){
	case ID_NOMODEL:
		OnNoModel( hWnd );
		break;
	}
}
//窗口处理函数( 自定义,处理消息)
LRESULT CALLBACK WndProc( HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam ){
	switch(msgID){
	case WM_COMMAND:
		OnCommand( hWnd, wParam );
		break;
	case WM_DESTROY:
		PostQuitMessage( 0 );
		break;
	}
	return DefWindowProc( hWnd, msgID, wParam, lParam );
}
//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns, LPSTR lpCmdLine, int nCmdShow){
	g_hInstance = hIns;  // 赋值为当前程序示例句柄
	//注册窗口类
	WNDCLASS wc = { 0 };
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
	wc.hCursor = NULL;
	wc.hIcon = NULL;
	wc.hInstance = hIns;
	wc.lpfnWndProc = WndProc;
	wc.lpszClassName = "Main";
	wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);//(CHAR*)IDR_MENU1; 数字资源转为字符串形式
	wc.style = CS_HREDRAW | CS_VREDRAW;
	RegisterClass( &wc );//将以上所有赋值全部写入操作系统。
	//在内存创建窗口
	HWND hWnd = CreateWindowEx( 0, "Main", "window", WS_OVERLAPPEDWINDOW,
								100, 100, 500, 500, NULL, NULL, hIns, NULL );
	//显示窗口
	ShowWindow( hWnd, SW_SHOW );
	UpdateWindow( hWnd );
	//消息循环
	MSG nMsg = { 0 };
	while( GetMessage(&nMsg,NULL,0,0) ){
		TranslateMessage( &nMsg );
		DispatchMessage( &nMsg );//将消息交给窗口处理函数来处理。
	}
	return 0;
}

可以同时启动多个窗口

创建窗口的其他方式,通过禁用父窗口给了一种模式对话框的错觉

cpp 复制代码
void OnNoModel(HWND hWnd) {
	//  直接创建模式对话框
	//	HWND hDlg = CreateDialog( g_hInstance, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, DlgProc );//直接创建
	//  ShowWindow( hDlg, SW_SHOW );

	//  模拟模式对话框
	EnableWindow(hWnd, FALSE);  // 禁用父窗口

	// 等效于 CreateDialog() 函数 创建对话框,间接方式创建无模式对话框
	// 从当前进程内存中找对话框资源数据
	HRSRC hRs = FindResource(g_hInstance, MAKEINTRESOURCE(IDD_DIALOG1), RT_DIALOG);
	// 加载进来需要用的资源数据
	HGLOBAL hGl = LoadResource(g_hInstance, hRs);
	// 把资源数据整理到结构体保存
	LPCDLGTEMPLATE pTemplate = (LPCDLGTEMPLATE)LockResource(hGl);
	// 创建无模式对话框
	HWND hDlg = CreateDialogIndirect(g_hInstance, pTemplate, hWnd, DlgProc);

	ShowWindow(hDlg, SW_SHOW);
}

销毁无模式对话框, 切忌不能EndDialog,它只能隐藏无模式对话框, 但可以销毁模式对话框

cpp 复制代码
INT CALLBACK DlgProc(HWND hwndlg, UINT msgID, WPARAM wParam, LPARAM lParam) {
	switch (msgID) {
	case WM_DESTROY:
		MessageBox(NULL, "我要死了", "Infor", MB_OK);
		break;
	case WM_SYSCOMMAND:
		if (wParam == SC_CLOSE) {
			HWND hWnd = GetParent(hwndlg);  // 通过子窗口拿到父窗口的句柄
			EnableWindow(hWnd, TRUE);  // 启用父窗口
			DestroyWindow(hwndlg);//销毁无模式对话框, 切忌不能EndDialog
//			EndDialog( hwndlg, 1001 );//只能隐藏无模式对话框, 可以销毁模式对话框
		}
		break;
	}
	return FALSE;//对话框的消息交给真正对话框窗口处理函数处理。
}

对话框架构

MFC对话框分类:模式对话框(假)/无模式。MFC其实只有一种对话框,就是无模式对话框。通过禁用父窗口给了一种模式对话框的错觉。

MFC参与架构的类:CDialog,CWinApp 只有两个参与架构

代码书写:添加对话框资源,定义一个自己的对话框的类(CMyDlg)。管理对话框,派生自CDialog或CDialogEx均可

代码如下:

cpp 复制代码
#include <afxwin.h>
#include "resource.h"


class CMyDlg : public CDialog{
	DECLARE_MESSAGE_MAP()
public:
	void OnZjwOK();
	void OnZjwCancel( );
};


BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
	ON_COMMAND( IDOK, OnZjwOK )
	ON_COMMAND( IDCANCEL, OnZjwCancel )
END_MESSAGE_MAP()


void CMyDlg::OnZjwCancel( ){
//	CDialog::OnCancel( );
	this->DestroyWindow( );
}


void CMyDlg::OnZjwOK(){
//	CDialog::OnOK();//只能将无模式对话框隐藏,并没有销毁。
	::DestroyWindow( this->m_hWnd );
}


class CMyWinApp : public CWinApp{
public:
	virtual BOOL InitInstance( );
};


BOOL CMyWinApp::InitInstance( ){
	CMyDlg* pdlg = new CMyDlg;
	pdlg->Create( IDD_DIALOG1 );
	m_pMainWnd = pdlg;
	pdlg->ShowWindow( SW_SHOW );
	return TRUE;
}
CMyWinApp theApp;

无模式对话框架构程序执行过程

相关推荐
神仙别闹1 小时前
基于 C++ 实现(控制台)学生成绩管理系统
开发语言·c++
会周易的程序员1 小时前
5 节点边缘冗余方案(上):基于 aiRaft 的物联网高可用控制面设计
c++·分布式·物联网·raft·iot·共识
qq_199886874 小时前
第6板块·第4节:构建系统与多文件项目
c++·人工智能·gpu算力
汉克老师5 小时前
GESP2026年9月认证C++三级( 第三部分编程题(2、分割字符串))精讲
c++·gesp·小学生·学c++编程
估值探索者6 小时前
【Python量化系统工程化 #08】关了 SSH 就停?systemd 让脚本开机自启 + 异常自动拉起
java·c++·人工智能·分类·数据挖掘
天若有情6736 小时前
C++花式魔改!手写头文件复刻Java语法,彻底打破编码思维定式
java·c++·语言做语言·jac++
qq_199886876 小时前
第7板块·第3节:CUTLASS 的 GEMM 实现与优化策略
c++·人工智能·gpu算力·cuda
hetao17338376 小时前
2026-09-17 hetao1733837 的刷题记录
c++·算法
shada7 小时前
Boost.Process v2 在旧内核上报 `assign: Bad file descriptor`
c++
别动我齐刘海8 小时前
ROS2 Jazzy + C++ 实战路线——基础学习2
c++·人工智能·vscode·python·学习·机器学习·机器人