안녕하세요. MFC 카테고리의 꽃집총각입니다.

꽤나 오랜만에 글을 올리는군요 ^^;
그동안 팀 블로그에 올려 두었던 MFC의 기능 소개 글들을 한 번에 정리할 기회를 갖게 되어 예전 글들을 다시 살펴보며 정리하다가 CTaskDialog 클래스 사용법을 알아볼 수 있는 공개용 예제코드를 작성해 보았습니다. 포스팅을 할 때 사용했던 코드이기 때문에 주요코드들은 모두 블로그에 조각조각 올라와 있기는 하지만 다운받아서 직접 빌드하고 실행해보실 수 있도록 프로젝트 파일과 솔루션 파일 모두 함께 올립니다.


소스코드는 당연히 Visual Studio 2010 RC 버전에서 제작되었습니다 ^^;...
아래는 예제 코드를 켭쳐한 이미지 입니다.

프로그램을 빌드해서 실행하면 대화상자 중앙에 두 개의 버튼이 있습니다.
왼쪽 버튼을 누르면 간단한 출력 방식인 CTaskDialog::ShowDialog() 함수의 사용법을,
오른쪽 버튼을 누르면 좀 더 디테일한 방법인 CTaskDialog::DoModal() 함수의 사용법을
확인해 보실 수 있습니다.

아래 두 장의 이미지는 각각의 방법들로 띄운 예제 Task Dialog 의 모습입니다.


 CTaskDialog::ShowDialog()를 이용해 출력한 Task Dialog.


CTaskDialog::DoModal()을 이용해 출력한 Task Dialog.

학습하시는 데 도움이 되었으면 하는 마음으로 올립니다.

곧 MFC의 새롭고 재밌는 기능들을 주제로 다시 포스팅을 이어나가도록 하겠습니다.
조금만 기다려 주세요 ~

그럼 다음 포스팅에서 뵙겠습니다 ~
감사합니다 ^^*

신고
크리에이티브 커먼즈 라이선스
Creative Commons License

Intro
안녕하세요. MFC 카테고리의 꽃집총각 입니다.
우리는 지금 비주얼 스튜디오 2010에서 새롭에 추가되는 MFC 클래스인 CTaskDialog를 알아보고 있습니다.
지난 시간까지는 2회의 연재에 걸쳐서 태스크 대화상자가 무엇인지, 그리고 태스크 대화상자를 기존의 MessageBox 처럼 간단한 용도로 사용하고자 할 때엔 어떻게 해야 하는지를 함께 살펴보았습니다. 앞서 연재된 포스팅은 아래의 링크를 따라가시면 읽어보실 수 있습니다.

이번에는 태스크 대화상자의 세 번째 포스팅으로, 태스크 매니저가 제공하는 다양한 기능들을 본격적으로 활용하기 위한 방법을 알아보기로 하겠습니다.



태스크 대화상자를 띄우는 또다른 방법 - DoModal() 함수.
지난번 포스팅에서 소개했던 단순 출력 방식은 CTaskDialog::ShowDialog 함수 하나만 호출해 주면 바로 태스크 대화상자를 띄울 수 있었습니다. 8개의 인자를 통해 기본적인 기능을 어느 정도 제어할 수는 있었지만 애초부터가 심플한 사용을 위한 방법이었으므로, CTaskDialog의 여러가지 강력한 기능들을 모두 제어하기에는 무리가 있었습니다.
이번에는 CTaskDialog의 객체를 직접 생성하고, CTaskDialog의 멤버함수들을 통해 다양한 기능을 활용하는 방법을 알아보도록 하겠습니다. 이미 우리에게 익숙한 방식인 CDialog의 파생클래스를 출력하던 방식과 유사합니다. 객체를 만들어 DoModal() 함수를 호출하면 창이 뜨고, 창이 떠있는 동안 함수 내부에서 제어를 쥐고 있다가, 사용자가 창을 끄게 되면 리턴값을 내면서 함수의 호출이 종료되는 방식입니다.

// 객체 생성.
CTaskDialog dlg( L"본문", L"머릿글", L"타이틀" );

// TODO : DoModal을 호출하기 전, dlg의 멤버함수를 호출해 원하는 기능들을 설정한다.

INT_PTR iRet = dlg.DoModal();

switch( iRet )
{
case IDOK:        ... break;
case IKCANCEL:    ... break;
    ...
}

