본문 바로가기

Programming Study/Win32 API

입력_키보드

키보드

WM_CHAR 메시지

윈도우즈 환경에서는 명시적인 입력 함수가 존재하지 않으며 반드시 메시지를 받아야 한다.

왜냐하면 여러 개의 프로그램이 동시에 실행되는 멀티 태스킹 환경이며

사용자가 언제 자신에게 관심을 가질지 예측할 수 없기 때문이다.

윈도우즈 환경에서는 주로 마우스가 많이 사용되지만 아직까지도 컴퓨터의 가장 기본적인 입력장치는 키보드이다.

키보드로부터 입력이 발생했을 경우 윈도우즈 포커스를 가진 프로그램에게 키보드 메시지(WM_CHAR, WM_KEYDOWN)를 보내며

프로그램은 이런 메시지를 받아 키보드 입력을 처리한다.

여기서 포커스(Focus)란 입력 초점이라는 뜻이며 키보드 입력을 받아 들일 수 있는 상태라는 뜻이다.

포커스를 가진 상태란 활성화되어 있고 현재 사용자가 쓰고 있다는 뜻인데 한 번에 오직 하나의 프로그램만 활성화 된다.

한 번에 하나의 프로그램만 키보드 입력을 받을 수 있는 이유는 간단하다.

시스템에 키보드는 하나뿐이며, 키보드를 사용하는 주체인 사용자도 오직 한 명뿐이기 때문이다.

 

입력된 문자들을 바로바로 출력하지 않고 반드시 문자열에 모아 두어야 하는 이유는

키보드 입력이 발생하는 시점과 문자열을 출력해야 할 시점이 분리되어 있기 때문이다.

키보드 입력 시점은 키보드 메시지인 WM_CHAR가 발생했을 때인데 이 메시지에서 문자열을 조립만 하고

출력은 WM_PAINT에서 처리한다.

WM_CHAR 메시지는 입력된 문자의 코드를 wParam으로 전달하며 우리는 wParam의 값을 읽어 사용자가 어떤 문자키를 눌렀는지를 알아 낸다.

WM_CHAR 메시지에서 lParam의 정보들을 사용해야 할 경우는 드물다.

메시지 별로 필요한 추가 정보는 함께 전달되는 wParam, lParam을 통해 넘어오는데 wParam과 lParam을 사용하는 방법은 메시지별로 다르므로 추가 정보에 대한 사항은 따로 공부하자.

키보드 메시지에서는 str배열에 문자열을 집어넣기만 하며 문자열을 화면으로 출력하는 일은 WM_PAINT에서 맡는다.

단 키보드 메시지에 의해 문자열이 다시 입력되더라도 화면상의 변화는 없으므로 WM_PAINT메시지가 자동으로 발생하지 않는데

이 때에는 InvalidateRect 함수를 호출하면 된다.

 

무효영역(Invalid Region)

앞의 예제에서 InvalidateRect 함수를 호출하여 강제로 WM_PAINT 메시지를 발생시켰다.

WM_PAINT 메시지는 윈도우가 다시 그려져야 할 필요가 있을 때마다 호출되는데 다시 그려져야 할 필요가 있다는 말은

무효영역이 있다는 뜻이다.

무효하다는 말은 원래 그려져야 할 모습과는 다른 모습을 가지고 있다는 뜻이며 곧 다시 그릴 필요가 있다는 의미이다.

프로그램의 내부에서 윈도우의 모습을 변경시켰을 때는 변경된 부분을 다시 그리도록 강제로 무효화해야 하며

이때 사용하는 함수가 InvaliddateRect이다.

BOOL InvalidateRect(HWND hWnd, CONST RECT *lpRect, BOOL bErase); 

이 함수는 윈도우의 작업영역을 무효화하여 운영체제로 하여금 WM_PAINT 메시지를 해당 윈도우로 보내도록 한다.

첫 번째 인수 hWnd는 무효화의 대상이 되는 윈도우, 즉 다시 그려져야 할 윈도우의 핸들이다.

두 번째 인수 lpRect는 무효화할 사각영역을 지정하되 이 값이 NULL이면 윈도우의 전 영역이 무효화 된다.

전 영역을 무효화하면 완전히 다시 그리므로 확실하게 그려지기는 하겠지만 그만큼 그리는 속도는 느려질 것이다.

속도를 최대한 높이려면 변경된 최소한의 영역만을 계산하여 꼭 필요한 부분만 무효화하는 것이 좋다.

세 번째 인수 bErase는 무효화되기 전에 배경을 모두 지운 후 다시 그릴 것인지 아니면 배경을 지우지 않고 그릴 것인지 지정한다.

 

WM_KEYDOWN

WM_KEYDOWN 메시지는 키보드를 누를 때마다 윈도우로 전달되는데 문자가 아닌 모든 키에 대해서도 발생한다.

단, Alt키와 윈도우 키, 한영 전환키 등의 특수 키 몇가지는 제외된다.

이때 wParam으로는 문자 코드가 아닌 가상 키코드라는 것이 전달 된다.

가상 키코드(Virtual Key Code)란 시스템에 장착된 키보드의 종류에 상관없이 키를 입력받기 위해 만들어진 범용적인 코드값이다.

WM_KEYDOWN의 반대 메시지는 WM_KEYUP이며 키가 떨어질 때 발생한다.

wParam, lParam의 의미는 WM_KEYDOWN과 동일하다.

키보드는 주로 눌렀을 때 입력된 것으로 간주하기 때문에 WM_KEYUP 메시지는 잘 사용되지는 않는다.

이 메시지를 사용할 것인가의 여부는 응용 프로그램의 필요에 따라 결정하면 된다.

 

TranslateMessage

Whlie(GetMessage(&Message, NULL, 0, 0))

{

    TranslateMessage(&Message);

    DispatchMessage(&Message);

}

GetMessage는 메시지 큐에서 메시지를 꺼낸 후 이 메시지를 TranslateMessage 함수로 넘긴다.

TranslateMessage 함수는 전달된 메시지가 WM_KEYDOWN인지 눌러진 키가 문자키인지 검사해 보고

조건이 맞을 경우 WM_CHAR 메시지를 추가로 발생시킨다.

물론 문자 입력이 아닐 경우는 아무 일도 하지 않으며 이 메시지는 DispatchMessage 함수에 의해 WndProc으로 보내진다.

만약 메시지 루프에서 TranslateMessage 함수를 빼 버리면 WM_CHAR 메시지는 절대로 WndProc으로 전달되지 않을 것이다.

메시지 루프의 TrnaslateMessage 함수는오로지 키보드로부터 문자키 입력 메시지인 WM_CHAR를 만들어내기 위해 존재한다.

 

- 윈도우즈 API 정복 中 -

 

'Programming Study > Win32 API' 카테고리의 다른 글

입력_타이머  (0) 2014.09.10
입력_마우스  (0) 2014.09.10
출력  (0) 2014.09.06
윈도우즈 프로그래밍 한번 알아보기  (0) 2014.09.06
윈도우즈 프로그래밍  (0) 2014.09.06