WindowsAPI - 실습 - 그림판 구현하기 3 ( UI부분 구현 )

컴퓨터/Win32-API

728x90
반응형

서론

본문에서는 지난 포스트에서 작성한 구조에 컨트롤 버튼 등을 만드는 UI작업을 진행해 보도록 하겠습니다.

2개의 토글 버튼과 색상을 제어할수 있는 색상판을 만들어 보도록 합시다.

이전 글

 

 

WindowsAPI - 실습 - 그림판 구현하기 2 ( 프로젝트 구조 설계 및 시작)

서론 지난 포스트에 이어서 그림판 구현하기 본격적인 소스코드 구현을 시작해 보도록 합시다. 기본적으로 소스코드를 구현할 틀을 만들어 보도록 합시다. 지난 글 WindowsAPI - 실습 - 그림판 구현

blog-of-gon.tistory.com

버튼 만들기

2개의 버튼을 만들도록 하겠습니다. 그리기 기능과 지우기 기능이 있는 2가지의 버튼을 만들기 위해 

하나의 함수를 만들었습니다.

//버튼생성하기 
void CreateButton(const WCHAR* name,LONG x,LONG y,LONG width ,LONG height, HMENU id, HWND hWnd, HINSTANCE hInst)
{
    CreateWindowW(L"button", name, WS_CHILD | WS_VISIBLE | BS_CHECKBOX, x,y,width,height, hWnd, id, hInst,NULL);
}

BS_CHECKBOX 스타일로 체크박스 스타일로 변경을 했습니다. 

추구에 기능을 추가한다면 그룹, 또는 라디오의 형태로 제어하는 것이 효율적일 것 같지만, 아직 해당 기능들을 포스트 하지 않은 관계로 위처럼 버튼을 생성하도록 합시다.

 

이후 WM_CREATE에 해당 함수를 호출하여 버튼을 생성하도록 합시다.

    case WM_CREATE:
    {
        //버튼 생성
        CreateButton(L"Pen",20,20,50,50,(HMENU)1, hWnd, hInst); 
        CreateButton(L"Erase", 20, 75, 50, 50, (HMENU)2, hWnd, hInst);
        //버튼 생성 및 이미지 씌우기
        break;
    }

 

색상 테이블 만들기

색상 테이블은 크게 2가지의 목적을 달성해야 됩니다.

  • RGB 값을 통해 색상을 선택할 수 있어야 한다.
  • 계속해서 사용자에게 현 색상을 표현해주어야 한다.

RGB 값을 통해 색상을 선택할 수 있어야 하기 때문에 3개의 스크롤 바를 생성해주도록 합시다.

//색상 선택 도구 만들기
void CreateRGBTable(const WCHAR* name, LONG left, LONG top, LONG right, LONG bottom, HMENU id, HWND hWnd, HINSTANCE hInst)
{
    
    //RGB의 스크롤 바 생성 및 범위 설정
    CreateWindowW(L"scrollbar", L"R", WS_CHILD | WS_VISIBLE | SBS_HORZ, right+20, top+15, right + 30, 15, hWnd, id, hInst, NULL);
    SetScrollRange(FindWindowW(L"scrollbar", L"R"), SB_CTL, 0, 255, TRUE);
    CreateWindowW(L"scrollbar", L"G", WS_CHILD | WS_VISIBLE | SBS_HORZ, right+20, top+40, right + 30, 15, hWnd, id+1, hInst, NULL);
    SetScrollRange(FindWindowW(L"scrollbar", L"G"), SB_CTL, 0, 255, TRUE);
    CreateWindowW(L"scrollbar", L"B", WS_CHILD | WS_VISIBLE | SBS_HORZ, right+20, top+65, right + 30, 15, hWnd, id+2, hInst, NULL);
    SetScrollRange(FindWindowW(L"scrollbar", L"B"), SB_CTL, 0, 255, TRUE);
    //SetColor(hWnd);
}

 

이후 현 사용자에게 계속해서 어떤 색상이 선택되었는지 표현을 해주어야 합니다.

따라서 하나의 함수를 더 만들어서 계속 색상의 값을 찾고 표시하도록 하겠습니다.

