키보드 후킹을 해봤으니 마우스 후킹을 해봅시다.
마우스 후킹은 키보드 후킹이랑 방식이 같습니다.
단지 훅을 설치할때 'WH_KEYBOARD_LL'대신 'WH_MOUSE_LL'를 사용해야 합니다.
// 키보드 hook 설치
hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, hInst, 0);
// 마우스 hook 설치
hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, LowLevelMouseProc, hInst, 0);
마우스를 후킹 하여 좌표를 얻어옵시다.
이때 사용하는 API는 'GetCursorPos'입니다.
(참고 : MS Learn - GetCursorPos 함수(winuser.h) )
void ShowMouse(HDC hdc)
{
TCHAR strM[256];
POINT pos;
GetCursorPos(&pos);//마우스 좌표를 알려주는 API
wsprintf(strM, L"X : %6d, Y : %6d", pos.x, pos.y);
}
이 함수는 호출될 때 한 번만 좌표를 출력하게 됩니다.
위 함수 만들고 메시지 프록( WndProc, MsgProc 등등) 에서
'case WM_PAINT:'를 찾아 위 함수를 넣고
마우스 후킹 코드에 'PostMessage( NULL, WM_PAINT, NULL, NULL);'을 넣고
실행해봅시다.
중단점을 잡아보면 알겠지만 후킹까지만 오고 'WM_PAINT'까지는 오지 않습니다.
당연하지만 'WM_PAINT'가 호출된 윈도우를 'NULL'로 잡았으니까 그렇죠 ㅎㅎㅎ
메시지프록( WndProc, MsgProc 등등)의 시작 부분에서 HWND를 받아서 전역변수에 저장하고
HWND hwndWnd;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
hwndWnd = hWnd;
...
...
...
}
코드를 'PostMessage( hwndWnd, WM_PAINT, NULL, NULL);' 이렇게 수정합시다.
'WM_PAINT'까지 넘어가고 마우스 'ShowMouse()'도 동작하지만 화면은 변하지 않습니다.
헐키.... 화면크기를 조정하거나 최소화하거나 해야 값이 변하는 걸 알수 있습니다.
이것은 'WM_PAINT'가 호출될 때는 화면 전체를 다시 그리는 것이 아니고 무효화 영역(다시 그려야 할 필요성이 있는 영역)만 다시 그리기 때문에 발생하는 현상입니다.
이 무효화 영역을 우리가 좌표를 출력할 곳으로 설정해야 제대로 동작할 수 있다는 것을 느낄 수 있을 것입니다.
그 무효와 영역을 만들어주는 함수가 'InvalidateRect'입니다.
이제 후킹 코드에 'InvalidateRect(hwndWnd, NULL, true);' 이렇게 넣고 'PostMessage'는 지워줍니다. ( I'nvalidateRect'가 호출되면 'WM_PAINT'가 호출되므로 따로 호출할 필요가 없습니다.)
동작시켜보면 이제는 창과 관계없이 좌표가 출력되는걸 볼 수 있습니다.
- 2022-11-14 추가
글을 정리하는데....
이 글은 정말 대충 썼군요;;;;
나중에라도 샘플부터 다시 만들어야 할 것같습니다 ㅎㅎㅎ