128
Chap. 6 Chap. 6 Dialog and Control Classes Dialog and Control Classes

Chap. 6 Dialog and Control Classes. Contents CDialog class Common Dialogs Property Sheets Control classes

Embed Size (px)

DESCRIPTION

CDialog Class  Dialog 의 종류  Modal dialog Close 될 때 까지 다른 부분을 사용할 수 없음 Close 될 때 까지 다른 부분을 사용할 수 없음 DoModal() 함수를 이용 DoModal() 함수를 이용 예 : common dialog box 예 : common dialog box  Modeless dialog Close 되기 전에 다른 부분을 사용할 수 있음 Close 되기 전에 다른 부분을 사용할 수 있음 Create() 함수를 이용 Create() 함수를 이용 DestroyWindow() 함수를 이용하여 명시적으로 종료함 DestroyWindow() 함수를 이용하여 명시적으로 종료함 예 : find and replace dialog box 예 : find and replace dialog box

Citation preview

Page 1: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Chap. 6Chap. 6

Dialog and Control ClassesDialog and Control Classes

Page 2: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

ContentsContents CDialog classCDialog class Common DialogsCommon Dialogs Property SheetsProperty Sheets Control classesControl classes

Page 3: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDialog ClassCDialog Class DialogDialog 의 종류의 종류

Modal dialogModal dialog CloseClose 될 때 까지 다른 부분을 사용할 수 없음될 때 까지 다른 부분을 사용할 수 없음 DoModal()DoModal() 함수를 이용함수를 이용 예 예 : : common dialog boxcommon dialog box

Modeless dialogModeless dialog CloseClose 되기 전에 다른 부분을 사용할 수 있음되기 전에 다른 부분을 사용할 수 있음 Create()Create() 함수를 이용함수를 이용 DestroyWindow()DestroyWindow() 함수를 이용하여 명시적으로 종료함함수를 이용하여 명시적으로 종료함 예 예 : : find and replace dialog boxfind and replace dialog box

Page 4: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDialog Class (cont’d)CDialog Class (cont’d) HistoryHistory

MFC 1.0 MFC 1.0 Modal dialog : CModalDialogModal dialog : CModalDialog Modeless dialog : CDialogModeless dialog : CDialog

Current version Current version Modal dialog : CDialogModal dialog : CDialog Modeless dialog : CdialogModeless dialog : Cdialog

AFXWIN.HAFXWIN.H// all CModalDialog functionality is now in CDialog#define CModalDialog CDialog

Page 5: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDialog Class (cont’d)CDialog Class (cont’d)void CMyView::DisplayOrderDialog(){

CMyDialog myDialog(ID_DLG_MYDIALOG);if ( myDialog.DoModal() == IDOK ) {

// Do OK processing} else {

// Do Calnel processing}

}

m_pDlgMyDlgPtr = new CMyDialog;m_pDlgMyDlgPtr->Create(ID_DLG_MYDIALOG);// Do somethingm_pDlgMyDlgPtr->DestroyWindow();m_pDlgMyDlgPtr = NULL;

Page 6: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Win32 APIsWin32 APIs DialogDialog 생성을 위한 생성을 위한 Win32 APIsWin32 APIs

CreateDialog()CreateDialog() Modeless dialogModeless dialog 생성생성 , , template resourcetemplate resource 이용이용

CreateDialogIndirect()CreateDialogIndirect() Modeless dialogModeless dialog 생성생성 , , template pointertemplate pointer 이용이용

DialogBox()DialogBox() Modal dialogModal dialog 생성생성 , , template resourcetemplate resource 이용이용

DialogBoxIndirect()DialogBoxIndirect() Modal dialogModal dialog 생성생성 , , template pointertemplate pointer 이용이용

Page 7: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Win32 APIs (cont’d)Win32 APIs (cont’d) CDialog ClassCDialog Class

오직 오직 CreateDialogIndirect() APICreateDialogIndirect() API 을 이용을 이용 ModalityModality 를 내부적으로 구현를 내부적으로 구현 AFXWIN.HAFXWIN.H DLGCORE.CPP, AFXWIN2.INLDLGCORE.CPP, AFXWIN2.INL

Page 8: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDialogCDialogclass CDialog : public CWnd{ DECLARE_DYNAMIC(CDialog) BOOL Create(LPCTSTR lpszTemplateName, CWnd* pParentWnd = NULL); BOOL Create(UINT nIDTemplate, CWnd* pParentWnd = NULL); BOOL CreateIndirect(LPCDLGTEMPLATE lpDialogTemplate,

CWnd* pParentWnd = NULL, void* lpDialogInit = NULL); BOOL CreateIndirect(HGLOBAL hDialogTemplate, CWnd* pParentWnd = NULL);

// Modal constructpublic: CDialog(LPCTSTR lpszTemplateName, CWnd* pParentWnd = NULL); CDialog(UINT nIDTemplate, CWnd* pParentWnd = NULL); BOOL InitModalIndirect(LPCDLGTEMPLATE lpDialogTemplate,

CWnd* pParentWnd = NULL, void* lpDialogInit = NULL); BOOL InitModalIndirect(HGLOBAL hDialogTemplate,

CWnd* pParentWnd = NULL);

// Operationspublic: // modal processing virtual int DoModal();

Page 9: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDialog (cont’d)CDialog (cont’d) void NextDlgCtrl() const; void PrevDlgCtrl() const; void GotoDlgCtrl(CWnd* pWndCtrl); // termination void EndDialog(int nResult);// Overridables (special message map entries) virtual BOOL OnInitDialog(); virtual void OnSetFont(CFont* pFont);protected: virtual void OnOK(); virtual void OnCancel();// Implementationpublic: virtual ~CDialog(); virtual BOOL PreTranslateMessage(MSG* pMsg); virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra,

AFX_CMDHANDLERINFO* pHandlerInfo); virtual BOOL CheckAutoCenter();

Page 10: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

protected: // parameters for 'DoModal' LPCTSTR m_lpszTemplateName; // name or MAKEINTRESOURCE HGLOBAL m_hDialogTemplate; // indirect (m_lpDialogTemplate == NULL) LPCDLGTEMPLATE m_lpDialogTemplate; void* m_lpDialogInit; // DLGINIT resource data CWnd* m_pParentWnd; // parent/owner window HWND m_hWndTop; // top level parent window (may be disabled) virtual void PreInitDialog(); // implementation helpers HWND PreModal(); void PostModal(); BOOL CreateIndirect(LPCDLGTEMPLATE lpDialogTemplate,

CWnd* pParentWnd, void* lpDialogInit, HINSTANCE hInst); BOOL CreateIndirect(HGLOBAL hDialogTemplate, CWnd* pParentWnd,

HINSTANCE hInst);

protected:DECLARE_MESSAGE_MAP()

};

CDialog (cont’d)CDialog (cont’d)

Page 11: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Declaration(AFXWIN.H)Declaration(AFXWIN.H) 멤버 변수멤버 변수

m_nIDHelpm_nIDHelp ButtonButton 을 위한 을 위한 help IDhelp ID

m_lpszTemplateNamem_lpszTemplateName Resource templateResource template 의 이름의 이름

m_hDialogTemplatem_hDialogTemplate 일단 일단 loadload 된 후의 된 후의 resource templateresource template 의 의 handlehandle

m_lpDialogInitm_lpDialogInit 초기화에 관련된 초기화에 관련된 datadata 에 대한 에 대한 pointerpointer

CDialog (cont’d)CDialog (cont’d)

Page 12: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

m_pParentWndm_pParentWnd Parent windowParent window 에 대한 에 대한 pointerpointer

m_hWndTopm_hWndTop Top-level parent windowTop-level parent window

m_pOccDialogInfom_pOccDialogInfo OLE controlsOLE controls 을 위한 을 위한 stored informationstored information

멤버 함수멤버 함수 virtual PreTranslateMessage()virtual PreTranslateMessage()

특별한 특별한 message(tool tips, context-sensitive help)message(tool tips, context-sensitive help) 에 대한 에 대한 filteringfiltering

CDialog (cont’d)CDialog (cont’d)

Page 13: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

virtual OnCmdMsg()virtual OnCmdMsg() Command messageCommand message 처리작업처리작업

virtual CheckAutoCenter()virtual CheckAutoCenter() Auto-centerAuto-center 옵션이 체크되었는지 확인옵션이 체크되었는지 확인

virtual SetOccDialogInfo()virtual SetOccDialogInfo() M_pOccDialogInfoM_pOccDialogInfo 변수에 데이터를 변수에 데이터를 settingsetting

virtual PreInitDialog()virtual PreInitDialog() WM_INITDIALOG messageWM_INITDIALOG message 이전에 불리워지는 함수이전에 불리워지는 함수

PreModal()PreModal() DoModal()DoModal() 함수 실행을 위한 준비작업함수 실행을 위한 준비작업

PostModal()PostModal() DoModal()DoModal() 함수가 끝난후의 뒤처리함수가 끝난후의 뒤처리

CDialog (cont’d)CDialog (cont’d)

Page 14: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

일반적으로 두가지의 과정을 거침일반적으로 두가지의 과정을 거침 CDialog constructionCDialog construction DoModal()DoModal() 함수의 호출함수의 호출

CDialog constructionCDialog construction DLGCORE.CPPDLGCORE.CPP 에 있음에 있음 두가지 버전이 있으며 두가지 버전이 있으며 CDialog classCDialog class 의 필요한 의 필요한

변수에 값을 입력하는 역할을 함변수에 값을 입력하는 역할을 함

Modal Dialog CreationModal Dialog Creation

Page 15: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Modal Dialog Creation (cont’d)Modal Dialog Creation (cont’d)“DlgCore.cpp”

CDialog::CDialog(LPCTSTR lpszTemplateName, CWnd* pParentWnd){

m_pParentWnd = pParentWnd;m_lpszTemplateName = lpszTemplateName;if (HIWORD(m_lpszTemplateName) == 0)

m_nIDHelp = LOWORD((DWORD)m_lpszTemplateName);}

CDialog::CDialog(UINT nIDTemplate, CWnd* pParentWnd){

m_pParentWnd = pParentWnd;m_lpszTemplateName =

MAKEINTRESOURCE(nIDTemplate);m_nIDHelp = nIDTemplate;

}

