3_2、MFC常用控件用法:组合框、滚动条和图片控件

MFC控件用法

1、组合框

1.1 简介

组合框其实就是把一个编辑框和一个列表框组合到了一起,分为三种:简易(Simple)组合框、下拉式(Dropdown)组合框和下拉列表式(Drop List)组合框。

  1. 简易组合框中的列表框是一直显示的;
  2. 下拉式组合框默认不显示列表框,只有在点击了编辑框右侧的下拉箭头才会弹出列表框;
  3. 下拉列表式组合框的编辑框是不能编辑的,只能由用户在下拉列表框中选择了某项后,在编辑框中显示其文本。.

    常用的当属下拉式组合框和下拉列表式组合框了,它们在很多时候能使程序看起来更专业,更简洁,让用户在进行选择操作时更方便。
    组合框被操作时会向父窗口发送通知消息,这些通知消息及其含义如下:
通知消息 含义
CBN_CLOSEUP 组合框的列表框组件被关闭,简易组合框不会发送该通知消息
CBN_DBLCLK 用户在某列表项上双击鼠标,只有简易组合框才会发送该通知消息
CBN_DROPDOWN 组合框的列表框组件下拉,简易式组合框不会发送该通知消息
CBN_EDITUPDATE 在编辑框准备显示改变了的正文时发送该消息,下拉列表式组合框不会发送该消息
CBN_EDITCHANGE 编辑框的内容被用户改变了,与CBN_EDITUPDATE不同,该消息是在编辑框显示的正文被刷新后才发出的,下拉列表式组合框不会发送该消息
CBN_ERRSPACE 组合框无法申请足够的内存来容纳列表项
CBN_SELENDCANCEL 表明用户的选择应该取消,当用户在列表框中选择了一项,然后又在组合框控件外单击鼠标时就会导致该消息的发送
CBN_SELENDOK 用户选择了一项,然后按了回车键或单击了下滚箭头,该消息表明用户确认了自己所作的选择
CBN_KILLFOCUS 组合框失去了输入焦点
CBN_SELCHANGE 用户通过单击或移动箭头键改变了列表的选择
CBN_SETFOCUS 组合框获得了输入焦点

1.2 创建

MFC将组合框控件的所有操作都封装到了CComboBox类中。

创建有两种方式:

  1. 往对话框模板中拖入Combo Box控件,而后添加CComboBox类型的控件变量使用。
  2. 在程序中动态创建,使用CComboBox类的成员函数Create。Create函数的原型如下:
cpp 复制代码
virtual BOOL Create(
   DWORD dwStyle,
   const RECT& rect,
   CWnd* pParentWnd,
   UINT nID 
);
  • CComboBox类的Create成员函数同大多数控件类的Create成员函数非常类似,dwStyle指定组合框控件的风格,rect为列表框弹出后组合框的位置和尺寸,pParentWnd是指向父窗口的指针,不能为NULL,nID指定组合框控件的ID。
  • 组合框控件的风格包括以下几种:
控件风格 含义
CBS_AUTOHSCROLL 使编辑框组件具有水平滚动的风格
CBS_DISABLENOSCROLL 使列表框在不需要滚动时显示一个禁止的垂直滚动条
CBS_DROPDOWN 指定一个下拉式组合框
CBS_DROPDOWNLIST 指定一个下拉列表式组合框
CBS_HASSTRINGS 指定一个含有字符串的自绘式组合框
CBS_LOWERCASE 将编辑框和列表框中的所有文本都自动转换为小写字符
CBS_NOINTEGRALHEIGHT 组合框的尺寸由应用程序而不是Windows 指定,通常,由Windows指定尺寸会使列表项的某些部分隐藏起来
CBS_OEMCONVERT 使编辑框组件中的正文可以在ANSI 字符集和OEM字符集之间相互转换。这在编辑框中包含文件名时是很有用的
CBS_OWNERDRAWFIXED 指定自绘式组合框,即由父窗口负责绘制列表框的内容,并且列表项有相同的高度
CBS_OWNERDRAWVARIABLE 指定自绘式组合框,并且列表项有不同的高度
CBS_SIIMPLE 指定一个简易组合框
CBS_SORT 自动对列表框组件中的项进行排序
CBS_UPPERCASE 将编辑框和列表框中的所有文本都自动转换为大写字符

