CDialog 类

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

语法

class CDialog : public CWnd

成员

公共构造函数

名称 描述
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。

注解

对话框有两种类型:模式和无模式。 在应用程序继续之前,用户必须关闭模式对话框。 无模式对话框允许用户显示对话框并返回到另一个任务,而无需取消或移除对话框。

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

与任何其他窗口一样,对话框也从 Windows 接收消息。 在对话框中,你特别关心如何处理来自对话框控件的通知消息,因为这关系到用户如何与对话框交互。 使用类向导选择要处理的消息,它将为你在类中添加适当的消息映射条目和消息处理程序成员函数。 你只需要在处理程序成员函数中编写特定于应用程序的代码。

如果你愿意的话,可以始终手动编写消息映射条目和成员函数。

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

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

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

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

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

编程器和框架都通过对 CWnd::UpdateData 的调用来间接调用 DoDataExchange

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

在执行模式或无模式对话框期间,可以随时调用 CWnd::UpdateData

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

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

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

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

继承层次结构

CObject

CCmdTarget

CWnd

CDialog

要求

标头:afxwin.h

CDialog::CDialog

若要构造基于资源的模式对话框,请调用构造函数的任一公共形式。

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

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

CDialog();

参数

lpszTemplateName
包含一个以 null 结尾的字符串,它是对话框模板资源的名称。

nIDTemplate
包含对话框模板资源的 ID 号码。

pParentWnd
指向对话框对象所属的父窗口对象或所有者窗口对象(类型为 CWnd)。 如果为 NULL,则对话框对象的父窗口设置为主应用程序窗口。

备注

构造函数的一种形式是通过模板名称来访问对话框资源。 另一个构造函数通过模板 ID 编号访问,此编号通常具有 IDD_ 前缀(例如 IDD_DIALOG1)。

若要从内存中的模板构造模式对话框,请先调用无参数、受保护的构造函数,然后再调用 InitModalIndirect

使用上述方法之一构造模式对话框后,调用 DoModal

若要构造无模式对话框,请使用 CDialog 构造函数的受保护形式。 构造函数受到保护,因为你必须派生自己的对话框类才能实现无模式对话框。 无模式对话框的构造过程分为两步。 首先,调用构造函数;然后调用 Create 成员函数以创建基于资源的对话框,或调用 CreateIndirect 以从内存中的模板创建对话框。

CDialog::Create

使用资源中的对话框模板调用 Create 以创建无模式对话框。

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

virtual BOOL Create(
    UINT nIDTemplate,
    CWnd* pParentWnd = NULL);

参数

lpszTemplateName
包含一个以 null 结尾的字符串,它是对话框模板资源的名称。

pParentWnd
指向对话框对象所属的父窗口对象(类型为 CWnd)。 如果为 NULL,则对话框对象的父窗口设置为主应用程序窗口。

nIDTemplate
包含对话框模板资源的 ID 号码。

返回值

如果已成功创建和初始化对话框,这两种形式将返回非零值,否则返回 0。

备注

可以将对 Create 的调用放在构造函数内部,或者在调用构造函数后再调用它。

提供了 Create 成员函数的两种形式,以便通过模板名称或模板 ID 编号(例如IDD_DIALOG1)访问对话框模板资源。

对于任一形式,都是将指针传递给父窗口对象。 如果 pParentWnd 为 NULL,创建对话框时,其父窗口或所有者窗口将设置为主应用程序窗口。

Create 成员函数在创建对话框后会立即返回。

如果应在创建父窗口时显示对话框,请使用对话框模板中的 WS_VISIBLE 样式。 否则,必须调用 ShowWindow。 有关更多对话框样式及其应用,请参阅 Windows SDK 中的 DLGTEMPLATE 结构和“MFC 参考”中的窗口样式

使用 CWnd::DestroyWindow 函数销毁 Create 函数创建的对话框。

示例

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"));
   }
}

CDialog::CreateIndirect

调用此成员函数,以从内存中的对话框模板创建无模式对话框。

virtual BOOL CreateIndirect(
    LPCDLGTEMPLATE lpDialogTemplate,
    CWnd* pParentWnd = NULL,
    void* lpDialogInit = NULL);

virtual BOOL CreateIndirect(
    HGLOBAL hDialogTemplate,
    CWnd* pParentWnd = NULL);

参数

lpDialogTemplate
指向包含用于创建对话框的对话框模板的内存。 此模板采用 DLGTEMPLATE 结构和控件信息的形式,如 Windows SDK 中所述。

pParentWnd
指向对话框对象的父窗口对象(类型为 CWnd)。 如果为 NULL,则对话框对象的父窗口设置为主应用程序窗口。

lpDialogInit
指向 DLGINIT 资源。

hDialogTemplate
包含一个全局内存的句柄,其中包含一个对话框模板。 此模板采用 DLGTEMPLATE 结构和对话框中每个控件的数据的形式。

返回值

如果已成功创建和初始化对话框,则为非零值;否则为 0。

备注

CreateIndirect 成员函数在创建对话框后会立即返回。

