Download presentation
Presentation is loading. Please wait.
1
Visual C++ Programming MFC Programming의 이해
Department of Digital Contents Sang Il Park
2
Outline MFC의 주요 특징 Review Look into the codes How to draw with MFC
3
Review: Application Wizard
AppWizard 기능 만들고자 하는 기본적인 프로젝트를 생성 해주고 그 안에 필요한 클래스 생성 클래스에 기본적인 내용을 코딩 기본적인 코딩시간을 절약 하므로 빠른 프로젝트 완성 AppWizard사용 도중 실수로 옵션을 선택하지 않았을 경우 소스에서 새로 추가할 수 있다.
4
Review: MFC 구성 요소 (1/2) 구성 요소 CObject 파생 클래스: 188개 MFC 클래스 나머지: 40개
매크로와 전역 변수 및 전역 함수
5
Review: MFC 구성 요소 (2/2) MFC클래스의 기본 구조 MFC의 계층적 구조 형태 CObject
CCmdTarget CWnd CWinThread CDocument 기타 CWinApp ► CMainFrame 과 Cview클래스는 CWnd에서 상속받음
6
Review: VC++ Framework
CFrameWnd CView CDocument CMainFrame CStartUpView CStartUpDoc 윈도우의 프레임(틀)을 관리 데이터를 보여주는 윈도우 데이터를 저장, 처리 (눈에 안보임) CWinApp : 위의 세 오브젝트를 묶어 주고, 프로그램을 구동 시킴(눈에 안보임) 메시지 루프를 돌림 CStartUpApp
7
Look into the code
8
The simplest MFC application
Single Document No Document/View architecture support No database support No ActiveX control No Docking toolbar No Initial status bar
9
The simplest MFC application
10
VC++ Framework CFrameWnd CChildView CDocument 윈도우의 프레임(틀)을 관리
데이터를 보여주는 윈도우 데이터를 저장, 처리 (눈에 안보임) CWinApp : 위의 세 오브젝트를 묶어 주고, 프로그램을 구동 시킴(눈에 안보임) 메시지 루프를 돌림
11
프로그램 내부 구조 theApp (CSimpleApp : CWinApp) m_pMainFrame
(CMainFrame : CFrameWnd) m_wndView (CChildView : CWnd)
12
응용 프로그램 실행순서 CSimpleApp theApp; WinMain() // MFC 내부에 숨겨짐 {
theApp.InitInstance(); // 초기화 theApp.Run(); // 메시지 루프 theApp.ExitInstance(); // 종료 }
13
응용 프로그램 클래스 (1/4) // Simple.h class CSimpleApp : public CWinApp {
virtual BOOL InitInstance(); afx_msg void OnAppAbout(); DECLARE_MESSAGE_MAP() };
14
응용 프로그램 클래스 (2/4) MFC 기본 header file을 모아놓음 #include "stdafx.h"
#include "simple.h" #include "MainFrm.h“ // Simple.cpp BEGIN_MESSAGE_MAP(CSimpleApp, CWinApp) ON_COMMAND(ID_APP_ABOUT, OnAppAbout) END_MESSAGE_MAP() CSimpleApp::CSimpleApp() { } CSimpleApp theApp; MFC 기본 header file을 모아놓음 // 응용프로그램 자신에 해당하는 전역객체
15
응용 프로그램 클래스 (3/4) BOOL CSimpleApp::InitInstance() {
SetRegistryKey(_T("Local AppWizard-Generated Applications")); CMainFrame* pFrame = new CMainFrame; m_pMainWnd = pFrame; pFrame->LoadFrame(IDR_MAINFRAME, WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL, NULL); pFrame->ShowWindow(SW_SHOW); pFrame->UpdateWindow(); return TRUE; }
16
응용 프로그램 클래스 (3/4) BOOL CSimpleApp::InitInstance() {
SetRegistryKey(_T("Local AppWizard-Generated Applications")); CMainFrame* pFrame = new CMainFrame; m_pMainWnd = pFrame; pFrame->LoadFrame(IDR_MAINFRAME, WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL, NULL); pFrame->ShowWindow(SW_SHOW); pFrame->UpdateWindow(); return TRUE; } 16
17
응용 프로그램 실행순서 CSimpleApp theApp; WinMain() // MFC 내부에 숨겨짐 {
theApp.InitInstance(); // 초기화 theApp.Run(); // 메시지 루프 theApp.ExitInstance(); // 종료 }
18
응용 프로그램 클래스 (4/4) // 대화상자 관련 클래스 선언 및 정의 부분 - 생략 // ...
void CSimpleApp::OnAppAbout() { CAboutDlg aboutDlg; aboutDlg.DoModal(); }
19
프레임 윈도우 클래스 (1/5) // MainFrm.h class CMainFrame : public CFrameWnd {
protected: DECLARE_DYNAMIC(CMainFrame) virtual BOOL PreCreateWindow(CREATESTRUCT& cs); virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo); virtual ~CMainFrame(); CChildView m_wndView; afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnSetFocus(CWnd *pOldWnd); DECLARE_MESSAGE_MAP() };
20
프레임 윈도우 클래스 (2/5) // MainFrm.cpp
IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd) BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) ON_WM_CREATE() ON_WM_SETFOCUS() END_MESSAGE_MAP() CMainFrame::CMainFrame() { } CMainFrame::~CMainFrame()
21
프레임 윈도우 클래스 (3/5) int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1; if (!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW, CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL)) TRACE0("Failed to create view window\n"); } return 0;
22
프레임 윈도우 클래스 (4/5) BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) {
if( !CFrameWnd::PreCreateWindow(cs) ) return FALSE; cs.dwExStyle &= ~WS_EX_CLIENTEDGE; cs.lpszClass = AfxRegisterWndClass(0); return TRUE; }
23
프레임 윈도우 클래스 (4/5) struct CREATESTRUCT{ LPVOID lpCreateParams;
HINSTANCE hInstance; HMENU hMenu; HWND hwndParent; int cy; int cx; int y; int x; LONG style; LPCTSTR lpszName; LPCTSTR lpszClass; DWORD dwExStyle; }; 23
24
프레임 윈도우 클래스 (5/5) void CMainFrame::OnSetFocus(CWnd* pOldWnd) {
m_wndView.SetFocus(); } BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) if (m_wndView.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo)) return TRUE; return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
25
뷰 클래스 (1/4) // ChildView.h class CChildView : public CWnd { public:
protected: virtual BOOL PreCreateWindow(CREATESTRUCT& cs); virtual ~CChildView(); afx_msg void OnPaint(); DECLARE_MESSAGE_MAP() };
26
뷰 클래스 (2/4) // ChildView.cpp CChildView::CChildView() { }
BEGIN_MESSAGE_MAP(CChildView,CWnd ) ON_WM_PAINT() END_MESSAGE_MAP()
27
뷰 클래스 (3/4) BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs) {
if (!CWnd::PreCreateWindow(cs)) return FALSE; cs.dwExStyle |= WS_EX_CLIENTEDGE; cs.style &= ~WS_BORDER; cs.lpszClass = AfxRegisterWndClass ( CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS, ::LoadCursor(NULL, IDC_ARROW), HBRUSH(COLOR_WINDOW+1), NULL); return TRUE; } Style: ExStyle: System Color:
28
뷰 클래스 (4/4) void CChildView::OnPaint() { CPaintDC dc(this);
dc.TextOut(100, 100, "안녕하세요."); }
29
요약 클래스 종류 베이스 클래스 이름 핵심 함수 - 주 역할 응용 프로그램 CWinApp
InitInstance() - 프레임 윈도우를 생성한다. Run() - 메시지 루프를 제공한다. 프레임 윈도우 CFrameWnd OnCreate() - 뷰를 생성한다. 뷰 CWnd OnPaint() - 화면에 출력한다.
30
매크로 단계 매크로 이름 사용 목적 사용 위치 1 DECLARE_DYNAMIC 실행 시간 클래스 정보 클래스 선언부 (*.H)
IMPLEMENT_DYNAMIC 클래스 정의부 (*.CPP) 2 DECLARE_DYNCREATE 실행 시간 클래스 정보, 동적 객체 생성 IMPLEMENT_DYNCREATE 3 DECLARE_SERIAL 동적 객체 생성, 직렬화 IMPLEMENT_SERIAL
31
Homework #1 1. 가상함수란? 2. 클래스 디자인 및 상속의 연습
최대한 자세히, 성실히, 자신의 언어를 이용하여 설명 2. 클래스 디자인 및 상속의 연습 도형(shape) class를 정의하고, 이를 상속받아 사각형(rectangle), 원(circle) class를 정의하고, 각각의 특성에 맞는 draw()라는 함수를 정의해 본다. 동작하는 code를 제출
32
Homework #1 클래스 상속의 연습 Shape Class 정의하기 Rectangle Class 정의하기
맴버변수: float _x,_y 생성자: Shape(float x, float y) _x와 _y의 값을 설정 맴버함수: void Draw() const 아래와 같은 내용 출력 [SHAPE] position = ( ‘_x값’, ‘_y값’ ) Rectangle Class 정의하기 Shape Class로부터 상속 맴버변수: float _width, _height 생성자: Rectangle(float x, float y, float w, float h) 아래와 같은 내용 출력 [RECTANGLE] position = ( ‘_x값’, ‘_y값’), size = (‘_width’, ‘_height’)
33
Homework #1 클래스 상속의 연습 Circle Class 정의하기 Shape Class로부터 상속
맴버변수: float _radius 생성자: Circle(float x, float y, float radius) 맴버함수: void Draw() const 아래와 같은 내용 출력 [CIRCLE] position = ( ‘_x값’, ‘_y값’), radius = ‘_radius’
34
Homework #1 클래스 상속의 연습의 test - 다음과 같은 main 함수를 이용 int main() {
Shape* shapes[5] = {NULL}; shapes[0] = new Circle( 100, 100, 50); shapes[1] = new Rectangle( 300, 300, 100, 100); shapes[2] = new Rectangle( 200, 100, 50, 150); shapes[3] = new Circle(100, 300, 150); shapes[4] = new Rectangle( 200, 200, 200, 200); for (int i = 0; i < 5; ++i) shapes[i]->Draw(); for (i = 0; i < 5; ++i) delete shapes[i]; shapes[i] = NULL; }
35
Homework #1 클래스 디자인 및 상속의 연습 아래와 같은 결과가 나오도록 클래스를 디자인하라
36
Homework #1 리포트는 다음주 화요일 수업시간까지 제출
마감 3월 18일 화요일 9시(1반)/12시(2반) 최대한 성실히, 2번의 경우 코드에 대한 자세한 설명 Code 제출: 이메일 제출 이메일 제목: [숙제제출: 1(2)반] 학번, 이름 다음주 월요일 자정 (3월 17일 23:99)까지 Project file + source codes를 보낼것 (실행파일X) Visual C++ 6.0, Visual Studio .NET 2003, 2005
37
How to draw with MFC
38
GDI와 디바이스 컨텍스트 (1/5) 출력 시스템을 설계할 때 고려할 사항
모니터, 비디오 카드, 프린터 등 출력에 사용되는 주변 장치가 변경되는 경우에도 프로그램을 수정할 필요가 없어야 한다. 여러 프로그램이 화면을 분할해서 사용하므로 하나의 프로그램이 출력을 하는데 있어서 제약을 가해야 한다. 즉 화면이나 기타 출력 장치를 직접 접근(Direct Access)하거나 독점해서 사용하는 것을 운영체제 차원에서 막아야 한다.
39
GDI와 디바이스 컨텍스트 (2/5) GDI(Graphics Device Interface)
운영체제의 하위 시스템 중 하나로 DLL로 존재 응용 프로그램의 요청을 받아서 실제 출력 장치에 대한 출력을 담당 응용 프로그램 GDI 출력 장치 (화면, 프린터 등) 장치 독립적 장치 의존적
40
GDI와 디바이스 컨텍스트 (3/5) 화면 출력할 때 고려할 사항
클라이언트 영역에 출력하려면 화면에 해당하는 윈도우 위치를 알아야 한다. 화면에 여러 개의 윈도우가 있을 때 출력 결과가 다른 윈도우의 영역을 침범하지 않아야 한다. 현재 출력할 화면이 다른 윈도우에 가려졌다면 출력을 할 수 없어야 한다.
41
GDI와 디바이스 컨텍스트 (4/5) 디바이스 컨텍스트(DC, Device Context) 윈도우 응용 프로그램의 출력 과정
멀티태스킹(멀티스레딩) GUI 환경에서 발생할 수 있는 여러 상황을 고려한 출력 가능 윈도우 응용 프로그램의 출력 과정 출력하기 전에 윈도우 운영체제에게 디바이스 컨텍스트를 요청한다. 운영체제의 GDI는 내부적으로 디바이스 컨텍스트를 만든 후 디바이스 컨텍스트 핸들(HDC 타입, 32비트 포인터)을 해당 프로그램에게 돌려준다.
42
GDI와 디바이스 컨텍스트 (5/5) 윈도우 응용 프로그램의 출력 과정 (cont'd)
응용 프로그램은 자신이 받은 핸들을, 출력 관련 API 함수를 호출할 때 사용한다. 출력 관련 API 함수를 호출하면 GDI가 이를 처리한다. GDI는 해당 프로그램이 넘겨준 디바이스 컨텍스트 핸들로 내부 데이터를 참조하여 다양한 상황을 고려해서 출력한다. 응용 프로그램 디바이스 컨텍스트 GDI 장치 드라이버 출력 장치 (화면, 프린터 등)
43
무효 영역 (1/3) 화면을 다시 그려야 하는 상황
44
무효 영역 (2/3) WM_PAINT 메시지 처리 HelloSDK HelloMFC case WM_PAINT:
hdc = BeginPaint(hwnd, &ps); TextOut(hdc, 100, 100, str, lstrlen(str)); EndPaint(hwnd, &ps); return 0; void CMainFrame::OnPaint() { char *msg = "Hello, MFC"; CPaintDC dc(this); dc.TextOut(100, 100, msg, lstrlen(msg)); }
45
무효 영역 (3/3) WM_PAINT 메시지 발생 상황 무효 영역 생성 윈도우가 생성될 때 윈도우의 크기가 변경될 때
최소화 또는 최대화 되었을 때 다른 윈도우가 가렸다가 드러날 때 무효 영역 생성 void CWnd::Invalidate (BOOL bErase = TRUE); void CWnd::InvalidateRect (LPCRECT lpRect, BOOL bErase = TRUE);
46
출력 방법 비교 SDK MFC 윈도우 운영체제에게 디바이스 컨텍스트를 요청한다.
운영체제로부터 받은 디바이스 컨텍스트 핸들을 사용하여 출력을 한다. 운영체제에게 디바이스 컨텍스트 사용이 끝났음을 알린다. MFC 디바이스 컨텍스트 객체를 생성한다. 객체의 멤버 함수를 호출하여 출력한다.
47
다양한 디바이스 컨텍스트 클래스 메타 파일(Metafile)에 출력할 때 CMetaFileDC
윈도우의 전체 영역(클라이언트 영역 + 비 클라이언트 영역)에 출력할 때 CWindowDC 클라이언트 영역에 출력할 때 (WM_PAINT 메시지 핸들러를 제외한 다른 모든 곳에서 사용) CClientDC (WM_PAINT 메시지 핸들러에서만 사용) CPaintDC 용도 클래스 이름
48
CPaintDC 클래스 클래스 계층도 CPaintDC 사용 예 void CChildView::OnPaint() {
CPaintDC dc(this); // ... }
49
CClientDC 클래스 CClientDC 사용 예
void CChildView::OnLButtonDown(UINT nFlags, CPoint point) { CClientDC dc(this); // ... }
50
CWindowDC 클래스 CWindowDC 사용 방법 원점 위치 CPaintDC, CClientDC 클래스와 동일
51
CMetaFileDC 클래스 메타 파일(Metafile) CMetaFileDC 사용 방법 GDI 명령어를 저장할 수 있는 파일
CMetaFileDC 객체를 만든 후 CMetaFileDC::Create() 호출 메타 파일 객체를 일반적인 디바이스 컨텍스트 객체로 간주하고 출력 관련 멤버 함수를 호출 CMetaFileDC::Close()를 호출하면 윈도우 운영체제가 내부적으로 메타 파일을 만든 후 메타 파일 핸들(HMETAFILE 타입)을 리턴 CDC::PlayMetaFile()로 메타 파일을 실행
52
그리기 함수 (1/3) 점 찍기 SetPixel과 기능은 동일하지만 SetPixel 함수와 달리 원래의 점의 색을 리턴하지 않으므로 속도가 더 빠르다. SetPixelV() 화면의 특정 위치에 원하는 색의 점을 찍으며 원래의 점의 색을 리턴한다. SetPixel() 화면의 특정 위치에 해당하는 점의 색을 얻는다. GetPixel() 기능 이름
53
그리기 함수 (2/3) 선 그리기 현재 위치로부터 특정 위치까지 선을 그린 후 현재 위치를 갱신한다. LineTo()
현재 위치를 옮긴다. MoveTo() 기능 이름
54
그리기 함수 (3/3) 도형 그리기 사각형에 내접하는 타원을 그린다. Ellipse() 사각형을 그린다. Rectangle()
기능 이름
55
텍스트 함수 텍스트 출력 함수 기준 위치에 대한 문자열의 정렬 방식을 정한다. SetTextAlign()
문자의 배경색을 바꾼다. SetBkColor() 문자의 색을 바꾼다. SetTextColor() 사각형을 기준으로 문자열을 출력한다. DrawText() 특정 위치에 문자열을 출력한다. TextOut() 기능 이름
Similar presentations