//색상 선택
void SetColor(HWND hWnd)
{
    HDC hdc = GetDC(hWnd);

    //스크롤 Bar의 값 받아오기
    int R = GetScrollPos(FindWindowW(L"scrollbar", L"R"),SB_HORZ);
    int G = GetScrollPos(FindWindowW(L"scrollbar", L"G"), SB_HORZ);
    int B = GetScrollPos(FindWindowW(L"scrollbar", L"B"), SB_HORZ);

    HBRUSH newBrush = CreateSolidBrush(RGB(R, G, B));
    HBRUSH OldBrush = (HBRUSH)SelectObject(hdc, newBrush);
    //선택된 색상 보여주기
    Rectangle(hdc, 80, 30, 150, 120);

    //스크롤 Bar의 값 표시해주기
    WCHAR text[10];
    wsprintf(text, L"R : %d", R, SB_HORZ);
    TextOutW(hdc, 360, 40, text, lstrlenW(text));
    wsprintf(text, L"G : %d", G, SB_HORZ);
    TextOutW(hdc, 360, 70, text, lstrlenW(text));
    wsprintf(text, L"B : %d", B, SB_HORZ);
    TextOutW(hdc, 360, 100, text, lstrlenW(text));
    SelectObject(hdc, OldBrush);
    DeleteObject(newBrush);
    ReleaseDC(hWnd, hdc);
}

 

이후 WM_PAINT에서 해당 함수를 호출해 주도록 합시다.

    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hWnd, &ps);
        SetColor(hWnd);
        EndPaint(hWnd, &ps);
        break;
    }

 

결과 및 소스코드 

이제 아직 기능은 들어가 있지 않지만 간단하게 외형을 만들었습니다. 

다음 포스트에서는 기능들을 부여해보도록 하겠습니다.

 

  • Paint.cpp
더보기
// Paint.cpp : Defines the entry point for the application.
//

#include "framework.h"
#include "Paint.h"

//함수 원형 선언 부분
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

// 전역변수
HINSTANCE hInst;                               

// WinMain함수 부분
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    hInst = hInstance; // 인스턴스 핸들을 전역 변수에 저장합니다.

    /*윈도우 설정 및 메인 윈도우를 생성합니다.*/
    HWND hWnd = InitMainWindowSet(hInstance, &WndProc, L"Paint");
    //정상적으로 생성되었다면 윈도우를 갱신합니다.
    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;
}

// WndProc 함수부분
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    //윈도우 생성 메세지
    case WM_CREATE:
    {
        //버튼 생성
        CreateButton(L"Pen",20,20,50,50,(HMENU)1, hWnd, hInst); 
        CreateButton(L"Erase", 20, 75, 50, 50, (HMENU)2, hWnd, hInst);
        //버튼 생성 및 이미지 씌우기

        //색상 테이블 생성
        CreateRGBTable(L"RGBtable", 80, 30, 150, 120, (HMENU)10, hWnd, hInst);
        break;
    }
    case WM_COMMAND:
    {
        //각종 버튼에 따른 동작 
        break;
    }
        /*각종 마우스 동작에 따른 컨트롤*/
    case WM_MOUSEMOVE:
    {
        break;
    }
    case WM_LBUTTONDOWN:
    {

        break;
    }
    case WM_LBUTTONUP:
    {
        break;
    }
    case WM_RBUTTONDOWN:
    {
        break;
    }
    case WM_RBUTTONUP:
    {
        break;
    }
    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hWnd, &ps);
        SetColor(hWnd);
        EndPaint(hWnd, &ps);
        break;
    }
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}
  • MySource.h
더보기
#pragma once

#include "framework.h"
#include "Paint.h"

//초기 구조 적용 함수
HWND InitMainWindowSet(HINSTANCE hInstance, WNDPROC WndProc,const WCHAR* name);

//버튼 생성 함수
void CreateButton(const WCHAR* name, LONG x, LONG y, LONG width, LONG height, HMENU id, HWND hWnd, HINSTANCE hInst);

void CreateRGBTable(const WCHAR* name, LONG left, LONG top, LONG right, LONG bottom, HMENU id, HWND hWnd, HINSTANCE hInst);
void SetColor(HWND hWnd);
  • MySource.cpp
더보기
#include "MySource.h"

