WINAPI - 체크 박스
내장형 하드웨어/WINAPI / 2011. 9. 20. 15:23
- 체크 박스의 종류
→ 체크 박스는 참, 거짓의 진위적인 선택을 입력받을 때 주로 사용.
→ 여러가지 선택 사항들을 입력받거나 보여주는 체크박스들이 있는데 각각의 기능을 사용하고 싶으면 해당 체크 박스를 클릭하여 체크 표시가 나타나도록 하면 된다.
→ 체크 박스도 푸쉬 버튼과 마찬가지로 차일드 윈도우이며 체크 마크를 표시하는 조그만 사각형과 체크 박스의 의미를 설명하는 짧은 문자열로 되어 있다.
→ 체크 박스를 만드는 방법은 푸쉬 버튼을 만드는 방법과 동일하며 클래스 이름도 푸쉬 버튼과 같은 "button"을 사용하되 스타일에 BS_PUSHBUTTON 대신 체크 박스 스타일을 지정한다는 것만 다르다.
→ 스타일에 따라 4가지 종류의 체크 박스가 있는데
→ 두가지 상태를 가지는 체크 박스(BS_CHECKBOX)와 세가지 상태를 가지는 체크 박스(BS_3STATE)를 가진다.
→ 두가지 상태를 가지는 체크 박스는 선택/비선택 둘 중 하나의 상태를 가지지만 세 가지 상태를 가지는 체크 박스는 선택/비선택 외에도 Grayed라는 제 3의 상태를 가진다. Grayed는 알 수 없음, 결정할 수 없음의 뜻을 가진다.
→ 동작 방법에 따라 자동체크 박스와 수동 체크 박스로 나누어 지는데 수동 체크 박스는 선택/비선택 상태를 부모 윈도우가 직접 바꾸어야 하며 자동 체크 박스는 스스로 상태를 바꾼다.
→ 체크 박스의 경우는 별도의 코드를 작성하지 않아도 되지만 수동 체크 박스의 경우는 체크 박스의 통지 코드가 전달될 대 체크 박스의 상태와 프로그램의 여러가지 상태를 보고 직접 토글시켜야 한다.
→ 체크 박스의 상태가 변경될 때마다 어떤 처리를 해야 하고 체크 조건이 복잡한 경우라면 수동 체크 박스를 사용하고 필요할 때 상태를 조사하기만 할 경우 자동 체크 박스를 사용한다.
- 예제
→ 체크박스를 사용하는 간단한 예제. 화면에 사각형을 하나 그리되 체크 박스의 상태에 따라 타원으로도 그릴 수 있도록 한다.
→ 또한 자동 체크 박스의 사용예를 보이기 위해 자동 체크 박스가 선택되어 있을 경우 프로그램 종료 전에 메시지 박스를 출력해 보이도록 한다.
→ WimMain의 윈도우 클래스 등록문을 WndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1); 로 바꾸어 주어 배경 브러시를 버튼 색상으로 지정했다.
→ COLOR_BTNFACE는 버튼 표면의 색상을 의미하는데 말 그대로 버튼을 그릴 때 시스템이 사용하는 색이다. 즉, 윈도우의 배경 브러시를 커늩롤의 색상과 일치 시켰다.
→ 4가지 종류의 체크 박스를 모두 만들어 보기 위해 c1~c4까지 네 개의 윈도우 핸들 변수를 선언했다. WM_CREATE에서 체크 박스의 스타일을 변경해 가며 4개의 체크 박스를 생성했으며 각 체크 박스의 ID는 0~3까지 주었다.
→ WM_PAINT에서는 bEllipse 변수값에 따라 타원 또는 사각형을 그린다.
→ 실행 결과
→ 첫 번째 체크 박스(ID 0번)의 선택 상태에 따라 사각형이 그려지기도 하고 타원형이 그려지기도 한다. 체크 박스가 눌러지는 즉시 이 체크 박스는 부모 윈도우로 BN_CLICKED 통지 메시지를 보낸다.
→ 부모 윈도우는 0번 컨트롤인 Draw Ellipse 체크 박스가 눌러질 때마다 체크 박스의 상태를 조사해서 체크 상태를 토글하고 bEllipse 변수의 값도 같이 토글시킨다. 그리고 화면을 다시 그림으로써 변경된 도형을 화면으로 출력하였다.
- 컨트롤의 메시지
→ 컨트롤은 자신에게 어떤 변화가 있을 때마다 부모 윈도우로 메시지를 보내며 이 메시지를 통지 메시지라고 부른다.
→ 예로 체크 박스의 경우 사용자가 마우스로 클릭할 때마다 부모 윈도우로 BN_CLICKED 메시지를 보낸다.
→ 컨트롤이 부모 윈도우로 보내는 통지 메시지와는 달리 부모 윈도우가 체크 박스의 현재 상태를 알아보거나 할 때도 차일드 윈도우로 메시지를 보낸다.
→ 통지 메시지는 차일드가 부모로 보내는 보고 메시지이고 그냥 메시지는 부모가 차일드에게 어떤 지시를 내리기 위해 보내는 명령
→ BM_GETCHECK에 의해 리턴되는 값, 또는 BM_SETCHECK에 의해 설정되는 체크 박스의 상태는 다음 세 가지가 있다.
→ 체크 박스는 참, 거짓의 진위적인 선택을 입력받을 때 주로 사용.
→ 여러가지 선택 사항들을 입력받거나 보여주는 체크박스들이 있는데 각각의 기능을 사용하고 싶으면 해당 체크 박스를 클릭하여 체크 표시가 나타나도록 하면 된다.
→ 체크 박스도 푸쉬 버튼과 마찬가지로 차일드 윈도우이며 체크 마크를 표시하는 조그만 사각형과 체크 박스의 의미를 설명하는 짧은 문자열로 되어 있다.
→ 체크 박스를 만드는 방법은 푸쉬 버튼을 만드는 방법과 동일하며 클래스 이름도 푸쉬 버튼과 같은 "button"을 사용하되 스타일에 BS_PUSHBUTTON 대신 체크 박스 스타일을 지정한다는 것만 다르다.
→ 스타일에 따라 4가지 종류의 체크 박스가 있는데
→ 두가지 상태를 가지는 체크 박스(BS_CHECKBOX)와 세가지 상태를 가지는 체크 박스(BS_3STATE)를 가진다.
→ 두가지 상태를 가지는 체크 박스는 선택/비선택 둘 중 하나의 상태를 가지지만 세 가지 상태를 가지는 체크 박스는 선택/비선택 외에도 Grayed라는 제 3의 상태를 가진다. Grayed는 알 수 없음, 결정할 수 없음의 뜻을 가진다.
→ 동작 방법에 따라 자동체크 박스와 수동 체크 박스로 나누어 지는데 수동 체크 박스는 선택/비선택 상태를 부모 윈도우가 직접 바꾸어야 하며 자동 체크 박스는 스스로 상태를 바꾼다.
→ 체크 박스의 경우는 별도의 코드를 작성하지 않아도 되지만 수동 체크 박스의 경우는 체크 박스의 통지 코드가 전달될 대 체크 박스의 상태와 프로그램의 여러가지 상태를 보고 직접 토글시켜야 한다.
→ 체크 박스의 상태가 변경될 때마다 어떤 처리를 해야 하고 체크 조건이 복잡한 경우라면 수동 체크 박스를 사용하고 필요할 때 상태를 조사하기만 할 경우 자동 체크 박스를 사용한다.
- 예제
→ 체크박스를 사용하는 간단한 예제. 화면에 사각형을 하나 그리되 체크 박스의 상태에 따라 타원으로도 그릴 수 있도록 한다.
→ 또한 자동 체크 박스의 사용예를 보이기 위해 자동 체크 박스가 선택되어 있을 경우 프로그램 종료 전에 메시지 박스를 출력해 보이도록 한다.
#include "MsgProc.h"
static HWND c1, c2, c3, c4;
static BOOL bEllipse = FALSE;
LRESULT OnCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
// 수동 체크 박스, 컨트롤 ID 0, 윈도우 핸들 c1
c1 = CreateWindow(TEXT("button"), TEXT("Draw Ellipse?"), WS_CHILD|WS_VISIBLE|
BS_CHECKBOX, 20, 20 , 160, 25, hWnd, (HMENU)0, g_hInst, NULL);
// 자동 체크 박스, 컨트롤 ID 1, 윈도우 핸들 c1
c2 = CreateWindow(TEXT("button"), TEXT("Good bye Message?"), WS_CHILD|WS_VISIBLE|
BS_AUTOCHECKBOX , 20, 50, 160, 25, hWnd, (HMENU)1, g_hInst, NULL);
// 3STATE, 컨트롤 ID 2, 윈도우 핸들 c3
c3 = CreateWindow(TEXT("button"), TEXT("3State"), WS_CHILD|WS_VISIBLE|
BS_3STATE, 20, 80, 160, 25, hWnd, (HMENU)2, g_hInst, NULL);
// 자동 3STATE, 컨트롤 ID 3, 윈도우 핸들 c4
c4 = CreateWindow(TEXT("button"), TEXT("Auto 3State"), WS_CHILD|WS_VISIBLE|
BS_AUTO3STATE, 20, 110, 160, 25, hWnd, (HMENU)3, g_hInst, NULL); return 0;
}
LRESULT OnCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
switch(LOWORD(wParam))
{
case 0:
if(SendMessage(c1, BM_GETCHECK, 0, 0) == BST_UNCHECKED)
{
SendMessage(c1, BM_SETCHECK, BST_CHECKED, 0);
bEllipse = TRUE;
}
else
{
SendMessage(c1, BM_SETCHECK, BST_UNCHECKED, 0);
bEllipse = FALSE;
}
InvalidateRect(hWnd, NULL, TRUE);
break;
case 2:
if(SendMessage(c3, BM_GETCHECK, 0, 0) == BST_UNCHECKED)
SendMessage(c3, BM_SETCHECK, BST_CHECKED, 0);
else if(SendMessage(c3, BM_GETCHECK, 0, 0) == BST_INDETERMINATE)
SendMessage(c3, BM_SETCHECK, BST_UNCHECKED, 0);
else
SendMessage(c3, BM_SETCHECK, BST_INDETERMINATE, 0);
}
return 0;
}
LRESULT OnLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
return 0;
}
LRESULT OnPaint(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
hdc = BeginPaint(hWnd, &ps);
if(bEllipse == TRUE)
{
Ellipse(hdc, 200, 100, 400, 200);
}
else
{
Rectangle(hdc, 200, 100, 400, 200);
}
EndPaint(hWnd, &ps);
return 0;
}
LRESULT OnDestroy(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
if(SendMessage(c2, BM_GETCHECK, 0, 0) == BST_CHECKED)
{
MessageBox(hWnd, TEXT("Good Bye"), TEXT("Check"), MB_OK);
}
PostQuitMessage(0);
return 0;
}
static HWND c1, c2, c3, c4;
static BOOL bEllipse = FALSE;
LRESULT OnCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
// 수동 체크 박스, 컨트롤 ID 0, 윈도우 핸들 c1
c1 = CreateWindow(TEXT("button"), TEXT("Draw Ellipse?"), WS_CHILD|WS_VISIBLE|
BS_CHECKBOX, 20, 20 , 160, 25, hWnd, (HMENU)0, g_hInst, NULL);
// 자동 체크 박스, 컨트롤 ID 1, 윈도우 핸들 c1
c2 = CreateWindow(TEXT("button"), TEXT("Good bye Message?"), WS_CHILD|WS_VISIBLE|
BS_AUTOCHECKBOX , 20, 50, 160, 25, hWnd, (HMENU)1, g_hInst, NULL);
// 3STATE, 컨트롤 ID 2, 윈도우 핸들 c3
c3 = CreateWindow(TEXT("button"), TEXT("3State"), WS_CHILD|WS_VISIBLE|
BS_3STATE, 20, 80, 160, 25, hWnd, (HMENU)2, g_hInst, NULL);
// 자동 3STATE, 컨트롤 ID 3, 윈도우 핸들 c4
c4 = CreateWindow(TEXT("button"), TEXT("Auto 3State"), WS_CHILD|WS_VISIBLE|
BS_AUTO3STATE, 20, 110, 160, 25, hWnd, (HMENU)3, g_hInst, NULL); return 0;
}
LRESULT OnCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
switch(LOWORD(wParam))
{
case 0:
if(SendMessage(c1, BM_GETCHECK, 0, 0) == BST_UNCHECKED)
{
SendMessage(c1, BM_SETCHECK, BST_CHECKED, 0);
bEllipse = TRUE;
}
else
{
SendMessage(c1, BM_SETCHECK, BST_UNCHECKED, 0);
bEllipse = FALSE;
}
InvalidateRect(hWnd, NULL, TRUE);
break;
case 2:
if(SendMessage(c3, BM_GETCHECK, 0, 0) == BST_UNCHECKED)
SendMessage(c3, BM_SETCHECK, BST_CHECKED, 0);
else if(SendMessage(c3, BM_GETCHECK, 0, 0) == BST_INDETERMINATE)
SendMessage(c3, BM_SETCHECK, BST_UNCHECKED, 0);
else
SendMessage(c3, BM_SETCHECK, BST_INDETERMINATE, 0);
}
return 0;
}
LRESULT OnLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
return 0;
}
LRESULT OnPaint(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
hdc = BeginPaint(hWnd, &ps);
if(bEllipse == TRUE)
{
Ellipse(hdc, 200, 100, 400, 200);
}
else
{
Rectangle(hdc, 200, 100, 400, 200);
}
EndPaint(hWnd, &ps);
return 0;
}
LRESULT OnDestroy(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
if(SendMessage(c2, BM_GETCHECK, 0, 0) == BST_CHECKED)
{
MessageBox(hWnd, TEXT("Good Bye"), TEXT("Check"), MB_OK);
}
PostQuitMessage(0);
return 0;
}
→ WimMain의 윈도우 클래스 등록문을 WndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1); 로 바꾸어 주어 배경 브러시를 버튼 색상으로 지정했다.
→ COLOR_BTNFACE는 버튼 표면의 색상을 의미하는데 말 그대로 버튼을 그릴 때 시스템이 사용하는 색이다. 즉, 윈도우의 배경 브러시를 커늩롤의 색상과 일치 시켰다.
→ 4가지 종류의 체크 박스를 모두 만들어 보기 위해 c1~c4까지 네 개의 윈도우 핸들 변수를 선언했다. WM_CREATE에서 체크 박스의 스타일을 변경해 가며 4개의 체크 박스를 생성했으며 각 체크 박스의 ID는 0~3까지 주었다.
→ WM_PAINT에서는 bEllipse 변수값에 따라 타원 또는 사각형을 그린다.
→ 실행 결과
→ 첫 번째 체크 박스(ID 0번)의 선택 상태에 따라 사각형이 그려지기도 하고 타원형이 그려지기도 한다. 체크 박스가 눌러지는 즉시 이 체크 박스는 부모 윈도우로 BN_CLICKED 통지 메시지를 보낸다.
→ 부모 윈도우는 0번 컨트롤인 Draw Ellipse 체크 박스가 눌러질 때마다 체크 박스의 상태를 조사해서 체크 상태를 토글하고 bEllipse 변수의 값도 같이 토글시킨다. 그리고 화면을 다시 그림으로써 변경된 도형을 화면으로 출력하였다.
- 컨트롤의 메시지
→ 컨트롤은 자신에게 어떤 변화가 있을 때마다 부모 윈도우로 메시지를 보내며 이 메시지를 통지 메시지라고 부른다.
→ 예로 체크 박스의 경우 사용자가 마우스로 클릭할 때마다 부모 윈도우로 BN_CLICKED 메시지를 보낸다.
→ 컨트롤이 부모 윈도우로 보내는 통지 메시지와는 달리 부모 윈도우가 체크 박스의 현재 상태를 알아보거나 할 때도 차일드 윈도우로 메시지를 보낸다.
→ 통지 메시지는 차일드가 부모로 보내는 보고 메시지이고 그냥 메시지는 부모가 차일드에게 어떤 지시를 내리기 위해 보내는 명령
BM_GETCHECK
- 체크 박스가 현재 체크 되어 있는 상태인지를 조사. wParam, lParam은 사용하지 않는다. 체크 상태는 리턴값으로 돌려진다.
- 체크 박스가 현재 체크 되어 있는 상태인지를 조사. wParam, lParam은 사용하지 않는다. 체크 상태는 리턴값으로 돌려진다.
BM_SETCHECK
- 체크 박스의 체크 상태를 변경하며 wParam에 변경할 체크 상태를 지정한다.
- 체크 박스의 체크 상태를 변경하며 wParam에 변경할 체크 상태를 지정한다.
상수 | 값 | 의미 |
BST_UNCHECKED | 0 | 현재 체크되어 있지 않다. |
BST_CHECKED | 1 | 현재 체크되어 있다. |
BST_INDETERMINATE | 2 | Grayed 상태(알수없다, 결정할 수 없다.) |
→ BM_GETCHECK에 의해 리턴되는 값, 또는 BM_SETCHECK에 의해 설정되는 체크 박스의 상태는 다음 세 가지가 있다.
'내장형 하드웨어 > WINAPI' 카테고리의 다른 글
WINAPI - Static (1) | 2011.09.22 |
---|---|
WINAPI - 라디오 버튼 (0) | 2011.09.21 |
WINAPI - 컨트롤(버튼) (0) | 2011.09.19 |
WINAPI - Font (0) | 2011.09.16 |
WINAPI - 비트맵 출력, 메모리 DC (0) | 2011.09.15 |