一、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函数不再执行