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

原文地址: https://blog.csdn.net/ling_xiao007/article/details/51721363

6.1 对话框基本知识

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

6.1.1常用控件

1.png

6.1.2对话框的种类

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

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

6.2对话框的创建和显示

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


1.png

构造函数如下,首先调用基类的构造函数,并传递两个参数,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);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,752评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,100评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,244评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,099评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,210评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,307评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,346评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,133评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,546评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,849评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,019评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,702评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,331评论 3 319
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,030评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,260评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,871评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,898评论 2 351

推荐阅读更多精彩内容