대화상자 컨트롤에 대해 알아보고, 컨트롤을 이용해 계산기 프로그램을 만들어봅시다.
대화상자에 보이는 [확인] [취소]는 버튼 컨트롤이며 CButton 클래스를 사용합니다. 컨트롤들은 전부 대응하는 MFC 클래스가 있습니다. Edit Control은 사용자로부터 문자나 숫자를 입력받는 컨트롤이며, Button Control은 행위를 결정하는 컨트롤입니다. (어떤걸 하겠다,실행 등)
도구상자에서 드래그앤 드롭이나 더블클릭으로 등록할 수 있습니다.
대화상자 테스트 키를 사용하면 컴파일하지 않고 작업한 리소스를 확인 가능합니다.
이렇게 작업한 리소스들은 resource.h에 정보가 저장됩니다. 리소스 dialog 파일과 resource.h파일을 같이 열경우 프로젝트가 손상될 수 있으므로 리소스를 수정하지 않고 내용자체만 확인하고 싶으면 .rc 파일을 메모장을 통해 열어서 확인하는 것이 좋습니다.
컨트롤의 속성창에 가면 컨트롤 ID와 Caption을 설정할 수 있습니다. 흔히 타이틀이라 알고 있는 부분이 캡션부분입니다. 만약 속성창이 안보이면 컨트롤 오른쪽클릭에 보면 속성이 있습니다.
계산기능을 만들어 보기 위해 컨트롤들을 배치해줍니다.
합산 기능 만들기 위해 합산 버튼을 더블클릭하여 함수를 생성합니다. 합산 버튼을 누를 때 동작하는 함수 입니다.
void CTestCtrlDlg::OnBnClickedSumBtn()
{
int num1 = GetDlgItemInt(IDC_EDIT1);//반환 값이 하나이므로 변수 하나로 받는다.
int num2 = GetDlgItemInt(IDC_EDIT2);//두 개의 값이 각각 들어감
SetDlgItemInt(IDC_EDIT3, num1+num2);
}
여기서 함수의 이름을 유추해볼 수 있는데, Get은 주로 얻는 것 , Dlg은 다이얼로그 대화상자, Item은 대화상자, 컨트롤 등 여러가지를 통칭하는 이름(각 기능마다 일일이 함수를 만들면 너무 많아지기 때문에)입니다.
따라서 GetDlgItemInt는 다이얼로그 아이템을 정수값으로 얻겠다는 뜻입니다. 처음 보는 클래스나 원하는 기능을 이런식으로 이름을 유추해서 찾을 줄 알아야 합니다.
각 에디트 컨트롤에 값을 받아서 합산한 값을 보여주도록 작서한 코드입니다.
정수 연산은 기본적으로 버림 연산이므로 2.3+4.5=6이 나옵니다.
대화상자에서 값을 가져오는 것은 정수형 또는 문자열 두가지 밖에 없습니다. 때문에 실수의 경우는 문자열로 가져와서 실수로 변환합니다.(wtof)
atof 함수의 경우 아스키코드를 실수로 바꿔줍니다. 현재는 유니코드 체계로 바뀌었기 때문에 쓰지 않습니다. 지금은 이 함수에서 파생되어 wtof 함수를 씁니다. MS는 _wtof함수를 쓰는데 한번 확장된 것으로, 표준을 하나 어겼다는 뜻입니다. __의 경우 거의 호환이 되지 않습니다.
예전에는 char *(1byte)를 썼고 지금은 wchar_t(2byte)형을 써서 wtof의 w는 wchar_t의 w입니다. 그렇다면 atof의 경우는 ctof여야 하지만 아스키코드를 강조하기 위해 atof라 된 것입니다.
&&참고
실수연산의 합산버튼을 설정해봅시다.
void CTestCtrlDlg::OnBnClickedSumBtn()
{
CString str;
GetDlgItemText(IDC_EDIT1, str);// edit1에 있는 숫자를 문자열로 가져온다
double num1 = _wtof(str);//atof
GetDlgItemText(IDC_EDIT2, str);
double num2 = _wtof(str);
//반환 값도 실수형을 가지지 못하기 때문에 합산 후 다시 문자열로
str.Format(L"%f", num1 + num2);//num1+num2에서 실수 합산, format이 실수를 문자열로 바꿔준다, 출력이 CString으로 가는 것
str.TrimRight(L”0”);//0이 다 사라질때까지 오른쪽 방향으로 가면서 지움
SetDlgItemText(IDC_EDIT3, str);
}
GetDlgItemText로 IDC_EDIT1,2에 있는 숫자를 문자열로 가져온 뒤 실수형으로 변환후 연산하고 다시 문자열로 내보냅니다. 여기서 format에 실수를 문자열로 바꿔줍니다. 출력이 CString으로 가는 것입니다.
%.nf와 같이 소숫점 자리수 출력을 정해주지 않으면 0이 출력되는데 지우고 싶다면 Trim(방향)함수를 사용하면 됩니다.
숫자 버튼을 눌렀을 때 숫자가 나오도록 해봅시다. 우선 숫자 버튼을 추가하고 아이디, 캡션명을 수정해줍니다.
각각 더블클릭해서 함수를 추가한 뒤 값을 얻어오도록 수정해줍니다.
void CTestCtrlDlg::OnBnClickednum1()
{
SetDlgItemText(IDC_EDIT1, L"1");
}
void CTestCtrlDlg::OnBnClickedNum2()
{
SetDlgItemText(IDC_EDIT1, L"2");
}
void CTestCtrlDlg::OnBnClickedNum3()
{
SetDlgItemText(IDC_EDIT1, L"3");
}
이렇게 할 경우 버튼 1,2,3을 누르면 값이 덮어집니다. 나열되기 위해서는 현재 Edit에 있는 값들을 가져온 후 그 뒤에 붙여야 합니다.
CString 클래스는 +가 연산자 오버로딩이 되어있습니다. CString 클래스의 멤버 함수(+)는 자신이 가진 스트링에 문자열을 추가하겠다는 뜻입니다. 따라서
void CTestCtrlDlg::OnBnClickednum1()
{
CString str;
SetDlgItemText(IDC_EDIT1, str + L"1");
}
이런식으로 수정해줍니다.
계산기를 만들기 위해서는 많은 버튼 컨트롤을 추가해야하는데, 같은 컨트롤을 많이 만들면 코드 중복이 일어나기 쉽습니다. 그때 OnCommand 함수를 이용합니다. [클래스마법사]->[가상함수]->OnCommand
BOOL CTestCtrlDlg::OnCommand(WPARAM wParam, LPARAM lParam)
{
if (wParam >= IDC_NUM1 && wParam <= IDC_NUM5){
CString str, num_str;
GetDlgItemText(IDC_EDIT1, str);
num_str.Format(L"%d", wParam - IDC_num1 + 1);
//어떤 컨트롤 군이 군집된 범위내에 순차적으로 존재할 때 초기값을 빼주면 0부터 절대인덱스값이 나옴. 1부터 시작하므로 +1을 해준다
SetDlgItemText(IDC_EDIT1, str + num_str);
}
return CDialogEx::OnCommand(wParam, lParam);
}
버튼 한 두개는 더블클릭해서 정의하면 되지만 버튼이 많아지면 이렇게 처리하는게 좋습니다.
위에서 숫자 버튼 1~5의 ID를 IDC_NUM1~5로 설정하였습니다. 버튼이 눌러졌을 때 WM_COMMAND가 발생하고 해당 메세지의 wParam에 버튼의 아이디가 들어갑니다.
&&WindowProc VS OnCommand
WindowProc는 윈도우에게 메세지가 발생했을 때 이 함수에서 동작합니다. api의 WindowProc의 인자중에 윈도우 핸들값이 빠진 것과 같습니다. Button을 클릭하면 wm_command 메세지가 발생하는데 이 메세지를 처리하는데 WindowProc로 처리할 수도 있지만 이 함수는 모든 메세지를 대상으로 하는 것이기 때문에 다른 함수를 써주는 것이 좋습니다.
OnCommand는 메시지만 따로 처리해주는 함수 입니다. wm_command가 발생했을 때만 호출됩니다.
WindowProc로 코드를 짤 경우 //모든 메세지가 전부 걸려서 좋지 않다
LRESULT CTestCtrlDlg::WindowProc(UNIT message, WPARAM wParam, LPARAM LParam)
{
if(message == WM_COMMAND){//조건을 또 걸어줘야함!
if(wParam >= IDC_NUM1 && wParam <= IDC_NUM5){
CString str, num_str;
GetDlgItemText(IDC_EDIT1, str);
num_str.Format(L”%d”,wParam - IDC_NUM1+1);
SetDlgItemText(IDC_EDIT1, num_str);
}
}
}
'Programming > Win32 API & MFC' 카테고리의 다른 글
MFC 09 : 계산기 만들기 2 (1) | 2015.08.16 |
---|---|
MFC 08 : 계산기 만들기 1 (0) | 2015.08.15 |
MFC 06 : 짝맞추기 게임 2 (2) | 2015.08.13 |
MFC 05 : 짝맞추기 게임 1 (1) | 2015.08.12 |
MFC 04 : 간단한 오목 프로그램 만들기 (2) | 2015.08.09 |