六. 对话框编程--Windows编程课程学习笔记

Posted ling_xiao007

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了六. 对话框编程--Windows编程课程学习笔记相关的知识,希望对你有一定的参考价值。

6.1 对话框基本知识

对话框是一个窗口,与对话框资源相关的类为CDialog,由CWnd类派生而来。可以将对话框看成是一个大容器,在它上面能够放置各种标准和扩展控件,是用户与程序进行交互的重要手段。在MFC中,所有的控件都是由CWnd派生而来,因此,控件实际上也是窗口

6.1.1常用控件


6.1.2对话框的种类

1)模式对话框:当其显示时,程序会暂停执行,直到关闭这个对话框后,才能继续执行程序中其他任务。例如“文件/打开” 对话框。

2)无模式对话框:当其显示时,允许转而执行程序中其他任务,而不用关闭这个对话框。该类型对话框不会垄断用户的操作,用户仍可以与其他界面对象进行交互。例如“查找”对话框。

6.2对话框的创建和显示

在MFC中对资源的操作通常都是通过一个与资源相关的类来完成。可以在新建的对话框资源上双击完成添加。看到对话框id已经默认填写。这是在ClassViea选项卡就可以看到这个新类。


构造函数如下,首先调用基类的构造函数,并传递两个参数,IDD成员以及父窗口指针。在头文件可以看打这个对话框资源的ID。

CTestDlg::CTestDlg(CWnd* pParent /*=NULL*/)
    : CDialogEx(IDD_DIALOG1, pParent)

 

 
// 对话框数据
#ifdef AFX_DESIGN_TIME
    enum  IDD = IDD_DIALOG1 ;
#endif

另一个函数是DoDataExchange,完成对话框数据的交换和校验。

现在有了一个类和IDD_DIALOG1资源相关联。接卸来希望显示,为此增加一个菜单项,用户点击显示对话框。在【帮助】下添加【对话框】,去掉Pop-up,ID设置为ID_DIALOG。 

6.2.1模态对话框

创建模式对话框需要调用CDialog类的成员函数:DoModal,该函数的功能就是创建并显示一个模式对话框。为此视类添加ID_DIALOG响应函数如下。

void CMyMFCAppView::OnDialog()

    //TODO: 在此添加命令处理程序代码
    CTestDlg dlg;
    dlg.DoModal();

6.2.2非模态对话框

创建无模式对话框需要调用CDialog类的成员函数:BOOL Create(UINT nIDTemplate, CWnd* pParentWnd = NULL);第一个参数可以是资源ID,也可以是名称,第二个指定父窗口。当利用Create函数创建无模式对话框时,还需要调用ShowWindow函数将这个对话框显示出来。且不能设为局部变量加Detach方式。有两种方式,其一是将其定义为视类的成员变量,其二是将其定义为指针,分配在堆上,需要在视类析构函数delete释放,或者重构CTestDlg类虚函数PostNcDestory。

void CMyMFCAppView::OnDialog()

    //TODO: 在此添加命令处理程序代码
   
    CTestDlg *dPlg = new CTestDlg;
    dPlg->Create(IDD_DIALOG1, this);
    dPlg->ShowWindow(SW_SHOW);

 
void CTestDlg::PostNcDestroy()

    //TODO: 在此添加专用代码和/或调用基类
    delete this;
    CDialogEx::PostNcDestroy();

若要在程序中主动销毁无模式对话框(例如在没有 “确定”和“取消”按钮的情况下销毁对话框),需调用函数DestroyWindow

6.3动态创建按钮

实现一个功能,单击对话框中某个按钮,在对话框动态创建一个新按钮。

1)为IDD_DIALOG1创建一个对话框资源,ID属性设置为IDC_BTN_ADD,Caption为Add。

2)添加自定义私有变量CButton类的m_btn。

3)CTestDlg类为IDC_BTN_ADD响应BN_CLICKED消息。WS_VISIBLE没有则需要ShowWindow函数。

 m_btn.Create("New", BS_DEFPUSHBUTTON | WS_VISIBLE | WS_CHILD,
 CRect(0,0, 100, 100), this, 123);

4)位CTestDlg类添加私有成员变量或者静态局部变量BOOL类m_bIsCreated,用来标识是否已经创建。亦可以用一个成员变量m_hWnd

void CTestDlg::OnClickedBtnAdd()

    //TODO: 在此添加控件通知处理程序代码
    if (FALSE == m_bIsCreated)
    
        m_btn.Create("New", BS_DEFPUSHBUTTON | WS_VISIBLE | WS_CHILD, CRect(0,0, 100, 100), this, 123);
        m_bIsCreated = TRUE;
    
    else
    
        m_btn.DestroyWindow();
        m_bIsCreated = FALSE;
    

 
void CTestDlg::OnClickedBtnAdd()

    //TODO: 在此添加控件通知处理程序代码
    if (!m_btn.m_hWnd)
        m_btn.Create("New", BS_DEFPUSHBUTTON | WS_VISIBLE | WS_CHILD, CRect(0,0, 100, 100), this, 123);
    else
        m_btn.DestroyWindow();

6.4控件的访问

6.4.1静态文本控件

实现点击”Number1:”,文本变成“数值1:”。

1)首先设置ID号为IDC_NUMBER1以区分三个静态文本。

2)响应IDC_NUMBER1的BN_CLICKED消息。

