Presentation is loading. Please wait.

Presentation is loading. Please wait.

Visual C programming Seminar

Similar presentations


Presentation on theme: "Visual C programming Seminar"— Presentation transcript:

1 Visual C++ 2010 programming Seminar
19장. GDI+ 그래픽 프로그래밍 22장. 라이브러리 만들기

2 19장. GDI+ 그래픽 프로그래밍

3 Graphic Device Interface +
19장. GDI+ 그래픽 프로그래밍 1. GDI+란? 프로그래머가 그래픽 장치의 종류에 상관없이 그래픽 기능을 가지는 프로그램을 작성하도록 도와주는 C++ API의 모음이다. Monitor Printer Graphic Devices Application1 Application2 Application3 Applications Graphic Device Interface + GDI+ [그림. GDI+의 역할]

4 19장. GDI+ 그래픽 프로그래밍 2. GDI+가 처리하는 그래픽 기능 ① 2D 벡터 그래픽 ② 이미징 ③ 문자 출력
선과 좌표를 기반으로 하는 그래픽 Ex> 직선, 사각형, 원 ... ② 이미징 그림 파일을 편집하는 기능 ③ 문자 출력 시스템의 폰트를 이용해 그래픽 장치에 문자를 출력하는 기능

5 19장. GDI+ 그래픽 프로그래밍 3. GDI+의 구조 [표. GDI+의 주요 클래스]
40개의 클래스, 50개의 나열자, 6개의 구조체, 몇몇의 전역함수로 이루어져 있다. 클래스 설명 Brush 브러쉬 클래스들의 조상이 되는 추상 클래스. 이 클래스로부터 상속 받는 HatchBrush, LinearGradientBrush, PathGradientBrush, SolidBrush, TextureBrush 등은 도형 내부를 칠하는 기능을 한다. Color 32bit의 컬러 데이터를 다룬다. 32bit중 첫 번째 8bit는 alpha값(투명도), 나머지 24bit는 Red, Green, Blue가 각각 8bit 씩을 나누어 갖는다. 이 Color 클래스는 네 가지의 바이트를 조합하여 색을 표현한다. Font 출력할 문자의 글꼴, 크기, 스타일 등을 다룬다. FontFamily 같은 서체를 갖지만 다른 스타일을 갖는 폰트의 그룹을 다룬다. 예를 들어 “굴림체”는 폰트 패밀리이고, 이 폰트 패밀리는 “굵게”, “이탤릭”, “밑줄”등의 스타일을 포함한다. Graphics GDI+의 핵심 클래스이다. GDI+에서 일어나는 모든 그리기가 바로 이 클래스에 의해 이루어진다. Image GDI+의 이미지 처리를 담당하는 클래스, JPG, GIF, BMP 등 다양한 포맷을 지원한다. Pen 선이나 곡선을 긋는데 사용하는 객체이다. Point, PointF 2차원 좌표를 표현하는 클래스이다. Point는 정수, PointF는 실수로 좌표를 표현한다는 것이 차이점이다. Rect, RectF 좌상단의 꼭지점으로부터 너비와 높이를 이용하여 사각형을 표현한다. Rect는 정수를, RectF는 실수를 이용한다. Size, SizeF 2차원 좌표계에서 너비와 높이를 표현한다. Size는 정수를, SizeF는 실수를 이용한다. Graphics GDI+의 핵심 클래스이다. GDI+에서 일어나는 모든 그리기가 바로 이 클래스에 의해 이루어진다. [표. GDI+의 주요 클래스]

6 19장. GDI+ 그래픽 프로그래밍 4. GDI+ API의 사용 절차
① GdiplusStartup() 함수를 호출하여 GDI+를 초기화한다. ② Graphics 객체를 생성하여 그리기를 한다. ③ 그리기를 끝냈으면 GDI+의 자원을 해제하기 위해 GdiplusShutdown()함수를 호출한다.

7 19장. GDI+ 그래픽 프로그래밍 5. GDI+를 이용한 예제 ① 프로젝트 생성 ② 2D 벡터 그래픽 기능 추가
③ 이미징 기능 추가 ④ 텍스트 기능 추가

8 19장. GDI+ 그래픽 프로그래밍 5. GDI+를 이용한 예제 ① 프로젝트 생성 ② 2D 벡터 그래픽 기능 추가
③ 이미징 기능 추가 ④ 텍스트 기능 추가

9 19장. GDI+ 그래픽 프로그래밍 5. GDI+를 이용한 예제 ① 프로젝트 생성 ② 2D 벡터 그래픽 기능 추가
③ 이미징 기능 추가 ④ 텍스트 기능 추가

10 19장. GDI+ 그래픽 프로그래밍 5. GDI+를 이용한 예제 ① 프로젝트 생성 ② 2D 벡터 그래픽 기능 추가
③ 이미징 기능 추가 ④ 텍스트 기능 추가

11 19장. GDI+ 그래픽 프로그래밍 5. GDI+를 이용한 예제 ① 프로젝트 생성 ② 2D 벡터 그래픽 기능 추가
③ 이미징 기능 추가 ④ 텍스트 기능 추가

12 19장. GDI+ 그래픽 프로그래밍 5. GDI+를 이용한 예제 ① 프로젝트 생성 ② 2D 벡터 그래픽 기능 추가
③ 이미징 기능 추가 ④ 텍스트 기능 추가

13 19장. GDI+ 그래픽 프로그래밍 5. GDI+를 이용한 예제 ① 프로젝트 생성 ② 2D 벡터 그래픽 기능 추가
③ 이미징 기능 추가 ④ 텍스트 기능 추가

14 19장. GDI+ 그래픽 프로그래밍 5. GDI+를 이용한 예제 이로써 프로젝트 생성이 끝났다. ① 프로젝트 생성
③ 이미징 기능 추가 ④ 텍스트 기능 추가

15 GDI+가 제공하는 기능을 사용하려면 gdiplus.h 헤더 파일을 참조해야 한다.
① 프로젝트 생성 GDI+가 제공하는 기능을 사용하려면 gdiplus.h 헤더 파일을 참조해야 한다. 헤더 파일 gdiplus.h를 생성되어 있는 stdafx.h 파일에 포함시킨다. 삽입하는 코드 #include <gdiplus.h> using namespace Gdiplus; ② 2D 벡터 그래픽 기능 추가 ③ 이미징 기능 추가 ④ 텍스트 기능 추가

16 이로써 GDI+가 제공하는 기능을 사용할 수 있게 되었다.
① 프로젝트 생성 이로써 GDI+가 제공하는 기능을 사용할 수 있게 되었다. ② 2D 벡터 그래픽 기능 추가 ③ 이미징 기능 추가 ④ 텍스트 기능 추가