Page 16: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Modal Dialog Creation (cont’d)Modal Dialog Creation (cont’d)int CDialog::DoModal(){ // STEP 1 : load resource as necessary LPCDLGTEMPLATE lpDialogTemplate = m_lpDialogTemplate; HGLOBAL hDialogTemplate = m_hDialogTemplate; HINSTANCE hInst = AfxGetResourceHandle(); if (m_lpszTemplateName != NULL) {

hInst = AfxFindResourceHandle(m_lpszTemplateName, RT_DIALOG);

HRSRC hResource = ::FindResource(hInst, m_lpszTemplateName,

RT_DIALOG);hDialogTemplate = LoadResource(hInst, hResource);

} if (hDialogTemplate != NULL) lpDialogTemplate = (LPCDLGTEMPLATE)LockResource (hDialogTemplate); // return -1 in case of failure to load the dialog template resource if (lpDialogTemplate == NULL) return -1;

Page 17: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Modal Dialog Creation (cont’d)Modal Dialog Creation (cont’d) // STEP 2 : Preparing to create the dialog HWND hWndParent = PreModal(); AfxUnhookWindowCreate(); BOOL bEnableParent = FALSE; if (hWndParent != NULL && ::IsWindowEnabled(hWndParent))

{::EnableWindow(hWndParent, FALSE);bEnableParent = TRUE;

} // STEP 3 : create modeless dialog AfxHookWindowCreate(this); if (CreateDlgIndirect(lpDialogTemplate,

CWnd::FromHandle(hWndParent), hInst)) {if (m_nFlags & WF_CONTINUEMODAL) {

// enter modal loopDWORD dwFlags = MLF_SHOWONIDLE;if (GetStyle() & DS_NOIDLEMSG) dwFlags |=

MLF_NOIDLEMSG;VERIFY(RunModalLoop(dwFlags) ==

m_nModalResult);}

Page 18: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Modal Dialog Creation (cont’d)Modal Dialog Creation (cont’d)// hide the window before enabling the parent, etc.if (m_hWnd != NULL)

SetWindowPos(NULL, 0, 0, 0, 0, SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|

SWP_NOZORDER); } if (bEnableParent)

::EnableWindow(hWndParent, TRUE); if (hWndParent != NULL && ::GetActiveWindow() == m_hWnd)

::SetActiveWindow(hWndParent); // STEP 4 : destroy modal window DestroyWindow(); PostModal();}

Page 19: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Modal Dialog Creation (cont’d)Modal Dialog Creation (cont’d)HWND CDialog::PreModal(){

// cannot call DoModal on a dialog already constructed as modeless

ASSERT(m_hWnd == NULL);

// allow OLE servers to disable themselvesCWinApp* pApp = AfxGetApp();if (pApp != NULL) pApp->EnableModeless(FALSE);

// find parent HWNDHWND hWnd = CWnd::GetSafeOwner_

(m_pParentWnd->GetSafeHwnd(), &m_hWndTop);

// hook for creation of dialogAfxHookWindowCreate(this);

// return window to use as parent for dialogreturn hWnd;

}

Page 20: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Modal Dialog Creation (cont’d)Modal Dialog Creation (cont’d)int CWnd::RunModalLoop(DWORD dwFlags){ BOOL bIdle = TRUE; LONG lIdleCount = 0; BOOL bShowIdle = (dwFlags & MLF_SHOWONIDLE) &&

!(GetStyle() & WS_VISIBLE); HWND hWndParent = ::GetParent(m_hWnd); // acquire and dispatch messages until the modal state is done for (;;) { // phase1: check to see if we can do idle work while(bIdle&&!::PeekMessage(pMsg,NULL,NULL,NULL,PM_NOREMOVE)) { } // phase2: pump messages while available do {

// pump message, but quit on WM_QUIT!AfxGetThread()->PumpMessage();

} while (::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE)); }}

Page 21: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

DoModal()(DLGCORE.CPP)DoModal()(DLGCORE.CPP) Dialog resourceDialog resource 의 의 loadingloading

Dialog template nameDialog template name 을 가지고 을 가지고 dialog templatedialog template 을 을 찾아서 찾아서 loadload 함함

DialogDialog 를 생성하기 위한 준비를 생성하기 위한 준비 PreModal()PreModal() 함수를 호출함함수를 호출함

Safety checksSafety checks Parent window handleParent window handle 을 찾음을 찾음

m_hWndTopm_hWndTop 에 저장에 저장 EnableWindow(FALSE)EnableWindow(FALSE) 를 호출를 호출

Parent windowParent window 를 를 disabledisable 시킴시킴

Modal Dialog Creation (cont’d)Modal Dialog Creation (cont’d)

Page 22: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

DialogDialog 를 생성하고 보여줌를 생성하고 보여줌 CWnd::CreateDlgIndirect()CWnd::CreateDlgIndirect() 함수 호출함수 호출 내부적으로 내부적으로 Win32APIWin32API 인 인 CreateDialogIndirect()CreateDialogIndirect() 를 호출를 호출 CWnd::RunModalLoop()CWnd::RunModalLoop() 함수 호출함수 호출 DialogDialog 가 끝날때 까지 일을 수행가 끝날때 까지 일을 수행 사용자가 사용자가 okok 나 나 cancelcancel 버튼을 누르면 버튼을 누르면

CWnd::EndModalLoop()CWnd::EndModalLoop() 함수가 호출됨함수가 호출됨 DialogDialog 를 화면에서 보이지 않게 함를 화면에서 보이지 않게 함 DialogDialog 가 종료하면 가 종료하면 EnableWindow(TRUE)EnableWindow(TRUE) 를 호출를 호출 Parent windowParent window 를 를 enableenable 시킴시킴

마지막 단계마지막 단계 DestroyWindow()DestroyWindow() 함수 호출함수 호출 PostModal()PostModal() 함수 호출함수 호출

Modal Dialog Creation (cont’d)Modal Dialog Creation (cont’d)

Page 23: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Modeless dialog creationModeless dialog creation 두가지 과정을 거침두가지 과정을 거침

New operatorNew operator 를 사용하여 변수 생성를 사용하여 변수 생성 CDialog::Create()CDialog::Create() 함수 호출함수 호출

Modeless Dialog CreationModeless Dialog Creation

Page 24: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Modeless Dialog Creation (cont’d)Modeless Dialog Creation (cont’d)BOOL CDialog::Create(LPCTSTR lpszTemplateName, CWnd* pParentWnd){ m_lpszTemplateName = lpszTemplateName; // used for help if (HIWORD(m_lpszTemplateName) == 0 && m_nIDHelp == 0)

m_nIDHelp = LOWORD((DWORD)m_lpszTemplateName); if (!_AfxCheckDialogTemplate(lpszTemplateName, FALSE)) {

PostNcDestroy(); // cleanup if Create fails too soonreturn FALSE;

} HINSTANCE hInst = AfxFindResourceHandle(lpszTemplateName, RT_DIALOG); HRSRC hResource = ::FindResource(hInst, lpszTemplateName, RT_DIALOG); HGLOBAL hTemplate = LoadResource(hInst, hResource); BOOL bResult = CreateIndirect(hTemplate, pParentWnd, hInst); FreeResource(hTemplate); return bResult;}

Page 25: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Modeless Dialog Creation (cont’d)Modeless Dialog Creation (cont’d)BOOL CDialog::CreateIndirect(LPCDLGTEMPLATE lpDialogTemplate, CWnd* pParentWnd,

void* lpDialogInit, HINSTANCE hInst){

ASSERT(lpDialogTemplate != NULL);

if (pParentWnd == NULL)pParentWnd = AfxGetMainWnd();

m_lpDialogInit = lpDialogInit;

return CreateDlgIndirect(lpDialogTemplate, pParentWnd, hInst);}

Page 26: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDialog::Create()(DLGCORE.CPP)CDialog::Create()(DLGCORE.CPP) Template nameTemplate name 과 과 help IDhelp ID 를 내부 변수에 저장를 내부 변수에 저장 Dialog resourceDialog resource 를 찾고 를 찾고 loadload 함함 CDialog::CreateIndirect()CDialog::CreateIndirect() 함수 호출함수 호출

내부적으로 내부적으로 Win32 APIWin32 API 인 인 CreateDialogIndirect()CreateDialogIndirect() 함수 함수 호출호출

사용자가 사용자가 okok 나 나 cancelcancel 버튼을 누르면 버튼을 누르면 EndDialog()EndDialog()가 호출되어 가 호출되어 dialogdialog 가 사라짐가 사라짐

Modeless Dialog Creation (cont’d)Modeless Dialog Creation (cont’d)

Page 27: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Dialog TerminatorDialog Terminator

void CDialog::EndDialog(int nResult){

ASSERT(::IsWindow(m_hWnd));if (m_nFlags & (WF_MODALLOOP|

WF_CONTINUEMODAL))EndModalLoop(nResult);

::EndDialog(m_hWnd, nResult);}

Page 28: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDialog Control InitializationCDialog Control Initialization DialogDialog 에 있는 에 있는 controlcontrol 의 초기화 작업의 초기화 작업

ResourceResource 에 의한 초기화에 의한 초기화 Combo boxCombo box 를 예로 살펴봄를 예로 살펴봄

DataData 는 “는 “ one”, “two”, “three”one”, “two”, “three” 라 가정라 가정 다음과 같은 코드가 생성되지 않는다다음과 같은 코드가 생성되지 않는다 ..

m_pCombo->AddString(“one”);m_pCombo->AddString(“two”);m_pCombo->AddString(“three”);

Page 29: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

WM_INITDIALOGWM_INITDIALOG DialogDialog 가 화면에 보이기 전에 발생하는 가 화면에 보이기 전에 발생하는 messagemessage ApplicationApplication 으로 하여금 으로 하여금 dialogdialog 에 있는 에 있는 controlcontrol

들을 초기화 할 수 있도록 함들을 초기화 할 수 있도록 함 CDialog::HandleInitDialog()CDialog::HandleInitDialog() 함수에 함수에 mappingmapping

되어 있음되어 있음

