Win32 ListBox控件

创建ListBox控件

  1. 创建窗口函数

    HWND CrateWindowEx(DWORD dwExStyle , // 窗口的扩展风格,基本没用LPCTSTR lpClassName, // 已经注册的窗口类名称LPCTSTR lpWindowName, // 窗口标题栏的名字DWORD dwStyle, // 窗口的基本风格int x, // 左上角水平坐标int y, // 左上角垂直坐标int nWidth,int nHeight,HWND hWndParent, // 窗口的父窗口句柄 --> 如果是子窗口要写这个参数HMENU hMenu,     // 窗口菜单句柄HINSTANCE hInstance, // 应用程序实例句柄 --> WinMain 第一个参数LPVOID lpParam // 窗口创建时附加参数 --> 一般给NULL
    ); // 创建成功返回窗口句柄
    
  2. 创建ListBox

    #define ID_LIST        1001   // 窗口句柄HWND hListBox = CreateWindowEx(0, TEXT("ListBox"), NULL, WS_VISIBLE | WS_CHILD | WS_BORDER | LBS_HASSTRINGS,10, 10, 200, 200, hWnd, (HMENU)ID_LIST, ((LPCREATESTRUCT)lParam)->hInstance, 0);const TCHAR *strArray[] = { TEXT("星期一"), TEXT("星期二"), TEXT("星期三"), TEXT("星期四"), TEXT("星期五"), TEXT("星期六"), TEXT("星期日")};
    for (int i = 0; i < 7; i++){// 添加内容SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM)strArray[i]);
    }
    
  3. 效果

控件样式

样式 说明
LBS_COMBOBOX 通知列表框它是组合框的一部分。 这允许两个控件之间的协调,以便它们呈现统一的 UI。 组合框本身必须设置此样式。
LBS_DISABLENOSCROLL 当列表框不包含足够的项目滚动时,显示禁用的水平或垂直滚动条。 如果未指定此样式,则当列表框不包含足够的项目时,滚动条将隐藏。 此样式必须与 WS_VSCROLL 或 WS_HSCROLL 样式一起使用。
LBS_EXTENDEDSEL 允许使用 SHIFT 键和鼠标或特殊键组合选择多个项。
LBS_HASSTRINGS 指定列表框包含由字符串组成的项。 列表框维护字符串的内存和地址,以便应用程序可以使用 LB_GETTEXT 消息检索特定项的文本。 默认情况下,除所有者绘制的列表框之外的所有列表框都具有此样式。 可以创建具有或不带此样式的所有者绘制列表框。对于没有此样式的所有者绘制列表框, LB_GETTEXT 消息检索与项关联的值, (项数据) 。
LBS_MULTICOLUMN 指定水平滚动的多列列表框。 列表框自动计算列的宽度,或者应用程序可以使用 LB_SETCOLUMNWIDTH 消息设置宽度。 如果列表框具有 LBS_OWNERDRAWFIXED 样式,则当列表框发送 WM_MEASUREITEM 消息时,应用程序可以设置宽度。具有 LBS_MULTICOLUMN 样式的列表框不能垂直滚动,它忽略它接收的任何 WM_VSCROLL 消息。不能组合 LBS_MULTICOLUMN 和 LBS_OWNERDRAWVARIABLE 样式。 如果同时指定了两者, 则忽略LBS_OWNERDRAWVARIABLE 。
LBS_MULTIPLESEL 每次用户单击或双击列表框中的字符串时,都会打开或关闭字符串选择。 用户可以选择任意数量的字符串。
LBS_NODATA 指定无数据列表框。 当列表框中的项数超出一千时,请指定此样式。 无数据列表框还必须具有 LBS_OWNERDRAWFIXED 样式,但不得具有 LBS_SORT 或 LBS_HASSTRINGS 样式。无数据列表框类似于所有者描述的列表框,但它不包含项的字符串或位图数据。 用于添加、插入或删除项的命令始终忽略任何指定的项数据;在列表框中查找字符串的请求始终失败。 系统在必须绘制项时将 WM_DRAWITEM 消息发送到所有者窗口。 使用WM_DRAWITEM消息传递的 DRAWITEMSTRUCT 结构的 itemID 成员指定要绘制的项的行号。 无数据列表框不发送 WM_DELETEITEM 消息。
LBS_NOINTEGRALHEIGHT 指定列表框的大小正好是应用程序在创建列表框时指定的大小。 通常,系统调整列表框的大小,以便列表框不显示部分项。对于 具有LBS_OWNERDRAWVARIABLE 样式的列表框,始终强制实施 LBS_NOINTEGRALHEIGHT 样式。
LBS_OWNERDRAWFIXED 指定列表框的所有者负责绘制其内容,并且列表框中的项目高度相同。 创建列表框时,所有者窗口会收到 WM_MEASUREITEM 消息,当列表框的可视方面发生更改时收到 WM_DRAWITEM 消息。
LBS_SORT 按字母顺序对列表框中的字符串进行排序。
LBS_STANDARD 按字母顺序对列表框中的字符串进行排序。 每当用户单击列表框项、双击项目或取消所选内容时,父窗口都会收到通知代码。 列表框具有垂直滚动条,其边框位于右侧。 此样式结合了 LBS_NOTIFY、 LBS_SORT、 WS_VSCROLL和 WS_BORDER 样式。
LBS_USETABSTOPS 允许列表框在绘制其字符串时识别和展开制表符。 可以使用 LB_SETTABSTOPS 消息指定制表位位置。 默认选项卡位置相隔 32 个对话框模板单位。 对话框模板单元是对话框模板中使用的与设备无关的单位。 若要将度量值从对话框模板单位转换为屏幕单位 (像素) ,请使用 MapDialogRect 函数。
LBS_WANTKEYBOARDINPUT 指定每当用户按下键且列表框具有输入焦点时,列表框的所有者将接收 WM_VKEYTOITEM 消息。 这使应用程序能够在键盘输入上执行特殊处理。

