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 以创建无模式对话框,或调用 InitModalIndirect 和 DoModal 以创建模式对话框。
这会在添加到新对话框类的 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
的详细信息,请参阅对话框。
继承层次结构
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 中的错误信息。
备注
此成员函数处理当对话框处于活动状态时与用户的所有交互。 这会使对话框模式化;也就是说,在对话框关闭之前,用户不能与其他窗口交互。
如果用户单击对话框中的某个按钮(如“确定”或“取消”),则会调用消息处理程序成员函数(如 OnOK 或 OnCancel)以尝试关闭对话框。 默认的 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 在 Create、CreateIndirect 或 DoModal 调用期间将 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。