CDilalog包含三个关键函数:OnInitDialog、OnOK和OnCancel,可以覆盖这三个函数初始化对话框、响应点击OK和Cancel按钮。尽管每个函数都响应一条对话框消息,但是不需要你提供消息映射,因为CDialog已经做了消息映射,并把它们视为一般的虚函数。CDialog还提供了这三个函数的默认实现,如果充分利用MFC的对话框数据交换机制和验证机制,就不必覆盖它们。
对话框创建后,它会收到一条WM_CREATE消息。但是 WM_CREATE到达时,对话框模板上指定的控件还没有被创建,因此,不能被初始化。对话框是空的。Windows用来处理对话框消息的内部窗口过程响 应WM_CREATE时创建对话框的控件。控件创建后,对话框收到WM_INITDIALOG消息,使得对话框有机会进行必要的初始化,包括初始化控件。 在CDialog派生类中,WM_INITDIALOG激活对话框的OnInitDialog函数,它的原型是:
- virtual BOOL OnInitDialog ()
OnInitDialog是对话框工作前作必要准备的地方,例如:选择单选按钮或在编辑控件插入文本。该函数一被调用,对话框就存在于内存中,只是在屏幕上不可见。用户无法知道在OnInitDialog中做了什么,但是将会看到结果。
OnInitDialog的返回值告诉Windows如何处理输 入焦点。如果返回TRUE,Windows按照tab顺序使第一个控件具有输入焦点。如果想让其它控件具有输入焦点,可以在OnInitDialog中调 用控件的SetFocus函数,并返回FALSE,阻止Windows设置输入焦点。可以这样设置输入焦点:
- GetDlgItem (IDC_EDIT)->SetFocus ();
如果覆盖了OnInitDialog,就应该调用基类的OnInitDialog函数。原因稍后讲解。
用户点击OK按钮时,对话框收到WM_COMMAND消息,报告按钮被单击,MFC就调用对话框的OnOK虚函数。为了使这种机制可以工作,必须使OK按钮的ID值等于IDOK,例如下面的资源语句:
- DEFPUSHBUTTON "OK", IDOK, 60, 34, 40, 24, WS_GROUP
如果要在对话框关闭前进行特殊的处理,可以覆盖OnOK函数,这可能包含数据交换和数据验证。如果覆盖了OnOK,必须调用EndDialog或基类的OnOK函数销毁对话框。否则,点击OK按钮时,对话框不会消失。
点击Cancel按钮时如果要调用OnCancel,它的ID就 必须等于IDCANCEL。即使对话框中没有Cancel按钮,按下Esc键或标题栏上的关闭按钮都会调用OnCancel。通常不会覆盖 OnCancel,因为改变被取消后,无需从控件读取数据。CDialog::OnCancel使用IDCANCEL参数调用EndDialog销毁对话 框,并通知用户应该忽略控件的改变。
除了WM_INITDIALOG消息(该消息是对话框特有的),对话框接收的消息和窗口接收的消息相同。可以使用消息映射将这些消息映射到对话框类的成员函数。例如:
- ON_BN_CLICKED (IDC_RESET,OnReset)
点击ID值等于IDC_RESET的按钮时,就会调用OnReset。
对话框甚至可以处理WM_PAINT消息。因为控件可以重画自身,多数对话框不需要OnPaint。