상세 컨텐츠

본문 제목

AND 연산과 쉬프트 연산을 이용한 추출법, 분할, 조합(마우스, lParam, wParam) 관련

프로그래밍 관련/프로그래밍 관련팁

by AlrepondTech 2017. 5. 18. 12:10

본문

반응형
728x170

 

 

 

 

=================================

=================================

=================================

 

 

 

 

 

 

 

출처: http://mhyun.tistory.com/39

 

 

마우스 입력에 관한 메시지

 

( 버튼 )    ( 누름 )                       ( 놓음 )                   ( 더블클릭 )

  좌측       WM_LBUTTONDOWN     WM_LBUTTONUP     WM_LBUTTONDBLCLK

  우측       WM_RBUTTONDOWN     WM_RBUTTONUP    WM_RBUTTONDBLCLK

  중앙       WM_MBUTTONDOWN    WM_MBUTTONUP    WM_MBUTTONDBLCLK



마우스 메시지는 lParam 의 상위 워드에 마우스 버튼이 눌러진 y 좌표, 하위 워드에 x 좌표를 가지며 좌표값을 검출해 내기 위해 HIWORD, LOWORD 등의 매크로 함수를 사용한다.

즉 마우스 메시지가 발생한 위치의 좌표는 ( LOWORD( lParam ), HIWORD( lParam ) )이 된다.

 

wParam 에는 마우스 버튼의 상태와 키보드 조합 키( Shift, Ctrl )의 상태가 전달된다.

조합키의 상태는 다음 값들과 비트 연산을 해보면 알 수 있다. 이 값을 참조하면 쉬프트 클릭, 좌우 동시 누름 등의 조건을 검출할 수 있다.

 

MK_CONTROL

Ctrl 키가 눌러져 있다.

 

MK_LBUTTON

마우스 왼쪽 버튼이 눌러져 있다.

 

MK_RBUTTON

마우스 오른쪽 버튼이 눌러져 있다.

 

MK_MBUTTON

마우스 중간 버튼이 눌러져 있다.

 

MK_SHIFT

Shift 키가 눌러져 있다.



마우스 버튼의 누름 메시지 외에 마우스가 이동할 때마다 전달되는 WM_MOUSEMOVE 메시지가 있다.

이 메시지도 다른 마우스 메시지와 마찬가지로 lParam 에 마우스 커서의 위치가 전달되며 wParam 에 조합키 상태가 전달된다.



개별 정보를 분리해내는 매크로

 

#define LOWORD( l )    ( ( WORD )( l ) )

#define HIWORD( l )     ( ( WORD )( ( ( DWORD )( l ) >> 16 ) & 0xFFFF ) )

#define LOBYTE( w )   ( ( BYTE )( w ) )

#define HIBYTE( w )    ( ( BYTE )( ( ( WORD )( w ) >> 8 ) & oxFF ) )

 

DWORD 로부터 상, 하위 워드 추출, WORD 로부터 상, 하위 바이트를 추출하는 매크로들인데 캐스트 연산자, 비트 AND, 쉬프트 연산자들의 조합으로 값을 추출한다.



#define MAKEWORD( a, b )    ( ( WORD )( ( ( BYTE )( a ) ) | ( ( WORD )( ( BYTE )( b ) ) ) << 8 ) )

#define MAKELONG( a, b )    ( ( LONG )( ( ( WORD )( a ) ) | ( ( DWORD )( ( WORD )( b ) ) ) << 16 ) )

 

MAKEWORD 는 두 개의 바이트로부터 16비트값을 만들고

MAKELONG 은 두 개의 16비트 값으로 32비트값을 만든다.

이 외에 MAKELONG 과 똑같이 정의된 MAKEWPARAM, MAKELPARAM 매크로가 정의되어 있는데 메시지를 직접 보내고자 할 때 파라미터 조립에 가끔 사용된다.

예를 들어 ( 123, 98 ) 좌표를 lParam 에 실어 보내려면 MAKELPARAM( 123, 98 ) 매크로를 사용한다.

 



출처: http://mhyun.tistory.com/39 [모지랭이]

 

 

 

=================================

=================================

=================================

 

 

 

출처: http://air802.tistory.com/227

 

 

마우스 입력에 대해 알아보자.

마우스 메시지 lParam 의 상위 워드와 하위 워드로 나눠서 좌표를 가진다. lParam 은 4 byte 이다. 



lParam 을 상위 워드와 하위 워드로 검출하는 방법

Y 좌표 - 상위 워드 

int y;
y = HIWORD(lParam);


X 좌표 - 하위 워드

int x;
x = LOWORD(lParam);


