비주얼 스튜디오가 기본적으로 제공해 주는 Client프로젝트의 winMain은 초심자인 나에게 도전 욕구를 꺽는 아주 불친절한 존재다.

별 것도 아닌 것들을 리소스에 넣고, 땡겨 오고, 변수화 하고 읽기 아주 불편하게 해놨다.

조금씩 정리를 해보고자 한다.


// 커널 오브젝트
// 윈도우 생성 후 핸들값 반환
HWND hWnd = CreateWindowW(L"Test", L"Game", WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);

윈도우 생성하고 핸들 값을 반환하는 WinApi 함수다.

클래스 이름과 윈도우 제목은 직접 지정해줘도 된다.

HWND CreateWindowW(
    LPCWSTR   lpClassName,   // 등록된 윈도우 클래스 이름
    LPCWSTR   lpWindowName,  // 윈도우 제목
    DWORD     dwStyle,       // 윈도우 스타일
    int       x,             // 윈도우의 x 좌표
    int       y,             // 윈도우의 y 좌표
    int       nWidth,        // 윈도우 너비
    int       nHeight,       // 윈도우 높이
    HWND      hWndParent,    // 부모 윈도우 핸들
    HMENU     hMenu,         // 메뉴 핸들(또는 자식 윈도우 ID)
    HINSTANCE hInstance,     // 인스턴스 핸들
    LPVOID    lpParam        // 추가 매개변수
);

이후 클래스 이름만 동일하게 맞춘다.

//  함수: MyRegisterClass()
//  용도: 창 클래스를 등록합니다.
ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEXW wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_CLIENT));
    wcex.hCursor        = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName = nullptr; //MAKEINTRESOURCEW(IDC_CLIENT);
    wcex.lpszClassName  = L"Test";
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassExW(&wcex);
}

GetMessage는 메세지가 없으면 반환값이 없다.

반응형 프로그램 제작시 사용가능하겠지만, 기본적으로 그래픽스는 게임과 연관이 많으니, 메세지가 없어도 구동 가능한 형태로 변경한다

PeekMessage는 메세지가 없어도 반환하니, 메세지가 없을때 우리의 그래픽이 연산을 하면 된다.

// 기본 메시지 루프입니다:
// 반응형 프로그램
// 윈도우 메세지가 없으면 반환되지 않음
// Getessage(&msg, nullptr, 0, 0)
while (true)
{
    // 메세지가 없더라도 반환한다.
    if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
    {
        if (WM_QUIT == msg.message)
            break;

        // 메세지가 있을때
        // 메세지 관련 작업 실행
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    else
    {
        // 메세지가 없을때
        // Game Engine 실행
        CEngine::GetInst()->progress(); // 한번 수행 == 1 프레임
    }
}

태그: ,

카테고리:

업데이트:

댓글남기기