本人微信公众号:CPP进阶之旅
如果觉得这篇文章对您有帮助,欢迎关注 “CPP进阶之旅” 学习更多技术干货
win32实现ListBox自绘
1、ListBox控件自绘要点
- 在CreateWindowEx创建窗口时,需要对参数dwStyle设置上LBS_OWNERDRAWFIXED | LBS_HASSTRINGS这两个属性。并且需要在创建listbox窗口的父窗口中处理WM_DRAWITEM和WM_MEASUREITEM两个消息进行列表框的重绘。
- LBS_OWNERDRAWFIXED:指定列表框的父窗口负责绘制其内容,并且列表框中的项目具有相同的高度。创建列表框时,父窗口将收到WM_MEASUREITEM消息;如果列表框的外观已发生更改,则父窗口将收到WM_DRAWITEM消息。
也可以根据需要用LBS_OWNERDRAWVARIABLE替换LBS_OWNERDRAWFIXED。LBS_OWNERDRAWVARIABLE指定也是用于列表框的父窗口负责绘制其内容,另外列表框中的条目的高度可变。 - LBS_HASSTRINGS:如果不设定LBS_HASSTRINGS,那么通过LB_GETTEXT消息或者ListBox_GetText方法取得的字符串将是乱码
2、ListBox控件自绘关键代码
//创建listbox
HWND hwndListBox =CreateWindowEx(0, WC_LISTBOX, L"",
WS_VISIBLE | WS_CHILD | WS_VSCROLL | WS_BORDER | WS_TABSTOP | LBS_NOTIFY | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS,//如果不设定LBS_HASSTRINGS,那么GetText取得的将是乱码
20, 20, 360, 240, hWnd, nullptr,GetModuleHandle(nullptr), nullptr);
//添加数据
for (int i = 0; i < 10; i++) {
WCHAR itemText[256];
ZeroMemory(itemText, sizeof(itemText));
wsprintf(itemText, L"item %d", i);
ListBox_AddString(hwndListBox, itemText);
}
//在父窗口中处理WM_DRAWITEM消息实现列表条目的自绘
case WM_DRAWITEM:
{
DRAWITEMSTRUCT* pdis = (DRAWITEMSTRUCT*)lParam;
if (pdis->itemAction != ODA_DRAWENTIRE && pdis->itemAction != ODA_SELECT)
break;
LPDRAWITEMSTRUCT pDI = (LPDRAWITEMSTRUCT)lParam;
HBRUSH brsh = CreateSolidBrush(RGB(255 - 30 * pDI->itemID, 128 + 40 * pDI->itemID, 128 + 40 * pDI->itemID));//yellow
FillRect(pDI->hDC, &pDI->rcItem, brsh);
DeleteObject(brsh);
// text
SetBkMode(pDI->hDC, TRANSPARENT);
WCHAR szText[260];
SendMessage(hwndListBox, LB_GETTEXT, pDI->itemID, (LPARAM)szText);
const DWORD dwStyle = DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_END_ELLIPSIS;
DrawText(pDI->hDC, szText, wcslen(szText), &pDI->rcItem, dwStyle);
} break;
3、完整代码
https://download.csdn.net/download/siyacaodeai/15452147
4、重要说明
欢迎大家关注我的个人微信公众号,查看专业的客户端/服务端开发知识、笔试面试题目、程序员职场经验与心得分享。