//윈도우 창 설정
HWND InitMainWindowSet(HINSTANCE hInstance, WNDPROC WndProc,const WCHAR* name)
{
    //윈도우 창 구조체 설정 및 적용하기
    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 = name;
    wcex.hIconSm = NULL;
    RegisterClassExW(&wcex);

    //해당 윈도우 창을 가지고와서 윈도우 창 생성하기
    return CreateWindowW(name, name, WS_MAXIMIZE| WS_SYSMENU,
        100, 100, 750, 750, nullptr, nullptr, hInstance, nullptr);
}

//버튼생성하기 
void CreateButton(const WCHAR* name,LONG x,LONG y,LONG width ,LONG height, HMENU id, HWND hWnd, HINSTANCE hInst)
{
    CreateWindowW(L"button", name, WS_CHILD | WS_VISIBLE | BS_CHECKBOX, x,y,width,height, hWnd, id, hInst,NULL);
}
//색상 선택 도구 만들기
void CreateRGBTable(const WCHAR* name, LONG left, LONG top, LONG right, LONG bottom, HMENU id, HWND hWnd, HINSTANCE hInst)
{
    
    //RGB의 스크롤 바 생성 및 범위 설정
    CreateWindowW(L"scrollbar", L"R", WS_CHILD | WS_VISIBLE | SBS_HORZ, right+20, top+15, right + 30, 15, hWnd, id, hInst, NULL);
    SetScrollRange(FindWindowW(L"scrollbar", L"R"), SB_CTL, 0, 255, TRUE);
    CreateWindowW(L"scrollbar", L"G", WS_CHILD | WS_VISIBLE | SBS_HORZ, right+20, top+40, right + 30, 15, hWnd, id+1, hInst, NULL);
    SetScrollRange(FindWindowW(L"scrollbar", L"G"), SB_CTL, 0, 255, TRUE);
    CreateWindowW(L"scrollbar", L"B", WS_CHILD | WS_VISIBLE | SBS_HORZ, right+20, top+65, right + 30, 15, hWnd, id+2, hInst, NULL);
    SetScrollRange(FindWindowW(L"scrollbar", L"B"), SB_CTL, 0, 255, TRUE);
    //SetColor(hWnd);
}
//색상 선택
void SetColor(HWND hWnd)
{
    HDC hdc = GetDC(hWnd);

    //스크롤 Bar의 값 받아오기
    int R = GetScrollPos(FindWindowW(L"scrollbar", L"R"),SB_HORZ);
    int G = GetScrollPos(FindWindowW(L"scrollbar", L"G"), SB_HORZ);
    int B = GetScrollPos(FindWindowW(L"scrollbar", L"B"), SB_HORZ);

    HBRUSH newBrush = CreateSolidBrush(RGB(R, G, B));
    HBRUSH OldBrush = (HBRUSH)SelectObject(hdc, newBrush);
    //선택된 색상 보여주기
    Rectangle(hdc, 80, 30, 150, 120);

    //스크롤 Bar의 값 표시해주기
    WCHAR text[10];
    wsprintf(text, L"R : %d", R, SB_HORZ);
    TextOutW(hdc, 360, 40, text, lstrlenW(text));
    wsprintf(text, L"G : %d", G, SB_HORZ);
    TextOutW(hdc, 360, 70, text, lstrlenW(text));
    wsprintf(text, L"B : %d", B, SB_HORZ);
    TextOutW(hdc, 360, 100, text, lstrlenW(text));
    SelectObject(hdc, OldBrush);
    DeleteObject(newBrush);
    ReleaseDC(hWnd, hdc);
}


//이미지 씌우기
//더블버퍼링
//색상선택
//버튼 제어
//등등 기능을 쪼개서 하나씩 추가할 예정
 

WindowsAPI - 실습 - 그림판 구현하기 4 (버튼 제어 추가 & 오류 수정)

서론 팬과 지우기 버튼에 토글 기능을 구현하고, 색상판에 스크롤바를 제어할 수 있는 기능을 추가하도록 하겠습니다. 그리고 몇가지 오류 수정을 하도록 합시다. WindowsAPI - 실습 - 그림판 구현

blog-of-gon.tistory.com

 

728x90
반응형

Commnet

G91개발일지

Gon91(지구일)

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

TODAY :

YESTER DAY :

TOTAL :