MFC 对话框编程 -- 总结 .

简介: 一、创建对话框对象 1.首先利用资源编辑器创建对话框资源,并针对该对话框资源定义一个对话框类:class   CTestDlg :  public CDialog 2.创建话话框对象 模态对话框的创建:     如:      CTestDlg    dlg;      dlg.DoModal();   非模态对话框创建:    如:    CTestDlg    dlg;    dlg.Create(IDD_DIALOG, this);    但这样是得不到一个正常显示的非模态对话框的。

一、创建对话框对象

1.首先利用资源编辑器创建对话框资源,并针对该对话框资源定义一个对话框类:class   CTestDlg :  public CDialog

2.创建话话框对象

模态对话框的创建:

    如:

     CTestDlg    dlg;

     dlg.DoModal();

 

非模态对话框创建:

   如:

   CTestDlg    dlg;

   dlg.Create(IDD_DIALOG, this);

  

但这样是得不到一个正常显示的非模态对话框的。因为模态与非模态对话框的实现方式并不相同,这里我们还要注意几点。

  1. 非模态对话框创建完成后是隐藏着的,必须调用ShowWindow来进行显示。
  2. 对于模态对话框,当执行到DoModal 函数以创建对话框时,程序会暂停执行,直至模态对话框关闭。所以创建模态对话框可以采用局部对象。
    但是,对于非模态对话框,当执行Create函数时并不会暂停执行,当执行到大括号"}后Dlg局部对象被销毁生命周期结束,于是异常出现了。
    解决方法有两个:
        一、在View类中定义一个CTestDlg 成员变量。
        二、动态创建一个CTestDlg 变量,并重写CTestDlg 类的 PostNcDestroy函数,在该函数里销毁对象 delete    this;
  3. 无论创建的是模态对话框,还是非模态对话框,当我们单击确定或取消按钮后对话框都会消失。但这时低层的操作却是不同的。
    对于模态对话框,此时对话框对象的确是被销毁了,但对于非模态对话框,这时只是隐藏起来不再显示。这需要我们自己调用DestoryWindow函数来进行销毁工作。
    这时我们必须重写 CTestDlg 的 OnOK 、 OnCancel 两个函数(这两个是基类CDialog的虚函数),在这两个函数内调用DestroyWindow函数,并注意不再调用基类CDialog相应的函数。

正确地创建非模态对话框的代码如下:

CTestDlg   *pDlg = new CTestDlg;
pDlg->Create(IDD_DIALOG, this);
pDlg->ShowWindow(SW_SHOW);   

同时,在CTestDlg 类的 PostNcDestroy函数中销毁对象:delete   this;

 

二、动态创建按钮

1. 在对话框类CTestDlg 中定义一个 CButton 类对象,作为其成员变量。

2. 在相应的消息处理中,调用 CButton类的Create函数创建按钮。

要注意两点:

  • 如果在调用CButton::Create创建按钮时没有指定WS_VISIBLE 风格,那么随后一定要调用这个按钮对象的ShowWindow函数,来将该按钮显示出来。
  • 为防止该CButton关联多个按钮,这里需要进行一些设置,如下:
    if (!m_btn.m_hwnd)
    {
          // CButton 对象m_btn 未关联一个按钮
          m_btn.Create(....);
    }
    else
    {
          // CButton 对象m_btn 已关联一个按钮
          其他操作...
    }
    当然,方法并不只这一种。但这是最漂亮的方法。

 

三、设置控件文本文字

1.下面列举几个用来设置控件文本文字的函数:

// 取得对话框中指定控件的窗口句柄。控件通过ID标识来指定
CWnd*         GetDlgItem( int nID ) const;
void CWnd::GetDlgItem( int nID, HWND* phWnd ) const;

// 取得窗口文本
int      GetWindowText( LPTSTR lpszStringBuf, int nMaxCount ) const;
void   GetWindowText( CString& rString ) const;

// 设置窗口文本
void  SetWindowText( LPCTSTR lpszString );

// 取得指定控件窗口文本。控件通过ID标识来指定
int    GetDlgItemText( int nID, LPTSTR lpStr, int nMaxCount ) const;
int    GetDlgItemText( int nID, CString& rString ) const;

// 设置指定控件窗口文本。控件通过ID标识来指定
void SetDlgItemText( int nID, LPCTSTR lpszString );

// 取得指定控件窗口文本,并转化为UINT 类型返回。控件通过ID标识来指定
UINT GetDlgItemInt( int nID, BOOL* lpTrans = NULL, BOOL bSigned = TRUE ) const;

