728x90
728x170
▶ Program.cs
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace TestProject
{
/// <summary>
/// 프로그램
/// </summary>
static class Program
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Delegate
////////////////////////////////////////////////////////////////////////////////////////// Private
#region 저수준 키보드 프로시저 대리자 - LowLevelKeyboardProc(code, wordParameter, longParameter)
/// <summary>
/// 저수준 키보드 프로시저 대리자
/// </summary>
/// <param name="code">코드</param>
/// <param name="wordParameter">WORD 매개 변수</param>
/// <param name="longParameter">LONG 매개 변수</param>
/// <returns>처리 결과</returns>
private delegate IntPtr LowLevelKeyboardProc(int code, IntPtr wordParameter, IntPtr longParameter);
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Import
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Private
#region 윈도우 디스플레이 어피너티 설정하기 - SetWindowDisplayAffinity(windowHandle, affinity)
/// <summary>
/// 윈도우 디스플레이 어피너티 설정하기
/// </summary>
/// <param name="windowHandle">윈도우 핸들</param>
/// <param name="affinity">어피너티</param>
/// <returns>처리 결과</returns>
[DllImport("user32.dll")]
private static extern uint SetWindowDisplayAffinity(IntPtr windowHandle, uint affinity);
#endregion
#region 윈도우 후킹 설정하기 - SetWindowsHookEx(hookID, lowLevelKeyboardProcessDelegate, moduleHandle, threadID)
/// <summary>
/// 윈도우 후킹 설정하기
/// </summary>
/// <param name="hookID">후킹 ID</param>
/// <param name="lowLevelKeyboardProc">저수준 키보드 처리 대리자</param>
/// <param name="moduleHandle">모듈 핸들</param>
/// <param name="threadID">쓰레드 ID</param>
/// <returns>후킹 핸들</returns>
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx
(
int hookID,
LowLevelKeyboardProc lowLevelKeyboardProc,
IntPtr moduleHandle,
uint threadID
);
#endregion
#region 윈도우 후킹 취소하기 - UnhookWindowsHookEx(hookHandle)
/// <summary>
/// 윈도우 후킹 취소하기
/// </summary>
/// <param name="hookHandle">후킹 핸들</param>
/// <returns>처리 결과</returns>
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hookHandle);
#endregion
#region 다음 후킹 호출하기 - CallNextHookEx(hookHandle, code, wordParameter, longParameter)
/// <summary>
/// 다음 후킹 호출하기
/// </summary>
/// <param name="hookHandle">후킹 핸들</param>
/// <param name="code">코드</param>
/// <param name="wordParameter">WORD 매개 변수</param>
/// <param name="longParameter">LONG 매개 변수</param>
/// <returns>후킹 핸들</returns>
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hookHandle, int code, IntPtr wordParameter, IntPtr longParameter);
#endregion
#region 모듈 핸들 구하기 - GetModuleHandle(moduleName)
/// <summary>
/// 모듈 핸들 구하기
/// </summary>
/// <param name="moduleName">모듈명</param>
/// <returns>모듈 핸들</returns>
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string moduleName);
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// 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_KEYUP
/// </summary>
private const int WM_KEYUP = 0x101;
/// <summary>
/// WDA_NONE
/// </summary>
private const uint WDA_NONE = 0;
/// <summary>
/// WDA_MONITOR
/// </summary>
private const uint WDA_MONITOR = 1;
/// <summary>
/// 저수준 키보드 프로시저 대리자
/// </summary>
private static LowLevelKeyboardProc _lowLevelKeyboardProc = HookCallback;
/// <summary>
/// 후킹 핸들
/// </summary>
private static IntPtr _hookHandle = IntPtr.Zero;
/// <summary>
/// 메인 폼
/// </summary>
private static MainForm _mainForm;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Static
//////////////////////////////////////////////////////////////////////////////// Private
#region 프로그램 시작하기 - Main()
/// <summary>
/// 프로그램 시작하기
/// </summary>
[STAThread]
private static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
_hookHandle = SetHook(_lowLevelKeyboardProc);
_mainForm = new MainForm();
Application.Run(_mainForm);
UnhookWindowsHookEx(_hookHandle);
}
#endregion
#region 후킹 콜백 처리하기 - HookCallback(code, wordParameter, longParameter)
/// <summary>
/// 후킹 콜백 처리하기
/// </summary>
/// <param name="code">코드</param>
/// <param name="wordParameter">WORD 매개 변수</param>
/// <param name="longParameter">LONG 매개 변수</param>
/// <returns>후킹 핸들</returns>
private static IntPtr HookCallback(int code, IntPtr wordParameter, IntPtr longParameter)
{
if(code >= 0 && wordParameter == (IntPtr)WM_KEYDOWN)
{
int vkCode = Marshal.ReadInt32(longParameter);
if(vkCode == 44) // PRINT SCREEN KEY
{
SetWindowDisplayAffinity(_mainForm.Handle, WDA_MONITOR);
Console.WriteLine("KEYDOWN");
Console.WriteLine((Keys)vkCode);
}
}
else if(code >= 0 && wordParameter == (IntPtr)WM_KEYUP)
{
int vkCode = Marshal.ReadInt32(longParameter);
if(vkCode == 44) // PRINT SCREEN KEY
{
SetWindowDisplayAffinity(_mainForm.Handle, WDA_NONE);
Console.WriteLine("KEYDOWN");
Console.WriteLine((Keys)vkCode);
}
}
return CallNextHookEx(_hookHandle, code, wordParameter, longParameter);
}
#endregion
#region 후킹 설정하기 - SetHook(lowLevelKeyboardProc)
/// <summary>
/// 후킹 설정하기
/// </summary>
/// <param name="lowLevelKeyboardProc">저수준 키보드 프로시저 대리자</param>
/// <returns>후킹 핸들</returns>
private static IntPtr SetHook(LowLevelKeyboardProc lowLevelKeyboardProc)
{
using(Process process = Process.GetCurrentProcess())
{
using(ProcessModule processModule = process.MainModule)
{
return SetWindowsHookEx
(
WH_KEYBOARD_LL,
lowLevelKeyboardProc,
GetModuleHandle(processModule.ModuleName),
0
);
}
}
}
#endregion
}
}
728x90
그리드형(광고전용)
'C# > WinForm' 카테고리의 다른 글
[C#/WINFORM] Bitmap 클래스 : 합성 이미지 만들기 (0) | 2020.12.25 |
---|---|
[C#/WINFORM] 화면 보호기/절전 모드 방지하기/허용하기 (0) | 2020.12.21 |
[C#/WINFORM] Form 클래스 : CreateParams 속성을 사용해 작업 전환기(Tab Switcher)에서 애플리케이션 숨기기 (0) | 2020.12.19 |
[C#/WINFORM] SVG 이미지 사용하기 (0) | 2020.12.19 |
[C#/WINFORM] 관리자 권한으로 실행하기 (0) | 2020.12.18 |
[C#/WINFORM] Control 클래스 : WndProc 메소드를 사용해 데이터 수신하기 (0) | 2020.12.05 |
[C#/WINFORM] 특정 프로세스의 윈도우 핸들 구하기 (0) | 2020.12.05 |
[C#/WINFORM] 누겟 설치 : Microsoft.Windows.Shell (0) | 2020.11.17 |
[C#/WINFORM] TextBox 클래스 : 영숫자/통화/날짜/정수/마스크/숫자 입력하기 (0) | 2020.11.13 |
[C#/WINFORM] SendKeys 클래스 : Send 정적 메소드를 사용해 이동 키 누르기 (0) | 2020.11.12 |