버튼 생성하기
드래그 - 앤 드롭 기능으로 버튼을 끌어와서 폼에 넣는다.
버튼 id는 중복이 불가하며 대문자로만 작성할 수 있다.
(파이큐티의 객체명과 비슷한 듯)
캡션은 버튼에 작성되는 부분을 수정할 수 있다.
BTN_TEST 라고 작성한 후 엔터를 치니
그에 맞게 버튼이 수정됨을 확인할 수 있다.
버튼 이벤트 생성하기
버튼에 클릭 이벤트를 설정하는 방법은 두 가지가 있다.
1. 버튼을 더블클릭해서 바로 더블클릭했을 때 코드로 이동한다.
2. 버튼을 우클릭 - [이벤트 처리 추가] 클릭 - 해당하는 설정값을 클릭한다.
이벤트처리기에서는 어떤 클래스에서 동작할 것인지,
버튼에 대한 이벤트 발생 유형은 어떻게 할 것인지(클릭, 더블클릭, 버튼에 FOCUS,,,)를 설정할 수 있다.
클릭을 의미하는 [BN_CLICKED] 를 클릭하고 [확인]을 클릭한다.
메세지 유형을 누르면 함수 이름이 자동으로 생성된다.
이동한 부분. 이 C++ 파일은 우측의 솔루션 파일에서 어디에 위치해 있는지 확인할 수 있다.
현재 MFCstartDig.cpp(다이얼로그 파일)에 존재함을 확인할 수 있다.
위의 OnBnClickedTest함수 내에 버튼을 더블클릭했을 때 의 이벤트 코드를 작성한다.
void CMFCstartDlg::OnBnClickedTest()
{
AfxMessageBox(_T("hello Window")); // 메세지박스 알림창을 추가한다.
}
파일을 실행시킨 후 버튼을 클릭하면 설정한 메세지박스가 띄워지는 것을 볼 수 있다.
글자 입력창(Edit Control) 생성하기
파이큐티의 라인에딧 혹은 텍스트 에딧과 같이 글자를 입력할 수 있는 도구이다.
왼쪽에 있는 라인컨트롤을 다이얼로그로 끌어오면 자동으로 생성된다. 버튼처럼 늘려서 크기를 조절할 수 있다.
크기 조절하기
상단에 있는 버튼들로 객체들을 정렬할 수 있는데, 만약 에딧창을 버튼과 동일한 크기로 만들고 싶다면,
[에딧 컨트롤] 클릭→ [Ctrl] 누른 상태에서 [버튼 클릭] → 우측 상단의 [같은 크기로] 를 클릭하면
라인 에딧 컨트롤과 버튼이 동일한 크기로 변환 것을 확인할 수 있다.
편집기 도구들
왼쪽정렬 | |
오른쪽 정렬 | |
위/아래 정렬 | |
세로/가로 맞춤 | |
같은 너비로 조정 | |
같은 높이로 조정 | |
같은 크기로 조정 | |
눈금선 설정/해제 |
에딧 컨트롤 속성창 수정하기
[숫자] 항목을 [True]로 설정하면 에딧 컨트롤에 숫자만 입력할 수 있도록 제한된다.
문자를 입력하면 이렇게 숫자만 나오게 제한된다.
에딧 컨트롤에 변수 추가하기
에딧 컨트롤 - 우클릭 - [변수 추가]
범주
- 컨트롤(control) : 다양한 것들을 하기 위해 필요한 것들
- 값(value) : 값만 사용한다.
변수 이름, 범주, 변수 형식을 지정하고 마침을 누르면
솔루션 파일에 변수가 선언된 모습을 확인할 수 있다. 여기서 사용된 m_nNum의 설명은 아래와 같다.
- m_ : 클래스의 멤버 변수(member variable)임을 나타낸다. C++ 같은 언어에서 객체 지향 프로그래밍을 할 때, 클래스 내의 멤버 변수를 나타낼 때 많이 사용하는 접두어이다.
- n : int 타입의 변수임을 나타낸다.
헝가리안 표기법이란?
헝가리안 표기법(Hungarian notation)은 프로그래밍에서 변수나 함수의 이름을 지을 때 그 타입이나 용도를 알 수 있게 하는 명명 규칙이다. 이 방법은 1980년대에 Microsoft의 프로그래머였던 Charles Simonyi가 소개했으며, 그가 헝가리에서 왔기 때문에 이런 이름이 붙었다.
헝가리안 표기법에는 크게 두 가지 형태가 있다:
1. 시스템 헝가리안 표기법(System Hungarian Notation):
변수의 데이터 타입을 나타내는 접두어를 사용한다. 예를 들어:
- int 타입: nCount
- char 타입: cLetter
- float 타입: fValue
- string 타입: szName
2. 애플리케이션 헝가리안 표기법(Apps Hungarian Notation):
변수의 용도나 의미를 나타내는 접두어를 사용한다. 예를 들어:
- 비밀번호: pwstrUserPassword
- 사용자 이름: ustrUsername
헝가리안 표기법은 코드를 읽는 사람에게 변수나 함수의 의미나 타입에 대한 추가적인 정보를 제공하여 코드의 가독성을 높여 줄 수 있다.
변수 위치 찾기
변수를 클릭하고 (커서가 올려져 있는 상태로) Ctrl + Shift + F 를 클릭하면 [찾기 및 바꾸기] 창이 보여진다.
[모두 찾기] 버튼을 누르면 해당 솔루션에 그 변수가 있는 위치를 보여준다.
해당 변수가 하이라이트 된 열을 클릭하면 그 위치로 이동한다.
m_nNum(0)은 기본값으로 0을 상정한다는 뜻이다.
실행하면 에딧 컨트롤 창에 0이 표시된 모습을 확인할 수 있다.
이렇게 0이 기본값으로 나온다.
만약 이 값을 100으로 바꾸면
100이 기본값으로 나온다.
라인에딧과 버튼 이벤트 연결하기
버튼을 누르면 100이 85로 변경되게 코드를 짜 보자.
void CMFCstartDlg::OnBnClickedTest()
{
int nTest = 85;
m_nNum = nTest;
UpdateData(false);
}
버튼을 클릭하면 100이 85로 변한다.
UpdateData(True) 와 UpdateData(False)
- UpdateData(True): 대화 상자의 컨트롤에서 클래스의 멤버 변수로 데이터를 전송. 예를 들어, 텍스트 박스에 사용자가 입력한 값을 가져와 클래스의 멤버 변수에 저장하려면 이 방식을 사용
- UpdateData(False): 클래스의 멤버 변수에서 대화 상자의 컨트롤로 데이터를 전송, 예를 들어, 어떤 값을 멤버 변수에 프로그래밍 방식으로 설정하고 해당 값을 대화 상자의 텍스트 박스에 표시하려면 이 방식을 사용
단순히 말하면, true는 UI로부터 데이터를 가져와 클래스 변수에 저장하고, false는 클래스 변수의 데이터를 UI로 전송하는 것
void CMFCstartDlg::OnBnClickedTest()
{
UpdateData(TRUE);
int nSum = 0;
for (int i = 0; i < m_nNum; i++) {
nSum += i;
}
m_nNum = nSum;
UpdateData(false);
}
MFC 콘솔창 출력, 디버깅
디버깅을 위해 헤더에
#pragma comment(linker, "/entry:WinMainCRTStartup /subsystem:console")
을 추가해 주고
#include <iostream>
void CMFCstartDlg::OnBnClickedTest()
{
UpdateData(TRUE);
int nSum = 0;
for (int i = 0; i < m_nNum; i++) {
std::cout << i << std::endl;
nSum += i;
}
m_nNum = nSum;
UpdateData(false);
}
이렇게 코드를 수정했다.
디버깅을 할 때 과정을 출력할 수 있다.
using namespace std; 를 추가하여 간단하게 std::를 생략하고 작성할 수 있다.
자세한 내용은 블로그에 따로 정리했다.
https://giveme-happyending.tistory.com/211
#include <iostream>
using namespace std;
void CMFCstartDlg::OnBnClickedTest()
{
UpdateData(TRUE);
int nSum = 0;
for (int i = 0; i < m_nNum; i++) {
cout << i << endl;
nSum += i;
}
m_nNum = nSum;
UpdateData(false);
}
간단한 계산식 만들기
static text 추가하여 계산식을 만들어 보자.
스태틱 텍스트는 왼쪽에 존재한다. Qt의 라벨과 비슷하다.
텍스트의 ID를 변경해 준다.
변수는 최소화, 함수는 최대화 하는것이 좋다.
버튼을 클릭했을 때 결과 text값이 변하게 하기 위해서
SetDlgItemText을 사용한다.
매개 변수 nID의 아이디를 가진 컨트롤에 lpszString의 문자열을 입력해주는 함수이다.
void SetDlgItemText(int nID, LPCTSTR lpszString);
버튼 클릭했을 때 타는 함수 밑에
SetDlgItemText(IDC_STATIC_RESULT, _T("결과"));
이렇게 작성해주고 실행 시켰을 때 버튼을 누르면 문자 '결과'가 들어간다.
버튼을 누르기 전에 나오게 하고 싶다면 init 밑에 선언해 준다.
// TODO: 여기에 추가 초기화 작업을 추가합니다. 라는 주석이 달린 곳 밑에 작성해 준다.
그럼 버튼을 누르지 않아도 결과 라는값이 IDC_STATIC_RESULT 텍스트에딧에 값이 넣어진다.
계산기 만들기
기존 UI 를 삭제하고 프로젝트에 버튼들과 라인텍스를 추가하여 계산기를 만들었다.
제작한 UI
전체 코드
MFCstartDIG.cpp
// MFCstartDlg.cpp: 구현 파일
//
// 헤더(파일 선언)
#include "pch.h"
#include "framework.h"
#include "MFCstart.h"
#include "MFCstartDlg.h"
#include "afxdialogex.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#pragma comment(linker, "/entry:WinMainCRTStartup /subsystem:console")
#endif
// 열거형 자료형을 사용해서 사용자가 어떤 연산자 버튼을 눌렀는지 구분하기
enum FourOP {
PLUS = 1001,
MINUS,
MULTIPLY,
DIVIDE,
NONE
};
CString m_strDisplay; // 화면에 표시될 문자열
int m_nSecondOperand; // 두 번째 입력한 피 연산자
// 응용 프로그램 정보에 사용되는 CAboutDlg 대화 상자입니다.
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();
// 대화 상자 데이터입니다.
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_ABOUTBOX };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 지원입니다.
// 구현입니다.
protected:
DECLARE_MESSAGE_MAP()
public:
};
CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
// CMFCstartDlg 대화 상자
// CMFstartDIg에 있는 부분을 상속받아 -> CMFstartDIg를 생성한다.(상속 개념)
CMFCstartDlg::CMFCstartDlg(CWnd* pParent /*=nullptr*/) // CWnd 의 Parent(부모)는 Null 값이다.
: CDialogEx(IDD_MFCSTART_DIALOG, pParent)
, m_EditDisplay(_T(""))
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CMFCstartDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT5, m_strDisplay); // IDC_EDIT5는 표시용 Edit Control의 ID입니다.
}
// 실행되는 이벤트들 모음
BEGIN_MESSAGE_MAP(CMFCstartDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON_1, &CMFCstartDlg::OnBnClickedButton1)
ON_BN_CLICKED(IDC_BUTTON_2, &CMFCstartDlg::OnBnClickedButton2)
ON_BN_CLICKED(IDC_BUTTON_3, &CMFCstartDlg::OnBnClickedButton3)
ON_BN_CLICKED(IDC_BUTTON_4, &CMFCstartDlg::OnBnClickedButton4)
ON_BN_CLICKED(IDC_BUTTON_5, &CMFCstartDlg::OnBnClickedButton5)
ON_BN_CLICKED(IDC_BUTTON_6, &CMFCstartDlg::OnBnClickedButton6)
ON_BN_CLICKED(IDC_BUTTON_7, &CMFCstartDlg::OnBnClickedButton7)
ON_BN_CLICKED(IDC_BUTTON_8, &CMFCstartDlg::OnBnClickedButton8)
ON_BN_CLICKED(IDC_BUTTON_9, &CMFCstartDlg::OnBnClickedButton9)
ON_BN_CLICKED(IDC_BUTTON_0, &CMFCstartDlg::OnBnClickedButton0)
ON_BN_CLICKED(IDC_BUTTON_RESULT2, &CMFCstartDlg::OnBnClickedButtonResult2)
ON_BN_CLICKED(IDC_BUTTON_ADD, &CMFCstartDlg::OnBnClickedButtonAdd)
ON_BN_CLICKED(IDC_BUTTON_MINUS, &CMFCstartDlg::OnBnClickedButtonMinus)
ON_BN_CLICKED(IDC_BUTTON_MUL, &CMFCstartDlg::OnBnClickedButtonMul)
ON_BN_CLICKED(IDC_BUTTON_DIV, &CMFCstartDlg::OnBnClickedButtonDiv)
ON_BN_CLICKED(IDC_BUTTON_RESULT, &CMFCstartDlg::OnBnClickedButtonResult)
END_MESSAGE_MAP()
// CMFCstartDlg 메시지 처리기
// CMFCstartDlg 밑에 OnInitDialog가 있다고 이해하기
// 초기화 할 때 수행되는 함수이다.
BOOL CMFCstartDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 시스템 메뉴에 "정보..." 메뉴 항목을 추가합니다.
// IDM_ABOUTBOX는 시스템 명령 범위에 있어야 합니다.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != nullptr)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 이 대화 상자의 아이콘을 설정합니다. 응용 프로그램의 주 창이 대화 상자가 아닐 경우에는
// 프레임워크가 이 작업을 자동으로 수행합니다.
SetIcon(m_hIcon, TRUE); // 큰 아이콘을 설정합니다.
SetIcon(m_hIcon, FALSE); // 작은 아이콘을 설정합니다.
// TODO: 여기에 추가 초기화 작업을 추가합니다.
m_selectedOP = NONE;
m_nFirstOperand = 0;
m_nSecondOperand = 0;
m_nResult = 0;
m_strDisplay = _T("");
UpdateData(FALSE); // 초기값 ui에 전송
return TRUE; // 포커스를 컨트롤에 설정하지 않으면 TRUE를 반환합니다.
}
void CMFCstartDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
// 대화 상자에 최소화 단추를 추가할 경우 아이콘을 그리려면
// 아래 코드가 필요합니다. 문서/뷰 모델을 사용하는 MFC 애플리케이션의 경우에는
// 프레임워크에서 이 작업을 자동으로 수행합니다.
void CMFCstartDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 그리기를 위한 디바이스 컨텍스트입니다.
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 클라이언트 사각형에서 아이콘을 가운데에 맞춥니다.
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 아이콘을 그립니다.
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
// 사용자가 최소화된 창을 끄는 동안에 커서가 표시되도록 시스템에서
// 이 함수를 호출합니다.
HCURSOR CMFCstartDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
#include <iostream>
using namespace std;
void CMFCstartDlg::OnBnClickedTest()
{
UpdateData(TRUE);
UpdateData(false);
}
void CMFCstartDlg::OnBnClickedButton1()
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
UpdateData(TRUE);
m_strDisplay = m_strDisplay + _T("1"); // "1"을 m_strDisplay에 추가합니다.
UpdateData(FALSE);
}
void CMFCstartDlg::OnBnClickedButton2()
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
UpdateData(TRUE);
m_strDisplay = m_strDisplay + _T("2");
UpdateData(FALSE);
}
void CMFCstartDlg::OnBnClickedButton3()
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
UpdateData(TRUE);
m_strDisplay = m_strDisplay + _T("3");
UpdateData(FALSE);
}
void CMFCstartDlg::OnBnClickedButton4()
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
UpdateData(TRUE);
m_strDisplay = m_strDisplay + _T("4");
UpdateData(FALSE);
}
void CMFCstartDlg::OnBnClickedButton5()
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
UpdateData(TRUE);
m_strDisplay = m_strDisplay + _T("5");
UpdateData(FALSE);
}
void CMFCstartDlg::OnBnClickedButton6()
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
UpdateData(TRUE);
m_strDisplay = m_strDisplay + _T("6");
UpdateData(FALSE);
}
void CMFCstartDlg::OnBnClickedButton7()
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
UpdateData(TRUE);
m_strDisplay = m_strDisplay + _T("7");
UpdateData(FALSE);
}
void CMFCstartDlg::OnBnClickedButton8()
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
UpdateData(TRUE);
m_strDisplay = m_strDisplay + _T("8");
UpdateData(FALSE);
}
void CMFCstartDlg::OnBnClickedButton9()
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
UpdateData(TRUE);
m_strDisplay = m_strDisplay + _T("9");
UpdateData(FALSE);
}
void CMFCstartDlg::OnBnClickedButton0()
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
UpdateData(TRUE);
m_strDisplay = m_strDisplay + _T("0");
UpdateData(FALSE);
}
void CMFCstartDlg::OnBnClickedButtonResult2()
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
m_selectedOP = NONE;
m_nFirstOperand = 0;
m_nSecondOperand = 0;
m_nResult = 0;
m_strDisplay = _T("");
UpdateData(FALSE);
}
void CMFCstartDlg::OnBnClickedButtonAdd()
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
UpdateData(TRUE);
m_nFirstOperand = _ttoi(m_strDisplay);
m_selectedOP = PLUS;
m_strDisplay = _T("");
UpdateData(FALSE);
}
void CMFCstartDlg::OnBnClickedButtonMinus()
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
UpdateData(TRUE);
m_nFirstOperand = _ttoi(m_strDisplay);
m_selectedOP = MINUS;
m_strDisplay = _T("");
UpdateData(FALSE);
}
void CMFCstartDlg::OnBnClickedButtonMul()
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
UpdateData(TRUE);
m_nFirstOperand = _ttoi(m_strDisplay);
m_selectedOP = MULTIPLY;
m_strDisplay = _T("");
UpdateData(FALSE);
}
void CMFCstartDlg::OnBnClickedButtonDiv()
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
UpdateData(TRUE);
m_nFirstOperand = _ttoi(m_strDisplay);
m_selectedOP = DIVIDE;
m_strDisplay = _T("");
UpdateData(FALSE);
}
void CMFCstartDlg::OnBnClickedButtonResult()
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
UpdateData(TRUE);
m_nSecondOperand = _ttoi(m_strDisplay);
switch (m_selectedOP) {
case PLUS:
m_nResult = m_nFirstOperand + m_nSecondOperand;
break;
case MINUS:
m_nResult = m_nFirstOperand - m_nSecondOperand;
break;
case MULTIPLY:
m_nResult = m_nFirstOperand * m_nSecondOperand;
break;
case DIVIDE:
if (m_nSecondOperand != 0)
m_nResult = m_nFirstOperand / m_nSecondOperand;
else
m_strDisplay = _T("Error"); // 0으로 나눌 때 오류 메시지 표시
break;
}
m_strDisplay.Format(_T("%d"), m_nResult);
UpdateData(FALSE);
}
MFCstartDIg.h
// MFCstartDlg.h: 헤더 파일
//
#pragma once
// CMFCstartDlg 대화 상자
class CMFCstartDlg : public CDialogEx
{
// 생성입니다.
public:
CMFCstartDlg(CWnd* pParent = nullptr); // 표준 생성자입니다.
enum FourOP m_selectedOP; // 사칙연산 선택자
CString m_strDisplay; // 화면에 표시될 문자열
int m_nFirstOperand; // 첫 번째 입력한 피 연산자
int m_nSecondOperand; // 두 번째 입력한 피 연산자
int m_nResult; // 결과값 저장
// 대화 상자 데이터입니다.
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_MFCSTART_DIALOG };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 지원입니다.
// 구현입니다.
protected:
HICON m_hIcon;
// 생성된 메시지 맵 함수
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedTest();
int m_nNum;
CString m_EditDisplay;
afx_msg void OnBnClickedButton1();
afx_msg void OnBnClickedButton2();
afx_msg void OnBnClickedButton3();
afx_msg void OnBnClickedButton4();
afx_msg void OnBnClickedButton5();
afx_msg void OnBnClickedButton6();
afx_msg void OnBnClickedButton7();
afx_msg void OnBnClickedButton8();
afx_msg void OnBnClickedButton9();
afx_msg void OnBnClickedButton0();
afx_msg void OnBnClickedButtonResult2();
afx_msg void OnBnClickedButtonAdd();
afx_msg void OnBnClickedButtonMinus();
afx_msg void OnBnClickedButtonMul();
afx_msg void OnBnClickedButtonDiv();
afx_msg void OnBnClickedButtonResult();
};
코드 설명
헤더 선언부 이후에 열거형 자료들을 사용해서 사용자가 어떤 연산자 버튼을 눌렀는지 구분하도록 한다.
// 열거형 자료형을 사용해서 사용자가 어떤 연산자 버튼을 눌렀는지 구분하기
enum FourOP {
PLUS = 1001,
MINUS,
MULTIPLY,
DIVIDE,
NONE
};
전역변수로 화면에 표시될 문자열, 두번째 입력될 피 연산자 변수를 선언한다.
CString m_strDisplay; // 화면에 표시될 문자열
int m_nSecondOperand; // 두 번째 입력한 피 연산자
CMFstartDig 대화상자 클래스 하단에 사칙연산 선택자, 문자열, 피 연산자, 두번째 피 연산자, 결과값 변수를 생성한다.
// CMFCstartDlg 대화 상자
class CMFCstartDlg : public CDialogEx
{
// 생성입니다.
public:
CMFCstartDlg(CWnd* pParent = nullptr); // 표준 생성자입니다.
enum FourOP m_selectedOP; // 사칙연산 선택자
CString m_strDisplay; // 화면에 표시될 문자열
int m_nFirstOperand; // 첫 번째 입력한 피 연산자
int m_nSecondOperand; // 두 번째 입력한 피 연산자
int m_nResult; // 결과값 저장
MFCstartDig.cpp 파일 초기화 부분에서 위에서 만든 변수드들의 초기값을 설정해 준다.
// TODO: 여기에 추가 초기화 작업을 추가합니다.
m_selectedOP = NONE;
m_nFirstOperand = 0;
m_nSecondOperand = 0;
m_nResult = 0;
m_strDisplay = _T("");
UpdateData(FALSE); // 초기값 ui에 전송
버튼1을 누르면 m_strDisplay에 값이 설정되도록 설정한다.
이 함수는 숫자 1에서 0까지 9개 모두 동일하게 만든다.
void CMFCstartDlg::OnBnClickedButton1()
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
UpdateData(TRUE);
m_strDisplay = m_strDisplay + _T("1"); // "1"을 m_strDisplay에 추가합니다.
UpdateData(FALSE);
}
CLEAR 버튼은 값을 다시 초기화 시켜주고 / 업데이트 해 준다.
void CMFCstartDlg::OnBnClickedButtonResult2()
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
m_selectedOP = NONE;
m_nFirstOperand = 0;
m_nSecondOperand = 0;
m_nResult = 0;
m_strDisplay = _T("");
UpdateData(FALSE);
}
덧셈 함수
_ttoi는 문자열을 정수로 변환해 준다.
첫번째 설정한 값을 첫번째 피연산자 변수 m_nFirstOperand에 저장하고 연산자를 m_selectedOP에 저장하고 보여지는 에딧 값을 지워준다.
그리고 UI에 이 값을 업데이트한다.
void CMFCstartDlg::OnBnClickedButtonAdd()
{
UpdateData(TRUE);
m_nFirstOperand = _ttoi(m_strDisplay);
m_selectedOP = PLUS;
m_strDisplay = _T("");
UpdateData(FALSE);
}
뺄셈, 나눗셈, 곱셈도 이와 동일하게 진행
결과값 함수
- UI의 데이터를 멤버 변수로 가져온다.
- 사용자가 입력한 두 번째 피연산자 값을 정수로 변환한다.
- 사용자가 선택한 연산자에 따라 해당 연산을 수행하고 결과를 저장한다.
- 연산 결과를 문자열 형태로 포맷팅하여 표시 준비를 한다.
- 계산된 결과를 UI에 업데이트한다.
void CMFCstartDlg::OnBnClickedButtonResult()
{
// 데이터를 UI로부터 멤버 변수로 업데이트합니다.
UpdateData(TRUE);
// m_strDisplay의 문자열 값을 정수로 변환하여 m_nSecondOperand에 저장합니다.
m_nSecondOperand = _ttoi(m_strDisplay);
// 사용자가 선택한 연산자에 따라 연산을 수행합니다.
switch (m_selectedOP) {
case PLUS:
// 더하기 연산
m_nResult = m_nFirstOperand + m_nSecondOperand;
break;
case MINUS:
// 빼기 연산
m_nResult = m_nFirstOperand - m_nSecondOperand;
break;
case MULTIPLY:
// 곱하기 연산
m_nResult = m_nFirstOperand * m_nSecondOperand;
break;
case DIVIDE:
// 나누기 연산
if (m_nSecondOperand != 0) // 분모가 0이 아닌 경우에만
m_nResult = m_nFirstOperand / m_nSecondOperand;
else
// 분모가 0인 경우 오류 메시지 설정
m_strDisplay = _T("Error");
break;
}
// 연산 결과를 m_strDisplay 문자열로 포맷팅합니다.
m_strDisplay.Format(_T("%d"), m_nResult);
// 멤버 변수의 데이터를 UI로 업데이트합니다.
UpdateData(FALSE);
}
실행 영상
참고 영상
https://youtu.be/bcNGUOveSko?list=PLlIX4lkC1JdMx-vfK8I-J3-L-GL7TbMf9
'개발공부 > C++' 카테고리의 다른 글
[C++] MFC 모달리스 다이얼로그 생성하기 (0) | 2023.09.18 |
---|---|
[C++] MFC Bitmap Image로 버튼 만들기, 클릭시 이미지 전환 (1) | 2023.09.17 |
[C++] MFC CImage 이미지 생성, 저장, 로드, 움직이는 사각형 만들기 (0) | 2023.09.17 |
[C++] MFC 콘솔창 띄우기, 특정 변수의 값 콘솔창 출력 (0) | 2023.09.16 |
[C++] MFC 개발환경 설정하기 (0) | 2023.09.15 |