ListView time sorting problem Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
afe
Posts: 615
Joined: 06 Dec 2018, 04:36

ListView time sorting problem

16 Aug 2019, 04:21

Hello,

When a column is time, how to ensure that when clicking the ListView column header, the sorting is correct?
For example, the following example, the sorting is a bit confusing.

Code: Select all

Gui, Add, ListView, vl, Title
Gui, ListView, l
LV_Add(, "2019/8/13 17:01:52")
LV_Add(, "2019/8/13 1:54:50")
LV_Add(, "2019/8/14 20:31:43")
LV_Add(, "2019/8/9 23:41:52")
Gui, Show
return
Odlanir
Posts: 659
Joined: 20 Oct 2016, 08:20

Re: ListView time sorting problem  Topic is solved

16 Aug 2019, 07:37

The DateTime has to be converted into yyyy-MM-dd hh:mm:ss format if you want a correct sort on it.
Or, as a workaround, if your month, day, hour, minutes, seconds are never padded with 0 you can use:

Code: Select all

LV_ModifyCol(1,"Logical")
____________________________________________________________________________
Windows 10 Pro 64 bit - Autohotkey v1.1.30.01 64-bit Unicode
teadrinker
Posts: 4326
Joined: 29 Mar 2015, 09:41
Contact:

Re: ListView time sorting problem

16 Aug 2019, 09:08

Hi

You could use the custom sort function for ListView like this:

Code: Select all

Gui, Add, ListView, hwndhLV, Title
Gui, ListView, %hLV%
LV_Add(, "2019/08/13 07:01:52")
LV_Add(, "2019/8/13 1:54:50")
LV_Add(, "2019/8/14 20:31:43")
LV_Add(, "2019/8/9 23:41:52")
SendMessage, LVM_SORTITEMSEX := 0x1051, hLV, RegisterCallback("SortItems", "F"),, ahk_id %hLV%
Gui, Show
return

SortItems(a, b, hCtrl) {
   static pattern := "O)(\d+)/(\d+)/(\d+) (\d+):(\d+):(\d+)"
   Gui, ListView, %hCtrl%
   LV_GetText(textA, a + 1)
   LV_GetText(textB, b + 1)
   if RegExMatch(textA, pattern, _a) && RegExMatch(textB, pattern, _b) {
      Loop 6 {
         if (_a[A_Index] != _b[A_Index])
            Return _a[A_Index] > _b[A_Index] ? 1 : -1
      }
      Return 0
   }
}
Last edited by teadrinker on 16 Aug 2019, 10:00, edited 1 time in total.
teadrinker
Posts: 4326
Joined: 29 Mar 2015, 09:41
Contact:

Re: ListView time sorting problem

16 Aug 2019, 09:58

Better like this:

Code: Select all

Gui, Add, ListView, hwndhLV, Title
Gui, ListView, %hLV%
LV_Add(, "2019/08/13 07:01:52")
LV_Add(, "2019/8/13 1:54:50")
LV_Add(, "2019/8/14 20:31:43")
LV_Add(, "2019/8/9 23:41:52")

pSortItems := RegisterCallback("SortItems", "F")
info := {guiID: 1, lv: hLV, even: true, callback: pSortItems}
pInfo := Object(info)
eventHandler := Func("Events").Bind(pInfo)
GuiControl, +g, %hLV%, % eventHandler
SendMessage, LVM_SORTITEMSEX := 0x1051, pInfo, pSortItems,, ahk_id %hLV%
ObjRelease(pInfo)

Gui, Show
Return

GuiClose:
   ExitApp

Events(pInfo) {
   if (A_GuiEvent = "ColClick" && A_EventInfo = 1) {
      info := Object(pInfo)
      info.even := !info.even
      SendMessage, LVM_SORTITEMSEX := 0x1051, pInfo, info.callback,, % "ahk_id" . info.lv
   }
}

SortItems(a, b, pInfo) {
   static pattern := "O)(\d+)/(\d+)/(\d+) (\d+):(\d+):(\d+)"
   info := Object(pInfo)
   Gui, % info.guiID . ":ListView", % info.lv
   LV_GetText(textA, a + 1)
   LV_GetText(textB, b + 1)
   if RegExMatch(textA, pattern, _a) && RegExMatch(textB, pattern, _b) {
      Loop 6 {
         if (_a[A_Index] != _b[A_Index])
            Return _a[A_Index] > _b[A_Index] ? info.even*2 - 1 : 1 - info.even*2
      }
      Return 0
   }
}
Last edited by teadrinker on 17 Aug 2019, 05:10, edited 3 times in total.
afe
Posts: 615
Joined: 06 Dec 2018, 04:36

Re: ListView time sorting problem

16 Aug 2019, 09:59

Odlanir wrote:
16 Aug 2019, 07:37
The DateTime has to be converted into yyyy-MM-dd hh:mm:ss format if you want a correct sort on it.
Or, as a workaround, if your month, day, hour, minutes, seconds are never padded with 0 you can use:

Code: Select all

LV_ModifyCol(1,"Logical")
Great, this is exactly what I expected. Thank you very much!
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: ListView time sorting problem

17 Aug 2019, 02:15

@teadrinker, although unlikely significant in your examples, note that,
registercallback - memory wrote: Each use of RegisterCallback() allocates a small amount of memory (32 bytes plus system overhead). Since the OS frees this memory automatically when the script exits, any script that allocates a small, fixed number of callbacks does not have to explicitly free the memory. By contrast, a script that calls RegisterCallback() an indefinite/unlimited number of times should explicitly call the following on any unused callbacks:

Code: Select all

DllCall("GlobalFree", "Ptr", Address, "Ptr")
src.

Cheers.
teadrinker
Posts: 4326
Joined: 29 Mar 2015, 09:41
Contact:

Re: ListView time sorting problem

17 Aug 2019, 05:03

@Helgef, thanks, I'll bear this in mind. I changed my code, now RegisterCallback() is called once.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Joey5, RandomBoy, wpulford and 383 guests