CDialog::HandleInitDialog()CDialog::HandleInitDialog() OLE control OLE control 관련 초기화 작업을 하고 관련 초기화 작업을 하고

CDialog::OnInitDialog()CDialog::OnInitDialog() 를 호출를 호출

CDialog::OnInitDialog()CDialog::OnInitDialog() CWnd::ExecuteDlgInit()CWnd::ExecuteDlgInit() 를 호출를 호출

CDialog Control Initialization CDialog Control Initialization (cont’d)(cont’d)

Page 30: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Resource fileResource fileCDialog Control Initialization CDialog Control Initialization (cont’d)(cont’d)

IDD_ABOUTBOX DLGINITBEGIN IDC_COMBO1, 0x403, 4, 00x6e6f, 0x0065, IDC_COMBO1, 0x403, 4, 00x7774, 0x006f, IDC_COMBO1, 0x403, 6, 00x6874, 0x6572, 0x0065, 0END

Page 31: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CWnd::ExecuteDlgInit()(WINCORE.CPP)CWnd::ExecuteDlgInit()(WINCORE.CPP) 두가지 버전이 존재두가지 버전이 존재

ArgumentArgument 로 로 dialog template namedialog template name ArgumentArgument 로 로 dialog datadialog data 에 대한 에 대한 pointerpointer

일단 첫번째 버전의 함수가 일단 첫번째 버전의 함수가 dialog template namedialog template name을 가지고 을 가지고 resource resource 파일에서 파일에서 controlcontrol 의 의 datadata 를 를 loadload 함함

이 후 이 후 pointerpointer 를 얻어서 두번째 버전의 함수를 호출를 얻어서 두번째 버전의 함수를 호출

why CWnd class member function?why CWnd class member function?

CDialog Control Initialization CDialog Control Initialization (cont’d)(cont’d)

Page 32: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CWnd::ExecuteDlgInit(LPVOID)CWnd::ExecuteDlgInit(LPVOID) Resource fileResource file 의 의 raw data(DLGINIT)raw data(DLGINIT) 를 를 parsingparsing 함함

BOOL CWnd::ExecuteDlgInit(LPVOID lpResource) { BOOL bSuccess = TRUE; UNALIGNED WORD* lpnRes = (WORD*)lpResource; while(bSuccess && *lpnRes != 0) { WORD nIDC = *lpnRes++;

WORD nMsg = *lpnRes++;DWORD dwLen = *((UNALIGNED DWORD*&)lpnRes)++;if (nMsg == LB_ADDSTRING || nMsg == CB_ADDSTRING) {

if (::SendDlgItemMessageA(m_hWnd, nIDC, nMsg, 0,

(LONG)lpnRes) == -1)bSuccess = FALSE;

} } return bSuccess;}

CDialog Control Initialization CDialog Control Initialization (cont’d)(cont’d)

Page 33: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

DDX/DDVDDX/DDV DDX/DDVDDX/DDV

DDX(Dynamic Data eXchange)DDX(Dynamic Data eXchange) DDV(Dynamic Data Validation)DDV(Dynamic Data Validation) Data members Data members Controls Controls 활용 사례활용 사례

void CMyDlg::DoDataExchange(CDataExchange * pDX){

CDialog::DoDataExchange(pDX);DDX_Text(pDX, IDC_EDIT1, m_strEdit1);DDV_MaxChars(pDX, IDC_EDIT1, 20);DDX_Text(pDX, IDC_EDIT2, m_uEdit2);DDV_MinMaxChars(pDX, IDC_EDIT2, 1, 234);DDX_Check(pDX, IDC_CHECK, m_bCheckState);DDX_Radio(pDX, IDC_RADIO, m_nRadioState);

}

Page 34: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

DDX/DDV (cont’d)DDX/DDV (cont’d) QuestionQuestion

CDataExchange classCDataExchange class 의 역할의 역할 ControlControl 들과 멤버 변수들간의 정보 교환은 언제들과 멤버 변수들간의 정보 교환은 언제 , ,

어디에서어디에서 , , 어떻게 이루어지는가어떻게 이루어지는가 DDX/DDV DDX/DDV 함수는 무슨 일들을 하는가함수는 무슨 일들을 하는가

Page 35: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

DDX/DDV (cont’d)DDX/DDV (cont’d) Helper classHelper class

CDataExchange(AFXWIN.H)CDataExchange(AFXWIN.H)class CDataExchange{// Attributespublic: BOOL m_bSaveAndValidate; // TRUE => save and validate data CWnd* m_pDlgWnd; // container usually a dialog// Operations (for implementors of DDX and DDV procs) HWND PrepareCtrl(int nIDC); // return HWND of control HWND PrepareEditCtrl(int nIDC); // return HWND of control void Fail(); // will throw exception CWnd* PrepareOleCtrl(int nIDC); // for OLE controls in dialog// Implementation CDataExchange(CWnd* pDlgWnd, BOOL bSaveAndValidate); HWND m_hWndLastControl; // last control used (for validation) BOOL m_bEditLastControl; // last control was an edit item};

Page 36: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

DDX/DDV (cont’d)DDX/DDV (cont’d) 멤버 변수멤버 변수

m_bSaveAndValidatem_bSaveAndValidate TRUE TRUE data data 가 가 controlcontrol 에서 변수로 감에서 변수로 감 FALSE FALSE data data 가 변수에서 가 변수에서 controlcontrol 로 감로 감 ValidationValidation 은 은 TRUETRUE 일때만 일어남일때만 일어남

m_pDlgWndm_pDlgWnd DialogDialog 에 대한 에 대한 CWnd pointerCWnd pointer

m_hWndLastControlm_hWndLastControl Previous controlPrevious control 에 대한 에 대한 handlehandle 을 저장을 저장

m_bEditLastControlm_bEditLastControl Previous controlPrevious control 이 수정되었는지를 저장이 수정되었는지를 저장

Page 37: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

멤버 함수멤버 함수 ConstructorConstructor PrepareCtrl()PrepareCtrl()

Non-edit controlNon-edit control 을 위한 준비을 위한 준비 PrepareEditCtrl()PrepareEditCtrl()

Edit controlEdit control 을 위한 준비을 위한 준비 Fail()Fail()

ValidationValidation 이 실패하면 호출됨이 실패하면 호출됨 FocusFocus 를 를 previous controlprevious control 로 보내고 로 보내고 CUserExceptionCUserException

예외를 발생시킴예외를 발생시킴 PrepareOleCtrl()PrepareOleCtrl()

OLE controlOLE control 을 위한 준비을 위한 준비

DDX/DDV (cont’d)DDX/DDV (cont’d)

Page 38: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

특징특징 DDX/DDVDDX/DDV 는 는 SerializeSerialize 과정과 유사과정과 유사 CDataExchange CDataExchange 는 는 CArchive CArchive 와 비슷와 비슷 DoDataExchange()DoDataExchange() 는 는 Serialize() Serialize() 와 비슷와 비슷 Save/load tagSave/load tag 를 가짐를 가짐

DDX/DDV (cont’d)DDX/DDV (cont’d)

Page 39: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

DDX/DDV DDX/DDV 함수들함수들 DDX_Text()(DLGDATA.CPP)DDX_Text()(DLGDATA.CPP)

m_bSaveAndValidatem_bSaveAndValidate 의 값을 기준으로 의 값을 기준으로 datadata 이동이동 DDV_MaxChars()(DLGDATA.CPP)DDV_MaxChars()(DLGDATA.CPP)

m_bSaveAndValidatem_bSaveAndValidate 값이 값이 TRUETRUE 인경우 인경우 validationvalidation 코드 코드 수행수행

DDX_TextWithFormat()(DLGDATA.CPP)DDX_TextWithFormat()(DLGDATA.CPP) StringString 과 과 intint 사이의 사이의 conversionconversion

DDX/DDV (cont’d)DDX/DDV (cont’d)

Page 40: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

DDX/DDV (cont’d)DDX/DDV (cont’d)void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, CString& value){ HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC); if (pDX->m_bSaveAndValidate) { int nLen = ::GetWindowTextLength(hWndCtrl);

::GetWindowText(hWndCtrl, value.GetBufferSetLength(nLen), nLen+1);

value.ReleaseBuffer(); } else { AfxSetWindowText(hWndCtrl, value); }}

Page 41: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

DDX/DDV (cont’d)DDX/DDV (cont’d)void AFXAPI DDV_MaxChars(CDataExchange* pDX, CString const& value, int nChars){ ASSERT(nChars >= 1); // allow them something if (pDX->m_bSaveAndValidate && value.GetLength() > nChars) { TCHAR szT[32];

wsprintf(szT, _T("%d"), nChars);CString prompt;AfxFormatString1(prompt, AFX_IDP_PARSE_STRING_SIZE,

szT);AfxMessageBox(prompt, MB_ICONEXCLAMATION,

AFX_IDP_PARSE_STRING_SIZE);prompt.Empty(); // exception preppDX->Fail();

} else if (pDX->m_hWndLastControl != NULL && pDX->m_bEditLastControl) {

// limit the control max-chars automatically::SendMessage(pDX->m_hWndLastControl,

EM_LIMITTEXT, nChars, 0); }}

Page 42: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

언제 언제 DoDataExchange()DoDataExchange() 가 호출되는가가 호출되는가 ?? 필요할 때 마다 필요할 때 마다 UpdateData()UpdateData() 함수 호출함수 호출 위 함수 내부에서 위 함수 내부에서 DoDataExchange()DoDataExchange() 를 호출함를 호출함

UpdateData()(WINCORE.CPP)UpdateData()(WINCORE.CPP)

DDX/DDV (cont’d)DDX/DDV (cont’d)

Page 43: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

DDX/DDV (cont’d)DDX/DDV (cont’d)BOOL CWnd::UpdateData(BOOL bSaveAndValidate){

CDataExchange dx(this, bSaveAndValidate);_AFX_THREAD_STATE* pThreadState =

AfxGetThreadState();HWND hWndOldLockout = pThreadState-

>m_hLockoutNotifyWindow;ASSERT(hWndOldLockout != m_hWnd); // must not

recursepThreadState->m_hLockoutNotifyWindow = m_hWnd;BOOL bOK = FALSE; // assume failureTRY {

DoDataExchange(&dx);bOK = TRUE; // it worked

}CATCH(CUserException, e) {

// validation failed - user already alerted, fall through

ASSERT(!bOK);}

}

