5

For example, I have Notepad, Word, and Chrome open. How do I write the script in AutoHotKey such that when I press the F9 key on the keyboard, it will move to the next application?

user1187968
  • 7,154
  • 16
  • 81
  • 152

2 Answers2

8

Try:

AltTab_ID_List_ := []

setTimer, updateList, 100

+f9::WinActivate, % "AHK_ID" AltTab_ID_List_[(pointer == 1 or pointer == 0 
                                   ? AltTab_ID_List_.Count()-1 : --pointer)]

f9::WinActivate, % "AHK_ID" AltTab_ID_List_[++pointer]

updateList:
list := AltTab_window_list()
if (AltTab_ID_List_.MaxIndex() != list.MaxIndex()) 
    AltTab_ID_List_ := list


cur:=WinExist("A")
for e, v in AltTab_ID_List_
    if (cur == v)
        pointer := AltTab_ID_List_.MaxIndex() == e ? 0 : e, break

return


AltTab_window_list()
{

  WS_EX_CONTROLPARENT =0x10000
  WS_EX_APPWINDOW =0x40000
  WS_EX_TOOLWINDOW =0x80
  WS_DISABLED =0x8000000
  WS_POPUP =0x80000000
  AltTab_ID_List_ := [] ;AltTab_ID_List_ =0

  WinGet, Window_List, List ; Gather a list of running programs
  id_list =
  Loop, %Window_List%
    {
    wid := Window_List%A_Index%
    WinGetTitle, wid_Title, ahk_id %wid%
    WinGet, Style, Style, ahk_id %wid%

    If ((Style & WS_DISABLED) or ! (wid_Title)) ; skip unimportant windows ; ! wid_Title or 
        Continue

    WinGet, es, ExStyle, ahk_id %wid%
    Parent := Decimal_to_Hex( DllCall( "GetParent", "uint", wid ) )
    WinGetClass, Win_Class, ahk_id %wid%
    WinGet, Style_parent, Style, ahk_id %Parent%

    If ((es & WS_EX_TOOLWINDOW)
        or ((es & ws_ex_controlparent) and ! (Style & WS_POPUP) and !(Win_Class ="#32770") and ! (es & WS_EX_APPWINDOW)) ; pspad child window excluded
        or ((Style & WS_POPUP) and (Parent) and ((Style_parent & WS_DISABLED) =0))) ; notepad find window excluded ; note - some windows result in blank value so must test for zero instead of using NOT operator!
      continue

     AltTab_ID_List_.push(wid)

    }
    return AltTab_ID_List_
}

Decimal_to_Hex(var)
{
  SetFormat, integer, hex
  var += 0
  SetFormat, integer, d
  return var
}
errorseven
  • 2,672
  • 2
  • 14
  • 20
  • What autohotkey version is this for, I can't seem to get it to work. Also it would be nice if there was a way to go both right and left. – Lime Aug 22 '18 at 04:02
  • @William : It was written with the latest version of AutoHotkey at the time of posting, you can look up which version that was in the version update history from the official documents. It was tested under Windows 10. I don't have time to test now to test now but it should be backwards compatible and work with the latested verison. Perhaps tonight I'll add left traversing with a shift modifier on the hotkey. – errorseven Aug 24 '18 at 14:14
  • @William : Added code to make it traverse in reverse order, it works with the latest version on Windows 10. – errorseven Aug 25 '18 at 01:18
  • Updated autohotkey and working great now thank you for the shift option. – Lime Aug 25 '18 at 01:46
0

I changed the "errorseven" code for better performance (removing the update timer from the list) and usability

!WheelDown::
    gosub UpdateWindowsList
    Item_ID_List.Push(Item_ID_List.RemoveAt(1))
    gosub PrintList
    WinActivate, % "AHK_ID" Item_ID_List[1]
return

!WheelUp::
    gosub UpdateWindowsList
    Item_ID_List.InsertAt(1, Item_ID_List.Pop())
    gosub PrintList
    WinActivate, % "AHK_ID" Item_ID_List[1]
return

; Update list order
!MButton::
    Item_ID_List := Get_Windows_List()
return

UpdateWindowsList:
    New_Item_ID_List := Get_Windows_List()
    FirstNow := New_Item_ID_List[1]
    ; Checks if the active program was already on the old list
    for index, value in Item_ID_List {
        if (value = FirstNow)
            break
    }
    ; If the active program is not at the beginning of the list, bring it to the beginning
    if (value = New_Item_ID_List[1]) {
        while(FirstNow != Item_ID_List[1]) {
            RemovedValue := Item_ID_List.RemoveAt(1)
            Item_ID_List.Push(RemovedValue)
        }
    }
    ; Delete closed items from the old list
    TempArray := []
    for index, value in Item_ID_List {
        for index2, value2 in New_Item_ID_List {
            if (value = value2) {
                TempArray.push(New_Item_ID_List.RemoveAt(index2))
                break
            }
        }
    }
    ; Updates the old list with new open programs
    for index2, value2 in New_Item_ID_List {
        TempArray.push(value2)
    }
    Item_ID_List := TempArray
    ; If the active program is not at the beginning of the list, bring it to the beginning
    while(FirstNow != Item_ID_List[1]) {
        RemovedValue := Item_ID_List.RemoveAt(1)
        Item_ID_List.Push(RemovedValue)
    }
return

Get_Windows_List()
{
    WS_EX_CONTROLPARENT =0x10000
    WS_EX_APPWINDOW =0x40000
    WS_EX_TOOLWINDOW =0x80
    WS_DISABLED =0x8000000
    WS_POPUP =0x80000000
    AltTab_ID_List := [] ;AltTab_ID_List =0

    WinGet, Window_List, List ; Gather a List of running programs
    id_List =
    Loop, %Window_List%
    {
        wid := Window_List%A_Index%
        WinGetTitle, wid_Title, ahk_id %wid%
        WinGet, Style, Style, ahk_id %wid%

        if ((Style & WS_DISABLED) or ! (wid_Title)) ; skip unimportant windows ; ! wid_Title or 
        Continue

        WinGet, es, ExStyle, ahk_id %wid%
        Parent := Decimal_to_Hex( DllCall( "GetParent", "uint", wid ) )
        WinGetClass, Win_Class, ahk_id %wid%
        WinGet, Style_parent, Style, ahk_id %Parent%

        if ((es & WS_EX_TOOLWINDOW)
        or ((es & ws_ex_controlparent) and ! (Style & WS_POPUP) and !(Win_Class ="#32770") and ! (es & WS_EX_APPWINDOW)) ; pspad child window excluded
        or ((Style & WS_POPUP) and (Parent) and ((Style_parent & WS_DISABLED) =0))) ; notepad find window excluded ; note - some windows result in blank value so must test for zero instead of using NOT operator!
        continue

         AltTab_ID_List.push(wid)

    }
    return AltTab_ID_List
}

Decimal_to_Hex(var)
{
    Setformat, integer, hex
    var += 0
    Setformat, integer, d
    return var
}

PrintList:
    names =
    for index, value in Item_ID_List {
        WinGetTitle, OutputVar , AHK_ID %value%
        frase = % "Item " index " is '" OutputVar "'"
        names = %names%%frase%`n
    }
    ToolTip, %names%
    SetTimer, RemoveToolTip, -1000
return

RemoveToolTip:
ToolTip
return