Make ListView selection toggle individual selection Topic is solved

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
User avatar
WarlordAkamu67
Posts: 229
Joined: 21 Mar 2023, 06:52

Make ListView selection toggle individual selection

Post by WarlordAkamu67 » 13 May 2024, 06:15

Hello. I have a file deleter for old files. It displays the captured files and allows a deselection of files to be made. I would like to convert from a ListBox to a ListView, but I want the selection style of the ListBox. Adding +Multi to the ListBox makes it behave more like the ListView, which is the opposite of what I want.

The list box allowed me to toggle the selection of each line at a time, without the use of Shift or Control.

Is there a way to do this with the options or must a function be created for it?

ListBox:

Code: Select all

#Requires AutoHotkey v2.0

deleter := Gui("","File Deleter")
demoArray := ["File 1","File 2","File 3"]
button_DeleteFiles := deleter.Add("Button", "Default x25 y5 w70 h30", "Delete Files")
button_DeleteFiles.OnEvent("Click", delete_Old_Files.Bind())
edit_captured_Number := deleter.Add("Edit", "vcaptured_Number ReadOnly x100 y7 w375 h25", "This would be the directory.")
edit_LB_Box := deleter.Add("ListBox", "voutput_Box x25 y40 w450 h430 T1 8", demoArray)
edit_deletion_Count := deleter.Add("Edit", "vdeletion_Count ReadOnly center x25 y475 w450 h20", "Files deleted:")
deleter.OnEvent("Close", close_the_Deleter)
deleter.OnEvent("Escape", close_the_Deleter)
deleter.Show("xCenter yCenter w500 h500")

for (select_File in demoArray) {
  edit_LB_Box.Choose(select_File)
}
return

; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ;

; Function to delete captured files.
delete_Old_Files(*) {
	global
	subbed_GUI := deleter.Submit()
	try {
		for (file_to_Delete in subbed_GUI.output_Box) {
			MsgBox(file_to_Delete " would have been deleted.")
}
}
	return
}

; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ;

; If close button is hit on GUI.
; If escape key is hit on GUI.
close_the_Deleter(*) {
	deleter.Destroy()
	Exit()
}

; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ;
ListView:

Code: Select all

#Requires AutoHotkey v2.0

deleter := Gui("","File Deleter")
demoArray := ["File 1","File 2","File 3"]
button_DeleteFiles := deleter.Add("Button", "Default x25 y5 w70 h30", "Delete Files")
button_DeleteFiles.OnEvent("Click", delete_Old_Files.Bind())
edit_captured_Number := deleter.Add("Edit", "vcaptured_Number ReadOnly x100 y7 w375 h25", "This would be the directory.")
edit_LV_Box := deleter.Add("ListView", "+E0x8 +E0x4 +E0x3 x25 y40 w450 h430", ["File Name", "Creation Date"])
; edit_LV_Box.OnEvent("Click", lvSelectorSwap) <-- would be my fuction to mimic behavior.
edit_deletion_Count := deleter.Add("Edit", "vdeletion_Count ReadOnly center x25 y475 w450 h20", "Files deleted:")
deleter.OnEvent("Close", close_the_Deleter)
deleter.OnEvent("Escape", close_the_Deleter)
edit_LV_Box.ModifyCol(1, 300)
edit_LV_Box.Add("+Select","File 1","Created Now")
edit_LV_Box.Add("+Select","File 2","Created Now")
edit_LV_Box.Add("+Select","File 3","Created Now")
deleter.Show("xCenter yCenter w500 h500")
edit_LV_Box.Modify(0, "Select")
edit_LV_Box.Focus()
return

; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ;

; Function to delete captured files.
delete_Old_Files(*) {
	global
  RowNumber := 0
  Loop {
    RowNumber := edit_LV_Box.GetNext(RowNumber)
    if (!RowNumber) {
      break
}
    MsgBox(edit_LV_Box.GetText(RowNumber) " wouldve been deleted.")
}
  ExitApp()
	return
}

; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ;

; If close button is hit on GUI.
; If escape key is hit on GUI.
close_the_Deleter(*) {
	deleter.Destroy()
	Exit()
}

; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ;
Edit: removed RegWrite that wasn't suppose to be in the demo.
Last edited by WarlordAkamu67 on 21 May 2024, 10:01, edited 1 time in total.

User avatar
mikeyww
Posts: 27193
Joined: 09 Sep 2014, 18:38

Re: Make ListView selection toggle individual selection

Post by mikeyww » 13 May 2024, 07:49

Hello,

Have you looked at the Checked ListView option?

teadrinker
Posts: 4368
Joined: 29 Mar 2015, 09:41
Contact:

Re: Make ListView selection toggle individual selection  Topic is solved

Post by teadrinker » 13 May 2024, 12:19

Code: Select all

#Requires AutoHotkey v2

