컴퓨터/Win32-API
지난번 포스트에서 간단하게 DialogBox에 대한 개념을 알아보았습니다.
크게 2가지의 종류로 구분할 수 있다고 했습니다.
본문에서는 사용자 정의 템플릿을 사용한 대화 상자를 이해하고 구현해 보도록 합시다.
개발자가 WindowsAPI에서 대화 상자의 기능을 동작시키고 이용하려면 다음과 같은 과정이 필요합니다.
위의 3가지 과정을 간단하게 정리하자면 다음과 같습니다.
이 과정들을 하나씩 구현해보도록 하겠습니다.
앞서 언급했다시피, 템플릿 즉 대화 상자를 찍어내기 위한 하나의 틀을 말합니다.
본문에서는 리소스를 이용해서 간단하게 이 템플릿을 만들어 보도록 합시다.
Visualstudio를 통해 Dialog리소스를 생성해 주도록 합시다.
Visualstudio에서 제공하는 대화 상자 편집기를 통해 다양한 형태로 템플릿을 간단하게 수정할 수 있습니다.
위처럼 편집기를 통해 리소스를 등록하면 visualstudio에서 사용하기 쉽게 항목들을 데이터화 시켜줍니다.
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++에서 생성한 포함 파일입니다.
// Mywin32.rc에서 사용되고 있습니다.
//
#define IDI_ICON1 101
#define IDI_ICON2 102
//실습을 위해 생성된 대화상자에 들어있는 리소스
#define IDD_DIALOG1 118
#define IDC_CHECK1 1001
#define IDC_CHECK2 1002
#define IDC_CHECK3 1003
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 120
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1003
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
이제 만들어진 템플릿을 이용해서 원하는 시점에 대화상자를 만들어 보도록 합시다.
우선 대화상자를 생성하기 위한 가장 기본적인 함수 DialogBox()의 선언부를 살펴보면 다음과 같습니다.
void DialogBox(
[in, optional] hInstance,
[in] lpTemplate,
[in, optional] hWndParent,
[in, optional] lpDialogFunc
);
이를 이용하여 WM_CREATE에서 대화상자를 생성해 보도록 합시다.
case WM_CREATE:
{
DialogBox(hInst,MAKEINTRESOURCE(IDD_DIALOG1), hWnd, NULL);
break;
}
WM_CREATE 메시지를 처리하는 과정에서 대화 상자가 생성되어 표시되었습니다.
하지만, 처리하는 프로시저에 대한 내용이 없기 때문에 정상적인 동작을 하지 않는 것을 확인할 수 있습니다.
이제 생성된 대화상자의 내용을 처리하는 과정을 만들어 주어야 합니다.
콜백 함수의 형태로 개발자가 직접 정의하여 처리를 할수있도록 도와줍니다.
콜백함수의 형태는 다음과 같습니다.
BOOL CALLBACK DeleteItemProc(HWND hwndDlg,
UINT message,
WPARAM wParam,
LPARAM lParam)
위의 원형을 보고 제가 사용하기 위한 함수를 소스코드에서 정의해주고 생성되는 시점에서 연동시켜 주도록 합시다.
//대화 상자용 콜백함수
BOOL CALLBACK MyDialogBox(HWND hwndDig, UINT message, WPARAM wParam, LPARAM IParam) {
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
//대화 상자 적용 및 콜백함수 연동하기
DialogBox(hInst,MAKEINTRESOURCE(IDD_DIALOG1), hWnd,(DLGPROC)MyDialogBox);
break;
}
case WM_COMMAND:
{
break;
}
case WM_PAINT:
{
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
WndProc와 비슷한 구조입니다. 즉, 대화 상자에서 발생하는 처리 또한 콜백 함수에서 메시지와 파라미터의 형태로 처리가 가능하다는 말입니다.
그럼 간단하게 동작을 제어하기 위한 몇 가지 소스코드를 작성해 보도록 합시다.
(다양한 동작이나 메시지는 MSDN에서 찾아보도록 합시다!)
//대화 상자용 콜백함수
BOOL CALLBACK MyDialogBox(HWND hwndDig, UINT message, WPARAM wParam, LPARAM IParam) {
static WCHAR word[20] = L"push button";
static int number;
switch (message)
{
case WM_INITDIALOG:
{
}
case WM_COMMAND:
{
switch (wParam)
{
case IDC_CHECK1:
number = 1;
wsprintfW(word, L"last check box : %d", number);
break;
case IDC_CHECK2:
number = 2;
wsprintfW(word, L"last check box : %d", number);
break;
case IDC_CHECK3:
number = 3;
wsprintfW(word, L"last check box : %d", number);
break;
case IDOK:
case IDCANCEL:
EndDialog(hwndDig, 0);
return TRUE;
}
InvalidateRect(hwndDig, NULL, TRUE);
UpdateWindow(hwndDig);
}
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwndDig, &ps);
TextOutW(hdc, 10, 10, word, lstrlen(word));
EndPaint(hwndDig, &ps);
}
}
return FALSE;
}
해당 코드를 실행시켜보면 생성한 대화 상자에서 체크박스의 동작에 따라 텍스트가 변경되는 것을 확인할 수 있습니다.
MSDN을 보고 다양한 방법으로 응용해 보세요.
// Windows 헤더 파일
#include <windows.h>
// C 런타임 헤더 파일입니다.
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
#include <wincodec.h>
#include "resource.h"
// 전역 변수:
HINSTANCE hInst; // 현재 인스턴스입니다.
HWND hButton;
// 이 코드 모듈에 포함된 함수의 선언을 전달합니다:
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK MyDialogBox(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;
}
//대화 상자용 콜백함수
BOOL CALLBACK MyDialogBox(HWND hwndDig, UINT message, WPARAM wParam, LPARAM IParam) {
static WCHAR word[20] = L"push button";
static int number;
switch (message)
{
case WM_INITDIALOG:
{
}
case WM_COMMAND:
{
switch (wParam)
{
case IDC_CHECK1:
number = 1;
wsprintfW(word, L"last check box : %d", number);
break;
case IDC_CHECK2:
number = 2;
wsprintfW(word, L"last check box : %d", number);
break;
case IDC_CHECK3:
number = 3;
wsprintfW(word, L"last check box : %d", number);
break;
case IDOK:
case IDCANCEL:
EndDialog(hwndDig, 0);
return TRUE;
}
InvalidateRect(hwndDig, NULL, TRUE);
UpdateWindow(hwndDig);
}
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwndDig, &ps);
TextOutW(hdc, 10, 10, word, lstrlen(word));
EndPaint(hwndDig, &ps);
}
}
return FALSE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
//대화 상자 적용 및 콜백함수 연동하기
DialogBox(hInst,MAKEINTRESOURCE(IDD_DIALOG1), hWnd,(DLGPROC)MyDialogBox);
break;
}
case WM_COMMAND:
{
break;
}
case WM_PAINT:
{
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
WindowsAPI - Dialog Boxes(대화상자) (0) | 2022.04.27 |
---|---|
WindowsAPI - 실습 그림판 구현하기 종합 (마지막 / 정리) (0) | 2022.04.23 |
WindowsAPI - 실습 - 그림판 구현 6 (버튼 이미지 삽입 / 그리기 영역 ) (0) | 2022.04.20 |
WindowsAPI - 실습 - 그림판 구현 5 (기능 구현 / 더블 버퍼링) (0) | 2022.04.19 |
WindowsAPI - 실습 - 그림판 구현하기 4 (버튼 제어 추가 & 오류 수정) (0) | 2022.04.19 |
91년생 공학엔지니어의 개발일지
TODAY :
YESTER DAY :
TOTAL :
Commnet