控件消息

消息码 说明 WPARAM LPARAM 返回值
LB_ADDSTRING 添加字符串到列表项中 0 LPCTSTR Int
LB_DELETESTRING 删除指定字符串项 nIndex 0 Int
LB_GETCOUNT 获得列表项的部数 0 0 Int
LB_GETCURSEL 获得当前选中项的索引 0 0 Int
LB_GETITEMDATA 获得指定项的附加数据 nIndex 0 DWORD_PTR
LB_GETSEL 获得指定项的选中状态 nIndex 0 Int
LB_GETSELCOUNT 获得多选项的总数 0 0 Int
LB_GETSELITEMS 获得选中项的索引数组 nMaxArray(数组大小) lpArray(数组) Int
LB_GETTEXT 获得指定项的字符串 nIndex LPTSTR Int
LB_GETTEXTLEN 获得指定项字符串长度 nIndex 0 Int
LB_GETTOPINDEX 获得第一个可见项的索引 0 0 Int
LB_INSERTSTRING 插入字符串项 nIndex LPCTSTR Int
LB_RESETCONTENT 删除所有的项 0 0 Void
LB_SELITEMRANGE 范围选择项或取消范围选择 BOOL(选择=TRUE,取消=FALSE) DWORD (L=开始选择项的索引,H=结束项的索引) Int
LB_SETCARETINDEX 设置指定项获得焦点,并可见 nIndex BOOL(FALSE为完全可见,TRUE为部分可见) Int
LB_SETCURSEL 设置当前选中的字符串项 nIndex 0 Int
LB_SETITEMDATA 设置指定项的附加数据 nIndex DWORD_PTR Int
LB_SETSEL 设置指定项的选中状态,并获得焦点和可见 BOOL 为真突出显示,为FALSE取消突出显示 nIndex Int
LB_SETTOPINDEX 设置指定项为可见项 nIndex 0 Int

Demo