如果应在创建父窗口时显示对话框,请使用对话框模板中的 WS_VISIBLE 样式。 否则,必须调用 ShowWindow 才能使它显示。 有关如何在模板中指定其他对话框样式的详细信息,请参阅 Windows SDK 中的 DLGTEMPLATE 结构。

使用 CWnd::DestroyWindow 函数销毁 CreateIndirect 函数创建的对话框。

包含 ActiveX 控件的对话框需要在 DLGINIT 资源中提供额外的信息。

CDialog::DoModal

调用此成员函数以调用模式对话框,并在完成后返回对话框结果。

virtual INT_PTR DoModal();

返回值

一个 int 值,指定传递给 CDialog::EndDialog 成员函数的 nResult 参数的值,用于关闭对话框。 如果函数无法创建对话框,则返回值为 -1;如果发生了其他错误,则返回值为 IDABORT,在这种情况下,输出窗口将包含 GetLastError 中的错误信息。

备注

此成员函数处理当对话框处于活动状态时与用户的所有交互。 这会使对话框模式化;也就是说,在对话框关闭之前,用户不能与其他窗口交互。

如果用户单击对话框中的某个按钮(如“确定”或“取消”),则会调用消息处理程序成员函数(如 OnOKOnCancel)以尝试关闭对话框。 默认的 OnOK 成员函数将验证和更新对话框数据,并以结果 IDOK 关闭对话框,默认的 OnCancel 成员函数将以结果 IDCANCEL 关闭对话框,而不会验证或更新对话框数据。 可以替代这些消息处理程序函数以更改其行为。

注意

现在将调用 PreTranslateMessage 以处理模式对话框消息。

示例

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;
   };
}

CDialog::EndDialog

调用此成员函数以终止模式对话框。

void EndDialog(int nResult);

参数

nResult
包含要从对话框返回到 DoModal 的调用方的值。

备注

此成员函数将返回 nResult 作为 DoModal 的返回值。 每当创建模式对话框时,都必须使用 EndDialog 函数完成处理。

可以随时调用 EndDialog,甚至是在 OnInitDialog 中,在这种情况下,应在显示对话框之前或者在设置输入焦点之前关闭对话框。

EndDialog 不会立即关闭对话框。 相反,它会设置一个标志,指示对话框在当前消息处理程序返回后立即关闭。

示例

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!
}

CDialog::GetDefID

调用 GetDefID 成员函数以获取对话框的默认按钮控件的 ID。

DWORD GetDefID() const;

返回值

一个 32 位的值 (DWORD)。 如果默认按钮具有 ID 值,则高序位字包含 DC_HASDEFID,低序位字包含 ID 值。 如果默认按钮没有 ID 值,则返回值为 0。

备注

这通常是“确定”按钮。

CDialog::GotoDlgCtrl

将焦点移动到对话框中的指定控件。

void GotoDlgCtrl(CWnd* pWndCtrl);

参数

pWndCtrl
标识要接收焦点的窗口(控件)。

注解

若要获取指向控件(子窗口)的指针以作为 pWndCtrl 传递,请调用 CWnd::GetDlgItem 成员函数,这会返回指向 CWnd 对象的指针。

示例

请参阅 CWnd::GetDlgItem 的示例。

CDialog::InitModalIndirect

调用此成员函数,以使用在内存中构造的对话框模板初始化模式对话框对象。

BOOL InitModalIndirect(
    LPCDLGTEMPLATE lpDialogTemplate,
    CWnd* pParentWnd = NULL,
    void* lpDialogInit = NULL);

    BOOL InitModalIndirect(
    HGLOBAL hDialogTemplate,
    CWnd* pParentWnd = NULL);

参数

lpDialogTemplate
指向包含用于创建对话框的对话框模板的内存。 此模板采用 DLGTEMPLATE 结构和控件信息的形式,如 Windows SDK 中所述。

hDialogTemplate
包含一个全局内存的句柄,其中包含一个对话框模板。 此模板采用 DLGTEMPLATE 结构和对话框中每个控件的数据的形式。

pParentWnd
指向对话框对象所属的父窗口对象或所有者窗口对象(类型为 CWnd)。 如果为 NULL,则对话框对象的父窗口设置为主应用程序窗口。

lpDialogInit
指向 DLGINIT 资源。

返回值

如果已成功创建和初始化对话框对象,则为非零值;否则为 0。

备注

若要间接创建模式对话框,首先要分配一个全局内存块,并将其填充到对话框模板。 然后调用空 CDialog 构造函数来构造对话框对象。 接下来,调用 InitModalIndirect 以将句柄存储到内存中的对话框模板。 稍后,在调用 DoModal 成员函数时,会创建并显示 Windows 对话框。

包含 ActiveX 控件的对话框需要在 DLGINIT 资源中提供额外的信息。

CDialog::MapDialogRect

调用以将矩形的对话框单位转换为屏幕单位。

void MapDialogRect(LPRECT lpRect) const;

参数

lpRect
指向包含要转换的对话框坐标的 RECT 结构或 CRect 对象。

注解

