다른 명령
키보드 후킹 예제
- AutoIt에서 SetWindowsHookEx를 이용해 키보드 입력을 가로채고, 특정 키를 F13~F20으로 매핑하는 예제
- 예: CapsLock 키를 누르면 F13(가상 키 코드 0x7C)을 대신 보내도록 시스템 레벨에서 처리합니다.
- 이 코드는 모든 창에서 작동하며, 일반적인 HotKeySet()보다 안정적입니다.
준비 사항
- 반드시 AutoIt을 관리자 권한으로 실행하세요.
- WinAPIEx.au3 또는 유사한 API 확장 라이브러리가 필요합니다.
⸻
소스 코드 예제 (SetWindowsHookEx 기반 키보드 후킹)
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <StructureConstants.au3>
Global $hHook, $hMod
; DLL 콜백 등록
Global $pFunc = DllCallbackRegister("_LowLevelKeyboardProc", "long", "int;wparam;lparam")
; 현재 모듈 핸들
$hMod = _WinAPI_GetModuleHandle(0)
; 후킹 시작 (WH_KEYBOARD_LL = 13)
$hHook = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($pFunc), $hMod, 0)
If @error Or $hHook = 0 Then
MsgBox(16, "Error", "Hook 설치 실패!")
Exit
EndIf
; 메시지 루프 유지
While True
Sleep(100)
WEnd
; 프로그램 종료 시 후킹 해제
DllCallbackFree($pFunc)
_WinAPI_UnhookWindowsHookEx($hHook)
; 후킹 함수 정의
Func _LowLevelKeyboardProc($nCode, $wParam, $lParam)
If $nCode < 0 Then
Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
EndIf
Local $tKBDLLHOOKSTRUCT = DllStructCreate($tagKBDLLHOOKSTRUCT, $lParam)
Local $vkCode = DllStructGetData($tKBDLLHOOKSTRUCT, "vkCode")
; 눌림 이벤트만 처리
If $wParam = $WM_KEYDOWN Or $wParam = $WM_SYSKEYDOWN Then
; CapsLock(0x14) 키를 F13(0x7C)로 대체
If $vkCode = 0x14 Then
_SendVirtualKey(0x7C) ; F13
Return 1 ; 원래 키는 무시
EndIf
EndIf
Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
EndFunc
Func _SendVirtualKey($vk)
_WinAPI_Keybd_Event($vk, 0, 0, 0) ; key down
_WinAPI_Keybd_Event($vk, 0, $KEYEVENTF_KEYUP, 0) ; key up
EndFunc
프로그램 확장 예시
- 다른 키도 다음처럼 바꿀 수 있습니다:
If $vkCode = 0x2D Then ; Insert
_SendVirtualKey(0x7D) ; F14
Return 1
EndIf
If $vkCode = 0x91 Then ; ScrollLock
_SendVirtualKey(0x7E) ; F15
Return 1
EndIf
참고자료
키 이름 가상 키 코드 (Hex) 설명 F13 ~ F20 0x7C ~ 0x83 확장 펑션키 CapsLock 0x14 일반 키 Insert 0x2D 일반 키 Scroll Lock 0x91 일반 키
⚠️ 주의사항
- 후킹은 시스템 자원을 사용하는 민감한 작업입니다.
- 잘못 구현 시 전체 시스템이 느려질 수 있습니다.
- 키를 너무 많이 리매핑하면 충돌이 생길 수 있으므로 필요한 키만 설정하세요.
트레이에 등록 하여 사용 하는 방법
- 키보드 후킹 프로그램을 트레이 아이콘으로 실행하고, 우클릭 시 종료 메뉴가 뜨도록 만들기
기능 요약
- CapsLock 키를 F13으로 변환
- 트레이 아이콘 표시
- 트레이 아이콘 우클릭 → 종료 메뉴 제공
전체 코드 (트레이 포함)
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <StructureConstants.au3>
#include <TrayConstants.au3>
#include <MsgBoxConstants.au3>
Global $hHook, $hMod
Global $pFunc = DllCallbackRegister("_LowLevelKeyboardProc", "long", "int;wparam;lparam")
Global $hMod = _WinAPI_GetModuleHandle(0)
; 트레이 아이콘 설정
#NoTrayIcon
TraySetToolTip("F13 키 후킹 프로그램")
TraySetClick(8) ; 우클릭 감지
TrayCreateItem("종료")
TraySetState($TRAY_ICONSTATE_SHOW)
; 후킹 설치
$hHook = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($pFunc), $hMod, 0)
If @error Or $hHook = 0 Then
MsgBox($MB_ICONERROR, "오류", "후킹 설치 실패!")
Exit
EndIf
; 메시지 루프
While True
Switch TrayGetMsg()
Case 0 ; 아무 동작 없음
; pass
Case 1 ; "종료" 클릭 시
ExitLoop
EndSwitch
Sleep(50)
WEnd
; 종료 처리
_WinAPI_UnhookWindowsHookEx($hHook)
DllCallbackFree($pFunc)
TraySetState($TRAY_ICONSTATE_HIDE)
Exit
; 후킹 함수
Func _LowLevelKeyboardProc($nCode, $wParam, $lParam)
If $nCode < 0 Then
Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
EndIf
Local $tKBDLLHOOKSTRUCT = DllStructCreate($tagKBDLLHOOKSTRUCT, $lParam)
Local $vkCode = DllStructGetData($tKBDLLHOOKSTRUCT, "vkCode")
; 눌림만 처리
If $wParam = $WM_KEYDOWN Or $wParam = $WM_SYSKEYDOWN Then
; CapsLock → F13
If $vkCode = 0x14 Then
_SendVirtualKey(0x7C) ; F13
Return 1 ; 원래 키 무시
EndIf
EndIf
Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
EndFunc
Func _SendVirtualKey($vk)
_WinAPI_Keybd_Event($vk, 0, 0, 0) ; down
_WinAPI_Keybd_Event($vk, 0, $KEYEVENTF_KEYUP, 0) ; up
EndFunc
실행 방법
- .au3 파일로 저장 (예: F13_Tray.au3)
- AutoIt 스크립트로 실행하거나, SciTE 또는 Aut2Exe로 .exe로 컴파일
- 실행 후 트레이 아이콘 확인
- CapsLock 키를 누르면 F13처럼 동작
- 트레이 아이콘 우클릭 → 종료
추가 팁
- 아이콘 변경: TraySetIcon("icon.ico")
- 더 많은 단축키 추가 가능 (Insert → F14, ScrollLock → F15 등)
- TrayCreateItem()에 여러 항목 추가해 기능 확장 가능
#include <WinAPIProc.au3>
#include <WindowsConstants.au3>
Global Const $WH_KEYBOARD_LL = 13
Global Const $WM_KEYDOWN = 0x0100
Global Const $WM_KEYUP = 0x0101
Global Const $WM_SYSKEYDOWN = 0x0104
Global Const $WM_SYSKEYUP = 0x0105
Global $g_hHook = 0
Global $g_hStub_KeyProc = 0
; ── 콜백 함수 등록 ──
$g_hStub_KeyProc = DllCallbackRegister("_KEYBOARD_HOOK_PROC", "long", "int;wparam;lparam")
; ── 훅 설치 ──
$g_hHook = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, _
DllCallbackGetPtr($g_hStub_KeyProc), _
_WinAPI_GetModuleHandle(0))
If $g_hHook = 0 Then
debugprint("키보드 훅 설치 실패")
Exit
EndIf
debugprint("키보드 훅 설치 완료 - ESC로 종료")
; ── 메인 루프 (메시지 펌프 필수) ──
While 1
Sleep(10)
WEnd
; ── 종료 처리 ──
Func _EXIT_HOOK()
_WinAPI_UnhookWindowsHookEx($g_hHook)
DllCallbackFree($g_hStub_KeyProc)
EndFunc
; ── 키보드 훅 콜백 ──
Func _KEYBOARD_HOOK_PROC($nCode, $wParam, $lParam)
If $nCode < 0 Then Return _WinAPI_CallNextHookEx($g_hHook, $nCode, $wParam, $lParam)
; KBDLLHOOKSTRUCT 구조체에서 정보 추출
Local $tKBDLL = DllStructCreate( _
"dword vkCode;" & _ ; 가상키 코드
"dword scanCode;" & _ ; 스캔코드
"dword flags;" & _ ; 확장키, injected 등 플래그
"dword time;" & _ ; 타임스탬프
"ulong_ptr dwExtraInfo", _ ; 추가 정보
$lParam)
Local $iVKCode = DllStructGetData($tKBDLL, "vkCode")
Local $iScanCode = DllStructGetData($tKBDLL, "scanCode")
Local $iFlags = DllStructGetData($tKBDLL, "flags")
; 키 상태 판별
Local $sState = ""
Switch $wParam
Case $WM_KEYDOWN, $WM_SYSKEYDOWN
$sState = "DOWN"
Case $WM_KEYUP, $WM_SYSKEYUP
$sState = "UP"
EndSwitch
; 확장키 여부 (Right Ctrl, Right Alt, Insert, Delete, 방향키 등)
Local $bExtended = BitAND($iFlags, 1)
debugprint("[" & $sState & "] VK=0x" & Hex($iVKCode, 2) & _
" Scan=0x" & Hex($iScanCode, 2) & _
" Ext=" & $bExtended & _
" Key=" & _VK_TO_NAME($iVKCode))
; ESC 키로 종료
If $iVKCode = 0x1B And $sState = "DOWN" Then
_EXIT_HOOK()
Exit
EndIf
; ── 키 가로채기 예시 ──
; 특정 키를 먹고 싶으면 여기서 Return 1 (다음 훅으로 전달 안 함)
; If $iVKCode = 0x41 Then Return 1 ; A키 차단
; 정상 전달
Return _WinAPI_CallNextHookEx($g_hHook, $nCode, $wParam, $lParam)
EndFunc
; ── VK코드 → 키 이름 변환 (주요 키) ──
Func _VK_TO_NAME($iVK)
Switch $iVK
Case 0x08
Return "Backspace"
Case 0x09
Return "Tab"
Case 0x0D
Return "Enter"
Case 0x10
Return "Shift"
Case 0x11
Return "Ctrl"
Case 0x12
Return "Alt"
Case 0x14
Return "CapsLock"
Case 0x1B
Return "ESC"
Case 0x20
Return "Space"
Case 0x25
Return "Left"
Case 0x26
Return "Up"
Case 0x27
Return "Right"
Case 0x28
Return "Down"
Case 0x2E
Return "Delete"
Case 0x5B
Return "LWin"
Case 0x5C
Return "RWin"
Case 0xA0
Return "LShift"
Case 0xA1
Return "RShift"
Case 0xA2
Return "LCtrl"
Case 0xA3
Return "RCtrl"
Case 0xA4
Return "LAlt"
Case 0xA5
Return "RAlt"
Case 0x30 To 0x39
Return Chr($iVK) ; 0~9
Case 0x41 To 0x5A
Return Chr($iVK) ; A~Z
Case 0x70 To 0x87
Return "F" & ($iVK - 0x6F) ; F1~F24
Case Else
Return "0x" & Hex($iVK, 2)
EndSwitch
EndFunc
주요 포인트를 정리하면 다음과 같습니다.
동작 원리 — $WH_KEYBOARD_LL(13)은 저수준 키보드 훅으로, 시스템 전체의 키 입력을 가로챕니다. 포커스가 어느 프로그램에 있든 상관없이 모든 키 입력이 콜백으로 들어옵니다.
KBDLLHOOKSTRUCT — $lParam이 가리키는 구조체에서 vkCode(가상키), scanCode(스캔코드), flags(확장키·주입 여부)를 추출합니다. flags의 bit 0이 1이면 확장키(Right Ctrl, Right Alt 등)입니다.
키 차단 — 콜백에서 Return 1을 하면 해당 키 입력이 다른 프로그램에 전달되지 않습니다. 정상 전달하려면 반드시 _WinAPI_CallNextHookEx를 호출해야 합니다.
메시지 펌프 필수 — 메인 루프에서 Sleep(10) 등으로 메시지 처리가 돌아야 훅 콜백이 정상 호출됩니다. 메인 루프가 멈추면 시스템 전체 키 입력이 지연될 수 있으므로, 콜백 안에서 무거운 처리는 피해야 합니다.
종료 시 — _WinAPI_UnhookWindowsHookEx로 훅을 해제하고 DllCallbackFree로 콜백을 반드시 해제해야 메모리 누수가 없습니다.