VC/MFC 工具栏上动态添加组合框等控件的方法

简介: 引言  工具条作为大多数标准的Windows应用程序的一个重要组成部分,使其成为促进人机界面友好的一个重要工具。通过工具条极大方便了用户对程序的操作,但是在由Microsoft Visual C++开发环境所创建的应用程序框架中的工具条只是一个简单的按钮的集合,在功能上也仅仅是起到了菜单快捷方式的作用,而没有做到象VC、Word等软件的工具条那样,提供多种不同类型的标准控件如组合框、编辑框等。

引言

  工具条作为大多数标准的Windows应用程序的一个重要组成部分,使其成为促进人机界面友好的一个重要工具。通过工具条极大方便了用户对程序的操作,但是在由Microsoft Visual C++开发环境所创建的应用程序框架中的工具条只是一个简单的按钮的集合,在功能上也仅仅是起到了菜单快捷方式的作用,而没有做到象VC、Word等软件的工具条那样,提供多种不同类型的标准控件如组合框、编辑框等。尤其是组合框在添加到工具条上后,可将原本需要在弹出对话框中完成的交互操作在工具条上就可以进行,从而在很大程度上改善了应用程序的界面友好程度。本文就此给出一种在普通应用程序的工具条上动态创建组合框、编辑框等标准控件的一般方法,并使应用程序能够响应由这些控件所触发的事件。

  组合框的添加

  组合框是添加到工具条中最常见的一种标准控件,弥补了列表框控件占用较大空间和编辑控件的数据输入烦琐等弊端,可以在工具条的有限区域内提供全部备选数据,用户一般情况下只需通过鼠标操作即可实现对数据的选取。因此,多数情况下都是需要向工具条添加组合框控件来改善程序的界面友好程度的。

  由于是在工具条上动态创建组合框控件,而工具条又非标准客户区,因此动态创建过程就存在一定的困难。这里的处理方式是先在VC的资源视图中为工具条添加一个空按钮IDC_COMBOX,然后通过CToolBar类的SetButtonInfo()函数来对此空白按钮进行设置,其目的是为后面将要创建的组合框在工具条上占据一块空间,然后再通过CToolBar类的GetItemRect()函数得到经过修改后的按钮区域坐标,该坐标值在后面创建动态组合框时将指定在工具条的什么地方创建一个多大的组合框。经过这些准备工作后,接下来组合框在工具条上的动态创建过程则完全同在客户区中的处理,即以CComboBox类的Create()函数动态完成。

  根据前面的设计思路不难写出实现代码。显然,这部分代码应当与工具条的创建代码一起添加到主框架类的创建函数OnCreate()中,下面结合注释给出部分关键代码:

……
// 工具条m_wndToolBar的创建代码
……
//设置组合框的宽度,四个参数依次为控件在工具条中的索引号、ID号、风格、宽度 
m_wndToolBar.SetButtonInfo(8, IDC_COMBOX, TBBS_SEPARATOR, 160 ); 
//得到组合框的位置 
m_wndToolBar.GetItemRect(8, &rect); 
//设置组合框的下拉高度 
rect.bottom += 100;
//创建组合框,四个参数依次为窗口风格、组合框位置、父窗口、ID号 
m_combobox.Create(CBS_DROPDOWN|WS_VISIBLE|WS_TABSTOP|CBS_AUTOHSCROLL,rect, &m_wndToolBar, IDC_COMBOX);
//在组合框中加入字符串 
m_combobox.AddString("第一条记录"); 
m_combobox.AddString("第二条记录"); 
//选中第1条记录
m_combobox.SetCurSel(0);

 对组合框事件的响应

  经过上述编码,已经在工具条上空白按纽处动态创建出了一个组合框,但是仅仅创建出组合框还是不够的,为了能通过此组合框实现同用户的交互还必须编写相关代码,使其嫩够响应由组合框发出的事件消息。通常情况下对此类控件事件的响应处理是通过ClassWizard类向导来完成的,但由于此处是通过CComboBox类的Create()函数动态创建的,因此只能手动添加事件响应代码。对于组合框,其比较常用的两个事件消息是在选中一条记录时发出的CBN_SELCHANGE事件和在对组合框内文字进行编辑时产生的CBN_EDITCHANGE事件,下面就以这两个事件为例对其进行讲解,至于其他消息的处理过程可参照其进行。

  首先在头文件中给出消息响应函数的声明:

