19、Visual C++ 常见控件使用指南

Visual C++ 常见控件使用指南

在创建和显示对话框之后,接下来要探讨的是如何使用对话框中的控件,并将这些控件与源代码进行关联。以下将详细介绍一些常见控件的使用方法。

1. 数据验证函数

有一些 DDV(对话框数据验证)函数用于验证数据范围,除了 DDV_MinMaxInt() 外,还有 DDV_MinMaxByte() DDV_MinMaxDouble() 等函数,它们用于验证其他数值数据类型的范围。表 8.2 列出了两个 DDV 函数,其详细信息将在后续对应控件的部分进行讨论。

2. 常见控件概述

对话框资源编辑器可用于排列对话框中的控件,以实现所需的外观。同时,还可以为每个控件分配一个 ID,这些 ID 会在 resource.h 文件中声明,以便在代码中与控件进行交互。

除了常见控件,还有 ActiveX 控件。ActiveX 控件可以像常见控件一样放置在对话框中,其独特之处在于不一定用 C++ 编写。可以将用 Visual Basic 编写的 ActiveX 控件插入到 C++ 程序中,这为开发者提供了更多的控件选择。

由于可用的控件众多,无法逐一讨论其用法。下面将介绍 Visual C++ 中一些常见控件的使用,如按钮、编辑框、列表框和组合框等。掌握这些常见控件的使用后,使用其他控件也会变得类似。

3. 按钮控件

按钮控件是对话框中最常见的控件,主要有三种类型:标准按钮、复选框和单选按钮。

3.1 标准按钮

对话框中的“确定”和“取消”按钮就是标准按钮的例子。按下标准按钮时会生成 WM_COMMAND 消息,可以使用 ON_COMMAND() 宏将按钮的标识符与消息处理程序关联起来。 CDialog 类将 IDOK 映射到 OnOK() 处理程序,将 IDCANCEL 映射到 OnCancel() 处理程序。

可以使用“按钮属性”对话框为按钮分配合适的标识符。为按钮点击事件分配消息处理程序有两种方法:
1. 使用 ON_COMMAND() 宏。例如,若按钮标识符为 IDC_NEW_ENTRY ,可通过以下消息映射将其消息映射到 OnNewEntry() 函数:

ON_COMMAND(IDC_NEW_ENTRY, OnNewEntry)

这种方法处理按钮消息与处理其他资源的菜单项消息相同,若应用程序中有相同标识符的菜单项,选择该菜单项会产生与点击此按钮相同的效果。
2. 使用 ON_BN_CLICKED() 宏。例如:

ON_BN_CLICKED(IDC_NEW_ENTRY, OnNewEntry)

使用 ON_BN_CLICKED() 宏可使消息映射更易读,因为从宏名就能明确消息来自按钮点击。Visual C++ 中的类向导在生成消息映射项时会使用该宏。

3.2 复选框

复选框由标签和一个可勾选或取消勾选的框组成。勾选框内会显示一个小勾号。虽然复选框外观不像按钮,但行为与按钮类似。

可以使用“复选框属性”窗口为复选框分配标签和标识符。由于复选框本质上是按钮,所以可以使用 ON_COMMAND() ON_BN_CLICKED() 宏来响应用户勾选操作。不过,通常不需要对复选框生成的消息进行响应,而是在用户关闭对话框或接受选择时,了解哪些复选框被选中。

为实现这一点,需要为对话框类中的每个复选框控件关联一个成员变量,然后使用 DDX_Check() 函数将复选框的数据传输到相应的成员变量。示例代码如下:

class HobbyDialog : public CDialog
{
private:
    BOOL m_ckSports; // Sports check box
    BOOL m_ckMusic;  // Music check box
    BOOL m_ckComputers; // Computers check box
protected:
    virtual void DoDataExchange(CDataExchange*);
    // remainder of class declaration
};