Page 44: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

DDX/DDV (cont’d)DDX/DDV (cont’d)void CDialog::OnOK(){

if (!UpdateData(TRUE)) {TRACE0("UpdateData failed during dialog

termination.\n");// the UpdateData routine will set focus to correct

itemreturn;

}EndDialog(IDOK);

}

BOOL CDialog::OnInitDialog(){

BOOL bDlgInit;if (m_lpDialogInit != NULL) bDlgInit =

ExecuteDlgInit(m_lpDialogInit);else bDlgInit = ExecuteDlgInit(m_lpszTemplateName);UpdateData(FALSE);return TRUE; // set focus to first one

}

Page 45: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Common DialogsCommon Dialogs Common DialogsCommon Dialogs

표준 표준 interfaceinterface 제공을 위하여제공을 위하여 종류종류

CColorDialogCColorDialog CFileDialogCFileDialog CFindReplaceDialogCFindReplaceDialog CFontDialogCFontDialog CPrintDialogCPrintDialog CPageSetupDialog ( MFC 4.0 )CPageSetupDialog ( MFC 4.0 )

Page 46: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

StepsSteps 생성자 호출생성자 호출 DoModal() DoModal() 호출호출 IDOKIDOK 가 리턴될 때 적절한 처리가 리턴될 때 적절한 처리

Common Dialogs (cont’d)Common Dialogs (cont’d)

CFileDialog myDialog(TRUE, NULL, NULL, OFN_FILEMUSTEXIST);if ( myDialog.DoModal() == IDOK ) {

Cstring strPath = myDialog.GetPathName();CString strFile = myDialog.GetFileName();

}else // User selected Cancel …

Page 47: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Win32 API Win32 API 관점에서관점에서 모든 모든 common dialogcommon dialog 는는

대응되는 대응되는 structurestructure 를 가지고 있다를 가지고 있다 .. 대응되는 대응되는 APIAPI 를 가지고 있다를 가지고 있다 .. 예예 ) ) Open File common dialogOpen File common dialog

Structure – OPENFILENAMEStructure – OPENFILENAME API – GetOpenFileName(LP OPENFILENAME)API – GetOpenFileName(LP OPENFILENAME)

모든 모든 common dialogcommon dialog 의 의 base classbase class CCommonDialog(AFXDLGS.H)CCommonDialog(AFXDLGS.H) OnOK()OnOK() 와 와 OnCancel() OnCancel() 추가추가

Common Dialogs (cont’d)Common Dialogs (cont’d)

Page 48: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

예제 예제 dialogdialog CFileDialog(AFXDLGS.H)CFileDialog(AFXDLGS.H)

Common Dialogs (cont’d)Common Dialogs (cont’d)

class CFileDialog : public CCommonDialog{public:

OPENFILENAME m_ofn; // open file parameter blockvirtual int DoModal();CString GetPathName() const; // return full path and

filenameCString GetFileName() const; // return only filenameCString GetFileExt() const; // return only extCString GetFileTitle() const; // return file titleBOOL GetReadOnlyPref() const; // return TRUE if

readonly checked// Enumerating multiple file selectionsPOSITION GetStartPosition() const;CString GetNextPathName(POSITION& pos) const;

Page 49: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Common Dialogs (cont’d)Common Dialogs (cont’d)protected: friend UINT CALLBACK _AfxCommDlgProc(HWND, UINT, WPARAM, LPARAM); virtual UINT OnShareViolation(LPCTSTR lpszPathName); virtual BOOL OnFileNameOK(); virtual void OnLBSelChangedNotify(UINT nIDBox, UINT iCurSel, UINT nCode); // only called back if OFN_EXPLORER is set virtual void OnInitDone(); virtual void OnFileNameChange(); virtual void OnFolderChange(); virtual void OnTypeChange();// Implementation BOOL m_bOpenFileDialog; // TRUE for file open, FALSE for file save CString m_strFilter; // filter string TCHAR m_szFileTitle[64]; // contains file title after return TCHAR m_szFileName[_MAX_PATH]; // contains full path name after return OPENFILENAME* m_pofnTemp; virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);};

Page 50: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

예제 예제 dialogdialog CFileDialog(AFXDLGS.H)CFileDialog(AFXDLGS.H)

OPENFILENAME structureOPENFILENAME structure 여러 개의 여러 개의 virtual protected virtual protected 함수함수 기타 여러 정보 저장을 위한 변수기타 여러 정보 저장을 위한 변수

CFileDialogCFileDialog 의 생성의 생성 ((DLGFILE.CPP)DLGFILE.CPP) 생성자의 생성자의 argumentargument 들을 들을 OPENFILENAME structureOPENFILENAME structure 의 의

멤버에 멤버에 settingsetting 함함 ((m_ofn)m_ofn) Window95Window95 이상일 경우에는 이상일 경우에는 OFN_EXPLOREROFN_EXPLORER 와 와

OFN_ENABLEHOOK flagOFN_ENABLEHOOK flag 를 를 setset 함함 OFN_ENABLEHOOK OFN_ENABLEHOOK Hook routine Hook routine 을 제공을 제공

(_(_AfxCommDlgProc()AfxCommDlgProc() 를 를 m_ofnm_ofn 의 의 hook fieldhook field 에 에 set)set)

Common Dialogs (cont’d)Common Dialogs (cont’d)

Page 51: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CFileDialog::DoModal()(DLGFILE.CPP)CFileDialog::DoModal()(DLGFILE.CPP) M_bOpenFileDialogM_bOpenFileDialog 변수의 값을 보고 변수의 값을 보고 Win32 APIWin32 API 인 인

GetOpenFileName()GetOpenFileName() 을 호출할건지 을 호출할건지 GetSaveFileName()GetSaveFileName()을 호출할건지를 결정을 호출할건지를 결정

Common Dialogs (cont’d)Common Dialogs (cont’d)

Page 52: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Common Dialogs (cont’d)Common Dialogs (cont’d)int CFileDialog::DoModal(){ int nResult; BOOL bEnableParent = FALSE; m_ofn.hwndOwner = PreModal(); AfxUnhookWindowCreate(); if (m_ofn.hwndOwner != NULL && ::IsWindowEnabled(m_ofn.hwndOwner)) { bEnableParent = TRUE;

::EnableWindow(m_ofn.hwndOwner, FALSE); } if (m_bOpenFileDialog) nResult = ::GetOpenFileName(&m_ofn); else nResult = ::GetSaveFileName(&m_ofn); if (bEnableParent)

::EnableWindow(m_ofn.hwndOwner, TRUE); PostModal(); return nResult ? nResult : IDCANCEL;}

Page 53: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Property SheetsProperty Sheets Tabbed dialogsTabbed dialogs MFC 3.0 MFC 3.0 때부터 제공때부터 제공 하나의 하나의 dialog dialog 에서 사용자로부터 많은 입력을 에서 사용자로부터 많은 입력을

받을 수 있는 인터페이스받을 수 있는 인터페이스

Page 54: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Property Sheets (cont’d)Property Sheets (cont’d) 두개의 두개의 classclass

CPropertySheetCPropertySheet Tabbed dialogTabbed dialog 를 위한 를 위한 classclass

CPropertyPageCPropertyPage Tabbed dialogTabbed dialog 의 각각의 의 각각의 tab(page)tab(page) 을 위한 을 위한 classclass

일반 일반 dialogdialog 와의 차이점와의 차이점 ApplyApply 버튼 제공버튼 제공

PagePage 별로 별로 updateupdate 하는 기능을 제공하는 기능을 제공

Page 55: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Property Sheets (cont’d)Property Sheets (cont’d) STEPSTEP

1. Dialog template 1. Dialog template 생성 및 생성 및 property sheet property sheet 의 의 layout layout 설정설정

2. 2. 각 각 template template 에 대응하는 에 대응하는 CPropertyPage CPropertyPage 파생 파생 클래스들을 생성클래스들을 생성

3-1. (3-1. (modal property sheet)modal property sheet) CPropertySheetCPropertySheet 의 의 instanceinstance 를 생성하고 를 생성하고 AddPage() AddPage()

멤버 함수를 통해 추가한 뒤 멤버 함수를 통해 추가한 뒤 DoModal() DoModal() 호출호출 OK/Apply/Cancel OK/Apply/Cancel 버튼이 자동적으로 추가버튼이 자동적으로 추가

3-2. (3-2. (modeless property sheet)modeless property sheet) CPropertySheetCPropertySheet 의 파생클래스 생성한 뒤 인스턴스를 의 파생클래스 생성한 뒤 인스턴스를

생성하고 생성하고 Create() Create() 함수 호출함수 호출 OK/Apply/Cancel OK/Apply/Cancel 버튼이 자동적으로 추가되지 않음버튼이 자동적으로 추가되지 않음

Page 56: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Property Sheets (cont’d)Property Sheets (cont’d)

CPropertySheet mySheet(“My Property Sheet!”, this);CPageOne myPage1;CPageTwo myPage2;CPageThree myPage3;

mySheet.AddPage(&myPage1);mySheet.AddPage(&myPage2);mySheet.AddPage(&myPage3);

mySheet.DoModal();…

Page 57: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CPropertySheet ClassCPropertySheet Class Declaration of CPropertySheetDeclaration of CPropertySheet

AFXDLGS.HAFXDLGS.Hclass CPropertySheet : public CWnd{// Attributespublic: AFX_OLDPROPSHEETHEADER m_psh; int GetPageCount() const; CPropertyPage* GetActivePage() const; int GetActiveIndex() const; CPropertyPage* GetPage(int nPage) const; int GetPageIndex(CPropertyPage* pPage); BOOL SetActivePage(int nPage); BOOL SetActivePage(CPropertyPage* pPage); void SetTitle(LPCTSTR lpszText, UINT nStyle = 0); void EnableStackedTabs(BOOL bStacked);

Page 58: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CPropertySheet Class (cont’d)CPropertySheet Class (cont’d)// Operationspublic: virtual int DoModal(); void AddPage(CPropertyPage* pPage); void RemovePage(CPropertyPage* pPage); void RemovePage(int nPage); void EndDialog(int nEndID); // used to terminate a modal dialog BOOL PressButton(int nButton);// Implementationpublic: virtual ~CPropertySheet(); void CommonConstruct(CWnd* pParentWnd, UINT iSelectPage); virtual BOOL PreTranslateMessage(MSG* pMsg); virtual void BuildPropPageArray(); virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam); virtual BOOL OnInitDialog(); virtual BOOL ContinueModal();

Page 59: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CPropertySheet Class (cont’d)CPropertySheet Class (cont’d)protected: CPtrArray m_pages; // array of CPropertyPage pointers CString m_strCaption; // caption of the pseudo-dialog CWnd* m_pParentWnd; // parent window of property sheet BOOL m_bStacked; // EnableStackedTabs sets this BOOL m_bModeless; // TRUE when Create called instead of DoModal // Generated message map functions //{{AFX_MSG(CPropertySheet) afx_msg BOOL OnNcCreate(LPCREATESTRUCT); afx_msg LRESULT HandleInitDialog(WPARAM, LPARAM); afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); afx_msg LRESULT OnCommandHelp(WPARAM, LPARAM); afx_msg void OnClose(); afx_msg void OnSysCommand(UINT nID, LPARAM); afx_msg LRESULT OnSetDefID(WPARAM, LPARAM); //}}AFX_MSG friend class CPropertyPage;};

Page 60: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Declaration of CPropertySheetDeclaration of CPropertySheet AFXDLGS.HAFXDLGS.H CWndCWnd 에서 상속받음 에서 상속받음 ((why?)why?) 멤버 멤버

CommonConstruct()CommonConstruct() 수많은 수많은 constructorconstructor 들이 호출하는 공통 함수들이 호출하는 공통 함수

m_pagesm_pages CPtrArrayCPtrArray 형의 형의 pointerpointer 로 로 CPropertyPage classCPropertyPage class 의 의 pointerpointer

의 배열의 배열

CPropertySheet Class (cont’d)CPropertySheet Class (cont’d)

Page 61: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

m_strCaptionm_strCaption Property sheetProperty sheet 의 의 captioncaption

m_pParentWndm_pParentWnd Parent windowParent window 에 대한 에 대한 pointerpointer

m_bStackedm_bStacked TabTab 을 을 stacked modestacked mode 로 할건지 로 할건지 scrolled modescrolled mode 로 할 건지를 로 할 건지를

결정결정 m_bModelessm_bModeless

Property sheetProperty sheet 를 를 modalmodal 로 할건지 로 할건지 modelessmodeless 로 할건지로 할건지

CPropertySheet Class (cont’d)CPropertySheet Class (cont’d)

Page 62: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CPropertySheet::DoModal()CPropertySheet::DoModal() DLGPROP.CPPDLGPROP.CPP 내부 수행내부 수행

AfxDeferRegisterClass()AfxDeferRegisterClass() 호출호출 내부적으로 내부적으로 InitCommonControls()InitCommonControls() 함수 호출함수 호출 ((Windows Windows

common controls DLLcommon controls DLL 을 초기화을 초기화 )) BuildPropPageArray()BuildPropPageArray() 호출호출 Main windowMain window 를 를 disabledisable 하고 하고 ::::PropertySheet()PropertySheet() 함수를 함수를

호출 호출 (( 이후는 이후는 CDialog::DoModal()CDialog::DoModal() 과 동일과 동일 ))

CPropertySheet Class (cont’d)CPropertySheet Class (cont’d)

Page 63: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CPropertySheet::AddPage()CPropertySheet::AddPage() DLGPROP.CPPDLGPROP.CPP m_pagesm_pages 멤버 변수에 멤버 변수에 page page 추가추가

CPropertySheet::BuildPropPageArray()CPropertySheet::BuildPropPageArray() DLGPROP.CPPDLGPROP.CPP 각 각 pagepage 에 있는 에 있는 PROPSHEETPAGE structurePROPSHEETPAGE structure

정보를 저장함정보를 저장함

CPropertySheet Class (cont’d)CPropertySheet Class (cont’d)

Page 64: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CPropertySheet Class (cont’d)CPropertySheet Class (cont’d)int CPropertySheet::DoModal(){

VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTLS_REG));BuildPropPageArray();

HWND hWndParent = CWnd::GetSafeOwner_();::EnableWindow(hWndParent, FALSE);

HWND hWnd = (HWND)::PropertySheet((PROPSHEETHEADER*)psh);

nResult = RunModalLoop(dwFlags);DestroyWindow();::EnableWindow(hWndTop, TRUE);

return nResult;}

