I just found out that listviews can have natural sorting:
<!-- m -->http://www.autohotke... ... tm#Logical<!-- m -->
I was looking for something else but found this instead
A DLL call to StrCmpLogicalW should be the solution to sorting other lists.
Natural sorting
Started by
Joolee
, Sep 16 2008 09:05 AM
21 replies to this topic
I was showed this thread and it is exactly what I was looking for. I tweaked Laszlo's solution from a few posts ago because I need to allow sorting regardless how many numbers are in the string - looking for performance feedback.
LogicalSort(x,y,offset) { static RegEx := "S)(\D*)(\d*)(.*)" Loop { RegExMatch(x, RegEx, x) RegExMatch(y, RegEx, y) if (x1 != y1) return x1 < y1 ? -1 : 1 if (x2 != y2) return x2 < y2 ? -1 : 1 if (x3 = "" || y3 = "") break x := x3 y := y3 } if (x3 != "") { ;x is "longer" return 1 } else if (y3 != "") { ;y is "longer" return -1 } else { ;equal - maintain original order (stable) return -offset } }
#17
-
Posted 03 March 2009 - 01:41 PM
As always, if you have any further questions, don't hesitate to ask.
Add OOP to your scripts via the Class Library. Check out my scripts.
Add OOP to your scripts via the Class Library. Check out my scripts.
how would:I just found out that listviews can have natural sorting:
http://www.autohotke... ... tm#Logical
A DLL call to StrCmpLogicalW should be the solution to sorting other lists.
int StrCmpLogicalW( LPCWSTR psz1, LPCWSTR psz2)http://msdn.microsof.../bb759947(VS.85).aspx
translate to AutoHotkey?
how would this work?(UPDATE: You could achieve logical sorting in a script by writing a sort algorithm and calling MultiByteToWideChar + StrCmpLogicalW via DllCall (requires Windows XP).
http://www.autohotke...ic9822-30.htmls
#18
-
Posted 25 August 2009 - 06:36 PM
Try:
String1=test String2=test String3=test1 String4=tesa String5=x Loop 5 VarSetCapacity(wideString%A_Index%, StrLen(String%A_Index%)*2+1,0) , DllCall("MultiByteToWideChar", "UInt",0, "UInt",0, "UInt",&String%A_Index%, "Int",-1, "UInt",&wideString%A_Index%, "Int",StrLen(String%A_Index%)+1) MsgBox % string1 " . " string2 ": " DllCall("Shlwapi.dll\StrCmpLogicalW","Uint",&wideString1,"UInt",&wideString2) MsgBox % string1 " . " string3 ": " DllCall("Shlwapi.dll\StrCmpLogicalW","Uint",&wideString1,"UInt",&wideString3) MsgBox % string1 " . " string4 ": " DllCall("Shlwapi.dll\StrCmpLogicalW","Uint",&wideString1,"UInt",&wideString4) MsgBox % string4 " . " string5 ": " DllCall("Shlwapi.dll\StrCmpLogicalW","Uint",&wideString4,"UInt",&wideString5)
#19
-
Posted 25 August 2009 - 07:50 PM
Here's a function that you can use with the built-in Sort command (or just pass two strings as parameters):
StrCmpLogical(str1, str2){ Loop, 2 MultiByteToWideChar(str%A_Index%) return DllCall("ShlWapi\StrCmpLogicalW", "UInt", &str1, "UInt", &str2) } MultiByteToWideChar(ByRef str){ ostr := str, size = 0 Loop, 2 { VarSetCapacity(str, size*2) size := DllCall("MultiByteToWideChar", "UInt", 65001, "UInt", 0, "UInt", &ostr, "int", -1, "UInt", &str, "int", size) } } ; Example: list= ( 1234568 File 1.ahk File 20.png File 2 File 3.tmp File 9.abc 1234567 ) msgbox Unsorted/Before:`n`n%list% Sort, list, F StrCmpLogical msgbox Sorted/After:`n`n%list%
#20
-
Posted 05 September 2009 - 12:07 AM
temp01, MultiByteToWideChar requires VarSetCapacity. Without it, it is likely to corrupt the script's memory. For instance,
MultiByteToWideChar(a:="1234567") MsgBox % VarSetCapacity(a)This shows 7, which is clearly not enough to hold a unicode string of 7 characters. COM_Unicode4Ansi shows the correct way to do it.
#21
-
Posted 05 September 2009 - 03:32 AM
Oops, I forgot that. Thanks Lex, I fixed the function above.
#22
-
Posted 05 September 2009 - 04:47 PM