void HobbyDialog::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX); // invoke parent's
    DDX_Check(pDX, IDC_SPORTS, m_ckSports);
    DDX_Check(pDX, IDC_MUSIC, m_ckMusic);
    DDX_Check(pDX, IDC_COMPUTERS, m_ckComputers);
}

void HobbyDialog::OnOK()
{
    // the parent's OnOK() invokes UpdateData()
    CDialog::OnOK();
    CString message("You like ");
    if (m_ckSports)
        message += "sports ";
    if (m_ckMusic)
        message += "music ";
    if (m_ckComputers)
        message += "computers";
    MessageBox(message, "Hobbies");
}
3.3 单选按钮

单选按钮是一种特殊的复选框,同一组单选按钮中每次只能选择一个。可以将一组单选按钮视为一个整体,只需知道哪个按钮被选中即可。

为创建单选按钮组,需要为组中的第一个按钮选择“Group”样式,后续的单选按钮将属于同一组。

在对话框类中,只需为一组单选按钮添加一个整型成员变量,用于表示被选中按钮的索引(第一个按钮索引为 0,依次递增)。使用 DDX_Radio() 函数在对话框和成员变量之间传输数据。示例代码如下:

class ColorDialog : public CDialog
{
private:
    int m_SelectedColor; // index of radio button group
protected:
    virtual void DoDataExchange(CDataExchange*);
    // remainder of class definition
};

void ColorDialog::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    DDX_Radio(pDX, IDC_RED, m_SelectedColor);
}

void CRadioButtonsDlg::OnOK()
{
    CDialog::OnOK();
    CString message("Your favorite color is ");
    switch (m_SelectedColor)
    {
    case 0:
        message += "red";
        break;
    case 1:
        message += "green";
        break;
    case 2:
        message += "blue";
        break;
    default:
        message = "You did not select a color";
    }
    MessageBox(message, "Favorite color");
}
4. 静态控件

静态控件用于提供视觉显示,不涉及用户交互。常见的静态控件有文本控件和分组框控件。文本控件用于显示文本,分组框控件用于在一组单选按钮周围显示视觉边框。

所有静态控件共享相同的标识符 IDC_STATIC ,因为它们不生成消息,所以无需为其分配唯一 ID。

5. 编辑控件

编辑控件为用户提供输入文本的机制,窗口为用户提供单行文本输入区域。若输入文本超出控件宽度,可使用左右箭头在文本行内滚动。

编辑控件通常使用静态文本控件来描述所需输入的类型。使用 DDX_Text() 函数在编辑控件和对话框类的成员变量之间传输数据。 DDX_Text() 函数进行了重载,可用于传输字节、短整型、整型、长整型、浮点型、双精度型、 DWORD UINT 等数值类型的数据。

无论输入的数据类型如何,都可以使用 DDV 函数验证数据。例如, DDV_MaxChars() 函数可用于限制字符串的字符数,还有针对不同数值类型的 DDV 函数用于指定值的范围。

示例代码如下,展示了一个登录对话框的实现:

class LogonDialog : public CDialog
{
private:
    CString m_Username;
    CString m_Password;
protected:
    virtual void DoDataExchange(CDataExchange*);
    // remainder of class declaration
};

void LogonDialog::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    DDX_Text(pDX, IDC_PASSWORD, m_Password);
    DDX_Text(pDX, IDC_USERNAME, m_Username);
    DDV_MaxChars(pDX, m_Username, 10);
}

void LogonDialog::OnOK()
{
    CDialog::OnOK();
    if (m_Username == "raposa" && m_Password == "password")
        MessageBox("Successfully logged in!", "Success");
    else
        MessageBox("Invalid user info!", "Error", MB_OK | MB_ICONERROR);
}
6. 列表框控件

列表框控件在可滚动窗口中显示字符串列表,有单选和多选两种类型。

6.1 列表框初始化

不能使用资源编辑器确定列表框中最初显示的字符串,需要创建 CListBox 对象,并调用其 AddString() InsertString() 成员函数。通常在 OnInitDialog() 函数中完成此操作,该函数在对话框即将显示时由框架调用。示例代码如下:

BOOL TeamDialog::OnInitDialog()
{
    CDialog::OnInitDialog();
    // get a pointer to the list box
    CListBox *teams = (CListBox *)GetDlgItem(IDC_TEAMS);
    // add the teams
    teams->AddString("Broncos");
    teams->AddString("Packers");
    teams->AddString("Steelers");
    teams->AddString("Cardinals");
    teams->AddString("Dolphins");
    teams->AddString("Vikings");
    return TRUE;
}
6.2 单选列表框

若列表框使用单选样式, DDX_LBString() 函数会将选中的字符串传输到相应的成员变量中。若未选择任何项,成员变量将为空字符串。示例代码如下:

class TeamDialog : public CDialog
{
private:
    CString m_Team;
protected:
    virtual void DoDataExchange(CDataExchange*);
    // remainder of class declaration
};

void TeamDialog::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    DDX_LBString(pDX, IDC_TEAMS, m_Team);
}

void CListBoxDlg::OnDblclkTeams()
{
    UpdateData(TRUE);
    MessageBox(m_Team, "You selected ...");
}
6.3 多选列表框

多选列表框生成的消息与单选列表框相同, DDX_LBString() 函数可用于将当前选中的项传输到 CString 成员变量中。但了解多选列表框中当前选中项通常用处不大,因为在多选列表框中,当前选中项可能刚刚被取消选择,所以通常不使用数据交换来处理这些列表框。

控件使用流程总结

graph LR
    A[创建对话框] --> B[使用资源编辑器排列控件并分配 ID]
    B --> C{选择控件类型}
    C --> |按钮| D[处理按钮消息]
    C --> |复选框| E[关联成员变量并使用 DDX_Check 传输数据]
    C --> |单选按钮| F[创建组并关联成员变量使用 DDX_Radio 传输数据]
    C --> |静态控件| G[无需特殊处理]
    C --> |编辑控件| H[使用 DDX_Text 传输数据并使用 DDV 验证]
    C --> |列表框| I[初始化列表框并处理选择项]

常见控件类型及处理方式总结

控件类型 特点 处理方式
标准按钮 按下生成 WM_COMMAND 消息 使用 ON_COMMAND() ON_BN_CLICKED() 宏关联消息处理程序
复选框 可勾选或取消勾选 关联成员变量,使用 DDX_Check() 传输数据
单选按钮 同一组中只能选一个 关联成员变量,使用 DDX_Radio() 传输数据
静态控件 提供视觉显示,无用户交互 无需特殊处理,共享标识符 IDC_STATIC
编辑控件 提供文本输入 使用 DDX_Text() 传输数据,用 DDV 函数验证数据
列表框 显示字符串列表,有单选和多选类型 初始化列表框,单选用 DDX_LBString() 传输数据
7. 组合框控件

组合框结合了编辑框和列表框的功能,用户既可以从列表中选择一个选项,也可以直接在编辑框中输入内容。组合框有三种样式:下拉式组合框、下拉式列表框和简单组合框。

7.1 组合框的初始化

与列表框类似,组合框也不能直接使用资源编辑器来确定初始显示的字符串。需要创建 CComboBox 对象,并调用其 AddString() InsertString() 成员函数来添加选项。通常在 OnInitDialog() 函数中完成初始化操作。示例代码如下:

BOOL ComboDialog::OnInitDialog()
{
    CDialog::OnInitDialog();
    // 获取组合框指针
    CComboBox *combo = (CComboBox *)GetDlgItem(IDC_COMBO);
    // 添加选项
    combo->AddString("Option 1");
    combo->AddString("Option 2");
    combo->AddString("Option 3");
    return TRUE;
}
7.2 处理组合框的选择事件

当用户从组合框中选择一个选项时,会生成 CBN_SELCHANGE 消息。可以使用 ON_CBN_SELCHANGE() 宏来处理这个消息。示例代码如下:

BEGIN_MESSAGE_MAP(ComboDialog, CDialog)
    ON_CBN_SELCHANGE(IDC_COMBO, OnSelChangeCombo)
END_MESSAGE_MAP()

void ComboDialog::OnSelChangeCombo()
{
    CComboBox *combo = (CComboBox *)GetDlgItem(IDC_COMBO);
    int selIndex = combo->GetCurSel();
    CString selectedText;
    combo->GetLBText(selIndex, selectedText);
    MessageBox(selectedText, "You selected");
}
8. 进度条控件

进度条控件用于显示任务的进度,它可以是水平的或垂直的。进度条有一个最小值、最大值和当前值。

8.1 初始化进度条

在对话框的 OnInitDialog() 函数中,可以设置进度条的最小值、最大值和初始值。示例代码如下:

BOOL ProgressDialog::OnInitDialog()
{
    CDialog::OnInitDialog();
    // 获取进度条指针
    CProgressCtrl *progress = (CProgressCtrl *)GetDlgItem(IDC_PROGRESS);
    // 设置最小值和最大值
    progress->SetRange(0, 100);
    // 设置初始值
    progress->SetPos(0);
    return TRUE;
}
8.2 更新进度条

在任务执行过程中,可以通过调用 SetPos() 函数来更新进度条的当前值。示例代码如下:

void ProgressDialog::UpdateProgress(int value)
{
    CProgressCtrl *progress = (CProgressCtrl *)GetDlgItem(IDC_PROGRESS);
    progress->SetPos(value);
}
9. 滑块控件

滑块控件允许用户通过拖动滑块来选择一个数值。滑块有一个最小值、最大值和当前值。

9.1 初始化滑块

在对话框的 OnInitDialog() 函数中,可以设置滑块的最小值、最大值和初始值。示例代码如下:

BOOL SliderDialog::OnInitDialog()
{
    CDialog::OnInitDialog();
    // 获取滑块指针
    CSliderCtrl *slider = (CSliderCtrl *)GetDlgItem(IDC_SLIDER);
    // 设置最小值和最大值
    slider->SetRange(0, 100);
    // 设置初始值
    slider->SetPos(50);
    return TRUE;
}
9.2 处理滑块的滑动事件

当用户拖动滑块时,会生成 NM_CUSTOMDRAW WM_HSCROLL (水平滑块)、 WM_VSCROLL (垂直滑块)消息。可以使用相应的消息映射宏来处理这些消息。示例代码如下:

BEGIN_MESSAGE_MAP(SliderDialog, CDialog)
    ON_NOTIFY(NM_CUSTOMDRAW, IDC_SLIDER, OnCustomDrawSlider)
END_MESSAGE_MAP()

void SliderDialog::OnCustomDrawSlider(NMHDR *pNMHDR, LRESULT *pResult)
{
    CSliderCtrl *slider = (CSliderCtrl *)GetDlgItem(IDC_SLIDER);
    int value = slider->GetPos();
    CString message;
    message.Format("Current value: %d", value);
    MessageBox(message, "Slider Value");
    *pResult = 0;
}

控件使用注意事项

  • 资源管理 :在创建控件对象时,要确保在合适的时机进行资源的分配和释放,避免内存泄漏。
  • 消息处理 :不同的控件会生成不同的消息,要正确使用消息映射宏来处理这些消息,确保程序的响应性和稳定性。
  • 数据验证 :使用 DDV 函数对用户输入的数据进行验证,避免非法数据导致程序出现错误。

不同控件的使用场景建议

控件类型 使用场景
按钮控件 用于触发操作,如提交表单、关闭窗口等
复选框 用于选择多个选项的场景
单选按钮 用于从多个选项中选择一个的场景
编辑控件 用于用户输入文本或数值的场景
列表框 用于显示一组选项,用户可以选择一个或多个的场景
组合框 既需要用户输入,又提供选项供用户选择的场景
进度条控件 显示任务进度的场景
滑块控件 允许用户选择一个连续数值范围的场景

完整控件使用流程图