// 设置指定控件窗口文本,由UINT类型转化为字符 。控件通过ID标识来指定
void  SetDlgItemInt( int nID, UINT nValue, BOOL bSigned = TRUE );

2.可以为对话框控件关联一个变量,在CTestDlg 类的DoDataExchange来完成数据的更新与交换。

这里我们需要重点说明 DoDataExChange 函数:
首先引用MSDN的一段解释吧:Called by the framework to exchange and validate dialog data。意指框架调用此函数来改写与确认对话框数据。

其实DoDataExChange函数主要是通过DDX_TEXT(....)  或 DDX_CONTROL(....) 来实现数据的实时关联的。
我从我的MSDN中随便拿来一个定义:

void AFXAPI DDX_Text( CDataExchange* pDX, int nIDC, BYTE& value );

其实这个要关联的话也很简单,没有那么复杂。如下:

value = GetDlgItemInt(nIDC);
SetDlgItemInt(nIDC, value);


而DoDataExchange 函数是在UpdateData函数内部调用的。
该函数只有一个布尔型参数,它决定了数据传送的方向:

  • 调用UpdateData(TRUE)    , 将数据从对话框的控件中传送到对应的数据成员中。
  • 调用UpdateData(FALSE)  , 则将数据从数据成员中传送给对应的控件。

UpdateData(FALSE) 是将变量的值传到控件.
UpdateData(TRUE)  是从控件中取值到关联的变量

 

四、对话框伸缩功能的实现

只关联到两个函数:

// 取得指定窗口边框折尺寸

void GetWindowRect( LPRECT lpRect ) const;

// 设置指定窗口(控件)的位置同尺寸

BOOL SetWindowPos( const CWnd* pWndInsertAfter, intx, inty, int cx, intcy, UINTnFlags );

 

 

 

五、逃跑按钮的实现

1. 创建一个基于对话框的MFC 程序,删除原有的控件后,再添加两个按钮,更改两按钮名为"你能抓到我吗?"

2.打开类视图,定义一个新类CNewButton,这个新类的基类为CButton。并为此类添加一个成员变量:CNewButton   *m_pbtn;

3.打开资源视图,分别为两个按钮创建两个CNewButton类关联变量:m_btn1, m_btn2;

4.在CXXXDlg中改写其OnInitDialog函数。主要添加:

           m_btn1.m_pbtn = &m_btn2;

           m_btn2.m_pbtn = &m_btn1;

5.对于CNewButton 类,必定其OnMouseMove函数。主要添加:

           ShowWindow(SW_HIDE);

           m_pbtn->ShowWindow(SW_SHOW);

 

编译,连接。 OK

 

六、属性页、属性表单与向导的建立

1.创建属性页

打开资源编辑器,点击Dialog 资源并在列出的选项中,选择:IDD_PROPPAGE_LARGE。建立属性页资源。

之后,我们就可以其上添加其他控件来完善我们的属性页。关于属性页的完善操作我们在后面会谈到。

属性页资源完善后,再为每一个属性页关联一个类。

2.创建属性表单

打开类视图,添加新类CPropSheet,其基类为CPropertySheet。

之后再为其添加属性页类对象,并在其构造函数中利用AddPage函数将属性页添加到表单上。

3.消息响应

再主菜单的最后再增加一个菜单项,并为此菜单添加消息响应函数。

在此响应函数中创建属性表单:

CPropSheet     propSheet(TEXT("属性表单"));

propSheet.DoModal();

4.向导的创建

创建一个向导类型的对话框,应该遵循创建一个标准属性表单的步骤来实现。

但在调用属性表单对象的DoModal函数之前,应该先调用SetWizardMode函数,来声明建立的是一个作为向导的属性表单。

所以,应在DoModal函数之前添加如下代码:

propSheet.SetWizardMode();

5.属性页的完善操作

首先我们要注意到属性页,在三个不同时期的关键性操作:

  1. 当属性表单中的某属性页被选中,从而成为一个活动的页面时,应用程序框架就会调用OnSetActive函数。
    OnSetActive 是其基类的一个虚函数,我们可以重写这个函数并在其中进行一些操作。
  2. 假设当前我们处于属性表单中的某属性页,当我们点击下一步并将进入下一个属性页时,应用程序框架会调用OnWizardNext函数。
    OnWizardNext 是其基类的一个虚函数,我们可以重写这个函数并在其中进行一些操作。
    类似的还有OnWizardBack 同 OnWizardFinish函数。
  3. 当一个属性页被创建时,会调用其OnInitDialog函数。
    我们可以在这个函数里对属性页中的控件进行一些操作。如为列表框或下拉框添加字符串等。

 

