다음은 마우스 입력 메시지다. 직관적이라 잘 알수 있을듯.

WM_LBUTTONDOWN
WM_RBUTTONDOWN
WM_MBUTTONDOWN
WM_LBUTTONUP
WM_RBUTTONUP
WM_MBUTTONUP
WM_LBUTTONDBLCLK
WM_RBUTTONDBLCLK
WM_MBUTTONDBLCLK


 그리고 여기서 하나더, 마우스 메시지는 lParam의 상위 워드에 마우스 버튼이 눌러진, y좌표, 하위 워드에 x좌표를 가지며 좌표값을 검출해 내기 위해 HIWORD, LOWORD등의 매크로 함수를 사용한다. 즉 마우스 메시지가 발생한 위치의 조표는  (LOWORD(lParam),HIWORD(lParam))이 된다.

 또한 다중모니터의 경우 이 좌표값이 음수가 될수도 있다.

wParam에는 마우스 버튼의 상태와 키보드 조합키의 상태가 전달된다.

MK_CONTROL Ctrl버튼이 눌러져 있음
MK_LBUTTON 마우스 왼쪽버튼이 눌러져 있음.
MK_RBUTTON 마우스 오른쪽 버튼이 눌러져 있음.
MK_MBUTTON 마우스 중간버튼이 눌러져 있음.
MK_SHIFT Shift버튼이 눌러져 있음.

이외에도 마우스가 움직일때 전달되는 WM_MOUSEMOVE, 휠마우스 상태를 정해주는 WM_MOUSEWHEEL등이 있다.

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

타이머.  (0) 2011.06.29
기타. WM_CREATE  (0) 2011.06.29
입력3. TranslateMessage  (0) 2011.06.29
입력2. WM_KEYDOWN  (0) 2011.06.29
입력1. WM_CHAR  (0) 2011.06.29
키보드에서 A라는 글자가 눌렀다 뗏을 경우.

발생하는 메시지는 순서대로
WM_KEYDOWN, WM_CHAR, WM_KEYUP이 발생한다.
하지만 사실 WM_CAHR는 사용자로부터 발생한것은 아니다. WM_KEYDOWN이 오면, 그값을 토대로 WM_CHAR를 발생시킨다. 이 발생시키는 것이 TranslateMessage다.
 이 TranslateMessage라는 놈은 많은 걸 보고 판단해서 WM_CHAR를 발생시킨다. 예를들어 눌렀을때의 Shift키라던가 Caps Lock라던가, 현재 운영체재의 언어설정이라던가 말이다.

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

기타. WM_CREATE  (0) 2011.06.29
입력5. 마우스  (0) 2011.06.29
입력2. WM_KEYDOWN  (0) 2011.06.29
입력1. WM_CHAR  (0) 2011.06.29
출력5. MessageBox & MessageBeep  (0) 2011.06.28

WM_CHAR가 문자만 받는다면 WM_KEYDOWN은 문자이외에도 키보드가 눌리면 발생하는 이벤트 메시지다. 각각의 값은 다른데서 찾아보시고.
wParam값에 키보드가 눌러진 값이 반환이 된다.

다음은 WM_KEYDOWN의 예제이다.
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
 HDC hdc;
 PAINTSTRUCT ps;
 static int x=100;
 static int y=100;

 switch(iMessage)
 {
 case WM_KEYDOWN:
  switch(wParam)
  {
  case VK_LEFT:
   x-=8;
   break;
  case VK_RIGHT:
   x+=8;
   break;
  case VK_UP:
   y-=8;
   break;
  case VK_DOWN:
   y+=8;
   break;
  }
  InvalidateRect(hWnd,NULL,TRUE);
  return 0;
 case WM_PAINT:
  hdc=BeginPaint(hWnd,&ps);
  TextOut(hdc,x,y,TEXT("A"),lstrlen(TEXT("A")));
  EndPaint(hWnd,&ps);
  return 0;
 case WM_DESTROY:
  PostQuitMessage(0);
  return 0;
  }
 return(DefWindowProc(hWnd,iMessage,wParam,lParam));
 }