Page 65: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CPropertySheet Class (cont’d)CPropertySheet Class (cont’d)

void CPropertySheet::AddPage(CPropertyPage* pPage){ m_pages.Add(pPage); if (m_hWnd != NULL) { HPROPSHEETPAGE hPSP =

CreatePropertySheetPage((PROPSHEETPAGE*)ppsp);

if (hPSP == NULL) AfxThrowMemoryException();

if (!SendMessage(PSM_ADDPAGE, 0, (LPARAM)hPSP))

{ DestroyPropertySheetPage(hPSP); AfxThrowMemoryException();}

}}

Page 66: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CPropertySheet Class (cont’d)CPropertySheet Class (cont’d)

void CPropertySheet::BuildPropPageArray(){ delete[] (PROPSHEETPAGE*)m_psh.ppsp; m_psh.ppsp = NULL; AFX_OLDPROPSHEETPAGE* ppsp = new

AFX_OLDPROPSHEETPAGE[m_pages.GetSize()]; m_psh.ppsp = (LPPROPSHEETPAGE)ppsp; for (int i = 0; i < m_pages.GetSize(); i++) {

CPropertyPage* pPage = GetPage(i);memcpy(&ppsp[i], &pPage->m_psp, sizeof(pPage-

>m_psp));pPage->PreProcessPageTemplate

((PROPSHEETPAGE&)ppsp[i], bWizard); } m_psh.nPages = m_pages.GetSize();}

Page 67: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Control ClassesControl Classes Control classControl class 의 세가지 의 세가지 groupgroup

Old fashioned (6)Old fashioned (6) Button, combo box, edit, list box, scroll bar, staticButton, combo box, edit, list box, scroll bar, static

New fangledNew fangled Window common controlsWindow common controls

OLE controlsOLE controls

Page 68: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Old-Fashioned Old-Fashioned 특징특징

모두 모두 CWndCWnd 에서 상속받음에서 상속받음 Cbitmap, CBitmapButton, CComboBox, CEdit, Cbitmap, CBitmapButton, CComboBox, CEdit,

CListBox, CDragListBox, CCheckListBox, CListBox, CDragListBox, CCheckListBox, CScrollBar, CStaticCScrollBar, CStatic

DeclarationDeclaration 은 은 AFXWIN.HAFXWIN.H ImplementationImplementation

AFXWIN2.INLAFXWIN2.INL WINCTRL1.CPPWINCTRL1.CPP WINCTRL2.CPPWINCTRL2.CPP WINCTRL3.CPPWINCTRL3.CPP WINBTN.CPPWINBTN.CPP

Page 69: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Old-Fashioned (cont’d)Old-Fashioned (cont’d)

Cbutton* pButton = (Cbutton *)pDialog->GetDlgItem(IDC_CHECK1);ASSERT(pButton != NULL);pButton->SetCheck(m_bShowState);

////

Crect rectButton(10, 10, 50, 50);Cbutton* pButton = new Cbutton;pButton->Create(“Text”, WS_CHILD|BS_PUSHBUTTON, rectButton, pView, ID_BUTTON);…pBtton->DestroyWindow();delete pButton;

Page 70: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

New-fangledNew-fangled 특징특징

모두 모두 CWndCWnd 에서 상속받음에서 상속받음 CAnimateCtrl, CDragListBox, CHotKeyCtrl, CAnimateCtrl, CDragListBox, CHotKeyCtrl,

CImageList, CProgressCtrl, CRichEditCtrl, CImageList, CProgressCtrl, CRichEditCtrl, CSliderCtrl, CSpinButtonCtrl, …CSliderCtrl, CSpinButtonCtrl, …

DeclarationDeclaration 은 은 AFXCMN.HAFXCMN.H ImplementationImplementation

AFXCMN.INLAFXCMN.INL WINCTRL2.CPPWINCTRL2.CPP WINCTRL4.CPPWINCTRL4.CPP

Page 71: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Chap. 7Chap. 7

Document/View ArchitectureDocument/View Architecture

Page 72: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

ContentsContents IntroductionIntroduction ArchitectureArchitecture Inside document/view architectureInside document/view architecture Document/view internalsDocument/view internals

Page 73: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

IntroductionIntroduction ApplicationApplication 의 의 datadata 관리관리

DataData 를 분리하여 관리하자를 분리하여 관리하자 .. 중요한 이슈중요한 이슈

누가 누가 datadata 를 관리할 것인가를 관리할 것인가 누가 누가 datadata 를 를 updateupdate 할 것인가할 것인가 data data 의 의 rendering rendering 어떻게 다르게 할 것인가어떻게 다르게 할 것인가 ……

Print Print 와 와 print previewprint preview 의 지원의 지원 두 부분두 부분

Data managementData management User-interface managementUser-interface management

Page 74: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Introduction (cont’d)Introduction (cont’d) 기존의 방법기존의 방법

분리하지 않고 하나의 클래스에서 처리분리하지 않고 하나의 클래스에서 처리 대단히 복잡대단히 복잡

중요성중요성 Multiple ways to represent your dataMultiple ways to represent your data

Rendering & UpdatingRendering & Updating Multiple types of dataMultiple types of data

User interfaceUser interface

Page 75: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

ArchitectureArchitecture DocumentDocument 와 와 viewview

DocumentDocument ApplicationApplication 의 의 datadata 를 의미를 의미

ViewView ApplicationApplication 의 의 datadata 의 표현을 의미의 표현을 의미

Page 76: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Document/View ComponentsDocument/View Components MFC document/view architectureMFC document/view architecture 를 위한 를 위한 44

