目录
Win32对话框回顾
对话框架构
无模式对话框架构程序执行过程
Win32对话框回顾
MFC框架中都是无模式对话框,不会阻塞,先回顾一下无模式对话框的创建:
- 添加对话框资源
- 查找资源,FindResource
- 加载资源,LoadResource
- 锁定资源,LockResource
- 创建无模式对话框,CreateDialogIndirect
Win32创建对话框代码如下:
#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;
}
可以同时启动多个窗口
创建窗口的其他方式,通过禁用父窗口给了一种模式对话框的错觉
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,它只能隐藏无模式对话框, 但可以销毁模式对话框
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均可
代码如下:
#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;