본문 바로가기

WinAPI

[WinAPI] 기본 윈도우 창

HINSTANCE hInst;                                // 현재 인스턴스입니다.
WCHAR szTitle[MAX_LOADSTRING];                  // 제목 표시줄 텍스트입니다.
WCHAR szWindowClass[MAX_LOADSTRING];            // 기본 창 클래스 이름입니다.

hInst는 윈도우의 인스턴스 핸들을 나타내는데 이것은 운영체제가 프로그램을 식별하기 위한 번호이다. 만약 윈도우에 메모장 2개가 켜져있다면 두 메모장을 인스턴스 핸들로 구분할 수 있다.

 

 

//main함수 역할
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,  //h가 붙으면 핸들, 운영체제가 프로그램을 구별하기 위한 식별번호
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // TODO: 여기에 코드를 입력합니다.

    // 전역 문자열을 초기화합니다.
    LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadStringW(hInstance, IDC_WIN32API, szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance);

WinMain은 main함수 역할을 하는 함수이다. 먼저 MyRegisterClass로 창 클래스를 등록한다.

 

 

ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEXW wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc; //윈도우에게 WndProc함수를 포인터로 전달 
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32API));
    wcex.hCursor        = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = MAKEINTRESOURCEW(IDC_WIN32API);
    wcex.lpszClassName  = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassExW(&wcex);
}

클래스에서 아이콘, 커서 타입, 배경, 메뉴 등을 설정할 수 있고 WndProc함수를 포인터로 전달한다.

WndProc함수는 메시지에 따라서 명령을 처리한다.

 

 // 애플리케이션 초기화를 수행합니다:
    if (!InitInstance (hInstance, nCmdShow))
    {
        return FALSE;
    }

    //단축키 지정, 무시
    HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WIN32API));

    //윈도우 메시지 구조체
    MSG msg;

    // 기본 메시지 루프입니다:
    //데드 타임: 메시지 큐가 비어있는 경우
    //GetMessage: 메시지가 발생해야 루프를 빠져나옴
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        //메시지가 발생하면 이 밑 코드들이 실행된다.
        //Translate: 사용자가 입력한 키값을 어떤 메시지인지 번역
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    return (int) msg.wParam;

다시 WinMain으로 돌아와서 InitInstance함수로 인스턴스를 초기화한다. 그리고 메시지큐에서 메시지를 읽어 (GetMessage) 사용자로부터 입력받은 메시지를 Translate해서 (TranslateMessage) 메시지 처리 함수 WndProc로 전달한다. (DispatchMessage) 메시지 루프가 종료되면 WM_QUIT으로부터 전달된 탈출코드 msg.wParam을 리턴하고 종료한다.

 

 

'WinAPI' 카테고리의 다른 글

[WinAPI] 더블 버퍼링  (0) 2022.01.20
[WinAPI] 삼각함수  (0) 2022.01.16
[WinAPI] 델타 타임  (0) 2022.01.16
[WinAPI] PeekMessage와 윈도우 창 크기 설정  (0) 2022.01.15
[WinAPI] 도형 그리기, 마우스 좌표  (0) 2022.01.15