sample\rawinput\sample_keyhook_global.hsp » Plain Format
;============================================================
; SetWindowsHookEx WH_KEYBOARD_LL サンプル: グローバルキーフック
;
; Low-level keyboard hook で全プロセスのキーストロークを受信します。
; ホットキーマネージャ、キー履歴、自動操作検出などに応用できます。
;
; 注意:
; - setcallback が必要 (hsp3net 専用機能)
; - ブロッキング動作のため重い処理は避ける
; - 終了時に UnhookWindowsHookEx を必ず呼ぶ (さもないと全プロセスが固まる)
; - Ctrl+Alt+X で終了
;============================================================
#include "hsp3_net_64.as"
#include "user32_gen2.as"
#include "win32_types_gen2.as"
title "グローバル KeyHook サンプル"
screen 0, 720, 520, screen_normal
color 255, 255, 255 : boxf
color 0, 0, 0
pos 10, 10
mes "Windows 全体のキーストロークを受信中..."
mes "【終了】 Ctrl + Alt + X を押す"
mes ""
pos 10, 80
log_y = 80
; setcallback で LowLevelKeyboardProc を作成
; プロトタイプ: LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
setcallback *on_key_hook, 3
cb_ptr = stat
; SetWindowsHookExW(WH_KEYBOARD_LL=13, proc, hInstance=0, threadId=0)
WH_KEYBOARD_LL = 13
SetWindowsHookExW WH_KEYBOARD_LL, cb_ptr, 0, 0
hhk = stat
if hhk = 0 : dialog "SetWindowsHookEx failed" : end
terminated = 0
*main_loop
wait 2
if terminated : goto *done
goto *main_loop
; ---------------------------------------------------------
; LowLevelKeyboardProc (callback)
; nCode: < 0 なら必ず CallNextHookEx を呼んで素通し
; wParam: WM_KEYDOWN (0x100) / WM_KEYUP (0x101) /
; WM_SYSKEYDOWN (0x104) / WM_SYSKEYUP (0x105)
; lParam: KBDLLHOOKSTRUCT* へのポインタ
; struct KBDLLHOOKSTRUCT {
; DWORD vkCode; // offset 0
; DWORD scanCode; // offset 4
; DWORD flags; // offset 8
; DWORD time; // offset 12
; ULONG_PTR dwExtraInfo; // offset 16 (8 byte on x64)
; }
; ---------------------------------------------------------
*on_key_hook
n_code = callbackarg(0)
w_param = callbackarg(1)
l_param = callbackarg(2)
if n_code < 0 {
; 素通し
CallNextHookEx 0, n_code, w_param, l_param
comret stat
return
}
; l_param から KBDLLHOOKSTRUCT を読む
; lparam は intptr なので dupptr でバッファに紐付け
dupptr kbs, l_param, 24, 4 ; 24 byte, int 型
vk_code = kbs(0) ; offset 0
scan = kbs(1) ; offset 4
flags = kbs(2) ; offset 8
; 終了判定: Ctrl+Alt+X (keyup のみ)
if w_param == 0x101 { ; WM_KEYUP
if vk_code == 'X' {
dim ks1, 1
GetKeyState 0x11 ; VK_CONTROL
if (stat & 0x8000) {
GetKeyState 0x12 ; VK_MENU (Alt)
if (stat & 0x8000) {
terminated = 1
}
}
}
}
; KEYDOWN のみログ表示
if (w_param == 0x100) | (w_param == 0x104) {
; ロック系は log 取らない (CapsLock/NumLock/ScrollLock 頻出)
if (vk_code != 0x14) & (vk_code != 0x90) & (vk_code != 0x91) {
redraw 0
pos 10, log_y
; 印字可能な文字は strf
ch = ""
if (vk_code >= 'A') & (vk_code <= 'Z') : ch = strf(" '%c'", vk_code)
if (vk_code >= '0') & (vk_code <= '9') : ch = strf(" '%c'", vk_code)
if vk_code == 0x08 : ch = " [BS]"
if vk_code == 0x0D : ch = " [ENTER]"
if vk_code == 0x20 : ch = " [SP]"
if vk_code == 0x1B : ch = " [ESC]"
color 0, 0, 0
mes strf(" VK=0x%02X%s scan=0x%02X flags=0x%02X msg=0x%03X",
vk_code, ch, scan, flags, w_param)
log_y += 18
if log_y > 500 {
color 255, 255, 255 : boxf 10, 80, 710, 515
color 0, 0, 0
log_y = 80
}
}
}
; 次のフック or 既定処理へ素通し
CallNextHookEx 0, n_code, w_param, l_param
comret stat
return
*done
UnhookWindowsHookEx hhk
dialog "Hook removed. Bye!"
end