[MFC] 메시지 처리 - Timer(타이머) 만들기
Visual Studio 2019(C++.NET MFC 142)에서 Timer(타이머)를 작성해보도록 하겠다.
실시간 타이머는 말 그대로 일정+시간을 의미하는 타이머이다.
일상생활에서 컴퓨터의 "날짜 및 시간"을 보면 확인할 수 있다.
아래의 그림은 정적인 Timer이다.
이번 예제는 동적인 실시간 타이머를 구현하도록 하겠다.
[작성 환경]
Microsoft Visual Studio 2019
Microsoft Windows 10
1. 프로젝트 생성하기
프로젝트 생성하는 방법은 이전 예제에서도 다루고 있지만, SDI, MDI 등이 있을 수 있어서 표기하고 있다.
그림 1) 프로젝트 생성하기
그림 2) 프로젝트 생성하기
그림 3) 프로젝트 생성하기
그림 4) 프로젝트 생성하기
그림 5) 프로젝트 생성하기
그림 6) 프로젝트 생성하기
2. 변수 만들기, 클래스 마법사, 코드 입력하기
코드 작성 전략을 소개하면 크게, "변수 만들기"->"클래스 마법사"->"코드 입력하기" 순서로 진행해볼 수 있겠다.
그림 7) 프로젝트 생성 후 첫 화면
그림 8) 클래스 뷰에서 "CTimerDigitalView" 오른쪽 버튼 후 추가에서 변수 추가(B)... 클릭하기
그림 8처럼 따라서 진행하도록 한다.
그림 9) 변수 추가의 예(m_bTimerRun)
그림 9의 변수는 타이머의 실행 유무를 bool(부울)로 체크하는 함수이다.
그림 10) 코드 완성의 예
정상적으로 변수가 생성되었음을 알 수 있다. 그림 8처럼 그림 11을 다시 따라하도록 한다.
그림 11) 변수 추가의 예
그림 12) m_bTimerType 변수 추가 모습
그림 12는 m_bTimerType이라는 변수를 추가하고 있는 모습이다. m_bTimerType의 목표는 타이머 출력의 형식을 어떻게 할지 추후에 구현할 때 사용하게 될 것이다. 이 예제에서는 추후 고려에 대해서만 담고 있다.
그림 13) Timer_DigitalView.cpp 더블 클릭
그림 13은 CTimerDigitalView::CTimerDigitalView를 변형한 모습을 담고 있다.
// CTimerDigitalView 생성/소멸
CTimerDigitalView::CTimerDigitalView() noexcept
:m_bTimerRun(false)
, m_bTimerType(true)
{
// TODO: 여기에 생성 코드를 추가합니다.
}
코드를 입력한다.
3. 생성자 만들기
Ctrl+Shift+X 단축키를 클릭해서 클래스 마법사를 실행한다.
메시지 탭을 클릭 후, "WM_Create"라고 입력한다.
그리고 "처리기 추가(A)"를 클릭한다.
OnCreate를 선택한 후, "코드 편집(E)"를 클릭한다.
그림 14) 클래스 마법사 실행하기
그림 15처럼 코드를 입력한다.
그림 15) OnCreate에 코드 작성하기
// CTimerDigitalView 메시지 처리기
int CTimerDigitalView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: 여기에 특수화된 작성 코드를 추가합니다.
SetTimer(0, 1000, NULL); // 타이머 설정
m_bTimerRun = TRUE; // 타이머 동작
return 0;
}
4. 메시지 출력을 담을 변수 추가하기
다음은 메시지 출력을 담을 변수를 추가할 것이다.
CString 자료형으로 메시지 출력을 담을 것이다.
CTimerDigitalView를 오른쪽 버튼한 후, "추가", "변수 추가(B)..."를 클릭한다.
그림 16) 변수 추가의 모습
그림 17) m_strTimer 변수 추가 모습
변수를 추가한 후, 확인을 누른다.
Ctrl+Shift+X키를 눌러서 클래스 마법사를 호출한다.
그림 18) 클래스 마법사 호출한 모습
메시지 탭에서 "WM_TIMER"를 검색한다.
"처리기 추가"를 누른다.
"OnTimer"를 클릭 후 "코드 편집(E)"를 클릭한다.
그림 19) OnTimer()에 소스코드를 입력한 모습의 예(1)
그림 20) OnTimer()에 소스코드를 입력한 모습의 예(1)
void CTimerDigitalView::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
int hour;
CString str;
CTime timer;
timer = CTime::GetTickCount(); // Visual Studio 2017부터 GetCurrentTime() 삭제
if (m_bTimerType) {
m_strTimer.Format(_T("현재는 %d년 %d월 %d일 %d시 %d분 %d초"),
timer.GetYear(), timer.GetMonth(), timer.GetDay(),
timer.GetHour(), timer.GetMinute(), timer.GetSecond());
}
else {
hour = timer.GetHour();
if (hour >= 12) {
str = _T("PM");
if (hour >= 13) {
hour = hour - 12;
}
}
else {
str = _T("AM");
}
m_strTimer.Format(_T("지금은 %s %d %d %초"), str, hour,
timer.GetMinute(), timer.GetSecond());
}
Invalidate();
CView::OnTimer(nIDEvent);
}
코드 입력을 마쳤으면, OnDraw를 클릭한다. 코드를 입력해준다.
그림 21) OnDraw() 함수 원형 내에 코드 입력해주기
// CTimerDigitalView 그리기
void CTimerDigitalView::OnDraw(CDC* pDC)
{
CTimerDigitalDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: 여기에 원시 데이터에 대한 그리기 코드를 추가합니다.
CRect rect;
GetClientRect(&rect);
// 윈도우의 중앙에 타이머를 출력
pDC->DrawText(m_strTimer, rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
}
코드 입력을 마쳤다면, Ctrl+Shift+X를 누른다.
5. 소멸자 만들기
지금 작업은 실시간 타이머를 윈도우 프로그램이 종료할 때, 같이 종료될 수 있도록 지정해주는 기능을 구현하는 것이다.
메시지 탭에서 "WM_Destory"를 검색한다.
"처리기 추가(A)"를 클릭한다.
"OnDestory"를 클릭 후 "코드 편집(E)"을 클릭한다.
그림 22) 창 소멸에 관한 클래스 정의
그림 23) 코드 입력하기
6. 시연하기
시연하는 것이다.
Ctrl+F5를 눌러서 시연한다.
그림 25) 시연하기
[소스코드]
[첨부(Attachment)]
Timer_Digital.7z
7. 참고자료(Reference)
1. CTime::GetCurrentTime intellisense missing - Developer Community, Last Modified , Accessed by 2019-11-30, https://developercommunity.visualstudio.com/content/problem/100004/ctimegetcurrenttime-intellisense-missing.html
2. CTime 클래스 | Microsoft Docs, Last Modified, Accessed by 2019-11-30, https://docs.microsoft.com/ko-kr/cpp/atl-mfc-shared/reference/ctime-class?view=vs-2019#getcurrenttime