728x90
728x170
▶ LowLevelKeyboardHook.cs
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace TestProject
{
/// <summary>
/// 저수준 키보드 후킹
/// </summary>
public class LowLevelKeyboardHook
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Delegate
////////////////////////////////////////////////////////////////////////////////////////// Private
#region 저수준 키보드 대리자 - LowLevelKeyboardDelegate(code, wordParameter, longParameter)
/// <summary>
/// 저수준 키보드 대리자
/// </summary>
/// <param name="code">코드</param>
/// <param name="wordParameter">WORD 매개 변수</param>
/// <param name="longParameter">LONG 매개 변수</param>
/// <returns></returns>
private delegate IntPtr LowLevelKeyboardDelegate(int code, IntPtr wordParameter, IntPtr longParameter);
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Import
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Private
#region 모듈 핸들 구하기 - GetModuleHandle(moduleName)
/// <summary>
/// 모듈 핸들 구하기
/// </summary>
/// <param name="moduleName">모듈명</param>
/// <returns>모듈 핸들</returns>
[DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string moduleName);
#endregion
#region 윈도우즈 후킹 설정하기 (확장) - SetWindowsHookEx(hookType, callback, moduleHandle, threadID)
/// <summary>
/// 윈도우즈 후킹 설정하기 (확장)
/// </summary>
/// <param name="hookType">후킹 타입</param>
/// <param name="callback">콜백 함수</param>
/// <param name="moduleHandle">모듈 핸들</param>
/// <param name="threadID">쓰레드 ID</param>
/// <returns>후킹 ID</returns>
[DllImport("user32", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int hookType, LowLevelKeyboardDelegate callback, IntPtr moduleHandle, uint threadID);
#endregion
#region 다음 후킹 호출하기 (확장) - CallNextHookEx(hookID, code, wordParameter, longParameter)
/// <summary>
/// 다음 후킹 호출하기 (확장)
/// </summary>
/// <param name="hookID">후킹 ID</param>
/// <param name="code">코드</param>
/// <param name="wordParameter">WORD 매개 변수</param>
/// <param name="longParameter">LONG 매개 변수</param>
/// <returns>후킹 ID</returns>
[DllImport("user32", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hookID, int code, IntPtr wordParameter, IntPtr longParameter);
#endregion
#region 윈도우즈 후킹 취소하기 (확장) - UnhookWindowsHookEx(hookID)
/// <summary>
/// 윈도우즈 후킹 취소하기 (확장)
/// </summary>
/// <param name="hookID">후킹 ID</param>
/// <returns>처리 결과</returns>
[DllImport("user32", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hookID);
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Event
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 키 PRESSED 이벤트 - KeyPressed
/// <summary>
/// 키 PRESSED 이벤트
/// </summary>
public event EventHandler<Keys> KeyPressed;
#endregion
#region 키 UNPRESSED 이벤트 - KeyUnpressed
/// <summary>
/// 키 UNPRESSED 이벤트
/// </summary>
public event EventHandler<Keys> KeyUnpressed;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// WH_KEYBOARD_LL
/// </summary>
private const int WH_KEYBOARD_LL = 13;
/// <summary>
/// WM_KEYDOWN
/// </summary>
private const int WM_KEYDOWN = 0x0100;
/// <summary>
/// WM_SYSKEYDOWN
/// </summary>
private const int WM_SYSKEYDOWN = 0x0104;
/// <summary>
/// WM_KEYUP
/// </summary>
private const int WM_KEYUP = 0x101;
/// <summary>
/// WM_SYSKEYUP
/// </summary>
private const int WM_SYSKEYUP = 0x105;
/// <summary>
/// 저수준 키보드 대리자
/// </summary>
private LowLevelKeyboardDelegate lowLevelKeyboardDelegate;
/// <summary>
/// 후킹 ID
/// </summary>
private IntPtr hookID = IntPtr.Zero;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - LowLevelKeyboardHook()
/// <summary>
/// 생성자
/// </summary>
public LowLevelKeyboardHook()
{
this.lowLevelKeyboardDelegate = ProcessLowLevelKeyboard;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 키보드 후킹하기 - HookKeyboard()
/// <summary>
/// 키보드 후킹하기
/// </summary>
public void HookKeyboard()
{
this.hookID = SetHook(this.lowLevelKeyboardDelegate);
}
#endregion
#region 키보드 후킹 취소하기 - UnHookKeyboard()
/// <summary>
/// 키보드 후킹 취소하기
/// </summary>
public void UnHookKeyboard()
{
UnhookWindowsHookEx(this.hookID);
}
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Private
#region 후킹 설정하기 - SetHook(lowLevelKeyboardDelegate)
/// <summary>
/// 후킹 설정하기
/// </summary>
/// <param name="lowLevelKeyboardDelegate">저수준 키보드 대리자</param>
/// <returns>후킹 ID</returns>
private IntPtr SetHook(LowLevelKeyboardDelegate lowLevelKeyboardDelegate)
{
using(Process process = Process.GetCurrentProcess())
{
using(ProcessModule processModule = process.MainModule)
{
return SetWindowsHookEx
(
WH_KEYBOARD_LL,
lowLevelKeyboardDelegate,
GetModuleHandle(processModule.ModuleName),
0
);
}
}
}
#endregion
#region 저수준 키보드 처리하기 - ProcessLowLevelKeyboard(code, wordParameter, longParameter)
/// <summary>
/// 저수준 키보드 처리하기
/// </summary>
/// <param name="code">코드</param>
/// <param name="wordParameter">WORD 매개 변수</param>
/// <param name="longParameter">LONG 매개 변수</param>
/// <returns>처리 결과</returns>
private IntPtr ProcessLowLevelKeyboard(int code, IntPtr wordParameter, IntPtr longParameter)
{
if(code >= 0 && wordParameter == (IntPtr)WM_KEYDOWN || wordParameter == (IntPtr)WM_SYSKEYDOWN)
{
int vkCode = Marshal.ReadInt32(longParameter);
KeyPressed?.Invoke(this, ((Keys)vkCode));
}
else if(code >= 0 && wordParameter == (IntPtr)WM_KEYUP || wordParameter == (IntPtr)WM_SYSKEYUP)
{
int vkCode = Marshal.ReadInt32(longParameter);
KeyUnpressed?.Invoke(this, ((Keys)vkCode));
}
return CallNextHookEx(hookID, code, wordParameter, longParameter);
}
#endregion
}
}
728x90
▶ MainForm.cs
using System.Windows.Forms;
namespace TestProject
{
/// <summary>
/// 메인 폼
/// </summary>
public partial class MainForm : Form
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MainForm()
/// <summary>
/// 생성자
/// </summary>
public MainForm()
{
InitializeComponent();
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 메시지 표시하기 - DisplayMessage(keys)
/// <summary>
/// 메시지 표시하기
/// </summary>
/// <param name="keys">키</param>
public void DisplayMessage(Keys keys)
{
this.messageLabel.Text = keys.ToString();
}
#endregion
}
}
300x250
▶ Program.cs
using System;
using System.Windows.Forms;
namespace TestProject
{
/// <summary>
/// 프로그램
/// </summary>
class Program
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Private
#region 프로그램 시작하기 - Main()
/// <summary>
/// 프로그램 시작하기
/// </summary>
[STAThread]
private static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
MainForm mainForm = new MainForm();
LowLevelKeyboardHook keyboardHook = new LowLevelKeyboardHook();
keyboardHook.KeyPressed += (sender, e) => mainForm.DisplayMessage(e);
keyboardHook.HookKeyboard();
Application.Run(mainForm);
keyboardHook.UnHookKeyboard();
}
#endregion
}
}
728x90
그리드형(광고전용)
'C# > WinForm' 카테고리의 다른 글
[C#/WINFORM] ListView 클래스 : RetrieveVirtualItem 이벤트를 사용해 대용량 데이터 조회하기 (0) | 2022.07.20 |
---|---|
[C#/WINFORM] 고품질 이미지 크기 변경하기 (0) | 2022.07.05 |
[C#/WINFORM/.NET6] FontFamily 클래스 : GenericMonospace 정적 속성을 사용해 고정 폭 폰트 만들기 (0) | 2022.07.04 |
[C#/WINFORM/.NET6] Application 클래스 : ProductVersion 정적 속성을 사용해 프로그램 버전 구하기 (0) | 2022.06.21 |
[C#/WINFORM/.NET6] SoundPlayer 클래스 : PlaySync 메소드를 사용해 비프음 만들기 (0) | 2022.06.10 |
[C#/WINFORM] 멀티미디어 타이머 사용하기 (0) | 2022.05.25 |
[C#/WINFORM] 날짜 형식 버전 사용하기 (0) | 2022.05.25 |
[C#/WINFORM] MessageBox 클래스 : Show 정적 메소드를 사용해 최상위 메시지 박스 표시하기 (0) | 2022.05.14 |
[C#/WINFORM] Screen 클래스 : FromHandle 정적 메소드를 사용해 폼 최대화시 윈도우 작업표시줄 가리지 않기 (0) | 2022.05.13 |
[C#/WINFORM] UserControl 클래스 : 대용량 이미지 갤러리 사용하기 (0) | 2022.05.12 |