1 / 128

Chapter 06 MFC Dialog 와 Control Class

Chapter 06 MFC Dialog 와 Control Class. Contents. CDialog class Common Dialogs Property Sheets Control classes. CDialog Class. Dialog 의 종류 Modal dialog Close 될 때 까지 다른 부분을 사용할 수 없음 DoModal() 함수를 이용 예 : common dialog box Modeless dialog Close 되기 전에 다른 부분을 사용할 수 있음 Create() 함수를 이용

adie
Download Presentation

Chapter 06 MFC Dialog 와 Control Class

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Chapter06 MFC Dialog 와 Control Class

  2. Contents • CDialog class • Common Dialogs • Property Sheets • Control classes

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

  4. CDialog Class (cont’d) • History • MFC 1.0 • Modal dialog : CModalDialog • Modeless dialog : CDialog • Current version • Modal dialog : CDialog • Modeless dialog : Cdialog • AFXWIN.H // all CModalDialog functionality is now in CDialog #define CModalDialog CDialog

  5. 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 something m_pDlgMyDlgPtr->DestroyWindow(); m_pDlgMyDlgPtr = NULL;

  6. Win32 APIs • Dialog생성을 위한 Win32 APIs • CreateDialog() • Modeless dialog생성, template resource이용 • CreateDialogIndirect() • Modeless dialog생성, template pointer이용 •  Modal()/Modaless를 만들때 모두 사용되는 함수 • DialogBox() • Modal dialog생성, template resource이용 • DialogBoxIndirect() • Modal dialog생성, template pointer이용

  7. Win32 APIs (cont’d) • CDialog Class • 오직 CreateDialogIndirect() API을 이용 • Modality를 내부적으로 구현 • AFXWIN.H • DLGCORE.CPP, AFXWIN2.INL

  8. CDialog class 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 construct public: 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); // Operations public: // modal processing virtual int DoModal();

  9. 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(); // Implementation public: virtual ~CDialog(); virtual BOOL PreTranslateMessage(MSG* pMsg); virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo); virtual BOOL CheckAutoCenter();

  10. CDialog (cont’d) 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() };

  11. CDialog (cont’d) • Declaration(AFXWIN.H) • 멤버 변수 • m_nIDHelp • Button을 위한 help ID • m_lpszTemplateName • Resource template의 이름 • m_hDialogTemplate • 일단 load된 후의 resource template의 handle • m_lpDialogInit • 초기화에 관련된 data에 대한 pointer

  12. CDialog (cont’d) • m_pParentWnd • Parent window에 대한 pointer • m_hWndTop • Top-level parent window • m_pOccDialogInfo • OLE controls을 위한 stored information • 멤버 함수 • virtual PreTranslateMessage() • 특별한 message(tool tips, context-sensitive help)에 대한 filtering

  13. CDialog (cont’d) • virtual OnCmdMsg() • Command message처리작업 • virtual CheckAutoCenter() • Auto-center옵션이 체크되었는지 확인 • virtual SetOccDialogInfo() • M_pOccDialogInfo변수에 데이터를 setting • virtual PreInitDialog() • WM_INITDIALOG message이전에 불리워지는 함수 • PreModal() • DoModal()함수 실행을 위한 준비작업 • PostModal() • DoModal()함수가 끝난후의 뒤처리

  14. Modal Dialog Creation • 일반적으로 두가지의 과정을 거침 • CDialog construction • DoModal()함수의 호출 • CDialog construction • DLGCORE.CPP에 있음 • 두가지 버전이 있으며 CDialog class의 필요한 변수에 값을 입력하는 역할을 함

  15. 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; }

  16. 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;

  17. 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 loop DWORD dwFlags = MLF_SHOWONIDLE; if (GetStyle() & DS_NOIDLEMSG) dwFlags |= MLF_NOIDLEMSG; VERIFY(RunModalLoop(dwFlags) == m_nModalResult); }  CWnd Run함수를 대치한다.

  18. 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(); }

  19. 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 themselves CWinApp* pApp = AfxGetApp(); if (pApp != NULL) pApp->EnableModeless(FALSE); // find parent HWND HWND hWnd = CWnd::GetSafeOwner_ (m_pParentWnd->GetSafeHwnd(), &m_hWndTop); // hook for creation of dialog AfxHookWindowCreate(this); // return window to use as parent for dialog return hWnd; 부모 핸들 }

  20. Modal Dialog Creation (cont’d) int CWnd::RunModalLoop(DWORD dwFlags)  CWnd Run함수를 대치한다. {  CWnd에 존재한다.(다이얼로그 이외의 다른 클레스에서도 사용된다는 의미) 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)); } }

  21. Modal Dialog Creation (cont’d) • DoModal()(DLGCORE.CPP) • Dialog resource의 loading • Dialog template name을 가지고 dialog template을 찾아서 load함 • Dialog를 생성하기 위한 준비 • PreModal()함수를 호출함 • Safety checks • Parent window handle을 찾음 • m_hWndTop에 저장 • EnableWindow(FALSE)를 호출 • Parent window를 disable시킴

  22. Modal Dialog Creation (cont’d) • Dialog를 생성하고 보여줌 • CWnd::CreateDlgIndirect()함수 호출 • 내부적으로 Win32API인 CreateDialogIndirect()를 호출 • CWnd::RunModalLoop()함수 호출 • Dialog가 끝날때 까지 일을 수행 • 사용자가 ok나 cancel버튼을 누르면 CWnd::EndModalLoop()함수가 호출됨 • Dialog를 화면에서 보이지 않게 함 • Dialog가 종료하면 EnableWindow(TRUE)를 호출 • Parent window를 enable시킴 • 마지막 단계 • DestroyWindow()함수 호출 • PostModal()함수 호출

  23. Modeless Dialog Creation • Modeless dialog creation • 두가지 과정을 거침 • New operator를 사용하여 변수 생성 힙메모리에 변수 생성 • CDialog::Create()함수 호출

  24. 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 soon return 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; }

  25. 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); }

  26. Modeless Dialog Creation (cont’d) • CDialog::Create()(DLGCORE.CPP) • Template name과 help ID를 내부 변수에 저장 • Dialog resource를 찾고 load함 • CDialog::CreateIndirect()함수 호출 • 내부적으로 Win32 API인 CreateDialogIndirect()함수 호출 • 사용자가 ok나 cancel버튼을 누르면 EndDialog()가 호출되어 dialog가 사라짐

  27. Dialog Terminator void CDialog::EndDialog(int nResult) { ASSERT(::IsWindow(m_hWnd)); if (m_nFlags & (WF_MODALLOOP|WF_CONTINUEMODAL)) EndModalLoop(nResult); ::EndDialog(m_hWnd, nResult); }

  28. CDialog Control Initialization • Dialog에 있는 control의 초기화 작업 • Resource에 의한 초기화 • Combo box를 예로 살펴봄 • Data는 “one”, “two”, “three”라 가정 • 다음과 같은 코드가 생성되지 않는다. m_pCombo->AddString(“one”); m_pCombo->AddString(“two”); m_pCombo->AddString(“three”);

  29. CDialog Control Initialization (cont’d) • WM_INITDIALOG • Dialog가 화면에 보이기 전에 발생하는 message • Application으로 하여금 dialog에 있는 control들을 초기화 할 수 있도록 함 • CDialog::HandleInitDialog()함수에 mapping되어 있음 • CDialog::HandleInitDialog() • OLE control 관련 초기화 작업을 하고 CDialog::OnInitDialog()를 호출 • CDialog::OnInitDialog() • CWnd::ExecuteDlgInit()를 호출

  30. CDialog Control Initialization (cont’d) • Resource file 예제를 쎃넣을 경우 다음과 같은 내용이 첨부된다. IDD_ABOUTBOX DLGINIT BEGIN IDC_COMBO1, 0x403, 4, 0 0x6e6f, 0x0065, IDC_COMBO1, 0x403, 4, 0 0x7774, 0x006f, IDC_COMBO1, 0x403, 6, 0 0x6874, 0x6572, 0x0065, 0 END

  31. CDialog Control Initialization (cont’d) • CWnd::ExecuteDlgInit()(WINCORE.CPP) • 두가지 버전이 존재 • Argument로 dialog template name • Argument로 dialog data에 대한 pointer • 일단 첫번째 버전의 함수가 dialog template name을 가지고 resource 파일에서 control의 data를 load함 • 이 후 pointer를 얻어서 두번째 버전의 함수를 호출 • why CWnd class member function?

  32. CDialog Control Initialization (cont’d) • CWnd::ExecuteDlgInit(LPVOID) • Resource file의 raw data(DLGINIT)를 parsing함 리소스파일의 시작주소 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)++;  AddString등의 동일한 작업을 할수 있게 if문 작성됨 if (nMsg == LB_ADDSTRING || nMsg == CB_ADDSTRING) { if (::SendDlgItemMessageA(m_hWnd, nIDC, nMsg, 0, (LONG)lpnRes) == -1) bSuccess = FALSE; } } return bSuccess; }

  33. DDX/DDV • DDX/DDV • DDX(Dynamic Data eXchange) • DDV(Dynamic Data Validation) • Data members  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); }

  34. DDX/DDV (cont’d) • Question • CDataExchange class의 역할 • Control들과 멤버 변수들간의 정보 교환은 언제, 어디에서, 어떻게 이루어지는가 • DDX/DDV 함수는 무슨 일들을 하는가

  35. DDX/DDV (cont’d) • Helper class • CDataExchange(AFXWIN.H) class CDataExchange { // Attributes public: 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 };

  36. DDX/DDV (cont’d) • 멤버 변수 • m_bSaveAndValidate • TRUE  data가 control에서 변수로 감 • FALSE  data가 변수에서 control로 감 • Validation은 TRUE일때만 일어남 • m_pDlgWnd • Dialog에 대한 CWnd pointer • m_hWndLastControl • Previous control에 대한 handle을 저장 • m_bEditLastControl • Previous control이 수정되었는지를 저장

  37. DDX/DDV (cont’d) • 멤버 함수 • Constructor • PrepareCtrl() • Non-edit control을 위한 준비 • PrepareEditCtrl() • Edit control을 위한 준비 • Fail() • Validation이 실패하면 호출됨 • Focus를 previous control로 보내고 CUserException예외를 발생시킴 • PrepareOleCtrl() • OLE control을 위한 준비

  38. DDX/DDV (cont’d) • 특징 • DDX/DDV는 Serialize과정과 유사 • CDataExchange 는 CArchive 와 비슷 • DoDataExchange()는 Serialize() 와 비슷 • Save/load tag를 가짐

  39. DDX/DDV (cont’d) • DDX/DDV 함수들 • DDX_Text()(DLGDATA.CPP) • m_bSaveAndValidate의 값을 기준으로 data이동 • DDV_MaxChars()(DLGDATA.CPP) • m_bSaveAndValidate값이 TRUE인경우 validation코드 수행 • DDX_TextWithFormat()(DLGDATA.CPP) • String과 int사이의 conversion

  40. 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); 맴버변수에서 컨트롤로(FALSE) } }

  41. DDX/DDV (cont’d) void AFXAPI DDV_MaxChars(CDataExchange* pDX, CString const& value, int nChars)  예)범위에 맞는지 틀린지 check { 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 prep pDX->Fail(); } else if (pDX->m_hWndLastControl != NULL && pDX->m_bEditLastControl) { // limit the control max-chars automatically ::SendMessage(pDX->m_hWndLastControl, EM_LIMITTEXT, nChars, 0); } }

  42. DDX/DDV (cont’d) • 언제 DoDataExchange()가 호출되는가? • 필요할 때 마다 UpdateData()함수 호출 • 위 함수 내부에서 DoDataExchange()를 호출함 • UpdateData()(WINCORE.CPP)

  43. 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 recurse pThreadState->m_hLockoutNotifyWindow = m_hWnd; BOOL bOK = FALSE; // assume failure TRY { DoDataExchange(&dx); bOK = TRUE; // it worked } CATCH(CUserException, e) { // validation failed - user already alerted, fall through ASSERT(!bOK); } }

  44. 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 item return; } 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 }

  45. Common Dialogs • Common Dialogs • 표준 interface제공을 위하여 • 종류 • CColorDialog • CFileDialog • CFindReplaceDialog • CFontDialog • CPrintDialog • CPageSetupDialog ( MFC 4.0 )

  46. Common Dialogs (cont’d) • Steps • 생성자 호출 • DoModal() 호출 • IDOK가 리턴될 때 적절한 처리 CFileDialog myDialog(TRUE, NULL, NULL, OFN_FILEMUSTEXIST); if ( myDialog.DoModal() == IDOK ) { Cstring strPath = myDialog.GetPathName(); CString strFile = myDialog.GetFileName(); } else // User selected Cancel …

  47. Common Dialogs (cont’d) • Win32 API 관점에서 • 모든 common dialog는 • 대응되는 structure를 가지고 있다. • 대응되는 API를 가지고 있다. • 예) Open File common dialog • Structure – OPENFILENAME • API – GetOpenFileName(LP OPENFILENAME) • 모든 common dialog의 base class • CCommonDialog(AFXDLGS.H) • OnOK()와 OnCancel() 추가

  48. Common Dialogs (cont’d) • 예제 dialog • CFileDialog(AFXDLGS.H) class CFileDialog : public CCommonDialog { public: OPENFILENAME m_ofn; // open file parameter block virtual int DoModal(); CString GetPathName() const; // return full path and filename CString GetFileName() const; // return only filename CString GetFileExt() const; // return only ext CString GetFileTitle() const; // return file title BOOL GetReadOnlyPref() const; // return TRUE if readonly checked // Enumerating multiple file selections POSITION GetStartPosition() const; CString GetNextPathName(POSITION& pos) const;

  49. 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); };

  50. Common Dialogs (cont’d) • 예제 dialog • CFileDialog(AFXDLGS.H) • OPENFILENAME structure • 여러 개의 virtual protected 함수 • 기타 여러 정보 저장을 위한 변수 • CFileDialog의 생성(DLGFILE.CPP) • 생성자의 argument들을 OPENFILENAME structure의 멤버에 setting함(m_ofn) • Window95이상일 경우에는 OFN_EXPLORER와 OFN_ENABLEHOOK flag를 set함 • OFN_ENABLEHOOK  Hook routine을 제공(_AfxCommDlgProc()를 m_ofn의 hook field에 set)

More Related