How to sort Array by key value in the embedded Map objects Topic is solved

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
vysmaty
Posts: 11
Joined: 26 Mar 2024, 12:13

How to sort Array by key value in the embedded Map objects

11 Apr 2024, 12:09

Hi, can anyone help me with sorting the Array? I've tried various methods here from the forums, but most used assigning a value to an index, which is probably not possible in version 2 and the index must be an integer.
In the following I would like to sort the Array by Hotkey. Sort the programs by Hotkey. F1,F2... Hotkeys can also take equal or empty values.

Code: Select all

app := Array()
app.Push(
  ; Windows Explorer
  Map(
    "Hotkey", "F2", ; <- Set ME
    "Name", "WinExplorer",
    "EXE", "explorer.exe",
    "ID", "ahk_class CabinetWClass",
    "TabKey", "^{tab}"
  )
)

app.Push(
  ; One Commander
  Map(
    "Hotkey", "F1", ; <- Set ME
    "Name", "OneCommander",
    "EXE", "onecommander.exe",
    "ID", "ahk_exe OneCommander.exe",
    "TabKey", "^{tab}"
  )
)

... and more
Thank you for your help.
User avatar
mikeyww
Posts: 27370
Joined: 09 Sep 2014, 18:38

Re: How to sort Array by key value in the embedded Map objects  Topic is solved

11 Apr 2024, 12:27

Welcome to this AutoHotkey forum!

Code: Select all

app2 := [], m := Map()
For n, arr in app
 m[arr['Hotkey']] := n
For hk, n in m
 app2.Push(app[n])
For arr in app2
 MsgBox arr['Name'], arr['Hotkey']
vysmaty
Posts: 11
Joined: 26 Mar 2024, 12:13

Re: How to sort Array by key value in the embedded Map objects

11 Apr 2024, 12:40

Thank you. Thank you. I figured it was just the change in angle. Unfortunately, I came across the fact to the fact that F1 and F11 both start at 1. 🤦‍♂️

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

Re: How to sort Array by key value in the embedded Map objects

11 Apr 2024, 12:57

The hotkeys are sorted alphanumerically in the way that Map objects are enumerated. An Array object contains a list or sequence of values, so no keys are duplicated. If you do have duplicate hotkeys in your array, you would probably need to make some adjustments here.

The script that I posted works by creating a new Map object. The key is the hotkey, so there are no duplicates of these; the value is the key (numerical index) from the original array. As the new map is then enumerated alphanumerically by hotkey, a new array is assembled. Each array value comes from the original array.

There are, of course, other approaches. One could even build a simple string of the hotkeys and array keys, sort the string, and assemble a new array that way.

When forum readers work with the forum posts, they often use whatever data samples are originally provided. At least that is what I usually do. A different sample may yield different results!
vysmaty
Posts: 11
Joined: 26 Mar 2024, 12:13

Re: How to sort Array by key value in the embedded Map objects

11 Apr 2024, 13:17

Yeah, I kind of figured that out. I need to keep duplicated values and items with unassigned shortcuts. So this ends up not being appropriate at all, although it is beautifully simple.

It's rushing me to do some complicated moving around in indexes and loops, and I'm wondering if something hasn't already been created for this.

Generated from algorithm description. Untested. Non human code:

Code: Select all

; Functions to split a string into alphanumeric parts
SplitName(name) {
    parts := []
    currentPart := ""
    for i, char in StrSplit(name, "") {
        if (RegExMatch(char, "\d")) {
            ; If the character is a number, add it to the current part
            currentPart .= char
        } else {
            ; If the character is a letter, add the current part to the list and start a new part
            if (currentPart != "")
                parts.Push(currentPart)
            currentPart := char
        }
    }
    if (currentPart != "")
        parts.Push(currentPart)
    return parts
}

