当前位置: 首页 > 工具软件 > cdialog > 使用案例 >

【MFC】CDialog类详解

史鸿运
2023-12-01

00. 目录

01. 概述

用于在屏幕上显示对话框的基类。

对话框分为两种类型:模式和无模式。 在应用程序继续之前,用户必须关闭模式对话框。 无模式对话框允许用户在不取消或删除对话框的情况下显示对话框并返回到其他任务。

CDialog对象是对话框模板和 CDialog 派生类的组合。 使用对话框编辑器创建对话框模板并将其存储在资源中,然后使用添加类向导创建派生自的类 CDialog

对话框与任何其他窗口一样,接收来自 Windows 的消息。 在对话框中,您特别希望处理来自对话框的控件发出的通知消息,因为这是用户与您的对话框进行交互的方式。 使用 类向导 可以选择要处理的消息,并将相应的消息映射项和消息处理程序成员函数添加到类。 只需在处理程序成员函数中编写特定于应用程序的代码即可。

如果您愿意,您始终可以手动编写消息映射项和成员函数。

在除最普通对话框以外的所有对话框中,您可以向派生对话框类添加成员变量,以存储用户在对话框控件中输入的数据或显示用户的数据。 您可以使用 “添加变量向导” 创建成员变量并将其与控件相关联。 同时,为每个变量选择变量类型和允许的值范围。 代码向导将成员变量添加到您的派生对话框类。

系统将生成数据映射,以自动处理成员变量与对话框控件之间的数据交换。 数据映射提供了一些函数,这些函数用适当的值初始化对话框中的控件,检索数据并验证数据。

若要创建模式对话框,请使用派生对话框类的构造函数在堆栈上构造对象,然后调用 DoModal 以创建对话框窗口及其控件。 如果希望创建无模式对话框,请 Create 在对话框类的构造函数中调用。

还可以使用 DLGTEMPLATE 数据结构在内存中创建模板,如 Windows SDK 中所述。 构造 CDialog 对象后,调用 CreateIndirect 创建无模式对话框,或调用 InitModalIndirect 和 DoModal 创建模式对话框。

交换和验证数据映射是用 CWnd::DoDataExchange 添加到新对话框类的的重写编写的。 CWnd 有关 exchange 和验证功能的详细信息,请参阅中的 DoDataExchange 成员函数。

程序员和框架 DoDataExchange 通过调用 CWnd::UpdateData间接调用。

UpdateData当用户单击 “确定” 按钮关闭模式对话框时,框架会调用。 (如果单击 “取消” 按钮,则不检索数据。 ) OnInitDialog 的默认实现也会调用 UpdateData 来设置控件的初始值。 通常会重写 OnInitDialog 以进一步初始化控件。 OnInitDialog 在所有对话框控件都创建之后,在对话框显示之前调用。

CWnd::UpdateData在执行模式对话框或无模式对话框的过程中,您可以随时调用。

如果手动开发一个对话框,则需要自行向派生对话框类添加必要的成员变量,并添加成员函数以设置或获取这些值。

当用户按 “确定” 或 “取消” 按钮时,或者当你的代码调用成员函数时,模式对话框将自动关闭 EndDialog

实现无模式对话框时,请始终重写 OnCancel 成员函数并 DestroyWindow 从该函数中调用。 请勿调用基类 CDialog::OnCancel ,因为它 EndDialog 会调用,这会使对话框不可见,但不会销毁它。 还应 PostNcDestroy 为无模式对话框重写,以便删除 this ,因为无模式对话框通常是用分配的 new 。 模式对话框通常是在框架上构造的,无需 PostNcDestroy 清除。

有关的详细信息 CDialog ,请参阅 对话框

02. 继承层次结构

CObject 
 └CCmdTarget 
    └CWnd 
       └CDialog 

头文件
afxwin.h

03. 成员方法

构造函数

“属性”描述
CDialog::CDialog构造 CDialog 对象。

公有成员方法

