U E D R , A S I H C RSS

5�용C++스터디/키보드�마우스�입출력

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 문�배열� 저장한다.


~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 함수를 호ìœí•´ 주어 키보드가 ìž…ë ¥ë�  때마다 화면ì�„ 다시 그리ë�„ë¡� 하였다.





  • 1-2) WM_KEYDOWN
    키보드로부터 문ìž�를 입력받고ìž� í•  경우는 WM_CHAR 메시지를 사용하면 ë�œë‹¤ëŠ” 것ì�„ 배웠다. 문ìž� ì�´ì™¸ì�˜ 키를 ìž…ë ¥ 받으려면 WM_CHAR 메시지만으로는 ìž…ë ¥ì�„ ë°›ì�„ 수 없다. 예를 들어 커서 ì�´ë�™í‚¤ë�¼ë“ ê°€ Ins, Del, PgUp, 펑션키 등ì�˜ 키는 문ìž�키가 아니기 때문ì—� WM_CHAR 메시지로는 ê²€ìœí•´ 낼 수 없다. ì�´ë•ŒëŠ” WM_KEYDOWN 메시지를 사용해야 한다.
WM_KEYDOWN 메시지는 wParam� 문� 코드가 아닌 가� 키코드�는 것� 전달해 준다. 가�키코드(Virtual Key Code)란 시스템� 장착� 키보드� 종류� �관없� 키를 입력받기 위해 만들어진 코드값�며 다�과 같� 정��어 있다.

가�키 코드 / 값 / 키
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
VK_NUMLOCK / 90 / Num Lock
VK_SCROLL / 91 / Scroll Lock




  • 1-3) TranslateMessage
키보드�서 A키를 눌렀다 �다고 해 보�. � 때 발�하는 메시지는 순서대로 WM_KEYDOWN, WM_CHAR, WM_KEYUP 세가지�다. � 중 WM_CHAR 메시지는 사용�� �해 발�하는 메시지가 아니다. 키보드로부터 전달�는 메시지는 키를 누를 때 WM_KEYDOWN, 키를 뗄 때 WM_KEYUP �가지��다. 그럼 WM_CHAR 메시지는 어디서 발�할까? � 메시지는 WM_KEYDOWN� �해 추가로 발�하는 메시지�며 메시지 루프�서 �위�으로 �성�다. 전� 코드 내용 중� 메시지 루프를 다시 보�.


~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� 조합키 �태가 전달�다.




Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:22:19
Processing time 0.0092 sec