; Function for comparing two alphanumeric strings
CompareAlphanumeric(str1, str2) {
    parts1 := SplitName(str1)
    parts2 := SplitName(str2)
    minParts := Min(parts1.Length(), parts2.Length())
    for i, part1 in parts1 {
        if (i >= minParts)
            break
        part2 := parts2[i]
        if (RegExMatch(part1, "^\d") && RegExMatch(part2, "^\d")) {
            ; Porovnání jako čísla
            num1 := StrReplace(part1, ",", ".") ; Converting a decimal point to a period
            num2 := StrReplace(part2, ",", ".")
            if (num1 < num2)
                return -1
            else if (num1 > num2)
                return 1
        } else {
            ; Comparison as a chain
            if (part1 < part2)
                return -1
            else if (part1 > part2)
                return 1
        }
    }
    ; If we have come this far, the comparison was identical and the number of parts
    return parts1.Length() - parts2.Length()
}

; Example of use
name1 := "text123moretext456"
name2 := "text456moretext123"
result := CompareAlphanumeric(name1, name2)
if (result < 0)
    MsgBox "The first name is formerly."
else if (result > 0)
    MsgBox "The second name is formerly."
else
    MsgBox "The names are the same."

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

Re: How to sort Array by key value in the embedded Map objects

11 Apr 2024, 14:07

Why not Sort?
Why post a script that you have not run?
Why not post your data sample as I mentioned?

Code: Select all

#Requires AutoHotkey v2.0
app := Array()
app.Push(
  ; Windows Explorer
  Map(
    'Hotkey', 'F2', ; <- Set ME
    'Name', 'WinExplorer'
  )
)
app.Push(
  ; One Commander
  Map(
    'Hotkey', 'F1', ; <- Set ME
    'Name', 'OneCommander'
  )
)
app.Push(
  Map(
    'Hotkey', 'F1', ; <- Set ME
    'Name', 'AAzzzzzzzzzzzz'
  )
)
app.Push(
  Map(
    'Hotkey', '', ; <- Set ME
    'Name', 'bbbbbb'
  )
)
app2 := [], sorted := out := '', regex := '\d+$'
For n, arr in app
 sorted .= Format('{:-10}{:-20}{}`n', arr['Hotkey'], arr['Name'], n)
For line in StrSplit(Sort(sorted), '`n')
 If RegExMatch(line, regex, &m)
  app2.Push(app[m[]])
For arr in app2
 out .= (out = '' ? '' : '`n') arr['Hotkey'] ': ' arr['Name']
MsgBox out, 'Result', 'Iconi'
image240411-1453-001.png
Output
image240411-1453-001.png (21.94 KiB) Viewed 223 times
Last edited by mikeyww on 11 Apr 2024, 15:38, edited 1 time in total.
vysmaty
Posts: 11
Joined: 26 Mar 2024, 12:13

Re: How to sort Array by key value in the embedded Map objects

11 Apr 2024, 15:30

I tried not to demand ready-made solutions from the beginning. I'm sorry I didn't understand this help part works. I didn't want to take up anyone's time here. I rather expected to be directed to the appropriate place in the documentation or forum. I will do it differently next time. Forgive me. I'm sorry if I didn't express myself properly. I was probably looking for a function for "numerical" sorting. (As shown in the illustration after sorting.) By example I wanted to illustrate base of function what I'm probably looking for. "Numeric sorting" of Alphanumeric lines - I would like to ask if it does not exist in someway yet.

"Sort:" Thank you. I tried Sort by your example, but the basic option seems to me to sort the same as Map. And the numeric option doesn't seem to do what I expect. ... Whitch is the order: F9 F10 F11... I tried it in your example like this:

Code: Select all

For line in StrSplit(Sort(sorted, "N"), '`n')
"Why not post your data sample as I mentioned?" I found it rather confusing and unnecessarily long. It probably won't say anything new. Sorry. If necessary:

Code: Select all

