프로그래밍

[AutoHotKey] 단축키 키보드 에뮬레이션 문제점에 관하여 (Send, ControlSend)

채윤아빠 2021. 8. 10. 09:26
728x90
반응형


AutoHotKey의 키보드 에뮬레이션으로 단축키(Hot-key)를 이용할 때, 보편적으로 "Send", "ControlSend" 두 내장함수를 이용하게 됩니다.

일반적인 경우 아무런 문제없이 잘 동작합니다. 하지만, 저와 같이 전체 윈도우 중에 현재 활성화된 윈도우에 키보드 에뮬레이션을 하는 것이 아닌 활성화되지 않았더라도 특정 윈도우에만 지속적으로 에뮬레이션하고자 할 때는 적합하지 않습니다.

아래와 같이 특정 문구를 로깅을 위한 메모창과 파일에 기록하는 함수를 작성하였습니다.

; @brief 입력한 내용을 로그창 및 파일에 기록한다.
;        로그 파일은 .\Logs\lr-yyyyMMdd.log 파일에 시각 정보를 포함하여 기록된다.
; @param strMsg 기록할 로그의 내용
AppendLogWindow(strMsg)
{
    global g_hwndLogEditControl

    FormatTime, strTime, , HH:mm:ss
    strTime .= " " . strMsg

    ControlSend, , ^{End}`n, ahk_id %g_hwndLogEditControl%
    SendMessage, 0xC2, 0, &strTime,, ahk_id %g_hwndLogEditControl%

    FormatTime, strLogFileName, , yyyyMMdd
    strLogFileName := ".\Logs\lr-" . strLogFileName . ".log"
    FileAppend, %strTime%`r`n, %strLogFileName%
}

"ControlSend, , ^{End}`n, ahk_id %g_hwndLogEditControl%" 이 코드는 메모창의 마지막 줄로 이동하는 단축키인 + 를 이용하여 끝까지 이동한 후에, 를 입력하여 다음 로그를 출력할 위치로 이동하도록 하려는 의도로 작성되었습니다.

아무런 문제 없이 정상적으로 로깅이 잘 처리됩니다. 그런데 위와 같은 함수로 로깅하도록 한 상태에서 다른 편집 프로그램에서 열심히 문자를 입력하는 도중에 편집 프로그램의 단축키가 동작하는 비정상적인 상황이 가끔 지속적으로 발생하였습니다.

문제는 "ControlSend" 내장 함수를 이용하여 단축키인 + 를 보내는 과정에서 키가 전역으로 에뮬레이션 처리한다는 점이었습니다. 그래서 다른 프로그램에서 편집중에 로깅되는 순간 눌린 상태가 되어 글자가 입력되어야 하는 상황에서 단축키가 동작하는 불상사가 발생하곤 하였던 것입니다.

이와 같은 경우에 대한 해결 방법은 아래와 같이 단순하게 로깅할 문자열 마지막에 미리 줄바꿈을 추가해 주는 것입니다.

; @brief 입력한 내용을 로그창 및 파일에 기록한다.
;        로그 파일은 .\Logs\lr-yyyyMMdd.log 파일에 시각 정보를 포함하여 기록된다.
; @param strMsg 기록할 로그의 내용
AppendLogWindow(strMsg)
{
    global g_hwndLogEditControl

    FormatTime, strTime, , HH:mm:ss
    strTime .= " " . strMsg . chr(13) . chr(10)

    SendMessage, 0xC2, 0, &strTime,, ahk_id %g_hwndLogEditControl%

    FormatTime, strLogFileName, , yyyyMMdd
    strLogFileName := ".\Logs\lr-" . strLogFileName . ".log"
    FileAppend, %strTime%, %strLogFileName%
}

그러나 꼭 단축키를 이용해야만 하는 경우라면, WM_KEY_DOWN, WM_KEY_UP 등의 메시지를 직접 에뮬레이션 해주어야만 합니다.

메모장에서 + 단축키를 누르를 동작을 Spy++을 이용하여 키보드 메시지들을 확인하면 다음 화면과 같습니다.

위 화면의 메시지들을 AutoHotKey로 에뮬레이션하는 코드를 작성하면 다음과 같습니다.

hwndNotepad = 0x002221CE

PostMessage, 0x100, 0x11, 0x001D0001, , ahk_id %hwndNotepad% ; 0x100 = WM_KEYDOWN ; 0x11 = VK_CONTROL
PostMessage, 0x100, 0x23, 0x014F0001, , ahk_id %hwndNotepad% ; 0x100 = WM_KEYDOWN ; 0x23 = VK_END
PostMessage, 0x101, 0x23, 0xC14F0001, , ahk_id %hwndNotepad% ; 0X101 = WM_KEYUP ; 0x23 = VK_END
PostMessage, 0x101, 0x11, 0xC01D0001, , ahk_id %hwndNotepad% ; 0X101 = WM_KEYUP ; 0x11 = VK_CONTROL

위와 같이 작성하고, 실행하면 대상 hwndNotepad 창에 + 가 모의하여 동작하게 됩니다.

결론은 "Send", "ControlSend" 등의 내장 키보드 에뮬레이션 함수에서 , , 등과 조합된 단축키를 이용할 경우 , , 키가 현재 활성화된 윈도우에도 영향을 받기 때문에 이용시 주의가 필요합니다.