프로그래밍/MFC

훅 프로시저

이재만박사 2018. 2. 9. 11:05

훅 체인에 등록되어 메시지를 감시하는 함수를 훅 프로시저(Hook Procedure)라고 한다


훅 타입에 따라 훅 프로시저의 인수나 리턴값의 의미는 달라지지만 원형은 고정되어 있다


다음은 WH_KEYBOARD 타입의 키보드 훅 프로시저인데 다른 타입의 훅 프로시저도 이름만 다르고 원형은 동일하다


LRESULT CALLBACK KeyboardProc( int code, WPARAM wParam, LPARAM lParam);


훅 프로시저는 응용 프로그램이 제공하는 콜백함수이므로 원형만 제대로 지킨다면 이름은 마음대로 정할 수 있다


세 개의 인수


1. code : 훅 프로시저에서 이 메시지를 어떻게 처리할 것인가를 지정

           이 값이 음수이면 훅 프로시저는 이 메시지를 처리하지 말고 다음

           훅 프로시저에게 메시지를 넘김


2. wParam : 메시지 추가 정보


3. lParam : 메시지 추가 정보


훅 프로시저를 설치할 때는 다음 함수를 사용한다


HHOOK SetWindowsHookEx

( int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId );



1. idHook : 설치하고자 하는 훅의 타입을 지정

              WH_로 시작되는 매크로 상수중 하나를 사용


2. lpfn : 훅 프로시저의 번지


3. hMod : 훅 프로시저를 가진 인스턴스 핸들


4. dwThreadId : 훅 프로시저가 감시할 스레드의 ID

                   이 값이 0이면 시스템의 모든 스레드에서 발생하는 메시지가 훅                     프로시저로 전달



자신의 메시지를 훅킹할 때는 GetCurrentTrheadId 함수로 현재 스레드의 ID를 넘긴다


시스템의 모든 메시지를 감시하고자 한다거나 다른 프로그램의 메시지를 감시하고자 할 경우 lpfn은 반드시 분리된 DLL에 있어야 하며 이 때 hMod는 이 DLL의 핸들이어야 한다


다음은 지역 훅과 전역 훅을 설치하는 일반적인 방법이다


지역 훅 : SetWindowsHookEx( idHook, lpfn, NULL, GetCurrentThreadId() );


전역 훅 : SetWindowsHookEx( idHook, hpfn, hDll, 0 );



SetWindowsHookEx 함수는 훅 프로시저를 설치한 후 HHOOK 타입의 훅 핸들을 리턴하는데 이 핸들은 해제를 위해 전역 변수에 잘 보관해 두어야 한다


만약 에러가 발생했ㄷ사면 NULL 을 리턴한다


훅 프로시저를 해제하는 함수는 다음과 같다


BOOL UnhookWindowsHookEx( HOOK hhk );


해제하고자 하는 훅 핸들을 인수로 전달하는데 이 핸들은 설치할 때 받은 값이다


훅을 설치한 프로그램은 종료되기 전에 반드시 훅 프로시저를 해제해야 한다


훅 프로시저가 설치되면 해당 타입의 메시지는 목표 윈도우로 보내지기 전에 훅 프로시저에게 먼저 전달되는데 훅 프로시저는 메시지를 살펴본 후 특별한 이유가 없으면 메시지를 훅 체인의 다음 훅 프로시저에게 전달해야 한다


이 때는 다음 함수를 사용한다


LRESULT CallNextHookEx( HHOOK hhk, int nCode, WPARAM wParam, LPARAM lParam);


hhk 는 현재 처리하고 있는 훅의 핸들인데 SetWindowsHookEx 함수가 리턴한 값이다