graph LR
    A[创建对话框] --> B[使用资源编辑器排列控件并分配 ID]
    B --> C{选择控件类型}
    C --> |按钮| D[处理按钮消息]
    C --> |复选框| E[关联成员变量并使用 DDX_Check 传输数据]
    C --> |单选按钮| F[创建组并关联成员变量使用 DDX_Radio 传输数据]
    C --> |静态控件| G[无需特殊处理]
    C --> |编辑控件| H[使用 DDX_Text 传输数据并使用 DDV 验证]
    C --> |列表框| I[初始化列表框并处理选择项]
    C --> |组合框| J[初始化组合框并处理选择事件]
    C --> |进度条| K[初始化进度条并更新进度]
    C --> |滑块| L[初始化滑块并处理滑动事件]

通过以上对各种常见控件的介绍和示例代码,你可以在 Visual C++ 中灵活运用这些控件来创建功能丰富、交互性强的对话框和应用程序。在实际开发中,根据具体的需求选择合适的控件,并正确处理控件的消息和数据,将有助于提高程序的质量和用户体验。

内容概要:本文档是一份关于交换路由配置的学习笔记,系统地介绍了网络设备的远程管理、交换机与路由器的核心配置技术。内容涵盖Telnet、SSH、Console三种远程控制方式的配置方法;详细讲解了VLAN划分原理及Access、Trunk、Hybrid端口的工作机制,以及端口镜像、端口汇聚、端口隔离等交换技术;深入解析了STP、MSTP、RSTP生成树协议的作用与配置步骤;在路由部分,涵盖了IP地址配置、DHCP服务部署(接口池与全局池)、NAT转换(静态与动态)、静态路由、RIP与OSPF动态路由协议的配置,并介绍了策略路由和ACL访问控制列表的应用;最后简要说明了华为防火墙的安全区域划分与基本安全策略配置。; 适合人群:具备一定网络基础知识,从事网络工程、运维或相关技术岗位1-3年的技术人员,以及准备参加HCIA/CCNA等认证考试的学习者。; 使用场景及目标:①掌握企业网络中常见的交换与路由配置技能,提升实际操作能力;②理解VLAN、STP、OSPF、NAT、ACL等核心技术原理并能独立完成中小型网络搭建与调试;③通过命令示例熟悉华为设备CLI配置逻辑,为项目实施和故障排查提供参考。; 阅读建议:此笔记以实用配置为主,建议结合模拟器(如eNSP或Packet Tracer)动手实践每一条命令,对照拓扑理解数据流向,重点关注VLAN间通信、路由选择机制、安全策略控制等关键环节,并注意不同设备型号间的命令差异。
多旋翼无人机组合导航系统-多源信息融合算法(Matlab代码实现)内容概要:本文围绕多旋翼无人机组合导航系统,重点介绍了基于多源信息融合算法的设计与实现,利用Matlab进行代码开发。文中采用扩展卡尔曼滤波(EKF)作为核心融合算法,整合GPS、IMU(惯性测量单元)、里程计和电子罗盘等多种传感器数据,提升无人机在复杂环境下的定位精度与稳定性。特别是在GPS信号弱或丢失的情况下,通过IMU惯导数据辅助导航,实现连续可靠的位姿估计。同时,文档展示了完整的算法流程与Matlab仿真实现,涵盖传感器数据预处理、坐标系转换、滤波融合及结果可视化等关键环节,体现了较强的工程实践价值。; 适合人群:具备一定Matlab编程基础和信号处理知识,从事无人机导航、智能控制、自动化或相关领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于多旋翼无人机的高精度组合导航系统设计;②用于教学与科研中理解多传感器融合原理与EKF算法实现;③支持复杂环境下无人机自主飞行与定位系统的开发与优化。; 阅读建议:建议结合Matlab代码与理论推导同步学习,重点关注EKF的状态预测与更新过程、多传感器数据的时间同步与坐标变换处理,并可通过修改噪声参数或引入更多传感器类型进行扩展实验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值