개의 개의 componentscomponents DocumentsDocuments ViewsViews Document/view framesDocument/view frames Document templatesDocument templates

Page 77: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

DocumentsDocuments CDocument classCDocument class

Managing file I/OManaging file I/O Updating renderings of the dataUpdating renderings of the data CCmdTarget(CObject)CCmdTarget(CObject) 로 부터 상속 받음로 부터 상속 받음

CObject CObject Run-time type information, dynamic creation, Run-time type information, dynamic creation, serializationserialization

CCmdTarget CCmdTarget Command message (WM_COMMAND) Command message (WM_COMMAND) 를 를 받을 수 있음받을 수 있음

Document/View Components Document/View Components (cont’d)(cont’d)

Page 78: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

ViewsViews CView classCView class

CWnd(CCmdTarget, CObject)CWnd(CCmdTarget, CObject) 로 부터 상속 받음로 부터 상속 받음 CCmdTarget CCmdTarget Command message (WM_COMMAND) Command message (WM_COMMAND) 를 를

받을 수 있음받을 수 있음 CWnd CWnd Window message(WM_PAINT) Window message(WM_PAINT) 를 받을 수 있음를 받을 수 있음

ViewView 는 는 borderborder 가 없는 가 없는 windowwindow 임임 ViewView 를 둘러싸고 있는 를 둘러싸고 있는 borderborder 있는 있는 windowwindow 를 를 frame frame

windowwindow 라고 함라고 함

Document/View Components Document/View Components (cont’d)(cont’d)

Page 79: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Document/View FramesDocument/View Frames 각각의 각각의 viewview 에 서로 다른 에 서로 다른 user-interfaceuser-interface 를 적용할 를 적용할

수 있게 함수 있게 함

View

Frame

Document/View Components Document/View Components (cont’d)(cont’d)

Page 80: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

SDI SDI CFrameWnd class CFrameWnd class Single Document InterfaceSingle Document Interface 워드패드워드패드

MDI MDI CMDIChildWnd class CMDIChildWnd class Multiple Document IntefaceMultiple Document Inteface MS WordMS Word

Document/View Components Document/View Components (cont’d)(cont’d)

Page 81: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Document templatesDocument templates CDocTemplate classCDocTemplate class Document, view, frameDocument, view, frame 을 묶어서 하나의 을 묶어서 하나의 unitunit

으로 관리으로 관리 각각의 서로 다른 각각의 서로 다른 document typedocument type 에 대하여 에 대하여

하나씩의 하나씩의 templatetemplate 을 가질 수 있다을 가질 수 있다 . . 실제 사용시실제 사용시

한 한 typetype 의 의 document document CSingleDocTemplate class CSingleDocTemplate class 여러 여러 typetype 의 의 document document CMultiDocTemplate class CMultiDocTemplate class

Document/View Components Document/View Components (cont’d)(cont’d)

Page 82: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CSingleDocTemplateCSingleDocTemplate 생성자의 인자생성자의 인자

Resource IDResource ID Documet/View/Frame Documet/View/Frame 의 의 Run-time classRun-time class

CMultiDocTemplateCMultiDocTemplate CSingleDocTemplateCSingleDocTemplate 와 생성자의 인자가 동일와 생성자의 인자가 동일 차이점 차이점 : : linked listlinked list 를 통해 다수의 정보 유지를 통해 다수의 정보 유지

Document/View Components Document/View Components (cont’d)(cont’d)

Page 83: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Resource IDResource ID application application 의 의 string tablestring table window title, document namewindow title, document name 새 새 document document 생성 시 생성 시 descriptiondescription 파일 파일 open open 시 파일 시 파일 type type 에 대한 에 대한 descriptiondescription file extension filter, …file extension filter, …

Document/View Components Document/View Components (cont’d)(cont’d)

Page 84: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CWinAppCWinApp 의 역할의 역할 CWinAppCWinApp 의 역할은의 역할은 ??

Document templateDocument template 을 관리함을 관리함 CWinApp::InitInstance()CWinApp::InitInstance() 함수함수

Document templateDocument template 을 생성함을 생성함 생성이 끝나면 생성이 끝나면 CWinApp::AddDocTemplate()CWinApp::AddDocTemplate() 호출호출

CWinAppCWinApp 의 의 document template listdocument template list 에 추가함에 추가함

Page 85: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CWinAppCWinApp 의 역할 의 역할 ((cont’d)cont’d)

BOOL CTestApp::InitInstance(){

…CMultiDocTemplate* pDocTemplate;pDocTemplate = new CMultiDocTemplate(

IDR_TESTTYPE,RUNTIME_CLASS(CTestDoc),RUNTIME_CLASS(CChildFrame), // custom MDI child

frameRUNTIME_CLASS(CTestView));

AddDocTemplate(pDocTemplate);…

}

Page 86: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Document/View Arch. InternalsDocument/View Arch. Internals Document/View arch.Document/View arch. 의 기본의 기본

CWinAppCWinApp Document templateDocument template 의 관리의 관리

Document templateDocument template Frames/Views/DocumentsFrames/Views/Documents 의 관리의 관리

Page 87: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDocManager ClassCDocManager Class CDocManagerCDocManager

CWinAppCWinApp 와 와 CDocTemplateCDocTemplate 사이의 사이의 interfaceinterface역할역할

CWinAppCWinApp 가 필요한 가 필요한 document templatedocument template 의 의 listlist를 관리하는 역할를 관리하는 역할

CWinAppCWinApp 의 의 declaration(AFXWIN.H)declaration(AFXWIN.H) CDocManager * m_pDocManager;CDocManager * m_pDocManager;

Page 88: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDocManager Class(contd.)CDocManager Class(contd.)

class CDocManager : public CObject{

DECLARE_DYNAMIC(CDocManager)CDocManager();virtual void AddDocTemplate(CDocTemplate* pTemplate);virtual POSITION GetFirstDocTemplatePosition() const;virtual CDocTemplate* GetNextDocTemplate(POSITION&

pos) const;virtual void RegisterShellFileTypes(BOOL bCompat);void UnregisterShellFileTypes();virtual CDocument* OpenDocumentFile(LPCTSTR

lpszFileName); virtual BOOL SaveAllModified(); // save before exitvirtual void CloseAllDocuments(BOOL bEndSession); virtual int GetOpenDocumentCount();CPtrList m_templateList;int GetDocumentCount();

};

Page 89: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDocManager Class(contd.)CDocManager Class(contd.) Declaration(AFXWIN.H)Declaration(AFXWIN.H)

멤버 변수멤버 변수 m_templateListm_templateList

CPtrList typeCPtrList type 실제 실제 document templatedocument template 의 의 listlist

멤버 함수멤버 함수 대부분의 함수가 대부분의 함수가 m_templateListm_templateList 에 대한 조작과 에 대한 조작과

CWinAppCWinApp 와의 와의 interfaceinterface 를 위해서 존재를 위해서 존재

Page 90: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDocManager Class(contd.)CDocManager Class(contd.) 대부분의 대부분의 CWinAppCWinApp 의 의 document templatedocument template 관련 함수는 관련 함수는

CDocManagerCDocManager 의 함수를 그대로 호출함의 함수를 그대로 호출함 CWinApp::AddDocTemplate()CWinApp::AddDocTemplate() CWinApp::CloseAllDocument()CWinApp::CloseAllDocument() CWinApp::DoPromptFileName()CWinApp::DoPromptFileName() CWinApp::GetFirstDocTemplatePosition()CWinApp::GetFirstDocTemplatePosition() CWinApp::GetNextDocTemplate()CWinApp::GetNextDocTemplate() CWinApp::GetOpenDocumentCount()CWinApp::GetOpenDocumentCount() CWinApp::OnFileNew()CWinApp::OnFileNew() CWinApp::OnFileOpen()CWinApp::OnFileOpen() ……

Page 91: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDocManager Class(contd.)CDocManager Class(contd.)

void CWinApp::AddDocTemplate(CDocTemplate* pTemplate){

if (m_pDocManager == NULL)m_pDocManager = new CDocManager;

m_pDocManager->AddDocTemplate(pTemplate);}

void CWinApp::OnFileNew(){

if (m_pDocManager != NULL)m_pDocManager->OnFileNew();

}

Page 92: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDocManager Class(contd.)CDocManager Class(contd.) CDocManager::OnFileNew()CDocManager::OnFileNew()

새로운 새로운 document templatedocument template 을 생성하는 역할을 생성하는 역할 하나 이상의 하나 이상의 document templatedocument template 가 있을때는 가 있을때는

CNewTypeDlg dialog classCNewTypeDlg dialog class 를 이용를 이용((DOCMGR.CPP)DOCMGR.CPP) 사용자가 사용자가 document templatedocument template 을 선택하게 함을 선택하게 함 사용자에게 사용자에게 document template listdocument template list 로 보여주는 좋은 로 보여주는 좋은

예가 됨예가 됨

Page 93: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDocManager Class(contd.)CDocManager Class(contd.)“DocMgr.cpp”

void CDocManager::OnFileNew(){

CDocTemplate* pTemplate=

(CDocTemplate*)m_templateList.GetHead();if (m_templateList.GetCount() > 1){

CNewTypeDlg dlg(&m_templateList);int nID = dlg.DoModal();if (nID == IDOK)

pTemplate = dlg.m_pSelectedTemplate;

elsereturn; // none - cancel operation

}pTemplate->OpenDocumentFile(NULL);

}

Page 94: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDocManager Class(contd.)CDocManager Class(contd.)

class CNewTypeDlg : public CDialog{protected:

CPtrList* m_pList; // actually a list of doc templatespublic:

CDocTemplate* m_pSelectedTemplate;enum { IDD = AFX_IDD_NEWTYPEDLG };CNewTypeDlg(CPtrList* pList) :

CDialog(CNewTypeDlg::IDD) {m_pList = pList;m_pSelectedTemplate = NULL;

}protected:

BOOL OnInitDialog();void OnOK();

};

CNewTypeDlg classCNewTypeDlg class DOCMGR.CPPDOCMGR.CPP

Page 95: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDocManager Class(contd.)CDocManager Class(contd.) CNewTypeDlg resourceCNewTypeDlg resource