wnd := Gui()
lv := wnd.Add('ListView', 'r10 w400', ['Name','Size (KB)'])
Loop Files, A_MyDocuments . '\*.*' {
    lv.Add(, A_LoopFileName, A_LoopFileSizeKB)
}
lv.ModifyCol(1, 'AutoHdr')
lv.ModifyCol(2, 'AutoHdr Integer')
wnd.Show()

OnMessage(0x201, WM_LBUTTONDOWN)

WM_LBUTTONDOWN(wp, lp, msg, hwnd) {
    if hwnd == lv.hwnd {
        POINT := lp & 0xFFFF | lp >> 16 << 32
        Loop lv.GetCount() {
            i := A_Index
            SendMessage LVM_GETITEMRECT := 0x100E, i - 1, RECT := Buffer(16, 0), lv
            if DllCall('PtInRect', 'Ptr', RECT, 'Int64', POINT) {
                lv.Modify(i, (i == lv.GetNext(i - 1) ? '-' : '') . 'Select')
                return 1
            }
        }
    }
}

User avatar
WarlordAkamu67
Posts: 229
Joined: 21 Mar 2023, 06:52

Re: Make ListView selection toggle individual selection

Post by WarlordAkamu67 » 21 May 2024, 13:35

Thank you guys for your time. I did not want to go with checkboxes </3

This is what I ended up with:

Code: Select all

#Requires AutoHotkey v2.0

deleter := Gui("","File Deleter")
demoArray := ["File 1","File 2","File 3"]
button_DeleteFiles := deleter.Add("Button", "Default x25 y5 w70 h30", "Delete Files")
button_DeleteFiles.OnEvent("Click", delete_Old_Files.Bind())
edit_captured_Number := deleter.Add("Edit", "vcaptured_Number ReadOnly x100 y7 w375 h25", "This would be the directory.")
edit_LV_Box := deleter.Add("ListView", "+E0x8 +E0x4 +E0x3 x25 y40 w450 h430", ["File Name", "Creation Date"])
edit_deletion_Count := deleter.Add("Edit", "vdeletion_Count ReadOnly center x25 y475 w450 h20", "Files deleted:")
deleter.OnEvent("Close", close_the_Deleter)
deleter.OnEvent("Escape", close_the_Deleter)
edit_LV_Box.ModifyCol(1, 300)
edit_LV_Box.Add("+Select","File 1","Created Then")
edit_LV_Box.Add("+Select","File 2","Created Now")
edit_LV_Box.Add("+Select","File 3","Will Be Created")
deleter.Show("xCenter yCenter w500 h500")
edit_LV_Box.Modify(0, "Select")
edit_LV_Box.Focus()
OnMessage(0x201, WM_LBUTTONDOWN)
OnMessage(0x203, WM_LBUTTONDDOWN)
return

; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ;

; Function to delete captured files.
delete_Old_Files(*) {
	global
  RowNumber := 0
  Loop {
    RowNumber := edit_LV_Box.GetNext(RowNumber)
    if (!RowNumber) {
      break
}
    MsgBox(edit_LV_Box.GetText(RowNumber) " wouldve been deleted.")
}
  ExitApp()
	return
}

; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ;

; If close button is hit on GUI.
; If escape key is hit on GUI.
close_the_Deleter(*) {
	OnMessage(0x201, WM_LBUTTONDOWN, 0)
	OnMessage(0x203, WM_LBUTTONDDOWN, 0)
	deleter.Destroy()
	Exit()
}

; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ;

WM_LBUTTONDOWN(wp, lp, msg, hand) {
	global file_Selection_Array
	if (hand == edit_LV_Box.hwnd) {
		POINT := lp & 0xFFFF | lp >> 16 << 32
    Loop (edit_LV_Box.GetCount()) {
    	i := A_Index
      SendMessage(LVM_GETITEMRECT := 0x100E, i - 1,RECT := Buffer(16, 0), edit_LV_Box)
      if (DllCall('PtInRect', 'Ptr', RECT, 'Int64', POINT)) {
        edit_LV_Box.Modify(i, (i == edit_LV_Box.GetNext(i - 1) ? '-' : '') 'Select')
				edit_LV_Box.Focus()
        return 1
}
}
		edit_LV_Box.Focus()
		return(0)
}
}

; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ;

WM_LBUTTONDDOWN(wp, lp, msg, hand) {
	if (hand == edit_LV_Box.hwnd) {
		edit_LV_Box.Focus()
		return(0)
}
}

just me
Posts: 9530
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Make ListView selection toggle individual selection

Post by just me » Yesterday, 03:01

Hi,

one SendMessage might be enough (tested only briefly):

Code: Select all