dwStyle参数可以是以上风格的组合。跟其他控件一样,创建时一般也还要指定WS_CHILD、WS_VISIBLE、WS_TABSTOP和WS_VSCROLL等风格。

CComboBox类的主要成员函数

因为组合框是由编辑框和列表框组合而成的,所以组合框的操作和编辑框与列表框的操作有很多相似之处,同样的,CComboBox类的成员函数也和CEdit类与CListBox类的成员函数有很多相似之处,不但功能相似,甚至函数名和参数也很相似。

  1. int GetCount( ) const;
    获取组合框控件的列表框中列表项的数量。
  2. int GetCurSel( ) const;
    获取组合框控件的列表框中选中项的索引,如果没有选中任何项,该函数返回CB_ERR。
  3. int SetCurSel(int nSelect);
    在组合框控件的列表框中选择某项。nSelect参数指定了要选择的列表项的索引,如果为-1则列表框中当前选择项被取消选中,编辑框也被清空。
  4. DWORD GetEditSel( ) const;
    获取组合框控件的编辑框中当前选择范围的起始和终止字符的位置。该函数返回一个32位数,低16位存放起始位置,高16位存放选择范围后第一个非选择字符的位置。如果该函数用于下拉列表式组合框时,会返回CB_ERR。
  5. BOOL SetEditSel(int nStartChar,int nEndChar);
    用于在组合框控件的编辑框中选择字符。nStartChar参数指定起始位置,nEndChar参数指定终止位置。
  6. DWORD_PTR GetItemData(int nIndex) const;
    获取组合框中指定项所关联的32位数据。nIndex参数指定组合框控件的列表框某项的索引(从0开始)。
  7. int SetItemData(int nIndex,DWORD_PTR dwItemData);
    为某个指定的组合框列表项设置一个关联的32位数。nIndex参数指定要进行设置的列表项索引。dwItemData参数指定要关联的新值。
  8. void GetLBText(int nIndex,CString& rString) const;
    从组合框控件的列表框中获取某项的字符串。nIndex参数指定要获取字符串的列表项的索引,CString参数用于接收取到的字符串。
  9. int GetLBTextLen(int nIndex) const;
    获取组合框控件的列表框中某项的字符串长度。nIndex参数指定要获取字符串长度的列表项的索引。
  10. int GetTopIndex( ) const;
    获取组合框控件的列表框中第一个可见项的索引。
  11. int SetTopIndex(int nIndex);
    将组合框控件的列表框中某个指定项设置为可见的。nIndex参数指定了该列表项的索引。该函数成功则返回0,有错误发生则返回CB_ERR。
  12. BOOL LimitText(int nMaxChars);
    用于限制用户在组合框控件的编辑框中能够输入的最大字节长度。nMaxChars参数指定了用户能够输入文字的最大字节长度,如果为0则长度被限制为65535个字节。
  13. int AddString(LPCTSTR lpszString);
    为组合框控件中的列表框添加新的列表项。lpszString参数是指向要添加的字符串的指针。该函数的返回值如果大于等于0,那么它就是新列表项的索引,而如果有错误发生则会返回CB_ERR,如果没有足够的内存存放新字符串则返回CB_ERRSPACE。
  14. int DeleteString(UINT nIndex);
    删除组合框中某指定位置的列表项。nIndex参数指定了要删除的列表项的索引。该函数的返回值如果大于等于0,那么它就是组合框中剩余列表项的数量。如果nIndex指定的索引超出了列表项的数量则返回CB_ERR。
  15. int FindString(int nStartAfter,LPCTSTR lpszString) const;
    在组合框控件的列表框中查找但不选中第一个包含指定前缀的列表项。nStartAfter参数指定了第一个要查找的列表项之前的那个列表项的索引。lpszString指向包含要查找的前缀的字符串。该函数的返回值如果大于等于0,那么它是匹配列表项的索引,如果查找失败则返回CB_ERR。
  16. int InsertString(int nIndex,LPCTSTR lpszString);
    向组合框控件的列表框中插入一个列表项。nIndex参数指定了要插入列表项的位置,lpszString参数则指定了要插入的字符串。该函数返回字符串被插入的位置,如果有错误发生则会返回CB_ERR,如果没有足够的内存存放新字符串则返回CB_ERRSPACE。
  17. int SelectString(int nStartAfter,LPCTSTR lpszString);
    在组合框控件的列表框中查找一个字符串,如果查找到则选中它,并将其显示到编辑框中。参数同FindString。如果字符串被查找到则返回此列表项的索引,如果查找失败则返回CB_ERR,并且当前选择项不改变。

