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;

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

相关推荐
一只旭宝6 小时前
【C++入门精讲22】常见设计模式
c++·设计模式
c++之路8 小时前
Bazel C++ 构建系列文档(三):构建第一个 C++ 项目
开发语言·c++
旖-旎8 小时前
《LeetCode 695 岛屿的最大面积 FloodFill DFS 解法》
c++·算法·力扣·深度优先遍历·floodfill
森G8 小时前
61、信号与槽机制在 TCP 编程中的应用---------网络编程
网络·c++·qt·网络协议·tcp/ip
syagain_zsx9 小时前
STL 之 vector 讲练结合
c++·算法
牛油果子哥q9 小时前
STL set与map底层精讲,红黑树适配原理、有序去重特性、迭代器遍历、API实战与面试核心考点全解
开发语言·数据结构·c++·面试
奇妙方程式10 小时前
2026年第九届GXCPC广西大学生程序设计大赛(热身赛)题解
c++·编程比赛·编程竞赛·gxcpc
Tian_Hang10 小时前
C++原型模式(Protype)
开发语言·c++·算法
FL162386312911 小时前
[cmake]基于C++使用纯opencv部署ppocrv5v6的onnx模型
开发语言·c++·opencv
玖玥拾11 小时前
C/C++ 数据结构(六)链表迭代器与底层
c语言·数据结构·c++·链表·stl库