반응형

윈도우 프로그래밍에 갑작스레 관심이 높아진 이후로 C# 을 통해 이것 저것 만들다보니, 매크로나 유틸리티를 만드는데 거의 필수로 사용되는 기능임에도 정리가 잘된 곳이 없어 고생하며(삽질) 습득한 지식을 정리해본다. 


물론 남이 보기엔 허섭하겠지만...



1편: API와 상수보기 (지금 페이지)

2편: API와 상수등을 이용한 키 후킹하기 / 보내기 예제



1. user32.dll 살펴보기

 윈도우 OS에서 사용하는 사용자 인터페이스 API입니다.

 user32.dll 은 그래픽 장치 인터페이스(GDI)을 통해 입력장치(키보드/마우스 등)의 데이터를 프로그램이나 장치에 전송합니다.


 즉, 키보드 / 마우스 후킹에 있어서 윈도우 OS에서 가장 중요한 라이브러리죠.

 그렇기 때문에 아래와 같은 API 를 제공하고 있습니다.



2. API 보기

2.1. 데이터를 후킹할때 사용하는 API

[DllImport("user32.dll")]

public static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc callback, IntPtr hInstance, uint threadId);

// 내 프로그램에서 후킹을 시작할 때 사용


[DllImport("user32.dll")]

public static extern bool UnhookWindowsHookEx(IntPtr hInstance);

// 내 프로그램에서 후킹을 해제할 때 사용



[DllImport("user32.dll")]

public static extern IntPtr CallNextHookEx(IntPtr idHook, int nCode, int wParam, IntPtr lParam);

// 키 입력이 일어난 원 프로그램에 값을 전달


[DllImport("kernel32.dll")]

public static extern IntPtr LoadLibrary(string lpFileName);

// user32 호출하기 위해 사용


[DllImport("user32.dll")]

public static extern ushort GetAsyncKeyState(Int32 vKey);

// 같이 눌린 키를 확인할 때 사용. 복합키 (CTRL + A 같은) 일때 사용.

// C# Keyboard.GetKeyStates 로 대체 가능합니다.



// 전역변수

private static LowLevelKeyboardProc _proc = HookProc;

private static IntPtr hhook = IntPtr.Zero;




2.2. 프로그램(또는 프로세스)에 임의의 입력값을 보낼 때 사용하는 API

[DllImport("user32.dll", EntryPoint = "FindWindowEx")]

public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

// 프로그램(또는 프로세스)의 핸들러값을 찾는다.


[DllImport("user32.dll", CharSet = CharSet.Auto)]

private static extern int SendMessage(IntPtr hWnd, int msg, int wParam, IntPtr lParam);

// 프로그램(또는 프로세스)에 내가 원하는 값을 바로 보낸다.


[DllImport("user32.dll", CharSet = CharSet.Auto)] // used for button-down & button-up

private static extern int PostMessage(IntPtr hWnd, int msg, int wParam, IntPtr lParam);

// 프로그램(또는 프로세스)에 내가 원하는 값을 윈도우 메시지큐에 쌓는다. 큐에 쌓인 값은 순차적으로 나가게 된다.


[DllImport("user32.dll", CharSet = CharSet.Auto)]

private static extern bool SetForegroundWindow(IntPtr hWnd);

// 프로그램을 활성화 시킨다. 



2.3. API 관련 상수

API에서 사용하는 상수값은 아래와 같습니다.



4. 주의할 점

`SendMassage` 혹은 `PostMessage` API는 거의 동일하게 동작하며, 실행시간도 크게 다르지 않다.

따라서 둘 중 무엇을 써도 상관은 없으나, `SendMessage`는 반환에 있어 `예상치 못한 익셉션`으로 인해 시스템이 죽어버릴 수도 있다고 합니다. (발췌)




다음편에서는 실제 사용예제를 보겠습니다.

반응형

WRITTEN BY
데르벨준

,