AFXRES.RCAFXRES.RC

Page 96: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDocManager Class(contd.)CDocManager Class(contd.)

BOOL CNewTypeDlg::OnInitDialog(){ CListBox* pListBox = (CListBox*)GetDlgItem(AFX_IDC_LISTBOX); POSITION pos = m_pList->GetHeadPosition(); while (pos != NULL) { CDocTemplate* pTemplate =

(CDocTemplate*)m_pList->GetNext(pos); CString strTypeName; if (pTemplate->GetDocString(strTypeName,

CDocTemplate::fileNewName) && !strTypeName.IsEmpty()) {

int nIndex = pListBox->AddString(strTypeName);

pListBox->SetItemDataPtr(nIndex, pTemplate);

} } return CDialog::OnInitDialog();}

Page 97: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDocTemplate classCDocTemplate class CDocTemplateCDocTemplate

Document/View/FrameDocument/View/Frame 을 관리을 관리 Base classBase class 실제 사용시에는실제 사용시에는

CSingleDocTemplateCSingleDocTemplate DOCSINGL.CPPDOCSINGL.CPP

CMultiDocTemplateCMultiDocTemplate DOCMULTI.CPPDOCMULTI.CPP

Page 98: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDocTemplate class(contd.)CDocTemplate class(contd.) Declaration(AFXWIN.H)Declaration(AFXWIN.H)

class CDocTemplate : public CCmdTarget{ DECLARE_DYNAMIC(CDocTemplate)protected: CDocTemplate(UINT nIDResource, CRuntimeClass* pDocClass,

CRuntimeClass* pFrameClass, CRuntimeClass* pViewClass);// Attributespublic: virtual POSITION GetFirstDocPosition() const = 0; virtual CDocument* GetNextDoc(POSITION& rPos) const = 0; virtual void AddDocument(CDocument* pDoc); // must override virtual void RemoveDocument(CDocument* pDoc); // must override virtual BOOL GetDocString(CString& rString, enum DocStringIndex index) const; // get one of the info strings CFrameWnd* CreateOleFrame(CWnd* pParentWnd,

CDocument* pDoc, BOOL bCreateView); virtual CDocument* CreateNewDocument(); virtual CFrameWnd* CreateNewFrame(CDocument* pDoc,

CFrameWnd* pOther);

Page 99: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDocTemplate class(contd.)CDocTemplate class(contd.) virtual void InitialUpdateFrame(CFrameWnd* pFrame, CDocument* pDoc,

BOOL bMakeVisible = TRUE); virtual BOOL SaveAllModified(); // for all documents virtual void CloseAllDocuments(BOOL bEndSession); virtual CDocument* OpenDocumentFile(

LPCTSTR lpszPathName, BOOL bMakeVisible = TRUE) = 0; virtual void SetDefaultTitle(CDocument* pDocument) = 0;public: BOOL m_bAutoDelete; virtual ~CDocTemplate();protected: UINT m_nIDResource; CRuntimeClass* m_pDocClass; // class for creating new documents CRuntimeClass* m_pFrameClass; // class for creating new frames CRuntimeClass* m_pViewClass; // class for creating new views CString m_strDocStrings; // '\n' separated names};

Page 100: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDocTemplate class(contd.)CDocTemplate class(contd.) Declaration(AFXWIN.H)Declaration(AFXWIN.H)

멤버 변수멤버 변수 m_nIDResourcem_nIDResource

Document templateDocument template 에 대한 에 대한 resource IDresource ID m_pDocClassm_pDocClass

CDocumentCDocument 에 대한 에 대한 CRuntimeClass structureCRuntimeClass structure 의 의 pointerpointer m_pFrameClassm_pFrameClass

CFrameWndCFrameWnd 에 대한 에 대한 CRuntimeClass structureCRuntimeClass structure 의 의 pointerpointer

Page 101: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDocTemplate class(contd.)CDocTemplate class(contd.) m_pViewClassm_pViewClass

CViewCView 에 대한 에 대한 CRuntimeClass structureCRuntimeClass structure 의 의 pointerpointer m_strDocStringsm_strDocStrings

Document templateDocument template 의 의 string resourcestring resource

Implementation(DOCTEMPL.CPP)Implementation(DOCTEMPL.CPP) Document/View/FrameDocument/View/Frame 을 생성하는 함수을 생성하는 함수

CDocTemplate::CreateNewDocument()CDocTemplate::CreateNewDocument() CDocTemplate::CreateNewFrame()CDocTemplate::CreateNewFrame() ViewView 에 관한 명시적인 함수는 없음에 관한 명시적인 함수는 없음

Page 102: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDocTemplate class(contd.)CDocTemplate class(contd.)CDocument* CDocTemplate::CreateNewDocument(){

CDocument* pDocument = (CDocument*)m_pDocClass->CreateObject();

AddDocument(pDocument);return pDocument;

}

Page 103: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDocTemplate class(contd.)CDocTemplate class(contd.)CFrameWnd* CDocTemplate::CreateNewFrame(CDocument* pDoc, CFrameWnd* pOther){

CCreateContext context;context.m_pCurrentFrame = pOther;context.m_pCurrentDoc = pDoc;context.m_pNewViewClass = m_pViewClass;context.m_pNewDocTemplate = this;CFrameWnd* pFrame =

(CFrameWnd*)m_pFrameClass->CreateObject();pFrame->LoadFrame(m_nIDResource,

WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL, &context))

return pFrame;}

Page 104: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDocTemplate class(contd.)CDocTemplate class(contd.) CDocTemplate::CreateNewDocument()CDocTemplate::CreateNewDocument()

m_pDocClass->CreateObject()m_pDocClass->CreateObject() 를 이용해 를 이용해 documentdocument생성생성

생성된 생성된 documentdocument 를 를 openopen 된 된 document listdocument list 에 추가에 추가

CDocTemplate::CreateNewFrame()CDocTemplate::CreateNewFrame() CCreateContextCCreateContext 에 필요한 정보를 채움에 필요한 정보를 채움 m_pFrameClass->CreateObject()m_pFrameClass->CreateObject() 를 이용해 를 이용해 frameframe 생성생성 FrameFrame 에 필요한 에 필요한 resourceresource 를 를 loadload

Page 105: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDocTemplate class(contd.)CDocTemplate class(contd.) CCreateContext structureCCreateContext structure

Declaration(AFXEXT.H)Declaration(AFXEXT.H)

struct CCreateContext // Creation information structure// All fields are optional and may be NULL

{CRuntimeClass* m_pNewViewClass; CDocument* m_pCurrentDoc;// for creating MDI children

(CMDIChildWnd::LoadFrame)CDocTemplate* m_pNewDocTemplate;// for sharing view/frame state from the original

view/frameCView* m_pLastView;CFrameWnd* m_pCurrentFrame;

// ImplementationCCreateContext();

};

Page 106: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDocTemplate class(contd.)CDocTemplate class(contd.) CCreateContext structureCCreateContext structure

Declaration(AFXEXT.H)Declaration(AFXEXT.H) m_pNewViewClass m_pNewViewClass View View 생성을 위한 생성을 위한 CRuntimeClass CRuntimeClass

pointerpointer m_pCurrentDoc m_pCurrentDoc Current document Current document m_pCurrentFrame m_pCurrentFrame Current frame Current frame m_pNewDocTemplate m_pNewDocTemplate Multiple document Multiple document 일 때 마지막 일 때 마지막

documentdocument 를 가리킴를 가리킴 m_pLastView m_pLastView Multiple view Multiple view 일 때 마지막 일 때 마지막 viewview 를 가리킴를 가리킴

Page 107: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDocTemplate class(contd.)CDocTemplate class(contd.) OpenOpen 된 된 documentdocument 의 관리는의 관리는 ??

CSingleDocTemplateCSingleDocTemplate 와 와 CMultiDocTemplateCMultiDocTemplate 가 가 담당담당

CSingleDocTemplateCSingleDocTemplate CDocument* m_pOnlyDoc;CDocument* m_pOnlyDoc;

CMultiDocTemplateCMultiDocTemplate CPtrList m_docList;CPtrList m_docList; int m_nUntitledCount; int m_nUntitledCount; Untitled document Untitled document 의 의

수를 저장함수를 저장함 ((Untitled[X])Untitled[X])

Page 108: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDocTemplate class(contd.)CDocTemplate class(contd.) CMultiDocTemplate::OpenDocumentFile()CMultiDocTemplate::OpenDocumentFile()

DOCMULTI.CPPDOCMULTI.CPP DocumentDocument 와 와 frameframe 의 생성의 생성 CFrameWnd::InitialUpdateFrame()CFrameWnd::InitialUpdateFrame() 호출호출

Page 109: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDocTemplate class(contd.)CDocTemplate class(contd.)“DocMulti.cpp”CDocument* CMultiDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName,

BOOL bMakeVisible){

CDocument* pDocument = CreateNewDocument();CFrameWnd* pFrame = CreateNewFrame(pDocument,

NULL);if (lpszPathName == NULL) {

// create a new document - with default document name

SetDefaultTitle(pDocument);pDocument->OnNewDocument();

} else {// open an existing documentCWaitCursor wait;pDocument->OnOpenDocument(lpszPathName);pDocument->SetPathName(lpszPathName);

}return pDocument;

}

Page 110: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CFrameWnd classCFrameWnd class CFrameWndCFrameWnd

CViewCView 의 생성의 생성 !! m_pViewActivem_pViewActive

현재 현재 atciveatcive 한 한 viewview 에 대한 에 대한 pointerpointer CFrameWnd::GetActiveView()CFrameWnd::GetActiveView() CFrameWnd::SetActiveView()CFrameWnd::SetActiveView()

InitialUpdateFrame()InitialUpdateFrame() 함수함수 모든 모든 viewview 의 의 OnInitialUpdate()OnInitialUpdate() 함수를 호출함함수를 호출함

Page 111: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CFrameWnd class(contd.)CFrameWnd class(contd.)

Implementation(WINFRM.CPP)Implementation(WINFRM.CPP) CFrameWnd::CreateView()CFrameWnd::CreateView()

진정한 진정한 viewview 의 생성의 생성