对话框单位是以当前的对话框基础单位来表示的,基础单位来自对话框文本所用字体的字符平均宽度和高度。 一个水平单位是对话框基础宽度单位的四分之一,一个垂直单位是对话框基础高度单位的八分之一。

GetDialogBaseUnits Windows 函数返回系统字体的大小信息,但如果你在资源定义文件中使用 DS_SETFONT 样式,可以为每个对话框指定不同的字体。 MapDialogRect Windows 函数为此对话框使用相应的字体。

MapDialogRect 成员函数将 lpRect 中的对话框单位替换为屏幕单位(像素),这样就可以使用矩形来创建对话框或将控件置于对话框内。

CDialog::NextDlgCtrl

将焦点移动到对话框中的下一个控件。

void NextDlgCtrl() const;

备注

如果焦点位于对话框中的最后一个控件上,它将移到第一个控件。

CDialog::OnCancel

当用户单击“取消”或者在模式或无模式对话框中按 ESC 键时,框架将调用此方法。

virtual void OnCancel();

注解

替代此方法,在用户通过单击“取消”或按 ESC 键关闭对话框时执行操作(例如还原旧数据)。 默认将通过调用 EndDialog 并导致 DoModal 返回 IDCANCEL 来关闭模式对话框。

如果在无模式对话框中实现“取消”按钮,则必须替代 OnCancel 方法并在其中调用 DestroyWindow 不要调用基类方法,因为它会调用 EndDialog,这将使对话框不可见,但不会销毁它。

注意

在 Windows XP 下编译的程序中使用 CFileDialog 对象时,不能替代此方法。 有关 CFileDialog 的详细信息,请参阅 CFileDialog 类

示例

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();
}

CDialog::OnInitDialog

在响应 WM_INITDIALOG 消息时调用此方法。

virtual BOOL OnInitDialog();

返回值

指定应用程序是否已将输入焦点设置为对话框中的一个控件。 如果 OnInitDialog 返回非零值,Windows 会将输入焦点设置为默认位置,即对话框中的第一个控件。 仅当应用程序已将输入焦点明确设置为对话框中的某个控件时,应用程序才能返回 0。

备注

Windows 在 CreateCreateIndirectDoModal 调用期间将 WM_INITDIALOG 消息发送到对话框,这些调用在显示对话框之前立即发生。

如果要在初始化对话框时执行特殊处理,请替代此方法。 在替代后的版本中,首先调用基类 OnInitDialog,但忽略其返回值。 通常会从替代后的方法返回 TRUE

Windows 使用所有 Microsoft 基础类库对话框通用的标准全局对话框过程调用 OnInitDialog 函数。 它不会通过消息映射调用此函数,因此你不需要为此方法设置消息映射条目。

注意

在 Windows Vista 或更高版本的操作系统下编译的程序中使用 CFileDialog 对象时,不能替代此方法。 有关 Windows Vista 及更高版本下的 CFileDialog 更改的详细信息,请参阅 CFileDialog 类

示例

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
}

CDialog::OnOK

在用户单击“确定”按钮(ID 为 IDOK 的按钮)时调用。

virtual void OnOK();

注解

替代此方法以在激活“确定”按钮时执行操作。 如果对话框包含自动数据验证和交换,则此方法的默认实现将验证对话框数据,并更新应用程序中的相应变量。

如果在无模式对话框中实现“确定”按钮,必须替代 OnOK 方法并在其中调用 DestroyWindow 不要调用基类方法,因为它会调用 EndDialog,这将使对话框不可见,但不会销毁它。

注意

在 Windows XP 下编译的程序中使用 CFileDialog 对象时,不能替代此方法。 有关 CFileDialog 的详细信息,请参阅 CFileDialog 类

示例

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.
}

CDialog::OnSetFont

指定对话框控件在绘制文本时使用的字体。

Virtual void OnSetFont(CFont* pFont);

参数

pFont
[in] 指定指向将用作此对话框中所有控件的默认字体的字体的指针。

注解

对话框将使用指定的字体作为其所有控件的默认值。

对话框编辑器通常将对话框字体设置为对话框模板资源的一部分。

注意

在 Windows Vista 或更高版本的操作系统下编译的程序中使用 CFileDialog 对象时,不能替代此方法。 有关 Windows Vista 及更高版本下的 CFileDialog 更改的详细信息,请参阅 CFileDialog 类

CDialog::PrevDlgCtrl

将焦点设置为对话框中的上一个控件。

void PrevDlgCtrl() const;

注解

如果焦点位于对话框中的第一个控件上,它将移到对话框中的最后一个控件。

CDialog::SetDefID

更改对话框的默认按钮控件。

void SetDefID(UINT nID);

参数

nID
指定将成为默认值的按钮控件的 ID。

CDialog::SetHelpID

设置对话框的上下文相关帮助 ID。

void SetHelpID(UINT nIDR);

参数

nIDR
指定上下文相关的帮助 ID。

另请参阅

MFC Sample DLGCBR32
MFC Sample DLGTEMPL
CWnd 类
层次结构图