by just me » 31 May 2022, 06:40
Moin,
weil mich das Thema interessiert hat, habe ich eine Minimalvariante von teadrinker's Klasse erstellt. Man muss die Spalten 'händisch' setzen, z.B. aus dem ListView-Label heraus:
Code: Select all
#NoEnv
SetBatchLines, -1
Gui, Margin, 20, 20
Gui, Add, ListView, w400 r12 hwndHLV1 +Grid +NoSort +LV0x010000 gLV1_Event, Column 1|Column 2|Column 3|Column 4
Loop, 16
LV_Add("", A_Index . "1", A_Index . "2", A_Index . "3", A_Index . "4")
LV_ModifyCol(LV_GetCount("Col"), "AutoHdr")
Gui, Show, , ListView with colored columns
Return
LV1_Event:
If (A_GuiEvent = "ColClick")
LV_SelectColumns.Select(HLV1, A_EventInfo, GetKeyState("Ctrl", "P"))
Return
GuiClose:
ExitApp
; ======================================================================================================================
; LV_SelectColumns - Select columns in a list-view to be drawn using the selection colors
; ======================================================================================================================
Class LV_SelectColumns {
Static Ctrls := []
Static MsgFunc := ObjBindMethod(LV_SelectColumns, "Draw")
; ===================================================================================================================
__New(P*) {
Return False ; don't allow instances
}
; ===================================================================================================================
; Store selected columns
; HLV - handle of the list-view
; Col - 1-based column index
; CtrlDown - is the Ctrl key down?
; ===================================================================================================================
Select(HLV, Col, CtrlPressed) {
If !This.Ctrls.HasKey(HLV) || !CtrlPressed
This.Ctrls[HLV] := {(Col): 1}
Else {
If This.Ctrls[HLV].HasKey(Col) {
This.Ctrls[HLV].Delete(Col)
If !This.Ctrls[HLV].Count()
This.Ctrls.Delete(HLV)
}
Else
This.Ctrls[HLV, Col] := 1
}
This.Check()
WinSet, Redraw, , ahk_id %HLV%
}
; ===================================================================================================================
; Clear the entry for the passed list-view control
; ===================================================================================================================
Clear(HLV) {
If This.Ctrls.HasKey(HLV) {
This.Ctrls.Delete(HLV)
This.Check()
WinSet, Redraw, , ahk_id %HLV%
}
}
; ===================================================================================================================
; Draw the selected columns - for unternal use
; ===================================================================================================================
Draw(W, L, M, HWND := "") {
Static CDRF_NEWFONT := 0x02
Static CB := DllCall("GetSysColor", "Int", 13, "UInt") ; COLOR_HIGHLIGHT
Static CT := DllCall("GetSysColor", "Int", 14, "UInt") ; COLOR_HIGHLIGHTTEXT
Static DB := 0 ; default background color
Static DT := 0 ; default text color
Static NMHDRSize := A_PtrSize * 3 ; size off NMHDR structure
Static NCDSize := NMHDRSize + (4 * 4) + (A_PtrSize * 5) ; size of NMCUSTOMDRAW structure
Critical
H := NumGet(L + 0, 0, "UPtr")
C := NumGet(L + (A_PtrSize * 2), 0, "Int")
; NM_CUSTOMDRAW --------------------------------------------------------------------------------------------------
If (This.Ctrls.HasKey(H) && (C = -12)) { ; NM_CUSTOMDRAW = -12
Stage := NumGet(L + NMHDRSize, 0, "UInt")
Switch Stage {
; CDDS_SUBITEMPREPAINT -------------------------------------------------------------------------------------
Case 0x00030001:
SubItem := NumGet(L + NCDSize, 8, "Int") + 1
If This.Ctrls[H].HasKey(SubItem) {
NumPut(CT, L + NCDSize, 0, "UInt") ; clrText
NumPut(CB, L + NCDSize, 4, "UInt") ; clrTextBk
NumPut(CB, L + NCDSize, 16, "UInt") ; clrFace
}
Else {
NumPut(DT, L + NCDSize, 0, "UInt") ; clrText
NumPut(DB, L + NCDSize, 4, "UInt") ; clrTextBk
NumPut(DB, L + NCDSize, 16, "UInt") ; clrFace
}
Return 0x20 ; CDRF_NOTIFYITEMDRAW
; CDDS_ITEMPREPAINT ----------------------------------------------------------------------------------------
Case 0x00010001:
Return 0x20 ; CDRF_NOTIFYITEMDRAW
; CDDS_PREPAINT --------------------------------------------------------------------------------------------
Case 0x00000001:
DB := DllCall("SendMessage", "Ptr", H, "UInt", 0x1025, "Ptr", 0, "Ptr", 0, "UInt") ; LVM_GETTEXTBKCOLOR
DT := DllCall("SendMessage", "Ptr", H, "UInt", 0x1023, "Ptr", 0, "Ptr", 0, "UInt") ; LVM_GETTEXTCOLOR
Return 0x20 ; CDRF_NOTIFYITEMDRAW
; Default --------------------------------------------------------------------------------------------------
Default:
Return 0x00 ; CDRF_DODEFAULT
}
}
}
; ===================================================================================================================
; Check whether the massage handler needs to be active
; ===================================================================================================================
Check() {
Static Drawing := False
If (Drawing) {
If !This.Ctrls.Count() {
OnMessage(0x004E, This.MsgFunc, 0)
Drawing := False
}
}
Else {
If This.Ctrls.Count() {
OnMessage(0x004E, This.MsgFunc, -1)
Drawing := True
}
}
}
}
Wem die Systemauswahlfarben nicht gefallen, der kann in der Methode
Draw() die statischen Variablen
CB (Hintergrund) und
CT (Text) auf die eigenen Wunschfarben setzen (Achtung: BGR!).
Moin,
weil mich das Thema interessiert hat, habe ich eine Minimalvariante von teadrinker's Klasse erstellt. Man muss die Spalten 'händisch' setzen, z.B. aus dem ListView-Label heraus:
[code]#NoEnv
SetBatchLines, -1
Gui, Margin, 20, 20
Gui, Add, ListView, w400 r12 hwndHLV1 +Grid +NoSort +LV0x010000 gLV1_Event, Column 1|Column 2|Column 3|Column 4
Loop, 16
LV_Add("", A_Index . "1", A_Index . "2", A_Index . "3", A_Index . "4")
LV_ModifyCol(LV_GetCount("Col"), "AutoHdr")
Gui, Show, , ListView with colored columns
Return
LV1_Event:
If (A_GuiEvent = "ColClick")
LV_SelectColumns.Select(HLV1, A_EventInfo, GetKeyState("Ctrl", "P"))
Return
GuiClose:
ExitApp
; ======================================================================================================================
; LV_SelectColumns - Select columns in a list-view to be drawn using the selection colors
; ======================================================================================================================
Class LV_SelectColumns {
Static Ctrls := []
Static MsgFunc := ObjBindMethod(LV_SelectColumns, "Draw")
; ===================================================================================================================
__New(P*) {
Return False ; don't allow instances
}
; ===================================================================================================================
; Store selected columns
; HLV - handle of the list-view
; Col - 1-based column index
; CtrlDown - is the Ctrl key down?
; ===================================================================================================================
Select(HLV, Col, CtrlPressed) {
If !This.Ctrls.HasKey(HLV) || !CtrlPressed
This.Ctrls[HLV] := {(Col): 1}
Else {
If This.Ctrls[HLV].HasKey(Col) {
This.Ctrls[HLV].Delete(Col)
If !This.Ctrls[HLV].Count()
This.Ctrls.Delete(HLV)
}
Else
This.Ctrls[HLV, Col] := 1
}
This.Check()
WinSet, Redraw, , ahk_id %HLV%
}
; ===================================================================================================================
; Clear the entry for the passed list-view control
; ===================================================================================================================
Clear(HLV) {
If This.Ctrls.HasKey(HLV) {
This.Ctrls.Delete(HLV)
This.Check()
WinSet, Redraw, , ahk_id %HLV%
}
}
; ===================================================================================================================
; Draw the selected columns - for unternal use
; ===================================================================================================================
Draw(W, L, M, HWND := "") {
Static CDRF_NEWFONT := 0x02
Static CB := DllCall("GetSysColor", "Int", 13, "UInt") ; COLOR_HIGHLIGHT
Static CT := DllCall("GetSysColor", "Int", 14, "UInt") ; COLOR_HIGHLIGHTTEXT
Static DB := 0 ; default background color
Static DT := 0 ; default text color
Static NMHDRSize := A_PtrSize * 3 ; size off NMHDR structure
Static NCDSize := NMHDRSize + (4 * 4) + (A_PtrSize * 5) ; size of NMCUSTOMDRAW structure
Critical
H := NumGet(L + 0, 0, "UPtr")
C := NumGet(L + (A_PtrSize * 2), 0, "Int")
; NM_CUSTOMDRAW --------------------------------------------------------------------------------------------------
If (This.Ctrls.HasKey(H) && (C = -12)) { ; NM_CUSTOMDRAW = -12
Stage := NumGet(L + NMHDRSize, 0, "UInt")
Switch Stage {
; CDDS_SUBITEMPREPAINT -------------------------------------------------------------------------------------
Case 0x00030001:
SubItem := NumGet(L + NCDSize, 8, "Int") + 1
If This.Ctrls[H].HasKey(SubItem) {
NumPut(CT, L + NCDSize, 0, "UInt") ; clrText
NumPut(CB, L + NCDSize, 4, "UInt") ; clrTextBk
NumPut(CB, L + NCDSize, 16, "UInt") ; clrFace
}
Else {
NumPut(DT, L + NCDSize, 0, "UInt") ; clrText
NumPut(DB, L + NCDSize, 4, "UInt") ; clrTextBk
NumPut(DB, L + NCDSize, 16, "UInt") ; clrFace
}
Return 0x20 ; CDRF_NOTIFYITEMDRAW
; CDDS_ITEMPREPAINT ----------------------------------------------------------------------------------------
Case 0x00010001:
Return 0x20 ; CDRF_NOTIFYITEMDRAW
; CDDS_PREPAINT --------------------------------------------------------------------------------------------
Case 0x00000001:
DB := DllCall("SendMessage", "Ptr", H, "UInt", 0x1025, "Ptr", 0, "Ptr", 0, "UInt") ; LVM_GETTEXTBKCOLOR
DT := DllCall("SendMessage", "Ptr", H, "UInt", 0x1023, "Ptr", 0, "Ptr", 0, "UInt") ; LVM_GETTEXTCOLOR
Return 0x20 ; CDRF_NOTIFYITEMDRAW
; Default --------------------------------------------------------------------------------------------------
Default:
Return 0x00 ; CDRF_DODEFAULT
}
}
}
; ===================================================================================================================
; Check whether the massage handler needs to be active
; ===================================================================================================================
Check() {
Static Drawing := False
If (Drawing) {
If !This.Ctrls.Count() {
OnMessage(0x004E, This.MsgFunc, 0)
Drawing := False
}
}
Else {
If This.Ctrls.Count() {
OnMessage(0x004E, This.MsgFunc, -1)
Drawing := True
}
}
}
}[/code]
Wem die Systemauswahlfarben nicht gefallen, der kann in der Methode [c]Draw()[/c] die statischen Variablen [c]CB[/c] (Hintergrund) und [c]CT[/c] (Text) auf die eigenen Wunschfarben setzen (Achtung: BGR!).