Win32_API - 버튼 연동하기

컴퓨터/Win32-API

728x90
반응형

서론

지난 포스트에서 생성한 하위 윈도인 버튼을 클릭하면 반응을 하기 위한 간단한 예제를 알아보도록 합시다.

 

WM_COMMAND:

윈도우윈도 창에서 클릭을 한다던지, 특정 키보드를 누른다면 기본적으로 윈도에서는 WM_COMMAND라는 메시지를 보냅니다. 이 메시지 안에 어떤 처리를 할 것인지 입력한다면, 만든 버튼에 기능을 부여할 수 있게 됩니다.

 

그렇다면 버튼이 클릭된 것을 어떻게 알 것인가 ?

아무런 입력이나 WM_COMMAND를 생성한다는 것을 이해했습니다. 그렇다면 어떻게 버튼이 눌렸는지 알 수 있을까요? 

 

우선 메시지를 처리하는 콜백 함수를 살펴볼 필요가 있습니다.

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

 

위처럼 윈도 핸들, 윈도우 메시지를 받고 2가지의 파라미터 변수를 받는 것을 알 수 있습니다. 

이 2가지의 파라미터 변수를 통해 다양한 윈도의 상태 정보를 가지고 올 수 있습니다.

 

이 파라미터를 처리하는 방법은 나중에 다른 포스트에서 조금 더 다루도록 하겠습니다.

 

일단은! wParam이라는 매개변수를 통해 버튼 상태의 알 림메 세지가 발생하게 됩니다. 

wParam을 통해 버튼이 클릭되었다고 알려주는 코드는 BN_CLICKED입니다. (정수로는 1)

#define BN_CLICKED          0

본 포스트에서는 버튼을 누르면 wparam에는 BN_CLICKED가 담긴다까지만 알아도 무방합니다. 

 

버튼이 클릭되면 알림 메시지를 만들어보자

    case WM_COMMAND:
        switch (wParam)
        {
        case BN_CLICKED:
            MessageBox(hWnd, L"클릭 되었습니다!",L"buttion",NULL);
            break;
        }

콜백 함수에서 WM_COMMAND: 메시지 처리에 진입 후. 

wParam의 정보를 읽어 BN_CLICKED 코드가 발생하면 처리하는 소스코드를 작성했습니다. 

 

전체 소스코드


#include <windows.h>

#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>


HINSTANCE hInst;

// 이 코드 모듈에 포함된 함수의 선언을 전달합니다:
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);


int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{

    //윈도우 창 구조체 정의 및 적용
    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 = NULL;
    wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = L"Test";
    wcex.hIconSm = NULL;
    RegisterClassExW(&wcex);

    //적용한 윈도우 생성 및 업데이트
    hInst = hInstance; // 인스턴스 핸들을 전역 변수에 저장합니다.
    HWND hWnd = CreateWindowW(L"Test", L"Test", 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)
{
    HDC hdc;
    switch (message)
    {
    case WM_CREATE:
        CreateWindowW(L"button",L"buttion1", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 20, 20, 100, 25,hWnd, NULL , hInst,NULL);
        break;
    case WM_LBUTTONDOWN:
        hdc = GetDC(hWnd); //DC을얻는 방법 1
        ReleaseDC(hWnd, hdc);
        break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            // TODO: 여기에 hdc를 사용하는 그리기 코드를 추가합니다...
            TextOutW(hdc, 100, 100, L"Hello World", 12);
            TextOutA(hdc, 200, 200, "Hello World", 12);
            EndPaint(hWnd, &ps);
        }
        break;
    case WM_COMMAND:
        switch (wParam)
        {
        case BN_CLICKED:
            MessageBox(hWnd, L"클릭 되었습니다!",L"buttion",NULL);
            break;
        }
    case WM_SETTEXT:

    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

 

 

추가로 생각해 볼 것

그렇다면, 버튼이 여러 개면 위의 소스코드로는 구분하기 버튼의 클릭 명령만을 이해하고 있지 어떤 버튼인지는 이해할 수 없습니다. 이를 이해하기 위해서는 콜백 함수로 전달되는 파라미터들에 대한 이해가 필요합니다. 

 

다음 포스트에서는 이 콜백 함수의 파라미터들에 대한 공부를 해보도록 하겠습니다.

728x90
반응형

Commnet

G91개발일지

Gon91(지구일)

91년생 공학엔지니어의 개발일지

TODAY :

YESTER DAY :

TOTAL :