컴퓨터/Win32-API
Windows 응용 프로그래밍 과정에서 대표적인 컨트롤 중 하나인 버튼을 기본적인 양식대로 만들면 기능은 구현할 수 있으나 시각적으로는 부적합한 경우가 상당히 많습니다.
본문에서는 버튼 컨트롤을 마치 아이콘의 형태처럼 이미지를 씌우는 방법에 대해서 알아보고 사용해보도록 합시다.
버튼을 생성하는 과정이 이해가 안 되면 아래 글을 참조해주세요
당연히 버튼에 사용할 이미지를 준비해야 됩니다. 이미지를 준비하고 리소스 파일에 추가해주도록 합시다.
본문에서는 그냥 실습을 위해 기본 양식을 사용합니다. 응용하시려면 Import를 이용해서 추가해 주세요.
새로 생성한 리소스를 보면 다음과 같습니다.
//Resource.h
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by Mywin32.rc
//
#define IDI_ICON1 101
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 106
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
이제 본격적으로 버튼 컨트롤을 만들고 이미지를 씌우는 과정을 거치도록 하겠습니다.
우선 버튼 컨트롤을 만들어 보도록 합시다.
case WM_CREATE:
{
//버튼 생성
HWND hButton = CreateWindowW(
L"button",
L"buttion1",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_ICON, //만약 비트맵으로 한다면 BS_BITMAP
20, 20, 50, 50,
hWnd,
NULL,
hInst,
NULL);
break;
}
이때 스타일에서 BS_ICON 또는 BS_BITMAP으로 이 버튼 컨트롤은 어떤 형태로 사용할지 표시해 주어야 합니다.
이제 생성된 버튼에 이미지를 씌어주어야 합니다.
이미지를 설정하기 위해서는 BM_SETIMAGE 메세지에서 처리가 되어야 하므로 해당 메시지를 호출해 주어야 합니다.
BM_SETIMAGE 메시지를 보내려면 SendMessage 함수를 이용할 수 있습니다.
SendMessageW(hWnd,Msg,wParam,lParam)
BM_SETIMAGE의 경우도 메시지의 형태이기 때문에 wparam과 lparam값을 취할 수 있습니다.(자세히 보기)
위의 내용을 정리하면 SendMessage에는 다음과 같이 호출되어야 할 것입니다.
SendMessageW(버튼의 핸들 값 , BM_SETIMAGE, 이미지 타입 , 이미지 핸들 값);
결국 SendMessage의 호출을 하기 위한 인자를 하나 빼고 다 확인이 되었습니다.
SendMessageW(hButton, BM_SETIMAGE, IMAGE_ICON, 이미지의 핸들 값??);
이제 이미지의 핸들 값 즉 리소스로부터 이미지의 데이터를 소스코드위에 올려야 됩니다.
본문에서는 아이콘으로 처리를 했으니 아이콘을 핸들 값을 리소스로 부터 불러오도록 합시다.
//이미지 로딩
HICON hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICON1));
//HBITMAP hBitmap = LoadBitmap(hInst, MAKEINTRESOURCE(비트맵 값)); 비트맵으로 사용할 때
이때 LoadIcon 함수를 호출해서 리소스 상의 아이콘 데이터의 핸들 값을 받아옵니다.
이후 최종적으로 SendMessage를 호출해 주겠습니다.
//BM_SETIMAGE로 버튼에 이미지 씌우기
SendMessageW(hButton, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
//SendMessageW(hButton, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hBitmap);
이미지를 씌우는 과정에 대해서 부분적으로 알아야 할 내용들이 많지만 결과 소스 코드는 간략하게 확인이 가능합니다.
// Windows 헤더 파일
#include <windows.h>
// C 런타임 헤더 파일입니다.
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
#include "resource.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)
{
switch (message)
{
case WM_CREATE:
{
//버튼 생성
HWND hButton = CreateWindowW(
L"button",
L"buttion1",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_ICON, //만약 비트맵으로 한다면 BS_BITMAP
20, 20, 50, 50,
hWnd,
NULL,
hInst,
NULL);
//이미지 로딩
HICON hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICON1));
//HBITMAP hBitmap = LoadBitmap(hInst, MAKEINTRESOURCE(비트맵 값));
//BM_SETIMAGE로 버튼에 이미지 씌우기
SendMessageW(hButton, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon);
//SendMessageW(hButton, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hBitmap);
break;
}
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;
}
WindowsAPI - 실습 - 그림판 구현하기 1 (개요) (0) | 2022.04.13 |
---|---|
Win32_API - 체크버튼과 토글버튼 구현하기 (0) | 2022.04.11 |
Win32_API - GDI로 자유곡선 그리기3 (비트맵을 저장해서 쓰자) (0) | 2022.04.01 |
Win32_API_GDI로 자유곡선 그리기2(지우기/지우개 기능 추가) (0) | 2022.03.30 |
Win32_API - GDI로 자유 곡선 그리기 (마우스로 글씨 쓰기) (1) | 2022.03.28 |
91년생 공학엔지니어의 개발일지
TODAY :
YESTER DAY :
TOTAL :
Commnet