Whats a better way to get which column was double-clicked in a gui listview? Topic is solved
Whats a better way to get which column was double-clicked in a gui listview?
Something better than this?
Re: Whats a better way to get which column was double-clicked in a gui listview? Topic is solved
script from user 'just me'
https://autohotkey.com/board/topic/80265-solved-which-column-is-clicked-in-listview/
https://autohotkey.com/board/topic/80265-solved-which-column-is-clicked-in-listview/
Code: Select all
;-------- saved at Mittwoch, 18. September 2019 21:42:50 --------------
;;-------- https://autohotkey.com/board/topic/80265-solved-which-column-is-clicked-in-listview/ ---
#NoEnv
Gui, Margin, 20, 20
Gui, Add, ListView, w400 r9 Grid HwndHLV1 gSubLV AltSubmit, Column 1|Column 2|Column 3
Loop, 9
LV_Add("", A_Index, A_Index, A_Index)
Loop, 3
LV_ModifyCol(A_Index, "AutoHdr")
Gui, Show, , ListView
Return
; ----------------------------------------------------------------------------------------------------------------------
GuiCLose:
ExitApp
; ----------------------------------------------------------------------------------------------------------------------
SubLV:
If (A_GuiEvent = "Normal") {
Row := A_EventInfo
Column := LV_SubItemHitTest(HLV1)
ToolTip, You clicked on column %Column% in row %Row%!
SetTimer, KillToolTip, -1500
}
Return
; ----------------------------------------------------------------------------------------------------------------------
KillToolTip:
ToolTip
Return
; ----------------------------------------------------------------------------------------------------------------------
LV_SubitemHitTest(HLV) {
; To run this with AHK_Basic change all DllCall types "Ptr" to "UInt", please.
; HLV - ListView's HWND
Static LVM_SUBITEMHITTEST := 0x1039
VarSetCapacity(POINT, 8, 0)
; Get the current cursor position in screen coordinates
DllCall("User32.dll\GetCursorPos", "Ptr", &POINT)
; Convert them to client coordinates related to the ListView
DllCall("User32.dll\ScreenToClient", "Ptr", HLV, "Ptr", &POINT)
; Create a LVHITTESTINFO structure (see below)
VarSetCapacity(LVHITTESTINFO, 24, 0)
; Store the relative mouse coordinates
NumPut(NumGet(POINT, 0, "Int"), LVHITTESTINFO, 0, "Int")
NumPut(NumGet(POINT, 4, "Int"), LVHITTESTINFO, 4, "Int")
; Send a LVM_SUBITEMHITTEST to the ListView
SendMessage, LVM_SUBITEMHITTEST, 0, &LVHITTESTINFO, , ahk_id %HLV%
; If no item was found on this position, the return value is -1
If (ErrorLevel = -1)
Return 0
; Get the corresponding subitem (column)
Subitem := NumGet(LVHITTESTINFO, 16, "Int") + 1
Return Subitem
}
/*
typedef struct _LVHITTESTINFO {
POINT pt;
UINT flags;
int iItem;
int iSubItem;
int iGroup;
} LVHITTESTINFO, *LPLVHITTESTINFO;
*/
-
- Posts: 4565
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: Whats a better way to get which column was double-clicked in a gui listview?
Code: Select all
Gui, Add, ListView, Grid r5, Col 1|Col 2|Col 3|Col 4
Loop 5
LV_Add()
Gui, Show
OnMessage(0x4E, "WM_NOTIFY")
Return
GuiClose:
ExitApp
WM_NOTIFY(wp, lp) {
static NM_DBLCLK := -3
if NumGet(lp + A_PtrSize*2, "Int") = NM_DBLCLK
ToolTip % NumGet(lp + A_PtrSize*3 + 4, "Int") + 1
}
Re: Whats a better way to get which column was double-clicked in a gui listview?
Thank you for the code.
Re: Whats a better way to get which column was double-clicked in a gui listview?
@teadrinker, thank you for the script
-
- Posts: 4565
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: Whats a better way to get which column was double-clicked in a gui listview?
@garry
Code: Select all
Gui, Add, ListView, Grid r5, Col 1|Col 2|Col 3|Col 4
Loop 5
LV_Add()
Gui, Show
OnMessage(0x4E, "WM_NOTIFY")
Return
GuiClose:
ExitApp
WM_NOTIFY(wp, lp) {
static notices := {-2: "NM_CLICK", -3: "NM_DBLCLK"}
notice := NumGet(lp + A_PtrSize*2, "Int")
if (notice = -2 || notice = -3)
ToolTip % "Action: " . notices[notice] . "`n"
. "Row: " . NumGet(lp + A_PtrSize*3, "Int") + 1 . "`n"
. "Column: " . NumGet(lp + A_PtrSize*3 + 4, "Int") + 1
}
Re: Whats a better way to get which column was double-clicked in a gui listview?
@teadrinker, thank again, now see info : click/doubleclick , row , column
tried this to get row/column
tried this to get row/column
Code: Select all
Gui, Add, ListView, w400 r9 Grid HwndHLV1 gLV1 AltSubmit, Column 1|Column 2|Column 3
global action,notice,rowx,colx
Loop,5
LV_Add("", "Field 1-" . A_Index, "Field 2-" . A_Index, "Field 3-" . A_Index)
Gui, Show
OnMessage(0x4E, "WM_NOTIFY")
Return
;---------------
GuiClose:
ExitApp
;---------------
WM_NOTIFY(wp, lp)
{
static notices := {-2: "NM_CLICK", -3: "NM_DBLCLK"}
notice := NumGet(lp + A_PtrSize*2, "Int")
if (notice = -2 || notice = -3)
Action:= notices[notice]
rowx:= NumGet(lp + A_PtrSize*3, "Int") + 1
colx:= NumGet(lp + A_PtrSize*3 + 4, "Int") + 1
}
;---------------
LV1:
Gui,1:ListView,%a_guicontrol%
if a_guievent=Normal
{
LV_GetText(Cx,rowx,colx)
msgbox,%action% - "%cx%"
}
return
;================================================================
Last edited by garry on 24 May 2022, 15:30, edited 1 time in total.
Re: Whats a better way to get which column was double-clicked in a gui listview?
Moin (northern German equivalent for: "Hi!")teadrinker wrote: ↑19 Sep 2019, 11:27@garryCode: Select all
Gui, Add, ListView, Grid r5, Col 1|Col 2|Col 3|Col 4 Loop 5 LV_Add() Gui, Show OnMessage(0x4E, "WM_NOTIFY") Return GuiClose: ExitApp WM_NOTIFY(wp, lp) { static notices := {-2: "NM_CLICK", -3: "NM_DBLCLK"} notice := NumGet(lp + A_PtrSize*2, "Int") if (notice = -2 || notice = -3) ToolTip % "Action: " . notices[notice] . "`n" . "Row: " . NumGet(lp + A_PtrSize*3, "Int") + 1 . "`n" . "Column: " . NumGet(lp + A_PtrSize*3 + 4, "Int") + 1 }
Is there a chance to select a whole column with clicking its header?
-
- Posts: 4565
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: Whats a better way to get which column was double-clicked in a gui listview?
Aloha!
Do you mean this?
Code: Select all
LVM_SETEXTENDEDLISTVIEWSTYLE := 0x1036
LVS_EX_DOUBLEBUFFER := 0x00010000
Gui, Add, ListView, w350 vLV hwndhLV NoSort Grid R15, Col 1|Col 2|Col 3|Col 4
Loop 15
LV_Add("", "Field " . A_Index, "Field " . A_Index, "Field " . A_Index, "Field " . A_Index)
Loop, % LV_GetCount("Column")
LV_ModifyCol(A_Index, 80)
Gui, Show
SendMessage, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_DOUBLEBUFFER, LVS_EX_DOUBLEBUFFER,, ahk_id %hLV%
OnMessage(0x004E, Func("WM_NOTIFY").Bind(hLV))
Return
WM_NOTIFY(hLV, wp, lp) {
static LVN_COLUMNCLICK := -108, LVM_SETSELECTEDCOLUMN := 0x108C
hCtrl := NumGet(lp + 0)
if !(hCtrl = hLV)
Return
notify := NumGet(lp + A_PtrSize*2, "Int")
if (notify = LVN_COLUMNCLICK) {
col := NumGet(lp + A_PtrSize*3 + 4, "Int")
SendMessage, LVM_SETSELECTEDCOLUMN, col,,, ahk_id %hLV%
}
}
GuiClose() {
ExitApp
}
Re: Whats a better way to get which column was double-clicked in a gui listview?
@teadrinker - yep! erm, bear with me if it's kinda obvious but,...
a) allows this as well to extract that selection for further processing?
b) how to 'unselect' that selection if needed (ie if a row is clicked afterward, the column is still selected)?
a) allows this as well to extract that selection for further processing?
b) how to 'unselect' that selection if needed (ie if a row is clicked afterward, the column is still selected)?
-
- Posts: 4565
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: Whats a better way to get which column was double-clicked in a gui listview?
What would you like to get, a text array from selected items?
-
- Posts: 4565
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: Whats a better way to get which column was double-clicked in a gui listview?
Code: Select all
LVM_SETEXTENDEDLISTVIEWSTYLE := 0x1036
LVM_GETSELECTEDCOLUMN := 0x10AE
LVS_EX_DOUBLEBUFFER := 0x010000
Gui, Add, ListView, w350 vLV hwndhLV NoSort Grid R15, Col 1|Col 2|Col 3|Col 4
Loop 15
LV_Add("", "Field 1-" . A_Index, "Field 2-" . A_Index, "Field 3-" . A_Index, "Field 4-" . A_Index)
Loop, % LV_GetCount("Column")
LV_ModifyCol(A_Index, 80)
Gui, Show
SendMessage, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_DOUBLEBUFFER, LVS_EX_DOUBLEBUFFER,, ahk_id %hLV%
OnMessage(0x004E, Func("WM_NOTIFY").Bind(hLV))
Return
$F1::
SendMessage, LVM_GETSELECTEDCOLUMN,,,, ahk_id %hLV%
if !col := ErrorLevel + 1
Return
textArr := []
Loop % LV_GetCount() {
LV_GetText(text, A_Index, col)
textArr.Push(text)
MsgBox, % text
}
Return
WM_NOTIFY(hLV, wp, lp) {
static LVN_COLUMNCLICK := -108, LVM_SETSELECTEDCOLUMN := 0x108C, NM_CLICK := -2
hCtrl := NumGet(lp + 0)
if !(hCtrl = hLV)
Return
notify := NumGet(lp + A_PtrSize*2, "Int")
if (notify = LVN_COLUMNCLICK) {
while selectedRow := LV_GetNext()
LV_Modify(selectedRow, "-Select")
col := NumGet(lp + A_PtrSize*3 + 4, "Int")
SendMessage, LVM_SETSELECTEDCOLUMN, col,,, ahk_id %hLV%
}
if (notify = NM_CLICK)
SendMessage, LVM_SETSELECTEDCOLUMN, -1,,, ahk_id %hLV%
}
GuiClose() {
ExitApp
}
-
- Posts: 4565
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: Whats a better way to get which column was double-clicked in a gui listview?
Or without OnMessage():
Code: Select all
LVM_SETEXTENDEDLISTVIEWSTYLE := 0x1036
LVM_GETSELECTEDCOLUMN := 0x10AE
LVS_EX_DOUBLEBUFFER := 0x010000
Gui, Add, ListView, w350 hwndhLV NoSort Grid R15 AltSubmit, Col 1|Col 2|Col 3|Col 4
handler := Func("OnNotify").Bind(hLV)
GuiControl, +g, % hLV, % handler
Loop 15
LV_Add("", "Field 1-" . A_Index, "Field 2-" . A_Index, "Field 3-" . A_Index, "Field 4-" . A_Index)
Loop, % LV_GetCount("Column")
LV_ModifyCol(A_Index, 80)
Gui, Show
SendMessage, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_DOUBLEBUFFER, LVS_EX_DOUBLEBUFFER,, ahk_id %hLV%
Return
$F1::
SendMessage, LVM_GETSELECTEDCOLUMN,,,, ahk_id %hLV%
if !col := ErrorLevel + 1
Return
textArr := []
Loop % LV_GetCount() {
LV_GetText(text, A_Index, col)
textArr.Push(text)
MsgBox, % text
}
Return
OnNotify(hLV) {
static LVM_SETSELECTEDCOLUMN := 0x108C
if (A_GuiEvent = "Normal")
SendMessage, LVM_SETSELECTEDCOLUMN, -1,,, ahk_id %hLV%
if (A_GuiEvent = "ColClick") {
while selectedRow := LV_GetNext()
LV_Modify(selectedRow, "-Select")
SendMessage, LVM_SETSELECTEDCOLUMN, A_EventInfo - 1,,, ahk_id %hLV%
}
}
GuiClose() {
ExitApp
}
Re: Whats a better way to get which column was double-clicked in a gui listview?
@teadrinker - Perfetto Signore Mille Gracie
If you're OK with it I'd transfer a copy of that code on your behalf to the forum "Scripts&Funtions"-section?!?
If you're OK with it I'd transfer a copy of that code on your behalf to the forum "Scripts&Funtions"-section?!?
-
- Posts: 4565
- Joined: 29 Mar 2015, 09:41
- Contact:
-
- Posts: 4565
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: Whats a better way to get which column was double-clicked in a gui listview?
With some effort, I managed to apply the @just me's LV_Colors class to get a more contrasty selection:
Code: Select all
SetBatchLines, -1
selectionTextColor := 0xFFFFFF
selectionBackColor := 0x3399FF
Gui, Add, ListView, w350 hwndhLV NoSort Grid R15, Col 1|Col 2|Col 3|Col 4
Info := {hLV: hLV, selTextColor: selectionTextColor, selBackColor: selectionBackColor}
Loop 15
LV_Add("", "Field 1-" . A_Index, "Field 2-" . A_Index, "Field 3-" . A_Index, "Field 4-" . A_Index)
Loop, % LV_GetCount("Column")
LV_ModifyCol(A_Index, 80)
Gui, Show
OnMessage(0x004E, Func("WM_NOTIFY").Bind(Info))
Info.LV := new LV_Colors(hLV)
Return
#If Info.col
$F1::
textArr := []
Loop % LV_GetCount() {
LV_GetText(text, A_Index, Info.col)
textArr.Push(text)
MsgBox, % text
}
Return
#If
WM_NOTIFY(Info, wp, lp) {
static LVN_COLUMNCLICK := -108, NM_CLICK := -2
hCtrl := NumGet(lp + 0)
if !(hCtrl = Info.hLV)
Return
notify := NumGet(lp + A_PtrSize*2, "Int")
if (notify = LVN_COLUMNCLICK) {
Info.col := NumGet(lp + A_PtrSize*3 + 4, "Int") + 1
while selectedRow := LV_GetNext()
LV_Modify(selectedRow, "-Select")
Info.LV.Clear()
Loop % LV_GetCount()
Info.LV.Cell(A_Index, Info.col, Info.selBackColor, Info.selTextColor)
WinSet, Redraw,, % "ahk_id" . Info.hLV
}
if (notify = NM_CLICK && Info.col) {
Info.col := 0
Info.LV.Clear()
WinSet, Redraw,, % "ahk_id" . Info.hLV
}
}
GuiClose() {
ExitApp
}
Class LV_Colors {
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; META FUNCTIONS ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ===================================================================================================================
; __New() Create a new LV_Colors instance for the given ListView
; Parameters: HWND - ListView's HWND.
; Optional ------------------------------------------------------------------------------------------
; StaticMode - Static color assignment, i.e. the colors will be assigned permanently to the row
; contents rather than to the row number.
; Values: True/False
; Default: False
; NoSort - Prevent sorting by click on a header item.
; Values: True/False
; Default: True
; NoSizing - Prevent resizing of columns.
; Values: True/False
; Default: True
; ===================================================================================================================
__New(HWND, StaticMode := False, NoSort := True, NoSizing := True) {
If (This.Base.Base.__Class) ; do not instantiate instances
Return False
If This.Attached[HWND] ; HWND is already attached
Return False
If !DllCall("IsWindow", "Ptr", HWND) ; invalid HWND
Return False
VarSetCapacity(Class, 512, 0)
DllCall("GetClassName", "Ptr", HWND, "Str", Class, "Int", 256)
If (Class <> "SysListView32") ; HWND doesn't belong to a ListView
Return False
; ----------------------------------------------------------------------------------------------------------------
; Set LVS_EX_DOUBLEBUFFER (0x010000) style to avoid drawing issues.
SendMessage, 0x1036, 0x010000, 0x010000, , % "ahk_id " . HWND ; LVM_SETEXTENDEDLISTVIEWSTYLE
; Get the default colors
SendMessage, 0x1025, 0, 0, , % "ahk_id " . HWND ; LVM_GETTEXTBKCOLOR
This.BkClr := ErrorLevel
SendMessage, 0x1023, 0, 0, , % "ahk_id " . HWND ; LVM_GETTEXTCOLOR
This.TxClr := ErrorLevel
; Get the header control
SendMessage, 0x101F, 0, 0, , % "ahk_id " . HWND ; LVM_GETHEADER
This.Header := ErrorLevel
; Set other properties
This.HWND := HWND
This.IsStatic := !!StaticMode
This.AltCols := False
This.AltRows := False
This.NoSort(!!NoSort)
This.NoSizing(!!NoSizing)
This.OnMessage()
This.Critical := "Off"
This.Attached[HWND] := True
}
; ===================================================================================================================
__Delete() {
This.Attached.Remove(HWND, "")
This.OnMessage(False)
WinSet, Redraw, , % "ahk_id " . This.HWND
}
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; PUBLIC METHODS ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ===================================================================================================================
; Clear() Clears all row and cell colors.
; Parameters: AltRows - Reset alternate row coloring (True / False)
; Default: False
; AltCols - Reset alternate column coloring (True / False)
; Default: False
; Return Value: Always True.
; ===================================================================================================================
Clear(AltRows := False, AltCols := False) {
If (AltCols)
This.AltCols := False
If (AltRows)
This.AltRows := False
This.Remove("Rows")
This.Remove("Cells")
Return True
}
; ===================================================================================================================
; AlternateRows() Sets background and/or text color for even row numbers.
; Parameters: BkColor - Background color as RGB color integer (e.g. 0xFF0000 = red) or HTML color name.
; Default: Empty -> default background color
; TxColor - Text color as RGB color integer (e.g. 0xFF0000 = red) or HTML color name.
; Default: Empty -> default text color
; Return Value: True on success, otherwise false.
; ===================================================================================================================
AlternateRows(BkColor := "", TxColor := "") {
If !(This.HWND)
Return False
This.AltRows := False
If (BkColor = "") && (TxColor = "")
Return True
BkBGR := This.BGR(BkColor)
TxBGR := This.BGR(TxColor)
If (BkBGR = "") && (TxBGR = "")
Return False
This["ARB"] := (BkBGR <> "") ? BkBGR : This.BkClr
This["ART"] := (TxBGR <> "") ? TxBGR : This.TxClr
This.AltRows := True
Return True
}
; ===================================================================================================================
; AlternateCols() Sets background and/or text color for even column numbers.
; Parameters: BkColor - Background color as RGB color integer (e.g. 0xFF0000 = red) or HTML color name.
; Default: Empty -> default background color
; TxColor - Text color as RGB color integer (e.g. 0xFF0000 = red) or HTML color name.
; Default: Empty -> default text color
; Return Value: True on success, otherwise false.
; ===================================================================================================================
AlternateCols(BkColor := "", TxColor := "") {
If !(This.HWND)
Return False
This.AltCols := False
If (BkColor = "") && (TxColor = "")
Return True
BkBGR := This.BGR(BkColor)
TxBGR := This.BGR(TxColor)
If (BkBGR = "") && (TxBGR = "")
Return False
This["ACB"] := (BkBGR <> "") ? BkBGR : This.BkClr
This["ACT"] := (TxBGR <> "") ? TxBGR : This.TxClr
This.AltCols := True
Return True
}
; ===================================================================================================================
; SelectionColors() Sets background and/or text color for selected rows.
; Parameters: BkColor - Background color as RGB color integer (e.g. 0xFF0000 = red) or HTML color name.
; Default: Empty -> default selected background color
; TxColor - Text color as RGB color integer (e.g. 0xFF0000 = red) or HTML color name.
; Default: Empty -> default selected text color
; Return Value: True on success, otherwise false.
; ===================================================================================================================
SelectionColors(BkColor := "", TxColor := "") {
If !(This.HWND)
Return False
This.SelColors := False
If (BkColor = "") && (TxColor = "")
Return True
BkBGR := This.BGR(BkColor)
TxBGR := This.BGR(TxColor)
If (BkBGR = "") && (TxBGR = "")
Return False
This["SELB"] := BkBGR
This["SELT"] := TxBGR
This.SelColors := True
Return True
}
; ===================================================================================================================
; Row() Sets background and/or text color for the specified row.
; Parameters: Row - Row number
; Optional ------------------------------------------------------------------------------------------
; BkColor - Background color as RGB color integer (e.g. 0xFF0000 = red) or HTML color name.
; Default: Empty -> default background color
; TxColor - Text color as RGB color integer (e.g. 0xFF0000 = red) or HTML color name.
; Default: Empty -> default text color
; Return Value: True on success, otherwise false.
; ===================================================================================================================
Row(Row, BkColor := "", TxColor := "") {
If !(This.HWND)
Return False
If This.IsStatic
Row := This.MapIndexToID(Row)
This["Rows"].Remove(Row, "")
If (BkColor = "") && (TxColor = "")
Return True
BkBGR := This.BGR(BkColor)
TxBGR := This.BGR(TxColor)
If (BkBGR = "") && (TxBGR = "")
Return False
This["Rows", Row, "B"] := (BkBGR <> "") ? BkBGR : This.BkClr
This["Rows", Row, "T"] := (TxBGR <> "") ? TxBGR : This.TxClr
Return True
}
; ===================================================================================================================
; Cell() Sets background and/or text color for the specified cell.
; Parameters: Row - Row number
; Col - Column number
; Optional ------------------------------------------------------------------------------------------
; BkColor - Background color as RGB color integer (e.g. 0xFF0000 = red) or HTML color name.
; Default: Empty -> row's background color
; TxColor - Text color as RGB color integer (e.g. 0xFF0000 = red) or HTML color name.
; Default: Empty -> row's text color
; Return Value: True on success, otherwise false.
; ===================================================================================================================
Cell(Row, Col, BkColor := "", TxColor := "") {
If !(This.HWND)
Return False
If This.IsStatic
Row := This.MapIndexToID(Row)
This["Cells", Row].Remove(Col, "")
If (BkColor = "") && (TxColor = "")
Return True
BkBGR := This.BGR(BkColor)
TxBGR := This.BGR(TxColor)
If (BkBGR = "") && (TxBGR = "")
Return False
If (BkBGR <> "")
This["Cells", Row, Col, "B"] := BkBGR
If (TxBGR <> "")
This["Cells", Row, Col, "T"] := TxBGR
Return True
}
; ===================================================================================================================
; NoSort() Prevents/allows sorting by click on a header item for this ListView.
; Parameters: Apply - True/False
; Default: True
; Return Value: True on success, otherwise false.
; ===================================================================================================================
NoSort(Apply := True) {
If !(This.HWND)
Return False
If (Apply)
This.SortColumns := False
Else
This.SortColumns := True
Return True
}
; ===================================================================================================================
; NoSizing() Prevents/allows resizing of columns for this ListView.
; Parameters: Apply - True/False
; Default: True
; Return Value: True on success, otherwise false.
; ===================================================================================================================
NoSizing(Apply := True) {
Static OSVersion := DllCall("GetVersion", "UChar")
If !(This.Header)
Return False
If (Apply) {
If (OSVersion > 5)
Control, Style, +0x0800, , % "ahk_id " . This.Header ; HDS_NOSIZING = 0x0800
This.ResizeColumns := False
}
Else {
If (OSVersion > 5)
Control, Style, -0x0800, , % "ahk_id " . This.Header ; HDS_NOSIZING
This.ResizeColumns := True
}
Return True
}
; ===================================================================================================================
; OnMessage() Adds/removes a message handler for WM_NOTIFY messages for this ListView.
; Parameters: Apply - True/False
; Default: True
; Return Value: Always True
; ===================================================================================================================
OnMessage(Apply := True) {
If (Apply) && !This.HasKey("OnMessageFunc") {
This.OnMessageFunc := ObjBindMethod(This, "On_WM_Notify")
OnMessage(0x004E, This.OnMessageFunc) ; add the WM_NOTIFY message handler
}
Else If !(Apply) && This.HasKey("OnMessageFunc") {
OnMessage(0x004E, This.OnMessageFunc, 0) ; remove the WM_NOTIFY message handler
This.OnMessageFunc := ""
This.Remove("OnMessageFunc")
}
WinSet, Redraw, , % "ahk_id " . This.HWND
Return True
}
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; PRIVATE PROPERTIES +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Static Attached := {}
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; PRIVATE METHODS +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
On_WM_NOTIFY(W, L, M, H) {
; Notifications: NM_CUSTOMDRAW = -12, LVN_COLUMNCLICK = -108, HDN_BEGINTRACKA = -306, HDN_BEGINTRACKW = -326
Critical, % This.Critical
If ((HCTL := NumGet(L + 0, 0, "UPtr")) = This.HWND) || (HCTL = This.Header) {
Code := NumGet(L + (A_PtrSize * 2), 0, "Int")
If (Code = -12)
Return This.NM_CUSTOMDRAW(This.HWND, L)
If !This.SortColumns && (Code = -108)
Return 0
If !This.ResizeColumns && ((Code = -306) || (Code = -326))
Return True
}
}
; -------------------------------------------------------------------------------------------------------------------
NM_CUSTOMDRAW(H, L) {
; Return values: 0x00 (CDRF_DODEFAULT), 0x20 (CDRF_NOTIFYITEMDRAW / CDRF_NOTIFYSUBITEMDRAW)
Static SizeNMHDR := A_PtrSize * 3 ; Size of NMHDR structure
Static SizeNCD := SizeNMHDR + 16 + (A_PtrSize * 5) ; Size of NMCUSTOMDRAW structure
Static OffItem := SizeNMHDR + 16 + (A_PtrSize * 2) ; Offset of dwItemSpec (NMCUSTOMDRAW)
Static OffItemState := OffItem + A_PtrSize ; Offset of uItemState (NMCUSTOMDRAW)
Static OffCT := SizeNCD ; Offset of clrText (NMLVCUSTOMDRAW)
Static OffCB := OffCT + 4 ; Offset of clrTextBk (NMLVCUSTOMDRAW)
Static OffSubItem := OffCB + 4 ; Offset of iSubItem (NMLVCUSTOMDRAW)
; ----------------------------------------------------------------------------------------------------------------
DrawStage := NumGet(L + SizeNMHDR, 0, "UInt")
, Row := NumGet(L + OffItem, "UPtr") + 1
, Col := NumGet(L + OffSubItem, "Int") + 1
, Item := Row - 1
If This.IsStatic
Row := This.MapIndexToID(Row)
; CDDS_SUBITEMPREPAINT = 0x030001 --------------------------------------------------------------------------------
If (DrawStage = 0x030001) {
UseAltCol := !(Col & 1) && (This.AltCols)
, ColColors := This["Cells", Row, Col]
, ColB := (ColColors.B <> "") ? ColColors.B : UseAltCol ? This.ACB : This.RowB
, ColT := (ColColors.T <> "") ? ColColors.T : UseAltCol ? This.ACT : This.RowT
, NumPut(ColT, L + OffCT, "UInt"), NumPut(ColB, L + OffCB, "UInt")
Return (!This.AltCols && !This.HasKey(Row) && (Col > This["Cells", Row].MaxIndex())) ? 0x00 : 0x20
}
; CDDS_ITEMPREPAINT = 0x010001 -----------------------------------------------------------------------------------
If (DrawStage = 0x010001) {
; LVM_GETITEMSTATE = 0x102C, LVIS_SELECTED = 0x0002
If (This.SelColors) && DllCall("SendMessage", "Ptr", H, "UInt", 0x102C, "Ptr", Item, "Ptr", 0x0002, "UInt") {
; Remove the CDIS_SELECTED (0x0001) and CDIS_FOCUS (0x0010) states from uItemState and set the colors.
NumPut(NumGet(L + OffItemState, "UInt") & ~0x0011, L + OffItemState, "UInt")
If (This.SELB <> "")
NumPut(This.SELB, L + OffCB, "UInt")
If (This.SELT <> "")
NumPut(This.SELT, L + OffCT, "UInt")
Return 0x02 ; CDRF_NEWFONT
}
UseAltRow := (Item & 1) && (This.AltRows)
, RowColors := This["Rows", Row]
, This.RowB := RowColors ? RowColors.B : UseAltRow ? This.ARB : This.BkClr
, This.RowT := RowColors ? RowColors.T : UseAltRow ? This.ART : This.TxClr
If (This.AltCols || This["Cells"].HasKey(Row))
Return 0x20
NumPut(This.RowT, L + OffCT, "UInt"), NumPut(This.RowB, L + OffCB, "UInt")
Return 0x00
}
; CDDS_PREPAINT = 0x000001 ---------------------------------------------------------------------------------------
Return (DrawStage = 0x000001) ? 0x20 : 0x00
}
; -------------------------------------------------------------------------------------------------------------------
MapIndexToID(Row) { ; provides the unique internal ID of the given row number
SendMessage, 0x10B4, % (Row - 1), 0, , % "ahk_id " . This.HWND ; LVM_MAPINDEXTOID
Return ErrorLevel
}
; -------------------------------------------------------------------------------------------------------------------
BGR(Color, Default := "") { ; converts colors to BGR
Static Integer := "Integer" ; v2
; HTML Colors (BGR)
Static HTML := {AQUA: 0xFFFF00, BLACK: 0x000000, BLUE: 0xFF0000, FUCHSIA: 0xFF00FF, GRAY: 0x808080, GREEN: 0x008000
, LIME: 0x00FF00, MAROON: 0x000080, NAVY: 0x800000, OLIVE: 0x008080, PURPLE: 0x800080, RED: 0x0000FF
, SILVER: 0xC0C0C0, TEAL: 0x808000, WHITE: 0xFFFFFF, YELLOW: 0x00FFFF}
If Color Is Integer
Return ((Color >> 16) & 0xFF) | (Color & 0x00FF00) | ((Color & 0xFF) << 16)
Return (HTML.HasKey(Color) ? HTML[Color] : Default)
}
}
Re: Whats a better way to get which column was double-clicked in a gui listview?
Hi,
Is it possible to select more than one column while holding down the ctrl key?
Is it possible to select more than one column while holding down the ctrl key?
Re: Whats a better way to get which column was double-clicked in a gui listview?
So cool! (well, I can't test/use it ATM bc iOS doesn’t support AHK ) Thx a lot anywayWith some effort, I managed to apply the @just me's LV_Colors class to get a more contrasty selection:
-
- Posts: 4565
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: Whats a better way to get which column was double-clicked in a gui listview?
Yep, try this:
Code: Select all
SetBatchLines, -1
Gui, Add, ListView, w350 hwndhLV NoSort Grid R15, Col 1|Col 2|Col 3|Col 4
SelCol := new LV_SelectColumn(hLV)
Loop 15
LV_Add("", "Field 1-" . A_Index, "Field 2-" . A_Index, "Field 3-" . A_Index, "Field 4-" . A_Index)
Loop, % LV_GetCount("Column")
LV_ModifyCol(A_Index, 80)
Gui, Show,, Press F1 to get selected columns
Return
$F1:: ; get selected columns
selected := ""
selArr := SelCol.GetSelectedColumns()
for k, v in selArr
selected .= (selected ? ", " : "") . v
MsgBox, % "selected columns: " . selected
Return
; select first column
$F2:: SelCol.SelectColumn(1)
; deselect first column
$F3:: SelCol.SelectColumn(1, false)
; toggle first column state
$F4:: SelCol.SelectColumn(1, !SelCol.GetColumnState(1))
GuiClose() {
ExitApp
}
class LV_SelectColumn
{
__New(hLV, selBackColor := 0x3399FF, selTextColor := 0xFFFFFF) {
this.Info := {hLV: hLV, backColor: selBackColor, textColor: selTextColor, selColoumns: {}}
this.OnNotify := ObjBindMethod(this.Events, "WM_NOTIFY", this.Info)
OnMessage(0x004E, this.OnNotify)
this.Info.LV := new LV_Colors(hLV,, false, false)
}
SelectColumn(n, select := true) {
this.Info.selColoumns[n] := !select
this.Events.ToggleColumnSelState(this.Info, n)
WinSet, Redraw,, % "ahk_id" . this.Info.hLV
}
GetColumnState(n) {
Return !!this.Info.selColoumns[n]
}
GetSelectedColumns() {
selected := []
for k, v in this.Info.selColoumns
(v && selected.Push(k))
Return selected
}
class Events
{
WM_NOTIFY(Info, wp, lp) {
static LVN_COLUMNCLICK := -108, NM_CLICK := -2
hCtrl := NumGet(lp + 0)
if !(hCtrl = Info.hLV)
Return
notify := NumGet(lp + A_PtrSize*2, "Int")
Switch notify {
case NM_CLICK : this.OnRowClick(Info)
case LVN_COLUMNCLICK : this.OnColumnClick(Info, lp)
}
}
OnRowClick(Info) {
isSelected := false
for k, v in Info.selColoumns {
if v {
isSelected := true
Info.selColoumns[k] := false
}
}
if isSelected {
Info.LV.Clear()
WinSet, Redraw,, % "ahk_id" . Info.hLV
}
}
OnColumnClick(Info, lp) {
Gui, %A_Gui%: ListView, % Info.hLV
clickedColumn := NumGet(lp + A_PtrSize*3 + 4, "Int") + 1
while selectedRow := LV_GetNext()
LV_Modify(selectedRow, "-Select")
this[ GetKeyState("Ctrl", "P") ? "ToggleColumnSelState" : "SelectSingleColumn" ](Info, clickedColumn)
WinSet, Redraw,, % "ahk_id" . Info.hLV
}
SelectSingleColumn(Info, column) {
Info.LV.Clear()
for k in Info.selColoumns
Info.selColoumns[k] := false
this.ToggleColumnSelState(Info, column)
}
ToggleColumnSelState(Info, column) {
static LVM_GETITEMCOUNT := 0x1004
isSelected := Info.selColoumns[column]
Info.selColoumns[column] := !isSelected
SendMessage, LVM_GETITEMCOUNT,,,, % "ahk_id" . Info.hLV
Loop % ErrorLevel
Info.LV.Cell(A_Index, column, isSelected ? "" : Info.backColor, isSelected ? "" : Info.textColor)
}
}
__Delete() {
this.Info.LV.Clear()
OnMessage(0x004E, this.OnNotify, 0)
WinSet, RedRaw,, % "ahk_id" . this.Info.hLV
this.Info := ""
}
}
Class LV_Colors {
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; META FUNCTIONS ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ===================================================================================================================
; __New() Create a new LV_Colors instance for the given ListView
; Parameters: HWND - ListView's HWND.
; Optional ------------------------------------------------------------------------------------------
; StaticMode - Static color assignment, i.e. the colors will be assigned permanently to the row
; contents rather than to the row number.
; Values: True/False
; Default: False
; NoSort - Prevent sorting by click on a header item.
; Values: True/False
; Default: True
; NoSizing - Prevent resizing of columns.
; Values: True/False
; Default: True
; ===================================================================================================================
__New(HWND, StaticMode := False, NoSort := True, NoSizing := True) {
If (This.Base.Base.__Class) ; do not instantiate instances
Return False
If This.Attached[HWND] ; HWND is already attached
Return False
If !DllCall("IsWindow", "Ptr", HWND) ; invalid HWND
Return False
VarSetCapacity(Class, 512, 0)
DllCall("GetClassName", "Ptr", HWND, "Str", Class, "Int", 256)
If (Class <> "SysListView32") ; HWND doesn't belong to a ListView
Return False
; ----------------------------------------------------------------------------------------------------------------
; Set LVS_EX_DOUBLEBUFFER (0x010000) style to avoid drawing issues.
SendMessage, 0x1036, 0x010000, 0x010000, , % "ahk_id " . HWND ; LVM_SETEXTENDEDLISTVIEWSTYLE
; Get the default colors
SendMessage, 0x1025, 0, 0, , % "ahk_id " . HWND ; LVM_GETTEXTBKCOLOR
This.BkClr := ErrorLevel
SendMessage, 0x1023, 0, 0, , % "ahk_id " . HWND ; LVM_GETTEXTCOLOR
This.TxClr := ErrorLevel
; Get the header control
SendMessage, 0x101F, 0, 0, , % "ahk_id " . HWND ; LVM_GETHEADER
This.Header := ErrorLevel
; Set other properties
This.HWND := HWND
This.IsStatic := !!StaticMode
This.AltCols := False
This.AltRows := False
This.NoSort(!!NoSort)
This.NoSizing(!!NoSizing)
This.OnMessage()
This.Critical := "Off"
This.Attached[HWND] := True
}
; ===================================================================================================================
__Delete() {
This.Attached.Remove(HWND, "")
This.OnMessage(False)
WinSet, Redraw, , % "ahk_id " . This.HWND
}
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; PUBLIC METHODS ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ===================================================================================================================
; Clear() Clears all row and cell colors.
; Parameters: AltRows - Reset alternate row coloring (True / False)
; Default: False
; AltCols - Reset alternate column coloring (True / False)
; Default: False
; Return Value: Always True.
; ===================================================================================================================
Clear(AltRows := False, AltCols := False) {
If (AltCols)
This.AltCols := False
If (AltRows)
This.AltRows := False
This.Remove("Rows")
This.Remove("Cells")
Return True
}
; ===================================================================================================================
; AlternateRows() Sets background and/or text color for even row numbers.
; Parameters: BkColor - Background color as RGB color integer (e.g. 0xFF0000 = red) or HTML color name.
; Default: Empty -> default background color
; TxColor - Text color as RGB color integer (e.g. 0xFF0000 = red) or HTML color name.
; Default: Empty -> default text color
; Return Value: True on success, otherwise false.
; ===================================================================================================================
AlternateRows(BkColor := "", TxColor := "") {
If !(This.HWND)
Return False
This.AltRows := False
If (BkColor = "") && (TxColor = "")
Return True
BkBGR := This.BGR(BkColor)
TxBGR := This.BGR(TxColor)
If (BkBGR = "") && (TxBGR = "")
Return False
This["ARB"] := (BkBGR <> "") ? BkBGR : This.BkClr
This["ART"] := (TxBGR <> "") ? TxBGR : This.TxClr
This.AltRows := True
Return True
}
; ===================================================================================================================
; AlternateCols() Sets background and/or text color for even column numbers.
; Parameters: BkColor - Background color as RGB color integer (e.g. 0xFF0000 = red) or HTML color name.
; Default: Empty -> default background color
; TxColor - Text color as RGB color integer (e.g. 0xFF0000 = red) or HTML color name.
; Default: Empty -> default text color
; Return Value: True on success, otherwise false.
; ===================================================================================================================
AlternateCols(BkColor := "", TxColor := "") {
If !(This.HWND)
Return False
This.AltCols := False
If (BkColor = "") && (TxColor = "")
Return True
BkBGR := This.BGR(BkColor)
TxBGR := This.BGR(TxColor)
If (BkBGR = "") && (TxBGR = "")
Return False
This["ACB"] := (BkBGR <> "") ? BkBGR : This.BkClr
This["ACT"] := (TxBGR <> "") ? TxBGR : This.TxClr
This.AltCols := True
Return True
}
; ===================================================================================================================
; SelectionColors() Sets background and/or text color for selected rows.
; Parameters: BkColor - Background color as RGB color integer (e.g. 0xFF0000 = red) or HTML color name.
; Default: Empty -> default selected background color
; TxColor - Text color as RGB color integer (e.g. 0xFF0000 = red) or HTML color name.
; Default: Empty -> default selected text color
; Return Value: True on success, otherwise false.
; ===================================================================================================================
SelectionColors(BkColor := "", TxColor := "") {
If !(This.HWND)
Return False
This.SelColors := False
If (BkColor = "") && (TxColor = "")
Return True
BkBGR := This.BGR(BkColor)
TxBGR := This.BGR(TxColor)
If (BkBGR = "") && (TxBGR = "")
Return False
This["SELB"] := BkBGR
This["SELT"] := TxBGR
This.SelColors := True
Return True
}
; ===================================================================================================================
; Row() Sets background and/or text color for the specified row.
; Parameters: Row - Row number
; Optional ------------------------------------------------------------------------------------------
; BkColor - Background color as RGB color integer (e.g. 0xFF0000 = red) or HTML color name.
; Default: Empty -> default background color
; TxColor - Text color as RGB color integer (e.g. 0xFF0000 = red) or HTML color name.
; Default: Empty -> default text color
; Return Value: True on success, otherwise false.
; ===================================================================================================================
Row(Row, BkColor := "", TxColor := "") {
If !(This.HWND)
Return False
If This.IsStatic
Row := This.MapIndexToID(Row)
This["Rows"].Remove(Row, "")
If (BkColor = "") && (TxColor = "")
Return True
BkBGR := This.BGR(BkColor)
TxBGR := This.BGR(TxColor)
If (BkBGR = "") && (TxBGR = "")
Return False
This["Rows", Row, "B"] := (BkBGR <> "") ? BkBGR : This.BkClr
This["Rows", Row, "T"] := (TxBGR <> "") ? TxBGR : This.TxClr
Return True
}
; ===================================================================================================================
; Cell() Sets background and/or text color for the specified cell.
; Parameters: Row - Row number
; Col - Column number
; Optional ------------------------------------------------------------------------------------------
; BkColor - Background color as RGB color integer (e.g. 0xFF0000 = red) or HTML color name.
; Default: Empty -> row's background color
; TxColor - Text color as RGB color integer (e.g. 0xFF0000 = red) or HTML color name.
; Default: Empty -> row's text color
; Return Value: True on success, otherwise false.
; ===================================================================================================================
Cell(Row, Col, BkColor := "", TxColor := "") {
If !(This.HWND)
Return False
If This.IsStatic
Row := This.MapIndexToID(Row)
This["Cells", Row].Remove(Col, "")
If (BkColor = "") && (TxColor = "")
Return True
BkBGR := This.BGR(BkColor)
TxBGR := This.BGR(TxColor)
If (BkBGR = "") && (TxBGR = "")
Return False
If (BkBGR <> "")
This["Cells", Row, Col, "B"] := BkBGR
If (TxBGR <> "")
This["Cells", Row, Col, "T"] := TxBGR
Return True
}
; ===================================================================================================================
; NoSort() Prevents/allows sorting by click on a header item for this ListView.
; Parameters: Apply - True/False
; Default: True
; Return Value: True on success, otherwise false.
; ===================================================================================================================
NoSort(Apply := True) {
If !(This.HWND)
Return False
If (Apply)
This.SortColumns := False
Else
This.SortColumns := True
Return True
}
; ===================================================================================================================
; NoSizing() Prevents/allows resizing of columns for this ListView.
; Parameters: Apply - True/False
; Default: True
; Return Value: True on success, otherwise false.
; ===================================================================================================================
NoSizing(Apply := True) {
Static OSVersion := DllCall("GetVersion", "UChar")
If !(This.Header)
Return False
If (Apply) {
If (OSVersion > 5)
Control, Style, +0x0800, , % "ahk_id " . This.Header ; HDS_NOSIZING = 0x0800
This.ResizeColumns := False
}
Else {
If (OSVersion > 5)
Control, Style, -0x0800, , % "ahk_id " . This.Header ; HDS_NOSIZING
This.ResizeColumns := True
}
Return True
}
; ===================================================================================================================
; OnMessage() Adds/removes a message handler for WM_NOTIFY messages for this ListView.
; Parameters: Apply - True/False
; Default: True
; Return Value: Always True
; ===================================================================================================================
OnMessage(Apply := True) {
If (Apply) && !This.HasKey("OnMessageFunc") {
This.OnMessageFunc := ObjBindMethod(This, "On_WM_Notify")
OnMessage(0x004E, This.OnMessageFunc) ; add the WM_NOTIFY message handler
}
Else If !(Apply) && This.HasKey("OnMessageFunc") {
OnMessage(0x004E, This.OnMessageFunc, 0) ; remove the WM_NOTIFY message handler
This.OnMessageFunc := ""
This.Remove("OnMessageFunc")
}
WinSet, Redraw, , % "ahk_id " . This.HWND
Return True
}
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; PRIVATE PROPERTIES +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Static Attached := {}
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; PRIVATE METHODS +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
On_WM_NOTIFY(W, L, M, H) {
; Notifications: NM_CUSTOMDRAW = -12, LVN_COLUMNCLICK = -108, HDN_BEGINTRACKA = -306, HDN_BEGINTRACKW = -326
Critical, % This.Critical
If ((HCTL := NumGet(L + 0, 0, "UPtr")) = This.HWND) || (HCTL = This.Header) {
Code := NumGet(L + (A_PtrSize * 2), 0, "Int")
If (Code = -12)
Return This.NM_CUSTOMDRAW(This.HWND, L)
If !This.SortColumns && (Code = -108)
Return 0
If !This.ResizeColumns && ((Code = -306) || (Code = -326))
Return True
}
}
; -------------------------------------------------------------------------------------------------------------------
NM_CUSTOMDRAW(H, L) {
; Return values: 0x00 (CDRF_DODEFAULT), 0x20 (CDRF_NOTIFYITEMDRAW / CDRF_NOTIFYSUBITEMDRAW)
Static SizeNMHDR := A_PtrSize * 3 ; Size of NMHDR structure
Static SizeNCD := SizeNMHDR + 16 + (A_PtrSize * 5) ; Size of NMCUSTOMDRAW structure
Static OffItem := SizeNMHDR + 16 + (A_PtrSize * 2) ; Offset of dwItemSpec (NMCUSTOMDRAW)
Static OffItemState := OffItem + A_PtrSize ; Offset of uItemState (NMCUSTOMDRAW)
Static OffCT := SizeNCD ; Offset of clrText (NMLVCUSTOMDRAW)
Static OffCB := OffCT + 4 ; Offset of clrTextBk (NMLVCUSTOMDRAW)
Static OffSubItem := OffCB + 4 ; Offset of iSubItem (NMLVCUSTOMDRAW)
; ----------------------------------------------------------------------------------------------------------------
DrawStage := NumGet(L + SizeNMHDR, 0, "UInt")
, Row := NumGet(L + OffItem, "UPtr") + 1
, Col := NumGet(L + OffSubItem, "Int") + 1
, Item := Row - 1
If This.IsStatic
Row := This.MapIndexToID(Row)
; CDDS_SUBITEMPREPAINT = 0x030001 --------------------------------------------------------------------------------
If (DrawStage = 0x030001) {
UseAltCol := !(Col & 1) && (This.AltCols)
, ColColors := This["Cells", Row, Col]
, ColB := (ColColors.B <> "") ? ColColors.B : UseAltCol ? This.ACB : This.RowB
, ColT := (ColColors.T <> "") ? ColColors.T : UseAltCol ? This.ACT : This.RowT
, NumPut(ColT, L + OffCT, "UInt"), NumPut(ColB, L + OffCB, "UInt")
Return (!This.AltCols && !This.HasKey(Row) && (Col > This["Cells", Row].MaxIndex())) ? 0x00 : 0x20
}
; CDDS_ITEMPREPAINT = 0x010001 -----------------------------------------------------------------------------------
If (DrawStage = 0x010001) {
; LVM_GETITEMSTATE = 0x102C, LVIS_SELECTED = 0x0002
If (This.SelColors) && DllCall("SendMessage", "Ptr", H, "UInt", 0x102C, "Ptr", Item, "Ptr", 0x0002, "UInt") {
; Remove the CDIS_SELECTED (0x0001) and CDIS_FOCUS (0x0010) states from uItemState and set the colors.
NumPut(NumGet(L + OffItemState, "UInt") & ~0x0011, L + OffItemState, "UInt")
If (This.SELB <> "")
NumPut(This.SELB, L + OffCB, "UInt")
If (This.SELT <> "")
NumPut(This.SELT, L + OffCT, "UInt")
Return 0x02 ; CDRF_NEWFONT
}
UseAltRow := (Item & 1) && (This.AltRows)
, RowColors := This["Rows", Row]
, This.RowB := RowColors ? RowColors.B : UseAltRow ? This.ARB : This.BkClr
, This.RowT := RowColors ? RowColors.T : UseAltRow ? This.ART : This.TxClr
If (This.AltCols || This["Cells"].HasKey(Row))
Return 0x20
NumPut(This.RowT, L + OffCT, "UInt"), NumPut(This.RowB, L + OffCB, "UInt")
Return 0x00
}
; CDDS_PREPAINT = 0x000001 ---------------------------------------------------------------------------------------
Return (DrawStage = 0x000001) ? 0x20 : 0x00
}
; -------------------------------------------------------------------------------------------------------------------
MapIndexToID(Row) { ; provides the unique internal ID of the given row number
SendMessage, 0x10B4, % (Row - 1), 0, , % "ahk_id " . This.HWND ; LVM_MAPINDEXTOID
Return ErrorLevel
}
; -------------------------------------------------------------------------------------------------------------------
BGR(Color, Default := "") { ; converts colors to BGR
Static Integer := "Integer" ; v2
; HTML Colors (BGR)
Static HTML := {AQUA: 0xFFFF00, BLACK: 0x000000, BLUE: 0xFF0000, FUCHSIA: 0xFF00FF, GRAY: 0x808080, GREEN: 0x008000
, LIME: 0x00FF00, MAROON: 0x000080, NAVY: 0x800000, OLIVE: 0x008080, PURPLE: 0x800080, RED: 0x0000FF
, SILVER: 0xC0C0C0, TEAL: 0x808000, WHITE: 0xFFFFFF, YELLOW: 0x00FFFF}
If Color Is Integer
Return ((Color >> 16) & 0xFF) | (Color & 0x00FF00) | ((Color & 0xFF) << 16)
Return (HTML.HasKey(Color) ? HTML[Color] : Default)
}
}
Last edited by teadrinker on 26 May 2022, 06:53, edited 2 times in total.
Who is online
Users browsing this forum: ByronicZero, Google [Bot], leothlon and 109 guests