1. 单击选项弹出消息框显示选择的项
if (LOWORD (wParam) == ID_LIST && HIWORD(wParam) == LBN_SELCHANGE) {int iIndex = SendMessage(hListBox, LB_GETCURSEL, 0, 0);int iLength = SendMessage(hListBox, LB_GETTEXTLEN, iIndex, 0) + 1;TCHAR * pVarName = (TCHAR*)malloc(iLength*sizeof(TCHAR));SendMessage(hListBox, LB_GETTEXT, iIndex, (LPARAM)pVarName);MessageBox(hWnd, pVarName, TEXT("选择的内容"), MB_OK);free(pVarName);
}
2. ListBox重绘

ListBox重绘,实现QQ 消息列表效果

通过指定LBS_OWNERDRAWFIXED样式,可以进行ListBox的重绘。

两个重要消息:WM_DRAWITEMWM_MEASUREITEM

2.1 WM_DRAWITEM 消息

第二个附加参数lParam里包含了控件的相关信息, 其实际类型是DRAWITEMSTRUCT的指针类型

DRAWITEMSTRUCT 原型:

typedef struct tagDRAWITEMSTRUCT {UINT      CtlType;UINT      CtlID;UINT      itemID;UINT      itemAction;UINT      itemState;HWND      hwndItem;HDC       hDC;RECT      rcItem;ULONG_PTR itemData;
} DRAWITEMSTRUCT, *PDRAWITEMSTRUCT, *LPDRAWITEMSTRUCT;
  • CtlType 指定了控件的类型

  • CtlID

    组合框、列表框、按钮或静态控件的标识符。 此成员不用于菜单项。

  • itemID

    菜单项的菜单项标识符或列表框或组合框中项的索引。 对于空列表框或组合框,此成员可以是 -1

    这允许应用程序仅在 rcItem 成员指定的坐标处绘制焦点矩形,即使控件中没有项也是如此。 这向用户指示列表框或组合框是否具有焦点。

    itemAction 成员中设置位的方式决定了矩形是否与列表框或组合框具有焦点一样绘制

  • itemAction

    所需的绘图操作。 此成员可以是一个或多个值。

  • itemState

    当前绘图操作发生后项的视觉状态。 此成员可以是下表中显示的值的组合。

  • hwndItem

    组合框、列表框、按钮和静态控件的控件的句柄。 对于菜单,此成员是包含该项的菜单的句柄。

  • hDC

    设备上下文的句柄;在控件上执行绘图操作时,必须使用此设备上下文。

  • rcItem

    一个矩形,用于定义要绘制的控件的边界。 此矩形位于 hDC 成员指定的设备上下文中。 系统会自动剪辑所有者窗口在组合框、列表框和按钮的设备上下文中绘制的任何内容,但不会剪辑菜单项。 绘制菜单项时,所有者窗口不得在 rcItem 成员定义的矩形边界之外绘制。

  • itemData

    与菜单项关联的应用程序定义值。 对于控件,此参数指定LB_SETITEMDATA或CB_SETITEMDATA消息最后分配给列表框或组合框的值。 如果列表框或组合框具有 LBS_HASSTRINGS或 CBS_HASSTRINGS样式,则此值最初为零。 否则,此值最初是传递给下列消息之一的 lParam 参数中的列表框或组合框的值:

    • CB_ADDSTRING
    • CB_INSERTSTRING
    • LB_ADDSTRING
    • LB_INSERTSTRING

    如果 CtlTypeODT_BUTTONODT_STATIC, 则itemData 为零。

2.2 WM_MEASUREITEM消息

第二个附加参数lParam描述了相关项的绘制信息,其实际类型是MEASUREITEMSTRUCT的指针类型

typedef struct tagMEASUREITEMSTRUCT {UINT      CtlType;UINT      CtlID;UINT      itemID;UINT      itemWidth;UINT      itemHeight;ULONG_PTR itemData;
} MEASUREITEMSTRUCT, *PMEASUREITEMSTRUCT, *LPMEASUREITEMSTRUCT;

大部分字段同DRAWITEMSTRUCT, 两个重要字段itemWidth, itemHeight 指定列表项的宽度和高度

