[C/C++] 윈도우 마우스 후킹으로 제스처 인식 프로그램 만들기 (마우스 이동거리 계산하기)
마우스 후킹을 이용한 매크로 프로그램 제작
저번 포스팅에 이어 이번에도 마우스 후킹에 관련된 내용입니다.
아직 못 보셨다면 기본 마우스 후킹에 대한 내용을 보시고 보셔도 좋습니다.
https://wendys.tistory.com/107
동작의 핵심은 오른쪽 마우스를 누른 상태에서 마우스의 액션을 감지하는 것에 있습니다.
처음엔 동작이 약간 헷갈릴 수도 있지만 익숙해지면 정말 편하게 이용하실 수 있습니다.
이제 left click event는 필요가 없어졌습니다. 오로지 right click event만을 사용하는 프로그램이 기 때문에 이제 필요한 이벤트는 WM_RBUTTONDOWN
, WM_RBUTTONUP
, WM_MOUSEMOVE
이 세 가지입니다.
이제 마우스 후킹의 콜백 함수에는 다음과 같은 코드를 이용하여 시작될 것입니다.
LRESULT hook_mouse_callback::new_function(
__in int code,
__in WPARAM wparam,
__in LPARAM lparam
) {
do {
if (code < HC_ACTION) {
break;
}
MOUSEHOOKSTRUCT* mouse_param = (MOUSEHOOKSTRUCT*)lparam;
if (wparam == WM_RBUTTONDOWN) {
}
else if (wparam == WM_RBUTTONUP) {
}
else if (wparam == WM_MOUSEMOVE) {
}
else {
break;
}
} while (false);
return ::CallNextHookEx(_hook, code, wparam, lparam);
}
동작 순서를 말하자면
1. 오른쪽 마우스 다운 이벤트 발생 시 마우스 액션 캡처 시작
3. 오른쪽 마우스 업 이벤트 발생 시 방향 목록을 획득하여 그에 대한 액션 처리
??? : 이게 끝입니다. 참 쉽죠
그런 줄 알았으나 여기서 한 가지 문제가 발생합니다.
1차 문제
방향을 잡기 위해선 시작 지점과 끝 지점이 있어야 한다입니다. 하지만 마우스는 이동이 너무나도 자유롭기 때문에 그것을 감지해내는 것에 아이디어가 필요합니다.
2차 문제
방향을 잡긴 잡겠는데 얼마만큼 이동했을 때 그것을 방향으로 인식을 하느냐도 문제입니다. 얼마만큼의 기준이 없다면 마우스를 한번 흔드는 것만으로 수십 개의 방향으로 인식이 될 수 있기 때문입니다.
해결방법
방향을 잡는 것보다 먼저 이동 거리를 계산하는 방법을 제시해드리겠습니다. 이는 정형화된 방법이 아닐 수 있지만 제가 이렇게 사용을 하기 때문에 알려드리는 방법이며, 이 외에도 여러 가지 방법이 존재할 것으로 예상됩니다.
일단 캡처를 시작할 때 현재 시작 POINT를 멤버 변수에 기록해놓습니다. _latest_mouse_point 가 되겠죠
그리고 오른쪽 마우스 다운 상태에서 마우스 MOVE시 current point와 _latest_mouse_point를 비교하게 되면 2차 문제였던 거리를 계산할 수 있게 됩니다. 2차 문제가 해결돼야 1차 문제를 해결할 수 있어요
개발자는 글로 보는 것보다 코드를 보는 게 더 직관적이니 코드로 한번 보겠습니다.
LRESULT hook_mouse_callback::new_function(
__in int code,
__in WPARAM wparam,
__in LPARAM lparam
) {
do {
if (code < HC_ACTION) {
break;
}
MOUSEHOOKSTRUCT* mouse_param = (MOUSEHOOKSTRUCT*)lparam;
if (wparam == WM_RBUTTONDOWN) {
_is_right_button_down = true;
_latest_mouse_point = mouse_param->pt;
}
else if (wparam == WM_MOUSEMOVE) {
if (_is_right_button_down) {
POINT current_point = mouse_param->pt;
double distance = get_distance(_latest_mouse_point, current_point);
if (distance < 50) { // 거리가 50이상이어야 하나의 방향으로 감지
break;
}
//
// 방향 결정 ← ↑ ↓ → 목록 추가 (ToDo.)
//
//
// 기준 포인트를 현재 포인트로 변환
//
_latest_mouse_point = current_point;
}
}
else if (wparam == WM_RBUTTONUP) {
_is_right_button_down = false;
}
else {
break;
}
} while (false);
return ::CallNextHookEx(_hook, code, wparam, lparam);
}
current point와 latest point를 구했습니다. 이제 distance 값을 구하면 자신이 지정한 거리를 기준으로 삼을 수 있습니다.
그렇다면 distance를 구하는 방법은.. 다들 수학 잘하시니까 간단하게 구하실 수 있으리라 믿습니다.
근데 그걸 코드로 짜는 게 귀찮으실 테니 이걸 참고하시는 거죠?
inline double get_distance(
__in const POINT p1,
__in const POINT p2
) {
double distance = 0.0;
distance = sqrt(pow(p1.x - p2.x, 2) + pow(p1.y - p2.y, 2));
return distance;
}
생각보다 아주 간단합니다. 그렇다면 위의 코드에 이것만 추가해서 정말 길이가 잘 계산되는지 확인해볼까요??
아주 잘 나오네요 0은 시작 지점이니 MOUSE MOVE가 일어나기 전이라서 표시가 안 되는 게 맞고 마우스를 우클릭 상태로 쭉쭉 움직임에 따라 distance 값이 계속 증가하는 모습을 볼 수 있습니다.
Sample Download
처음부터 직접 개발을 하시면 좋겠지만 그렇지 않은분들은 아래 샘플 프로젝트를 통하여 이것저것 시도해보시길 바랍니다.
'⌨ DEVELOPMENT > WIndows Hooking' 카테고리의 다른 글
[C++] 최고의 API Hooking Library MS Detours. (1) | 2019.12.07 |
---|---|
[Hooking] dll injection을 이용하여 다른 프로세스에 dll 로드하기 (0) | 2019.11.16 |
[C/C++] 키보드 메시지 후킹을 이용한 키로거 만들기 (6) | 2019.07.27 |
[C/C++] 윈도우 마우스 후킹으로 제스처 인식 프로그램 만들기 (마무리) (2) | 2019.07.25 |
[C/C++] 윈도우 마우스 후킹으로 제스처 인식 프로그램 만들기 (마우스 이동 방향 및 각도 구하기) (0) | 2019.07.23 |
[C/C++] 윈도우 메시지 후킹 마우스를 지배하는자 (windows mouse message hooking) (1) | 2019.07.21 |
[C/C++] 윈도우 후킹을 하기 전에 알아야 할 DLL Main에서 하면 안되는 5가지 작업 (2) | 2019.07.16 |
[C/C++] 윈도우 메시지 가로채기 기법 (windows message hooking) (0) | 2019.07.14 |
댓글
이 글 공유하기
다른 글
-
[C/C++] 윈도우 마우스 후킹으로 제스처 인식 프로그램 만들기 (마무리)
[C/C++] 윈도우 마우스 후킹으로 제스처 인식 프로그램 만들기 (마무리)
2019.07.25 -
[C/C++] 윈도우 마우스 후킹으로 제스처 인식 프로그램 만들기 (마우스 이동 방향 및 각도 구하기)
[C/C++] 윈도우 마우스 후킹으로 제스처 인식 프로그램 만들기 (마우스 이동 방향 및 각도 구하기)
2019.07.23 -
[C/C++] 윈도우 메시지 후킹 마우스를 지배하는자 (windows mouse message hooking)
[C/C++] 윈도우 메시지 후킹 마우스를 지배하는자 (windows mouse message hooking)
2019.07.21 -
[C/C++] 윈도우 후킹을 하기 전에 알아야 할 DLL Main에서 하면 안되는 5가지 작업
[C/C++] 윈도우 후킹을 하기 전에 알아야 할 DLL Main에서 하면 안되는 5가지 작업
2019.07.16