1.3 实例

步骤:

  1. 创建控件,创建控件变量;
  2. 在OnInitDialog函数中进行控件的初始化;
cpp 复制代码
	m_comFood.AddString(_T("蔬菜"));
	m_comFood.AddString(_T("水果"));
	m_comFood.InsertString(1,_T("肉类"));
	m_comFood.SetCurSel(0);
  1. 在对话框类的成员函数中对控件相关的消息相应进行处理。生成组合框控件的相关消息相应函数。针对CBN_SELCHANGE通知消息生成消息相应函数,在函数体中操作:
cpp 复制代码
	CString strFood;
	int nSel;
	nSel = m_comFood.GetCurSel();
	m_comFood.GetLBText(nSel, strFood);

	SetDlgItemText(IDC_EDT_COM, strFood);

2、滚动条控件

2.1 简介

滚动条分为水平滚动条(Horizontal Scroll Bar)和垂直滚动条(Vertical Scroll Bar)两种。滚动条中有一个滚动块,用于标识滚动条当前滚动的位置。我们可以拖动滚动块,也可以用鼠标点击滚动条某一位置使滚动块移动。

从滚动条的创建形式来分,有标准滚动条和滚动条控件两种。像列表框和组合框设置了WS_HSCROLL 或WS_VSCROLL风格以后出现的滚动条,不是一个独立的窗口,而是这些窗口的一部分,这就是标准滚动条。而滚动条控件是一个独立的窗口,它可以获得焦点,响应某些操作。

2.2 创建

MFC也为滚动条控件的操作提供了类,即为CScrollBar类。

创建有两种方式:

  1. 一种是直接在Toolbox中将滚动条控件拖入对话框模板,然后添加控件变量使用。
  2. 用CScrollBar类的Create成员函数动态创建。 CScrollBar类的成员函数Create的函数原型如下:
cpp 复制代码
virtual BOOL Create(
   DWORD dwStyle,
   const RECT& rect,
   CWnd* pParentWnd,
   UINT nID 
);
  • 此函数与其他控件类的Create函数原型基本相同。参数dwStyle指定滚动条控件的风格,rect指定滚动条控件的位置和尺寸,pParentWnd为指向滚动条控件父窗口的指针,nID指定滚动条控件的ID。
控件风格 含义
SBS_HORZ 指定滚动条为水平滚动条。如果没有指定SBS_BOTTOMALIGN或SBS_TOPALIGN风格,则滚动条的高度、宽度和位置由Create函数的rect参数给出。
SBS_VERT 指定滚动条为垂直滚动条。如果没有指定SBS_RIGHTALIGN或SBS_LEFTALIGN风格,则滚动条的高度、宽度和位置由Create函数的rect参数给出。
SBS_TOPALIGN 与SBS_HORZ配合使用。滚动条的上边缘与Create函数的rect参数指定矩形的上边缘对齐。滚动条高度为系统滚动条的默认高度。
SBS_BOTTOMALIGN 与SBS_HORZ配合使用。滚动条的下边缘与Create函数的rect参数指定矩形的下边缘对齐。滚动条高度为系统滚动条的默认高度。
SBS_LEFTALIGN 与SBS_VERT配合使用。滚动条的左边缘与Create函数的rect参数指定矩形的左边缘对齐。滚动条宽度为系统滚动条的默认宽度。
SBS_RIGHTALIGN 与SBS_VERT配合使用。滚动条的右边缘与Create函数的rect参数指定矩形的右边缘对齐。滚动条宽度为系统滚动条的默认宽度。

CScrollBar类的主要成员函数

  1. BOOL GetScrollInfo(LPSCROLLINFO lpScrollInfo, UINT nMask = SIF_ALL);
    获取的滚动条的参数信息,该信息为SCROLLINFO结构体的形式。参数lpScrollInfo为指向SCROLLINFO结构体变量的指针。
    参数nMask 的含义与SCROLLINFO 结构体中的fMask一样。该函数在获取信息成功则返回TRUE,否则返回FALSE。SCROLLINFO结构体的定义如下:
