개요

우리는 Alt+Tab을 이용해 여러 프로그램을 오가며 작업합니다. 하지만, 열려있는 프로그램이 많을수록 Alt+Tab를 여러번 눌러 원하는 창을 찾기 어려우며, 작업 흐름도 끊겨 집중력이 떨어지기도 합니다.

이를 해결하기 위해 자주 사용하는 프로그램으로 즉시 전환할 수 있도록 AutoHotkey 스크립트를 만들어 공유하고자 합니다.

스크립트 설명

AutoHotkey는 윈도우용 오픈소스 프로그램으로, 키보드 단축키 설정, 반복작업 자동화 등 다양한 기능을 제공하여 업무 효율을 크게 높일 수 있습니다.

아래 스크립트를 사용하면 단축키 하나로 원하는 프로그램을 즉시 활성화할 수 있습니다.

  • Win+Shift+W : 웹브라우저

  • Win+Shift+N : 메모장

  • Win+Shift+V : Visual Studio Code

  • Win+F : 같은 프로그램의 다음 창 (MacOS의 CMD+` 기능)

  • Win+Shift+F : 같은 프로그램의 이전 창

스크립트 실행

아래 스크립트를 메모장에 붙여넣고 .AHK 파일로 저장해 Hotkey Definitions 섹션의 항목을 원하는 단축키와 원하는 프로그램으로 수정하여 .AHK 파일을 실행하면 됩니다. 물론, AutoHotkey는 2.0 버전으로 설치되어 있어야 합니다.

참고로, 부팅시 자동으로 실행하게끔 하려면 Win+R 및 Shell:Startup 입력 후 열리는 폴더에 .AHK 파일을 저장하면 됩니다.

#Requires AutoHotkey v2.0
#SingleInstance force

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Hotkey Modifier Symbols
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; # WIN 
; ! ALT 
; ^ CTRL 
; + SHIFT

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Hotkey Definitions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

#f:: SwitchToNextInstance()
#+f::SwitchToPrevInstance()

#+q::Activate("C:\Program Files\Everything 1.5a\Everything64.exe")
#+w::Activate("C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe")
#+e::WinExist('ahk_class CabinetWClass') ? WinActivate() : Run('Explorer.exe')
#+r::Reload()
#+t::Activate("C:\Program Files\PuTTY\PuTTY.exe")
#+o::Activate("C:\Program Files\Obsidian\Obsidian.exe")

#+d::ActivateStoreApp("Microsoft To Do")
#+g::Activate(EnvGet("LOCALAPPDATA") . "\GitHubDesktop\GitHubDesktop.exe")
#+h::Activate("C:\Program Files (x86)\Hnc\HOffice9\Bin\hwp.exe")

#+x::Activate("Cmd.exe")
#+c::ActivateStoreApp("계산기")
#+v::ActivateStoreApp("Visual Studio Code")
#+n::Activate("C:\Program Files\HeyNote\HeyNote.exe")

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Functions (No need to read or change)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Activate(programPath) {
    if WinExist("ahk_exe " . programPath)
        WinActivate
    else
        Run programPath
}

ActivateStoreApp(appName) {
    SetTitleMatchMode 2
    if WinExist(appName)
        WinActivate
    else {
        for app in ComObject('Shell.Application').NameSpace('shell:AppsFolder').Items
            if (app.Name = appName)
                RunWait('explorer shell:appsFolder\' app.Path)
    }
}

SwitchToNextInstance() {
    activeExe := WinGetProcessName("A")

    SetTitleMatchMode "RegEx"
    instances := WinGetList("ahk_exe " activeExe,, "Program Manager", "Shell_TrayWnd|SysShadow")
    instances := SortArray(instances)
    if instances.Length < 2
        return
    
    currentHwnd := WinGetID("A")
    currentIndex := 0
    
    for index, hwnd in instances {
        if hwnd == currentHwnd {
            currentIndex := index
            break
        }
    }
    
    if currentIndex > 0 {
        nextIndex := Mod(currentIndex, instances.Length) + 1
        WinActivate("ahk_id " instances[nextIndex])
    }
}

SwitchToPrevInstance() {
    activeExe := WinGetProcessName("A")

    SetTitleMatchMode "RegEx"
    instances := WinGetList("ahk_exe " activeExe,, "Program Manager", "Shell_TrayWnd|SysShadow")
    instances := SortArray(instances)
    if instances.Length < 2
        return
    
    currentHwnd := WinGetID("A")
    currentIndex := 0
    
    for index, hwnd in instances {
        if hwnd == currentHwnd {
            currentIndex := index
            break
        }
    }
    
    if currentIndex > 0 {
        prevIndex := Mod(currentIndex - 2 + instances.Length, instances.Length) + 1
        WinActivate("ahk_id " instances[prevIndex])
    }
}

SortArray(arr) {
    str := ""
    for value in arr
        str .= value . "`n"
    sortedStr := Sort(RTrim(str, "`n"))
    return StrSplit(sortedStr, "`n")
}