그리고 다음 예제는 스페이스가 눌리면 A와 #이 토글되는 예제이다.
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
 HDC hdc;
 PAINTSTRUCT ps;
 static BOOL sp_in=FALSE;
 static int x=100;
 static int y=100;
 LPCTSTR a=TEXT("A");

 switch(iMessage)
 {
 case WM_KEYDOWN:
  switch(wParam)
  {
  case VK_LEFT:
   x-=8;
   break;
  case VK_RIGHT:
   x+=8;
   break;
  case VK_UP:
   y-=8;
   break;
  case VK_DOWN:
   y+=8;
   break;
  case VK_SPACE:
   sp_in=!sp_in;
   break;
  }
  InvalidateRect(hWnd,NULL,TRUE);
  return 0;
 case WM_PAINT:
  hdc=BeginPaint(hWnd,&ps);
  if(sp_in==FALSE)a=TEXT("A");
  else if(sp_in==TRUE) a=TEXT("#");
  TextOut(hdc,x,y,a,lstrlen(a));
  EndPaint(hWnd,&ps);
  return 0;
 case WM_DESTROY:
  PostQuitMessage(0);
  return 0;
  }
 return(DefWindowProc(hWnd,iMessage,wParam,lParam));
 }

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

입력5. 마우스  (0) 2011.06.29
입력3. TranslateMessage  (0) 2011.06.29
입력1. WM_CHAR  (0) 2011.06.29
출력5. MessageBox & MessageBeep  (0) 2011.06.28
출력4. 기타  (0) 2011.06.28

 일반적으로 도스에서 입력하는걸 생각해보자. 그러면 생각할것없이 키보드가 갖고 있는 고유의 값을 받아서 프로그램에서 문자로 해석해 모니터로 쏴주면 된다.
 그럼 윈도우에서는 어떠한가? 멀티테스킹이란 것으로 윈도우의 여러개의 창들이 있고 내가 실행하고 있는 프로그램중에서도 내가 원하는 위치에 글자를 출력해야 한다.
 이렇게 어디에 글자를 출력할것인지 선택하는걸 "포커스"라고 한다.
 키보드에서 입력받은 문자는 "활성화"된 프로그램의 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
MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCation, UINT uType);
핸들값, 메시지 박스에 넣을 글자, 타이틀에 나올글자, 메시지 박스에 나타날 버튼의 종류

MB_ABORTRETRYIGNORE Abort, Retry Ignore 세개의 버튼이 나타난다.
MB_OK, OK버튼 하나만 나타난다.
MB_OKCANCEL, OK, CANCEL 두개의 버튼이 나타난다.
MB_RETRYCANCEL, Retry, Cancel 두개의 버튼이 나타난다.
MB_YESNO
MB_YESNOCANCEL

이것뿐아니라 아이콘또한 표시할 수 있다.
MB_ICONEXCLAMATION,MB_ICONWARNING.
MB_ICONINFORMATION,MB_ICONASTERISK.
MB_ICONQUESTION
MB_ICONSTOP, MB_ICONERROR,MB_ICONHAND

그리고 이 MessageBox의 리턴값은 사용자가 누른 버튼값을 되돌려준다.
IDABORT Abort 버튼을 눌렀다.
IDCANCEL
IDIGNORE
IDNO
IDOK
IDRETRY
IDYES

EX)
if(MessageBox(hWnd,Text("응? 뭐라고?"),TEXT("야!!"),MB_YESNO==IDYES){}
else{}

요롷게;



BOOL MessageBeep(UINT uType);
비프음을 내는 함수
0xffffffff  pc스피커를 통해 음을 낸다.
MB_ICONASTERISK Asterisk 비프음
MB_ICONEXCLAMATION Exclamation 비프음
MB_ICONQUESTION Question 비프음
MB_OK 시스템 디폴트 비프음.





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

입력2. WM_KEYDOWN  (0) 2011.06.29
입력1. WM_CHAR  (0) 2011.06.29
출력4. 기타  (0) 2011.06.28
출력3. DrawText  (0) 2011.06.28
출력2. WM_Paint  (0) 2011.06.28

+ Recent posts