cpp 复制代码
typedef struct tagSCROLLINFO {    
    UINT cbSize;         // 结构的尺寸(字节为单位)   
    UINT fMask;          // 说明结构中的哪些参数是有效的,可以是屏蔽值的组合,如SIF_POS|SIF_PAGE,若为SIF_ALL则整个结构都有效   
    int  nMin;           // 滚动范围最小值,当fMask 中包含SIF_RANGE 时有效   
    int  nMax;           // 滚动范围最大值,当fMask 中包含SIF_RANGE 时有效   
    UINT nPage;          // 页尺寸,用来确定比例滚动框的大小,当fMask中包含SIF_PAGE时有效   
    int  nPos;           // 滚动框的位置,当fMask 中包含SIF_POS 有效   
    int  nTrackPos;      // 滚动时滚动框的位置,当fMask 中包含SIF_TRACKPOS 时有效,该参数只能查询,不能设置,最好不要用该参数来查询拖动时滚动框的位置   
}   SCROLLINFO, *LPSCROLLINFO;    
typedef SCROLLINFO CONST *LPCSCROLLINFO;
  1. BOOL SetScrollInfo(LPSCROLLINFO lpScrollInfo, BOOL bRedraw = TRUE);
    用于设置滚动条的各种参数信息。参数lpScrollInfo为指向SCROLLINFO结构体变量的指针,参数bRedraw表示是否需要重绘滚动条,如果为TRUE,则重绘。该函数操作成功则返回TRUE,否则返回FALSE。
  2. int GetScrollPos( ) const;
    获取滚动块的当前位置。如果失败则返回0。
  3. int SetScrollPos(int nPos, BOOL bRedraw = TRUE);
    将滚动块移动到指定位置。参数nPos指定了滚动块的新位置,参数bRedraw 表示是否需要重绘滚动条,如果为TRUE,则重绘。函数返回滚动框原来的位置,若操作失败则返回0。
  4. void GetScrollRange(LPINT lpMinPos, LPINT lpMaxPos) const;
    获取滚动条的滚动范围。参数lpMinPos指向滚动条滚动范围的最小值,参数lpMaxPos指向滚动条滚动范围的最大值。
  5. void SetScrollRange(int nMinPos, int nMaxPos, BOOL bRedraw = TRUE);
    用于指定滚动条的滚动范围。参数nMinPos 和nMaxPos 分别指定了滚动范围的最小值和最大值,两者的差不得超过32767。当两者都为0 时,滚动条将被隐藏。参数bRedraw 表示是否需要重绘滚动条,如果为TRUE,则重绘。
  6. OnHScroll()与OnVScroll()函数
    无论是标准滚动条,还是滚动条控件,滚动条的通知消息都是用WM_HSCROLL 和WM_VSCROLL消息发送出去的。对这两个消息的默认处理函数是CWnd::OnHScroll和CWnd::OnVScroll,一般需要在派生类中对这两个函数进行重载,以实现滚动功能。也就是说,假设在一个对话框中放入了一个水平滚动条,我们可以在对话框类中重载OnHScroll函数,并在OnHScroll函数中实现滚动功能。
cpp 复制代码
 afx_msg void OnHScroll(UINT nSBCode,UINT nPos,CScrollBar* pScrollBar);
afx_msg void OnVScroll(UINT nSBCode,UINT nPos,CScrollBar* pScrollBar);
  • 参数nSBCode是通知消息码,主要通知码及含义的介绍下面已列出。nPos 是滚动框的位置,只有在nSBCode为SB_THUMBPOSITION或SB_THUMBTRACK时,该参数才有意义。如果通知消息是滚动条控件发来的,那么pScrollBar 是指向该控件的指针,如果是标准滚动条发来的,则pScrollBar 为NULL。
通知消息码 含义
SB_BOTTOM/SB_RIGHT 滚动到底端(右端)
SB_TOP/SB_LEFT 滚动到顶端(左端)
SB_LINEDOWN/SB_LINERIGHT 向下(向右)滚动一行(列)
SB_LINEUP/SB_LINELEFT 向上(向左)滚动一行(列)
SB_PAGEDOWN/SB_PAGERIGHT 向下(向右)滚动一页
SB_PAGEUP/SB_PAGELEFT 向上(向左)滚动一页
SB_THUMBPOSITION 滚动到指定位置
SB_THUMBTRACK 滚动框被拖动。可利用该消息来跟踪对滚动框的拖动
SB_ENDSCROLL 滚动结束

2.3 实例

步骤:

  1. 创建控件,创建控件变量;
  2. 在OnInitDialog函数中进行控件的初始化;
