'PostQuitMessage'에 해당되는 글 1건

  1. 2012.10.28 기본 윈도우 출력

 #include <windows.h>

 

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

HINSTANCE g_hInst;  //많은 API함수들이 hInstance값을 요구하기때문에 전역변수로 선언하여 WinMain함수 내에서

                      hInstance값으로 초기화

LPCTSTR lpszClass=TEXT("First");   //클래스 이름

 

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

        LPSTR lpCmdLine, int nShowCmd ) {     //윈도우즈 프로그램의 시작점

 

               HWND hWnd;

               MSG Message;

               WNDCLASS WndClass;

 

               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=lpszClass;

               WndClass.lpszMenuName=NULL;

               WndClass.style=CS_HREDRAW | CS_VREDRAW;

               RegisterClass(&WndClass);

 

               hWnd=CreateWindow(lpszClass, TEXT("HI~"), 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 Message.wParam;

}

 

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage,

        WPARAM wparam, LPARAM lparam) {

              

               switch(iMessage) {

               case WM_DESTROY:

                       PostQuitMessage(0);

                       return 0;

               }

        return DefWindowProc(hWnd, iMessage, wparam, lparam);

}

 

해더파일

 #include <windows.h>

윈도우즈에서는 하나의 헤더파일에 모든 API함수들의 원형과 사용하는 상수들이 정의 되어있기때문에 windows.h만 포함하면된다.

 

WinMain

 int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)

윈도우즈 프로그램의 시작점은 main이 아닌 WinMain이며 모든 윈도우즈 프로그램은 WinMain에서부터 실행을 한다.

APINETRY지정자는 윈도우즈의 표준 호출 규약인 _stdcall을 사용한다는 뜻인데 없다고 생각하도 무방하다.

- hInstance : 프로그램의 인스턴스 핸들이다.

- hPrevInstance : 바로 앞에서 실행된 현재 프로그램의 인스턴스 핸들이다. Win32에서는 항상 NULL이다.

- lpszCmdParam : 명령행으로 입력된 프로그램 인수이다. 도스의 argv인수에 해당하며 보통 실행직후에 열 파일의 경로가 전달

- nCmdShow : 프로그램이 실행될 형태이며 최소화, 보통 모양들이 전달된다.

 

보통은 hInstance이외에는 잘사용되지 않으며. 인스턴스란 실행중인 프로그램 하나를 칭하는 용어이다. 많은 API함수들이 hInstance값을 인수로 요구하는데 WinMain의 인수로 전달된 hInstance값은 지역변수이기때문에 WnMain함수 내에서만 사용할수있기때문에 편의성을 위해 전역변수 g_hInst에 대입해둔다.

 

WndProc

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wparam, LPARAM lparam)

WndProc은 사용자와 시스템이 보내오는 메세지를 처리하는 역할을 한다. 윈도우즈에서는 특별한 경우를 제외하고는 이 함수가 있어야한다. WinMain은 메인윈도우를 만들고 화면에 윈도우를 표시하기만 할 뿐이며 대부분의 일은 WndProc에서 이루어진다.

WndProc함수에는 CALLBACK이라는 메크로가 사용되었는데 이 메크로도 APIENTRY와 마찬가지로 _stdcall로 정의 되어있다.  

 

윈도우클래스

WinMain함수에서 윈도우를 만들려면 윈도우 클래스를 먼저 등록한우 CreateWindow함수를 호출해야한다. 윈도우 클래스는 만들어질 윈도우의 여러가지 특성을 정의하는 구조체이며 모든 윈도우는 윈도우 클래스의 정보를 기반으로하여 만들어진다.

윈도우 클래스는 windows.h에 다음와 같이 구조체로 정의되어있다.

typedef struct tagWNDCLASSW {

    UINT        style;          //윈도우의 스타일을 정의

    WNDPROC     lpfnWndProc;    //윈도우의 메세지를 처리하는 함수를 지정

    int         cbClsExtra;     //예약예약 영역, 윈도우즈가 내부적으로 사용되며 사용하지 않을경우 0으로 지정

    int         cbWndExtra;     //예약예약 영역, 윈도우즈가 내부적으로 사용되며 사용하지 않을경우 0으로 지정

    HINSTANCE   hInstance;      //윈도우 클래스를 등록하는 프로그램 번호

    HICON       hIcon;          //아이콘 모양

    HCURSOR     hCursor;        //마우스 커서모양

    HBRUSH      hbrBackground;  //윈도우의 배경색상을 지정

    LPCWSTR     lpszMenuName;   //프로그램이 사용할 메뉴를 지정

    LPCWSTR     lpszClassName;  //윈도우 클래스의 이름

} WNDCLASSW, *PWNDCLASSW, NEAR *NPWNDCLASSW, FAR *LPWNDCLASSW;

 

RegisterClass

RegisterClass(&WndClass);

RegisterClass함수의 인수로 WNDCLASS구조체의 번지를 전달한다. 이러한 특성을 가진 윈도우를 사용하겠다는 등록과정

 

CreateWindow

