八、MFC对话框

一、Win32对话框

        模式对话框:子对话框未关闭,父对话框无法拖拽和关闭

        无模式对话框:子对话框未关闭,父对话框可以拖拽和关闭

1、创建项目

(1)创建Win32项目(WinDlg)

(2)添加资源文件(.rc文件),添加菜单项

八、MFC对话框_第1张图片

(3)添加对话框

八、MFC对话框_第2张图片

 (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对话框_第3张图片

二、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

你可能感兴趣的:(Windows-MFC,mfc)