CWnd* CFrameWnd::CreateView(CCreateContext* pContext, UINT nID){

CWnd* pView = (CWnd*)pContext->m_pNewViewClass

->CreateObject();if (pView == NULL)

return NULL;if (!pView->Create(NULL, NULL,

AFX_WS_DEFAULT_VIEW,CRect(0,0,0,0), this, nID, pContext))return NULL; // can't continue without a

viewreturn pView;

}

Page 112: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CFrameWnd class(contd.)CFrameWnd class(contd.) 그러면 그러면 CreateView()CreateView() 는 어디서 호출되나는 어디서 호출되나 ??

int CFrameWnd::OnCreate(LPCREATESTRUCT lpcs){

return OnCreateHelper(lpcs, pContext);}

int CFrameWnd::OnCreateHelper(LPCREATESTRUCT lpcs, CCreateContext* pContext){

if (CWnd::OnCreate(lpcs) == -1)return -1;

// create special children firstOnCreateClient(lpcs, pContext);

}

Page 113: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CFrameWnd class(contd.)CFrameWnd class(contd.)

BOOL CFrameWnd::OnCreateClient(LPCREATESTRUCT, CCreateContext* pContext){

if (pContext != NULL && pContext->m_pNewViewClass != NULL)

{CreateView(pContext,

AFX_IDW_PANE_FIRST);}

}

Page 114: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CFrameWnd class(contd.)CFrameWnd class(contd.) CreateNewFrame()CreateNewFrame() 이 호출되면이 호출되면

WindowsWindows 가 가 WM_CREATE messageWM_CREATE message 를 보냄를 보냄 OnCreate()OnCreate() 함수의 호출함수의 호출 OnCreateHelper()OnCreateHelper() 의 호출의 호출 OnCreateClient()OnCreateClient() 의 호출의 호출 CreateView()CreateView() 의 호출의 호출

결국 결국 CreateNewFrame()CreateNewFrame() 의 호출 결과임의 호출 결과임

Page 115: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CFrameWnd class(contd.)CFrameWnd class(contd.) CFrameWnd::InitialUpdateFrame()CFrameWnd::InitialUpdateFrame()

FrameFrame 의 모든 의 모든 viewview 를 를 updateupdate 함함void CFrameWnd::InitialUpdateFrame(CDocument* pDoc, BOOL bMakeVisible){ CView* pView = NULL; if (bMakeVisible) {

SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE);

ActivateFrame(nCmdShow);if (pView != NULL)

pView->OnActivateView(TRUE, pView, pView); } // update frame counts and frame title (may already have been visible) if (pDoc != NULL) pDoc->UpdateFrameCounts(); OnUpdateFrameTitle(TRUE);}

Page 116: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDocument ClassCDocument Class CDocumentCDocument

Declaration(AFXWIN.H)Declaration(AFXWIN.H)class CDocument : public CCmdTarget{public:

const CString& GetTitle() const;virtual void SetTitle(LPCTSTR lpszTitle);const CString& GetPathName() const;virtual void SetPathName(LPCTSTR lpszPathName,

BOOL bAddToMRU = TRUE);virtual BOOL IsModified();virtual void SetModifiedFlag(BOOL bModified = TRUE);virtual POSITION GetFirstViewPosition() const;virtual CView* GetNextView(POSITION& rPosition) const;void UpdateAllViews(CView* pSender, LPARAM lHint = 0L,

CObject* pHint = NULL);virtual void DeleteContents(); // delete doc items etc

Page 117: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDocument Class (cont’d)CDocument Class (cont’d) // File helpers virtual BOOL OnNewDocument(); virtual BOOL OnOpenDocument(LPCTSTR lpszPathName); virtual CFile* GetFile(LPCTSTR lpszFileName, UINT nOpenFlags, …); virtual void ReleaseFile(CFile* pFile, BOOL bAbort);protected: CString m_strTitle; CString m_strPathName; CDocTemplate* m_pDocTemplate; CPtrList m_viewList; // list of views BOOL m_bModified; // changed since last saved virtual BOOL DoSave(LPCTSTR lpszPathName, BOOL bReplace = TRUE); virtual BOOL DoFileSave(); virtual void UpdateFrameCounts(); void DisconnectViews(); void SendInitialUpdate(); friend class CDocTemplate;};

Page 118: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Implementation(DOCCORE.CPP)Implementation(DOCCORE.CPP) Key aspectsKey aspects

Creating documentsCreating documents Saving documentsSaving documents Communicating with viewsCommunicating with views

CDocument Class (cont’d)CDocument Class (cont’d)

Page 119: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Creating DocumentsCreating Documents Empty documentEmpty document 일 경우일 경우

OnNewDocument()OnNewDocument() 함수 호출함수 호출 DeleteContents()DeleteContents() 호출호출 Modified flagModified flag 를 를 FALSEFALSE 로 함로 함 m_strPathNamem_strPathName 이 이 NULLNULL 인지 확인인지 확인

FileFile 로 부터 로 부터 createcreate 하는 경우하는 경우 OnOpenDocument()OnOpenDocument() 함수 호출함수 호출

GetFile()GetFile() 함수를 이용하여 함수를 이용하여 file openfile open DeleteContents()DeleteContents() 함수 호출함수 호출 Modified flagModified flag 를 를 TRUETRUE 로 함로 함 CArchive classCArchive class 를 이용하여 를 이용하여 serializationserialization Modified flagModified flag 를 를 FALSEFALSE 로 함로 함

CDocument Class (cont’d)CDocument Class (cont’d)

Page 120: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDocument Class (cont’d)CDocument Class (cont’d)BOOL CDocument::OnNewDocument(){

if (IsModified())TRACE0("Warning: OnNewDocument replaces an

unsaved document.\n");

DeleteContents();m_strPathName.Empty(); // no path name yetSetModifiedFlag(FALSE); // make clean

return TRUE;}

Page 121: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDocument Class (cont’d)CDocument Class (cont’d)BOOL CDocument::OnOpenDocument(LPCTSTR lpszPathName){ CFileException fe; CFile* pFile = GetFile(lpszPathName,

CFile::modeRead|CFile::shareDenyWrite, &fe); DeleteContents(); SetModifiedFlag(); // dirty during de-serialize CArchive loadArchive(pFile, CArchive::load | CArchive::bNoFlushOnDelete); loadArchive.m_pDocument = this; loadArchive.m_bForceFlat = FALSE; CWaitCursor wait; if (pFile->GetLength() != 0) Serialize(loadArchive); // load me loadArchive.Close(); ReleaseFile(pFile, FALSE); SetModifiedFlag(FALSE); // start off with unmodified return TRUE;}

Page 122: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDocument Class (cont’d)CDocument Class (cont’d) Saving DocumentsSaving Documents

OnSaveDocument()OnSaveDocument() GetFile()GetFile() 함수를 이용하여 함수를 이용하여 file openfile open CArchive classCArchive class 를 이용하여 를 이용하여 serializationserialization Modified flagModified flag 를 를 FALSEFALSE 로 함로 함

Page 123: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDocument Class (cont’d)CDocument Class (cont’d)BOOL CDocument::OnSaveDocument(LPCTSTR lpszPathName){ CFileException fe; CFile* pFile = NULL; pFile = GetFile(lpszPathName, CFile::modeCreate |

CFile::modeReadWrite | CFile::shareExclusive, &fe); CArchive saveArchive(pFile, CArchive::store | CArchive::bNoFlushOnDelete); saveArchive.m_pDocument = this; saveArchive.m_bForceFlat = FALSE; CWaitCursor wait; Serialize(saveArchive); // save me saveArchive.Close(); ReleaseFile(pFile, FALSE); SetModifiedFlag(FALSE); // back to unmodified return TRUE; // success}

Page 124: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

ViewView 와의 통신와의 통신 m_viewListm_viewList 에 에 viewview 의 의 listlist 를 저장를 저장 통신이 필요한 경우통신이 필요한 경우

DestroyDestroy 시시 DisconnectViews()DisconnectViews() 함수를 호출하여 각 함수를 호출하여 각 viweviwe 의 의

m_pDocumentm_pDocument 가 가 NULLNULL 이 되게 함이 되게 함 FrameFrame 에 접근하고자 할 때에 접근하고자 할 때

Cview::GetParentFrame()Cview::GetParentFrame() 함수 이용함수 이용 ViewView 들에게 들에게 documentdocument 의 변경을 알리고자 할 때의 변경을 알리고자 할 때

UpdateAllViews()UpdateAllViews() 함수 호출함수 호출

CDocument Class (cont’d)CDocument Class (cont’d)

Page 125: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CDocument Class (cont’d)CDocument Class (cont’d)void CDocument::UpdateAllViews(CView* pSender, LPARAM lHint, CObject* pHint)

// walk through all views{

ASSERT(pSender == NULL || !m_viewList.IsEmpty());// must have views if sent by one of them

POSITION pos = GetFirstViewPosition();while (pos != NULL){

CView* pView = GetNextView(pos);ASSERT_VALID(pView);if (pView != pSender)

pView->OnUpdate(pSender, lHint, pHint);}

}

Page 126: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

CView ClassCView Class CViewCView

Declaration(AFXWIN.H)Declaration(AFXWIN.H) Implementation(VIEWCORE.CPP)Implementation(VIEWCORE.CPP)

void CView::OnPaint(){

// standard paint routineCPaintDC dc(this);OnPrepareDC(&dc);OnDraw(&dc);

}

Page 127: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Document/View InternalsDocument/View Internals

CWinApp::OnFileOpen() CWinApp::OnFileNew()

CDocManager::OnFileOpen() CDocManager::OnFileNew()

CDocTemplate::OpenDocumentFile()

CDocTemplate::CreateNewDocument()

CDocTemplate::CreateNewFrame()

WM_CREATE

Page 128: Chap. 6 Dialog and Control Classes. Contents  CDialog class  Common Dialogs  Property Sheets  Control classes

Document/View…(contd.)Document/View…(contd.)

WM_CREATE

CFrameWnd::OnCreate()

CFrameWnd::OnCreateHelper()

CFrameWnd::OnCreateClient()

CFrameWnd::CreateView()

CMyDocument::OnOpenDocument()

CMyDocument::OnNewDocument()