본문 바로가기
WIN32 API

[WIN32 API]기본 API 정리 및 코드 설명

by Junk_Seo 2018. 4. 25.
반응형

API

visual studio 2017에서 Windows 데스크톱 응용 프로그램을 선택하고 프로젝트를 생성하면 기본 API 코드가 작성되어 있는 프로젝트를 생성합니다. 

하지만 이 기본 프로젝트 코드가 보기 힘들기 때문에 정리를 하는 과정이 필요합니다.

 

정리를 하면 다음과 같은 코드가 되고 실행하면 아무 기능 없는 기본 윈도우 창을 띄어줍니다.

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

int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);
    // TODO: 여기에 코드를 입력합니다.

    // 윈도우 클래스 등록
    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_WIN32APIBASIC));
    wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wcex.lpszMenuName = 0;
    wcex.lpszClassName = L"calssName";
    wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
    RegisterClassExW(&wcex);

    // 윈도우 생성
    HWND hWnd = CreateWindowW(L"calssName", L"Seo", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
    if (!hWnd)
        return FALSE;

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    // 이벤트(메시지) 처리
    MSG msg;
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return (int)msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    // 이벤트(메시지)처리 콜백 함수

    switch (message)
    {
    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hWnd, &ps);

        // TODO: 여기에 hdc를 사용하는 그리기 코드를 추가합니다.
        EndPaint(hWnd, &ps);
    }
    break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

 

<코드 설명>

1. 윈도우 클래스 등록

WNDCLASSEXW wcex;

~

RegisterClassExW(&wcex);

이 코드는 윈도우 클래스를 등록하는 코드입니다.

WINCLASSEXW 구조체 변수 wcex에 값을 세팅하고 RegisterClassExW() 함수를 통해 윈도우 클래스를 등록합니다.

wcex 구조체 변수에 값을 세팅할 때 안 쓰는 값이라도 0으로 초기화를 해주어야 합니다. 그렇지 않으면 쓰레기 값으로 세팅이 되어 문제가 발생하게 됩니다.

이렇게 등록된 윈도우 클래스를 통해 윈도우를 생성하게 됩니다.

 

여기서 가장 중요한 부분은 

 wcex.lpfnWndProc    = WndProc;

 wcex.lpszClassName  = L"calssName";

이 2개의 값을 세팅하는 것입니다.

 

wcex.lpfnWndProc    = WndProc;

이 부분은 콜백콜백 함수 포인터를 저장하는 것으로 WndProc() 함수는 메시지 처리 콜백 함수입니다.

윈도우의 메시지 처리를 위한 콜백 함수를 등록하는 것으로 윈도우를 생성하고 메시지를 처리할 때 여기에 등록한 함수를 사용하여 처리합니다.

wcex.lpszClassName  = L"calssName";

윈도우 클래스의 id값을 세팅하는 것으로 윈도우를 생성할 때 이 값을 참조하여, 윈도우를 생성합니다.

이 값은 WCHAR형 문자열의 값을 가지기 때문에 L"~"을 사용하여 값을 세팅합니다.

 

****WCHAR****

WCHAR 16bit 유니코드 문자 집합입니다.  (1바이트 char형(아스키)과 호환이 안됩니다.)

WCHAR형은 "문자열"로 초기화하거나 문자열은 대입하는 것이 아니라. L"문자열"로 합니다. 앞에 L을 붙여준다.

 _T("문자열") 로도 가능한데 찾아보면 #define으로 L"문자열"과 같은 것 임을 알 수 있다.

 

 

2. 윈도우 생성

CreateWindowW() 함수를 사용하여 등록된 윈도우 클래스로 윈도우를 생성합니다.

첫 번째 인자로 윈도우 클래스를 등록할 때 세팅했던 wcex.lpszClassName 값과 동일한 값을 인자로 주어야 이 값을 참조하여 등록된 윈도우를 찾아서 윈도우를 생성하게 됩니다.

두 번째이라고 WCHAR 문자열을 받는데, 이 값은 생성된 윈도우 좌측 상단에 뜨는 윈도우 창의 이름(?)입니다. 특별히 값을 설정하고 싶지 않으면 nullptr로 주면 됩니다.

 

 

3. 윈도우 메시지(이벤트) 처리

API는 이벤트 처리 프로그램입니다. 따라서 윈도우에서 이벤트가 발생하면 GetMessage() 함수를 통해서 받아오고 TranslateMessage(), DispatchMessage() 함수를 거쳐서 이벤트를 메시지로 바꾸고 메시지 큐에 순서대로 들어가게 됩니다.. 

이 메시지 큐에 들어간 이벤트를 콜백함수에서 순차적으로 처리하게 됩니다.

 

프로그램에서 이벤트가 발생하면 이 이벤트가 메시지로 바뀌고 메시지 큐에 들어가게 된다.

이 메시지 큐에 들어있는 이벤트를 처리할 수 있을 때 콜백 함수가 순차적으로 처리하게 된다.

 

이벤트를 처리하는 과정에 대한 절차를 지키면서 작업을 해야 합니다. 그렇지 않으면 이벤트 처리가 꼬이게 됩니다.

즉 무엇인가 일을 하게 하려면 이벤트를 처리하는 방식으로 해야 한다.

 

 

4. 메시지(이벤트) 처리 콜백 함수

여기서 콜백 함수는 WndProc() 함수입니다.

WndProc()는 자신의 윈도우에 발생하는 메시지를 처리하는 함수입니다. 이 함수는 콜백(CALLBACK, 함수의 포인터) 기술을 사용하기 때문에 함수의 원형은 아래의 형식을 지켜야 하지만 함수의 이름은 변경이 가능합니다.

 

윈도우에 발생하는 엄청난 양의 메시지를 모두 처리하는 것은 현실적으로 힘들기 때문에 이 함수에서는 자신이 처리하고 싶은 메시지만 처리하면 됩니다. 

하지만 프로그램 동작과 관련하여 필수적으로 처리해야 하는 메시지를 처리하지 않으면 문제가 되기 때문에 DefWindowProc() 함수를 호출하여 내부적으로 정해진 작업을 수행하도록 해야 합니다. 

 

함수의 형태

LRESULT CALLBACK WndProc(HWND hWnd, UNIT message, WPARAM wParam, LPARAM, lParam)

{

//메시지 처리

return DefWindowProc(hWnd, message, wParam, lParam);  // 자신이 처리하지 않은 메시지들의 기본작업을 대신 처리해 주는 함수

}

 

인자 

hWnd         : 메시지가 발생만 윈도우의 핸들

message         : 발생한 메시지(이벤트)

wParam, lParam : 들어오는 메시지에 따라서 들어오는 값 

반응형

'WIN32 API' 카테고리의 다른 글

[WIN32 API] 더블 버퍼링(Double Buffering)  (0) 2018.05.03
[WIN32 API]기본 class 작업  (1) 2018.04.25
[WIN32 API]HINSTANCE와 자료형 의미 설명  (0) 2018.04.25