科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件VC中Windows常用控件的创建和使用

VC中Windows常用控件的创建和使用

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

本文将要介绍的Windows控件指的是Windows系统预定义的标准控件,如按钮控件、编辑控件和列表控件等。

作者:青岛郎锐 来源:天极网 2007年10月19日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
列表框与组合框

  列表框是窗口类名为"ListBox"的预定义子窗口,在窗口矩形内包含有一些可以滚动显示的栏状字符串列表。标准的列表框只能允许选中一个条目,选中的条目将以系统颜色COLOR_HIGHLIGHT高亮显示。Windows还提供了多种不同风格的标准列表框,其中包括多选列表框、多列显示的列表框和可以显示图象的拥有者画(Owner-draw)列表框等。另一种与列表框相关的控件是组合框,该控件预定义类名为"COMBOBOX",实际是一个编辑控件同一个彼此相关的列表框控件的组合。用户既可以在组合框的编辑栏上直接输入、编辑文字也可以从下拉列表中显示的可能选择中进行选取。

  MFC的CListBox 类封装了列表框控件,由成员函数Create()完成对列表框的创建,在创建的同时指定了控件的窗口风格。当列表框中的条目被选中或被鼠标双击后将向父窗口发送WM_COMMAND消息。如果列表框采用了LBS_NOTIFY风格,父窗口就可以通过ON_LBN消息映射宏直接将通知消息同消息处理函数建立起映射关系。列表框提供了十余种窗口风格,现将列表框风格及说明列表如下:

列表框风格 说明
LBS_STANDARD 创建一个具有边界和垂直滚动条、当选择发生变化或条目被双击时能够通知父窗口的标准列表框。所有条目按字母排序。
LBS_SORT 按字母排序。
LBS_NOSEL 条目可视但不可选。
LBS_NOTIFY 当用户选择或双击一个串时,发出消息通知父窗口。
LBS_DISABLENOSCROLL 在条目不多时依然显示并不起作用的滚动条。
LBS_MULTIPLESEL 允许条目多选。
LBS_EXTENDEDSEL 可用SHIFT和鼠标或指定键组合来选择多个条目。
LBS_MULTICOLUMN 允许多列显示。
LBS_OWNERDRAWVARIABLE 创建一个拥有者画列表框,条目高度可以不同。
LBS_OWNERDRAWFIXED 创建一个具有相同条目高度的拥有者画列表框。
LBS_USETABSTOPS 允许使用TAB制表符。
LBS_NOREDRAW 当条目被增删后不自动更新列表显示。
LBS_HASSTRINGS 记忆了添加到列表中的字串。
LBS_WANTKEYBOARDINPUT 当有键按下时向父窗口发送WM_VKEYTOITEM或WM_CHARTOITEM消息。
LBS_NOINTEGRALHEIGHT 按程序设定尺寸创建列表框。

  缺省的,列表框在每添加或删除一个条目后都会自动重绘,如果在列表框中已经有了几百条甚至上千条条目,将会因为重绘而引起比较严重的闪烁。可以通过使用LBS_NOREDRAW风格来禁止列表框的自动重绘。在需要更新显示时强制重绘列表框窗口即可。如果在创建时未使用LBS_NOREDRAW风格,可以在增删条目前向列表框发送WM_SETREDRAW消息,指定其不重绘,增添完毕后再次发送WM_SETREDRAW消息重新启用自动重绘风格。示例过程如下:

CListBox m_ctrListBox;
// 禁止自动重绘
m_ctrListBox.SendMessage(WM_SETREDRAW, FALSE, 0);
// 进行条目增删操作
……
// 允许自动重绘
m_ctrListBox.SendMessage(WM_SETREDRAW, TRUE, 0);

  列表框创建之初是不含任何条目的,通过CListBox成员函数AddString()和InsertString()向列表框增添或插入条目。如果列表框具有LBS_SORT风格,那么新添加字串的位置是不固定的,要根据字串的字母进行排序;如果不具有该风格,新字串将添加到列表框的末尾。

  如果有必要,可以使用SetItemDataPtr()或SetItemData()将一个32位的指针(或一个DWORD的值)同列表框中的一个条目联系起来,并且在设置后可以通过调用GetItemDataPtr()或GetItemData()而获取。这样做的目的是可以将列表框中的条目同外部数据建立联系。例如:可以用这种方式非常方便地将一个包含有地址、电话号码和E-mail地址等信息的数据结构同列举在列表框中的持有人建立起关联。当从列表框中选中某个人时,可以同时得到有关该人的通讯信息。

  当操作列表框时,将会通过WM_COMMAND消息发送通知给父窗口,消息参数lParam的高字节包含了通知码标识符。在MFC应用程序中,列表框的通知消息通过ON_LBN消息映射宏而映射到类成员函数。下表给出了列表框的几个通知消息以及相应的ON_LBN宏。其中,LBN_DBLCLK,LBN_SELCHANGE和LBN_SELCANCEL通知消息只有在列表框使用了LBS_NOTIFY或LBS_STANDARD风格时才会被发出,其他通知消息则无此限制。

通知码标识符 ON_LBN宏 含义
LBN_SETFOCUS ON_LBN_SETFOCUS 4 列表框接收到输入焦点
LBN_KILLFOCUS ON_LBN_KILLFOCUS 5 列表框接失去输入焦点
LBN_ERRSPACE ON_LBN_ERRSPACE -2 列表框存储溢出
LBN_DBLCLK ON_LBN_DBLCLK 2 双击条目
LBN_SELCHANGE ON_LBN_SELCHANGE 1 改变选择
LBN_SELCANCEL ON_LBN_SELCANCEL 3 取消选择

  其中,最经常使用的两个通知消息是LBN_DBLCLK和LBN_SELCHANGE。对于不可复选的列表框可以通过GetCurSel()来获取当前双击的是列表框条目的索引值;对于允许多选的列表框则需要用GetCaretIndex()来代替GetCurSel()。下面通过一段示例代码对列表控件的使用做一个直观的演示:

// 创建并初始化列表框
// 创建列表框
m_ctrListBox.Create(WS_VISIBLE | WS_CHILD | WS_BORDER | LBS_STANDARD,CRect(270, 50, 370, 150), this, IDC_LIST1);
// 添加条目
CString Item[9] = {"Item1", "Item2", "Item3", "Item4", "Item5", "Item6", "Item7", "Item8", "Item9"};
for (int i = 0; i < 9; i++)
m_ctrListBox.AddString(Item[i]);
// 选中第4个条目
m_ctrListBox.SetCurSel(3);
……
// 父窗口对通知消息的处理函数的声明(在头文件中)
//{{AFX_MSG(CSample02View)
afx_msg void OnLbnDblClk();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
……
// 父窗口对通知消息的映射入口 (在实现文件中)
BEGIN_MESSAGE_MAP(CSample02View, CView)
//{{AFX_MSG_MAP(CSample02View)
ON_LBN_DBLCLK(IDC_LIST1, OnLbnDblClk)
//}}AFX_MSG_MAP
// Standard printing commands
END_MESSAGE_MAP()
……
// 父窗口对LBN_DBLCLK通知消息的处理
void CSample02View::OnLbnDblClk()
{
// 得到当前选中条目的索引
int Index = m_ctrListBox.GetCurSel();
// 得到此条目的内容
char Text[20];
m_ctrListBox.GetText(Index, Text);
// 以信息框报告得到的内容
AfxMessageBox(CString(Text));
}

  虽然组合框实际是列表框和编辑框的组合,但在使用中的表现使得组合框同其他控件一样当作一个独立的控件去使用。MFC的CComboBox类提供了对组合框的功能支持。在使用Create()函数创建组合框时可以同时指定组合框的风格(参见下表)。

窗口风格 说明
CBS_AUTOHSCROLL 当在行尾输入字符时自动将编辑框中的文字向右滚动。
CBS_DROPDOWN 同CBS_SIMPLE风格类似,只是只有在用户点击下拉图标时才会显示出下拉列表。
CBS_DROPDOWNLIST 同CBS_DROPDOWN类似,只是显示当前选项的编辑框为一静态框所代替。
CBS_HASSTRINGS 创建一个包含了由字串组成的项目的拥有者画组合框。
CBS_OEMCONVERT 将组合框中的ANSI字串转化为OEM字符。
CBS_OWNERDRAWFIXED 由下拉列表框的拥有者负责对内容的绘制;列表框中各项目高度相同。
CBS_OWNERDRAWVARIABLE 由下拉列表框的拥有者负责对内容的绘制;列表框中各项目高度可以不同。
CBS_SIMPLE 下拉列表始终显示。
CBS_SORT 自动对下拉列表中的项目进行排序。
CBS_DISABLENOSCROLL 当下拉列表显示内容过少时显示垂直滚动条。
CBS_NOINTEGRALHEIGHT 在创建控件时以指定的大小来精确设定组合框尺寸。

  对组合框进行操作也会向父窗口发送通知消息,处理过程同前面几种控件大同小异,是通过ON_CBN消息映射宏完成对通知消息的映射的。下面就给出这些ON_CBN宏的详细说明:

ON_CBN宏 对应事件
ON_CBN_CLOSEUP 关闭下拉列表。
ON_CBN_DBLCLK 双击下拉列表中的项目。
ON_CBN_DROPDOWN 下拉显示列表框。
ON_CBN_EDITCHANGE 编辑框中文本内容被改动。
ON_CBN_EDITUPDATE 编辑框内容更新显示。
ON_CBN_ERRSPACE 组合框不能为某个特殊请求分配足够的内存。
ON_CBN_SELENDCANCEL 用户的选择被取消。
ON_CBN_SELENDOK 用户选择了一个项目并且通过回车键或按下鼠标而隐藏组合框的下拉列表。
ON_CBN_KILLFOCUS 组合框失去焦点。
ON_CBN_SELCHANGE 选择发生变化。
ON_CBN_SETFOCUS 组合框获得输入焦点。

  最后给出一段有关组合框的示例代码,从代码实现不难看出组合框控件同前面给出的列表控件在编程实现上的相似性。

// 组合框的创建
// 创建列表控件
m_ctrComboBox.Create(WS_VISIBLE | WS_CHILD | WS_BORDER | CBS_DROPDOWN, CRect(400, 50, 470, 150), this, IDC_COMBOX1);
// 添加条目
CString Item[9] = {"Item1", "Item2", "Item3", "Item4", "Item5", "Item6", "Item7", "Item8", "Item9"};
for (int i = 0; i < 9; i++)
m_ctrComboBox.AddString(Item[i]);
// 选中第4个条目
m_ctrComboBox.SetCurSel(3);
……
// 通知消息响应函数的声明(在头文件中)
//{{AFX_MSG(CSample02View)
afx_msg void OnCbnSelChange();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
……
// 对通知消息的响应处理(在实现文件中)
BEGIN_MESSAGE_MAP(CSample02View, CView)
//{{AFX_MSG_MAP(CSample02View)
ON_CBN_SELCHANGE(IDC_COMBOX1, OnCbnSelChange)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
……
void CSample02View::OnCbnSelChange()
{
 // 得到当前选中条目的索引
 int Index = m_ctrComboBox.GetCurSel();
 // 得到此条目的内容
 char Text[20];
 m_ctrComboBox.GetLBText(Index, Text);
 // 以信息框报告得到的内容
 AfxMessageBox(CString(Text));
}
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章