对话框基础知识(一)

来源:互联网 发布:兰芝睡眠面膜 知乎 编辑:程序博客网 时间:2024/05/16 09:50

对话框是Windows应用程序中重要的用户接口,对话框实际上也是一个窗口,可以接收消息,绘制图案、移动窗口等。我们可以把对话框看做是一个大容器,能够在上面放置各种各样的标准空间和扩展控件。


对话框种类


对话框有两种类型:模态(Modal)对话框和非模态(Modaless)对话框。

  • 模态对话框
模态对话框是指当其显示时,程序会暂停执行,直至关闭这个模态对话框,才能继续执行程序中的其他任务。模态对话框具有阻塞性质。

  • 非模态窗口
         当非模态窗口对话框显示时,允许执行继续其他任务,而不用关心这个对话框。


对话框的创建&显示

     

        如果想在程序中创建自己的对话框,可以通过插入一个对话框资源来完成。在MFC中,对资源的操作通常都是通过一个与资源相关的类来完成的。例如,对话框资源对应的类就是CDialog,该类派生于CWnd类,是窗口相关的类。CWnd类中的m_hWnd指示了与其所关联的窗口。


对话框资源添加步骤:

        资源视图->添加->添加资源->选择“Dialog”->点击“新建”,效果如图1所示。在对话框上面默认有两个按钮:“确定”和“取消”,对应ID号是ID_OK和ID_CANCAL.

        添加与资源相关的类:

        资源编辑器->鼠标右键->添加类,效果如图2所示:

                                                 图1 对口框资源


                                            图2 绑定对对话框资源的类


模态对话框创建


创建模态对话框需要调用CDialog类中的成员函数DoModal,该函数的功能是创建并显示一个模态对话框,其返回值作为Endialog的参数,其功能是关闭模态对话框。通常我们根据该DoModal返回值来判断用户单击的是哪一个按钮,从而确定用户行为

DoModal的函数声明如下:

virtual int DoModal();
由于DoMal函数具有阻塞性,函数执行会停止在DoMal所在的行,所以此时对话框的对象可以是临时的。代码如下:

    //模态窗口创建    CTestDlg dlg;    //窗口关闭,DoModal程序执行完成,否则程序一直阻塞在DoModal函数。    dlg.DoModal();    //窗口关闭,程序执行到该语句

非模态对话框创建


如果要创建非模态窗口,则需要利用CDialog类的Create成员函数,该函数相关声明如下:

BOOL Create(LPCSTR lpszTemplateName, CWnd* pParentWnd = NULL);BOOL Create(UNIT nIDTemplate, CWnd* pParentWnd = NULL);返回值:如果对话框创建和初始化成功,则返回非零值,否则为0。参数: lpszTemplateName 包含一个对话框模板资源的空终止字符串。  pParentWnd 指向含有对话框的父窗口对象的指针。如果为NULL,对话框对象的父窗口设置为应用的主窗口。  nIDTemplate 包含对话框模板资源的ID数。  说明:调用Create,使用资源中对话框模板来创建非模态对话框。可将调用置于构造程序内部或者在构造程序启动之后调用。
具体代码下:
    //非模态窗口创建    if (GetDlg() != NULL)    {        if (NULL == GetDlg()->m_hWnd)        {            GetDlg()->Create(IDD_DIALOG_EXPORT, this);//GetDlg返回CDialog对象指针            GetDlg()->ShowWindow(SW_SHOW);        }    }

三个重要函数说明


我们创建的默认对话框中包含了两个按钮“确认”和“取消”,它们所对应的功能都是一样的,就是关闭对话框。对于模态对话框而言,此时对话框对象被销毁了,所对应的窗口也被释放,而对于非模态对口框来说,对话框对象并未被消息销毁,只是被隐藏起来了。下面说明这两个按钮所对应的函数以及窗口创建初始化函数OnInitDialog。

virtual void OnCancel();
说明:
当用户在模态对话框或非模态对话框内单击Cancel按钮或按ESC键时,窗体调用这个成员函数。
对于模态窗口:
调用EndDialog来简单中止模态对话框,并使DoModal返回IDCANCEL,该模态窗口被销毁,不需要重写改函数。
对于非模态窗口:
需要重写OnCancel成员函数,并调用DestoryWindow函数来销毁窗口。不能再调用基类的OnCancel函数,否则那将会调用EndDialog,使对话框虽然存在但不可视。

virtual void OnOK();
说明:
当用户按OK按钮(ID是IDOK)时调用。对于模态窗口可以销毁窗口,而非模态窗口则需要重写该函数,具体使用和OnCancel类似。  
virtual BOOL OnInitDialog();
说明:
调用这个成员函数是对WM_INITDIALOG消息作出的反应。这条消息是在对话框即将显示之前,在Create,CreateIndirect或DoModal调用期间发出的。我们可以利用重写该函数完成数据的初始化。


案例 


根据以上知识介绍,可以完成对话框的创建和显示,这里以创建非模态窗口为例,我们在菜单栏中创建Test菜单,并在视类中完成消息的响应,对口框窗口所对应的类是CTestDlg,具体代码如下:

对话框消息消息响应函数:

//对话框创建,显示之前响应BOOL CTestDlg::OnInitDialog(){    CDialog::OnInitDialog();    // TODO:  在此添加额外的初始化    //主要用于用户数据初始化    AfxMessageBox("OnInitDialog");    return TRUE;  }//确定按钮响应函数void CTestDlg::OnOK(){    // TODO: 在此添加专用代码和/或调用基类    AfxMessageBox("OnOK");    DestroyWindow();        //CDialog::OnOK();}//取消按钮响应函数void CTestDlg::OnCancel(){    // TODO: 在此添加专用代码和/或调用基类    AfxMessageBox("OnCancel");    DestroyWindow();    //CDialog::OnCancel();}
视类中的相关函数:

//创建对话框类CTestDlg* CDialogView::GetDlg(){    if (m_dlg == NULL)    {        m_dlg = new CTestDlg;    }    return m_dlg;}//Test菜单消息响应函数void CDialogView::OnTest(){    //非模态窗口创建    if (GetDlg() != NULL)    {        if (NULL == GetDlg()->m_hWnd)        {            GetDlg()->Create(IDD_DIALOG_EXPORT, this);            GetDlg()->ShowWindow(SW_SHOW);        }    }}

运行结果:


1 0