17 19장. GDI+ 그래픽 프로그래밍 5. GDI+를 이용한 예제 ① 프로젝트 생성 ② 2D 벡터 그래픽 기능 추가
③ 이미징 기능 추가 ④ 텍스트 기능 추가

18 CGdiPlusTestDlg 클래스에 다음과 같이 멤버 변수와 상수를 추가한다. 삽입하는 코드 private:
① 프로젝트 생성 CGdiPlusTestDlg 클래스에 다음과 같이 멤버 변수와 상수를 추가한다. 삽입하는 코드 private: int m_nDrawMode; // 어떤 도형을 그릴 것인지를 결정하는 변수 CPoint m_ptCurrent; // 마우스 버튼을 누른 좌표 // 그리기 모드 상수 static const int LINE = 1; static const int RECT = 2; static const int CIRCLE = 3; ② 2D 벡터 그래픽 기능 추가 ③ 이미징 기능 추가 ④ 텍스트 기능 추가

19 OnBnClickedRdoDrawline() 함수
19장. GDI+ 그래픽 프로그래밍 5. GDI+를 이용한 예제 ① 프로젝트 생성 ② 2D 벡터 그래픽 기능 추가 BN_Clicked 윈도우 메시지 발생 CGdiPlusTestDlg 클래스의 멤버 함수인 OnBnClickedRdoDrawline() 함수가 호출 된다. OnBnClickedRdoDrawline() 함수 void CGdiPlusTestDlg::OnBnClickedRdoDrawline() { m_nDrawMode = LINE; } ③ 이미징 기능 추가 ④ 텍스트 기능 추가

20 OnBnClickedRdoDrawrect() 함수
19장. GDI+ 그래픽 프로그래밍 5. GDI+를 이용한 예제 ① 프로젝트 생성 ② 2D 벡터 그래픽 기능 추가 BN_Clicked 윈도우 메시지 발생 CGdiPlusTestDlg 클래스의 멤버 함수인 OnBnClickedRdoDrawrect() 함수가 호출 된다. OnBnClickedRdoDrawrect() 함수 void CGdiPlusTestDlg::OnBnClickedRdoDrawrect() { m_nDrawMode = RECT; } ③ 이미징 기능 추가 ④ 텍스트 기능 추가

21 OnBnClickedRdoDrawcircle() 함수
19장. GDI+ 그래픽 프로그래밍 5. GDI+를 이용한 예제 ① 프로젝트 생성 ② 2D 벡터 그래픽 기능 추가 BN_Clicked 윈도우 메시지 발생 CGdiPlusTestDlg 클래스의 멤버 함수인 OnBnClickedRdoDrawcircle() 함수가 호출 된다. OnBnClickedRdoDrawcircle() 함수 Void CGdiPlusTestDlg::OnBnClickedRdoDrawcircle() { m_nDrawMode = CIRCLE; } ③ 이미징 기능 추가 ④ 텍스트 기능 추가

22 WM_LBUTTONDOWN 윈도우 메시지 발생
19장. GDI+ 그래픽 프로그래밍 5. GDI+를 이용한 예제 ① 프로젝트 생성 ② 2D 벡터 그래픽 기능 추가 마우스 왼쪽 버튼을 누름 WM_LBUTTONDOWN 윈도우 메시지 발생 CGdiPlusTestDlg 클래스의 멤버 함수인 OnLbuttonDown() 함수가 호출 된다. OnLbuttonDown() 함수 void CGdiPlusTestDlg::OnLButtonDown(UINT nFlags, CPoint point) { m_ptCurrent.SetPoint(point.x, point.y); CDialogEx::OnLButtonDown(nFlags, point); } ③ 이미징 기능 추가 ④ 텍스트 기능 추가

23 CGdiPlusTestDlg 클래스의 멤버 함수인 OnLbuttonUp() 함수가 호출 된다.
① 프로젝트 생성 ② 2D 벡터 그래픽 기능 추가 CGdiPlusTestDlg 클래스의 멤버 함수인 OnLbuttonUp() 함수가 호출 된다. 마우스 왼쪽 버튼을 누른 상태로 드래그 WM_LBUTTONUP 윈도우 메시지 발생 누르고 있던 마우스 왼쪽 버튼을 뗌 ③ 이미징 기능 추가 ④ 텍스트 기능 추가

