一、Win32对话框
模式对话框:子对话框未关闭,父对话框无法拖拽和关闭
无模式对话框:子对话框未关闭,父对话框可以拖拽和关闭
1、创建项目
(1)创建Win32项目(WinDlg)
(2)添加资源文件(.rc文件),添加菜单项
(3)添加对话框
(4)编写程序
#include
#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 ){
EnableWindow( hWnd, FALSE );
// HWND hDlg = CreateDialog( g_hInstance, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, DlgProc );//直接创建
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 );
}
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;
}
二、MFC无模式对话框
对话框分类:模式对话框(假,由无模式对话框实现);无模式对话框
1、对话框框架的使用
(1)参与架构的类
CDialog / CWinApp
2、创建MFC无模式对话框项目
(1)创建(Win32)项目(MFCDlg)
(2)创建资源文件(.rc),创建对话框
(3)编写程序
#include
#include "resource.h"
class CMyDlg:public CDialog
{
DECLARE_MESSAGE_MAP()
public:
void OnOK();
};
BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
ON_COMMAND(IDOK, OnOK)
END_MESSAGE_MAP()
void CMyDlg::OnOK()
{
CDialog::OnOK();
}
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;
(4)执行过程
AFX_MODULE_STATE aaa;//当前程序模块状态信息
AFX_MODULE_THREAD_STATE bbb; //当前程序线程状态信息
CWinApp::CWinApp()//构造全局对象CMyWinApp theApp
{
AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
//获取全局变量&aaa
AFX_MODULE_THREAD_STATE* pThreadState = pModuleState->m_thread;
//获取全局变量&bbb
pThreadState->m_pCurrentWinThread = this;//将&theApp保存到bbb的一个成员中
AfxGetThread()
{
AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();//获取&bbb
CWinThread* pThread = pState->m_pCurrentWinThread;
return pThread;//返回的为&theApp
}
pModuleState->m_pCurrentWinApp = this;//将&theApp保存到aaa的一个成员中
AfxGetApp()
{
return AfxGetModuleState()->m_pCurrentWinApp;//返回&theApp
}
}
进入入口函数
WinMain(...)
{
AfxWinMain(..)
{
CWinThread* pThread = AfxGetThread();
CWinApp* pApp = AfxGetApp();//获取&theApp
pApp->InitApplication();//利用theApp调用应用程序类的成员 虚函数(初始化)
pThread->InitInstance()//利用theApp调用应用程序类的成员 虚函数(创建并显示无模式对话框)
{
CMyDlg* pdlg = new CMyDlg;
pdlg->Create( IDD_DIALOG1 )//函数内部this为pdlg(自己new的对话框类对象地址)
{
CDialog::Create(MAKEINTRESOURCE(IDD_DIALOG1), ..)//函数内部this为pdlg
{
//查找对话框资源
HRSRC hResource = ::FindResource(hInst, lpszTemplateName, RT_DIALOG);
//加载对话框资源
HGLOBAL hTemplate = LoadResource(hInst, hResource);
//以上两行代码,查找并加载对话框资源
CreateIndirect(MAKEINTRESOURCE(IDD_DIALOG1), ...)
{
//锁定对话框资源
LPCDLGTEMPLATE lpDialogTemplate = LockResource(hDialogTemplate);
CreateIndirect(lpDialogTemplate..)
{
CreateDlgIndirect(...)
{
::CreateDialogIndirect(...);//以间接方式创建无模式对话框
}
}
}
}
}
}
pThread->Run()//函数内部this为&theApp
{
CWinThread::Run()//函数内部this为&theApp
{
for (;;)
{
while(没有消息时)
{
OnIdle(..);//空闲处理(虚函数)
}
do
{
if(::GetMessage抓到WM_QUIT消息)
return ExitInstance(..);//善后处理(虚函数)
}while(...)
}
}
}
}
}
(5)点击OK/确定处理流程
CDialog::OnOK()
{
EndDialog(IDOK)
{
::EndDialog(m_hWnd, nResult);//只能将无模式对话框隐藏
}
}
(6)在命令IDOK与IDCANCEL销毁对话框,可以实现关闭对话框
#include
#include "resource.h"
class CMyDlg:public CDialog
{
DECLARE_MESSAGE_MAP()
public:
void OnOK();
void OnCancel();
};
BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
ON_COMMAND(IDOK, OnOK)
ON_COMMAND(IDCANCEL, OnCancel)
END_MESSAGE_MAP()
void CMyDlg::OnOK()
{
//::DestroyWindow(this->m_hWnd);
this->DestroyWindow();
}
void CMyDlg::OnCancel()
{
//::DestroyWindow(this->m_hWnd);
this->DestroyWindow();
}
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、无模式对话框使用
参与框架的类
CDialog / CWinApp
2、创建项目
(1)创建(Win32)项目(MFCModelDlg)
(2)添加资源文件(.rc)
(3)添加对话框资源
(4)编写程序
#include
#include "resource.h"
class CMyDlg:public CDialog
{
public:
enum{IDD=IDD_DIALOG1};
CMyDlg():CDialog(IDD)
{
};
};
class CMyWinApp:public CWinApp
{
public:
virtual BOOL InitInstance();
};
BOOL CMyWinApp::InitInstance()
{
CMyDlg dlg;
m_pMainWnd = &dlg;
dlg.DoModal();
return TRUE;
}
CMyWinApp theApp;
(5)执行过程
AFX_MODULE_STATE aaa;//当前程序模块状态信息
AFX_MODULE_THREAD_STATE bbb; //当前程序线程状态信息
CWinApp::CWinApp()//构造全局对象CMyWinApp theApp
{
AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
//获取全局变量&aaa
AFX_MODULE_THREAD_STATE* pThreadState = pModuleState->m_thread;
//获取全局变量&bbb
pThreadState->m_pCurrentWinThread = this;//将&theApp保存到bbb的一个成员中
AfxGetThread()
{
AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();//获取&bbb
CWinThread* pThread = pState->m_pCurrentWinThread;
return pThread;//返回的为&theApp
}
pModuleState->m_pCurrentWinApp = this;//将&theApp保存到aaa的一个成员中
AfxGetApp()
{
return AfxGetModuleState()->m_pCurrentWinApp;//返回&theApp
}
}
进入入口函数
WinMain(...)
{
AfxWinMain(..)
{
CWinThread* pThread = AfxGetThread();
CWinApp* pApp = AfxGetApp();//获取&theApp
pApp->InitApplication();//利用theApp调用应用程序类的成员 虚函数(初始化)
pThread->InitInstance()
{
CMyDlg dlg===CDialog(IDD)//函数内部this为&dlg
{
m_lpszTemplateName=MAKEINTRESOURCE(IDD)//将对话框资源ID保存dlg的一个成员中
}
m_pMainWnd = &dlg;
dlg.DoModal( )//函数内部this为&dlg
{
HRSRC hResource = ::FindResource(hInst, m_lpszTemplateName, RT_DIALOG);
hDialogTemplate = LoadResource(hInst, hResource);
lpDialogTemplate = (LPCDLGTEMPLATE)LockResource(hDialogTemplate);
//以上三行代码,查找加载并锁定对话框资源
HWND hWndParent = PreModal();//获取父窗口的句柄
::EnableWindow(hWndParent, FALSE);//将父窗口设置为不可用状态
CreateDlgIndirect(...);//间接方式创建无模式对话框
RunModalLoop(...)//函数内部this为&dlg
{
for (;;) //消息循环
{
while(没有消息){ 空闲处理 }
do{
消息循环的相关函数;
if (!ContinueModal())//函数内部this为&dlg(m_nFlags(24/8) & 0x0010)
goto ExitModal;
}while(....);
}
ExitModal:
return m_nModalResult;
}
}
::EnableWindow(hWndParent, TRUE);//将父窗口设置为可用
DestroyWindow();//销毁无模式对话框
return m_nModalResult;//????dlg的一个成员变量
}
}
}
(6)点击确认按钮
class CMyDlg:public CDialog
{
DECLARE_MESSAGE_MAP()
public:
enum{IDD=IDD_DIALOG1};
CMyDlg():CDialog(IDD)
{
};
afx_msg void OnOK();
};
BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
ON_COMMAND(IDOK, OnOK)
END_MESSAGE_MAP()
void CMyDlg::OnOK()
{
CDialog::OnOK();
}
消息处理流程
CDialog::OnOK()//函数内部this为&dlg
{
EndDialog(IDOK) //参数为1
{
EndModalLoop(IDOK)//函数内部this为&dlg
{
m_nModalResult = IDOK; // 1
m_nFlags = 8;
}
::EndDialog(m_hWnd, nResult);//只能将无模式对话框隐藏
}
}
CDialog::OnCancel()//函数内部this为&dlg
{
EndDialog(IDCANCEL) //参数为2
{
EndModalLoop(IDCANCEL)//函数内部this为&dlg
{
m_nModalResult = IDCANCEL; // 1
m_nFlags = 8;
}
::EndDialog(m_hWnd, nResult);//只能将无模式对话框隐藏
}
}
(7)OnModal内部执行过程
将父窗口设置为不可用
创建无模式对话框
进入消息循环(自带的)
退出消息循环(父类的OnOK/OnCancel导致循环退出)
将父窗口设置为可用状态
销毁无模式对话框
返回的值导致CWinApp的Run函数不再执行
程序源代码:https://download.csdn.net/download/liutit/86738815