'output'에 해당되는 글 5건

  1. 2010.07.18 WinApi 타이머
  2. 2010.07.17 WinApi MessageBox
posted by nsakura 2010. 7. 18. 17:49

메세지는 프로그램 실행중에 사용자로부터 입력 된다.

메세지는 이렇게 사용자에 의해 대부분 유발되지만  사용자의 동작과 상관없이 발생하는 메세지도 있는데

대표적으로 WM_TIMER가있다.

자 WM_TIMER를 이용해 프로그램을 하나 짜보자.

#include <windows.h>

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);

HINSTANCE g_Inst;
LPCTSTR wndname=TEXT("GFP TIME");

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,int nShowCmd){
 HWND hWnd;
 MSG Message;
 WNDCLASS WndClass;
 g_Inst=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;
 WndClass.lpszClassName=wndname;
 WndClass.lpszMenuName=NULL;
 WndClass.style=CS_HREDRAW|CS_VREDRAW;
 RegisterClass(&WndClass);

 hWnd=CreateWindow(wndname,wndname,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,(HMENU)NULL,hInstance,NULL);

 ShowWindow(hWnd,nShowCmd);

 while(GetMessage(&Message,NULL,0,0)){
  TranslateMessage(&Message);
  DispatchMessage(&Message);
 }
 return (int)Message.wParam;

}

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam){
 HDC hdc;
 PAINTSTRUCT ps;
 SYSTEMTIME st;
 static TCHAR sTime[128];

 switch(iMessage){
 case WM_DESTROY:
  KillTimer(hWnd,1);
  PostQuitMessage(0);
  return 0;
 case WM_CREATE:
  SetTimer(hWnd,1,1000,NULL);
  return 0;
 case WM_TIMER:
  GetLocalTime(&st);
  wsprintf(sTime,TEXT("%d : %d: %d"),st.wHour,st.wMinute,st.wSecond);
  InvalidateRect(hWnd,NULL,true);
  return 0;
 case WM_PAINT:
  hdc=BeginPaint(hWnd,&ps);
  TextOut(hdc,100,100,sTime,lstrlen(sTime));
  EndPaint(hWnd,&ps);
  return 0;
 }
 return (DefWindowProc(hWnd,iMessage,wParam,lParam));
}

여기서 새로운 구조체와 몇개의 함수가 등장하는데.

SYSTEMTIME 구조체와  GetLocalTimer이라는 함수는  일단 차후에 자세히 다루게 될 것이다.

WM_CREATE메세지는 윈도우가 처음 생설될 때 발생한다.

WM_CREATE가 발생하면

SetTimer 함수가 호출되는데.. 함수 원형은

UINT SetTimer(HWND hWnd, UINT nlDEvent, UINT uElapse, TIMERPROC ipTimerFunc);

첫 번째 인수 타이머 메세지를 받을 윈도우

두 번째  타이머의 번호를 지정하며 이 번호 WM_TIMER 메시지에서 타이머를 구분하기 위한 표식을 사용

세 번째 타이머의 주기를 설정하는데 단위는 1/1000초이다.

네 번째 타이머 메세지가 발생할 때마다 호출되는 함수를 지정하는데 사용하지 않을 경우 NULL로 지정한다.

WM_TIMER 메세지는 wParam으로 타이머 ID를 전달 받으면 lParam으로 타이머 메세지를 발생시 호출될 함수의 번지를 전달한다.

WM_TIMER 메세지가 발생하면 GetLocalTime함수로 시간을 조사한 후 출력을 위해 sTimer 문자열로 변환해 둔다. 시간이 바뀔때마다.

갱신 InvalidateRect함수로 통해 WM_PAINT를 발생.

그리고 윈도우가 꺼질때.

WM_DESTROY메세지가 발생 되는데...

KillTimer함수는 설치된 타이머를 없애는 함수 이다.


'Computer > Win API' 카테고리의 다른 글

WinApi 타이머 확장 문제.  (0) 2010.07.18
WinApi 타이머2 [SendMessage]  (0) 2010.07.18
WinApi 마우스 입력.  (0) 2010.07.18
WinApi WM_KEYDOWN  (0) 2010.07.18
WinApi input WM_CHAR  (0) 2010.07.17
posted by nsakura 2010. 7. 17. 15:47

요즘 게임 말고 예전 게임을 생각을 해보자 저 MessageBox는 상당히 많이 나왔었다는 사실.

특히 게임을 종료할때 작은창이 뜨면서. "너님 종료할래얌?"

이라는 메세지가 뜨면서 확인 취소 버튼이있는 작은 창을 본적 있을 것이다.

오늘은 그것에 대해서 알아보도록 하자.

이번 코드도 상당히 간단하다.

#include <windows.h>

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);

HINSTANCE g_Inst;

LPCTSTR winName=TEXT("GFP MESSAGEBOX");

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,int nShowCmd){
 HWND hWnd;
 MSG Message;
 WNDCLASS WndClass;
 g_Inst=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;
 WndClass.lpszClassName=winName;
 WndClass.lpszMenuName=NULL;
 WndClass.style=CS_HREDRAW|CS_VREDRAW;
 RegisterClass(&WndClass);

 hWnd=CreateWindow(winName,winName,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,(HMENU)NULL,hInstance,NULL);
 
 ShowWindow(hWnd,nShowCmd);

 while(GetMessage(&Message,NULL,0,0)){
  TranslateMessage(&Message);
  DispatchMessage(&Message);
 }


 return (int)Message.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam){
 switch(iMessage){
 case WM_DESTROY:
  PostQuitMessage(0);
  return 0;
 case WM_LBUTTONDOWN:
  MessageBox(hWnd,TEXT("메세지 박스 입니다,"),winName,MB_OK);
  return 0;
 }

 return (DefWindowProc(hWnd,iMessage,wParam,lParam));

}