24 (m_ptCurrent.x, m_ptCurrent.y)
19장. GDI+ 그래픽 프로그래밍 5. GDI+를 이용한 예제 void CGdiPlusTestDlg::OnLButtonUp(UINT nFlags, CPoint point) { GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; // GDI+ 초기화 하기 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); // Graphics 객체를 이용하여 도형 그리기 Graphics graphics(this->m_hWnd); Pen pen(Color(255, 87, 92, 112)); switch ( m_nDrawMode ) case LINE : // 선분 그리기 graphics.DrawLine(&pen, m_ptCurrent.x, m_ptCurrent.y, point.x, point.y); break; case RECT: // 사각형 그리기 graphics.DrawRectangle(&pen, m_ptCurrent.x, m_ptCurrent.y, point.x - m_ptCurrent.x, point.y - m_ptCurrent.y); case CIRCLE: // 원 그리기 graphics.DrawEllipse(&pen, m_ptCurrent.x, m_ptCurrent.y, } } // 이 블록안에서 스택에 생성된 모든 객체는 소멸된다. // GDI+ 자원 해제하기 GdiplusShutdown(gdiplusToken); CDialogEx::OnLButtonUp(nFlags, point); (Point.x, point.y) (m_ptCurrent.x, m_ptCurrent.y)

25 CGdiPlusTestDlg 클래스의 멤버 함수인 OnBnClickedBtnImage() 함수가 호출 된다.
① 프로젝트 생성 ② 2D 벡터 그래픽 기능 추가 ③ 이미징 기능 추가 ④ 텍스트 기능 추가 BN_CLICKED 윈도우 메시지 발생 CGdiPlusTestDlg 클래스의 멤버 함수인 OnBnClickedBtnImage() 함수가 호출 된다.

26 19장. GDI+ 그래픽 프로그래밍 5. GDI+를 이용한 예제 (0, 0) (200, 20)
void CGdiPlusTestDlg::OnBnClickedBtnImage() { GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); CFileDialog dlg(TRUE); if (dlg.DoModal() == IDOK) { Image image( dlg.GetPathName().AllocSysString()); Graphics graphics(this->m_hWnd); graphics.DrawImage(&image, 200, 20, image.GetWidth(), image.GetHeight()); } GdiplusShutdown(gdiplusToken); (0, 0) (200, 20)

27 19장. GDI+ 그래픽 프로그래밍 5. GDI+를 이용한 예제

28 CGdiPlusTestDlg 클래스의 멤버 함수인 OnBnClickedBtnText() 함수가 호출 된다.
① 프로젝트 생성 ② 2D 벡터 그래픽 기능 추가 ③ 이미징 기능 추가 ④ 텍스트 기능 추가 컨트롤 ID : IDC_EDIT_TEXT 변수이름 : m_strText BN_CLICKED 윈도우 메시지 발생 CGdiPlusTestDlg 클래스의 멤버 함수인 OnBnClickedBtnText() 함수가 호출 된다.

29 19장. GDI+ 그래픽 프로그래밍 5. GDI+를 이용한 예제
void CGdiPlusTestDlg::OnBnClickedBtnText() { UpdateData(TRUE); GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; // Initialize GDI+. GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); Graphics graphics(this->m_hWnd); SolidBrush brush(Color(255, 87, 92, 112)); FontFamily fontFamily(L”맑은 고딕”); Gdiplus::Font font(&fontFamily, 24, FontStyleRegular, UnitPixel); PointF pointf(200.0f, 10.0f); graphics.DrawString( m_strText.AllocSysString(), -1, &font, pointf, &brush); } GdiplusShutdown(gdiplusToken);

30 19장. GDI+ 그래픽 프로그래밍 6. ClimateMonitor 차트 기능 추가하기

31 6. ClimateMonitor 차트 기능 추가하기
19장. GDI+ 그래픽 프로그래밍 6. ClimateMonitor 차트 기능 추가하기 CClimateMonitorView 클래스에 멤버 변수와 상수를 추가 추가 되는 코드 private: // 차트/목록 모드 플래그 int m_nViewMode; // 막대 그래프 간격 static const int OFFSET = 125; // 차트 보기 static const int CM_VIEW_CHART = 0; // 목록 보기 static const int CM_VIEW_TEXT = 1; 목록 보기 클릭 차트 보기 클릭

32 6. ClimateMonitor 차트 기능 추가하기
19장. GDI+ 그래픽 프로그래밍 6. ClimateMonitor 차트 기능 추가하기 CClimateMonitorView() 생성자 변경 변경 되는 코드 CClimateMonitorView::CClimateMonitorView() : m_nViewMode(CM_VIEW_TEXT) { } ClimateMonitor 응용 프로그램은 초기에 “목록 보기” 상태이다.

33 6. ClimateMonitor 차트 기능 추가하기
19장. GDI+ 그래픽 프로그래밍 6. ClimateMonitor 차트 기능 추가하기 GDI+ 관련 자원의 초기화 및 해제 ☞ 자원의 초기화와 해제에 걸리는 부하를 줄이기 위해 CWinApp 클래스로부터 상속받은 CClimateMonitorApp 클래스를 이용한다. ☞ CClimateMonitorApp 클래스에 m_gdiplusToken 변수 추가 ☞ CClimateMonitorApp::InitInstance() 함수를 사용하여 GDI+ 관련 자원의 초기화를 진행한다. CClimateMonitorApp 클래스에 추가된 코드 private: ULONG_PTR m_gdiplusToken; CClimateMonitorApp::InitInstance() 함수에 추가된 코드 // GDI+ 초기화하기 GdiplusStartupInput gdiplusStartupInput; GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL); ☞ CClimateMonitorApp::ExitInstance() 함수를 사용하여 GDI+ 관련 자원의 해제를 진행한다. CClimateMonitorApp::ExitInstance() 함수에 추가된 코드 // GDI+ 자원해제하기 GdiplusShutdown(m_gdiplusToken);

34 m_nViewMode == CM_VIEW_TEXT
19장. GDI+ 그래픽 프로그래밍 6. ClimateMonitor 차트 기능 추가하기 이제 OnDraw() 함수로 그리는 부분을 새롭게 작성해야 한다. OnDraw() 함수 m_nViewMode == CM_VIEW_TEXT DrawList() 함수 DrawChart() 함수 YES NO [그림. OnDraw() 함수의 flow chart] OnDraw() 함수의 코드 void CClimateMonitorView::OnDraw(CDC* /*pDC*/) { CRect rect(0,0,0,0); //매개변수는 차례대로 left, top, right, bottom this->GetClientRect(rect); CClimateMonitorDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); //객체의 메모리 영역과 멤버 변수의 유효성 검사 if (!pDoc) return; if ( m_nViewMode == CM_VIEW_TEXT ) DrawList(m_hWnd, rect); } else DrawChart(m_hWnd, rect);

35 19장. GDI+ 그래픽 프로그래밍 6. ClimateMonitor 차트 기능 추가하기 좌표계의 변환과 이동 ☞ “행렬의 덧셈”은 좌표의 “이동”, “행렬의 곱셈”은 좌표의 “변환” (2,4) (4,2) [2 4] + [ ] = [4 2] [4 2] X = [ ] (4,-2)

36 19장. GDI+ 그래픽 프로그래밍 6. ClimateMonitor 차트 기능 추가하기 X축 Y축 X축 Y축

37 19장. GDI+ 그래픽 프로그래밍 6. ClimateMonitor 차트 기능 추가하기 텍스트가 기입됩니다.

38 6. ClimateMonitor 차트 기능 추가하기
19장. GDI+ 그래픽 프로그래밍 6. ClimateMonitor 차트 기능 추가하기 void CClimateMonitorView::DrawChart(HWND hwnd, CRect& rect) { Graphics graphics(hwnd); // 브러쉬 생성 SolidBrush redBrush(Color(255, 255, 0, 0)); SolidBrush blueBrush(Color(255, 0, 0, 255)); SolidBrush blackBrush(Color(255, 0, 0, 0)); // 폰트 생성 FontFamily fontFamily(L"굴림체"); Gdiplus::Font font(&fontFamily, 12, FontStyleRegular, UnitPixel); // 좌표계 초기화 하기... // 1) 막대 그래프의 좌표계 Matrix mtBar(1, 0, 0, -1, rect.left + 10, rect.Height() - 50); // 2) 텍스트의 좌표계 Matrix mtText(1, 0, 0, 1, 0, 0); // 막대 그래프의 너비 const int barWidth = 20.0f;

39 6. ClimateMonitor 차트 기능 추가하기
19장. GDI+ 그래픽 프로그래밍 6. ClimateMonitor 차트 기능 추가하기 CClimateMonitorDoc* pDoc = GetDocument(); for ( int i=0 ; i < pDoc->GetRecordCount() ; i++ ) { ClimateInfo* info = pDoc->GetClimateInfo(i); // 막대 그래프 좌표계 설정 // graphics.SetTransform(&mtBar); graphics.ScaleTransform(1.0f, 3.0f, MatrixOrderPrepend); graphics.FillRectangle(&redBrush, (i*OFFSET), 0, barWidth, info->Temperature); // 온도 그래프 graphics.FillRectangle(&blueBrush, (i*OFFSET)+barWidth, 0, barWidth, info->Humidity); // 습도 그래프 // 텍스트 좌표계 설정 // graphics.SetTransform(&mtText); graphics.TranslateTransform(rect.left + 10, rect.Height() -40, MatrixOrderAppend); graphics.ScaleTransform(1.0f, 1.0f, MatrixOrderPrepend); PointF ptWeather((float)i*OFFSET, 0.0f); PointF ptTime((float)i*OFFSET, 15.0f); // 날씨 출력 graphics.DrawString(info->Weather.AllocSysString(), -1, &font, ptWeather, &blackBrush); // 날짜 출력 graphics.DrawString(info->Time.AllocSysString(), -1, &font, ptTime, &blackBrush); } Matrix mtBar(1, 0, 0, -1, rect.left + 10, rect.Height() - 50); X축 Y축 rectHeight()-50 rectHeight() X축 Y축 10 50

40 6. ClimateMonitor 차트 기능 추가하기
19장. GDI+ 그래픽 프로그래밍 6. ClimateMonitor 차트 기능 추가하기 CClimateMonitorDoc* pDoc = GetDocument(); for ( int i=0 ; i < pDoc->GetRecordCount() ; i++ ) { ClimateInfo* info = pDoc->GetClimateInfo(i); // 막대 그래프 좌표계 설정 // graphics.SetTransform(&mtBar); graphics.ScaleTransform(1.0f, 3.0f, MatrixOrderPrepend); graphics.FillRectangle(&redBrush, (i*OFFSET), 0, barWidth, info->Temperature); // 온도 그래프 graphics.FillRectangle(&blueBrush, (i*OFFSET)+barWidth, 0, barWidth, info->Humidity); // 습도 그래프 // 텍스트 좌표계 설정 // graphics.SetTransform(&mtText); graphics.TranslateTransform(rect.left + 10, rect.Height() -40, MatrixOrderAppend); graphics.ScaleTransform(1.0f, 1.0f, MatrixOrderPrepend); PointF ptWeather((float)i*OFFSET, 0.0f); PointF ptTime((float)i*OFFSET, 15.0f); // 날씨 출력 graphics.DrawString(info->Weather.AllocSysString(), -1, &font, ptWeather, &blackBrush); // 날짜 출력 graphics.DrawString(info->Time.AllocSysString(), -1, &font, ptTime, &blackBrush); } 1 1

41 6. ClimateMonitor 차트 기능 추가하기
19장. GDI+ 그래픽 프로그래밍 6. ClimateMonitor 차트 기능 추가하기 CClimateMonitorDoc* pDoc = GetDocument(); for ( int i=0 ; i < pDoc->GetRecordCount() ; i++ ) { ClimateInfo* info = pDoc->GetClimateInfo(i); // 막대 그래프 좌표계 설정 // graphics.SetTransform(&mtBar); graphics.ScaleTransform(1.0f, 3.0f, MatrixOrderPrepend); graphics.FillRectangle(&redBrush, (i*OFFSET), 0, barWidth, info->Temperature); // 온도 그래프 // brush, x, y, width, height // OFFSET=125 graphics.FillRectangle(&blueBrush, (i*OFFSET)+barWidth, 0, barWidth, info->Humidity); // 습도 그래프 // 텍스트 좌표계 설정 // graphics.SetTransform(&mtText); graphics.TranslateTransform(rect.left + 10, rect.Height() -40, MatrixOrderAppend); graphics.ScaleTransform(1.0f, 1.0f, MatrixOrderPrepend); PointF ptWeather((float)i*OFFSET, 0.0f); PointF ptTime((float)i*OFFSET, 15.0f); // 날씨 출력 graphics.DrawString(info->Weather.AllocSysString(), -1, &font, ptWeather, &blackBrush); // 날짜 출력 graphics.DrawString(info->Time.AllocSysString(), -1, &font, ptTime, &blackBrush); }

42 6. ClimateMonitor 차트 기능 추가하기
19장. GDI+ 그래픽 프로그래밍 6. ClimateMonitor 차트 기능 추가하기 CClimateMonitorDoc* pDoc = GetDocument(); for ( int i=0 ; i < pDoc->GetRecordCount() ; i++ ) { ClimateInfo* info = pDoc->GetClimateInfo(i); // 막대 그래프 좌표계 설정 // graphics.SetTransform(&mtBar); graphics.ScaleTransform(1.0f, 3.0f, MatrixOrderPrepend); graphics.FillRectangle(&redBrush, (i*OFFSET), 0, barWidth, info->Temperature); // 온도 그래프 // 사용 brush, x, y, width, height // OFFSET=125 graphics.FillRectangle(&blueBrush, (i*OFFSET)+barWidth, 0, barWidth, info->Humidity); // 습도 그래프 // 텍스트 좌표계 설정 // graphics.SetTransform(&mtText); graphics.TranslateTransform(rect.left + 10, rect.Height() -40, MatrixOrderAppend); graphics.ScaleTransform(1.0f, 1.0f, MatrixOrderPrepend); PointF ptWeather((float)i*OFFSET, 0.0f); //x, y PointF ptTime((float)i*OFFSET, 15.0f); // 날씨 출력 //출력할 글자 정보, ?, 폰트, 위치, 사용 brush graphics.DrawString(info->Weather.AllocSysString(), -1, &font, ptWeather, &blackBrush); // 날짜 출력 graphics.DrawString(info->Time.AllocSysString(), -1, &font, ptTime, &blackBrush); } Matrix mtText(1, 0, 0, 1, 0, 0); 맑음 :40:12

43 6. ClimateMonitor 차트 기능 추가하기
19장. GDI+ 그래픽 프로그래밍 6. ClimateMonitor 차트 기능 추가하기 void CClimateMonitorView::DrawList(HWND hwnd, CRect& rect) { Graphics graphics(hwnd); // 좌표계 설정 graphics.TranslateTransform(0, rect.top, MatrixOrderAppend); // 브러쉬 생성 SolidBrush blackBrush(Color(255, 0, 0, 0)); // 폰트 생성 FontFamily fontFamily(L"굴림체"); Gdiplus::Font font(&fontFamily, 16, FontStyleRegular, UnitPixel); CClimateMonitorDoc* pDoc = GetDocument(); char tmp[7]; for ( int i=0; i<pDoc->GetRecordCount(); i++ ) { ClimateInfo* info = pDoc->GetClimateInfo(i); CString strTmp; strTmp = "날짜: " + info->Time; strTmp += ", 날씨: " + info->Weather; strTmp += ", 온도: "; sprintf(tmp, "%d", info->Temperature ); strTmp += tmp; strTmp += ", 습도: "; sprintf(tmp, "%d", info->Humidity ); PointF pt(rect.left, (float)i*25); graphics.DrawString(strTmp.AllocSysString(), -1, &font, pt, &blackBrush); // 텍스트 출력 }

44 6. ClimateMonitor 차트 기능 추가하기
19장. GDI+ 그래픽 프로그래밍 6. ClimateMonitor 차트 기능 추가하기 ID : ID_VIEW_CHART ID : ID_VIEW_TEXT 차트 보기 클릭 ☞ OnViewChart() 함수 실행 목록 보기 클릭 ☞ OnViewText() 함수 실행

45 6. ClimateMonitor 차트 기능 추가하기
19장. GDI+ 그래픽 프로그래밍 6. ClimateMonitor 차트 기능 추가하기 void CClimateMonitorView::OnViewChart() { // m_nViewMode 설정 m_nViewMode = CM_VIEW_CHART; //0 // 메뉴 체크 상태 변경 CMenu* menu = theApp.GetMainWnd()->GetMenu(); menu->CheckMenuItem(ID_VIEW_CHART, MF_CHECKED); menu->CheckMenuItem(ID_VIEW_TEXT, MF_UNCHECKED); Invalidate(TRUE); // OnDraw() 함수를 호출하도록 만든다. } void CClimateMonitorView::OnViewText() { // m_nViewMode 설정 m_nViewMode = CM_VIEW_TEXT; //1 // 메뉴체크상태변경 CMenu* menu = theApp.GetMainWnd()->GetMenu(); menu->CheckMenuItem(ID_VIEW_TEXT, MF_CHECKED); menu->CheckMenuItem(ID_VIEW_CHART, MF_UNCHECKED); Invalidate(TRUE); }

46 19장. GDI+ 그래픽 프로그래밍 6. ClimateMonitor 차트 기능 추가하기

47 6. ClimateMonitor 차트 기능 추가하기
19장. GDI+ 그래픽 프로그래밍 6. ClimateMonitor 차트 기능 추가하기 ☞ CClimateView의 부모 클래스를 CView에서 CScrollView로 바꿔준다. ☞ CScrollView 클래스를 이용하면 스크롤바와 함께 표시 영역을 벗어나는 부분을 표시할 수 있다. ☞ OnInitialUpdate() 함수를 추가한다. ☞ Cview::OnInitiaIupdate() 함수는 뷰가 다큐먼트와 결합한 후 자신이 표시되기 전에 호출된다. OnInitialUpdate() 함수 void CClimateMonitorView::OnInitialUpdate() { CScrollView::OnInitialUpdate(); CRect rect; this->GetClientRect(&rect); CSize sizeTotal(rect.Width(), rect.Height()); SetScrollSizes(MM_TEXT, sizeTotal); }

48 6. ClimateMonitor 차트 기능 추가하기
19장. GDI+ 그래픽 프로그래밍 6. ClimateMonitor 차트 기능 추가하기 OnDraw() 함수의 변경 ☞ 뷰가 표시해야 하는 영역을 계산해서 그 부분만 출력하도록 OnDraw() 함수를 변경한다. void CClimateMonitorView::OnDraw(CDC* /*pDC*/) { CRect rect(0,0,0,0); //매개변수는 차례대로 left, top, right, bottom this->GetClientRect(rect); CClimateMonitorDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; // 화면 스크롤 영역 계산 시작 CSize sizeTotal(rect.Width(), rect.Height()); if ( m_nViewMode == CM_VIEW_TEXT ) if ( pDoc->GetRecordCount() * 25 < rect.Height() ) sizeTotal.cy = rect.Height(); else sizeTotal.cy = pDoc->GetRecordCount() * 25; SetScrollSizes(MM_TEXT, sizeTotal); // 수직 방향으로 어느 곳을 사용자가 보려고 하는지를 계산 rect.top = rect.top - this->GetScrollPos(SB_VERT); DrawList(m_hWnd, rect); }

49 6. ClimateMonitor 차트 기능 추가하기
19장. GDI+ 그래픽 프로그래밍 6. ClimateMonitor 차트 기능 추가하기 OnDraw() 함수의 변경 ☞ 뷰가 표시해야 하는 영역을 계산해서 그 부분만 출력하도록 OnDraw() 함수를 변경한다. else { int ChartSize = pDoc->GetRecordCount() * OFFSET; if ( ChartSize < rect.Width() ) sizeTotal.cx = rect.Width(); sizeTotal.cx = ChartSize; SetScrollSizes(MM_TEXT, sizeTotal); // 수평 방향으로 어느 곳을 사용자가 보려고 하는지를 계산 rect.left = rect.left - this->GetScrollPos(SB_HORZ); DrawChart(m_hWnd, rect); }

50 OnVScroll() 함수 OnHScroll() 함수
19장. GDI+ 그래픽 프로그래밍 6. ClimateMonitor 차트 기능 추가하기 OnVScroll, OnHScroll 이벤트 처리기 추가 ☞ 수평 스크롤바를 움직였을 때는 OnVScroll 메시지가 발생하고 OnVScroll() 함수가 호출된다. ☞ 수직 스크롤바를 움직였을 때는 OnHScroll 메시지가 발생하고 OnHScroll() 함수가 호출된다. OnVScroll() 함수 void CClimateMonitorView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다. CScrollView::OnVScroll(nSBCode, nPos, pScrollBar); } OnHScroll() 함수 void CClimateMonitorView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다. CScrollView::OnHScroll(nSBCode, nPos, pScrollBar); }

51 22장. 라이브러리 만들기

52 계산기A 계산기B GUI 수식 분석기 GUI 수식 분석기 계산 엔진 계산 엔진
22장. 라이브러리 만들기 모듈화 프로그래밍 1. 라이브러리란? ☞ 라이브러리는 이러한 재사용 가능한 모듈의 모음을 말한다. ☞ 모듈의 형태는 소스 파일 그대로 일 수도 있지만, 대부분은 컴파일된 개체 파일(Object File) 수준의 이진 파일인 경우가 많다. 계산기A 계산기B GUI 수식 분석기 GUI 수식 분석기 계산 엔진 계산 엔진

53 ☞ 라이브러리의 기능을 사용하는 프로그램과 연결되어 하나의 실행 파일을 이룬다.
22장. 라이브러리 만들기 2. 라이브러리의 종류 ① 정적 라이브러리 ☞ 라이브러리의 기능을 사용하는 프로그램과 연결되어 하나의 실행 파일을 이룬다. ② 동적 라이브러리(Dynamic Link Library) ☞ 실행 파일에 같이 링크되지 않고 별도의 파일로 존재하고 있다가 실행 파일의 프로세스가 어떠한 기능을 호출할 때 동적으로 메모리에 로드되어 필요한 기능을 제공한다. EXE 파일 정적 라이브러리 EXE 파일 동적 라이브러리

54 BUT!! DLL에 새로운 함수나 클래스가 추가되면
22장. 라이브러리 만들기 3. 정적 라이브러리 VS 동적 라이브러리 ☞ 하드 디스크의 용량 측면, 메모리 공간 사용 측면에서 동적 라이브러리가 우세!! ☞ 라이브러리의 수정 측면에서 동적 라이브러리가 우세!! 빌드!! EXE 파일1 정적 라이브러리 EXE 파일2 EXE 파일3 EXE 파일1 동적 라이브러리 EXE 파일2 EXE 파일3 빌드!! 기존 함수나 클래스의 내용 Upgrade!! VS BUT!! DLL에 새로운 함수나 클래스가 추가되면 기존의 프로그램도 다시 빌드 기존 함수나 클래스의 내용 Upgrade!! 빌드!!

55 22장. 라이브러리 만들기 4. 정적 라이브러리 소스코드 lib 정적 라이브러리 컴파일 소스코드 obj 개체 파일 컴파일 링크
정적 라이브러리를 포함하는 프로그램의 실행 파일 생성 과정 소스코드 lib 정적 라이브러리 컴파일 소스코드 obj 개체 파일 컴파일 링크 obj 개체 파일 컴파일 소스코드 exe 실행파일

56 5. 계산기 프로그램을 위한 정적 라이브러리 만들기
22장. 라이브러리 만들기 5. 계산기 프로그램을 위한 정적 라이브러리 만들기 ① 프로젝트 생성

57 5. 계산기 프로그램을 위한 정적 라이브러리 만들기
22장. 라이브러리 만들기 5. 계산기 프로그램을 위한 정적 라이브러리 만들기 ① 프로젝트 생성

58 5. 계산기 프로그램을 위한 정적 라이브러리 만들기
22장. 라이브러리 만들기 5. 계산기 프로그램을 위한 정적 라이브러리 만들기 ① 프로젝트 생성

59 5. 계산기 프로그램을 위한 정적 라이브러리 만들기
22장. 라이브러리 만들기 5. 계산기 프로그램을 위한 정적 라이브러리 만들기 ① 프로젝트 생성

60 5. 계산기 프로그램을 위한 정적 라이브러리 만들기
22장. 라이브러리 만들기 5. 계산기 프로그램을 위한 정적 라이브러리 만들기 ② Calculator 클래스 추가하기

61 5. 계산기 프로그램을 위한 정적 라이브러리 만들기
22장. 라이브러리 만들기 5. 계산기 프로그램을 위한 정적 라이브러리 만들기 ② Calculator 클래스 추가하기

62 5. 계산기 프로그램을 위한 정적 라이브러리 만들기
22장. 라이브러리 만들기 5. 계산기 프로그램을 위한 정적 라이브러리 만들기 ② Calculator 클래스 추가하기

63 Calculator.cpp 코드 Calculator.h 코드
22장. 라이브러리 만들기 5. 계산기 프로그램을 위한 정적 라이브러리 만들기 ② 소스 코드 작성하기 Calculator.cpp 코드 #include "StdAfx.h" #include "Calculator.h" Calculator::Calculator(void) { } Calculator::~Calculator(void) int Calculator::Plus(int a, int b) return a+b; int Calculator::Minus(int a, int b) return a-b; int Calculator::Multiply(int a, int b) return a*b; int Calculator::Divide(int a, int b) return a/b; Calculator.h 코드 #pragma once class Calculator { public: Calculator(void); ~Calculator(void); int Plus(int a, int b); int Minus(int a, int b); int Multiply(int a, int b); int Divide(int a, int b); };

64 5. 계산기 프로그램을 위한 정적 라이브러리 만들기
22장. 라이브러리 만들기 5. 계산기 프로그램을 위한 정적 라이브러리 만들기 ③ 프로젝트 빌드하기 이제 프로젝트를 빌드하면 CalcLib.lib 파일이 생성된다.

65 6. 정적 라이브러리를 이용한 계산기 프로그램 만들기
22장. 라이브러리 만들기 6. 정적 라이브러리를 이용한 계산기 프로그램 만들기 ① 프로젝트 생성

66 6. 정적 라이브러리를 이용한 계산기 프로그램 만들기
22장. 라이브러리 만들기 6. 정적 라이브러리를 이용한 계산기 프로그램 만들기 ① 프로젝트 생성

67 6. 정적 라이브러리를 이용한 계산기 프로그램 만들기
22장. 라이브러리 만들기 6. 정적 라이브러리를 이용한 계산기 프로그램 만들기 ① 프로젝트 생성

68 6. 정적 라이브러리를 이용한 계산기 프로그램 만들기
22장. 라이브러리 만들기 6. 정적 라이브러리를 이용한 계산기 프로그램 만들기 ① 프로젝트 생성

69 CalcLib.lib가 제공하는 함수, 클래스, 변수를 알려줄께
22장. 라이브러리 만들기 6. 정적 라이브러리를 이용한 계산기 프로그램 만들기 ② 라이브러리와 헤더파일 복사하기 CalcLib.lib와 Calculator.h 파일을 LibCalculator 프로젝트 디렉토리에 복사해 넣는다. 그런데 Calculator.h 파일은 왜 추가해줄까? CalcLib.lib가 제공하는 함수, 클래스, 변수를 알려줄께 응용 프로그램을 빌드!! Visual C

70 6. 정적 라이브러리를 이용한 계산기 프로그램 만들기
22장. 라이브러리 만들기 6. 정적 라이브러리를 이용한 계산기 프로그램 만들기 ③ 프로젝트 입력 속성에 CalcLib.lib 추가하기 Visual C++에게 CalcLib.lib 라이브러리를 응용 프로그램에 포함시킬 것임을 알려준다.

71 6. 정적 라이브러리를 이용한 계산기 프로그램 만들기
22장. 라이브러리 만들기 6. 정적 라이브러리를 이용한 계산기 프로그램 만들기 ④ LibCalculator 프로젝트에 Calculator.h 파일 추가하기

72 6. 정적 라이브러리를 이용한 계산기 프로그램 만들기
22장. 라이브러리 만들기 6. 정적 라이브러리를 이용한 계산기 프로그램 만들기 ④ LibCalculator 프로젝트에 Calculator.h 파일 추가하기

73 LibCalculator.cpp 소스 코드
22장. 라이브러리 만들기 6. 정적 라이브러리를 이용한 계산기 프로그램 만들기 ⑤ LibCalculator.cpp 수정하기 LibCalculator.cpp 소스 코드 #include "stdafx.h" #include "Calculator.h" #include <iostream> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { Calculator calc; // Calculator 객체 생성 cout << " = " << calc.Plus(2, 3) << endl; cout << " = " << calc.Minus(4, 2) << endl; cout << "7 * 5 = " << calc.Multiply(7, 5) << endl; cout << "21 / 7 = " << calc.Divide(21, 7) << endl; return 0; }

74 6. 정적 라이브러리를 이용한 계산기 프로그램 만들기
22장. 라이브러리 만들기 6. 정적 라이브러리를 이용한 계산기 프로그램 만들기 ⑥ 빌드하고 실행하기

75 7. 동적 링크 라이브러리(Dynamic Link Library)
22장. 라이브러리 만들기 7. 동적 링크 라이브러리(Dynamic Link Library) DLLMain() : DLL의 시작과 끝 ☞ DLL이 실행되고 메모리에 적재된 뒤 DLL의 시동을 위해 진입점에서 호출되는 함수이다. 또한 DLL이 종료될 때에도 호출된다. DLLMain() 함수의 예 BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { return TRUE; } hModule은 DLL에 대한 핸들 DLL의 기본 주소 값을 가지고 있다. ul_reason_for_call은 DllMain() 함수가 호출된 이유를 설명한다. 설명 DLL_PROCESS_ATTACH 프로세스와 연결됨 DLL_THREAD_ATTACH 쓰레드와 연결됨 DLL_THREAD_DETACH 쓰레드와 분리됨 DLL_PROCESS_DETACH 프로세스와 분리됨 lpReserved는 ul_reason_for_call 매개 변수가 설명하는 DLL의 초기화와 종료에 대해 추가적인 정보를 제공한다.

76 7. 동적 링크 라이브러리(Dynamic Link Library)
22장. 라이브러리 만들기 7. 동적 링크 라이브러리(Dynamic Link Library) __declspec 키워드 : 내보내기와 가져오기 ① 내보내기 ☞ __declspec(export) 키워드를 사용한다. ☞ DLL을 빌드할 때 사용한다. ② 가져오기 ☞ __declspec(import) 키워드를 사용한다. ☞ 응용 프로그램을 빌드할 때 사용한다.

77 8. 계산기 프로그램을 위한 동적 링크 라이브러리 만들기
22장. 라이브러리 만들기 8. 계산기 프로그램을 위한 동적 링크 라이브러리 만들기 ① 프로젝트 생성 [파일] → [새로 만들기] → [프로젝트] 메뉴를 클릭하여 새 프로젝트 대화상자를 연다. [Visual C++] → [Win32] → [Win32 프로그램] 템플릿을 선택하고 프로젝트 이름을 “CalcDLL”로 입력한 후 [확인] 버튼을 클릭한다. 응용 프로그램 마법사가 나타나면 [응용 프로그램 설정] 항목을 선택하고 다음과 같이 구성을 변경한다. ☞ 응용 프로그램 종류 : DLL

78 8. 계산기 프로그램을 위한 동적 링크 라이브러리 만들기
22장. 라이브러리 만들기 8. 계산기 프로그램을 위한 동적 링크 라이브러리 만들기 ② 확인 사항 ③ Calculator 클래스 추가하기

79 Calculator.cpp 코드 Calculator.h 코드
22장. 라이브러리 만들기 8. 계산기 프로그램을 위한 동적 링크 라이브러리 만들기 ④ 소스 코드 작성하기 Calculator.cpp 코드 #include "StdAfx.h" #include "Calculator.h" Calculator::Calculator(void) { } Calculator::~Calculator(void) int Calculator::Plus(int a, int b) return a+b; int Calculator::Minus(int a, int b) return a-b; int Calculator::Multiply(int a, int b) return a*b; int Calculator::Divide(int a, int b) return a/b; Calculator.h 코드 #pragma once #ifdef CALCDLL_EXPORTS #define CALCDLL_API __declspec(dllexport) #else #define CALCDLL_API __declspec(dllimport) #endif class Calculator { public: Calculator(void); ~Calculator(void); int Plus(int a, int b); int Minus(int a, int b); int Multiply(int a, int b); int Divide(int a, int b); };

80 8. 계산기 프로그램을 위한 동적 링크 라이브러리 만들기 CalcDLL.cpp 코드
22장. 라이브러리 만들기 8. 계산기 프로그램을 위한 동적 링크 라이브러리 만들기 ⑤ CalcDLL.cpp 수정 CalcDLL.cpp 코드 #include "stdafx.h" #include <iostream> using namespace std; #ifdef _MANAGED #pragma managed(push, off) #endif BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { if (ul_reason_for_call == DLL_PROCESS_ATTACH) //프로세스와 연결될 때 cout << "CalcDll Initializing..." << endl; } else if (ul_reason_for_call == DLL_PROCESS_DETACH) //프로세스와 분리될 때 cout << "CalcDll Terminating..." << endl; return TRUE; #pragma managed(pop)

81 8. 계산기 프로그램을 위한 동적 링크 라이브러리 만들기
22장. 라이브러리 만들기 8. 계산기 프로그램을 위한 동적 링크 라이브러리 만들기 ⑥ 프로젝트 빌드 이제 프로젝트를 빌드하면 CalcDLL.dll, CalcDLL.lib 파일이 생성된다.

82 22장. 라이브러리 만들기 9. DLL을 사용한 계산기 만들기 ① 프로젝트 생성
[파일] → [새로 만들기] → [프로젝트] 메뉴를 클릭하여 새 프로젝트 대화상자를 연다. [Visual C++] → [Win32] → [Win32 콘솔 응용 프로그램] 템플릿을 선택하고 프로젝트 이름을 “DLLCalculator”로 입력한 후 [확인] 버튼을 클릭한다. 응용 프로그램 마법사가 나타나면 [응용 프로그램 설정] 항목을 선택하고 다음과 같이 구성을 변경한다. ☞ 응용 프로그램 종류 : 콘솔 응용 프로그램, 미리 컴파일된 헤더 : 확인

83 그런데 Calculator.lib 파일은 왜 추가해줄까?
22장. 라이브러리 만들기 9. DLL을 사용한 계산기 만들기 ② CalcDLL.dll, CalcDLL.lib, Calculator.h 복사하기 CalcDLL.dll, CalcDLL.lib, Calculator.h 파일을 LibCalculator 프로젝트 디렉토리에 복사해 넣는다. 그런데 Calculator.lib 파일은 왜 추가해줄까? ☞ CalcDLL.dll을 사용하려면 CalcDLL.dll의 내보내기 정보를 링크해야 한다. 이 내보내기 정보는 CalcDLL.lib 파일에 빌드되어 있으므로 이 파일을 Visual C++에게 응용 프로그램과 함께 빌드할 것임을 알려줘야 한다.

84 22장. 라이브러리 만들기 9. DLL을 사용한 계산기 만들기 DLLCalculator.cpp 코드
③ 프로젝트 입력 속성에 CalcDLL.lib 추가하기 프로젝트 속성 페이지에서 [구성 속성] → [링커] → [입력] 항목을 선택하고 세부 항목 중 [추가 종속성]에 “CalcDLL.lib”를 명시한다. ④ DLLCalculator 프로젝트에 Calculator.h 파일 추가하기 솔루션 뷰에서 [DLLCalculator] → [헤더 파일] 항목 위에서 오른쪽 마우스 버튼을 클릭하고 이 때 나타난 팝업 메뉴에서 [추가] → [기존 항목] 선택 대화상자가 나타나면 Calculator.h 파일을 선택하고 [추가] 버튼을 클릭한다. ⑤ DLLCalculator.cpp 수정하기 DLLCalculator.cpp 코드 #include "stdafx.h" #include "Calculator.h" #include <iostream> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { Calculator calc; // Calculator 객체 생성 cout << " = " << calc.Plus(2, 3) << endl; cout << " = " << calc.Minus(4, 2) << endl; cout << "7 * 5 = " << calc.Multiply(7, 5) << endl; cout << "21 / 7 = " << calc.Divide(21, 7) << endl; return 0; }

85 22장. 라이브러리 만들기 9. DLL을 사용한 계산기 만들기 ⑥ 빌드하고 실행하기

86 22장. 라이브러리 만들기 9. DLL을 사용한 계산기 만들기
DLL을 다른 응용 프로그램과 공유해서 사용하고 싶다면 해당 DLL을 윈도우 디렉토리나 시스템 디렉토리에 넣으면 된다.

87 22장. 라이브러리 만들기 10. MFC DLL이란? MFC를 이용하여 만든 DLL 11. MFC DLL의 종류 ① 기본 MFC DLL ☞ 함수만 내보낼 수 있다. ☞ 다른 언어나 툴에서 사용이 가능하다. ② 확장 MFC DLL ☞ C++ 클래스들과 전역 함수를 모두 내보낼 수 있다. ☞ 다른 언어나 툴에서 사용이 불가능하다.

88 Class AFX_EXT_CLASS MyClass { // … };
22장. 라이브러리 만들기 12. 확장 MFC DLL의 내보내기와 가져오기 비주얼 C++는 AFX_EXT_CLASS로 선언된 클래스를 확장 MFC DLL을 빌드할 때는 내보내고, 응용 프로그램을 빌드 할 때는 가져온다. Class AFX_EXT_CLASS MyClass { // … };

89 IntStack.h IntStack.cpp
22장. 라이브러리 만들기 13. 확장 MFC DLL 만들기 ① 프로젝트 생성 [파일] → [새로 만들기] → [프로젝트] 메뉴를 클릭하여 새 프로젝트 대화상자를 연다. [Visual C++] → [MFC] → [MFC DLL] 템플릿을 선택하고 프로젝트 이름을 “DLLStack”로 입력한 후 [확인] 버튼을 클릭한다. MFC DLL 마법사가 나타나면 [응용 프로그램 설정] 항목을 선택하고 다음과 같이 구성을 변경한다. ☞ DLL 형식 : MFC 확장 DLL ② 소스 코드 작성하기 IntStack.h #pragma once class AFX_EXT_CLASS CIntStack : public CObject { public: CIntStack(); virtual ~CIntStack(); void Push(int element); // 스택에 요소 쌓기 int Pop(void); // 스택의 최상위 요소 꺼내기 int GetStackSize(); // 스택의 요소 수 반환 private: CList<int> m_listStack; // 스택의 실제 데이터를 담는 자료구조 }; IntStack.cpp #include "stdafx.h" #include "IntStack.h" CIntStack::CIntStack(){} CIntStack::~CIntStack(){} void CIntStack::Push(int element) { m_listStack.AddTail(element); } int CIntStack::Pop(void) int tail = m_listStack.GetTail(); m_listStack.RemoveTail(); return tail; int CIntStack::GetStackSize() return m_listStack.GetCount();

90 이제 프로젝트를 빌드하면 DLLStack.dll, DLLStack.lib 파일이 생성된다.
22장. 라이브러리 만들기 13. 확장 MFC DLL 만들기 ③ 프로젝트 빌드 이제 프로젝트를 빌드하면 DLLStack.dll, DLLStack.lib 파일이 생성된다.

91 13. 확장 MFC DLL을 이용한 응용 프로그램 만들기
22장. 라이브러리 만들기 13. 확장 MFC DLL을 이용한 응용 프로그램 만들기 ① 프로젝트 생성 [파일] → [새로 만들기] → [프로젝트] 메뉴를 클릭하여 새 프로젝트 대화상자를 연다. [Visual C++] → [Win32] → [Win32 콘솔 응용 프로그램] 템플릿을 선택하고 프로젝트 이름을 “StackTester”로 입력한 후 [확인] 버튼을 클릭한다. 응용 프로그램 마법사가 나타나면 [응용 프로그램 설정] 항목을 선택하고 다음과 같이 구성을 변경한다. ☞ 응용 프로그램 종류 : 콘솔 응용 프로그램, 공용 헤더 파일 추가 대상 : MFC ② DLLStack.dll, DLLStack.lib, IntStack.h 복사하기 DLLStack.dll, DLLStack.lib, IntStack.h 파일을 StackTester 프로젝트 디렉토리에 복사해 넣는다. ③ 프로젝트 입력 속성에 DLLStack.lib 추가하기 프로젝트 속성 페이지에서 [구성 속성] → [링커] → [입력] 항목을 선택하고 세부 항목 중 [추가 종속성]에 “DLLStack.lib”를 명시한다. ④ StackTester 프로젝트에 IntStack.h 파일 추가하기 솔루션 뷰에서 [StackTester] → [헤더 파일] 항목 위에서 오른쪽 마우스 버튼을 클릭하고 이 때 나타난 팝업 메뉴에서 [추가] → [기존 항목] 선택 대화상자가 나타나면 IntStack.h 파일을 선택하고 [추가] 버튼을 클릭한다.

92 13. 확장 MFC DLL을 이용한 응용 프로그램 만들기 StackTester.cpp 코드
22장. 라이브러리 만들기 13. 확장 MFC DLL을 이용한 응용 프로그램 만들기 ⑤ StackTester.cpp 수정하기 StackTester.cpp 코드 #include "stdafx.h" #include "StackTester.h" #include "IntStack.h" #ifdef _DEBUG #define new DEBUG_NEW #endif CWinApp theApp; using namespace std; int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) { int nRetCode = 0; // MFC를 초기화합니다. 초기화하지 못한 경우 오류를 인쇄합니다. if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)) // TODO: 오류 코드를 필요에 따라 수정합니다. _tprintf(_T("심각한 오류: MFC를 초기화하지 못했습니다.\n")); nRetCode = 1; } else CIntStack stack; stack.Push(123); stack.Push(456); stack.Push(789); int size = stack.GetStackSize(); for ( int i=0; i<size; i++ ) cout << stack.Pop() << endl; return nRetCode;

93 13. 확장 MFC DLL을 이용한 응용 프로그램 만들기
22장. 라이브러리 만들기 13. 확장 MFC DLL을 이용한 응용 프로그램 만들기 ⑥ 빌드하고 실행하기


Download ppt "Visual C programming Seminar"

Similar presentations


Ads by Google