//{{AFX_MSG(CAddToToolBarView)
afx_msg void OnSelchangeCombo();//响应CBN_SELCHANGE消息的函数 
afx_msg void OnEditchangeCombo();//响应CBN_EDITCHANGE消息的函数 
//}}AFX_MSG
然后在实现文件中完成消息映射:
BEGIN_MESSAGE_MAP(CAddToToolBarView, CView)
//{{AFX_MSG_MAP(CAddToToolBarView)
ON_CBN_SELCHANGE(IDC_COMBOX, OnSelchangeCombo) 
ON_CBN_EDITCHANGE(IDC_COMBOX, OnEditchangeCombo) 
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
最后在消息处理函数中完成对事件的处理过程:
void CAddToToolBarView::OnSelchangeCombo() 
{
CString cs;
CMainFrame* frame=(CMainFrame*)AfxGetMainWnd(); 
frame->m_combobox.GetLBText(frame->m_combobox.GetCurSel(), cs); 
AfxMessageBox(cs);

void CAddToToolBarView::OnEditchangeCombo() 
{
CMainFrame* frame=(CMainFrame*)AfxGetMainWnd(); 
CString cs; 
frame->m_combobox.GetWindowText(cs); 
}

  从上述处理过程可以看出,对于在工具条上动态创建控件所发出事件的响应处理过程同手工处理消息响应的过程是非常相似的。

  对于其他控件的处理

  前面关于组合框控件在工具条上动态创建的介绍是比较有代表性的,其他标准控件的处理过程与之相比并没有什么太大的变化,只是由于控件类别的不同而在空间的创建和对控件本身的处理过程上有所不同,其思路则是完全一致的。下面再给出编辑框在工具条的创建过程。通过对这两段代码的比较可以对控件在工具条的动态创建过程有一个更好的认识:

……
// 工具条m_wndToolBar的创建代码
……
//设置组合框的宽度,四个参数依次为控件在工具条中的索引号、ID号、风格、宽度 
m_wndToolBar.SetButtonInfo(9, IDC_EDIT, TBBS_SEPARATOR, 160 ); 
//得到组合框的位置 
m_wndToolBar.GetItemRect(9, &rect); 
//创建组合框,四个参数依次为窗口风格、组合框位置、父窗口、ID号 
m_edit.Create (WS_VISIBLE|WS_TABSTOP,rect, &m_wndToolBar, IDC_EDIT);

  小结

  本文主要通过利用VC的资源视图来先可视化编辑标准控件在工具条中的位置,然后再把标准控件作为工具条的一个子窗口进行动态创建。基于这种思想,可以很方便地在工具条中进行其他类似处理。本文所述代码在Windows 2000 Professional下,由Microsoft Visual C++ 6.0编译通过。
目录
相关文章
|
编译器 程序员 C++
2023-4-6-C++11、C++14、C++17、C++20版本新特性系统全面的学习!(二)
2023-4-6-C++11、C++14、C++17、C++20版本新特性系统全面的学习!
622 0
2023-4-6-C++11、C++14、C++17、C++20版本新特性系统全面的学习!(二)
|
弹性计算
阿里云开Minecraft服务器配置选择及价格表
阿里云服务器搭建Minecraft我的世界CPU内存配置怎么选择?公网带宽和系统盘选择多少合适?一般20人以内玩家、1.12版本的大型整合包、100个以内个轻量mod,2核4G配置就够用了,公网带宽选择3M或5M都可以,系统盘就高效云盘40GB够用了
1474 0
阿里云开Minecraft服务器配置选择及价格表
|
3月前
|
机器学习/深度学习 人工智能 算法
通义OmniAudio大模型,让 AI 看懂 360° 视频,并“听”出对应的空间音频
OmniAudio 是一项突破性的空间音频生成技术,能够直接从 360° 视频生成 FOA(First-order Ambisonics)空间音频,为虚拟现实和沉浸式娱乐带来全新可能。通过自监督 coarse-to-fine 预训练和双分支视频表示微调,OmniAudio 在非空间音频质量和空间定位准确性上显著优于现有方法。项目包含超过 103,000 个视频片段的 Sphere360 数据集,支持高质量的模型训练与评估。代码、数据及论文均已开源,助力沉浸式体验技术发展。
453 62
|
关系型数据库 PostgreSQL 索引
PostgreSQL 11 新特性解读:分区表支持创建主键、外键、索引
PostgreSQL 10 版本虽然支持创建范围分区表和列表分区表,但创建过程依然比较繁琐,需要手工定义子表索引、主键,详见 PostgreSQL10:重量级新特性-支持分区表,PostgreSQL 11 版本得到增强,在父表上创建索引、主键、外键后,子表上将自动创建,本文演示这三种场景。
7557 0
|
2月前
|
机器学习/深度学习 算法
WebSailor:探索 WebAgent的超人类推理能力
通义实验室推出WebSailor方案,通过创新的post-training方法显著提升开源模型在复杂网页推理任务中的表现。该方案包括合成高不确定性数据、多轮工具调用轨迹重构及强化学习算法DUPO应用,在多个评测中展现优越性能。
225 0
|
5月前
|
人工智能 算法 程序员
揭秘 AI 编程工具的费用真相:2025 年开发者视角-优雅草卓伊凡
揭秘 AI 编程工具的费用真相:2025 年开发者视角-优雅草卓伊凡
186 1
揭秘 AI 编程工具的费用真相:2025 年开发者视角-优雅草卓伊凡
|
9月前
|
消息中间件 架构师 数据库
本地消息表事务:10Wqps 高并发分布式事务的 终极方案,大厂架构师的 必备方案
45岁资深架构师尼恩分享了一篇关于分布式事务的文章,详细解析了如何在10Wqps高并发场景下实现分布式事务。文章从传统单体架构到微服务架构下分布式事务的需求背景出发,介绍了Seata这一开源分布式事务解决方案及其AT和TCC两种模式。随后,文章深入探讨了经典ebay本地消息表方案,以及如何使用RocketMQ消息队列替代数据库表来提高性能和可靠性。尼恩还分享了如何结合延迟消息进行事务数据的定时对账,确保最终一致性。最后,尼恩强调了高端面试中需要准备“高大上”的答案,并提供了多个技术领域的深度学习资料,帮助读者提升技术水平,顺利通过面试。
本地消息表事务:10Wqps 高并发分布式事务的 终极方案,大厂架构师的 必备方案
|
NoSQL Java MongoDB
SpringBoot中MongoDB的那些高级用法
本文探讨了在Spring Boot项目中使用MongoDB的多种方式及其高级用法。MongoDB作为一种NoSQL数据库,在某些场景下相较于SQL数据库有着独特的优势。文中详细介绍了在Spring Boot中使用MongoDB的三种主要方式:直接使用官方SDK、使用Spring JPA以及使用MongoTemplate,并对比分析了它们之间的差异。此外,文章深入讲解了Spring Data MongoDB提供的各种注解(如@Id, @Document, @Field等)以简化操作流程,并探讨了MongoTemplate监听器的应用,如设置主键值、记录日志等。
769 2
|
9月前
|
JSON JavaScript 前端开发
什么是HTTP POST请求?初学者指南与示范
HTTP POST请求是一种常用的HTTP方法,主要用于向服务器发送数据。通过合理设置请求头和请求主体,可以实现数据的可靠传输。无论是在客户端使用JavaScript,还是在服务器端使用Node.js,理解和掌握POST请求的工作原理和应用场景,对于Web开发至关重要。
1460 18
|
IDE Java 开发工具
如何进行《我的世界》基于Spigot的插件开发
《我的世界》(Minecraft)是一款沙盒游戏,允许玩家在一个由方块组成的三维世界中进行探索、建造和冒险。通过使用Spigot服务器,你可以为《我的世界》开发自定义插件,扩展游戏功能,增加新的玩法和互动元素。本文将介绍如何进行《我的世界》基于Spigot的插件开发,帮助你从零开始创建自己的插件。
648 0