Win32_API - 버튼 만들기

컴퓨터/Win32-API

728x90
반응형

서론

수많은 Windows 프로그램들의 Window를 보면 다양한 기능들을 제공하는 버튼들을 많이 보았을 것입니다. 

첨부된 그림처럼 Window 프로그램에는 프로그램을 제어할 수 있는 다양한 기능이 존재합니다.  이를 컨트롤이라 부르며 가장 대표적이고 익숙한 컨트롤 중 하나가 '버튼'입니다.

  • 대표적인 컨트롤 종류
    • button
    • scrollbar
    • edit
    • listbox
    • combobox

 

CreateWindow함수로 버튼을 만들자

버튼 또한 윈도의 일종입니다. 우리가 만드는 메인 윈도의 하위 윈도의 개념으로 적용이 됩니다. 따라서 

윈도를 생성하는 함수인 CreateWindow함수를 통해 만들어집니다. 

 

함수의 원형을 보면 다음과 같습니다.

CreateWindowW(
	lpClassName,	//생성할 클래스 이름
    lpWindowName,	//생성할 윈도우 이름
    dwStyle,		//속성 값
    x, 				//좌표 x
    y,				//좌표 y
    nWidth, 		//폭
    nHeight, 		//높이
    hWndParent,		//상위 윈도우 
    hMenu, 			//메뉴
    hInstance, 		//인스턴스 핸들
    lpParam			//
    )

모르는 부분이 많이 있을 것입니다.  일단, 함수를 통해 버튼을 한번 만들어 보도록 합시다.

 

CreateWindowW(
	L"button",
    L"buttion1", 
    WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 
    20, 20, 100, 25,
    hWnd,
    NULL, 
    hInst,
    NULL);

유니코드를 권장하기 위한 Win32 API 함수인 CreateWindowW를 이용하여 만들어 봤습니다.

하나씩 해석해보자면 다음과 같습니다.

 

  • L"buttion" - Win32 API에서 제공하는 형태의 클래스 호출
  • L"buttion1" - 생성되는 윈도의 타이틀 이름
  • WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON - 스타일 옵션
  • 20, 20, 100, 25 - 좌표
  • hWnd - 생성할 위치 (상위 윈도우의 핸들)
  • hInst - 프로그램의 인스턴스 핸들

 

버튼의 스타일 옵션 

위의 생성되는 함수 코드를 보면 버튼을 생성하기 위해서 스타일 옵션이 존재하는 것을 확인할 수 있습니다. 

일단 기본적으로 버튼을 생성하면 눈에 보여야 합니다. 그리고 상위 윈도 안에서 존재하게 됩니다.

따라서 2가지의 옵션은 기본적으로 입력해야 됩니다.

  • WS_CHILD - 상위 윈도 우안에서 존재한다는 의미
  • WS_VISIBLE  - 눈에 보인다는 의미

이후 추가적으로 버튼의 종류에 대해 입력하는데 대표적인 종류는 아래와 같습니다.

  • BS_PUSHBUTTON
  • BS_DEFPUSHBUTTON
  • BS_CHECKBOX
  • BS_3 STATE
  • BS_RADIOBUTTON

정확한 내용이 궁금하면 한 번씩 생성해서 실행해 보도록 합시다.

 

함수를 사용하는 위치 WM_CREATE: 

버튼을 생성하려면, 생성된 프로그램의 상위 윈도가 생성된 후 버튼이 생성되는 것이 일반적일 것입니다.

따라서 윈도가 생성됐다는 메시지를 받은 후 처리를 해주는 것이 적합합니다. 

Windows에서 WM_CREATE 메세지 이후에 처리를 해주어야 합니다.

 

전체 소스코드 및 결과


#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);
    case WM_LBUTTONDOWN:
        hdc = GetDC(hWnd); //DC을얻는 방법 1

        ReleaseDC(hWnd, hdc);
    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_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

자 이제 버튼이 생성되는 것 까지 확인했습니다. 

 

하지만 아직 아무 기능을 하고 있지는 않습니다.  이제 다음 포스트를 통해서 버튼에 기능을 부여하고 사용해보도록 합시다.

 

 

728x90
반응형

Commnet

G91개발일지

Gon91(지구일)

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

TODAY :

YESTER DAY :

TOTAL :