좌표값은 기본적으로 양수지만 음수가 되는 경우도 있다. 모니터를 2 개 이상 사용될 때 오른쪽 모니터의 입자에서는 좌표값이 음수가 될 수 도있다. 캐스팅을 이용하여 부호를 제대로 변환해야 한다.

마우스 관련 메시지

WM_LBUTTONDOWN - 
더블 클릭 메시지를 사용하기 위해서는 WinMain 함수에 WndClass 를 정의할 때 윈도우 클래스 스타일 부분에 반드시 더블클릭 메시지를 사용할 것이라고 알려줘야한다. CS_DBLCLKS 를 OR 연산자로 추가 해줘야한다. 

WndClass.style = CS_DBLCLKS;

wParam 는 마우스 버튼의 상태와 키보드 조합 키의 상태가 전달된다.

MK_CONTROL - 컨트롤 키가 눌러져 있다.

lParam 과 wParam 은 32 비트의 크기를 가진다. 이를 분할해서 사용하기 위해 매크로 함수로 정의되어 있다.

#define LOWORD(l)           ((WORD)(l)) #define HIWORD(l)           ((WORD)(((DWORD)(l) >> 16) & 0xFFFF)) #define LOBYTE(w)           ((BYTE)(w)) #define HIBYTE(w)           ((BYTE)(((WORD)(w) >> 8) & 0xFF))


분할을 했다면 다시 조합을 해야한다. 조합을 하기 위해 다음과 같이 매크로 함수로 정의되어 있다.

#define MAKEWORD(a, b)      ((WORD)(((BYTE)(a)) | ((WORD)((BYTE)(b))) << 8)) #define MAKELONG(a, b)      ((LONG)(((WORD)(a)) | ((DWORD)((WORD)(b))) << 16)) 

메시지를 직접 보내고자 할 때 파라미터 조립에 사용된다. 예를 들면 (129, 98) 좌표를 lParam 에 실어 보낸다면 다음과 같다.

MAKELONG(129, 98);




출처: http://air802.tistory.com/227 [SpringRain]

 

 

 

 

=================================

=================================

=================================

 

 

 

출처: http://metalkim.tistory.com/287

 

 

 

마우스의 X, Y좌표는,

 

WM_LBUTTONDOWN ( R, M )

WM_LBUTTONUP ( R, M ) 등

 

마우스와 관련한 윈도우 메시지에서 구할 수 있다.

 

마우스와 관련한 윈도우의 LPARAM 에는, 실행한 위치의 좌표값을 저장하는데,

 

LONG형 4바이트 중, 2바이트는 Y좌표, 2바이트는 X좌표로 저장된다.

 

X와 Y좌표를 추출하기 위해서는, LPARAM에 대한 연산을 하여 추출해야 한다.

 

 

 

AND 연산과 쉬프트 연산을 이용한 추출법

 

우선, X좌표의 추출법이다.

 

X좌표는 LPARAM의 하위 2바이트에 저장된다.

따라서, & 연산을 통해 값을 추출해낼 수 있다.

0xYYYYXXXX 형식으로 저장되기 때문에,

 

LPARAM & 0x0000ffff

 

f는 2진수로 1111이기 때문에, Y좌표를 제외한 X좌표만을 추출 해낼 수 있다.

 

 

Y좌표의 추출은, 쉬프트 연산자를 이용하여 추출할 수 있다.

 

LPARAM >> 16 ( 16비트. 즉, 2바이트만큼 옮긴다. )

 

오른쪽으로 2바이트를 옮기면, X좌표는 사라지고, Y좌표의 자리에는 0만 남기 때문에, 그대로 사용하면

 

Y좌표를 사용할 수 있다.

 

정리

 

nX = LPARAM & 0x0000ffff (가독성을 위해 이렇게 표시했을 뿐, 0xffff 를 사용해도 된다.)

nY = LPARAM >> 16

 

 

 

HIWORD와 LOWORD를 이용한 추출법

 

 

HIWORD와 LOWORD는, LONG 자료형에 사용하여, 각각 2바이트로 값을 나누는 함수다.

 

LPARAM에 X좌표와 Y좌표는 각각 2바이트로 나눠져 있기 때문에, 이 함수를 이용하여 값을 추출해낼 수 있다.

 

여기서 주의해야할 점은, LPARAM의 X Y 좌표는 0xYYYYXXXX 형식으로 저장된다는 점이다.

 

따라서, HIWORD는 Y좌표를 추출, LOWORD는 X좌표를 추출한다.

 

 

정리

 

nX = LOWORD(LPARAM);

nY = HIWORD(LPARAM);

 



출처: http://metalkim.tistory.com/287 [태사장의 하루]

 

 

 

=================================

=================================

=================================

 

 

 

반응형
그리드형


관련글 더보기

댓글 영역