'PROGRAMMING/code exercise'에 해당되는 글 1건

  1. 2011.03.16 [WinApi] WinMain()과 WndProc()를 이용한 윈도우 만들기

#include <windows.h>

 

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

 

 

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, int nCmdShow)

{

        static TCHAR szAppName[] = TEXT("MainWindow"); // 프로그램내에서그프로그램을대표하는이름(해당창)

        HWND hWnd;

        MSG  msg;

        WNDCLASS wc;

 

        // 출력될윈도우의사양을채워준다.

        wc.style = CS_HREDRAW | CS_VREDRAW;  // Flag : 구조체에멤버의값을채우기위해매크로상수로만든것

        wc.lpfnWndProc = WndProc;

        wc.cbClsExtra = 0;

        wc.cbWndExtra = 0;

        wc.hInstance = hInstance;

        wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);

        wc.hCursor = LoadCursor(NULL, IDC_ARROW);

        wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);

        wc.lpszClassName = szAppName;

        wc.lpszMenuName = NULL;

        RegisterClass(&wc); // 윈도우등록

 

        hWnd = CreateWindow(

               szAppName, //  현재윈도우핸들을부여받지않은상태에서윈도우를구별하기위한식별문자열

               TEXT("Hello Window !!!"), // 제목표시줄에표시되는프로그램의제목

               WS_OVERLAPPEDWINDOW, // 출력되는윈도우의표준사양, 겹치기가능한윈도우가출력된다.

               CW_USEDEFAULT, CW_USEDEFAULT, // 전체화면의x,y 좌표

               CW_USEDEFAULT, CW_USEDEFAULT, // 윈도우의x크기, y크기

               NULL, // 부모윈도우의핸들

               NULL, // 윈도우에삽입되는메뉴표시줄의핸들

               hInstance,

               NULL);

 

        ShowWindow(hWnd, nCmdShow);

        UpdateWindow(hWnd);

 

        // 현재출력된위치와크기의윈도우에서발생되는윈도우메시지를

        // 윈도우메시지처리함수(WndProc)에전달하는루프

        while(GetMessage(&msg, NULL, 0, 0)) // 아래WM.QUIT메시지를만나면이리턴값으로msg.wParam을던져주고while(루프)을빠져나간다.

        {

               TranslateMessage(&msg); // 입력받은(이벤트로들어온) msg 구조체분석

               DispatchMessage(&msg); // 구조체를분석한msgWndProc함수로전달하는역할

               //구조체를분석한값을운영체제에전달-> 운영체제가wndProc로받음. 운영체제가WndProc를불러냄

        }

 

        return msg.wParam;

}

 

// WinMain함수에서전달되어져오는윈도우메시지를처리하는함수

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)

// 구조체를통째로받지않고4개로분석해서받는이유:

// msg의값은초기화된적이없고, GetMessage에서포인터로가리키고있을뿐. 실제값은큐공간에있다(응용프로그램이아니라)

// 큐공간을가리키고있으며, DispatchMessage 역시응용프로그램내의큐번지를가리키고있다.

// 실제값이전달되는것이아니라주소값만가리키고있음

// 이후에는실제값이필요하므로포인터를사용하지않고실제값을가져와메시지를처리한다.

{

        switch(msg)

        {

        case WM_DESTROY:

               PostQuitMessage(0); // WM.QUIT 메시지를큐끝에붙여줌.: 루프(위의while)를빠져나오게함

               // WM.QUIT메시지를거치지않으면프로그램이종료되지않는다. 창이없어졌더라도프로그램은실행중. 메모리상에존재.

               // 이런식으로종료되지않는프로그램을만들수있다.

               break;

        }

 

        return DefWindowProc(hWnd, msg, wParam, lParam); // 위의WM_DESTROY로처리할수없는나머지는전부DefWindowProc에서처리

        //위의것을사용자정의함수로사용자가통제가능. 그러나, DefWindowProcOS자체의함수. OS가알아서처리함.

        // WM_DESTROY에없는것은OS가알아서처리하고지워버림

}


Posted by 마마필로 :