3)控件也是窗口,所以可以利用CWnd的成员函数GetWindowText。

4)静态文本在默认状态下不可以发送通告消息,在属性对话框选定Notify选项。

void CTestDlg::OnStnClickedNumber1()

    //TODO: 在此添加控件通知处理程序代码
    CString str;
    if (GetDlgItem(IDC_NUMBER1)->GetWindowText(str), str == "Number1:")
        GetDlgItem(IDC_NUMBER1)->SetWindowText("数值1:");
    else
        GetDlgItem(IDC_NUMBER1)->SetWindowText("Number1:");

6.4.2 编辑框控件

1)GetDlgItem + Get/SetWindowText.重要函数:CWnd* GetDlgItem(int nID) const;该函数返回一个指向由参数nID指定的控件对象的指针。

    int num1, num2, num3;
    char c1[10], c2[10], c3[10];
    GetDlgItem(IDC_EDIT1)->GetWindowText(c1,10);
    GetDlgItem(IDC_EDIT2)->GetWindowText(c2,10);  
    num1 = atoi(c1);
    num2 = atoi(c2);
    num3 = num1 + num2;
    itoa(num3, c3, 10);
    GetDlgItem(IDC_EDIT3)->SetWindowText(c3);

2) Get/SetDlgItemText。该函数返回对话框中指定nID的控件上的文本。也就是说:GetDlgItemText函数把方法1中介绍的GetDlgItem和GetWindowText这两个函数的功能组合起来了。

   int num1, num2, num3;
    char c1[10], c2[10], c3[10];
    GetDlgItemText(IDC_EDIT1, c1, 10);
    GetDlgItemText(IDC_EDIT2, c2, 10);
 
    num1 = atoi(c1);
    num2 = atoi(c2);
    num3 = num1 + num2;
    itoa(num3, c3, 10);
    SetDlgItemText(IDC_EDIT3, c3);

3)Get/SetDlgItemInt。该函数首先获得对话框中指定nID的控件上的文本,然后将其转换为一个整型数值返回。

   int num1, num2, num3;
 
    num1 = GetDlgItemInt(IDC_EDIT1);
    num2 = GetDlgItemInt(IDC_EDIT2);
    num3 = num1 + num2;
 
    SetDlgItemInt(IDC_EDIT3,num3);

4)MFC的DDX数据交换——控件和整型变量关联。最简单的访问控件的方式:通过类向导,在对话框函数DoDataExchange内部实现对话框控件与对话框类的成员变量相关联。类别为Value。为了让数据交换生效,需调用UpdateData函数。(DDX对话框数据交换,DDV对话框数据校验)

    UpdateData();    //成员变量从对话框控件中获取数据
    m_num3 = m_num1 + m_num2;
    UpdateData(FALSE);    //以成员变量的值初始化对话框控件

5)MFC的DDX数据交换——控件和控件变量关联。类别为Control。CEdit派生于CWnd类,所以可以调用GetWindowText等函数。

    int num1, num2, num3;
    char c1[10], c2[10], c3[10];
    m_edit1.GetWindowText(c1,10);
    m_edit2.GetWindowText(c2,10);
    num1 = atoi(c1);
    num2 = atoi(c2);
    num3 = num1 + num2;
    itoa(num3, c3, 10);
    m_edit3.SetWindowText(c3);

6)发送消息——SendMessage。Windows程序是基于消息的系统,因此,只要获取设置窗口文本的消息,就可以通过SendMessage来发送这条消息,从而获取/设置窗口的文本。 

    int num1, num2, num3;
    char c1[10], c2[10], c3[10];
    ::SendMessage(GetDlgItem(IDC_EDIT1)->m_hWnd, WM_GETTEXT, 10, (LPARAM)c1);
    ::SendMessage(m_edit2.m_hWnd, WM_GETTEXT,10, (LPARAM)c2);
    num1 = atoi(c1);
    num2 = atoi(c2);
    num3 = num1 + num2;
    itoa(num3, c3, 10);
    m_edit3.SendMessage(WM_SETTEXT, 0,(LPARAM)c3);

7)发送消息——SendDlgItemMessage。直接给对话框的子控件发送消息:

LRESULTSendDlgItemMessage(int nID, UINT message, WPARA wParam = 0, LPARAM lParam = 0)

该函数功能相当于把上面GetDlgItem和SendMessage这两个函数的组合。

   int num1, num2, num3;
    char c1[10], c2[10], c3[10];
 
    SendDlgItemMessage(IDC_EDIT1, WM_GETTEXT, 10, (LPARAM)c1);
    SendDlgItemMessage(IDC_EDIT2, WM_GETTEXT, 10, (LPARAM)c2);
 
    num1 = atoi(c1);
    num2 = atoi(c2);
    num3 = num1 + num2;
    itoa(num3, c3, 10);
 
    SendDlgItemMessage(IDC_EDIT3, WM_SETTEXT, 0, (LPARAM)c3);

以上是关于六. 对话框编程--Windows编程课程学习笔记的主要内容,如果未能解决你的问题,请参考以下文章

Windows编程课程学习笔记

Windows编程课程学习笔记

五. 菜单编程--Windows编程课程学习笔记

五. 菜单编程--Windows编程课程学习笔记

MOOC《Linux操作系统编程》学习笔记-实验六

七. 界面编程--Windows编程课程学习笔记