메세지 박스 함수 원형을 자세히 살펴보자!

int MessageBox(HWND hWnd, LPCTSTR lpText,LPCTSTR lpCaption,UINT nType);

첫 번째 인수 박스의 오너 윈도우

두 번째 인수 메세지 박스의 내용

세 번째 인수 메세지 박스의 제목

네 번째 인수 메세지 박스의 종류

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

다 사용해 보자!

본인은 간단하게
 
  case WM_LBUTTONDOWN:
  cnt++;
  if(cnt==7){
   cnt=1;
  }

  switch(cnt){
   case 1:
    MessageBox(hWnd,TEXT("MB_OK 메세지 박스 입니다,"),winName,MB_OK);
    return 0;
   case 2:
    MessageBox(hWnd,TEXT("MB_ABORTRETRYIGNORE 메세지 박스 입니다,"),winName,MB_ABORTRETRYIGNORE);
    return 0;
   case 3:
    MessageBox(hWnd,TEXT("MB_OKCANCEL 메세지 박스 입니다,"),winName,MB_OKCANCEL);
    return 0;
   case 4:
    MessageBox(hWnd,TEXT("MB_RETRYCANCEL 메세지 박스 입니다,"),winName,MB_RETRYCANCEL);
    return 0;
   case 5:
    MessageBox(hWnd,TEXT("MB_YESNO 메세지 박스 입니다,"),winName,MB_YESNO);
    return 0;
   case 6:
    MessageBox(hWnd,TEXT("MB_YESNOCANCEL 메세지 박스 입니다,"),winName,MB_YESNOCANCEL);
    return 0;

  }

위의 코드를 사용할때 cnt변수는 전역으로 설정되어있어야하며 초기화는 잊지말자.

위의 코드를 사용하면 마우스 버튼을 누를때마다 각 다른 메세지박스가 나온다.



팁으로 메지박스에 아이콘을 출력할수 있는데 nType 버튼종류와 아이콘 종류를 or연산으로 묵어서 사용이 가능하다

아이콘 값은 다음과 같다.

 MB_ICONEXCLAMATION,MB_ICONWARNING  삼각형에 느낌표
 MB_ICONINFORMATION,MB_ICONASTERISK  말꾸러미에 !표
 MB_ICONQUESTION  말꾸러미에 ?표
 MB_ICONSTOP,MB_ICONERROR,MB_ICONHAND  금지 표시

한번 해보자

 case WM_LBUTTONDOWN:
  MessageBox(hWnd,TEXT("메세지 박스 입니다,"),winName,MB_OK|MB_ICONINFORMATION);
  return 0;
 }


앞에서 보면 여러가지 버튼이 나왔는데 그 버튼에 대한 처리를 한번 해보자.

MB_YESNO를 사용한다고 치자 즉 YES와 NO에 각각 이벤트를 넣어보자.

어떻게 해야할것 인가?

역시 간단하다.

 case WM_LBUTTONDOWN:
  if(MessageBox(hWnd,TEXT("메세지 박스 입니다,"),winName,MB_YESNO|MB_ICONINFORMATION)==IDYES){
   MessageBox(hWnd,TEXT("YES를 눌렀음."),TEXT("YES"),MB_OK|MB_ICONINFORMATION);
   return 0;
  }
  else{
   MessageBox(hWnd,TEXT("NO를 눌렀음,"),TEXT("NO"),MB_OK|MB_ICONINFORMATION);
   return 0;
  }
 }

자 그럼 버튼에 대한 리턴값을 알아보자

 IDABOUT  about 버튼을 눌렀다.
 IDCANCEL  cancel 버튼을 눌렀다.
 IDIGNORE  ignore 버튼을 눌렀다.
 IDNO  no 버튼을 눌렀다.
 IDOK  ok 버튼을 눌렀다.
 IDRETRY  retry 버튼을 눌렀다.
 IDYES  yes 버튼을 눌렀다.

이때까지는 대부분 눈에 보이는 출력을 했다. 글씨를 보여준다던가 그림을 그린다던가.

그런식의 출력을 했는데 마지막으로 보이지 않는 출력을 하려고한다.

바로 소리!

함수 원형은

BOOL MessageBeep(UINT nType);

nType은 역시 메크로 정의가 되어있는데.

 0xffffffff  PC의 스피커를 통해 음을 낸다.
 MB_ICONASTERISK  Asterisk 비프음
 MB_ICONEXCLAMATION  Exclamation 비프음
 MB_ICONHAND  Hand 비프음
 MB_ICONQUESTION  Question 비프음
 MB_OK  시스템 디폴트 비프음

하지만 시스템이 정의한 소리가 아닌 진짜 소리를 내고 싶으면 PalySound함수를 사용해야하지만 이건 차후에

사용해보자



tip

윈도우 타이틀 바에문자열을 출력함 SetWindowText 함수가 있는데

이 함수는 디버깅 목적으로도 사용을 하니 알아보는것도 나쁘지 않다.

타이틀바에서 문자열을 잃을때는 GetWindowText 함수가 있다.







자 이로서 출력 부분은 끝을 내도록 하자.

다음 포스팅은 당연히 입력 부분을 해보자!

'Computer > Win API' 카테고리의 다른 글

WinApi WM_KEYDOWN  (0) 2010.07.18
WinApi input WM_CHAR  (0) 2010.07.17
WinApi 여러가지 출력  (0) 2010.07.16
WinApi DrawText  (0) 2010.07.15
WinApi DC 예제  (0) 2010.07.15