“属性”描述
CDialog::Create初始化 CDialog 对象。 创建无模式对话框并将其附加到 CDialog 对象。
CDialog::CreateIndirect从内存中的对话框模板创建无模式对话框 (基于资源的) 。
CDialog::DoModal调用模式对话框并在完成时返回。
CDialog::EndDialog关闭模式对话框。
CDialog::GetDefID获取对话框的默认按钮控件的 ID。
CDialog::GotoDlgCtrl将焦点移到对话框中的指定对话框控件。
CDialog::InitModalIndirect从内存中的对话框模板创建一个模式对话框, (不是基于资源的) 。 在调用函数之前,将存储参数 DoModal 。
CDialog::MapDialogRect将矩形的对话框单位转换为屏幕单位。
CDialog::NextDlgCtrl将焦点移到对话框中的下一个对话框控件。
CDialog::OnInitDialog重写以增加对话框初始化。
CDialog::OnSetFont重写以指定对话框控件在绘制文本时使用的字体。
CDialog::PrevDlgCtrl将焦点移到对话框中的上一个对话框控件。
CDialog::SetDefID将对话框的默认按钮控件更改为指定的按钮。
CDialog::SetHelpID为对话框设置区分上下文的帮助 ID。

受保护的方法

名称描述
CDialog::OnCancel重写以执行 “取消” 按钮或 ESC 键操作。 默认关闭对话框并 DoModal 返回 IDCANCEL。
CDialog::OnOK重写以在模式对话框中执行 “确定” 按钮操作。 默认关闭对话框并 DoModal 返回 IDOK。

04. 常用成员方法描述

4.1 构造函数

explicit CDialog(
    LPCTSTR lpszTemplateName,
    CWnd* pParentWnd = NULL);

explicit CDialog(
    UINT nIDTemplate,
    CWnd* pParentWnd = NULL);

CDialog();

参数
lpszTemplateName
	包含一个以 null 结尾的字符串,它是对话框模板资源的名称。
nIDTemplate
	包含对话框模板资源的 ID 号。