; Create base object.
;{-----------------------------------------------
app := Array()
;{-----------------------------------------------

/*
; TEMPLATEs
;{-----------------------------------------------
app.Push(
  ; App Template
  Map(
    "Hotkey", "F13", ; <- Set ME  | OPTIONAL: IF EMPTY APP WILL BE IGNORED. Base Hotkey Key for App Switching. TODO: Reconsider not ignoring at menu.
    "Name", "Template", ; Name
    "EXE", "template.exe", ; Path to Executable (Full Path or Short from ENV)
    "ID", "ahk_class templates", ; Window Identification (ahk_exe, ahk_class)
    "TabKey", "^{tab}" ; OPTIONAL: Keystroke whitch is Switching Tabs
    "ComputerName", "COMPUTERNAME" ;OPTIONAL: IF NOT EMPTY, it will work only on a computer with this name. Must match AHK variable: A_ComputerName. For using same script on multiple machines with different apps.
; TODO: Line for manualy setting icon? UWPs?
  )
)
*/

; MARK: SET Apps and KEYS
;{-----------------------------------------------
; Set the desired last key of shortcut below for each desired app!

; FILE MANAGERs
;{-----------------------------------------------
app.Push(
  ; Windows Explorer
  Map(
    "Hotkey", "F2", ; <- Set ME
    "Name", "WinExplorer",
    "EXE", "explorer.exe",
    "ID", "ahk_class CabinetWClass",
    "TabKey", "^{tab}"
  )
)

app.Push(
  ; One Commander
  Map(
    "Hotkey", "F1", ; <- Set ME
    "Name", "OneCommander",
    "EXE", "onecommander.exe",
    "ID", "ahk_exe OneCommander.exe",
    "TabKey", "^{tab}"
  )
)


; WEB BROWSERS
;{-----------------------------------------------
app.Push(
  ; Vivaldi
  Map(
    "Hotkey", "F3", ; <- Set ME
    "Name", "Vivaldi",
    "EXE", "vivaldi.exe",
    "ID", "ahk_exe vivaldi.exe",
    "TabKey", "^{PgDn}"
  )
)

; NOTES
;{-----------------------------------------------
app.Push(
  ; Notion
  Map(
    "Hotkey", "F10", ; <- Set ME
    "Name", "Notion",
    "EXE", "C:\Users\" A_UserName "\AppData\Local\Programs\Notion\Notion.exe",
    "ID", "ahk_exe Notion.exe",
    "TabKey", "^{tab}"
  )
)

; OFFICE
;{-----------------------------------------------
; Microsoft Office
app.Push(
  Map(
    "Hotkey", "F11", ; <- Set ME
    "Name", "MicrosoftWord",
    "EXE", "C:\Program Files (x86)\Microsoft Office\root\Office16\WINWORD.EXE",
    "ID", "ahk_class OpusApp",
    "TabKey", ""
  )
)

; PDF
;{-----------------------------------------------
app.Push(
  ; Foxit PDF Editor
  Map(
    "Hotkey", "F4", ; <- Set ME
    "Name", "FoxitPDFEditor",
    "EXE", "C:\Program Files (x86)\Foxit Software\Foxit PDF Editor\FoxitPDFEditor.exe",
    "ID", "ahk_class classFoxitPhantom",
    "TabKey", "",
    "ComputerName", "BEAST"
  )
)

app.Push(
  ; Foxit PDF Editor
  Map(
    "Hotkey", "F4", ; <- Set ME
    "Name", "FoxitPDFReader",
    "EXE", "C:\Program Files (x86)\Foxit Software\Foxit Reader\FoxitReader.exe",
    "ID", "ahk_class classFoxitReader",
    "TabKey", "",
    "ComputerName", "AALTO"
  )
)


; CAD
;{-----------------------------------------------
; BricsCAD
app.Push(
  Map(
    "Hotkey", "F5", ; <- Set ME
    "Name", "BricsCAD",
    "EXE", "C:\Program Files\Bricsys\BricsCAD V21 en_US\bricscad.exe",
    "ID", "ahk_exe bricscad.exe",
    "TabKey", "^{tab}"
  )
)


; 3D
;{-----------------------------------------------
app.Push(
  Map(
    "Hotkey", "F6", ; <- Set ME
    "Name", "SketchUp",
    "EXE", "C:\Program Files\SketchUp\SketchUp 2020\SketchUp.exe",
    "ID", "ahk_exe SketchUp.exe",
  )
)


; GRAPHICS
;{-----------------------------------------------

; Reference
app.Push(
  ; PureRef
  Map(
    "Hotkey", "F9", ; <- Set ME
    "Name", "PureRef",
    "EXE", "C:\Program Files\PureRef\PureRef.exe",
    "ID", "ahk_exe PureRef.exe"
  )
)

; AFFINITY
app.Push(
  ; Photo
  Map(
    "Hotkey", "F7", ; <- Set ME
    "Name", "AffinityPhoto",
    "EXE", "C:\Users\" A_UserName "\AppData\Local\Microsoft\WindowsApps\AffinityPhoto2.exe",
    "ID", "ahk_exe Photo.exe",
    "TabKey", "^{tab}"
  )
)


app.Push(
  ; Publisher
  Map(
    "Hotkey", "F8", ; <- Set ME
    "Name", "AffinityPublisher",
    "EXE", "C:\Users\" A_UserName "\AppData\Local\Microsoft\WindowsApps\AffinityPublisher2.exe",
    "ID", "ahk_exe Publisher.exe",
    "TabKey", "^{tab}"
  )
)

; COMUNICATION
;{-----------------------------------------------
; Discord
app.Push(
  Map(
    "Hotkey", "", ; <- Set ME
    "Name", "Discord",
    "EXE", "C:\Users\" A_UserName "\Desktop\Discord.lnk",
    "ID", "ahk_exe Discord.exe",
    "TabKey", "^{PgDn}"
  )
)

; CODE
;{-----------------------------------------------
; VSCode
app.Push(
  Map(
    "Hotkey", "F12", ; <- Set ME
    "Name", "VSCode",
    "EXE", "C:\Users\" A_UserName "\AppData\Local\Programs\Microsoft VS Code\Code.exe",
    "ID", "ahk_exe Code.exe",
    "TabKey", "^{PgDn}"
  )
)
And if necessary, here it is in its entirety. If it doesn't belong here, I'm also sorry. Is it possible to edit posts here?

Code: Select all

; This is a modified script for v2.
; From Taran Van Hemert and … and … fill in your name. I had it too many years and I don't know exact source. It's rewriten.
; https://www.youtube.com/watch?v=OqyQABySV8k

; Script for quick switching between applications, application windows, application tabs and application minimization.
; You have to set your MODIFIER KEYS and APPS & KEYS below.

#Requires AutoHotkey v2.0
#SingleInstance force
#WinActivateForce
SendMode("Input")

; MARK: SET your MODIFIER KEYS
;{-----------------------------------------------

; Show Gui With Help
HelpHotkey := ["+#NumpadSub", "~LButton & NumpadSub"]

; Switch Between aka Cycle Through Windows
SwitchBetweenKey := ["+#", "~LButton & "] ; Eg. ( Shift+Win OR Left Mouse Button ) + Key set for app
; Switch to Window and cycle through tabs
SwitchToKey := ["^#"] ; Eg. ( Ctrl+Win) + Key set for app; Or USE Tabs On Wheels ;)
; Minimize Window
MinimalizeKey := ["!#", "~MButton & "] ; Eg. (Alt+Win) + Key set for app




;{-----------------------------------------------
; Close Window
for Modifier in SwitchBetweenKey
{
  Hotkey(Modifier "Esc", CloseWindow.Bind()) ; Eg. ( Shift+Win OR Left Mouse Button ) + Esc to Close Window
}
CloseWindow(this_hotkey) {
  Send "{LButton up}^w"
  ;WinClose("A")
}
;{-----------------------------------------------
; Show Help
for Modifier in HelpHotkey
{
  Hotkey(Modifier, Show.Bind())
}


; Create base object.
;{-----------------------------------------------
app := Array()
;{-----------------------------------------------

/*
; TEMPLATEs
;{-----------------------------------------------
app.Push(
  ; App Template
  Map(
    "Hotkey", "F13", ; <- Set ME  | OPTIONAL: IF EMPTY APP WILL BE IGNORED. Base Hotkey Key for App Switching. TODO: Reconsider not ignoring at menu.
    "Name", "Template", ; Name
    "EXE", "template.exe", ; Path to Executable (Full Path or Short from ENV)
    "ID", "ahk_class templates", ; Window Identification (ahk_exe, ahk_class)
    "TabKey", "^{tab}" ; OPTIONAL: Keystroke whitch is Switching Tabs
    "ComputerName", "COMPUTERNAME" ;OPTIONAL: IF NOT EMPTY, it will work only on a computer with this name. Must match AHK variable: A_ComputerName. For using same script on multiple machines with different apps.
; TODO: Line for manualy setting icon? UWPs?
  )
)
*/

; MARK: SET Apps and KEYS
;{-----------------------------------------------
; Set the desired last key of shortcut below for each desired app!

; FILE MANAGERs
;{-----------------------------------------------
app.Push(
  ; Windows Explorer
  Map(
    "Hotkey", "F2", ; <- Set ME
    "Name", "WinExplorer",
    "EXE", "explorer.exe",
    "ID", "ahk_class CabinetWClass",
    "TabKey", "^{tab}"
  )
)

app.Push(
  ; One Commander
  Map(
    "Hotkey", "F1", ; <- Set ME
    "Name", "OneCommander",
    "EXE", "onecommander.exe",
    "ID", "ahk_exe OneCommander.exe",
    "TabKey", "^{tab}"
  )
)


; WEB BROWSERS
;{-----------------------------------------------
app.Push(
  ; Vivaldi
  Map(
    "Hotkey", "F3", ; <- Set ME
    "Name", "Vivaldi",
    "EXE", "vivaldi.exe",
    "ID", "ahk_exe vivaldi.exe",
    "TabKey", "^{PgDn}"
  )
)

; NOTES
;{-----------------------------------------------
app.Push(
  ; Notion
  Map(
    "Hotkey", "F10", ; <- Set ME
    "Name", "Notion",
    "EXE", "C:\Users\" A_UserName "\AppData\Local\Programs\Notion\Notion.exe",
    "ID", "ahk_exe Notion.exe",
    "TabKey", "^{tab}"
  )
)

; OFFICE
;{-----------------------------------------------
; Microsoft Office
app.Push(
  Map(
    "Hotkey", "F11", ; <- Set ME
    "Name", "MicrosoftWord",
    "EXE", "C:\Program Files (x86)\Microsoft Office\root\Office16\WINWORD.EXE",
    "ID", "ahk_class OpusApp",
    "TabKey", ""
  )
)

; PDF
;{-----------------------------------------------
app.Push(
  ; Foxit PDF Editor
  Map(
    "Hotkey", "F4", ; <- Set ME
    "Name", "FoxitPDFEditor",
    "EXE", "C:\Program Files (x86)\Foxit Software\Foxit PDF Editor\FoxitPDFEditor.exe",
    "ID", "ahk_class classFoxitPhantom",
    "TabKey", "",
    "ComputerName", "BEAST"
  )
)

app.Push(
  ; Foxit PDF Editor
  Map(
    "Hotkey", "F4", ; <- Set ME
    "Name", "FoxitPDFReader",
    "EXE", "C:\Program Files (x86)\Foxit Software\Foxit Reader\FoxitReader.exe",
    "ID", "ahk_class classFoxitReader",
    "TabKey", "",
    "ComputerName", "AALTO"
  )
)


; CAD
;{-----------------------------------------------
; BricsCAD
app.Push(
  Map(
    "Hotkey", "F5", ; <- Set ME
    "Name", "BricsCAD",
    "EXE", "C:\Program Files\Bricsys\BricsCAD V21 en_US\bricscad.exe",
    "ID", "ahk_exe bricscad.exe",
    "TabKey", "^{tab}"
  )
)


; 3D
;{-----------------------------------------------
app.Push(
  Map(
    "Hotkey", "F6", ; <- Set ME
    "Name", "SketchUp",
    "EXE", "C:\Program Files\SketchUp\SketchUp 2020\SketchUp.exe",
    "ID", "ahk_exe SketchUp.exe",
  )
)


; GRAPHICS
;{-----------------------------------------------

; Reference
app.Push(
  ; PureRef
  Map(
    "Hotkey", "F9", ; <- Set ME
    "Name", "PureRef",
    "EXE", "C:\Program Files\PureRef\PureRef.exe",
    "ID", "ahk_exe PureRef.exe"
  )
)

; AFFINITY
app.Push(
  ; Photo
  Map(
    "Hotkey", "F7", ; <- Set ME
    "Name", "AffinityPhoto",
    "EXE", "C:\Users\" A_UserName "\AppData\Local\Microsoft\WindowsApps\AffinityPhoto2.exe",
    "ID", "ahk_exe Photo.exe",
    "TabKey", "^{tab}"
  )
)


app.Push(
  ; Publisher
  Map(
    "Hotkey", "F8", ; <- Set ME
    "Name", "AffinityPublisher",
    "EXE", "C:\Users\" A_UserName "\AppData\Local\Microsoft\WindowsApps\AffinityPublisher2.exe",
    "ID", "ahk_exe Publisher.exe",
    "TabKey", "^{tab}"
  )
)

; COMUNICATION
;{-----------------------------------------------
; Discord
app.Push(
  Map(
    "Hotkey", "", ; <- Set ME
    "Name", "Discord",
    "EXE", "C:\Users\" A_UserName "\Desktop\Discord.lnk",
    "ID", "ahk_exe Discord.exe",
    "TabKey", "^{PgDn}"
  )
)

; CODE
;{-----------------------------------------------
; VSCode
app.Push(
  Map(
    "Hotkey", "F12", ; <- Set ME
    "Name", "VSCode",
    "EXE", "C:\Users\" A_UserName "\AppData\Local\Programs\Microsoft VS Code\Code.exe",
    "ID", "ahk_exe Code.exe",
    "TabKey", "^{PgDn}"
  )
)

; SORT OBJECT TODO: Last part before sharing back to AHK.
/* 
; Great Example of Basic Sorting by mikeyww
;https://www.autohotkey.com/boards/viewtopic.php?f=82&t=128616
app2 := [], m := Map()
For arr in app
 m[arr['Hotkey']] := arr
For hk, arr in m
 app2.Push(arr)
app := app2
 */

/* 
; Another Example of Sorting With Use of Format. <- TODO: Concept - Need research.
app2 := [], sorted := '', regex := '\d+$'
For n, arr in app
 sorted .= (sorted = '' ? '' : '`n') Format('{:-10}{:-20}{}', arr['Hotkey'], arr['Name'], n)
For line in StrSplit(Sort(sorted, "N"), '`n')
 If RegExMatch(line, regex, &m)
  app2.Push(app[m[]])
out := ''
For arr in app2
 out .= (out = '' ? '' : '`n') arr['Hotkey'] ': ' arr['Name']
MsgBox out, 'Result', 'Iconi'
 */

;app := app2

/* TODO: Possible solution for this numeric sorting is algorithm that could compare two alphanumeric strings and determine which one comes first.
Than I could use that in loop. In loop compare alphanumeric string from examined map with each hotkey of sorted array - until i find place for it between, in front of or else behind.
Than I could use this as origin to construct sorted array. But I have duplicates and empty strings. - Empty strings i could maybe put to the end. - But duplicates, reconstruction will not be... I can allways make temporary strings. Stupid. I should try it again from the start. What about modifing base array at ones? That should make it. I need that sorting.

Concept of algorithm for numeric sorting. Found on stack. Revisit if needed.
Split each filename into alphabetical and numeric parts; i.e. the name text123moretext456 becomes the list {"text", "123", "moretext", "456"}

For each part in the two split names - there would be following:

If both parts are just numeric, compare them as numbers - easy
If the numbers are same, than compare them as strings
If the strings are same, than it should move on to the next part
If both parts are just letters, lets compare them as strings
If they're the same, move on to the next part. :)
If you run out of parts, the name with the fewest parts comes first
  
Lets get basic example as reference for asking. Maybe numeric sorting exist already at Autohotkey or as some kind of system library.*/


; TODO: Add help with set keys - usable also as launcher - surprise.
; Add to GUI
helpMenu := Menu()

;{-----------------------------------------------
; MARK: Loop Though Apps
;{-----------------------------------------------

; Asign HOTKEYS for All Application and Functions
for k, v in app
{
  if not (v.get("ComputerName", A_ComputerName) = A_ComputerName) {
    continue
  }
  if (v.get("Hotkey", "") = "") {
    continue
  }
  for Modifier in SwitchBetweenKey
  {
    Hotkey(Modifier v["Hotkey"], SwitchBetweenWindows.Bind(, v["ID"], v["Name"], v["EXE"]))
  }
  for Modifier in SwitchToKey
  {
    Hotkey(Modifier v["Hotkey"], SwitchToWindow.Bind(, v["ID"], v["EXE"], v.get("TabKey", "")))
  }
  for Modifier in MinimalizeKey
  {
    Hotkey(Modifier v["Hotkey"], MinimizeWindow.Bind(, v["ID"]))
  }
  item_name := "[" v["Hotkey"] "]   :   " v["Name"]
  helpMenu.Add(item_name, SwitchBetweenWindows.Bind("NONE", v["ID"], v["Name"], v["EXE"]))
  try{
    helpMenu.SetIcon(item_name, v["EXE"], "1")
  }
}

; MARK: Help with generated LIST of Apps and KEYs.
;{-----------------------------------------------
; Show Help
Show(this_hotkey) {
  ;Refresh DarkMode state when menu Called.
  LightTheme := RegRead("HKCU\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize", "AppsUseLightTheme")
  if !LightTheme {
    SetDarkMode()
  }
  helpMenu.Show()
  return
}

; DARKMODE
SetDarkMode() {
  uxtheme := DllCall("GetModuleHandle", "str", "uxtheme", "ptr")
  SetPreferredAppMode := DllCall("GetProcAddress", "ptr", uxtheme, "ptr", 135, "ptr")
  FlushMenuThemes := DllCall("GetProcAddress", "ptr", uxtheme, "ptr", 136, "ptr")
  DllCall(SetPreferredAppMode, "int", 1) ; Dark
  DllCall(FlushMenuThemes)
}

; MARK: Functions
;{-----------------------------------------------
; ShellRun runs the given program with restricted privileges as the AutoHotkey
; https://www.autohotkey.com/boards/viewtopic.php?p=404418#p404418
ShellRun(prms*)
{
  shellWindows := ComObject("Shell.Application").Windows
  desktop := shellWindows.FindWindowSW(0, 0, 8, 0, 1) ; SWC_DESKTOP, SWFO_NEEDDISPATCH

  ; Retrieve top-level browser object.
  tlb := ComObjQuery(desktop,
    "{4C96BE40-915C-11CF-99D3-00AA004AE837}", ; SID_STopLevelBrowser
    "{000214E2-0000-0000-C000-000000000046}") ; IID_IShellBrowser

  ; IShellBrowser.QueryActiveShellView -> IShellView
  ComCall(15, tlb, "ptr*", sv := ComValue(13, 0)) ; VT_UNKNOWN

  ; Define IID_IDispatch.
  NumPut("int64", 0x20400, "int64", 0x46000000000000C0, IID_IDispatch := Buffer(16))

  ; IShellView.GetItemObject -> IDispatch (object which implements IShellFolderViewDual)
  ComCall(15, sv, "uint", 0, "ptr", IID_IDispatch, "ptr*", sfvd := ComValue(9, 0)) ; VT_DISPATCH

  ; Get Shell object.
  shell := sfvd.Application

  ; IShellDispatch2.ShellExecute
  shell.ShellExecute(prms*)
}

; SwitchToWindow switches to the last active window matching the given selector
; or starts the program if it is not yet running. If a matching window is
; already active, the given keystroke is sent.
SwitchToWindow(this_hotkey, Selector, FilePath, KeystrokeIfActive := "")
{
  ; Check if a matching window is open
  if !WinExist(Selector)
  {
    ; If not, run the program
    if (FilePath != "")
      ShellRun(FilePath) ; Run the program as a limited user and not as an administrator
    return
  }

  ; Optionally send a keystroke if the window is alredy in focus
  if WinActive(Selector)
  {
    if (KeystrokeIfActive != "`"`"")
      Send(KeystrokeIfActive)
    return
  }

  ; If a window is currently open but not focussed, activate it
  WinActivate()
}

; SwitchBetweenWindows cycles between all windows matching the given selector.
SwitchBetweenWindows(this_hotkey, Selector, GroupIdentifier, FilePath := "", *)
{
  ; Check if a matching window is open
  if WinExist(Selector)
  {
    GroupName := "MacroWindows_" . GroupIdentifier

    ; Add all matching windows to the same group to allow switching between them
    GroupAdd(GroupName, Selector)

    ; Check if a matching window is in already focus
    if WinActive(Selector)
    {
      ; Switch to the next matching window
      GroupActivate(GroupName, "R")
      return
    }

    ; If a window is currently open but not focused, activate it
    WinActivate(Selector)
    return
  }
  else
  {
    ; If not, run the program
    if (FilePath != "")
      ShellRun(FilePath) ; Run the program as a limited user and not as an administrator
    return
  }
  return
}

; MinimizeWindow minimizes the first window matching the given selector.
MinimizeWindow(this_hotkey, Selector)
{
  WinMinimize(Selector)
}
User avatar
boiler
Posts: 17392
Joined: 21 Dec 2014, 02:44

Re: How to sort Array by key value in the embedded Map objects

11 Apr 2024, 15:41

vysmaty wrote: Is it possible to edit posts here?
Yes, although your account may not have edit privileges until you get past new member status, which occurs after something like 10 or 15 posts, depending on other factors.
User avatar
mikeyww
Posts: 27370
Joined: 09 Sep 2014, 18:38

Re: How to sort Array by key value in the embedded Map objects

11 Apr 2024, 15:45

OK. You may see success with some variations of calling the Sort function. For example, in light of your data sample, you can test the following call, which adds options to specify numbers and a column or position. The script that I posted could be adjusted with this simple option to sort the function keys in numeric order.

Code: Select all

#Requires AutoHotkey v2.0
f := '
(
F11
F10

F9
)'
MsgBox Sort(f, 'NP2')
If I had been posting this question, I would have provided a list of all hotkeys or text to sort (i.e., the input), and the final sorted list (i.e., the output). That seems to be your core question.

As noted, a different data sample may require a different script!

Enjoy! :)
vysmaty
Posts: 11
Joined: 26 Mar 2024, 12:13

Re: How to sort Array by key value in the embedded Map objects

11 Apr 2024, 16:24

I think I got the answer to the question right away with the first welcome reply. It is tailored to the question. But if I can sort out KeyList+all, we'll see about that. Numpad has numbers too, after all. Thanks for your help and welcome.
vysmaty
Posts: 11
Joined: 26 Mar 2024, 12:13

Re: How to sort Array by key value in the embedded Map objects

11 Apr 2024, 16:43

And this seems like an answer to the second question, to close it for those who would research after me.
viewtopic.php?p=320555#p320555

Return to “Ask for Help (v2)”

Who is online

Users browsing this forum: mikeyww and 44 guests