MFC Application Frameworks (AFX) 제1회 지킴이 워크샵에서 필자가 발표한 강좌 내용입니다. 강좌 동영상의 해상도가 낮으니, 이 파일을 꼭 같이 참조하시기 바랍니다. 제1회 지킴이 워크샵은 지킴이(http://www.zikimi.co.kr) 주최, 영진출판사 주관, 마이크로소프트, 진솔문고, 서린정보기술 후원으로 98년 7월 12일 진솔문고 강당에서 개최되었습니다.
Object Oriented Programming
Object 분리 예
일관된 사용자 인터페이스
Application Frameworks (AFX) CDocument 데이터를 저장, 처리 (눈에는 안보임) CFrameWnd 윈도우의 프레임(틀)을 관리 CView 데이터를 보여주는 윈도우 CWinApp 위의 세 오브젝트를 묶어주고, 프로그램을 구동 시킴 (눈에는 안보임)
도큐먼트/뷰 분리의 이유
AFX 클래스의 계층 구조 거의 모든 MFC 클래스의 기반 클래스 커맨드 메세지를 받는 기능 프로그램을 구동시키는 기능 CCmdTarget CWinApp CDocument CObject CWnd CFrameWnd CView 거의 모든 MFC 클래스의 기반 클래스 커맨드 메세지를 받는 기능 프로그램을 구동시키는 기능 데이터를 저장하고 처리하는 기능 윈도우에 관련된 기능 (눈에 보이는 오브젝트) 프로그램 윈도우 프레임(외곽)을 관리하는 기능 데이터를 보여주는 윈도우 관리하는 기능
AppWizard MFC 기반 클래스 파생 클래스 CCmdTarget CWinApp CDocument CObject CWnd CFrameWnd CView MFC 기반 클래스 CMyApp CMyDoc CMainFrame CMyView 파생 클래스
Overloading void main( ) int Max(int a, int b) { { int ix = 2, iy = 3, ir; double fx = 2.0, fy = 3.0, fr; ir = Max(ix, iy); fr = Max(fx, fy); } int Max(int a, int b) { if(a > b) return a; else return b; } double Max(double a, double b)
Overriding void main( ) { Counter a; NewCounter b; a.Increase( ); class Counter { private: int count; public: void Increase( ){count++;} } class NewCounter : public Counter { void Increase( ) { Counter::Increase( ); ... void main( ) { Counter a; NewCounter b; a.Increase( ); b.Increase( ); }
Virtual Function
Static Binding class Base { public: void Show( ) { printf(“기반 클래스\n”); } class Derived : public Base printf(“파생 클래스\n”); void main( ) { Base base; Derived derived; base.Show( ); derived.Show( ); }
Static Binding class Base { public: void Show( ) { printf(“기반 클래스\n”); } class Derived : public Base printf(“파생 클래스\n”); void main( ) { Base base; Derived derived; Base *ptr; ptr = &base; ptr->Show( ); ptr = &derived; }
Dynamic Binding class Base { public: void Show( ) { printf(“기반 클래스\n”); } class Derived : public Base virtual void Show( ) { printf(“파생 클래스\n”); void main( ) { Base base; Derived derived; Base *ptr; ptr = &base; ptr->Show( ); ptr = &derived; }
CFrameWnd protected/private 멤버 멤버 함수 멤버 변수 CWinApp CDocument CView CMyApp 클래스의 인스턴스 (전역 변수)
CWinApp 프로그램의 시작과 종료 담당 프레임 윈도우 생성 메시지 루프 (무한루프) InitInstance( ); 전역 변수로 인스턴스 생성 프레임 윈도우 생성 메시지 루프 (무한루프) InitInstance( ); Run( ); ExitInstance( );
CWinApp 클래스의 동작 CWinApp 프로그램 시작 무한 루프 프로그램 종료 InitInstance( ) Run( ) ExitInstance( ) 프로그램 종료
CWinApp 파생 클래스의 동작 CMyApp 상 속 CWinApp 프로그램 시작 무한 루프 프로그램 종료 InitInstance( ) Run( ) 무한 루프 ExitInstance( ) 프로그램 종료
CWinApp 파생 클래스의 동작 CWinApp CMyApp 상 속 프로그램 시작 프로그램 종료 무한 루프 InitInstance( ) Run( ) ExitInstance( ) 프로그램 종료 무한 루프 InitInstance( ) ExitInstance( )
CWinApp 파생 클래스의 구현 class CMyApp : public CWinApp { public: CMyApp(); // Overrides virtual BOOL InitInstance(); };
CWinApp 파생 클래스의 구현 BOOL CMyApp::InitInstance() { CSingleDocTemplate* pDocTemplate; pDocTemplate = new CSingleDocTemplate( IDR_MAINFRAME, RUNTIME_CLASS(CMyDoc), RUNTIME_CLASS(CMainFrame), RUNTIME_CLASS(CMyView)); AddDocTemplate(pDocTemplate); return TRUE; }
CWnd 클래스 윈도우 제어용 멤버 함수 (100여 개) 메시지 핸들러 함수 (200여 개)
윈도우 메시지
메시지 큐 윈도우 오퍼레이팅 시스템 메시지 프로그램 메시지 큐 CWinApp::Run( ) { switch( ) case : } 메시지 핸들러 WM_CREATE WM_ACTIVATE OnCreate OnActivate OnMove WM_ACTIVATE WM_MOVE
CWnd 파생 클래스의 동작 CMyWnd 속 상 CWnd WM_CREATE WM_MOVE WM_SIZE OnCreate OnMove OnSize( ) CWnd WM_CREATE OnCreate OnSize( ) WM_MOVE WM_SIZE
ClassWizard
Message Map
파일 메뉴 처리
Serialize void CMyDoc::Serialize(CArchive& ar) { if (ar.IsStoring()) // 저장하기 ar << n; } else // 읽어오기 ar >> n;
다중 도큐먼트 타입 MDI
Document Template BOOL CDrawApp::InitInstance() { // … CMultiDocTemplate* pDocTemplate; pDocTemplate = new CMultiDocTemplate( IDR_DRAWTYPE, RUNTIME_CLASS(CDrawDoc), RUNTIME_CLASS(CChildFrame), RUNTIME_CLASS(CDrawView)); AddDocTemplate(pDocTemplate); IDR_TEXTTYPE, RUNTIME_CLASS(CTextDoc), RUNTIME_CLASS(CTextFrame), RUNTIME_CLASS(CTextView)); }
도큐먼트 인스턴스 관리
OnFileNew void CDrawApp::OnFileNew() { POSITION pos = GetFirstDocTemplatePosition( ); CDocTemplate *pTemplate; for(int i=0 ; i<N ; i++) pTemplate = GetNextDocTemplate(pos); pTemplate->OpenDocumentFile(NULL); }
OnFileOpen
OnFileOpen void CDrawApp::OnFileOpen() { char szFilter[] = "Draw파일(*.drw), Text파일(*.txt) | *.drw;*.txt |모든파일(*.*)|*.*||"; CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY, szFilter); if(dlg.DoModal( ) == IDOK) OpenDocumentFile(dlg.GetPathName()); } for(POSITION pos = dlg.GetStartPosition( ); pos != NULL ; ) OpenDocumentFile(dlg.GetNextPathName(pos));
AFX 클래스들 간의 상호 참조