반응형
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Threading;
using System.Diagnostics;
namespace KeyHook
{
class HookKey
{
[DllImport("user32.dll")]
private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyProc callback, IntPtr hInstance, uint threadId);
[DllImport("user32.dll")]
private static extern bool UnhookWindowsHookEx(IntPtr hInstance);
[DllImport("user32.dll")]
private static extern IntPtr CallNextHookEx(IntPtr idHook, int nCode, int wParam, IntPtr lParam);
[DllImport("kernel32.dll")]
private static extern IntPtr GetModuleHandle(string lpModuleName);
private const int WH_KEYBOARD_LL = 13;
private const int WM_KEYDOWN = 0x100;
private delegate IntPtr LowLevelKeyProc(int nCode, IntPtr wParam, IntPtr lParam);
//이 위로는 DLL import 등입니다.
private static LowLevelKeyProc keyboardProc = KeyboardHookProc;
private static IntPtr keyHook = IntPtr.Zero;
private static Queue<char> texts = new Queue<char>();
public void SetHook() {
if (keyHook == IntPtr.Zero) {
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule) {
keyHook = SetWindowsHookEx(WH_KEYBOARD_LL, keyboardProc, GetModuleHandle(curModule.ModuleName), 0);
}
}
}
public static void UnHook() {
UnhookWindowsHookEx(keyHook);
}
private static IntPtr KeyboardHookProc(int code, IntPtr wParam, IntPtr lParam) {
//Code가 0보다 클 때에만 처리해야합니다. 아닐 경우엔 메세지를 흘려보냅니다.(이유는 잘 모릅니다.)
//wParam==256부분은, 키보드를 누르는 이벤트와 떼는 이벤트 중 누르는 이벤트만을 통과시킵니다.
//만약 ==267로 바꿀 경우, 키보드를 땔 떼 코드가 실행됩니다.
if (code >= 0 && (int)wParam == 256) {
//lParam포인터가 가리키는 곳에서 키코드를 읽어 keyCheck로 보냅니다.
texts.Enqueue(Convert.ToChar(Marshal.ReadInt32(lParam)));//texts큐에 데이터를 집어넣음
//return (IntPtr)1; <- 키를 씹을 수 있음
}
return CallNextHookEx(keyHook, code, (int)wParam, lParam);
}
String ttmp = "";
public void checkdata()
{
while (true) {
Thread.Sleep(100);
if (texts.Count > 0) {
char tmp = texts.Dequeue();
//if (tmp == 'p') ttmp += "F1을눌렀음";
ttmp += tmp;
}
}
}
public string getdata()
{
return ttmp;
}
private void Form1_Load(object sender, EventArgs e) {
SetHook();
new Thread(new ThreadStart(checkdata)).Start();
}
}
}
|
cs |
해당 키보드 후킹 코드를 사용하였을 때(참고 : LINK) F1~F12코드는 p ~ {로 찍히는걸 확인
따라서 일반적인 GetAsyncKeyState에서 F1~F12에 해당하는 0x70~0x7B를 사용해도 인식을 하지 못함
(Windows 10 1903버전부터 해당하는것같음)
따라서 위 후킹 코드의 getdata()함수를 통해 입력된 키코드값을 받아와 직접 매핑하여 핫키처리를 수행하면 편리함
반응형
'개발 > C#' 카테고리의 다른 글
[Winform] Tulpep을 이용한 윈도우 Alert 생성하기 (0) | 2023.06.20 |
---|---|
Network Check - HttpWebRequest, HttpWebResponse 이용 (0) | 2021.06.09 |
C# Form Auto Closing Message Box 만들기 (2) | 2017.01.03 |
C# 싱글톤 클래스 이용하기(singleton class,singleton pattern) (0) | 2016.12.11 |
C#-Oxyplot 연동하기!(1/2) (0) | 2016.11.14 |