HWND CreateWindow(

        LPCTSTR lpClassName,   //생성하고자 하는 윈도우 클래스를 지정

        LPCTSTR lpWindowName,  //윈도우의 타이틀바에 나타날 문자열

        DWORD dwStyle,         //만들고자하는 윈도우의 형태

        int x,                 //윈도우의 x좌표위치

        int y,                 //윈도우의 y좌표위치

        int nWidth,            //윈도우의 폭

        int nHeight,           //윈도우의 높이

        HWND hWndParent,       //부모윈도우가 있을경우 부모윈도우의 핸들을 지정

        HMENU hMenu,           //윈도우에 사용할 메뉴의 핸들

        HINSTANCE hInstance,   //윈도우를 만드는주체, 즉 프로그램 핸들을 지정

        LPVOID lpParam);       //구조체의 번지 여러개의 윈도우를 만들때 각 윈도우에 고유의 파라미터를 전달하는

                                 특수한 목적으로사용되며 보통은 NULL값을 전달

윈도우 클래스를 등록한후에는 이 윈도우 클래스를 기본으로 실제 윈도우를 생성한다. 윈도우를 생성할때는 CreateWindow함수를 사용한다.

CreateWindow함수는 윈도우에 관한 모든정보를 메모리에 만든후 윈도우를 대표하는 번호인 윈도우 핸들을 리턴한다. 넘겨지는 윈도우 핸들은 hWnd라는 변수에 저장되었다가 이 윈도우를 참조하는 모든함수의 인수로 사용한다.

 

ShowWindow

 ShowWindow(hWnd, nShowCmd);

CreateWindow로부터 생성된 윈도우를 화면으로 출력

nShowCmd는 윈도우를 화면에 출력하는 방법을 지정하며 다음과 같이 상수로 정의되어있다.

매크로상수

의미 

SW_HIDE

 윈도우를 숨긴다 

SW_MINIMIZE

 윈도우를 최소화, 활성화x 

SW_RESTORE

 윈도우를 활성화 

SW_SHOW

 윈도우 활성화하여 보여줌 

SW_SHOWNORMAL

 윈도우를 활성화하여 보여준다. 

 

메세지루프

윈도우즈는 도스와 다르게 미리 입력된 명령을 순서대로 실행하는것이 아니라 실행순서가 명확하게 정해져있지 않으며 상황에 따라 실행순서가 달라진다. 순서에 따르지않고 주어진 메세지를 처리하기위해 메세지루프를 사용하며 WinMain함수의 끝에 다음과 같이 존재한다. 메인 윈도우를 만든 직후 WinMain은 메세지 루프를 실행한다.

while(GetMessage(&Message, NULL, 0, 0)) {

        TranslateMessage(&Message);

        DispatchMessage(&Message);

}

메세지 루프는 윈도우즈의 멀티캐스팅을 지원하는 가장 중요한 역할을 한다.

 

GetMessage함수는 메세지큐에서 메세지를 읽어드린다. 읽어들인 메세지는 첫번째 인수에 전달되는 MSG구조체에 저장된다. 이 함수는 읽어들인 메세지가 프로그램을 종료하는 WM_QUIT일 경우 FALSE를 리턴하며 그외의 메세지는 TRUE를 리턴한다.

※메세지큐 : 메세지큐는 시스템이나 사용자로부터 발생된 메세지가 잠시 대기하는 일종의 메세지 임시 저장영역이다.

 

TranslateMessage함수는 키보드 입력 메세지를 가공하여 프로그램에서 쉽게쓸수 있도록한다.

(Ex : 예를들어 A키를 누르면 A문자가 입력되었다는 메세지를 만들어낸다)

 

DispatchMessage함수는 메세지큐에서 꺼낸 메세지를 윈도우의 메세지 처리 함수인 WndProc로 전달한다.

 

MSG구조체

 typedef struct tagMSG {

    HWND        hwnd;      //메세지를 받을 윈도우의 핸들

    UINT        message;   //어떤 종류의 메세지인가를 나타낸다.

    WPARAM      wParam;    //전달된 메세지에 대한 부가적인정보(32비트)

    LPARAM      lParam;    //전달된 메세지에 대한 부가적인정보(32비트)

    DWORD       time;      //메세지가 발생한 시간

    POINT       pt;        //메세지가 발생했을 때의 마우스 위치

#ifdef _MAC

    DWORD       lPrivate;

#endif

} MSG, *PMSG, NEAR *NPMSG, FAR *LPMSG;

 

WndProc

 LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage,

        WPARAM wparam, LPARAM lparam) {

               switch(iMessage) {

               case WM_DESTROY: //사용자가 프로그램을 끝내려고 할때 발생

                       PostQuitMessage(0);

                       return 0;  //정상적으로 처리됨정상적으로 처리됨

              }

        return DefWindowProc(hWnd, iMessage, wparam, lparam); //처리되지 않은 나머지 메세지에대한 처리

}

메세지가 발생했을 때 프로그램의 반응하는 일을 처리한다. WndProc는 WndMain에서 호출되는것이 아니라 운영체제에 의해 호출된다.

WndProc함수에서는 전달된 2번째인자 iMessage를 이용하여 어떤메세지인지를 구분하고 구분된 메세지에 따라 처리를 해주면된다. 정상적으로 처리됬을경우 0을 리턴한다.

 

WM_DESTROY메세지는 사용자가 프로그램을 끝내려고할때 발생되는 메세지이다. 사용자가 프로그램을 끝낼때 PostQuitMessage(0); 를 호출하여 메세지루프의 GetMessage함수의 리턴값을 False로 만들면서 루프를 종료하고 WndMain이 종료된다.

제일끝에 있는 DefWindowProc 함수는 WndProc에서 처리하지 않은 나머지 메세지에 대한 처리를 한다.

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

문자열, 그래픽 출력  (0) 2012.10.28
Window API배우기전 알아야할것들  (0) 2012.10.28
Posted by No names
,