소연의_개발일지
article thumbnail

 

버튼 생성하기

 

드래그 - 앤 드롭 기능으로 버튼을 끌어와서 폼에 넣는다. 

 

버튼 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

 

[C++] MFC 콘솔창 띄우기, 특정 변수의 값 콘솔창 출력

콘솔창 띄우기 디버그 헤더 파일에 #pragma comment(linker, "/entry:WinMainCRTStartup /subsystem:console") 을 작성해 주면 된다. 이렇게 작성해 주자 #ifdef _DEBUG #define new DEBUG_NEW #pragma comment(linker, "/entry:WinMainCRTStar

giveme-happyending.tistory.com

#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 

 

profile

소연의_개발일지

@ssoyxon

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!