기존의 스타일을 그대로 닮아있어서 훨씬 더 친숙하게 느껴집니다 :)
다만 다른점은, DoModal을 부르기 전에 여러가지 기능을 제공하는 CTaskDialog의 멤버함수를 이용해 태스크 대화상자의 동작 및 기능을 런타임에 디자인 한다는 점입니다. 각각의 기능들은 적절한 이름의 함수로 제공되어 있으며, 매우 직관적이므로 별도의 설명 없이도 쉽게 이해하실 수 있습니다.
함수들의 레퍼런스는 아무래도 MSDN 페이지를 직접 보시는 것이 좋을 것 같습니다. ( http://msdn.microsoft.com/en-us/library/dd293651(VS.100).aspx ) 사실은 제가 한글로 설명을 덧붙인 함수 참고표를 정리해 봤는데, 굳이 부가설명이 필요 없을 뿐더러 오히려 MSDN 페이지보다 더 읽기 힘들어지기만 하네요. 대신 눈에 쏙쏙 들어오는 예제 코드를 통해 주요 함수들의 사용 방법에 대한 설명을 갈음하도록 하겠습니다.
예제는 MS VC++ MVP인 Marc Gregoire의 블로그에 공개된 예제 코드를 기반으로 하여, 주석과 인자들을 한글로 수정하고, 강의의 진행에 맞도록 일부 수정한 버전입니다. 원본 코드는 이곳 ( http://www.nuonsoft.com/blog/2009/06/10/ctaskdialog-in-mfc-in-visual-c-2010/ )에서 다운받으실 수 있습니다.

// 태스크 대화상자 객체 생성.
CTaskDialog taskDlg( L"본문", L"머릿글", L"타이틀" );

// 본문, 머릿글, 타이틀 텍스트 별도 지정
taskDlg.SetContent(_T("여기가 본문이 출력되는 위치입니다.\n")
    _T("당연히 여러 줄로 텍스트를 출력할 수 있고,")
    _T("<a href=\"http://vsts2010.net\">하이퍼 링크</a>도 설정할 수 있습니다.") );

taskDlg.SetMainInstruction(_T("여기는 머릿글을 적는 곳입니다.\n")
    _T("머릿글도 여러 줄로 적을 수 있어요."));

taskDlg.SetWindowTitle(_T("이것이 태스크 대화상자 입니다."));

// 3개의 커맨드 버튼 추가. 한 버튼은 권한 승격이 필요한 작업임을 표시.
taskDlg.AddCommandControl(1, _T("커맨드 버튼 1 "));
taskDlg.AddCommandControl(2, _T("커맨드 버튼 2 "));
taskDlg.AddCommandControl(3, _T("커맨드 버튼 3 \n")
    _T("사용자 권한 설정(UAC) 기능의 권한 승격이 필요함을 표시할 수 있습니다."), TRUE, TRUE);


// 2개의 라디오 버튼 추가.
taskDlg.AddRadioButton(4, _T("라디오 버튼 1"));
taskDlg.AddRadioButton(5, _T("라디오 버튼 2"));

// 보이기, 감추기 버튼으로 사용자가 펼치고 접을 수 있는 추가 메세지 설정.
taskDlg.SetExpansionArea(
    _T("이 메세지는 사용자가 하단의 '자세히' 버튼을 누르면 추가로 보여지는 메세지 입니다.\n")
    _T("이곳에도 하이퍼 링크가 적용됩니다. <a href=\"notepad.exe\">메모장 열기</a>."),
    _T("자세히"), _T("감추기"));

// 꼬릿말 부분 설명 & 아이콘 설정.
taskDlg.SetFooterIcon(MAKEINTRESOURCE(IDI_INFORMATION));
taskDlg.SetFooterText(_T("꼬릿말 출력 위치. \n역시 멀티라인 지원됩니다."));

// 대화상자의 메인 아이콘 설정.
taskDlg.SetMainIcon(m_hIcon);

// 태스크 대화상자의 프로그레스바 설정.
taskDlg.SetProgressBarMarquee();
taskDlg.SetProgressBarRange(0, 100);
taskDlg.SetProgressBarPosition(0);

// 대화상자 하단의 체크박스 표시 설정 및 텍스트 셋팅.
taskDlg.SetVerificationCheckboxText(_T("윈도우 시작시 자동 실행"));
taskDlg.SetVerificationCheckbox(TRUE);

// 하이퍼 링크, 타이머 옵션 추가 설정.
int options = taskDlg.GetOptions();
options |= TDF_ENABLE_HYPERLINKS;
options |= TDF_CALLBACK_TIMER;
taskDlg.SetOptions(options);


// 태스크 대화상자 출력.
INT_PTR iRes = taskDlg.DoModal();

// 사용자가 선택한 커맨드 버튼 ID와 라디오 버튼 ID 확인하기.
int iSelectedCommandControlID = taskDlg.GetSelectedCommandControlID();
int iSelectedRadioButtonID = taskDlg.GetSelectedRadioButtonID();

위의 예제 코드로 생성된 태스크 대화상자의 모습은 아래와 같습니다.

(그림 1) 예제 코드로 생성된 태스크 대화상자의 모습.


(그림 2) 예제코드로 생성한 태스크 대화상자. '자세히' 버튼을 눌러 본문이 확장된 상태.


제가 개인적으로 판단하기에는 주요함수 참고 테이블 보다는 위의 예제 코드가 훨씬 더 사용법을 익히기에 좋아 보입니다. 익스플로러 창을 두 개 띄워서 스크린샷과 소스코드를 대조해서 확인해 보세요. 어지간한 기능은 MSDN을 참고하지 않고도 바로 사용법을 이해하실 수 있을겁니다.



CTaskDialog의 프로그레스바 컨트롤.
이 부분까지 포스팅을 유심히 살펴오신 분이시라면 이상한 점을 한 가지 파악하셨을겁니다. 바로 프로그레스바 컨트롤 입니다. 지난 번 포스팅에서도, CTaskDialog::ShowDialog 함수를 이용해 프로그레스바 컨트롤을 억지로 붙여보기만 하고는 제어하는 방법을 오늘로 미루었는데, 오늘의 예제에서도 프로그레스바의 수치 등을 조절하는 함수는 있었지만 여전히 텅 빈 황량한 프로그레스바만 출력되고 있습니다.
DoModal() 함수를 호출하기 전에 SetProgressBarPosition( ... ) 함수로 프로그레스바 컨트롤의 초기값을 정해줄 수는 있지만, 태스트 대화상자가 한 번 뜨고 나면 DoModal() 함수가 제어를 쥐고 있기 때문에 컨트롤의 값을 조작하도록 손쓸 방법도 마땅치가 않습니다.

(그림 3) SetProgressBarPosition(...)으로 초기값은 정할 수 있다고 치지만, 더이상 어떻게 컨트롤 한다는 말인가?

이럴 때 CTaskDialog 클래스의 주요 기능 중의 하나인 타이머를 이용해야 합니다. 프로그레스바 컨트롤을 다루는 방법을 통해 CTaskDialog의 파생 클래스 생성 및 타이머 사용 방법을 알아보도록 하겠습니다.



CTaskDialog::OnTimer 오버로딩하기.
대화상자가 떠있는 동안은 DoModal()이 제어권을 갖고 있기 때문에, 우리가 CTaskDialog 객체의 외부에서 추가적인 조작을 가하기는 어렵습니다. 하지만 프로그레스바 컨트롤의 값을 애니메이션 하려면 대화상자가 출력되어 있는 동안에 처리가 이루어 져야 하겠지요.
이런 경우에는 CTaskDialog를 상속받는 파생 클래스를 제작하고, 가상 함수인 OnTimer를 오버로딩합니다.
OnTimer의 기본형은 다음과 같습니다.

  • virtual HRESULT OnTimer(_In_ long lTime);

예제 코드에 보면 SetOption( ... ) 함수를 이용해 기본적인 옵션에 TDF_CALLBACK_TIMER 를 추가해주어 타이머 기능을 활성화 하는 처리를 확인할 수 있습니다. 이렇게 플래그를 통해 타이머를 활성화 시켜주면 OnTimer 함수가 약 200 밀리초 (=0.2초) 주기로 호출됩니다.

int options = taskDlg.GetOptions(); options |= TDF_CALLBACK_TIMER;   // 타이머 옵션 추가 설정. taskDlg.SetOptions(options);

타이머가 필요한 대표적인 예가 바로 프로그레스바 컨트롤의 애니메이션 이겠지요. 오버로딩한 OnTimer 함수에서 간단하게 프로그레스바의 값을 진행시키는 코드를 넣어보도록 하겠습니다. 값을 조절하는 건 위에서 언급되었던 SetProgressBarPosition 함수만으로 충분합니다 :)

class CMyTaskDialog : public CTaskDialog { // ... virtual HRESULT OnTimer(_In_ long lTime); } HRESULT CMyTaskDialog::OnTimer(_In_ long lTime) { static int iProgressPos = 0; iProgressPos += 2; if (iProgressPos >= 100) iProgressPos = 0; SetProgressBarPosition(iProgressPos); return S_OK; }

위의 코드는 매번 타이머 함수가 호출될 때마다 프로그레스바 컨트롤의 값을 2씩 증가시켜주다가, 컨트롤이 만땅이 되면 꽉 차면 다시 0으로 초기화 해주고 있습니다. 0.2초에 한 번씩 호출이 되는데 2씩 채우니까... 100을 다 채우려면... 그러니까 1초에 다섯번쯤 호출 되는데... 한 번에 2씩이면 초당 10씩인가...... 뭐 아무튼 실행해보면 적당한 속도로 컨트롤이 애니메이션 되는 모습을 확인할 수 있습니다.
(웃자고 적어본 거 아시죠... 저 덧셈 잘합니다...;;)

프로그레스바 컨트롤에 대한 이야기가 나왔으니까 프로그레스바의 스타일에 대해 몇가지만 더 이야기하고 마무리 짓도록 하지요.



Marquee 타입 프로그레스바
태스크 대화상자의 프로그레스바 컨트롤은 기존의 기본적인 프로그레스바 방식보다는 Marquee 타입으로 많이 쓰일것을 예상하고 디자인된 것으로 보입니다. 프로그레스바 컨트롤을 추가하는 함수의 이름부터가 SetProgressBarMarquee(...) 이니 말입니다. 우리 예제에서는 프로그레스바의 영역을 설정하고 값을 지정해 주어 일반 프로그레스바처럼 사용하였지만, SetProgressBarRange(...) 함수와 SetProgressBarPosition(...)을 주석처리하면 프로그레스바는 기본적으로 Marquee 타입으로 설정되고, 자동으로 애니메이션 됩니다.

(그림 4) Marquee 타입 프로그레스바. 지렁이 같은게 계속 스멀스멀...

윈도우 XP의 부팅속도를 가늠하기 위한 암묵적 의사소통 수단이기도 했지요. 지렁이 몇마리...
바로 그런 식입니다. Marquee 타입 프로그레스바 컨트롤은 내부에 초록색 불빛이 좌에서 우로 이동하는 애니메이션을 반복합니다. 내부적으로 무언가 작업을 처리하고 있음을 나타내는 용도로 사용하는데 적합합니다.



CTaskDialog::SetProgressBarState(...)로 프로그레스바 상태 설정하기.
프로그레스바 관련 함수 중에 SetProgressBarState(...)가 있습니다. 이 함수를 이용해 프로그레스바의 상태를 정상 / 일시 정지 / 에러 세가지 상태 중의 하나로 설정할 수가 있습니다. 인자로 아래의 플래그를 주면 됩니다.

  • PBST_NORMAL - 정상. 디폴트값이며, 프로그레스바가 녹색으로 표시됨.
  • PBST_ERROR - 에러. 프로그레스바가 빨강으로 표시됨.
  • PBST_PAUSED - 일시 정지. 프로그레스바가 노랑으로 표시됨.

상황에 따라 적절히 사용하면 좀 더 친절한 인터페이스를 제공할 수 있겠군요. 아래는 각각의 상태에 대한 프로그레스마 컨트롤의 스크린샷 입니다. 스크린샷을 비교하는 김에 위에 붙였던 Marquee 타입의 스크린샷까지 함께 대조해 보도록 하겠습니다.

(그림 5) 위에부터 차례대로, Marquee 타입, 기본형 정상상태 / 에러상태 /일시정지 상태



Outro
이것으로 MFC 10.0의 새로운 클래스인 CTaskDialog 편을 마무리 하도록 하겠습니다. 사용법은 그렇게 어려울 것도 없는데 막상 풀어서 설명하다보니 글이 꽤나 길어졌습니다. 3차례에 걸친 강좌를 마무리하고 보니, 제가 너무 상세한 설명까지 덧붙여 괜히 글이 장황해 진 것은 아닌가 하는 걱정도 드네요. 분명 내용이 어려울 게 없는데 말입니다 ^^; 하하...
제 글이 너무 지루하거나 수준이 낮으신 분들은 매번 포스팅마다 가장 아랫부분에 따로 정리해두는 Reference 링크를 참조하시기 바랍니다. 앞으로도 강의는 가능하면 초보 개발자나 학생들도 어렵다는 느낌 없이 쉽게 접하고 내용을 익힐 수 있는 수준으로 이어나갈 예정입니다.

VisualStudio는 이미 vs2008부터 Native Programmer들을 위한 지원에 많은 노력을 들이고 있다는 점을 확인할 수 있습니다. 그런 부분을 가장 확실하게 보여주는 점이 MFC 라이브러리의 보강 입니다.
vs2010에서도 MFC는 많은 신기능들을 소개하고 있습니다. 다음 강의에도 좀 더 흥미있는 주제로 포스팅을 이어 나가도록 하겠습니다.
그럼 다음 강좌에서 또 뵙도록 하겠습니다.
감사합니다 ^^*


Reference

저작자 표시
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

Intro
안녕하세요. MFC 카테고리의 꽃집총각입니다. 이번에는 앞서 말씀 드렸던 대로, MFC 10.0에서 새로 추가되는 클래스 중에 하나인 CTaskDialog에 대해서 알아보도록 하겠습니다. 이번 포스팅에서는 CTaskDialog클래스와 이를 이용해 구현할 수 있는 기능인 태스크 대화상자(Task Dialog; 이하 한글 표기만을 사용합니다)에 대한 전반적인 개념을 정리하고, 다음시간 부터는 실제 사용방법 및 주의 사항 등을 정리해 보도록 하겠습니다.


태스크 대화상자 소개
태스크 대화상자(Task Dialog)는 윈도우 비스타 버전에서 새롭게 선보인 컨셉의 대화상자 입니다. 태스크 대화상자를 이용해 개발자들은 기존의 메세지 박스를 이용해 구현하던 기능을 보다 손쉽고 강력하게 처리할 수 있습니다. 이전부터 널리 사용되고 있는 AfxMessageBox(...)를 이용해서도 간한단 정보의 노출이나 사용자 의사선택을 처리할 수 있었지만, 추가적인 기능을 확장해 넣기에는 번거로운 점이 많았습니다. 어떻게든 예, 아니오로 대답할 수 있는 연속적인 질문을 생각해내 메세지 박스를 연거푸 출력하거나, 리소스 에디터를 열고 새로운 대화상자를 직접 만들어 주어야 했습니다. 하지만 태스크 대화상자를 이용하면 개발자가 대화상자를 커스터마이징 하기 위해 필요한 거의 대부분의 기능을 옵션으로 제공하고 있어, 손쉽고 풍부한 기능확장을 아주 심플하게 해낼 수 있습니다.

원래 길게 말해봐야 한 번 보는게 더 와닿는 법입니다. 아래의 스크린샷이 바로 태스크 대화상자의 예시 입니다.

(그림 1) Internet Explorer 8.0의 세션 복구 기능에서 등장하는 태스크 대화상자.


(그림 2) 지난번 강좌에서 설명한 리스타트 매니저에서 사용되는 태스크 대화상자.


(그림 3) 윈도우 7의 업데이트 옵션 설정할때 등장하는 태스크 대화상자.


아마도 윈도우 비스타나 윈도우 7을 사용해보신 분이라면 이곳 저곳에서 많이 보셨던 형식의 대화상자 일겁니다. 위에서 예를 든 세 가지 스크린샷도 모두 프로그래머가 별도로 만든 것이 아니라, 운영체제나 인터넷 익스플로러 등에서 쓰인 녀석들 입니다. Visual Studio 2010의 MFC기반 응용 프로그램에서는 이러한 태스크 대화상자를 몇 줄 안되는 코드만으로 쉽게 제어할 수 있는 강력한 클래스를 제공합니다. 그 클래스가 바로 CTaskDialog 입니다 :)


CTaskDialog로 할 수 있는 일들.
거의 예/아니오 내지는 확인/취소 정도의 선택밖에 제공할 수 없었던 기존의 메세지 박스와는 달리 태스크 대화상자는 아래와 같은 풍부한 커스터마이징 옵션을 제공합니다.

  • 사용자 지정 아이콘
  • 메인 헤더 텍스트 (멀티라인 지원)
  • 본문 텍스트 (당연히 멀티라인 지원)
  • 프로그레스바 컨트롤 표시 가능.
  • 라디오 버튼 표시 가능.
  • 커맨드 버튼 - 대화상자의 가장 중앙에 나타나는, 사용자의 의사 선택을 받는 버튼 - 표시 가능.
  • 추가적인 본문 텍스트를 보이거나 숨길 수 있게 해주는 확장/축소 버튼 표시 가능.
  • 체크박스 표시 가능.
  • 꼬릿말 텍스트 (멀티라인 지원)
  • 대부분의 컨트롤 및 텍스트에 하이퍼 링크 지원.
  • 타이머 기능 제공.

위처럼 다양한 옵션을 제공하기 때문에 어지간한 대화상자 UI의 구성은 번거롭게 다이얼로그 리소스에 버튼을 배열하고 CDialog 파생클래스를 만들어 일일이 코딩을 해야 하는 수고를 들이지 않아도 CTaskDialog 를 이용해 아주 심플하게 처리할 수 있게 되었습니다. 개발 편의성 뿐만 아니라 실용성 측면에서도 실제 비스타 이후 버전의 윈도우 자체에서도 널리 쓰이고 있는 것을 보면 그 실용성은 입증 되었다 볼 수 있겠네요.
각각의 기능들에 대한 자세한 사용 방법은 다음 강좌에 보다 본격적으로 다루도록 하겠습니다.



태스크 대화상자와 운영체제, API들의 관계
이번 강좌에서는 이 부분을 좀 더 일찍 정리하고 싶었습니다. 실제 기능의 사용에는 크게 상관없지만 그래도 기본 개념의 정리가 중요한 법인데, 지난 번 강좌에서는 너무 늦게 말은 한 것 같아서요. 노파심에 다시 한 번 운영체제 및 API들과 기능간의 관계를 정리해 보겠습니다.

  1. 꼭 MFC에서만 할 수 있는 건 아닙니다. MFC는 보다 편리하게 쓸 수 있도록 도와줍니다.
    태스크 대화상자는 기존의 메세지 박스보다 확장성 측면에서 훨씬 유용하게 쓰일 수 있는 새로운 컨셉의 대화상자 입니다. 이 태스크 대화상자는 윈도우 비스타에서 처음 소개되었으며, 태스크 대화상자를 제어할 수 있는 Windows API들도 함께 제공 되었습니다. MFC에서는 이러한 API들을 쉽고 편하게 사용할 수 있도록 랩핑한 클래스를 제공하는 겁니다. 그래서 굳이 MFC를 사용하지 않아도 태스트 대화상자를 이용할 수는 있지만, MFC의 CTaskDialog를 이용해 보다 편하게 작업을 할 수 있습니다.
  2. 윈도우 비스타 이전 버전에서는 사용할 수 없습니다.
    하지만 애석한 점 한가지는, 비스타 이전 버전의 윈도우에 대한 대비책은 딱히 제공되지 않는다는 점입니다. 지난번 포스팅에서 소개했었던 리스타트 매니저도 마찬가지로 비스타 이후 버전에서만 동작했었습니다. 하지만 리스타트 매니저는 응용 프로그램을 윈도우 XP에서 실행해도 기능을 하지 않을 뿐 오류를 내지는 않았지만, 태스크 대화상자를 사용하는 응용 프로그램을 윈도우 XP에서 실행한다면 태스크 대화상자 출력시점에 에러를 내게 됩니다. 화면상에 출력되어야 하는 기능이니 리스타트 매니저 처럼 오동작 없이 넘어가기가 어렵기 때문입니다.


Outro

늘 마찬가지지만 제가 설명해 드리는 MFC의 새로운 기능들은 이해하기 쉽고 빠르게 개발에 적용할 수 있는 기능들 입니다. MFC의 기본적인 방향성 자체가 보편적인 기능을 손쉽게 다룰 수 있게 제공되는 라이브러리 이기도 하고요. 그래서 초보 개발자나, 학생 분들도 어렵지 않게 내용을 따라오실 수 있다고 생각합니다. 그래도 설명 중 잘 이해가 되지 않는 부분이나 잘못된 점이 있다면 피드백을 부탁 드리겠습니다.

그럼 이번 포스팅에서는 간략하게 기능소개 정도로 글을 마치고, 다음 글에서 본격적으로 태스크 대화상자를 사용하는 방법을 다뤄 보도록 하겠습니다. 다음 글을 기다리기가 지루하신 분들은 MSDN( http://msdn.microsoft.com/en-us/library/bb760441(VS.85).aspx )이나 다음의 글( http://www.nuonsoft.com/blog/2009/06/10/ctaskdialog-in-mfc-in-visual-c-2010/ )을 참고하세요.
그럼 다음에 뵙겠습니다.
감사합니다 ^^*


Reference

저작자 표시
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

Intro
안녕하세요. MFC 카테고리의 꽃집총각 입니다.
지난번 [MFC] 리스타트 매니저(Restart Manager) - (2/3) : 사용하기 편에 이어서 오늘은 리스타트 매니저 시리즈의 마지막인 ‘활용하기’ 편입니다. 이번 시간에는 실제로 리스타트 매니저의 동작을 확인해 볼 수 있는 샘플을 만드는 과정을 정리하고, 실제 동작에 관련된 이슈들을 몇 가지 정리해 보겠습니다. 


예제 프로그램작성 – 1. MFC Application Wizard 설정 하기.

자, 우선은 VIsual Studio 2010을 열어서 Ctrl + Shift + N 을 힘차게 누질러서 새 프로젝트 생성 창을 띄우고, MFC Application을 선택해 MFC 어플리케이션 위자드(Application Wizard;응용 프로그램 마법사)를 띄웁니다.

(그림 1) MFC Application을 선택해 새 프로젝트를 생성합니다.

어플리케이션 위자드가 뜨면 왼쪽 메뉴에서 Application Type을 선택하고, 기본 비주얼 스튜디오(Visual Studio) 형식으로 되어 있는 프로젝트 스타일 항목을 오피스(Office) 형식으로 변경해 줍니다. 비주얼 스튜디오 스타일의 여러 가지 도킹 pane들은 이번 예제에는 크게 쓸모가 없으니까, 괜히 걸리적 거리기만 하거든요 ^^;


(그림 2) MFC Application Wizard > Application Type 항목 설정.

Document Template Properties 항목을 선택하고, 파일 확장자(File extension) 란에 임의의 확장자를 입력해줍니다. 파일 확장자를 명시하게 되면 별도의 코딩을 추가하지 않아도 생성된 프로젝트에 자동 생성되는 소스코드 부분에 Document의 저장/로딩 처리가 추가됩니다. 파일 확장자를 입력하면 오른쪽에 있는 필터 이름(Filter name)칸도 자동으로 채워집니다. 저는 custom-document-format의 뜻으로 cdf라고 적어봤어요.

( 그림 3) MFC Application Wizard > Document Template Properties 항목 설정.

그리고 가장 중요한 부분! Advanced Features 항목에 가서 리스타트 매니저 지원 사항들을 확인합니다. 리스타트 매니저와 관련된 세 개의 체크사항들이 기본적으로 체크되어 있기 때문에 수정을 할 필요는 없지만 그래도 올바로 체크되어 있는지 확인해야 겠지요. 


(그림 4) MFC Application Wizard > Advanced Features 항목 설정.

자, 이제 마지막으로, Generate Class 페이지로 가서 뷰 클래스의 부모 클래스를 CView –> CEditView로 변경해 줍니다. CEditView를 상속받은 클래스는 기본적으로 뷰 영역이 메모장 프로그램처럼 캐럿이 깜박이는 에디트 컨트롤 형식으로 되어있어서, 별다른 처리 없이도 문서의 저장을 확인할 수 있는 문자열 형식의 데이터를 입력할 수 있게 됩니다.


(그림 5) MFC Application Wizard > Generated Class 항목 설정.

이제 어플리케이션 마법사의 모든 설정이 끝났습니다. Finish를 눌러 프로젝트를 생성합니다.


예제 프로그램작성 – 2. 크래시 발생 버튼 추가하기.

리스타트 매니저가 올바르게 동작하는지 알아보기 위해서는 프로그램이 비정상 종료 되어야 합니다. 샘플 프로그램의 리본 UI에 간단하게 패널 하나와 버튼 하나를 추가하고, 핸들링 함수를 추가해서 아래와 같이 잘못된 포인터 연산을 하는 코드를 넣어줍니다. 어플리케이션 위자드에서 오피스 형식의 Application Type을 선택하셨다면 아마 기본적으로 리본 UI가 붙어있을겁니다. 그렇지 않다면 툴바든, 마우스 입력이든 상관 없이 아무 이벤트나 받아서 고의적으로 예외를 발생시키는 코드를 넣어주면 됩니다.

  
(그림 6) 리본에 누르면 터지는 버튼을 넣어줍니다.

 

 예제 프로그램 작성 – 3. 문서 자동 저장 간격 조절하기.
지난번에 리스타트 매니저 사용 팁을 정리하면서, 문서 데이터 자동 저장 기능의 기본 저장 간격 시간은 5분이라고 말씀 드린 적이 있습니다. 우리는 매우 바쁜 사람이니까, 이 시간을 당겨보죠. 이왕이면 프로그램을 띄우고 나서 바로 확인할 수 있도록 아주 짧게 잡아보겠습니다. 한 10초 정도면 나쁘지 않겠죠?

(그림 7) CWinApp 파생클래스의 생성자에서 m_nAutosaveInterval의 값을 10000 미리세크(=10초)로 설정해줍니다.

시간 설정에 대한 내용은 지난회 포스팅이었던 [MFC] 리스타트 매니저(Restart Manager) - (2/3) : 사용하기 편을 참고하시면 됩니다.

 

예제 프로그램 실행!
이제 빌드를 하고 프로그램을 실행시켜서 에디트 뷰에 블라블라 테스트용 잡담을 늘어놓은 후, 10초가 지나 임시 문서가 만들어졌을 만한 충분한 시간을 제공한 뒤에 ‘누르면 폭발!’ 버튼을 야심차게 눌러주면 프로그램이 크래시가 나고 리스타트 매니저가 동작하면서 프로그램을 다시 띄워 주겠지요? 하지만 실제로 실행해보시면 아마 리스타트 매니저는 커녕 그냥 프로그램만 죽어버리고, 프로그램을 닫든지 디버깅을 하든지 니 맘대로 하라는 쓸쓸한 대화상자만 출력되고 말 겁니다.


(그림 8) 크래시가 났지만, 재시작도 문서 복구도 아무 것도 일어나지 않았습니다.
우리는 대 사기극에 휘말린 걸까요?


(그림 9) ‘그래, 내컴은 닷넷 디버거가 깔려 있어서 그럴 거야! 일반 사용자들은 이렇지 않겠지!’
라는 일말의 희망도 부질없습니다. 닷넷 미설치 PC에서는 위와 같은 창이 출력됩니다.

이 시점에서 몇 가지 더 알아두어야 할 것이 있습니다. 우리의 샘플 프로그램에서 리스타트 매니저가 동작하지 않는 이유와 함께, 실제로 리스타트 매니저를 사용하려고 할 때 알아두면 좋은 몇가지 정보들을 함께 정리해 보도록 하겠습니다.

  

(중요*) 리스타트 매니저 사용시 고려사항.

  1. 우리가 살펴보고 있는 MFC 10.0의 리스타트 매니저 기능이 실은 첫 번째 포스팅에서 설명 드렸던 것처럼 윈도우 비스타 시스템에서 선보인, OS 차원에서 제공되는 기능입니다. MFC 10.0에서는 이 기능을 좀 더 쉽게 사용할 수 있게끔 추가처리를 지원하는 것입니다. 예를 들자면 win32 GDI의 DC(Device Context)와 MFC의 CDC 클래스 관계 정도가 되겠네요. MFC의 리스타트 매니저도 내부 구현으로 들어가면 비스타 이후 OS에서 지원하는 윈도우 API인 RegisterApplicationRestart, RegisterApplicationRecoveryCallback 등의 함수를 사용해 재시작 및 문서 복구 기능을 제공하고 있습니다. MFC를 사용하지 않은 일반 Win32 윈도우 프로그램이나, 콘솔 프로그램에서 까지도 재시작 및 복구 기능을 사용할 수 있습니다. 하지만 MFC를 이용하면 보다 쉽게 사용할 수 있게 되는 것이지요.
  2. 프로그램 재시작 기능의 핵심이 되는 RegisterApplicationRestart 함수는 사용시 한가지 주의해야 할 사항이 있습니다. 만약 프로그램의 초기화 코드에 오류가 있어서 인스턴스가 실행되자마자 크래시를 내는 상황인데 리스타트 매니저가 동작한다면 어떻게 될까요? 아마 프로그램은 뻗고, 실행되고, 다시 뻗고, 다시 실행되는 무한 재실행을 반복하게 될겁니다. 이런 경우를 피하기 위해서 비스타의 응용 프로그램 재시작 기능은 초기 재시작 후 60초 동안은 크래시로 인한 비정상 종료가 있었다고 해도 동작하지 않습니다. 우리가 실행시킨 샘플 프로그램은 구동한지 60초가 지나지 않았기 때문에, 재실행 기능이 실행되지 않았던 겁니다. 보다 자세한 내용은 MSDN(http://msdn.microsoft.com/en-us/library/aa373347(VS.85).aspx)에서 확인하실 수 있습니다.
  3. 자동 저장되는 문서 파일의 경로는 CDataRecoveryHandler::GetAutosavePath 함수로 알아낼 수 있습니다. 프로그램을 실행하고 해당 경로에 가보면 실제로 자동 저장되는 버전의 문서파일을 확인하실 수 있습니다. 우리의 샘플 프로그램은 10초마다 착실하게 문서를 잘 저장하고 있네요 :) 임시 파일 저장 경로의 변경은 CDataRecoveryHandler::SetAutosavePath 함수로 가능합니다.

 

 이제 예제를 통해 리스타트 매니저 동작을 직접 확인해 봅시다.
이제는 정말로 리스타트 매니저의 놀라운 동작을 우리 눈으로 직접 확인할 시간입니다. 준비는 이미 다 끝났습니다. 단지 리스타트 매니저가 실행될 수 있도록 예제 프로그램 구동 후 60초의 시간을 기다려 주기만 하면 됩니다.


(그림 10) 리스타트 매니저의 동작을 한 눈에 파악하기 위해
 모두 저장된 파일, 반만 저장된 파일, 저장 안 된 파일을 준비.

60초의 시간이 흐르는 동안 저는 위의 (그림 10)과 같이 세 개의 문서 파일을 준비했습니다. 저장한 문서창 하나, 저장한 후 추가로 내용을 추가한 문서창 하나, 그리고 저장하지 않고 내용만 적은 문서창 하나. 곧 리스타트 매니저가 이들을 각각 제대로 복구해 주는지 실제로 확인해 보겠습니다.
그리고 실제로 우리가 설정한 10초의 간격으로 문서 파일이 저장되는지 확인해 보겠습니다. 저는 윈도우 7을 사용하고 있는데, 임시 문서 기본 저장 경로가 C:\Users\(윈도우계정명)\AppData\Local 으로 잡혀있네요. 윈도우 탐색기로 해당 경로를 열어보면 실제 10초 단위로 갱신되고 있는 임시 저장 파일들이 보입니다.


(그림 11) 착실히 저장되고 있는 자동 임시 저장 파일들.

이제 미리 만들어 두었던 리본 UI의 크래시 버튼을 눌러 프로그램을 비정상 종료 시킵니다. 프로그램이 비정상 종료된 후, 자동으로 재시작 되면서 문서를 임시 저장된 버전으로 복구할 것인지를 묻는 대화상자가 출력됩니다.


(그림 12) 크래시 발생후 리스타트 매니저가 자동으로 응용 프로그램을 재시작.


(그림 13) 응용 프로그램 재시작 후, 임시 저장된 버전의 문서를 복구할 것인지 묻는 대화상자 출력

그림 13의 문서 복구 여부 확인창이 떴을 때 ‘자동 저장 문서 복구’ 항목을 선택하면, 크래시가 나기 전에 저장해 두었던 문서의 텍스트들이 그대로 모두 복구되는 것을 확인할 수 있습니다. 임시 버전으로 복구된 파일들은 파일명이 출력되는 탭 부분에 [복구됨] 이라는 표기가 붙어서 출력됩니다.


(그림 14) 리스타트 매니저의 '자동 복구 기능'으로 복구된 문서파일의 모습.

 

Outro
이번 포스팅 에서는 리스타트 매니저를 직접 동작시키고 확인해 볼 수 있는 예제 작성 방법과 몇 가지 주의 사항을 짚어 보았습니다. 첨부된 이미지들이 많아서 괜히 길어 보이긴 하지만, 어려운 내용은 없었으리라 생각합니다.
이것으로 3회에 걸친 리스타트 매니저 강좌를 마치고, 다음에는 MFC 10.0에서 새롭게 선보이는 CTaskDialog 클래스에 대한 강좌를 가지고 다시 찾아 뵐 예정입니다.
그럼 다음 강좌에서 뵙도록 할게요.
감사합니다 ^^*

 

Reference

신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Intro
안녕하세요. MFC 카테고리의 꽃집총각 입니다.
지난번 [MFC] 리스타트 매니저(Restart Manager) - (1/3) : 기능 소개 편에 이어서 이번에는 실제로 리스타트 매니저를 사용하려면 어떻게 해야 하는가를 알아보도록 하겠습니다.


리스타트 매니저 사용하기

리스타트 매니저를 새로운 응용프로그램 프로젝트에 적용하는 방법과, 기존에 작성된 응용프로그램에 적용하는 방법에는 조금 차이가 있습니다. 하나씩 나누어서 알아보죠.

1. 새로운 프로젝트에서 리스타트 매니저 사용하기 
새 프로젝트로 MFC Application을 선택하면, MFC Application Wizard로 넘어가면서 프로젝트 설정을 하게 됩니다. 이 때 AdvancedFeatures 페이지에서 Support Restart Manager (리스타트 매니저 지원) 사항을 체크하면 됩니다.

(그림 1) 응용프로그램 마법사의 리스타트 매니저 지원 항목.


(그림 1)에서 보시는 대로 체크버튼이 세 개가 있습니다. 체크버튼의 선택 사항에 따라 지원 범위를 세가지로 선택할 수 있습니다.
  1. ① - 리스타트 매니저 지원 사항만 체크하는 경우
    이 경우 응용 프로그램은 재시작 기능만을 지원하게 됩니다. 응용 프로그램은 업그레이드나 크래시 발생 후 자동으로 재시작하는 기능이 추가되지만, 문서를 자동으로 열어주거나 복구해주는 처리는 하지 않습니다.
  2. ① + ②  - '리스타트 매니저 지원' 항목과 '이전 문서 다시열기' 항목에 체크하는 경우
    재시작 기능과 함께, 이 경우는 이전에 열려있던 문서를 다시 열어주는 기능까지 제공하지만 문서의 자동저장 버전을 복구하는 처리는 하지 않습니다.
  3. ① + ② + ③ - 싸그리 다 체크하는 경우
    자동 재시작 기능, 문서 다시 열어주기 기능, 자동 저장된 버전으로 복구하는 기능까지 모두 제공합니다.

참고 사항:

  • ② 항목을 선택하기 위해서는 반드시 ① 항목을 선택해야 하며 ( case B ), ③ 항목을 선택하기 위해서는 반드시 ② 항목을 선택해야 합니다. ( case C )
  • 다이얼로그 기반의 응용 프로그램에서는 ②, ③ 항목은 자동으로 비활성화 됩니다.

2. 기존의 프로젝트에서 리스타트 매니저 사용하기
기존의 응용프로그램에 적용하기 위해서는 CWinApp 파생 클래스의 생성자에 딱 한 줄의 코드만 추가해주면 끝입니다. (아래 코드는 각각 위에서 설명한 A, B, C 기능과 동일한 기능을 제공합니다.

  1. m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART
  2. m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART_ASPECTS
  3. m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_ALL_ASPECTS

사용된 플래그 상수들은 afxwin.h 파일에 정의되어 있으며, 정의된 위치를 찾아가보면 다른 플래들도 더 보이는 군요. 직접 찾아가 보시면 간단한 주석과 flag 결합 상태등을 좀 더 분명하게 확인하실 수 있습니다.

(그림 2) 소스코드에서 설정가능한 리스타트 매니저 지원 flag들 (in afxwin.h)

사실 어플리케이션 위자드에서 체크박스 항목으로 설정한 리스타트 매니저 지원사항들도 처음 기본 소스코드들을 생성해줄 때 위의 소스코드 한 줄을 선택사항에 맞춰 적절하게 적어주는 역할만을 할 뿐입니다.

(그림 3) 리스타트 매니저의 사용 설정 예시.



리스타트 매니저 사용에 대한 몇가지 팁들

팁 하나. 문서의 자동 저장 시간 간격 조절하기
CdataRecoveryHandler::SetAutosaveInterval() 함수를 사용하면 문서가 자동 저장되는 시간 간격을 조정할 수 있습니다. 기본값은 5분으로 설정되어 있습니다. CDataRecoveryHandler 클래스를 얻으려면 AfxGetApp()->GetDataRecoveryHandler()를 호출하면 됩니다.
혹은 CDataRecoveryHandler 클래스에 접근하지 않고도 바로 시간간격을 조절할 수도 있습니다. 바로 CWinApp 파생 클래스의 생성자에서 멤버변수 m_nAutosaveInterval에 값을 지정해주면 동일한 처리가 가능합니다.

(그림 4) 리스타트 매니저가 문서를 자동 저장하는 시간 간격 조절.

두가지 방법 모두 시간 단위는 밀리초로 입력합니다. 프로그램 실행 시 최초 1회만 시간설정을 하면 된다면 간단하게 CWinApp 생성자에서 설정해주면 되고, 사용자에게 설정 가능한 옵션으로 제공해 런타임에도 시간설정을 변경해야 한다면 SetAutosaveInterval() 함수를 사용하면 되겠지요.

팁 둘. 리스타트 매니저 직접 만들기(수정하기)
기본 제공되는 리스타트 매니저 만으로도 꽤나 유용한 기능을 사용할 수 있지만, 개발을 하다 보면 다른 방식의 데이터 저장 기능 등을 구현해야 할 때가 있습니다. 이런 경우에는 CWinApp::GetDataRecoveryHandler()를 오버로딩하고, CDataRecoveryHandler클래스를 상속받아 본인이 직접 구현한 CDataRecoveryHandler 파생 클래스를 붙여주면 됩니다.
참고로 윈도우 비스타 이전의 운영체제에서 이 함수가 시스템에 의해 호출되면 NULL을 리턴합니다. 앞서 말씀 드렸듯이 리스타트 매니저는 비스타 이후 OS에서만 지원됩니다. DataRecoveryHandler를 얻어내고자 하면 NULL이 반환되기 때문에, 비스타 이전 OS에서는 리스타트 매니저가 설정되지 않은 것처럼 동작하게 되지요. 그래서 리스타트 매니저를 사용하는 응용 프로그램을 비스타 이전 OS에서 구동하게 되어도 재시작 및 복구 기능만 비활성화 될 뿐, 오동작이나 다른 문제가 발생하지는 않습니다.

팁 셋. 업데이트 상황 재연하기

리스타트 매니저는 크래시가 발생한 경우 뿐만 아니라, 재실행을 필요로 하는 업데이트 진행시에도 사용할 수 있습니다. 크래시 상황을 재현하는 건 간단히 포인터 조작 오류 등을 넣어서 테스트 할 수 있고요, 인스톨러를 이용한 프로그램 업데이트 상황을 재연하고자 할 때에는 아래의 Rm...으로 시작하는 API 들을 사용해서 재현할 수 있습니다.

  • RmStartSession
  • RmRegisterResources
  • RmShutdown
  • RmRestart

이 API들은 윈도우 비스타부터 제공된 기능인 Restart Manager 를 설정 및 조작하는 함수들입니다. 응용 프로그램의 패치를 위해 윈도우즈 인스톨러 4.0 이상의 버전을 사용하는 경우는 자동으로 리스타트 매니저를 사용하게 되어 있고, 커스텀 인스톨러를 사용하는 경우도 역시 제공되는 API 함수들을 이용해 리스타트 매니저를 사용할 수 있습니다. 인스톨러에서 응용 프로그램의 종료 및 재시작을 제어하는 부분은 MFC 리스타트 매니저의 사용이라는 주제에서는 다소 벗어난 내용이므로, 본 포스팅에서는 다루지 않습니다. 보다 자세한 정보는 "메인 인스톨러에서 리스타트 매니저 사용하기(Using Restart Manager with a Primary Installer; http://msdn.microsoft.com/en-us/library/aa373681(VS.85).aspx)" 글을 참고하시기 바랍니다.
참고로 MSDN의 Restart Manager 부분을 한글 번역한 자료가 데브피아에 있습니다(http://www.devpia.com/Maeul/Contents/Detail.aspx?BoardID=63&MAEULNo=24&no=11). 이것도 참고하시면 좋겠네요.


Outro
이번 포스팅에서는 MFC 응용 프로그램에서 실제로 리스타트 매니저를 사용하는 방법과 몇가지 팁들을 정리해 보았습니다. 다음 번에는 '활용하기' 편으로, 예제를 위주로 실제 사용시점에 참고할 만한 사항들을 확인해 보는 것으로 리스타트 매니저 편을 마치도록 하겠습니다.
그럼 다음 포스팅에서 또 만나기로 하고 여기서 줄이겠습니다.
감사합니다 ^^*


참고 자료 (reference)

 

저작자 표시
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Intro
안녕하세요. 이번에 팀블로그에 MFC 카테고리를 맡아 합류하게 된 꽃집총각 이라고 합니다.
앞으로 vs 2010에서 새롭게 선보인 MFC의 기능들을 주제로 포스팅을 하려고 합니다.
많은 관심과 격려 부탁드립니다 ^^

리스타트 매니저(Restart Manager) 의 소개
오늘은 첫 번째 포스팅으로, 응용 프로그램의 예상 못한 종료 상황에 요긴하게 사용될 기능인 리스타트 매니저(Restart Manager; 이하 한글 표기만 사용하겠습니다)에 대해 이야기 하고자 합니다.
리스타트 매니저는 윈도우 비스타 시스템에서 소개된 새로운 기능입니다. 이 기능은 응용 프로그램이 재시작을 필요로 하는 업데이트를 할 때나 처리하지 못한 exception 등으로 크래시가 발생했을 때, 데이터가 손실되지 않도록 도와줍니다. 비정상적인 종료가 발생했을 때 사용자가 이전에 작업 하면서 저장하지 못했던 데이터를 자동 저장 해주고, 응용 프로그램이 재시작 됐을 때 비정상 종료 전의 상태로 복구하는 것을 가능하게 만들어줍니다. 멋진 기능이죠!
쉽게 생각하면 이번에 인터넷 익스플로러 8의 새롭게 선보인 '세션 복구' 기능과 비슷하다고 볼 수 있습니다.

(그림 1) 인터넷 익스플로러 8.0의 세션 복구 기능.


익스플로러 버전 8 부터는 오류 등으로 인해 예상치 못한 종료가 발생하면 다음 재시작에서 위와 같은 창이 뜹니다. 세션 복구를 선택하면 종료 전에 열려있던 웹 페이지들이 다시 열리게 되죠. 이와 유사한 복구기능을 리스타트 매니저가 지원합니다. 

vs2010의 MFC를 통해 지원되는 리스타트매니저의 특징들은 간략히 아래와 같이 정리할 수 있습니다.
  1. vs2010으로 새롭게 제작되는 MFC 응용 프로그램들은 MFC 어플리케이션 위자드 (Application Wizard;응용 프로그램 마법사)를 이용해 아주 간단하게 프로그램 재시작 및 복구 기능을 사용할 수 있습니다.
  2. 리스타트 매니저 API중에서 개발자가 설정/변경 가능한 모든 부분들은 오버라이드 할 수 있는 가상멤버의 형식으로 제공됩니다.
  3. 예전에 만들어진 MFC 응용 프로그램에 기본 제공되는 리스타트 매니저의 기능을 붙이고 싶다면, vs2010으로 옮겨온 후 한 줄의 소스코드만 넣으면 됩니다!
  4. 문서파일을 다루는 응용 프로그램의 경우, 문서를 일정 주기마다 임시 파일로 자동 저장하는 기능이 추가됩니다. 자동 저장되는 주기 역시 개발자가 직접 설정할 수 있습니다. 응용 프로그램이 예외상황으로 크래시가 나는 경우, 해당 프로그램은 가장 마지막으로 백업된 임시 데이터를 복구해 새로 시작됩니다.
  5. 복구가 가능한 자동 저장된 버전의 문서가 존재하는 경우, 사용자에게 복구할 것인지를 묻는 UI 창이 기본 제공됩니다.


리스타트 매니저가 제공하는 기능들

MFC의 리스타트 메니저가 제공하는 기능은 크게 '재시작 기능'과 '복구 기능' 두 단계로 나누어 볼 수 있습니다.

1. 재시작 기능 (Restart Support) :
업그레이드나 크래시가 발생한 후 바로 재시작하는 기능. 이 기능은 모든 MFC 프로그램에서 지원됩니다. 다시말해 다이얼로그 기반이나 SDI, MDI 등의 도큐먼트-뷰 기반 등에 상관없이 MFC 프로젝트로 만든 실행파일은 모두 다 사용 가능하다는 의미입니다.

(그림 2) 크래시가 나면 해결 방법을 확인 중이라는 창이 뜹니다. 과연 뭘 하는 중일까요...

(그림 3) 그리고는 곧 '다시 시작하는 중'이라는 창이 뜨고, 프로그램은 자동 재실행 됩니다.

2. 복구 기능 (Application Recover Support) :
복구 기능은 또 다시 두 가지 기능으로 나누어 볼 수 있습니다.
  1. 종료되기 전에 열어두고 있었던 문서를 바로 다시 열어주는 기능.
  2. 자동 저장된 버전의 문서를 복구해 주는 기능.
복구 기능은 문서(Document)에 관련된 기능이니만큼, 도큐먼트-뷰 형식의 MFC 응용 프로그램에서만 사용 가능합니다. 다이얼로그 기반 프로젝트로 만든 실행파일에서는 사용할 수 없어요. 다시 정리하자면, 데이터를 복구한다는 의미는 도큐먼트-뷰 형식의 프로그램에서 Document에 해당하는 문서 데이터 부분을 대상으로 하는 말입니다. 개발자가 임의로 선언해 사용하는 (CDocument 클래스와 크게 상관이 없는) 커스텀한 데이터들은 복구 대상이 아닙니다. 
하지만 이건 기본 제공되는 리스타트 매니저에 대한 설명입니다. 추가 동작이 필요하다면 기본 기능을 확장할 수 있는 가상함수 형식의 인터페이스들을 통해 직접 기능 확장을 하면 됩니다. 또한 기본 제공 기능만으로도 문서형식의 데이터들은 손하나 대지 않아도 크게 손색이 없는 복구 기능을 붙일 수 있습니다.

(그림 4) 복구 가능한 문서가 존재할 때 사용자에게 노출되는 UI.

자동저장된 파일이 존재해 복구가 가능한 경우, 프로그램은 재실행 되자 마자 (그림 4)와 같은 대화상자를 출력합니다.


Outro
실제로 리스타트 매니저를 사용하는 방법까지 정리하면 포스팅이 너무 길어질 것 같네요. 일단은 첫 포스팅이기도 하니 가볍게 기능 소개만으로 끝을 맺고, 다음 포스팅에서는 지극히 쉽고 심플한 리스타트 매니저 사용법에 대해서 정리해 보겠습니다. 얼른 적용해 보고 싶으신 분들은 아래에 있는 참고자료 링크들을 찾아가 보세요. 정말 너무너무 쉽습니다!
그리고 리스타트 매니저는 비스타 이후의 OS에서 지원가능합니다. (비스타, 윈도우7, 윈도우 서버 2008) 그럼 리스타트 매니저를 사용하는 MFC 프로그램이 xp에서 크래시가 나면 어떻게 될까요? 자동 저장 기능은 그냥 disable만 되고 마는 것일까요? 이런 부분들도 차곡차곡 정리해서 포스팅 하도록 하겠습니다.
글 내용 중 잘못된 부분이나 부족한 부분은 댓글로 의견 주세요. 참고 반영 하겠습니다.
감사합니다 ^^*

참고자료 링크 (reference)

저작자 표시
신고
크리에이티브 커먼즈 라이선스
Creative Commons License


 

티스토리 툴바