WM_LBUTTONDOWN(WP, LP, Msg, Hwnd) {
   ; LVM_HITTEST (0x1012) => https://learn.microsoft.com/en-us/windows/win32/controls/lvm-hittest
   Static LVHTI := Buffer(24, 0)
   Local Item := 0
   If (Hwnd == edit_LV_Box.Hwnd) {
      NumPut("Int", LP & 0xFFFF, "Int", LP >> 16, LVHTI)
      If (Item := (SendMessage(0x1012, 0, LVHTI, edit_LV_Box.Hwnd) << 32 >> 32) + 1) { ; LVM_HITTEST
         edit_LV_Box.Modify(Item, (Item == edit_LV_Box.GetNext(Item - 1) ? "-" : "") . "Select")
      }
      edit_LV_Box.Focus()
      Return(0)
   }
}

User avatar
WarlordAkamu67
Posts: 229
Joined: 21 Mar 2023, 06:52

Re: Make ListView selection toggle individual selection

Post by WarlordAkamu67 » Yesterday, 05:44

I changed what I had a bit to behave better. Removed the second function for the double-click, idk why I didn't hook it up to the original function.
Thank you very much for providing more approaches and resources! With a few minutes of clicking around, it appears this behaves just as I want it to.

Code: Select all

#Requires AutoHotkey v2.0

deleter := Gui("","File Deleter")
demoArray := ["File 1","File 2","File 3"]
button_DeleteFiles := deleter.Add("Button", "Default x25 y5 w70 h30", "Delete Files")
button_DeleteFiles.OnEvent("Click", delete_Old_Files.Bind())
edit_captured_Number := deleter.Add("Edit", "vcaptured_Number ReadOnly x100 y7 w375 h25", "This would be the directory.")
edit_LV_Box := deleter.Add("ListView", "+E0x8 +E0x4 +E0x3 x25 y40 w450 h430", ["File Name", "Creation Date"])
edit_deletion_Count := deleter.Add("Edit", "vdeletion_Count ReadOnly center x25 y475 w450 h20", "Files deleted:")
deleter.OnEvent("Close", close_the_Deleter)
deleter.OnEvent("Escape", close_the_Deleter)
edit_LV_Box.ModifyCol(1, 300)
edit_LV_Box.Add("+Select","File 1","Created Then")
edit_LV_Box.Add("+Select","File 2","Created Now")
edit_LV_Box.Add("+Select","File 3","Will Be Created")
deleter.Show("xCenter yCenter w500 h500")
edit_LV_Box.Modify(0, "Select")
edit_LV_Box.Focus()
OnMessage(0x201, WM_LBUTTONDOWN)
OnMessage(0x203, WM_LBUTTONDOWN)
return

; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ;

; Function to delete captured files.
delete_Old_Files(*) {
	global
	RowNumber := 0
  Loop {
    RowNumber := edit_LV_Box.GetNext(RowNumber)
    if (!RowNumber) {
      break
}
    MsgBox(edit_LV_Box.GetText(RowNumber) " wouldve been deleted.")
}
  close_the_Deleter()
	return
}

; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ;

; If close button is hit on GUI.
; If escape key is hit on GUI.
close_the_Deleter(*) {
	OnMessage(0x201, WM_LBUTTONDOWN, 0)
	OnMessage(0x203, WM_LBUTTONDOWN, 0)
	deleter.Destroy()
	ExitApp()
}

; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ;
/*
; Option 1 - Thanks to @teadrinker
WM_LBUTTONDOWN(wp, lp, msg, hand) {
	if (hand == edit_LV_Box.hwnd) {
		POINT := lp & 0xFFFF | lp >> 16 << 32
    Loop (edit_LV_Box.GetCount()) {
    	i := A_Index
      SendMessage(LVM_GETITEMRECT := 0x100E, i - 1,RECT := Buffer(16, 0), edit_LV_Box)
      if (DllCall('PtInRect', 'Ptr', RECT, 'Int64', POINT)) {
        edit_LV_Box.Modify(i, (i == edit_LV_Box.GetNext(i - 1) ? '-' : '') 'Select')
				edit_LV_Box.Focus()
        return 1
}
}
		edit_LV_Box.Focus()
		return(0)
}
}
*/
; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ; ------------------------- ;

; Option 2 - Thanks to @just me
WM_LBUTTONDOWN(WP, LP, Msg, Hwnd) {
   ; LVM_HITTEST (0x1012) => https://learn.microsoft.com/en-us/windows/win32/controls/lvm-hittest
   Static LVHTI := Buffer(24, 0)
   Local Item := 0
   If (Hwnd == edit_LV_Box.Hwnd) {
      NumPut("Int", LP & 0xFFFF, "Int", LP >> 16, LVHTI)
      If (Item := (SendMessage(0x1012, 0, LVHTI, edit_LV_Box.Hwnd) << 32 >> 32) + 1) { ; LVM_HITTEST
         edit_LV_Box.Modify(Item, (Item == edit_LV_Box.GetNext(Item - 1) ? "-" : "") . "Select")
}
      edit_LV_Box.Focus()
      Return(0)
}
}

Post Reply

Return to “Ask for Help (v2)”