Lecture 2 MFC and Application Frameworks
일관된 사용자 인터페이스 1 스크롤바 툴바 닫기버튼 최대화버튼 최소화버튼 메뉴바 클라이언트 영역
일관된 사용자 인터페이스 2 사용자 측면 개발자 측면 윈도우 프로그램들의 사용법이 비슷함 클라이언트의 내용 및 툴바 정도가 프로그램마다 상이 사용자가 사용법을 쉽게 습득 개발자 측면 자동화된 윈도우 프로그램 개발 가능 미리 구현되어 있는 인터페이스 클래스 사용
MFC 개요 1 윈도우 프로그래밍에 필요한 클래스 라이브러리 주요 MFC 클래스 유형 225 개의 클래스 (분산환경 컴포넌트 개발용 라이브러리 ATL의 클래스들을 합하면 300여개) 주요 MFC 클래스 유형 애플리케이션 프레임워크 관련 클래스 윈도우 관련 클래스 그래픽 관련 클래스 자료 구조 클래스 파일 및 데이터베이스 관련 클래스 인터넷 관련 클래스 OLE 관련 클래스 에러 처리 및 디버깅을 위한 클래스
MFC 개요 2 (MFC hierarchy chart)
MFC 개요 3 (MFC hierarchy chart categories)
MFC의 장점 응용프로그램 MFC SDK API 운영체제 효율성 (Efficiency) 안전성 (Safety) 확장성 (Extensibility) 새로운 기능이나 객체 안에 내용의 추가가 쉽도록 만들자는 개념 재사용성 (Reusability) 유지보수성 (Maintainability) 프로그램을 수정하기 용이한 정도 이식성 (Portability) 어느 한 컴퓨터 환경에서 다른 컴퓨터 환경으로 옮겨 갈 때 프로그램 등의 변경을 최소화할 수 있음 응용프로그램 MFC SDK API 운영체제
Application Frameworks (AFX) 1 Application 프로그램의 뼈대를 구성하는 class: AFX Application Framework Class CWinApp : 다른 class들을 묶고 프로그램을 구동시킴 CFrameWnd: 윈도우의 프레임을 관리 윈도우 이동, 크기조절, 등… CView : 데이터를 보여주는 윈도우 CDocument : 데이터를 저장, 처리
Application Frameworks (AFX) 2 애플리케이션 프레임워크 구조 CFrameWnd CView CDocument 윈도우의 프레임(틀)을 관리 데이터를 보여주는 윈도우 데이터를 저장, 처리 (눈에 안보임) CWinApp : 위의 세 오브젝트를 묶어 주고, 프로그램을 구동 시킴(눈에 안보임)
Application Frameworks (AFX) 3 프레임 윈도우와 뷰를 분리한 이유 프레임에 부여된 역할 즉, 창의 크기 조절, 확대, 축소 등을 사용자가 할 필요 없이 기본적으로 제공 뷰에서는 단지 실제 보여주어야 할 데이터 만을 사용자가 적절하게 계산하여 제공 도큐먼트와 뷰를 분리한 이유 데이터 저장 및 처리(CDocument)와 이를 보여주는(CView)을 분리 함으로써 클래스의 역할을 분담 클래스를 단순화 시킴 같은 데이터라도 보여주는 형태가 다를 수 있음 즉, 하나의 Document에 한 개 이상의 View가 존재
Application Frameworks (AFX) 4
AFX class 계층구조 거의 모든 MFC 클래스의 기반 클래스 커맨드 메세지를 받는 기능 프로그램을 구동시키는 기능 CCmdTarget CWinApp CDocument CObject CWnd CFrameWnd CView 거의 모든 MFC 클래스의 기반 클래스 커맨드 메세지를 받는 기능 프로그램을 구동시키는 기능 데이터를 저장하고 처리하는 기능 윈도우에 관련된 기능 (눈에 보이는 오브젝트) 프로그램 윈도우 프레임(외곽)을 관리하는 기능 데이터를 보여주는 윈도우 관리하는 기능
AppWizard를 이용한 MFC 프로그래밍 1 프로그램의 첫 단계로 프로그램 골격 형성 AppWizard 시작: FILE 메뉴의 New를 선택
AppWizard를 이용한 MFC 프로그래밍 2
AppWizard를 이용한 MFC 프로그래밍 3 데이터베이스 지원사항 설정
AppWizard를 이용한 MFC 프로그래밍 4 None : 데이터베이스 기능을 사용하지 않는다. Header files only : 데이터베이스 코딩에 필요한 AFXDB.H 헤더 파일만을 include해준다. 데이터베이스 기능은 직접 코딩해야 한다 A database view without file support : CRecordView, CRecordset 클래스를 상속 받아 데이터베이스 지원 기능을 생성해 준다 문서 저장 기능(Serialization)은 생성하지 않는다 A database view, with file support 문서 저장 기능(Serialization)도 생성한다
AppWizard를 이용한 MFC 프로그래밍 5 OLE(Object Linking & Embedding), Active-X 설정
AppWizard를 이용한 MFC 프로그래밍 6 OLE 복합 문서 기능 예를 들어 MS Word의 문서에 MS Excel의 표를 삽입할 수 있다 삽입된 Excel 표를 Word에서 직접 편집할 수 있다 OLE Server와 Container 이때 기능을 제공하는 Excel은 OLE Server이고 기능을 제공 받아 문서에 포함하는 Word는 OLE Container이다 Mini server 독립된 애플리케이션으로 실행될 수는 없고 다른 애플리케이션에 OLE server 기능 제공만 해준다 예: MS Equation Editor Full server 다른 애플리케이션에 OLE server 기능을 제공하며 독립된 애플리케이션으로 실행될 수도 있다 예: MS Excel
AppWizard를 이용한 MFC 프로그래밍 7 Automation 외부에 ActiveX Automation 인터페이스를 노출한다 ActiveX Automation 인터페이스를 제어하는 애플리케이션을 Visual Basic이나 Visual C++로 개발할 수 있다 즉 ActiveX Automation 인터페이스를 이용해서, 나중에 자동화나 일종의 매크로 기능을 구현할 수 있게 된다 MS Word와 Excel의 매크로 기능도 Word와 Excel이 노출하는 ActiveX Automation 인터페이스를 이용하여 구현되었다
AppWizard를 이용한 MFC 프로그래밍 8 사용자 인터페이스, WOSA(Windows Open Services Architecture) 기능, 파일 확장자, 윈도우 스타일 설정
AppWizard를 이용한 MFC 프로그래밍 9 Docking toolbar : 도킹 툴바 생성 Initial Status bar : 상태바 Printing & Print Preview : 파일메뉴에 인쇄/인쇄 미리보기 추가 Context-sensitive help : 문맥감지형 도움말을 지원하는 도움말파일생성 3D controls : 윈도우95 이상에서 볼 수 있는 다이얼로그 형태 MAPI : Messaging API 파일메뉴에 Send 메뉴와 관련 코드 Windows Sockets : Winsock API를 지원하기 위한 헤더파일 추가
AppWizard를 이용한 MFC 프로그래밍 10
AppWizard를 이용한 MFC 프로그래밍 11 "a shared DLL" MFC 라이브러리가 실행파일에 포함되지 않음 생성되는 실행 파일의 크기는 작지만 실행 시 MFC의 DLL 파일을 필요로 함 "a statically linked library" MFC 라이브러리가 실행파일에 포함됨 생성되는 실행 파일의 크기는 커지지만 실행 시 MFC의 DLL 파일을 필요로 하지 않음
AppWizard를 이용한 MFC 프로그래밍 12 생성된 클래스들 생성된 파일 부모 클래스를 선택
AppWizard에 의해 생성된 내용 1 기본 클래스의 계층구조 상속 받아 파생클래스 만듦 (기본 MFC 클래스에 추가 변경 삭제 가능)
AppWizard에 의해 생성된 내용 2
AppWizard에 의해 생성된 내용 3 (Class View) 클래스, 멤버 함수, 멤버 변수를 보여준다 클래스 노드를 확장하면 클래스의 멤버 함수와 멤버 변수 목록을 볼 수 있다 아이콘 - 클래스 - protected 멤버 함수 - private 멤버 함수 - public 멤버 함수 - protected 멤버변수 - private 멤버변수 - public 멤버변수
AppWizard에 의해 생성된 내용 4 (Class View) 클래스 이름을 클릭하고 마우스 오른쪽 버튼을 누르면 Go to Definition :클래스가 정의된 헤더 파일 열기 Add Member Function : 클래스에 멤버 함수 추가하기 Add Member Variable : 클래스에 멤버 변수 추가하기 Add Virtual Function : 클래스에 MFC 버추얼 멤버 함수 추가하기 Add Windows Message Handler : 클래스에 메시지 핸들러 추가하기 References : 클래스 정의된 곳, 참조된 곳 목록 보기 Derived Classes : 하위 클래스의 목록, 멤버 함수, 멤버 변수, 정의된 곳, 참조된 곳 보기 Base Classes : 상위 클래스의 목록, 멤버 함수, 멤버 변수, 정의된 곳, 참조된 곳 보기 Group by Access : 멤버의 정렬 순서 선택
AppWizard에 의해 생성된 내용 5
CWinApp 클래스 CWinApp 클래스의 역할 CMyApp 클래스의 인스턴스 theApp가 유일하게 전역변수로 선언 프로그램의 시작과 종료를 담당 프로그램이 시작될 때, 메인 프레임 윈도우를 생성 무한루프를 돌면서 메시지를 뿌려줌 WM_QUIT 메시지를 만나면 무한루프를 빠져 나옴 프로그램 전체를 대표하는 기능들을 수행 CMyApp 클래스의 인스턴스 theApp가 유일하게 전역변수로 선언
CWinApp 클래스 인스턴스가 생성되면서 다음 그림 멤버 함수를 차례로 호출 AfxGetApp – 프로그램 객체 포인터 반환 AfxWinInit – hInstance, nCmdShow 등을 멤버변수에 복사 InitApplication, InitInstance – 프로그램 초기화 Run – 메시지 루프 ExitInstance – WinMain으로 돌아감 AfxWinTerm – 프로그램 종료
CWinApp 클래스 “stdafx.h”는 “Standard Application Frameworks”의 약자 class CMyApp : public CWinApp { // …… // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CMyApp) public: virtual BOOL InitInstance(); virtual int ExitInstance(); //}}AFX_VIRTUAL };
CWinApp 클래스 도큐먼트 클래스, 프레임 윈도우 클래스, 뷰 클래스로 각각 CMyDoc, CMainFrame, CMyView를 사용할 것임을 명시 위 정보를 CSingleDocTemplate 클래스에 설정한 후 CWinApp 클래스의 멤버 함수인 AddDocTemplate 함수를 호출하여 CWinApp 클래스와 연결 CMyApp theApp; BOOL CMyApp::InitInstance() { CSingleDocTemplate* pDocTemplate; pDocTemplate = new CSingleDocTemplate( IDR_MAINFRAME, RUNTIME_CLASS(CMyDoc), RUNTIME_CLASS(CMainFrame), RUNTIME_CLASS(CMyView)); AddDocTemplate(pDocTemplate); return TRUE; }
CWnd 클래스 메시지 핸들러 함수 윈도우의 크기, 위치, 모양, 상태 등을 제어하기 위한 기능을 제공 메시지 핸들러-윈도우에서 발생하는 메시지를 처리
메시지 핸들러 호출의 원리 이벤트가 발생 윈도우 운영체제가 감지 프로그램의 메시지 큐에 적재 메시지 핸들러 호출
윈도우 메시지에 대응 int CMyWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) { CWnd::OnCreate(lpCreateStruct); // 여기에 수행 하고자 하는 기능을 넣으면 됩니다. }
메시지 맵 가상 함수 메시지 맵 바인딩 될 함수로 점프할 번지를 저장하기 위해 4바이트 짜리 포인터가 필요 CWnd 클래스의 메시지 핸들러 함수가 약 200개 이를 모두 가상 함수로 선언하면 약 800바이트의 메모리가 더 필요 프레임 윈도우,뷰 윈도우, 툴바, 상태바, 다이얼로그 박스, 각종 컨트롤 등 수십 개의 윈도우가 생성 메시지 맵 파생 클래스의 메시지 핸들러 함수를 여기에 등록하면 기반 클래스의 함수를 무시하고, 파생 클래스의 함수를 호출하는 매크로
CFrameWnd 클래스 일반적인 윈도우로서의 역할 프레임 윈도우로서의 고유한 역할 프레임 윈도우도 일종의 윈도우 윈도우의 크기, 위치, 상태 등의 조절에 관한 일과 같은 윈도우로서의 역할 툴바와 상태바를 다는 것은 CFrameWnd 클래스에서 상속을 받은 파생 클래스에서 추가 OnCreate 함수를 오버라이딩 하고, 그 함수 안에다가 툴바와 상태바를 생성시켜 메다는 기능을 추가 오버라이딩 된 OnCreate 함수에서 기반 클래스의 OnCreate 함수를 반드시 호출 int CMyWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) { CWnd::OnCreate(lpCreateStruct); // 여기에 수행 하고자 하는 기능을 넣으면 됩니다. }
CFrameWnd 클래스 afx_msg : virtual 대신 오버라이딩 된 함수임을 나타내기 위해 사용 class CMainFrame : public CFrameWnd { // …… // Generated message map functions protected: //{{AFX_MSG(CMainFrame) afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized); //}}AFX_MSG DECLARE_MESSAGE_MAP() };
AFX 전체구조
CView 클래스 일반적인 윈도우로서의 역할 뷰 윈도우로서의 고유한 역할 프로그램에서 다루는 데이터를 보여줌 class CMyView : public CView { public: CMyDoc* GetDocument( ); // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CMyView) virtual void OnDraw(CDC* pDC); // overridden to draw this view protected: virtual BOOL OnPreparePrinting(CPrintInfo* pInfo); virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo); virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo); //}}AFX_VIRTUAL };
CView 클래스 GetDocument() OnDraw() OnXXXPrinting() 도큐먼트 오브젝트의 포인터를 얻는 함수 각각 도큐먼트에서 데이터를 가져와 그리는 기능을 수행하는 함수 OnXXXPrinting() 프린터 출력에 관한 함수
CDocument 클래스 CDocument 클래스의 역할 파일로부터 데이터를 읽어오는 기능 (“파일” 메뉴의 “열기” 기능) 파일에 데이터를 저장하는 기능 (“파일” 메뉴의 “저장” 기능) 새로운 데이터를 만드는 기능 (“파일” 메뉴의 “새 파일” 기능) 작업 중인 데이터를 닫는 기능 (“파일” 메뉴의 “닫기” 기능) 데이터가 변경된 사실을 뷰 오브젝트에 알리는 기능 // MyDoc.h class CMyDoc : public CDocument { protected: // create from serialization only CMyDoc(); // Overrides public: virtual BOOL OnNewDocument(); // Implementation virtual ~CMyDoc(); };
ClassWizard 1 메뉴: View ClassWizard AppWizard는 처음 프로젝트를 생성할 때만 소스 코드를 생성해준다. 이후 생성된 코드에 변경을 가할 때 사용되는 마법사는 Class Wizard이다. 주요 기능 멤버 변수 추가 멤버 함수 추가/편집 메시지 핸들러 생성 MFC 버추얼 함수 생성 대화상자/메뉴 등의 추가 리소스에 대응되는 클래스 생성
ClassWizard 2