일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 언제나휴일
- 네트워크 프로그래밍
- 프로젝트
- 캡슐화
- 졸업 작품 소재
- 알고리즘
- 안드로이드 앱 개발
- 유튜브 동영상 강의
- 졸업 작품
- 표준 라이브러리 함수
- c#
- 소켓 통신
- 산책하기 좋은 곳
- 추천
- 원격 제어 프로그램
- 실습
- 소스 코드
- Windows Forms
- 실습으로 다지는 c#
- 파이썬
- 동영상 강의
- 동영상
- 무료 동영상 강의
- 표준 입출력
- C++
- 언제나 휴일
- 강의
- 클래스 다이어그램
- c언어
- 충남 천안
Archives
- Today
- Total
프로그래밍 언어 및 기술 [언제나휴일]
4. 마우스 입력 본문
윈도우즈 프로그램에서 사용하는 기본 입력 장치에는 마우스와 키보드가 있습니다.
그리고 시스템에서 제공하는 타이머도 자주 사용하는 입력 장치입니다.
Windows API에서 제공하는 마우스 관련 메시지는 크게 세 종류로 구분할 수 있어요.
클라이언트 영역에서 마우스를 누르거나 뗐을 때 발생하는 메시지, NC(Noc Client, 비 클라이언트) 영역에서 마우스를 누르거나 뗐을 때 발생하는 메시지, 그 외의 메시지(마우스 위치를 조사하기 위한 메시지나 마우스 휠 등)가 있어요.
실제 프로그래밍에서 많이 처리하는 메시지는 클라이언트 영역에서 누르거나 뗐을 때 발생하는 메시지입니다.
NC 영역에서 발생한 마우스 메시지는 DefWindowsProc에 의해 디폴트 처리를 하는 것이 대부분이겠죠.
Client 영역 | Non Client 영역 | 기타 |
WM_LBUTTONDOWN WM_LBUTTONUP WM_LBUTTONDBLCLK WM_RBUTTONDOWN WM_RBUTTONUP WM_RBUTTONDBLCLK WM_MBUTTONDOWN WM_MBUTTONUP WM_MBUTTONDBLCLK WM_MOUSEMOVE |
WM_NCLBUTTONDOWN WM_NCLBUTTONUP WM_NCLBUTTONDBLCLK WM_NCRBUTTONDOWN WM_NCRBUTTONUP WM_NCRBUTTONDBLCLK WM_NCMBUTTONDOWN WM_NCMBUTTONUP WM_NCMBUTTONDBLCLK WM_NCMOUSEMOVE |
WM_NCHITTEST WM_MOUSEWHEEL |
- 더블 클릭 메시지는 윈도우 클래스를 등록할 때 CS_DBLCLS 스타일을 지정한 윈도우에 발생
마우스 관련 메시지에서 LPARAM의 상위 2바이트는 Y좌표, 하위 2바이트는 X 좌표입니다.
int x = LOWORD(lParam);
int y = HIWORD(lParam);
//POINT pt = MAKEPOINTS(lParam);
마우스 관련 메시지에서 WPARAM은 키보드와 마우스의 상태 조합을 제공합니다.
매크로 상수명(값) | 의미 |
MK_LBUTTON(0x01) | 왼쪽 마우스 버튼이 눌러졌는지 여부 |
MK_RBUTTON(0x02) | 오른쪽 마우스 버튼이 눌러졌는지 여부 |
MK_SHIFT(0x04) | Shift 키가 눌러졌는지 여부 |
MK_CONTROL(0x08) | CTRL 키가 눌러졌는지 여부 |
MK_MBUTTON(0x10) | 가운데 마우스 버튼이 눌러졌는지 여부 |
MK_XBUTTON1(0x20) | 첫 번째 X 버튼이 눌러졌는지 여부 |
MK_XBUTTON2(0x40) | 두 번째 X 버튼이 눌러졌는지 여부 |
다음은 마우스 왼쪽 버튼을 클릭했을 때 WPARAM과 LPARAM의 값을 화면에 출력하는 소스 코드입니다.
void OnLButtonDown(HWND hWnd, WPARAM wParam, WORD x, WORD y)
{
HDC hdc = GetDC(hWnd);
RECT rt;
GetClientRect(hWnd, &rt);
Rectangle(hdc, 0, 0, rt.right, rt.bottom);
WCHAR buf[256];
wsprintf(buf, TEXT("X:%d , Y:%d"), x, y);
TextOut(hdc, 10, 10, buf, lstrlen(buf));
wsprintf(buf, TEXT("%#X"), wParam);
TextOut(hdc, 10, 40, buf, lstrlen(buf));
if (wParam & MK_LBUTTON)
{
lstrcpy(buf, TEXT("0x01 LBUTTON ON"));
}
else
{
lstrcpy(buf, TEXT("0x01 LBUTTON OFF"));
}
TextOut(hdc, 10, 70, buf, lstrlen(buf));
if (wParam & MK_RBUTTON)
{
lstrcpy(buf, TEXT("0x02 RBUTTON ON"));
}
else
{
lstrcpy(buf, TEXT("0x02 RBUTTON OFF"));
}
TextOut(hdc, 10, 100, buf, lstrlen(buf));
if (wParam & MK_SHIFT)
{
lstrcpy(buf, TEXT("0x04 Shift Key ON"));
}
else
{
lstrcpy(buf, TEXT("0x04 Shift Key OFF"));
}
TextOut(hdc, 10, 130, buf, lstrlen(buf));
if (wParam & MK_CONTROL)
{
lstrcpy(buf, TEXT("0x08 CTRL Key ON"));
}
else
{
lstrcpy(buf, TEXT("0x08 CTRL Key OFF"));
}
TextOut(hdc, 10, 160, buf, lstrlen(buf));
if (wParam & MK_MBUTTON)
{
lstrcpy(buf, TEXT("0x10 MBUTTON ON"));
}
else
{
lstrcpy(buf, TEXT("0x10 MBUTTON OFF"));
}
TextOut(hdc, 10, 190, buf, lstrlen(buf));
if (wParam & MK_XBUTTON1)
{
lstrcpy(buf, TEXT("0x20 XBUTTON1 ON"));
}
else
{
lstrcpy(buf, TEXT("0x20 XBUTTON1 OFF"));
}
TextOut(hdc, 10, 220, buf, lstrlen(buf));
if (wParam & MK_XBUTTON2)
{
lstrcpy(buf, TEXT("0x40 XBUTTON2 ON"));
}
else
{
lstrcpy(buf, TEXT("0x40 XBUTTON OFF"));
}
TextOut(hdc, 10, 250, buf, lstrlen(buf));
ReleaseDC(hWnd,hdc);
}
LRESULT CALLBACK MyWndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
switch (iMessage)
{
case WM_LBUTTONDOWN: OnLButtonDown(hWnd, wParam, LOWORD(lParam),HIWORD(lParam)); return 0;
case WM_DESTROY: OnDestroy(hWnd); return 0;
}
return DefWindowProc(hWnd, iMessage, wParam, lParam);
}
마우스 왼쪽 버튼을 클릭하였을 때 메시지 정보를 출력하는 프로그램의 전체 소스 코드입니다.
//Windows API
//마우스 메시지 출력기
//마우스 왼쪽 버튼을 클릭하면 메시지 정보를 출력하시오.
#include <Windows.h>
#define MY_DEF_STYLE CS_HREDRAW | CS_VREDRAW|CS_DBLCLKS
LRESULT CALLBACK MyWndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam);
void RegMyWndClass(LPCWSTR cname);
void MakeWindow(LPCWSTR cname);
void MsgLoop();
INT APIENTRY WinMain(HINSTANCE hIns, HINSTANCE hPrev, LPSTR cmd, INT nShow)
{
RegMyWndClass(TEXT("MyWindow"));
MakeWindow(TEXT("MyWindow"));
MsgLoop();
}
void RegMyWndClass(LPCWSTR cname)
{
//윈도우 클래스 속성 설정
WNDCLASS wndclass = { 0 };
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.hInstance = GetModuleHandle(0);
wndclass.hIcon = LoadIcon(0, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(0, IDC_ARROW);
wndclass.lpfnWndProc = MyWndProc;
wndclass.lpszMenuName = 0;
wndclass.lpszClassName = cname;
wndclass.style = MY_DEF_STYLE;
//윈도우 클래스 등록
RegisterClass(&wndclass);
}
void MakeWindow(LPCWSTR cname)
{
//윈도우 개체 생성
HWND hWnd = CreateWindow(cname,//클래스 이름
TEXT("타이틀"),//타이틀 명
WS_OVERLAPPEDWINDOW,//윈도우 스타일
100, 30, 700, 600,//Left, Top, Width, Height
0, //부모 윈도우 핸들
0,//메뉴
GetModuleHandle(0),//모듈 핸들
0 //WM_CREATE에 전달할 인자
);
//윈도우 개체 시각화
ShowWindow(hWnd, SW_SHOW);
}
void MsgLoop()
{
MSG Message;
while (GetMessage(&Message, 0, 0, 0))//응용 큐에서 메시지를 꺼내오기
{
DispatchMessage(&Message);//메시지 수행(콜백 가동)
}
}
void OnDestroy(HWND hWnd)
{
PostQuitMessage(0);
}
void OnLButtonDown(HWND hWnd, WPARAM wParam, WORD x, WORD y)
{
HDC hdc = GetDC(hWnd);
RECT rt;
GetClientRect(hWnd, &rt);
Rectangle(hdc, 0, 0, rt.right, rt.bottom);
WCHAR buf[256];
wsprintf(buf, TEXT("X:%d , Y:%d"), x, y);
TextOut(hdc, 10, 10, buf, lstrlen(buf));
wsprintf(buf, TEXT("%#X"), wParam);
TextOut(hdc, 10, 40, buf, lstrlen(buf));
if (wParam & MK_LBUTTON)
{
lstrcpy(buf, TEXT("0x01 LBUTTON ON"));
}
else
{
lstrcpy(buf, TEXT("0x01 LBUTTON OFF"));
}
TextOut(hdc, 10, 70, buf, lstrlen(buf));
if (wParam & MK_RBUTTON)
{
lstrcpy(buf, TEXT("0x02 RBUTTON ON"));
}
else
{
lstrcpy(buf, TEXT("0x02 RBUTTON OFF"));
}
TextOut(hdc, 10, 100, buf, lstrlen(buf));
if (wParam & MK_SHIFT)
{
lstrcpy(buf, TEXT("0x04 Shift Key ON"));
}
else
{
lstrcpy(buf, TEXT("0x04 Shift Key OFF"));
}
TextOut(hdc, 10, 130, buf, lstrlen(buf));
if (wParam & MK_CONTROL)
{
lstrcpy(buf, TEXT("0x08 CTRL Key ON"));
}
else
{
lstrcpy(buf, TEXT("0x08 CTRL Key OFF"));
}
TextOut(hdc, 10, 160, buf, lstrlen(buf));
if (wParam & MK_MBUTTON)
{
lstrcpy(buf, TEXT("0x10 MBUTTON ON"));
}
else
{
lstrcpy(buf, TEXT("0x10 MBUTTON OFF"));
}
TextOut(hdc, 10, 190, buf, lstrlen(buf));
if (wParam & MK_XBUTTON1)
{
lstrcpy(buf, TEXT("0x20 XBUTTON1 ON"));
}
else
{
lstrcpy(buf, TEXT("0x20 XBUTTON1 OFF"));
}
TextOut(hdc, 10, 220, buf, lstrlen(buf));
if (wParam & MK_XBUTTON2)
{
lstrcpy(buf, TEXT("0x40 XBUTTON2 ON"));
}
else
{
lstrcpy(buf, TEXT("0x40 XBUTTON OFF"));
}
TextOut(hdc, 10, 250, buf, lstrlen(buf));
ReleaseDC(hWnd,hdc);
}
LRESULT CALLBACK MyWndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
switch (iMessage)
{
case WM_LBUTTONDOWN: OnLButtonDown(hWnd, wParam, LOWORD(lParam),HIWORD(lParam)); return 0;
case WM_DESTROY: OnDestroy(hWnd); return 0;
}
return DefWindowProc(hWnd, iMessage, wParam, lParam);
}
'C & C++ > Windows API 예제' 카테고리의 다른 글
7. 첫 번째 실습 – 도형 이동 시키기 [Windows API] (1) | 2024.01.26 |
---|---|
6. 타이머 입력 [Windows API] (0) | 2024.01.26 |
5. 키보드 입력 [Windows API] (1) | 2024.01.25 |
3. 기본 그리기 [Windows API] (1) | 2024.01.24 |
2. 윈도우 클래스 등록 및 윈도우 개체 생성 (0) | 2024.01.24 |
1. Windows API 소개 (1) | 2023.12.26 |
테트리스 처음부터 끝까지 [C++, Windows API] (0) | 2023.12.25 |