Code: Select all
S := []
ToggleCheck(GuiCtrlObj, Item) {
If S[Item] {
LV.Modify(Item, '-Check')
S[Item] := False
} Else {
LV.Modify(Item, 'Check')
S[Item] := True
}
}
Code: Select all
S := []
ToggleCheck(GuiCtrlObj, Item) {
If S[Item] {
LV.Modify(Item, '-Check')
S[Item] := False
} Else {
LV.Modify(Item, 'Check')
S[Item] := True
}
}
Code: Select all
g := Gui("+AlwaysOnTop")
LV := g.AddListView("w200 r12 -readonly checked", ["name","items"])
loop 12
LV.Add(, "Name " A_Index,"Item " A_Index * 10)
LV.modifycol(1, 90)
LV.modifycol(2, 90)
LV.OnEvent("doubleclick", LVClick)
g.Show()
g.OnEvent("Close", (*) => ExitApp())
LVICE := LVICE_XXS(LV)
LVClick(LV, Item,*)
{
{
ItemState := SendMessage(0x102C, item - 1, 0xF000, LV)
if !((ItemState >> 12) - 1)
LV.Modify(item, "Check")
else
LV.Modify(item, "-Check")
}
}
; ======================================================================================================================
; Class LVICE_XXS - ListView in-cell editing for AHK v2 - minimal version (changed to edit with rightclick)
; ======================================================================================================================
Class LVICE_XXS {
; -------------------------------------------------------------------------------------------------------------------
__New(LV) {
If (Type(LV) != "Gui.ListView")
Throw Error("Class LVICE requires a GuiControl object of type Gui.ListView!")
This.RightClickFunc := ObjBindMethod(This, "RightClick")
This.BeginLabelEditFunc := ObjBindMethod(This, "BeginLabelEdit")
This.EndLabelEditFunc := ObjBindMethod(This, "EndLabelEdit")
This.CommandFunc := ObjBindMethod(This, "Command")
LV.OnNotify(-5, This.RightClickFunc)
This.LV := LV
This.HWND := LV.Hwnd
This.Changes := []
}
; -------------------------------------------------------------------------------------------------------------------
__Delete() {
If DllCall("IsWindow", "Ptr", This.HWND, "UInt")
This.LV.OnNotify(-3, This.RightClickFunc, 0)
This.RightClickFunc := ""
This.BeginLabelEditFunc := ""
This.EndLabelEditFunc := ""
This.CommandFunc := ""
}
; -------------------------------------------------------------------------------------------------------------------
; NM_DBLCLK (list view) notification
; -------------------------------------------------------------------------------------------------------------------
RightClick(LV, L) {
Critical -1
Item := NumGet(L + (A_PtrSize * 3), 0, "Int")
Subitem := NumGet(L + (A_PtrSize * 3), 4, "Int")
CellText := LV.GetText(Item + 1, SubItem + 1)
RC := Buffer(16, 0)
NumPut("Int", 0, "Int", SubItem, RC)
DllCall("SendMessage", "Ptr", LV.Hwnd, "UInt", 0x1038, "Ptr", Item, "Ptr", RC) ; LVM_GETSUBITEMRECT
This.CX := NumGet(RC, 0, "Int")
If (Subitem = 0)
This.CW := DllCall("SendMessage", "Ptr", LV.Hwnd, "UInt", 0x101D, "Ptr", 0, "Ptr", 0, "Int") ; LVM_GETCOLUMNWIDTH
Else
This.CW := NumGet(RC, 8, "Int") - This.CX
This.CY := NumGet(RC, 4, "Int")
This.CH := NumGet(RC, 12, "Int") - This.CY
This.Item := Item
This.Subitem := Subitem
This.LV.OnNotify(-175, This.BeginLabelEditFunc)
DllCall("PostMessage", "Ptr", LV.Hwnd, "UInt", 0x1076, "Ptr", Item, "Ptr", 0) ; LVM_EDITLABEL
}
; -------------------------------------------------------------------------------------------------------------------
; LVN_BEGINLABELEDIT notification
; -------------------------------------------------------------------------------------------------------------------
BeginLabelEdit(LV, L) {
Critical -1
This.HEDT := DllCall("SendMessage", "Ptr", LV.Hwnd, "UInt", 0x1018, "Ptr", 0, "Ptr", 0, "UPtr")
This.ItemText := LV.GetText(This.Item + 1, This.Subitem + 1)
DllCall("SendMessage", "Ptr", This.HEDT, "UInt", 0x00D3, "Ptr", 0x01, "Ptr", 4) ; EM_SETMARGINS, EC_LEFTMARGIN
DllCall("SendMessage", "Ptr", This.HEDT, "UInt", 0x000C, "Ptr", 0, "Ptr", StrPtr(This.ItemText)) ; WM_SETTEXT
DllCall("SetWindowPos", "Ptr", This.HEDT, "Ptr", 0, "Int", This.CX, "Int", This.CY,
"Int", This.CW, "Int", This.CH, "UInt", 0x04)
OnMessage(0x0111, This.CommandFunc, -1)
This.LV.OnNotify(-175, This.BeginLabelEditFunc, 0)
This.LV.OnNotify(-176, This.EndLabelEditFunc)
Return False
}
; -------------------------------------------------------------------------------------------------------------------
; LVN_ENDLABELEDIT notification
; -------------------------------------------------------------------------------------------------------------------
EndLabelEdit(LV, L) {
Static OffText := 16 + (A_PtrSize * 4)
Critical -1
This.LV.OnNotify(-176, This.EndLabelEditFunc, 0)
OnMessage(0x0111, This.CommandFunc, 0)
If (TxtPtr := NumGet(L, OffText, "UPtr")) {
ItemText := StrGet(TxtPtr)
If (ItemText != This.ItemText) {
LV.Modify(This.Item + 1, "Col" . (This.Subitem + 1), ItemText)
This.Changes.Push({Row: This.Item + 1, Col: This.Subitem + 1})
}
}
Return False
}
; -------------------------------------------------------------------------------------------------------------------
; WM_COMMAND notification
; -------------------------------------------------------------------------------------------------------------------
Command(W, L, M, H) {
Critical -1
If (L = This.HEDT) {
N := (W >> 16) & 0xFFFF
If (N = 0x0400) || (N = 0x0300) || (N = 0x0100) { ; EN_UPDATE | EN_CHANGE | EN_SETFOCUS
DllCall("SetWindowPos", "Ptr", L, "Ptr", 0, "Int", This.CX, "Int", This.CY,
"Int", This.CW, "Int", This.CH, "UInt", 0x04)
}
}
}
}
I was thinking is it possible to merge them into one by providing a parameter about whether the listview has checkboxes to the LVICE_XXS Class, but use two versions of the Class is a simple and easy way, anyway thank you very much.flyingDman wrote: ↑08 May 2024, 14:00I do not understand the question or the problem. You will determine in you script whether the Listiview has checkboxes or not. If it does have checkboxes you can use the modified Class so that a rightclick edits the cell and a doubleclick checks the box. If it does not have checkboxes you can use the original Class so that a doubleclick edits the cell. So depending on whether the listview has checkboxes or not, use one or the other version of the Class.
As a side note...
Code: Select all
This.EnterKeyFunc := ObjBindMethod(This, "EnterKey")
LV.OnNotify(NM_RETURN:=-4, This.EnterKeyFunc) ; EnterKey method is never called/triggered
EnterKey(LV, L)
{
MsgBox "[" L "]"
}
so perhaps:docs wrote: To detect when the user has pressed Enter while a ListView has focus, use a default button (which can be hidden if desired).
Code: Select all
g := Gui("+AlwaysOnTop")
LV := g.AddListView("w200 r12 -readonly checked", ["name","items"])
loop 12
LV.Add(, "Name " A_Index,"Item " A_Index * 10)
LV.modifycol(1, 90)
LV.modifycol(2, 90)
LV.OnEvent("doubleclick", LVClick)
g.add("button","hidden default x0 y0").OnEvent("Click", BTNClick)
g.Show()
g.OnEvent("Close", (*) => ExitApp())
LVICE := LVICE_XXS(LV)
LVClick(LV, Item,*)
{
ItemState := SendMessage(0x102C, item - 1, 0xF000, LV)
LV.modify(item, (ItemState >> 12) - 1 ? "-check" : "check")
}
BTNclick(*)
{
Item := LV.GetNext()
LVClick(LV, Item)
}