cpp 复制代码
	m_scrHBar.SetScrollRange(1,100);
	m_scrHBar.SetScrollPos(20);
	SetDlgItemInt(IDC_EDT_SCR, 20);
  1. 重载OnHScroll函数。具体操作为,属性页面的工具栏上点"Messages"按钮,找到WM_HSCROLL消息,添加响应函数就可以。
cpp 复制代码
	int pos = m_scrHBar.GetScrollPos();    // 获取水平滚动条当前位置   
    switch (nSBCode)
    {
        // 如果向左滚动一列,则pos减1   
    case SB_LINELEFT:
        pos -= 1;
        break;
        // 如果向右滚动一列,则pos加1   
    case SB_LINERIGHT:
        pos += 1;
        break;
        // 如果向左滚动一页,则pos减10   
    case SB_PAGELEFT:
        pos -= 10;
        break;
        // 如果向右滚动一页,则pos加10   
    case SB_PAGERIGHT:
        pos += 10;
        break;
        // 如果滚动到最左端,则pos为1   
    case SB_LEFT:
        pos = 1;
        break;
        // 如果滚动到最右端,则pos为100   
    case SB_RIGHT:
        pos = 100;
        break;
        // 如果拖动滚动块滚动到指定位置,则pos赋值为nPos的值   
    case SB_THUMBPOSITION:
        pos = nPos;
        break;
        // 下面的m_horiScrollbar.SetScrollPos(pos);执行时会第二次进入此函数,最终确定滚动块位置,并且会直接到default分支,所以在此处设置编辑框中显示数值   
    default:
        SetDlgItemInt(IDC_EDT_SCR, pos);

3、图片控件

3.1 简介

图片控件和前面讲到的静态文本框都是静态文本控件,因此两者的使用方法有很多相同之处,所属类都是CStatic类。

3.2 创建

图片控件静态和动态加载位图图片。

图片控件静态加载图片

  1. 常见图片控件;
  2. 导入图片资源,放置在资源文件夹中;
  3. 在图片控件属性中选择类型为:bitmap,然后导入相关的位图文件即可。图片控件的类型有:

Frame:显示一个无填充的矩形框,边框颜色可以通过Color属性的下拉列表设定

Etched Horz:显示一条横分割线

Etched Vert:显示一条竖分割线

Rectangle:显示一个填充的矩形框,矩形颜色可通过Color属性的下拉列表设定

Icon:显示一个图标(Icon),图标通过Image 下拉列表来设置图标资源ID

Bitmap:显示一个位图(Bitmap),位图通过Image 下拉列表来设置位图资源ID

Enhanced Metafile:显示一个加强的元数据文件(Metafile)

Owner Draw:自绘

图片控件动态加载图片

  1. 将图片控件的ID进行修改为:IDC_STA_PIC,并添加图片控件变量;
  2. 加载位图资源并设置ID号;
  3. 函数操作添加图片位图资源:
cpp 复制代码
	CBitmap bitmap;  // CBitmap对象,用于加载位图   
    HBITMAP hBmp;    // 保存CBitmap加载的位图的句柄   

    bitmap.LoadBitmap(IDB_BMP_TEST);  // 将位图IDB_BITMAP1加载到bitmap   
    hBmp = (HBITMAP)bitmap.GetSafeHandle();  // 获取bitmap加载位图的句柄   
    m_staPic.SetBitmap(hBmp);         // 设置图片控件m_jzmPicture的位图图片为IDB_BITMAP1 
相关推荐
菜鸟赵大宝12 分钟前
Visual Studio编译优化选项
c++·visual studio
北岛寒沫15 分钟前
算法刷题笔记 单调栈(C++实现)
c++·笔记·算法
一条闲鱼。17 分钟前
C++ 文件读写
c++·读写文件
imred19 分钟前
C++:std::function的libc++实现
c++·stl·template·function·libc++
jzwalliser24 分钟前
洛谷 P1035 [NOIP2002 普及组] 级数求和
c++·python·算法
汀小烟1 小时前
使用静态成员函数统计学生平均成绩
c语言·开发语言·数据结构·c++·vscode
LeoLei80602 小时前
新特性之C++17
开发语言·c++
jllws12 小时前
C++基础:STL概述
开发语言·c++
FightingLod2 小时前
C++中list容器使用详解
开发语言·c++·list
yyqzjw2 小时前
【C++】单例模式
c++·单例模式