autohotkey

Is it possible to create this kind of data in AutoHoktey?


I need to create a function that will take a window and resize it or restore its initial size. I am stuck on the part of recording the windows initial position and size, so I can restore its initial position later on.

Here is what I have:

win_snapToMonitor(winTitle := "a", subCommand := ""){
    static history := []
    hwnd := winExist(winTitle)
    monNo   := coord_OnMonitor(hwnd)                                                        ;this function simply return a monitor No, such as "1" or "2"
    SysGet, mon, Monitor,% monNo
    WinGetPos, winX, winY, winW, winH,% winTitle
    
    ;if (history has hwnd in it){                                                           ;this block is pseudo code
    ;   restore window
    ;   remove it from the "history" array                                      
    ;   return
    ;}
    ;else{
    ;   history.push(hwnd:{x:winX, y:winY, w:winW, h:winH})
    ;}

    if (subCommand = "toLeft")
        WinMove,% "ahk_id" hwnd,,% monLeft                                   ;snap to left corner of monitor
    else if (subCommand = "toTop")                                           ;snap to top corner of monitor  
        WinMove,% "ahk_id" hwnd,,,% monTop
    else if (subCommand = "toRight")
        winMove,% "ahk_id" hwnd,,,% monTop
    else if (subCommand = "toBottom")
        winMove,% "ahk_id" hwnd,,,% monBottom - winW
    else if (subCommand = "Horiz")
        winMove,% "ahk_id" hwnd,, monLeft,, monRight                               ;fill all horizontal
    else if (subCommand = "Vert")
        WinMove,% "ahk_id" hwnd,,,% monTop,,% (montop - monBottom) * -1   ;fill all vertical
}

The line history.push(hwnd:{x:winX, y:winY, w:winW, h:winH}) keeps throwing an ==> Unexpected "{" error.

I am trying to store a dictionary (map?) whose name is a window handle. Looking at it on its own, it looks like this

hwnd := winExist("code")
WinGetPos, winX, winY, winW, winH,% winTitle
history := []
history.push(hwnd{x:winX, y:winY, w:winW, h:winH})
history.push(%hwnd%:{x:winX, y:winY, w:winW, h:winH})      ;this does not work either
history.push((%hwnd%):{x:winX, y:winY, w:winW, h:winH})    ;this does not work either
history.push((hwnd):{x:winX, y:winY, w:winW, h:winH})      ;this does not work either
msgbox,% json.dump(history)                                ;print a strinfied json of the AHK object

I am trying to create data like this

[
    "0x13f11" : {
        "x"     : 100, 
        "y"     : 100,
        "w" : 1000,
        "w" : 1000,
    }
    "0x13f722" : {
        "x"     : 200, 
        "y"     : 200,
        "w" : 2000,
        "w" : 2000,
    }
...
]

I decided to have the data in this structure, because I am thinking I can query history and return a matching handle in a list of handles it has, doing arrayMatch(history, hwnd) should return a array element

The code for arrayMatch

;Match a value in a array using case-insensitive string matching, with the option to return first or all matches and value or index
arrayMatch(array, match, all := 0, index := 0){
    out := []
    loop,% array.Length()
        {
            if (index){
                if (array[A_Index] = match){
                        return A_Index
                    }   
                }
            else{
                if (array[A_Index] == match){
                    if (all)
                        out.push((array[A_Index]))
                    else
                        return (array[A_Index])
                    }   
                }
        }
    return out
}

I am a very novice programmer, so any suggestions for a better data structure would be most welcome.

PS: I know windows kind of does this feature, but this is a programming project for me.

Any help would be greatly appreciated!


Solution

  • Did you choose an array to keep your data in order? If not, then there is no point to using an array an it really just makes this harder.

    If using the array is important, then you should just do this:

    history := []
    hwnd := WinExist("A")
    WinGetPos, winX, winY, winW, winH
    
    history.push({ hwnd: hwnd
                 , x: winX
                 , y: winY
                 , w: winW
                 , h: winH })
    
    hwnd := WinExist("ahk_exe chrome.exe")
    WinGetPos, winX, winY, winW, winH
    
    history.push({ hwnd: hwnd
                 , x: winX
                 , y: winY
                 , w: winW
                 , h: winH })
    
    MsgBox, % json.dump(history, , 4)
    
    /* output
    [
        {
            "h": 1550,
            "hwnd": "0x907b0",
            "w": 2880,
            "x": 1456,
            "y": 528
        },
        {
            "h": 2108,
            "hwnd": "0x911e2",
            "w": 2718,
            "x": 0,
            "y": 0
        }
    ]
    */
    

    And then here you can index to the data you want, or of course even loop and search for a match.


    Or if it's actually not important to keep the data in order, you can just easily create a dict/map and index by hwnd:

    history := {}
    hwnd := WinExist("A")
    WinGetPos, winX, winY, winW, winH
    
    history[hwnd] := { x: winX
                     , y: winY
                     , w: winW
                     , h: winH }
    
    hwnd := WinExist("ahk_exe chrome.exe")
    WinGetPos, winX, winY, winW, winH
    
    history[hwnd] := { x: winX
                     , y: winY
                     , w: winW
                     , h: winH }
    
    MsgBox, % json.dump(history, , 4)
    
    /* output
    {
        "591792": {
            "h": 1550,
            "w": 2880,
            "x": 1456,
            "y": 528
        },
        "594402": {
            "h": 2108,
            "w": 2718,
            "x": 0,
            "y": 0
        }
    }
    */
    
    MsgBox, % json.dump(history[hwnd], , 4)
    
    /* output
    {
        "h": 2108,
        "w": 2718,
        "x": 0,
        "y": 0
    }
    */