pParentWnd
	指向对话框对象 所属) 类型 的父或所有者窗口对象 (。 如果为 NULL,则对话框对象的父窗口将设置为主应用程序窗口。


          
                          
              

               

4.2 Create函数

virtual BOOL Create(
    LPCTSTR lpszTemplateName,
    CWnd* pParentWnd = NULL);

virtual BOOL Create(
    UINT nIDTemplate,
    CWnd* pParentWnd = NULL);
功能:                               
	调用 Create 以使用资源的对话框模板创建无模式对话框。
参数:
lpszTemplateName
	包含一个以 null 结尾的字符串,它是对话框模板资源的名称。
pParentWnd
	指向对话框对象 所属) 类型 的父窗口对象 (。 如果为 NULL,则对话框对象的父窗口将设置为主应用程序窗口。
nIDTemplate
	包含对话框模板资源的 ID 号。
返回值
	如果对话框创建和初始化成功,两个窗体都将返回非零值;否则为0。                               

示例:
void CMyDialog::OnMenuShowSimpleDialog()
{
   //m_pSimpleDialog initialized to NULL in the constructor of CMyDialog class
   m_pSimpleDlg = new CSimpleDlg();
   //Check if new succeeded and we got a valid pointer to a dialog object
   if (m_pSimpleDlg != NULL)
   {
      BOOL ret = m_pSimpleDlg->Create(IDD_SIMPLEDIALOG, this);

      if (!ret) //Create failed.
      {
         AfxMessageBox(_T("Error creating Dialog"));
      }

      m_pSimpleDlg->ShowWindow(SW_SHOW);
   }
   else
   {
      AfxMessageBox(_T("Error Creating Dialog Object"));
   }
}                 

4.3 DoModal函数


virtual INT_PTR DoModal();
功能:
	调用此成员函数以调用模式对话框并在完成后返回对话框结果。
参数:
	无
返回值:
	一个 int 值,该值指定传递给 CDialog:: EndDialog成员函数的 n 结果 参数的值,该参数用于关闭对话框。 
	如果函数无法创建对话框,则返回值为-1; 如果发生其他错误,则返回值为 IDABORT,在这种情况下,"输出" 窗口
	将包含来自 GetLastError的错误信息。       

参考示例:
void CMyDialog::OnMenuShowAboutDialog()
{
   // Construct the dialog box passing the
   // ID of the dialog template resource
   CDialog aboutDlg(IDD_ABOUTBOX);

   // Create and show the dialog box
   INT_PTR nRet = -1;
   nRet = aboutDlg.DoModal();

   // Handle the return value from DoModal
   switch (nRet)
   {
   case -1:
      AfxMessageBox(_T("Dialog box could not be created!"));
      break;
   case IDABORT:
      // Do something
      break;
   case IDOK:
      // Do something
      break;
   case IDCANCEL:
      // Do something
      break;
   default:
      // Do something
      break;
   };
}             

4.4 EndDialog函数

void EndDialog(int nResult);
功能:
	调用此成员函数以终止模式对话框。
参数:                           
  	N 结果
	包含要从对话框返回给调用方的值 DoModal 。
                           
参考示例:
void CMyDialog::OnMenuShowSimpleModal()
{
   CSimpleDlg myDlg;
   INT_PTR nRet = myDlg.DoModal();

   if (nRet == IDOK || nRet == 5)
   {
      AfxMessageBox(_T("Dialog closed successfully"));
   }
}
                           
void CSimpleDlg::OnRButtonUp(UINT nFlags, CPoint point)
{
   UNREFERENCED_PARAMETER(nFlags);
   // Do something

   int nRet = point.x; // Just any value would do!
   EndDialog(nRet);    // This value is returned by DoModal!

   // Do something

   return; // Dialog closed and DoModal returns only here!
}            

4.5 OnCancel函数

virtual void OnCancel();
功能:
    当用户在模式对话框或无模式对话框中单击 " 取消 " 或按 ESC 键时,框架会调用此方法。
    
参考示例:
void CSimpleDlg::OnCancel()
{
   // TODO: Add extra cleanup here

   // Ensure that you reset all the values back to the
   // ones before modification. This handler is called
   // when the user doesn't want to save the changes.

   if (AfxMessageBox(_T("Are you sure you want to abort the changes?"),
                     MB_YESNO) == IDNO)
   {
      // Give the user a chance if he has unknowingly hit the
      // Cancel button. If he says No, return. Don't reset. If
      // Yes, go ahead and reset the values and close the dialog.
      return;
   }

   m_nMyValue = m_nPrevValue;
   m_pMyString = NULL;

   CDialog::OnCancel();
}    
    

4.6 OnInitDialog函数

virtual BOOL OnInitDialog();
功能:
    调用此方法以响应 WM_INITDIALOG 消息。
参数:
    
返回值:
    指定应用程序是否已将输入焦点设置到对话框中的某个控件。 如果 OnInitDialog 返回非零值,
    则 Windows 将输入焦点设置到对话框中的第一个控件的默认位置。 仅当应用程序已将输入焦点
    显式设置到对话框中的某个控件时,应用程序才能返回0。

参考示例:
BOOL CSimpleDlg::OnInitDialog()
{
   CDialog::OnInitDialog();

   // TODO: Add extra initialization here
   m_cMyEdit.SetWindowText(_T("My Name")); // Initialize control values
   m_cMyList.ShowWindow(SW_HIDE);          // Show or hide a control, etc.

   return TRUE; // return TRUE unless you set the focus to a control
   // EXCEPTION: OCX Property Pages should return FALSE
}    

4.7 OnOK函数

virtual void OnOK();
功能:
	当用户单击 "确定" 按钮时调用 () ID 为 IDOK 的按钮。
    
参考示例:
void CSimpleDlg::OnOK()
{
   // TODO: Add extra validation here

   // Ensure that your UI got the necessary input
   // from the user before closing the dialog. The
   // default OnOK will close this.
   if (m_nMyValue == 0) // Is a particular field still empty?
   {
      // Inform the user that he can't close the dialog without
      // entering the necessary values and don't close the
      // dialog.
      AfxMessageBox(_T("Please enter a value for MyValue"));
      return;
   }

   CDialog::OnOK(); // This will close the dialog and DoModal will return.
}    

05. 附录

 类似资料: