ListView Grid line color option

Propose new features and changes
User avatar
JoeWinograd
Posts: 2180
Joined: 10 Feb 2014, 20:00
Location: U.S. Central Time Zone

ListView Grid line color option

Post by JoeWinograd » 04 May 2021, 13:11

ListView offers Background and Grid options. Problem is, the Grid option does not offer a color choice, whereas Background does. The grid line is always a very light gray (maybe it's Silver), which shows up fine when the background is a dark color, but is barely visible when the background is a light color. This Wish List request is to provide a color choice on Grid using the same syntax as on Background. The Help write-up could be similar to the one for Background, something like this:

Grid: Provides horizontal and vertical lines to visually indicate the boundaries between rows and columns. Specify the word Grid followed immediately by a color name (see color chart) or RGB value (the 0x prefix is optional). Examples: GridBlack, GridFFFFFF. If this option is not present, the ListView defaults to the system's default text color for the grid lines. Specifying GridDefault applies the system's default text color (usually black). For example, a ListView's grid lines can be restored to the default color via GuiControl, +GridDefault, MyListView.

Thanks very much for your consideration of this enhancement. Regards, Joe

P.S. I'd be fine with hard-coding the default to Silver, which is what I think it is now.
SAbboushi
Posts: 252
Joined: 08 Dec 2014, 22:13

Re: ListView Grid line color option

Post by SAbboushi » 22 Jan 2024, 22:30

I second that wish
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: ListView Grid line color option

Post by just me » 23 Jan 2024, 10:23

The reason for the lack of an option for the grid color is that ListViews don't offer such an option. If you want to determine a color you need to draw the cell borders on NM_CUSTOMDRAW notifications.
SAbboushi
Posts: 252
Joined: 08 Dec 2014, 22:13

Re: ListView Grid line color option

Post by SAbboushi » 23 Jan 2024, 11:31

Thanks. Was looking at your V2 LV_Colors Class yesterday: does it offer such an option?
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: ListView Grid line color option

Post by just me » 23 Jan 2024, 11:35

It doesn't.
ntepa
Posts: 406
Joined: 19 Oct 2022, 20:52

Re: ListView Grid line color option

Post by ntepa » 24 Jan 2024, 03:52

Here's a function to change the ListView grid color:

Code: Select all

#Requires AutoHotkey v2.0

g1 := Gui(, "test")
LV := g1.AddListView("h200 +Grid Background1b1b1b cWhite", ["Column1", "Column2", "Column3"])
LV_GridColor(LV, 0x3283AC)
loop 20
    LV.Add(, "Row" A_Index, "Item" A_Index)
g1.Show("NA")

g2 := Gui(, "test")
LV := g2.AddListView("h200 +Grid Background1b1b1b cWhite", ["Column1", "Column2", "Column3"])
LV_GridColor(LV, 0xFF0000)
loop 20
    LV.Add(, "Row" A_Index, "Item" A_Index)
g1.GetPos(&X,, &W)
g2.Show("NA x" X+W)

LV_GridColor(LV, color?) {
    static LVSubclassCB := CallbackCreate(LVSubclassProc, 6)
    static Pens := Map()

    hLV := LV.hwnd

    if !IsSet(color) {
        if Pens.Has(hLV) {
            DllCall("DeleteObject", "ptr", Pens[hLV])
            DllCall("RemoveWindowSubclass", "ptr", hLV, "ptr", LVSubclassCB, "ptr", ObjPtr(LV))
        }
        return
    }

    ; RGB to BGR
    color := color >> 16 | (color & 0xFF00) | (color & 0xFF) << 16

    if Pens.Has(hLV) {
        DllCall("DeleteObject", "ptr", Pens[hLV])
        Pens[hLV] := DllCall("CreatePen", "uint", 0, "uint", 1, "uint", color)
        return
    }

    Pens[hLV] := DllCall("CreatePen", "uint", 0, "uint", 1, "uint", color)
    DllCall("SetWindowSubclass", "ptr", hLV, "ptr", LVSubclassCB, "ptr", ObjPtr(LV), "ptr", 0)

    static LVSubclassProc(H, M, W, L, I, R) {
        Critical
        static WM_NOTIFY := 0x004E
        static WM_PAINT := 0x000F
        static WM_DESTROY := 0x0002
        static LVM_GETHEADER := 0x101F
        static LVM_GETEXTENDEDLISTVIEWSTYLE := 0x1037
        static LVS_EX_GRIDLINES := 0x1
        static HDM_GETITEMCOUNT := 0x1200
        static LVM_GETCOUNTPERPAGE := 0x1028
        static LVM_GETCOLUMNWIDTH := 0x101D
        static LVM_GETITEMRECT := 0x100E

        switch M {
        case WM_PAINT:
            ; based on: https://web.archive.org/web/20081204015020/http://www.codeguru.com/cpp/controls/listview/gridlines/article.php/c963/#more
            ; If Grid is enabled, draw custom grid.
            if SendMessage(LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0, H) & LVS_EX_GRIDLINES
            {
                ; First let the control do its default drawing.
                DllCall("DefSubclassProc", "ptr", H, "uint", M, "ptr", W, "ptr", L, "ptr")
                pen := Pens[H]
                hdc := DllCall("GetDC", "ptr", H)
                HHEADER := SendMessage(LVM_GETHEADER,,, H)
                col_count := SendMessage(HDM_GETITEMCOUNT,,, HHEADER)
                ; The bottom of the header corresponds to the top of the line.
                WinGetClientPos(,,, &Top, HHEADER)
                WinGetClientPos(,, &Width, &Height, H)
                oldPen := DllCall("SelectObject", "ptr", hdc, "ptr", pen)
                ; The border of the width is offset by the horz scroll
                borderx := 0 - DllCall("GetScrollPos", "ptr", H, "uint", 0)
                ; Draw the vertical gridlines.
                loop col_count
                {
                    col_width := SendMessage(LVM_GETCOLUMNWIDTH, A_Index - 1, 0, H)
                    borderx += col_width
                    ; if next border is outside client area, break.
                    if borderx >= Width
                        break
                    DllCall("MoveToEx", "ptr", hdc, "int", borderx, "int", top, "ptr", 0)
                    DllCall("LineTo", "ptr", hdc, "int", borderx, "int", Height)
                }
                rc := Buffer(16, 0)
                SendMessage(LVM_GETITEMRECT, 0, rc, H)
                RowHeight := NumGet(rc, 12, "int") - NumGet(rc, 4, "int")
                count_per_page := SendMessage(LVM_GETCOUNTPERPAGE, 0, 0, H)
                ; Draw the horizontal gridlines.
                loop count_per_page
                {
                    DllCall("MoveToEx", "ptr", hdc, "int", 0, "int", top + RowHeight*A_Index-1, "ptr", 0)
                    DllCall("LineTo", "ptr", hdc, "int", Width, "int", top + RowHeight*A_Index-1)
                }
                DllCall("SelectObject", "ptr", hdc, "ptr", oldPen)
                DllCall("ReleaseDC", "ptr", H, "ptr", hdc)
                return 0
            }

        case WM_DESTROY:
                if IsSet(Pens)
                    DllCall("DeleteObject", "ptr", Pens.Delete(H))
                DllCall("RemoveWindowSubclass", "ptr", H, "ptr", LVSubclassCB, "ptr", ObjPtr(GuiCtrlFromHwnd(H)))
        }

        return DllCall("DefSubclassProc", "ptr", H, "uint", M, "ptr", W, "ptr", L, "ptr")
    }
}
image.png
image.png (23.7 KiB) Viewed 386 times
just me
Posts: 9424
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: ListView Grid line color option

Post by just me » 24 Jan 2024, 09:25

SAbboushi
Posts: 252
Joined: 08 Dec 2014, 22:13

Re: ListView Grid line color option

Post by SAbboushi » 24 Jan 2024, 12:01

Great stuff - thanks folks
Post Reply

Return to “Wish List”