您可以使用子类化窗口设置窗口子类 https://learn.microsoft.com/en-us/windows/win32/api/commctrl/nf-commctrl-setwindowsubclass(需要 comctl32.lib)和句柄WM_NCPAINT https://learn.microsoft.com/en-us/windows/win32/gdi/wm-ncpaint绘制控件的非客户区,如下所示:
#include <Windows.h>
#include <CommCtrl.h>
LRESULT CALLBACK ListViewProc(HWND hwnd,
UINT msg, WPARAM wp, LPARAM lp, UINT_PTR, DWORD_PTR)
{
switch(msg)
{
case WM_NCPAINT:
{
RECT rc;
GetWindowRect(hwnd, &rc);
OffsetRect(&rc, -rc.left, -rc.top);
auto hdc = GetWindowDC(hwnd);
auto hpen = CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
auto oldpen = SelectObject(hdc, hpen);
SelectObject(hdc, GetStockObject(NULL_BRUSH));
Rectangle(hdc, rc.left, rc.top, rc.right, rc.bottom);//draw red frame
SelectObject(hdc, oldpen);
DeleteObject(oldpen);
ReleaseDC(hwnd, hdc);
//*** EDIT
//documentation says we should return 0
//but that causes problem with vertical scrollbar
//maybe we should break for this subclass case
break; //not return 0!
}
case WM_NCDESTROY:
RemoveWindowSubclass(hwnd, ListViewProc, 0);
break;
}
return DefSubclassProc(hwnd, msg, wp, lp);
}
...
HWND hwndList1 = CreateWindow(...);
SetWindowSubclass(hwndList1, ListViewProc, 0, NULL);
Side note, (char*)L"text"
doesn't make sense. Either use ANSI ((char*)"text"
) or Unicode ((wchar_t*)L"text"
, recommended). You can change CreateItem
to accept const wchar_t*
, then cast to (wchar_t*)
for LVITEM
at the last step to avoid errors.
Edit
WM_NCPAINT
会中断,不会返回零。