如何更改列表视图的边框颜色

Posted

技术标签:

【中文标题】如何更改列表视图的边框颜色【英文标题】:How to change border color of a listview 【发布时间】:2019-08-17 15:59:22 【问题描述】:

我已经使用 win32 api 创建了一个列表视图。

InitCommonControls();
HWND hwndList1 = CreateWindow(WC_LISTVIEW , L"", WS_VISIBLE|WS_CHILD | LVS_REPORT | LVS_EDITLABELS |  LVS_ICON  | LV_VIEW_TILE |  LVS_EX_GRIDLINES | WS_BORDER | LVS_EX_FULLROWSELECT | ES_LEFT , 10, 10, 300, 190, hwnd, NULL, GetModuleHandle(NULL), 0); 

SendMessageW( hwndList1,
            LVM_SETEXTENDEDLISTVIEWSTYLE,
            LVS_EX_FULLROWSELECT ,
            LVS_EX_FULLROWSELECT );



CreateItem(hwndList1 , (char*)L"fault RS458");
CreateItem(hwndList1 , (char*)L"fault RS455");
CreateColumn(hwndList1 , 0 , (char*)L"Insert column" , 300);

我看到列表视图周围有黑色边框。我怎样才能改变它的颜色?

【问题讨论】:

尝试删除WS_BORDER 样式。另请参阅此处的 MS 示例:docs.microsoft.com/en-us/windows/win32/controls/… @Jesper Juhl 我使用 win32 api 创建了它...编辑了我的问题 @Richard Critten 通过删除WS_BORDER 边框被删除 我认为 WS_BORDER 会使用系统颜色,所以最简单的覆盖它的方法是自己继承和处理 WM_NCPAINT。 顺便说一句,您使用的样式标志不正确。 LV_VIEW_TILE 只能通过发送LVM_SETVIEW 消息来设置。对于LVS_EX_* 标志,您必须发送LVM_SETEXTENDEDLISTVIEWSTYLE。最后ES_LEFT和listview完全没有关系,属于编辑控件。 【参考方案1】:

您可以使用SetWindowSubclass(需要comctl32.lib)对窗口进行子类化并处理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);

旁注,(char*)L"text" 没有意义。使用 ANSI ((char*)"text") 或 Unicode ((wchar_t*)L"text",推荐)。您可以将CreateItem 更改为接受const wchar_t*,然后在最后一步将LVITEM 转换为(wchar_t*) 以避免错误。

编辑WM_NCPAINT 将中断,不返回零。

【讨论】:

请告诉我从标题中删除 3d 边框我应该处理哪些消息以及在哪些 proc 内?谢谢 您应该编辑问题并添加一些图片以显示您想要的内容。 listview 控件有其自己的标题控件,您可能必须对该控件进行子类化。顺便问一下,您是否启用了“现代 UI”?看看这个帖子enabling visual styles 看起来你有默认设置。您的所有控件都具有可追溯到 1990 年代的旧 3-D 外观。您需要启用视觉样式。然后您的列表视图、按钮、复选框等将看起来像 Windows 资源管理器中的那些。见前面的评论。你使用 Visual Studio 吗?如果没有,你必须在你的*.rc资源文件1 24 "myapplication.exe.manifest"中包含一个清单文件@ 当我启用视觉样式时,3d 边框被移除,但我在自定义绘图中指定的背景颜色和文本颜色不再应用。有没有办法更改标题的背景和文本颜色什么时候使用视觉样式? 使用HWND hHeader = ListView_GetHeader(hListView) 获取标题控件。如果您想恢复旧的 3d 查找单个控件,请使用 SetWindowTheme(hHeader, L"", L"");。然后使用“所有者绘制”(不是“自定义绘制”)重新绘制。我在post 中展示了如何使用“自定义绘图”,我对您的位置感到困惑。您应该发布一个新问题。

以上是关于如何更改列表视图的边框颜色的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式更改背景颜色而不影响边框?

在选择时更改 UITableViewCell 的边框颜色

SwiftUI间隙左边距并更改列表项底部边框的颜色

Cocoa Touch:如何改变 UIView 的边框颜色和粗细?

如何更改按钮的边框颜色并更改editText中下划线的颜色?

如何更改 QTableView 边框颜色?