[WinAPI] SetWindowsHookEx, UnhookWindowsHookEx 키보드 마우스 후킹

오늘은 Callback 함수를 이용하여 키보드 마우스를 후킹하는 방법을 알아보도록 하겠습니다.
후킹 개념은 여기를 참고해주시기 바랍니다.

간단하게 설명하자면 A->B의 순서로 호출되는 함수를 A->C->B로 만드는 겁니다.

저는 윈도우에서 제공하는 후킹 함수로, 키보드 마우스를 후킹을 해볼겁니다.

프로젝트 하나 생성해주시고, 헤더파일에 아래와 같이 변수와 함수를 선언해주세요.

// 변수선언
static HMODULE g_hModule;
static HHOOK g_hKeyboard;
static HHOOK g_hMouse;

// 함수 선언
static LRESULT CALLBACK KeyboardProc( int nCode, WPARAM wParam, LPARAM lParam ); // 키보드 콜백함수
static LRESULT CALLBACK MouseProc( int nCode, WPARAM wParam, LPARAM lParam ); // 마우스 콜백 함수
static void SetHook(); // 후킹 설정 함수
static void UnHook(); // 후킹 해제 함수

SetHook에는 아래와 같이 코딩해주세요 SetWindowsHookEx에 후킹할 콜백 함수들을 등록합니다.

void SetHook()
{
	g_hModule = GetModuleHandle( NULL );
	if ( NULL != g_hModule )
	{
		g_hKeyboard = SetWindowsHookEx( WH_KEYBOARD_LL, KeyboardProc, g_hModule, NULL );
		g_hMouse = SetWindowsHookEx( WH_MOUSE_LL, MouseProc, g_hModule, NULL );
	}

	if ( NULL == g_hKeyboard )
		AfxMessageBox( _T( "Keyboard Hook Fail" ) );

	if ( NULL == g_hMouse )
		AfxMessageBox( _T( "Mouse Hook Fail" ) );
}

UnHook에는 아래와 같이 코딩해주세요. 후킹을 해제할 땐 UnhookWindowsHookEx 함수를 사용합니다.

void UnHook()
{
	BOOL bKeyboardUnHook = UnhookWindowsHookEx( g_hKeyboard );
	BOOL bMouseUnHook = UnhookWindowsHookEx( g_hMouse );

	if ( (TRUE == bKeyboardUnHook) && (TRUE == bMouseUnHook) )
	{
		g_hKeyboard = NULL;
		g_hMouse = NULL;

		FreeLibrary( g_hModule );
		g_hModule = NULL;		
	}
}

키보드 콜백 함수는 아래와 같이 코딩해주세요.

LRESULT CALLBACK KeyboardProc( int nCode, WPARAM wParam, LPARAM lParam )
{
	// 키보드 Down과 시스템 키 Down일 경우 처리
	if ( (WM_KEYDOWN == wParam) || (WM_SYSKEYDOWN == wParam) )
	{
    	// 필요한 코드 입력
	}

	return CallNextHookEx( g_hHook, nCode, wParam, lParam );
}

마우스 콜백 함수는 아래와 같이 코딩해주세요.

LRESULT MouseProc( int nCode, WPARAM wParam, LPARAM lParam )
{
	MOUSEHOOKSTRUCT* pMouse = (MOUSEHOOKSTRUCT*)lParam;
	// 좌표 pMouse->pt.x, pMouse->pt.y
	
	// 마우스 움직일 때
	if ( WM_MOUSEMOVE == wParam )
	{
	}
	// 왼쪽 마우스 다운
	else if ( WM_LBUTTONDOWN == wParam )
	{
	}
	// 왼쪽 마우스 업
	else if ( WM_LBUTTONUP == wParam )
	{
	}

	return CallNextHookEx( g_hMouse, nCode, wParam, lParam );
}

후킹을 걸고 싶을 땐 SetHook, 후킹을 해제할 땐 UnHook을 하시면 됩니다.

해당 코드는 낮은 수준의 후킹이여서 보안이 작동하는 프로그램으로 막힐 수도 있습니다.
만약 키보드 마우스에 Event를 날리고 싶으시면 ::mouse_event 혹은 ::keybd_event를 사용하시면 됩니다.

다음 글에서 키보드, 마우스 후킹과 ::mouse_Event, ::keybd_event에 대해서 더 자세히 설명하겠습니다.