Overview 대화상자 대화상자, 대화상자템플렛, 대화상자편집기 모드형대화상자와비모드형대화상자의차이 대화상자기반응용프로그램 HCI Programming 2 (321190) 2007 년가을학기 11/19/2007 박경신 2 대화상자 대화상자 (Dialog Box) 다양한컨트롤을포함하고있는일종의윈도우 사용자로부터입력을받거나정보를출력 정적, 버튼, 편집등다양한컨트롤들을배치하고관리하는윈도우 대화상자종류 대화상자종류 윈도우스타일 Overlapped, Pop-up, Child 동작방식 모드형대화상자 (Modal Dialog Box) 대화상자를닫지않으면응용프로그램이더이상진행할수없다. 비모드형대화상자 (Modeless Dialog Box) - 대화상자를닫지않더라도응용프로그램이계속진행할수있다. 메시지박스, 윈도우 (Window Common Dialog Box) 3 4
Controls 표준화된형태와특성을가진윈도우 사용자에게입력을받거나정보를보여주는기능 다양한종류의컨트롤 Controls 표준컨트롤클래스 5 통지메시지 (Notification Message) 컨트롤에발생한이벤트를부모윈도우로전달하는메시지 컨트롤의상태가변화되었음을알려주는메시지 종류 버튼컨트롤 : BN_CLICKED, BN_DBLCLK 편집컨트롤 : EN_CHANGE, EN_SETFOCUS, EN_KILLFOCUS 콤보박스컨트롤 : CBN_SELCHANGE 리스트박스컨트롤 : LBN_SELCHANGE 6 대화상자템플릿 대화상자템플릿 (Dialog Box Template) 대화상자자체와포함된컨트롤에대한모든정보를가지고있는이진 (Binary) 데이터 리소스로실행파일에포함 대화상자템플릿작성 비주얼 C++ 리소스편집기나텍스트편집기를이용하여리소스스크립트 (*.RC) 작성 리소스컴파일러로이진파일 (*.RES) 파일생성 링크과정에서실행파일에포함 대화상자템플릿 리소스스크립트작성 7 8
대화상자템플릿 리소스스크립트 대화상자편집기 컨트롤추가와삭제 컨트롤 (Controls) 툴바이용 IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 187, 98 STYLE DS_MODALFRAME WS_POPUP WS_CAPTION WS_SYSMENU CAPTION "Dialog" FONT 10, "System" BEGIN DEFPUSHBUTTON "OK",IDOK,130,7,50,14 PUSHBUTTON "Cancel",IDCANCEL,130,24,50,14 EDITTEXT IDC_EDIT1,7,7,117,14,ES_AUTOHSCROLL EDITTEXT IDC_EDIT2,7,24,117,14,ES_AUTOHSCROLL END 9 10 대화상자편집기 컨트롤배치 대화상자 (Dialog) 툴바이용 컨트롤크기, 정렬, 간격등을편리하게설정 대화상자편집기 탭순서 Tab 키를눌렀을때키보드포커스가이동하는순서 [Layout]->[Tab Order] 메뉴를이용하여변경 원하는탭순서에따라컨트롤들을클릭 대화상자툴바 11 12
대화상자편집기 탭순서변경후 리소스스크립트 대화상자편집기 대화상자속성 IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 187, 98 STYLE DS_MODALFRAME WS_POPUP WS_CAPTION WS_SYSMENU CAPTION "Dialog" FONT 10, "System" BEGIN EDITTEXT IDC_EDIT1,7,7,117,14,ES_AUTOHSCROLL EDITTEXT IDC_EDIT2,7,24,117,14,ES_AUTOHSCROLL DEFPUSHBUTTON "OK",IDOK,130,7,50,14 PUSHBUTTON "Cancel",IDCANCEL,130,24,50,14 END 폰트를바꾸면대화상자와대화상자에포함된컨트롤의크기가폰트의크기에비례해서변경된다. 13 14 모드형대화상자 모드형대화상자생성 CDialog 클래스의 MFC 클래스계층도 모드형대화상자작성순서 1 대화상자리소스작성 2 CDialog ( 파생 ) 클래스객체생성 이때대화상자리소스 ID를생성자의인자로넘겨준다. 3 CDialog::DoModal() 함수호출 15 모달 (Modal) 대화상자 대화상자가출력되어있는동안제어권을독점하고있는형태 대화상자생성 : CDialog::DoModal() 대화상자종료 : Cdialog::EndDialog(int) 확인을버튼을누르면 EndDialog(IDOK) 이호출되어대화상자가종료되면서 IDOK 반환 취소버튼을누르면 EndDialog(IDCANCEL) 이호출되어대화상자가종료되면서 IDCANCEL 반환 대화상자객체는대화상자가필요한함수에지역변수로선언하여모달대화상자생성함수호출 CExDialog dlg; // 대화상자객체변수선언 int nresponse = dlg.domodal(); // 모달대화상자생성 if (nresponse == IDOK) // 확인버튼처리 else if (nresponse == IDCANCEL) // 취소버튼처리 16
모드형대화상자예제작성 프로젝트생성 기본대화상자작성법예제 1~6 단계옵션설정 모드형대화상자예제작성 Resource View 에서 Insert Dialog 를해서 IDD_DIALOG1 대화상자를생성한다 단계 변경사항 1 'Single document' 를선택한다. 2 Compound Document Support 변경사항없음 3 DB 변경사항없음 4 UI 변경사항없음 5 Advanced Features 'ActiveX Controls' 선택을해제함 6 Generated Classes 변경사항없음 17 18 모드형대화상자예제작성 모드형대화상자예제작성 실행결과 void CExModal1View::OnLButtonDblClk(UINT nflags, Cpoint point) CView::OnLButtonDblClk(nFlags, point); CDialog dlg(idd_dialog1); // 대화상자리소스 ID 를준다 if (dlg.domodal() == IDOK) MessageBox("OK 버튼을눌렀습니다 "); else MessageBox( CANCEL 버튼을눌렀습니다 "); 19 20
모드형대화상자주요함수 CDialog 클래스가상함수 모드형대화상자주요함수 CDialog 클래스가상함수 virtual BOOL CDialog::OnInitDialog ( ); virtual void CDialog::OnCancel ( ); 호출시점 : 대화상자가화면에보이기직전에 WM_INITDIALOG 메시지발생시 용도 : 컨트롤을초기화하거나키보드포커스를변경 virtual void CDialog::OnOK ( ); 호출시점 : IDCANCEL 버튼을누를때나윈도우의종료버튼또는 ESC 키를누르면 용도 : 대화상자종료 EndDialog(IDCANCEL) 를호출하여대화상자를종료 호출시점 : IDOK 버튼을누를때 용도 : 컨트롤의값을읽거나값의타당성여부를검사한후대화상자종료 EndDialog(IDOK) 를호출하여대화상자를종료 21 22 모드형대화상자주요함수 OnOK(), OnCancel() 함수내부구현 void CDialog::OnOK() UpdateData(TRUE); EndDialog(IDOK); void CDialog::OnCancel() EndDialog(IDCANCEL); 모드형대화상자예제작성 프로젝트생성 대화상자에편집컨트롤로값입력받는예제 1~6단계옵션설정단계변경사항 1 'Single document' 를선택한다. 2 Compound Document Support 변경사항없음 3 DB 변경사항없음 4 UI 변경사항없음 5 Advanced Features 'ActiveX Controls' 선택을해제함 6 Generated Classes 변경사항없음 23 24
대화상자편집 Resource View 에서 Insert Dialog 를해서 IDD_DIALOG1 대화상자를생성하고컨트롤을추가한다 CDialog 클래스생성 대화상자를나타내는클래스생성 ClassWizard를사용하여 Dialog class 생성 원하는 Class name ( 예 : CMyDialog) 을입력 각컨트롤의속성 ID Control 변경사항 IDC_STR IDC_COLOR IDC_CLRSCR Edit Control Edit Control Button Control 없음없음 25 Caption 을 지우기 로변경 26 CDialog 클래스 Member 정의 대화상자에포함된컨트롤을연결할멤버변수정의 변수명, 연결형태 (value, control), 자료형 ClassWizard의 [Member Variables] 탭이용 클래스위저스로생성된 CMyDialog //CDialog 로부터상속받은클래스생성 (MyDialog.h) class CMyDialog : public CDialog // Construction public: CMyDialog(CWnd* pparent = NULL); // standard constructor // Dialog Data enum IDD = IDD_DIALOG1 ; CString m_str; // 생성된 member, DDX 연결변수 ( 값형식 ) int m_color; // 생성된 member, DDX 연결변수 ( 값형식 ) protected: virtual void DoDataExchange(CDataExchange* pdx); // 27 28
// 대화상자클래스구현 (MyDialog.cpp) CMyDialog::CMyDialog(CWnd* pparent /*=NULL*/) : CDialog(CMyDialog::IDD, pparent) m_str = ""; // 추가된 member 초기화 // 대화상자클래스의멤버와대화상자의컨트롤을연결 void CMyDialog::DoDataExchange(CDataExchange* pdx) CDialog::DoDataExchange(pDX); DDX_Text(pDX, IDC_STR, m_str); // 컨트롤값과 m_str 문자열변수연결 DDX_Text(pDX, IDC_COLOR, m_color); // 컨트롤값과 m_color 값연결 void CMyDialog::OnClrsrc() // 지우기버튼이클릭됬을때 EndDialog(100); // 뷰클래스 class CExModal2View : public CView // Construction protected: CExModal2View(); DECLARE_DYNCREATE(CExModal2View) // Attributes public: CExModal2Doc* GetDocument(); CString m_str; 29 30 int m_color; // 뷰클래스 CExModal2View : CExModal2View() m_str = ; m_color = 0; void CExModal2View::OnLButtonDblClk(UINT nflags, Cpoint point) CMyDialog dlg; // 대화상자생성 dlg.m_str = m_str; dlg.m_color = m_color; int result = dlg.domodal(); if (result == IDOK) // OK 버튼을누른경우 m_str = dlg.m_str; m_color = dlg.m_color; Invalidate(); else if (result == 100) // 지우기버튼을누른경우 m_str = ; m_color = 0; Invalidate(); CView::OnLButtonDblClk(nFlags, point); // m_str과 m_color를받아서출력 void CExModal2View::OnDraw(CDC * pdc) 모드형대화상자예제작성 실행결과.. 31 32
모드형대화상자구현 동작원리 CMyDialog::OnInitDialog() CExModal2View::OnLButtonDblClk() class CMyDialog : public CDialog... CString m_str; // DDX 연결변수 ( 값형식 ) int m_color; // DDX 연결변수 ( 값형식 )... 대화상자 IDC_STR IDC_COLOR 대화상자 2 대화상자객체 m_str m_color 대화상자객체 1 뷰객체 m_str m_color 뷰객체 대화상자가생성될때 IDC_STR IDC_COLOR 3 m_str m_color 4 m_str m_color OK 버튼을누를때 CMyDialog::OnOK() CExModal2View::OnLButtonDblClk() 33 34 DDX(Dialog Data exchange) OnInitDialog(), OnOK() 함수내부구현 대화상자 IDC_STR IDC_COLOR 대화상자 IDC_STR IDC_COLOR 자동화? 2 3 대화상자객체 m_str m_color 대화상자객체 m_str m_color 1 4 뷰객체 m_str m_color 뷰객체 m_str m_color 35 BOOL CDialog::OnInitDialog()... UpdateData(FALSE); // 컨트롤에설정된값을변수로가져온다... UpdateData(TRUE) CString UpdateData(FALSE) void CDialog::OnOK()... UpdateData(TRUE); // 변수값을컨트롤에설정... 36 m_str;
CWnd::UpdateData() 함수내부구현 BOOL CWnd::UpdateData(BOOL bsaveandvalidate)... CDataExchange dx(this, bsaveandvalidate); DoDataExchange(&dx);... 37 CWnd::UpdateData() 함수 DDX_Value 형태로연결되었을경우, 자원을 update하기위한함수 UpdateData(TRUE) 컨트롤에있는값을연결된멤버변수에적용 대화상자종료 (OnOK) 시호출 내부적으로 DoDataExchange() 함수가호출되어정의된 DDV_* 함수호출로유효성검사후 DDX_* 함수를호출하여데이터전송 UpdateData(FALSE) 멤버변수에설정된값을컨트롤에적용 대화상자초기화함수 (OnInitDialog) 에서호출 내부적으로 DoDataExchange() 함수가호출되어정의된 DDX_* 함수를호출하여데이터전송 38 MFC에서제공하는대화상자컨트롤과대화상자객체의멤버변수사이의데이터교환기술 DDX(Dialog Data Exchange) : 대화상자데이터교환 DDV(Dialog Data Validation) : 대화상자데이터유효성확인 DDX 구현 컨트롤의값을저장할변수선언 DoDataExchange() 함수를자신의프로그램에맞게재정의 DDX_* 매크로사용 Data Data public : 데이터멤버 DDX DDV DDX Control void CMyDialog::DoDataExchange(CDataExchange* pdx) CDialog::DoDataExchange(pDX); //AFX_DATA_MAP(CMyDialog) DDX_Text(pDX, IDC_STR, m_str); DDX_Text(pDX, IDC_COLOR, m_color); //AFX_DATA_MAP Document/View Object Dialog Object Dialog Box 39 40
DDV(Dialog Data Validation) 구현 대화상자의컨트롤에입력한데이터의타당성여부를자동으로검사 DDV_* 매크로사용 void CMyDialog::DoDataExchange(CDataExchange* pdx) CDialog::DoDataExchange(pDX); //AFX_DATA_MAP(CMyDialog) DDX_Text(pDX, IDC_STR, m_str); DDV_MaxChars(pDX, m_str, 10); DDX_Text(pDX, IDC_COLOR, m_color); DDV_MinMaxInt(pDX, m_color, 0, 255); //AFX_DATA_MAP 대화상자클래스에서컨트롤제어 1. 컨트롤객체로접근 GetDlgItem( 컨트롤ID) 함수로얻어온컨트롤객체의포인터를이용하여컨트롤제어 CEdit *ptext; ptext = (CEdit *) GetDlgItem(IDC_STR); ptext->getwindowtext(m_str); //Edit 컨트롤의문자열얻기 ptext->setwindowtext(m_str); //Edit 컨트롤에문자열설정 41 42 대화상자클래스에서컨트롤제어 2. 컨트롤에설정된값만을접근하여제어 BOOL CMyDialog::OnInitDialog() CDialog::OnInitDialog(); // 문자열형태로 IDC_STR 컨트롤에 m_str 값을설정 SetDlgItemText(IDC_STR, m_str); // 정수형형태로 IDC_COLOR 컨트롤에 m_color 값을설정 SetDlgItemInt(IDC_COLOR, m_color); return TRUE; void CMyDialog::OnOK() // 문자열형태로 IDC_STR 컨트롤의값을 m_str 로얻어오기 GetDlgItemText(IDC_STR, m_str); // 정수형형태로 IDC_COLOR 컨트롤의값을얻어 m_color 에대입 m_color = GetDlgItemInt(IDC_COLOR); CDialog::OnOK(); 대화상자클래스에서컨트롤제어 3. DDX 를이용하여컨트롤과연결하는방법 클래스위저드를통하여컨트롤과연관된멤버변수를설정하면 DoDataExchange() 함수내에연결관련함수호출 Value는컨트롤에설정되어있는값만연결 DDX_Text 계열함수를이용하여자원에연결 Control은해당컨트롤을제어할수있는컨트롤클래스와연결 DDX_Control 계열함수를이용하여자원에연결 void CMyDialog::DoDataExchange(CDataExchange* pdx) CDialog::DoDataExchange(pDX); // Edit 컨트롤과컨트롤형의변수와연결 DDX_Control(pDX, IDC_EDIT, m_strctrl); // Edit 컨트롤의값을문자열형의변수와연결 DDX_Text(pDX, IDC_STR, m_str); 43 44
비모드형대화상자 차이점 CDialog::DoModal() 함수대신 CDialog::Create() 함수를이용하여생성한다. 대화상자를닫을때 CDialog::EndDialog() 함수대신 CWnd::DestroyWindow() 함수를호출한다. 모드형대화상자객체는대개스택에생성하지만비모드형대화상자객체는힙에생성한다. 스택에생성할경우변수선연영역을벗어나면소멸자가호출되면서대화상자가자동으로파괴되므로, 비모드형대화상자를계속유지할수없기때문이다. 45 비모드형대화상자생성 비모드형대화상자 (Modeless Dialog Box) 제어권을독점하고있지않아메인윈도우와정보를교환할수있는형태 대화상자생성 : CDialog::Create() 대화상자화면표시 : CWnd:: ShowWindow() 대화상자종료 : CWnd:: DestoryWindow() 대화상자객체는대화상자와정보를교환할메인윈도우에동적객체를유지시킬멤버변수로선언 //ExModalessView.h class CMyDialog; //CExDialog 클래스사용을선언 CMyDialog * m_dlg; // 대화상자객체에대한멤버변수선언 //ExModalessView.cpp #include MyDialog.h // 대화상자의헤더파일포함 m_dlg = new CMyDialog(); // 대화상자객체동적생성 m_dlg->create(idd_exdialog,this); // 대화상자생성 46 m_dlg->showwindow(sw_show) ; // 대화상자화면표시 SDI 의 Dialog Box SDI/MDI 프로그램에서 pop-up 스타일로대화상자기능이용 대화상자객체 m_pview 비모드형대화상자예제작성 프로젝트생성 1~6단계옵션설정단계변경사항 1 'Single document' 를선택한다. 2 Compound Document Support 변경사항없음 3 DB 변경사항없음 4 UI 변경사항없음 5 Advanced Features 'ActiveX Controls' 선택을해제함 Modal Dialog Box 뷰객체 m_pdlg Modeless Dialog Box 6 Generated Classes 변경사항없음 47 48
비모드형대화상자예제작성 Resource View 에서 Insert Dialog 를해서 IDD_DIALOG1 대화상자를생성하고컨트롤을추가한다 ID IDC_STR IDC_COLOR IDAPPLY IDCANCEL Control Edit Control Edit Control Button Control Button Control 변경사항없음없음 Caption을 적용 으로변경 49 Caption을 취소 로변경 //MyDialog.h Class CExModalessView; // 참조할클래스선언 class CMyDialog : public CDialog public: CMyDialog(CWnd* pparent = NULL); // standard constructor CExModalessView *m_pview; // 생략 //ExModalessView.h Class CExModalessView: public Cview protected: CExModalessView(); public: CExModalessDoc * GetDocument(); CMyDialog *m_pdlg; // 생략 50 비모드형대화상자예제작성 비모드형대화상자예제작성 void CExModalessView::OnLButtonDblClk(UINT nflags, Cpoint point) if(m_pdlg!= NULL) m_pdlg->setfocus(); // 키보드포커스를대화상자로옮김 else m_pdlg = new CMyDialog(); // 대화상자객체를생성 m_pdlg->m_pview = this; // 뷰객체의주소를넘겨줌 m_pdlg->m_str = m_str; // IDC_STR 컨트롤의초기값 m_pdlg->m_color = m_color; // IDC_COLOR 컨트롤의초기값 m_pdlg->create(idd_dialog1); // 대화상자생성 m_pdlg->showwindow(sw_show); // 대화상자가화면에출력 CView::OnLButtonDblClk(nFlags, point); 51 실행결과 52
대화상자기반응용프로그램 대화상자기반응용프로그램동작 대화상자기반응용프로그램 대화상자가메인윈도우역할을하는응용프로그램 AppWizard의응용프로그램형식을 Dialog Based로선택 CWinApp, CDialog 클래스만생성 CWinApp::InitInstance() 에서 DoModal() 로대화상자생성 53 54 대화상자기반응용프로그램 InitInstance() 함수 (Common Dialog Box) MFC 클래스계층도 BOOL CSimpleCalcApp::InitInstance() CSimpleCalcDlg dlg; m_pmainwnd = &dlg; int nresponse = dlg.domodal(); if (nresponse == IDOK) else if (nresponse == IDCANCEL) return FALSE; 55 56
MFC 클래스 MFC 클래스 용도 CColorDialog 색상선택 ChooseColor CFileDialog 파일열기또는저장 GetOpenFileName, GetSaveFileName CFindReplaceDialog 찾기또는바꾸기 FindText, ReplaceText CFontDialog 폰트선택 ChooseFont CPageSetupDialog 페이지설정 ( 페이지크기, 방향, 페이지여백등 ) CPrintDialog 인쇄설정 ( 프린터, 인쇄 범위등 ) CPrintDialogEx 인쇄설정 ( 프린터, 인쇄 (>MFC 7.0) 범위등 ) API 함수 PageSetupDlg PrintDlg PrintDlgEx (> 윈도우 2000) 57 CColorDialog CColorDialog dlg; dlg.domodal(); COLORREF color = dlg.getcolor(); CColorDialog dlg(rgb(255, 0, 0), CC_FULLOPEN); dlg.domodal(); COLORREF color = dlg.getcolor(); 58 CFileDialog CFileDialog dlg(true); if(dlg.domodal() == IDOK) MessageBox(dlg.GetPathName()); CFileDialog dlg(false); if(dlg.domodal() == IDOK) MessageBox(dlg.GetPathName()); 59 CFindReplaceDialog CFindReplaceDialog *pdlg; pdlg = new CFindReplaceDialog(); pdlg->create(false, "", " ); if(pdlg->isterminating()) pdlg = NULL; return 0; else if(pdlg->findnext()) str.format(" 찾을문자열 : %s", pdlg->getfindstring()); else if(pdlg->replacecurrent()) str.format(" 찾을문자열 : %s\n\r바꿀문자열 : %s", pdlg->getfindstring(), pdlg->getreplacestring()); else if(pdlg->replaceall()) str.format(" 찾을문자열 : %s\n\r바꿀문자열 : %s", pdlg->getfindstring(), pdlg->getreplacestring()); 60
CFontDialog CFontDialog CFontDialog dlg; // 글꼴대화상자 if(dlg.domodal() == IDOK) CClientDC dc(this); // 화면을지운다 CRect rect; GetClientRect(&rect); dc.selectstockobject(white_pen); dc.selectstockobject(white_brush); dc.rectangle(&rect); // 선택된색상을알아낸다 COLORREF color = dlg.getcolor(); dc.settextcolor(color); // 선택된폰트를알아낸다 LOGFONT lf; dlg.getcurrentfont(&lf); CFont font; font.createfontindirect(&lf); dc.selectobject(&font); // 텍스트를출력한다 dc.textout(10, 10, CString(" 한글 & English")); 61 62 CPageSetupDialog CPrintDialog CPageSetupDialog dlg; dlg.domodal(); CPrintDialog dlg(true); dlg.domodal(); CPrintDialog dlg(false); dlg.domodal(); 63 64
CPrintDialogEx // stdafx.h 파일에서 WINVER 상수값을 0x0500 이상으로정의한다. // ( 예 ) #define WINVER 0x0500 CPrintDialogEx dlg; dlg.domodal(); 65