일반적으로 도스에서 입력하는걸 생각해보자. 그러면 생각할것없이 키보드가 갖고 있는 고유의 값을 받아서 프로그램에서 문자로 해석해 모니터로 쏴주면 된다.
 그럼 윈도우에서는 어떠한가? 멀티테스킹이란 것으로 윈도우의 여러개의 창들이 있고 내가 실행하고 있는 프로그램중에서도 내가 원하는 위치에 글자를 출력해야 한다.
 이렇게 어디에 글자를 출력할것인지 선택하는걸 "포커스"라고 한다.
 키보드에서 입력받은 문자는 "활성화"된 프로그램의 CP부터 글자가 출력이 된다.(기본적으로)

 활성화를 "선택" 이라고 보면 되고 포커스를"집중"이라고 생각하면 쉽다.

자, 그럼 WM_CHAR의 활용을 보자.

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
 HDC hdc;
 PAINTSTRUCT ps;
 static TCHAR str[256];
 int len;

 switch(iMessage)
 {
 case WM_CHAR:
  len=lstrlen(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,lstrlen(str));
  EndPaint(hWnd,&ps);
  return 0;
 case WM_DESTROY:
  PostQuitMessage(0);
  return 0;
 }
 return (DefWindowProc(hWnd,iMessage,wParam,lParam));
}


여기서 집중해야 할것은 음...
 case WM_CHAR:
  len=lstrlen(str);
  str[len]=(TCHAR)wParam;
  str[len+1]=0;
  InvalidateRect(hWnd,NULL,FALSE);
  return 0;

이정도면 충분할것 같군.

대충 해석을 해보자면, 정수형 len에 str의 현재 길이를 구한다.
가장 처음 상태에선 아무것도 없는 0이 반환이 되겠지?
그럼 str[0]에 wParam글자가 온다.
여기서 WM_CHAR메시지는 은 입력된 문자의 코드를 wParam으로 전달한다.

여담으로 lParam도 한번 보고 가자. WM_CHAR의 경우 lParam에는 비트별로
0~15비트에는 반복카운트,
16~23 스캔코드
24 : 오른쪽 Alt, 오른쪽 Ctrl등 101키에만 있는 확장키가 눌러졌을경우 1
25~28 : 미사용
29 : Alt키가 눌렸으면 1
30 : 메시지가 보내기전에 키가 눌러져 있었으면 1
31 : 키가 놓아지면 1, 눌러지면 0

자 여담은 여기서 마치도록 하고

  len=lstrlen(str);
  str[len]=(TCHAR)wParam;
  str[len+1]=0;

이걸 조금더 자세히 보자면,
str[0]에 글자가 들어가고 그다음 배열에 널을 넣어 문자의 종료를 알린다.
그리고 만약또다시 뭔가가 들어온다싶으면 lstrlen(str)==1 이되므로.
str[1]에 글자가 넣어진다. 그리고 str[2]에 널문자가 오게 되겠지.
한글자 한글자씩 문자를 넣고 널문자를 하나씩 미루는 형식으로 되어있다.

자, 여기서 끝내고 글자가 짠! 하고 나타나면 좋겠지만, 하나 부족한것이 있다면, 출력하는 코드가 보이지 않는다. 화면에 표시하는코드는? 아, WM_PAINT에 있군. 그렇다면 WM_PAINT를 호출하는 시점은?

1. 프로그램을 시작할때.
자, 프로그램을 시작할때 str은 비어있다. 아무리 글자를 쳐봐도 화면에 나오지 않는 이유가 그것이다.
호출하는 시점이 틀려먹었잖아. 그렇다면 또 언제 호출을 하지?

2. 화면을 다시 그릴때.
 화면을 다시 그릴땐 WM_PAINT에 저장되있는것이 다시 호출이 된다. 음.. 언제 다시 호출이 되지? 윈도우창이 가려지고 다시 나타날때 다시 그려진다.

자, 이 화면을 다시그리라는 명령을 해주는 함수가 있으니

  InvalidateRect(hWnd,NULL,FALSE);

요 함수다.
이 함수는 윈도우의 작업영역을 무효화 하여 운영체제가 WM_PAINT메시지를 다시 호출하도록 한다.
첫번째 hWnd는 그 대상이 된다. 뭐, 다른 윈도우를 대상으로 할 수도 있다.
그다음은 CONST RECT *lpRect인데. 무효화할 사각형을 지정한다. 이 값이 NULL값이면, 윈도우의 전영역이 무효화 된다. 하지만 NULL값으로 두면 그릴것이 많아질수록 속도가 느려질수 있는 단점이 있다.
세번째는 BOOL bErase로 무효화되기 전에 배경을 모두 지운후 다시 그릴 것인지 아니면 배경을 지우지 않고 그릴것인지를 지정한다. TRUE면 배경을 지운호 다시그리고, FALSE면 배경을 지우지 않고 다시 그린다.

'Programming > Visual C++' 카테고리의 다른 글

입력3. TranslateMessage  (0) 2011.06.29
입력2. WM_KEYDOWN  (0) 2011.06.29
출력5. MessageBox & MessageBeep  (0) 2011.06.28
출력4. 기타  (0) 2011.06.28
출력3. DrawText  (0) 2011.06.28

+ Recent posts