1.키보드 ìž…ë ¥ ¶
- 1-1) WM_CHAR 메시지
키보드로부터 ìž…ë ¥ì�´ ë°œìƒ�í–ˆì�„ 경우 윈ë�„우즈는 í�¬ì»¤ìŠ¤ë¥¼ 가진 프로그램ì—�게 키보드 메시지(WM_CHAR)를 보내주며 프로그램ì�€ ì�´ 메시지를 받아 키보드 ìž…ë ¥ì�„ 처리한다. 여기서 í�¬ì»¤ìФ(Focus)를 가진 프로그램ì�´ëž€ 활성화ë�˜ì–´ 있는 윈ë�„우를 ë§�하며 한번ì—� 오ì§� 하나ì�˜ 프로그램만 활성화ë�œë‹¤. 아무리 여러개ì�˜ 프로그램ì�´ ë�™ì‹œì—� 실행ë�˜ëŠ” 멀티 태스킹 환경ì�´ë�¼ 하ë�”ë�¼ë�„ 활성화ë� 수 있는 프로그램ì�€ 오ì§� 하나밖ì—� 없으며 활성화ë�œ 프로그램만 í�¬ì»¤ìŠ¤ë¥¼ ê°€ì§€ê³ í‚¤ë³´ë“œ ìž…ë ¥ì�„ 받아들ì�¼ 수 있다. 왜ëƒ�하면 시스템ì—� 키보드는 하나ë¿�ì�´ë©° 키보드를 ì‚¬ìš©í• ìˆ˜ 있는 사용ìž�ë�„ 하나ë¿�ì�´ê¸° 때문ì�´ë‹¤.
~cpp
#include <windows.h>
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
LPSTR lpszClass="Key";
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance
,LPSTR lpszCmdParam,int nCmdShow)
{
HWND hWnd;
MSG Message;
WNDCLASS WndClass;
g_hInst=hInstance;
WndClass.cbClsExtra=0;
WndClass.cbWndExtra=0;
WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
WndClass.hInstance=hInstance;
WndClass.lpfnWndProc=(WNDPROC)WndProc;
WndClass.lpszClassName=lpszClass;
WndClass.lpszMenuName=NULL;
WndClass.style=CS_HREDRAW | CS_VREDRAW;
RegisterClass(&WndClass);
hWnd=CreateWindow(lpszClass,lpszClass,WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
NULL,(HMENU)NULL,hInstance,NULL);
ShowWindow(hWnd,nCmdShow);
while(GetMessage(&Message,0,0,0)) {
TranslateMessage(&Message);
DispatchMessage(&Message);
}
return Message.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
static char str[256];
int len;
switch(iMessage) {
case WM_CHAR:
len = strlen(str);
str[len]=(TCHAR)wParam;
str[len+1]=0;
InvalidateRect(hWnd,NULL,FALSE);
return 0;
case WM_PAINT:
hdc=BeginPaint(hWnd,&ps);
TextOut(hdc,100,100,str,strlen(str));
EndPaint(hWnd,&ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}
소스를 ìž…ë ¥í•œ 후 실행해 ë³´ìž�. 키보드ì—�서 키를 누르면 ìž…ë ¥í•œ 문ìž�들ì�´ 화면 ìƒ�단ì—� ì¶œë ¥ë� 것ì�´ë‹¤.WndProcì�„ ë³´ë©´ ìš°ì„ ë¬¸ìž�ì—´ strì�´ ì„ ì–¸ë�˜ì–´ 있으며 ì�´ 문ìž�ì—´ 변수ì—� 사용ìž�ê°€ ìž…ë ¥í•œ 문ìž�들ì�„ 모ì�€ë‹¤. 단 ì�´ 변수는 WndProcì—� ì„ ì–¸ë�˜ì–´ 있는 ì§€ì—변수ì�´ë¯€ë¡œ 그냥 ì„ ì–¸í•˜ë©´ 메시지가 ë°œìƒ�í• ë•Œë§ˆë‹¤ 초기화ë�˜ê¸° 때문ì—� staticì�„ 붙여 ì •ì �변수로 만들어 ë‘�어야 한다. 아니면 아예 WinMain 함수 ì�´ì „ì—� ì„ ì–¸í•˜ì—¬ ì „ì— ë³€ìˆ˜ë¡œ 만들어 ë‘�ì–´ë�„ ë�œë‹¤.
ìž…ë ¥ë�œ 문ìž�들ì�„ 바로 바로 ì¶œë ¥í•˜ì§€ ì•Šê³ ë°˜ë“œì‹œ 문ìž�ì—´ì—� 모아 ë‘�어야 하는 ì�´ìœ 는 키보드 ìž…ë ¥ì�´ ë°œìƒ�하는 시ì �ê³¼ 문ìž�ì—´ì�„ ì¶œë ¥í•´ì•¼ í• ì‹œì �ì�´ 분리ë�˜ì–´ 있기 때문ì�´ë‹¤. 키보드 ìž…ë ¥ 시ì �ì�€ 키보드 메시지ì�¸ WM_CHARê°€ ë°œìƒ�í–ˆì�„ 때ì�´ë©° ì�´ 메시지ì—�서 문ìž�ì—´ì�„ 조립하기만 í•˜ê³ ë¬¸ìž�ì—´ì�˜ ì¶œë ¥ì�€ WM_PAINTì—�서 처리한다. ë¬¼ë¡ WM_CHAR 메시지ì—�서 문ìž�ì—´ì�„ 바로 바로 ì¶œë ¥í•˜ëŠ” 것ë�„ 가능하기는 하지만 윈ë�„우즈 프로그램ì�€ 화면ì�„ 다시 그릴 준비를 í•ìƒ� í•´ ë‘�어야 하며 ëª¨ë“ ì¶œë ¥ì�€ WM_PAINTì—�서 하ë�„ë¡� ë�˜ì–´ 있다. ê·¸ë ‡ì§€ 않으면 ì¶œë ¥ë�œ 문ìž�들ì�´ 지워지면 다시 복구ë�˜ì§€ 않는다.
WM_CHAR 메시지는 ìž…ë ¥ë�œ 문ìž�ì�˜ 아스키 코드를 wParam으로 ì „ë‹¬í•˜ë�„ë¡� ë�˜ì–´ 있으며 우리는 wParamì�˜ ê°’ì�„ ì�½ì–´ 사용ìž�ê°€ ì–´ë–¤ 키를 ëˆŒë €ëŠ”ì§€ë¥¼ 알아내게 ë�œë‹¤.
다ì�Œ 코드는 wParam으로 ì „ë‹¬ë�œ 키 코드를 str 문ìž�ë°°ì—´ì—� ì €ìž¥í•œë‹¤.
ìž…ë ¥ë�œ 문ìž�들ì�„ 바로 바로 ì¶œë ¥í•˜ì§€ ì•Šê³ ë°˜ë“œì‹œ 문ìž�ì—´ì—� 모아 ë‘�어야 하는 ì�´ìœ 는 키보드 ìž…ë ¥ì�´ ë°œìƒ�하는 시ì �ê³¼ 문ìž�ì—´ì�„ ì¶œë ¥í•´ì•¼ í• ì‹œì �ì�´ 분리ë�˜ì–´ 있기 때문ì�´ë‹¤. 키보드 ìž…ë ¥ 시ì �ì�€ 키보드 메시지ì�¸ WM_CHARê°€ ë°œìƒ�í–ˆì�„ 때ì�´ë©° ì�´ 메시지ì—�서 문ìž�ì—´ì�„ 조립하기만 í•˜ê³ ë¬¸ìž�ì—´ì�˜ ì¶œë ¥ì�€ WM_PAINTì—�서 처리한다. ë¬¼ë¡ WM_CHAR 메시지ì—�서 문ìž�ì—´ì�„ 바로 바로 ì¶œë ¥í•˜ëŠ” 것ë�„ 가능하기는 하지만 윈ë�„우즈 프로그램ì�€ 화면ì�„ 다시 그릴 준비를 í•ìƒ� í•´ ë‘�어야 하며 ëª¨ë“ ì¶œë ¥ì�€ WM_PAINTì—�서 하ë�„ë¡� ë�˜ì–´ 있다. ê·¸ë ‡ì§€ 않으면 ì¶œë ¥ë�œ 문ìž�들ì�´ 지워지면 다시 복구ë�˜ì§€ 않는다.
WM_CHAR 메시지는 ìž…ë ¥ë�œ 문ìž�ì�˜ 아스키 코드를 wParam으로 ì „ë‹¬í•˜ë�„ë¡� ë�˜ì–´ 있으며 우리는 wParamì�˜ ê°’ì�„ ì�½ì–´ 사용ìž�ê°€ ì–´ë–¤ 키를 ëˆŒë €ëŠ”ì§€ë¥¼ 알아내게 ë�œë‹¤.
다ì�Œ 코드는 wParam으로 ì „ë‹¬ë�œ 키 코드를 str 문ìž�ë°°ì—´ì—� ì €ìž¥í•œë‹¤.
~cpp len = strlen(str); str[len]=(TCHAR)wParam; str[len+1]=0;
문ìž�ì—´ì�˜ ì œì�¼ ë�� 부분ì—� wParamê°’ì�„ ì�¨ ë„£ê³ ë°”ë¡œ 뒤쪽ì�˜ 0ì�„ ì�¨ 넣어 문ìž�ì—´ ë��ì�„ 표시한다. 키 ìž…ë ¥ì�´ 있ì�„ 때마다 ì�´ ë�™ìž‘ì�„ 반복함으로ì�¨ str 문ìž� ë°°ì—´ì—�는 ìž…ë ¥ë�œ 키 ê°’ì�´ 차곡 차곡 쌓여갈 것ì�´ë‹¤.
키보드 메시지ì—�서는 strë°°ì—´ì—� 문ìž�ì—´ì�„ ì§‘ì–´ 넣기만 하며 문ìž�ì—´ì�„ 화면으로 ì¶œë ¥í•˜ëŠ” ì�¼ì�€ WM_PAINTì—�서 맡는다. 단 키보드 메시지ì—� ì�˜í•´ 문ìž�ì—´ì�´ 다시 ìž…ë ¥ë�˜ë�”ë�¼ë�„ 화면ìƒ�ì�˜ 변화는 없으므로 WM_PAINT메시지가 ë°œìƒ�하지 않는다. 그래서 ê°•ì œë¡œ WM_PAINT 메시지를 ë°œìƒ�시켜 주어야 하는ë�° ì�´ 때는 InvalidateRect 함수를 호출해 주면 ë�œë‹¤. WM_CHARì—�서 문ìž�ì—´ì�„ 조립한 후 InvalidateRect 함수를 호출해 주어 키보드가 ìž…ë ¥ë� 때마다 화면ì�„ 다시 그리ë�„ë¡� 하였다.
>
키보드 메시지ì—�서는 strë°°ì—´ì—� 문ìž�ì—´ì�„ ì§‘ì–´ 넣기만 하며 문ìž�ì—´ì�„ 화면으로 ì¶œë ¥í•˜ëŠ” ì�¼ì�€ WM_PAINTì—�서 맡는다. 단 키보드 메시지ì—� ì�˜í•´ 문ìž�ì—´ì�´ 다시 ìž…ë ¥ë�˜ë�”ë�¼ë�„ 화면ìƒ�ì�˜ 변화는 없으므로 WM_PAINT메시지가 ë°œìƒ�하지 않는다. 그래서 ê°•ì œë¡œ WM_PAINT 메시지를 ë°œìƒ�시켜 주어야 하는ë�° ì�´ 때는 InvalidateRect 함수를 호출해 주면 ë�œë‹¤. WM_CHARì—�서 문ìž�ì—´ì�„ 조립한 후 InvalidateRect 함수를 호출해 주어 키보드가 ìž…ë ¥ë� 때마다 화면ì�„ 다시 그리ë�„ë¡� 하였다.
- 1-2) WM_KEYDOWN
키보드로부터 문ìž�를 ìž…ë ¥ë°›ê³ ìž� í• ê²½ìš°ëŠ” WM_CHAR 메시지를 사용하면 ë�œë‹¤ëŠ” 것ì�„ ë°°ì› ë‹¤. 문ìž� ì�´ì™¸ì�˜ 키를 ìž…ë ¥ ë°›ìœ¼ë ¤ë©´ WM_CHAR 메시지만으로는 ìž…ë ¥ì�„ ë°›ì�„ 수 없다. 예를 들어 커서 ì�´ë�™í‚¤ë�¼ë“ ê°€ Ins, Del, PgUp, 펑션키 등ì�˜ 키는 문ìž�키가 아니기 때문ì—� WM_CHAR 메시지로는 검출해 낼 수 없다. ì�´ë•ŒëŠ” WM_KEYDOWN 메시지를 사용해야 한다.
가�키 코드 / 값 / 키
VK_LBUTTON / 01
VK_RBUTTON / 02
VK_CANCEL / 03 / Ctrl-Break
VK_MBUTTON / 04
VK_BACK / 08 / Backspace
VK_TAB / 09 / Tab
VK_RETURN / 0D / Enter
VK_SHIFT / 10 / Shift
VK_CONTROL / 11 / Ctrl
VK_MENU / 12 / Alt
VK_ESCAPE / 1B / Esc
VK_SPACE / 20 / Space
VK_END / 23 / End
VK_HOME / 24 / Home
VK_LEFT / 25 / 좌측커서 ��키
VK_UP / 26 / 위쪽커서 ��키
VK_RIGHT / 27 / 오른쪽커서 ��키
VK_DOWN / 28 / 아래쪽커서 ��키
/ 30 ~ 39 / 숫�키 0~9
/ 41 ~ 5A / �문� A~Z
VK_F1 ~ VK_F16 / 70 ~ 7F / 펑션키 F1 ~ F16/ 41 ~ 5A / �문� A~Z
VK_NUMLOCK / 90 / Num Lock
VK_SCROLL / 91 / Scroll Lock
- 1-3) TranslateMessage
~cpp
while(GetMessage(&Message,0,0,0)) {
TranslateMessage(&Message);
DispatchMessage(&Message);
}
GetMessage는 메시지 í��ì—�서 메시지를 꺼내온 후 ì�´ 메시지를 TranslateMessage 함수로 넘겨 준다. TranslateMessage 함수는 ì „ë‹¬ë�œ 메시지가 WM_KEYDOWNì�¸ì§€ì™€ ëˆŒë ¤ì§„ 키가 문ìž�키ì�¸ì§€ 검사해 ë³´ê³ ì¡°ê±´ì�´ ë§žì�„ 경우 WM_CHAR 메시지를 만들어 메시지 í��ì—� ë�§ë¶™ì�´ëŠ” ì—í• ì�„ 한다. ë¬¼ë¡ ë¬¸ìž� ìž…ë ¥ì�´ ì•„ë‹� 경우는 아무 ì�¼ë�„ 하지 않으며 ì�´ 메시지는 DispatchMessage 함수ì—� ì�˜í•´ WndProc으로 보내진다. 만약 메시지 루프ì—�서 TranslateMessage 함수를 ë¹¼ 버리면 WM_CHAR 메시지는 ì ˆëŒ€ë¡œ WndProc으로 ì „ë‹¬ë�˜ì§€ 않ì�„ 것ì�´ë‹¤.
2.마우스 ìž…ë ¥ ¶
윈ë�„우즈와 ê°™ì�€ GUIìš´ì˜�ì²´ì œì—�서는 키보드보다 마우스가 ë�” ë§Žì�´ 사용ë�œë‹¤. 윈ë�„우즈ì�˜ ê³µì‹� ìž…ë ¥ 장치는 키보드ì�´ì§€ë§Œ 그래픽 툴ì�´ë‚˜ DTP, CAD 등ì�˜ 복잡한 프로그램ì—�서는 마우스가 주요 ìž…ë ¥ 장치로 사용ë�œë‹¤. 키보드 ìž…ë ¥ 처리를 메시지로 하는 것과 마찬가지로 마우스 ìž…ë ¥ 처리ë�„ 메시지를 받아 처리한다. 마우스 ìž…ë ¥ì—� 관한 메시지는 다ì�Œê³¼ ê°™ì�€ 종류가 있다.
버튼 / 누름 / 놓ì�Œ / ë�”블í�´ë¦
좌측 / WM_LBUTTONDOWN/ WM_LBUTTONUP / WM_LBUTTONDBLCLK
우측 / WM_RBUTTONDOWN/ WM_RBUTTONUP / WM_RBUTTONDBLCLK
마우스 메시지는 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ì—� 조합키 ìƒ�태가 ì „ë‹¬ë�œë‹¤.
버튼 / 누름 / 놓ì�Œ / ë�”블í�´ë¦
좌측 / WM_LBUTTONDOWN/ WM_LBUTTONUP / WM_LBUTTONDBLCLK
우측 / WM_RBUTTONDOWN/ WM_RBUTTONUP / WM_RBUTTONDBLCLK
마우스 메시지는 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ì—� 조합키 ìƒ�태가 ì „ë‹¬ë�œë‹¤.