from:http://blog.csdn.net/ltag0110rtag/article/details/7369105

目录
相关文章
|
Linux iOS开发 开发者
探索FFmpeg:实现自定义播放速度的全方位指南(一)
探索FFmpeg:实现自定义播放速度的全方位指南
1955 0
|
存储 编解码 调度
剖析ffmpeg视频解码播放:时间戳的处理
剖析ffmpeg视频解码播放:时间戳的处理
2230 0
|
4月前
|
人工智能 前端开发 小程序
26 年最新 AI 编程学习路线一条龙,5 分钟速通!
小白可懂的 AI 编程学习路线,6 个阶段从入门到进阶,覆盖 Cursor、Claude Code、Codex 三大主流工具,提示词工程、上下文管理、项目部署全流程,配套免费教程和实战项目。
1609 0
|
负载均衡 算法 Java
【SpringCloud(3)】Ribbon负载均衡:IRule原理轮询算法;LB负载均衡;loadbalancer和IRule组件;Ribbon和Ngin负载均衡的区别
Spring Cloud Ribbon 是基于Netflix Ribbon实现的一套客户端的负载均衡工具 简单地说,Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法和服务调用。Ribbon客户端组件提供一系列完善的配置项如连接超时、重试等。就在在配置文件中列出Load Balancer(LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机链接等)去连接这些机器。我们很容易使用Ribbon实现自定义的负载均衡算法
764 136
|
算法 Ubuntu API
探索FFmpeg:实现自定义播放速度的全方位指南(二)
探索FFmpeg:实现自定义播放速度的全方位指南
1085 0
|
存储 固态存储
磁盘和内存的区别
存储特性: • 磁盘:非易失性存储,数据在断电后不会丢失,适合长期存储数据。 • 内存:易失性存储,数据在断电后会丢失,适合临时存储当前运行的程序和数据。 容量: • 磁盘:容量通常较大,从几百GB到数TB不等,适合存储大量的文件和数据。 • 内存:容量相对较小,一般在几GB到几十GB之间,用于提供快速的临时存储空间。 速度: • 磁盘:读写速度较慢,HDD一般在几十MB/s,SSD可以达到几百MB/s甚至数GB/s。 • 内存:读写速度非常快,通常在几十纳秒到几百纳秒之间,能够快速响应CPU的指令。
1455 2
|
物联网 开发工具 Android开发
《鸿蒙HarmonyOS应用开发从入门到精通(第2版)》学习笔记——HarmonyOS产生的背景
HarmonyOS是华为自主研发的分布式操作系统,旨在应对美国“实体清单”带来的技术封锁。2019年首次亮相,它不仅支持手机、平板等多终端设备,还通过统一的软件系统解决了不同设备间的体验割裂问题。HarmonyOS强调全场景智能互联,提升设备间的安全性和协同能力。其商用版本基于OpenHarmony开源项目开发,而HarmonyOS NEXT则是去除了AOSP代码的纯自研版本,代表了未来发展方向。
1254 12
|
监控 网络协议 物联网
一款轻量级的通信协议---MQTT (内含Linux环境搭建)
**MQTT协议摘要** MQTT是一种轻量级的发布/订阅型网络协议,适用于低带宽、高延迟或不可靠的网络环境,尤其适合物联网(IoT)设备。其主要特点包括: 1. **发布/订阅模型**:设备通过主题进行通信,发布者无需知道订阅者,订阅者也不需知道消息来源。 2. **轻量级**:协议头部小,减少网络负载,适合资源受限的设备。 3. **断线重连**:支持客户端在失去连接后重新连接,保持通信。 4. **服务质量级别(QoS)**:提供0(最多一次)、1(至少一次)和2(恰好一次)三种级别,保证消息传递的可靠性。
914 1
无缝融合:使用 Python 和 PyFFmpeg 合并视频的完整指南
使用Python和PyFFmpeg合并视频教程:安装pyffmpeg和subprocess模块,编写merge_videos函数,通过ffmpeg命令行工具进行视频拼接。运行脚本将多个.mp4文件合并为一个,并保存为merged_video.mp4。简单易用,提升内容创作效率。
|
数据采集 传感器 存储
ESP32+MQTT+MySQL实现发布订阅【气味数据收集】
ESP32+MQTT+MySQL实现发布订阅【气味数据收集】
ESP32+MQTT+MySQL实现发布订阅【气味数据收集】

热门文章

最新文章