告诉所有者绘制列表框的最好方法是重新绘制项目
Best way to tell owner draw listbox redraw an item?
我创建了一个所有者绘制列表框,并像下面这样将texts
向量绑定到它。
vector<wchar_t*> texts;
lbHWND = CreateWindowExW(NULL, WC_LISTBOX, NULL,
WS_CHILD | WS_BORDER | WS_VISIBLE | LBS_NODATA |
LBS_OWNERDRAWFIXED | LBS_NOTIFY | LBS_NOINTEGRALHEIGHT,
0, 0, 400, 400, tkHWND, (HMENU)IDC_LISTBOX_ENTRY, hInstance, 0);
SCROLLINFO lbSi = { 0 };
lbSi.cbSize = sizeof(SCROLLINFO);
lbSi.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
lbSi.nMin = 0;
lbSi.nMax = text.size();
lbSi.nPage = 20;
lbSi.nPos = 0;
SetScrollInfo(lbHWND, SB_VERT, &lbSi, TRUE);
SendMessageW(lbHWND, LB_RESETCONTENT, 0, 0);
SendMessage(lbHWND, LB_SETCOUNT, iTotal, 0);
LRESULT CALLBACK WndProc(HWND phwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_MEASUREITEM:
{
MEASUREITEMSTRUCT* lpmis = (LPMEASUREITEMSTRUCT)lParam;
switch (lpmis->CtlID)
{
case IDC_LISTBOX_ENTRY:
lpmis->itemHeight = 20;
break;
default:
break;
}
return TRUE;
}
case WM_DRAWITEM:
{
DRAWITEMSTRUCT* lpdis = (LPDRAWITEMSTRUCT)lParam;
if (lpdis->itemID == -1) return;
HBRUSH hb = NULL;
HPEN hp = NULL;
switch (lpdis->itemAction)
{
case ODA_SELECT:
case ODA_DRAWENTIRE:
SetBkMode(lpdis->hDC, TRANSPARENT);
hb = CreateSolidBrush(lpdis->itemState & ODS_SELECTED ? 0xf1f1f1 : 0xffffff);
hp = CreatePen(PS_SOLID, 1, lpdis->itemState & ODS_SELECTED ? 0xcfcfcf : 0xffffff);
SelectObject(lpdis->hDC, hp);
SelectObject(lpdis->hDC, hb);
Rectangle(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, lpdis->rcItem.right, lpdis->rcItem.bottom);
TextOut(lpdis->hDC,
lpdis->rcItem.left + 5,
lpdis->rcItem.top + 2,
texts[i],
wcslen(texts[i]);
break;
}
if (hp) DeleteObject(hp);
if (hb) DeleteObject(hb);
}
}
}
现在假设我在texts
中更新了一个项目,你能告诉我一个好方法来告诉列表框重新绘制该项目吗?
目前,我使用以下代码:
texts[2] = L"Some text";
SendMessageW(lbHWND, LB_RESETCONTENT, 0, 0);
SendMessage(lbHWND, LB_SETCOUNT, iTotal, 0);
强制列表框重新绘制所有项,而不仅仅是第三项。有更好的方法吗?
您可以使用LB_GETITEMRECT
来检索项目的坐标,然后使用InvalidateRect()
来强制重新绘制窗口的特定区域:
RECT r = {};
if (SendMessage(lbHWND, LB_GETITEMRECT, index, &r) != LB_ERR)
InvalidateRect(lbHWND, &r, 0);
相关文章:
- QuadTree只在窗口的右上角绘制
- 绘制旋转的三角形
- flutter:即使shouldRepaint()返回true,自定义画家也不会重新绘制
- 如何在QT中的自定义视频小工具t上绘制矩形
- 如何在Visual Basic中使用矩形函数OpenGL绘制矩形
- 无法使用VAO和EBO(openGL)绘制多个对象
- 为什么我的点没有在 OpenGL 中绘制鼠标所在的位置?
- 绘制顺时针三角形,重新排序点
- 在顶点着色器中使用 OpenGl 的未声明标识符,我在顶点着色器中绘制三角形时遇到问题
- SFML 文本未绘制在窗口上
- 如何在快板的屏幕中显示子位图的绘制?
- 通过 GdkPixbuf 绘制时会绘制错误的像素坐标
- 使用绘制轮廓绘制点的序列
- C++ WinApi 绘制图像.jpg到新窗口
- 如何获取绘制点的新坐标
- 如果新图像中的原始像素为黑色,则Qt绘制一个蓝色像素
- 在 OpenGL 中每帧绘制新的全屏图像的最快方法是什么?
- MFC在最大化窗口处绘制新窗口
- cocos2dx c++如何用鼠标触控绘制线条(绘制元素)
- 如何编辑SFML源代码来添加一个新的可绘制对象