2.3 重要代码
void SetListBoxItemRect(LPARAM lParam) {PMEASUREITEMSTRUCT pmr = (PMEASUREITEMSTRUCT)lParam;if (pmr->CtlID == ID_LIST) {pmr->itemHeight = 58;}
}void DrawListBoxItem(LPARAM lParam) {TCHAR* pVarName;PDRAWITEMSTRUCT pdr = (PDRAWITEMSTRUCT)(lParam);COLORREF nColor = RGB(66, 66, 66);HBRUSH hBursh = NULL;   if(pdr->itemState & ODS_SELECTED ) // 选中状态hBursh = CreateSolidBrush(RGB(255, 128, 0));elsehBursh = CreateSolidBrush(RGB(255, 255, 255));FillRect(pdr->hDC, &pdr->rcItem, hBursh);DeleteObject(hBursh);int itemLength = SendMessage(hListBox, LB_GETTEXTLEN, pdr->itemID, 0) + 1;pVarName = (TCHAR*)malloc(itemLength * sizeof(TCHAR));SendMessage(hListBox, LB_GETTEXT, pdr->itemID, (LPARAM)pVarName);if (pVarName == NULL) return;HBITMAP hBmp = LoadBitmap(hInst, (char*)info_arr[atoi(pVarName)].bitmapId);HDC Bhdc = CreateCompatibleDC(pdr->hDC);HGDIOBJ oldBMP = SelectObject(Bhdc, hBmp);StretchBlt(pdr->hDC, pdr->rcItem.left + 1, pdr->rcItem.top + 1, 56, 56, Bhdc, 0, 0, 100, 100, SRCCOPY);HFONT font1 = CreateFont(20,0,0,0,900,NULL,NULL,NULL,GB2312_CHARSET,NULL,NULL,NULL,NULL,"仿宋");HFONT font2 = CreateFont(20,0,0,0,800,NULL,NULL,NULL,GB2312_CHARSET,NULL,NULL,NULL,NULL,"方正舒体");SetBkMode(pdr->hDC, TRANSPARENT);HGDIOBJ oldfont = SelectObject(pdr->hDC, font1);nColor = RGB(0, 0, 0);SetTextColor(pdr->hDC, nColor);TextOut(pdr->hDC, pdr->rcItem.left + 65, pdr->rcItem.top + 5, info_arr[atoi(pVarName)].userName, strlen(info_arr[atoi(pVarName)].userName));SelectObject(pdr->hDC, font2);nColor = RGB(133, 193, 246);SetTextColor(pdr->hDC, nColor);TextOut(pdr->hDC, pdr->rcItem.left + 65, pdr->rcItem.top + 30, info_arr[atoi(pVarName)].newData, strlen(info_arr[atoi(pVarName)].newData));SelectObject(pdr->hDC, oldfont);SelectObject(Bhdc, oldBMP);DeleteObject(hBmp);DeleteObject(font1);DeleteObject(font2);DeleteDC(Bhdc);free(pVarName);
}
2.4 实现效果

参考

  1. 基本使用:https://blog.csdn.net/qq_31178679/article/details/125904122

  2. ListBox风格、消息说明:https://www.cnblogs.com/H-R-J/p/11882224.html

  3. ListBox重绘: https://www.freesion.com/article/3893191680/

  4. ListBox简单使用:https://www.codenong.com/cs109127861/

  5. 微软文档:https://learn.microsoft.com/zh-cn/windows/win32/msi/listbox-control

  6. DRAWITEMSTRUCT 结构: https://learn.microsoft.com/zh-cn/windows/win32/api/winuser/ns-winuser-drawitemstruct

项目地址

  • https://github.com/wa-kakalala/QQMsgList

