WINAPI - DlgCheck
내장형 하드웨어/WINAPI / 2011. 9. 29. 14:56
- 대화상자를 통해 입력 받는 값이 BOOL 형과 열거인 예제
→ BOOL 형은 체크 박스로 표시하고 열거형은 라디오 박스로 표시하는데 값을 보여주고 다시 읽는 방법이 정수나 문자열과 다를 뿐 전체적인 논리는 비슷하다.
→ 출력 결과
→ 편집된 값을 다시 읽어올 때는 IsDlgButtonChecked 함수로 각 버튼의 체크 상태를 조사한다. 라디오 버튼 중 체크된 버튼을 구할 때는 모든 라디오 버튼에게 일일이 질문을 해서 체크된 버튼을 찾는 방법밖에 없다.
→ 이럴 때는 어떤 그룹에서 어떤 버튼이 선택되어 있는지 조사하는 다음과 같은 함수를 만들어 쓸 수도 있을 것이다.
→ 이 함수의 예에서 볼수 있듯이 려러개의 컨트롤에 대해 루프를 돌리기 위해 핸들 외에도 사용자가 값을 통제할 수 있는 ID가 필요하다.
→ 단, 이런식의 루프를 돌리려면 라디오 버튼들이 반드시 연속적인 ID를 가지고 있어야 한다.
→ BOOL 형은 체크 박스로 표시하고 열거형은 라디오 박스로 표시하는데 값을 보여주고 다시 읽는 방법이 정수나 문자열과 다를 뿐 전체적인 논리는 비슷하다.
//main.cpp
#include<windows.h>
#include "MsgProc.h" // add
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE g_hInst;
LPCTSTR lpszClass = TEXT("First");
// add
typedef struct MESSAGEMAP
{
UINT iMessage;
LRESULT (*lpfnMsgProc)(HWND, WPARAM, LPARAM);
}MESSAGEMAP;
//CALLBACKAboutDlgProc
typedef struct DLGMESSAGEMAP
{
UINT iMessage;
BOOL (*lpfnMsgProc)(HWND, WPARAM, LPARAM);
}DLGMESSAGEMAP;
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
{
HWND hWnd;
MSG Message;
WNDCLASS WndClass;
g_hInst = hInstance;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClass.hInstance = hInstance;
WndClass.lpfnWndProc = WndProc;
WndClass.lpszClassName = lpszClass;
WndClass.lpszMenuName = NULL;
WndClass.style = CS_HREDRAW | CS_VREDRAW;
RegisterClass(&WndClass);
hWnd = CreateWindow(lpszClass, lpszClass, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, (HMENU)NULL, hInstance, NULL);;
ShowWindow(hWnd, nCmdShow);
while(GetMessage(&Message, NULL, 0, 0))
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
return (int)Message.wParam;
}
BOOL CALLBACK MajorDlgProc(HWND hDlg,UINT iMessage, WPARAM wParam, LPARAM lParam)
{
int i;
static DLGMESSAGEMAP DlgMessageMaps[] = {
{WM_INITDIALOG, OnInitDialog},
{WM_COMMAND, OnDlgCommand}
};
for(i=0; i<sizeof(DlgMessageMaps)/sizeof(DlgMessageMaps[0]); ++i)
{
if(DlgMessageMaps[i].iMessage == iMessage)
return (*DlgMessageMaps[i].lpfnMsgProc)(hDlg, wParam, lParam);
}
return FALSE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
//add
int i;
static MESSAGEMAP MessageMaps[] = {
{WM_CREATE, OnCreate},
{WM_COMMAND, OnCommand},
{WM_LBUTTONDOWN, OnLButtonDown},
{WM_PAINT, OnPaint},
{WM_DESTROY, OnDestroy}
};
for(i=0; i<sizeof(MessageMaps)/sizeof(MessageMaps[0]);++i)
{
if(MessageMaps[i].iMessage == iMessage)
{
return (*MessageMaps[i].lpfnMsgProc)(hWnd, wParam, lParam);
}
}
///////////////////////////
return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}
#include<windows.h>
#include "MsgProc.h" // add
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE g_hInst;
LPCTSTR lpszClass = TEXT("First");
// add
typedef struct MESSAGEMAP
{
UINT iMessage;
LRESULT (*lpfnMsgProc)(HWND, WPARAM, LPARAM);
}MESSAGEMAP;
//CALLBACKAboutDlgProc
typedef struct DLGMESSAGEMAP
{
UINT iMessage;
BOOL (*lpfnMsgProc)(HWND, WPARAM, LPARAM);
}DLGMESSAGEMAP;
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
{
HWND hWnd;
MSG Message;
WNDCLASS WndClass;
g_hInst = hInstance;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClass.hInstance = hInstance;
WndClass.lpfnWndProc = WndProc;
WndClass.lpszClassName = lpszClass;
WndClass.lpszMenuName = NULL;
WndClass.style = CS_HREDRAW | CS_VREDRAW;
RegisterClass(&WndClass);
hWnd = CreateWindow(lpszClass, lpszClass, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, (HMENU)NULL, hInstance, NULL);;
ShowWindow(hWnd, nCmdShow);
while(GetMessage(&Message, NULL, 0, 0))
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
return (int)Message.wParam;
}
BOOL CALLBACK MajorDlgProc(HWND hDlg,UINT iMessage, WPARAM wParam, LPARAM lParam)
{
int i;
static DLGMESSAGEMAP DlgMessageMaps[] = {
{WM_INITDIALOG, OnInitDialog},
{WM_COMMAND, OnDlgCommand}
};
for(i=0; i<sizeof(DlgMessageMaps)/sizeof(DlgMessageMaps[0]); ++i)
{
if(DlgMessageMaps[i].iMessage == iMessage)
return (*DlgMessageMaps[i].lpfnMsgProc)(hDlg, wParam, lParam);
}
return FALSE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
//add
int i;
static MESSAGEMAP MessageMaps[] = {
{WM_CREATE, OnCreate},
{WM_COMMAND, OnCommand},
{WM_LBUTTONDOWN, OnLButtonDown},
{WM_PAINT, OnPaint},
{WM_DESTROY, OnDestroy}
};
for(i=0; i<sizeof(MessageMaps)/sizeof(MessageMaps[0]);++i)
{
if(MessageMaps[i].iMessage == iMessage)
{
return (*MessageMaps[i].lpfnMsgProc)(hWnd, wParam, lParam);
}
}
///////////////////////////
return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}
//MsgProc.cpp
#include "MsgProc.h"
BOOL bMale;
TCHAR str[128];
enum tag_Major{MANAGE, KOREAN, ENGLISH, LAW}Major;
TCHAR *arMajor[] = {TEXT("경영학과"), TEXT("국문학과"), TEXT("영문학과"), TEXT("법학과")};
LRESULT OnCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
bMale = TRUE;
Major = KOREAN;
return 0;
}
LRESULT OnCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
return 0;
}
LRESULT OnLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
if(DialogBox(g_hInst, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, MajorDlgProc) == IDOK)
{
InvalidateRect(hWnd, NULL, TRUE);
}
return 0;
}
LRESULT OnPaint(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
hdc = BeginPaint(hWnd, &ps);
wsprintf(str, TEXT("성별 = %s"), bMale ? TEXT("남자"):TEXT("여자"));
TextOut(hdc, 10, 10, str, lstrlen(str));
wsprintf(str, TEXT("전공 = %s"), arMajor[Major]);
TextOut(hdc, 10, 30, str, lstrlen(str));
EndPaint(hWnd, &ps);
return 0;
}
LRESULT OnDestroy(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
PostQuitMessage(0);
return 0;
}
/////////////////////////////////////////////////////////////////////
BOOL OnInitDialog(HWND hDlg, WPARAM wParam, LPARAM lParam)
{
CheckDlgButton(hDlg, IDC_MALE, bMale ? BST_CHECKED:BST_UNCHECKED);
CheckRadioButton(hDlg, IDC_MAJOR1, IDC_MAJOR4, IDC_MAJOR1+Major);
return TRUE;
}
BOOL OnDlgCommand(HWND hDlg, WPARAM wParam, LPARAM lParam)
{
switch(LOWORD(wParam))
{
case IDOK:
bMale = (IsDlgButtonChecked(hDlg, IDC_MALE)==BST_CHECKED);
if(IsDlgButtonChecked(hDlg, IDC_MAJOR1)==BST_CHECKED)
{
Major = MANAGE;
}
if(IsDlgButtonChecked(hDlg, IDC_MAJOR2)==BST_CHECKED)
{
Major = KOREAN;
}
if(IsDlgButtonChecked(hDlg, IDC_MAJOR3)==BST_CHECKED)
{
Major = ENGLISH;
}
if(IsDlgButtonChecked(hDlg, IDC_MAJOR4)==BST_CHECKED)
{
Major = LAW;
}
EndDialog(hDlg, IDOK);
return TRUE;
case IDCANCEL:
EndDialog(hDlg, IDCANCEL);
return TRUE;
}
return FALSE;
}
#include "MsgProc.h"
BOOL bMale;
TCHAR str[128];
enum tag_Major{MANAGE, KOREAN, ENGLISH, LAW}Major;
TCHAR *arMajor[] = {TEXT("경영학과"), TEXT("국문학과"), TEXT("영문학과"), TEXT("법학과")};
LRESULT OnCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
bMale = TRUE;
Major = KOREAN;
return 0;
}
LRESULT OnCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
return 0;
}
LRESULT OnLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
if(DialogBox(g_hInst, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, MajorDlgProc) == IDOK)
{
InvalidateRect(hWnd, NULL, TRUE);
}
return 0;
}
LRESULT OnPaint(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
hdc = BeginPaint(hWnd, &ps);
wsprintf(str, TEXT("성별 = %s"), bMale ? TEXT("남자"):TEXT("여자"));
TextOut(hdc, 10, 10, str, lstrlen(str));
wsprintf(str, TEXT("전공 = %s"), arMajor[Major]);
TextOut(hdc, 10, 30, str, lstrlen(str));
EndPaint(hWnd, &ps);
return 0;
}
LRESULT OnDestroy(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
PostQuitMessage(0);
return 0;
}
/////////////////////////////////////////////////////////////////////
BOOL OnInitDialog(HWND hDlg, WPARAM wParam, LPARAM lParam)
{
CheckDlgButton(hDlg, IDC_MALE, bMale ? BST_CHECKED:BST_UNCHECKED);
CheckRadioButton(hDlg, IDC_MAJOR1, IDC_MAJOR4, IDC_MAJOR1+Major);
return TRUE;
}
BOOL OnDlgCommand(HWND hDlg, WPARAM wParam, LPARAM lParam)
{
switch(LOWORD(wParam))
{
case IDOK:
bMale = (IsDlgButtonChecked(hDlg, IDC_MALE)==BST_CHECKED);
if(IsDlgButtonChecked(hDlg, IDC_MAJOR1)==BST_CHECKED)
{
Major = MANAGE;
}
if(IsDlgButtonChecked(hDlg, IDC_MAJOR2)==BST_CHECKED)
{
Major = KOREAN;
}
if(IsDlgButtonChecked(hDlg, IDC_MAJOR3)==BST_CHECKED)
{
Major = ENGLISH;
}
if(IsDlgButtonChecked(hDlg, IDC_MAJOR4)==BST_CHECKED)
{
Major = LAW;
}
EndDialog(hDlg, IDOK);
return TRUE;
case IDCANCEL:
EndDialog(hDlg, IDCANCEL);
return TRUE;
}
return FALSE;
}
→ 출력 결과
→ 출력 결과 |
→ bMale 변수의 상태를 IDC_MALE 체크 박스에 표시하고 Major 변수의 값을 IDC_MAJOR1 ~ IDC_MAJOR4 사이의 라디오 버튼에 표시하면 될 것이다.
→ WM_INITDIALOG에서 CheckDlgButton으로 bMale 변수값에 따라 IDC_MALE 체크 박스의 상태를 체크 또는 비체크로 설정했다. → 편집된 값을 다시 읽어올 때는 IsDlgButtonChecked 함수로 각 버튼의 체크 상태를 조사한다. 라디오 버튼 중 체크된 버튼을 구할 때는 모든 라디오 버튼에게 일일이 질문을 해서 체크된 버튼을 찾는 방법밖에 없다.
→ 이럴 때는 어떤 그룹에서 어떤 버튼이 선택되어 있는지 조사하는 다음과 같은 함수를 만들어 쓸 수도 있을 것이다.
int GetCheckedRadioButton(HWND hDlg, int First, int Last)
{
int id;
for(id = First; id<=Last ; ++id)
{
if(IsDlgButtonChecked(hDlg, id)==BST_CHECKED)
{
return id;
}
}
return -1;
}
→ 인수로 전달된 First ~ Last 까지 라디오 그룹의 범위만큼 루프를 돌며 각 버튼들에게 질문하여 체크된 버튼을 만나면 그 버튼의 id를 리턴하는 것이다. 이 함수를 쓴다면 다음 한 줄로 라디오 버튼에서 사용자가 선택한 옵션을 읽을 수 있다.{
int id;
for(id = First; id<=Last ; ++id)
{
if(IsDlgButtonChecked(hDlg, id)==BST_CHECKED)
{
return id;
}
}
return -1;
}
Major = tag_Major(GetCheckedRadioButton(hDlg, IDC_MAJOR1, IDC_MAJOR4)-IDC_MAJOR1);
→ API의 래퍼 라이브러리인 MFC에는 실제로 이 함수가 존재한다. → 이 함수의 예에서 볼수 있듯이 려러개의 컨트롤에 대해 루프를 돌리기 위해 핸들 외에도 사용자가 값을 통제할 수 있는 ID가 필요하다.
→ 단, 이런식의 루프를 돌리려면 라디오 버튼들이 반드시 연속적인 ID를 가지고 있어야 한다.
'내장형 하드웨어 > WINAPI' 카테고리의 다른 글
WINAPI - sokoban (0) | 2011.10.10 |
---|---|
WINAPI - 모델리스형 대화상자 (0) | 2011.10.06 |
WINAPI - 컨트롤과의 통신 (0) | 2011.09.28 |
WINAPI - 대화상자 (0) | 2011.09.27 |
WINAPI - 스크롤 바 (0) | 2011.09.26 |