Win32 ListBox控件相关推荐

  1. 『原创』用C++开发WM应用系列(6)——深化ListBox控件

    用C++开发WM应用系列文章索引 引言: 在上一篇博文中,我们简单的学习了ListBox控件的项添加.项的全部清除.接上一篇的尾巴,我们将在这篇博文中,介绍一些ListBox的小技巧吧,比如,获取选中 ...

  2. 为.net中的ListBox控件添加双击事件

    我在用dotnet做一个项目的过程中,遇到了一个ListBox的问题:通过在一个ListBox中双击,把选中的项添加到另一个ListBox中,但ListBox控件本身并没有该事件,那么如何实现呢?我就 ...

  3. C# 在DataGridView中,点击单元格调出 TreeView控件 或 ListBox控件

    1.调出 TreeView控件 或  ListBox控件 private void deductGrid1_CellClick(object sender, DataGridViewCellEvent ...

  4. [开发笔记]-winfom ListBox控件选中项上下移动排序

    实现ListBox控件选中项上下移动重新排序功能 效果图: 移动后效果: 代码: /// <summary>/// 上移选中项/// </summary>/// <par ...

  5. 扩展DropDownList控件和ListBox控件(1) - 支持分组功能(optgroup标签)

    介绍 扩展DropDownList控件和ListBox控件: 通过DropDownList控件和ListBox控件的.Items.Add(ListItem item)方法,来为其添加optgroup标 ...

  6. MATLAB GUI程序设计中ListBox控件在运行期间消失的原因及解决方法

    在运行期间,ListBox控件突然消失,同时给出如下错误提示: Warning: single-selection listbox control requires that Value be an ...

  7. matlab listbox选中输出,vba中ListBox控件的使用

    给ListBox添加内容 If CheckBox8 = True Then---------------------------checkbox控件被选中 For i = 0 To ListBox1. ...

  8. Python Tkinter 之Listbox控件(Python GUI 系列12)

    Python Tkinter 之Listbox控件(Python GUI 系列12) 1. 序言 本章介绍Tkinter的Listbox控件,本文是Python GUI系列的第12篇文章,整个系统约2 ...

  9. 说说wps jsa的ListBox控件的数组写入方法

    目前wps jsa的控件API只能说吐槽!再吐槽!目前很多WPS JS宏教程都不太愿意谈WPS的控件,也是因为WPS控件的功能太差,简直差到极点了. 目前小编很想用WPS的ListBox控件来做一些应 ...

最新文章

  1. 企业防火墙之iptables
  2. 苹果airpods android,苹果AirPodsPro搭配Android手机实测:支持功能不够完整,购买前要认真考虑...
  3. ffmpeg支持G711音频和H.264视频数据封装为mp4
  4. 每天学一点儿shell:Linux三剑客——sed命令
  5. Some Tips About Layout Resource
  6. Loadrunner的基本概念
  7. oracle查询表字段横向排序,sql 查询 - 横着走的螃蟹 - OSCHINA - 中文开源技术交流社区...
  8. amd黑苹果万能显卡驱动_22款显卡乱战《赛博朋克2077》:AMD 4K败走麦城-显卡,赛博朋克2077,AMD,NVIDIA ——快科技(驱动之家旗下媒体)-...
  9. html给table加外边框,如何给table添加边框
  10. python数据驱动登录_python之数据驱动ddt操作(方法三)
  11. 互联网高可用架构技术实践
  12. Mac 下 Nginx、PHP、MySQL 和 PHP-fpm 的安装和配置
  13. 使用php实现自动获取一个获取文章标题生成主题关键词功能源码
  14. java怎么给文本框加滚动条_懂Java中Swing的朋友,谁能帮我在Jtextare上加一个滚动条啊?很急!...
  15. 谷歌又发新操作系统了!
  16. 程序员副业接单做私活避坑指南
  17. IO(BIO),NIO,AIO的深度解析和区别
  18. 【Hadoop】谷歌的三篇论文(GFS、MapReduce分布式计算模型 、BigTable大表)
  19. Butter Knife
  20. (三)Horizon 队列管理工具

热门文章

  1. 概论_第5章_切比雪夫不等式
  2. Vue.js实战梁笔记02(第3-5章)
  3. .Net Core 集成 RabbitMQ 订阅与发送
  4. oracle连接失败的原因总结
  5. Ubuntu root密码忘记了怎么重置密码
  6. 理解矩阵 from孟岩--流星小屋
  7. (wake_lock)后台任务 - 保持设备唤醒状态
  8. 解决Antimalware Service Executable(windows defender)占用过高CPU和内存的方法
  9. t600和t1200的区别
  10. 优先级倒挂(priority inversion)