08장 윈도우에서의 그리기

Similar documents
MFC 프로그래밍

슬라이드 1

Chapter 1. MFC 시작하기

Microsoft PowerPoint - 09-CE-7-선과 도형

Microsoft PowerPoint - 11주차.pptx

Microsoft PowerPoint - hci2-lecture4.ppt

그래픽 프로그래밍

10 장세균전프로그래밍 10.1 게임룰 (1) 사람과컴퓨터가싸우는 2인용보드게임이다. (2) 사람이먼저움직이고, 컴퓨터가움직인다. (3) 세균을가로및세로방향으로 2칸까지빈칸으로이동시킬수있다. (4) 1칸을이동할경우에는복제가된다. (5) 이동한후주변세균은내편으로바뀐다.

Microsoft PowerPoint - CPP_chap3

설계란 무엇인가?

GDI 와 DC GDI (Graphics Device Iterface) 응용프로그램이하드웨어를제어할수있도록윈도우 OS 가제공하는모든기능 윈도우가출력장치에대한정보를스스로판단하고분석하여, 실제로사용할드라이버를불러옴 이를이용할경우, 하드웨어독립적인프로그래밍을할수있음 Widw

윈도우시스템프로그래밍

Visual C++의 개요

쉽게 풀어쓴 C 프로그래밍

PowerPoint 프레젠테이션

디지털영상처리3

5장 MFC기반 다지기

1. 객체의생성과대입 int 형변수 : 선언과동시에초기화하는방법 (C++) int a = 3; int a(3); // 기본타입역시클래스와같이처리가능 객체의생성 ( 복습 ) class CPoint private : int x, y; public : CPoint(int a

PowerPoint Presentation

GDI의 개념

쉽게 풀어쓴 C 프로그래밍

윈도우시스템프로그래밍

Programming hwp

untitled

12 강. 문자출력 Direct3D 에서는문자를출력하기위해서 LPD3DXFONT 객체를사용한다 LPD3DXFONT 객체생성과초기화 LPD3DXFONT 객체를생성하고초기화하는함수로 D3DXCreateFont() 가있다. HRESULT D3DXCreateFont

윈도우 프로그래밍의 개념

[ 마이크로프로세서 1] 2 주차 3 차시. 포인터와구조체 2 주차 3 차시포인터와구조체 학습목표 1. C 언어에서가장어려운포인터와구조체를설명할수있다. 2. Call By Value 와 Call By Reference 를구분할수있다. 학습내용 1 : 함수 (Functi

윈도우시스템프로그래밍

Microsoft PowerPoint - chap02-C프로그램시작하기.pptx

<4D F736F F F696E74202D203032C0E520C0AFC6BFB8AEC6BC20C5ACB7A1BDBABFCD20C1FDC7D520C5ACB7A1BDBA5FBFB5B3B2C0CCB0F8B4EB205BC8A3C8AF20B8F0B5E55D>

BMP 파일 처리

Microsoft PowerPoint - C++ 5 .pptx

4S 1차년도 평가 발표자료

JAVA 프로그래밍실습 실습 1) 실습목표 - 메소드개념이해하기 - 매개변수이해하기 - 새메소드만들기 - Math 클래스의기존메소드이용하기 ( ) 문제 - 직사각형모양의땅이있다. 이땅의둘레, 면적과대각

PowerPoint Presentation

4 장클래스와객체 클래스와객체 public과 private 구조체와클래스객체의생성과생성자객체의소멸과소멸자생성자와소멸자의호출순서디폴트생성자와디폴트소멸자멤버초기화멤버함수의외부정의멤버함수의인라인함수선언 C++ 프로그래밍입문

설계란 무엇인가?

금오공대 컴퓨터공학전공 강의자료

JAVA PROGRAMMING 실습 08.다형성

슬라이드 1

Microsoft PowerPoint - hci2-lecture11.ppt

Microsoft PowerPoint - hci2-lecture11.ppt

(Microsoft PowerPoint - 07\300\345.ppt [\310\243\310\257 \270\360\265\345])

1. 클래스와배열 int 형배열선언및초기화 int ary[5] = 1, 2, 3, 4, 5 ; for (int i = 0; i < 5; i++) cout << "ary[" << i << "] = " << ary[i] << endl; 5 장클래스의활용 1

<4D F736F F F696E74202D203036C0E520BBE7BFEBC0DA20C0CEC5CDC6E4C0CCBDBA205BC8A3C8AF20B8F0B5E55D>

1. auto_ptr 다음프로그램의문제점은무엇인가? void func(void) int *p = new int; cout << " 양수입력 : "; cin >> *p; if (*p <= 0) cout << " 양수를입력해야합니다 " << endl; return; 동적할

gnu-lee-oop-kor-lec06-3-chap7

<4D F736F F F696E74202D20C1A63034B0AD202D20C7C1B7B9C0D3B8AEBDBAB3CABFCD20B9ABB9F6C6DBC0D4B7C2>

PowerPoint Presentation

디지털영상처리3

<B9CCB5F0BEEE20C1A4BAB8C3B3B8AE2E687770>

<4D F736F F F696E74202D20C1A C0E520B5B5C5A5B8D5C6AE20C6C4C0CF20C0D4C3E2B7C220B9D720B4D9BEE7C7D120BAE420C5ACB7A1BDBA2E BC8A3C8AF20B8F0B5E55D>

C# Programming Guide - Types

歯Lecture2.PDF

1장 윈도우 프로그래밍 들어가기

C++ Programming

Microsoft PowerPoint - hci2-lecture5-messagemap.ppt

Microsoft PowerPoint - 04windows.ppt

KNK_C_05_Pointers_Arrays_structures_summary_v02

슬라이드 1

Microsoft PowerPoint - chap11-포인터의활용.pptx

Programming hwp

chap 5: Trees

Microsoft PowerPoint - hci2-lecture7.ppt

슬라이드 1

Microsoft PowerPoint _대화상자.ppt

JVM 메모리구조

PowerPoint Presentation

C++ Programming

Microsoft PowerPoint - hci2-lecture10.ppt

<4D F736F F F696E74202D2036C0CFC2B05FB0B4C3BCC1F6C7E2C7C1B7CEB1D7B7A1B9D62E707074>

Microsoft PowerPoint - 09-CE-5-윈도우 핸들

Lab 3. 실습문제 (Single linked list)_해답.hwp

윈도우즈 프로그래밍

<33372DC0A9B5B5BFECC7C1B7CEB1D7B7A1B9D62E687770>

Microsoft PowerPoint - 8ÀÏ°_Æ÷ÀÎÅÍ.ppt

API - Notification 메크로를통하여어느특정상황이되었을때 SolidWorks 및보낸경로를통하여알림메시지를보낼수있습니다. 이번기술자료에서는메크로에서이벤트처리기를통하여진행할예정이며, 메크로에서작업을수행하는데유용할것입니다. 알림이벤트핸들러는응용프로그램구현하는데있어

안드로이드기본 11 차시어댑터뷰 1 학습목표 어댑터뷰가무엇인지알수있다. 리스트뷰와스피너를사용하여데이터를출력할수있다. 2 확인해볼까? 3 어댑터뷰 1) 학습하기 어댑터뷰 - 1 -

윈도우 프로그래밍의 개념

윈도우 프로그래밍의 개념

1. 상속의기본개념 다음과같은문제를위한클래스설계 자동차 속성 : 색상, 배기량, 현재속도 메서드 : 가속하라, 멈춰라, 시동을켜라 트럭 속성 : 색상, 배기량, 현재속도, 최대중량 메서드 : 가속하라, 멈춰라, 시동을켜라 택시 속성 : 색상, 배기량, 현재속도, 요금,

(Microsoft PowerPoint - 11\300\345.ppt [\310\243\310\257 \270\360\265\345])

Frama-C/JESSIS 사용법 소개

<322EBCF8C8AF28BFACBDC0B9AEC1A6292E687770>

adfasdfasfdasfasfadf

Windows 8에서 BioStar 1 설치하기

학습목차 2.1 다차원배열이란 차원배열의주소와값의참조

어댑터뷰

PowerPoint 프레젠테이션

PowerPoint Template

; struct point p[10] = {{1, 2, {5, -3, {-3, 5, {-6, -2, {2, 2, {-3, -3, {-9, 2, {7, 8, {-6, 4, {8, -5; for (i = 0; i < 10; i++){ if (p[i].x > 0 && p[i

Microsoft PowerPoint - Chap12-OOP.ppt

Microsoft PowerPoint - ch07 - 포인터 pm0415

UI TASK & KEY EVENT

Microsoft PowerPoint - chap10-함수의활용.pptx

Convenience Timetable Design

Microsoft PowerPoint - hci2-lecture3.ppt

Microsoft PowerPoint - MFC-교재.ppt

구조체정의 자료형 (data types) 기본자료형 (primitive data types) : char, int, float 등과같이 C 언어에서제공하는자료형. 사용자정의자료형 (user-defined data types) : 다양한자료형을묶어서목적에따라새로운자료형을

Microsoft Word - hci07-final-answer.doc

Transcription:

8 장 윈도우에서의그리기 김성영교수 금오공과대학교 컴퓨터공학부

그래픽장치인터페이스객체 GDI 객체 객체의핸들타입 MFC 클래스속성 HPEN CPen 선속성 HBRUSH CBrush 채우기속성 HFONT CFont 글꼴속성 HBITMAP CBitmap 비트맵영상속성 HPALETTE CPalette 팔레트속성 HRGN CRgn 영역속성 GDI 클래스는 CGdiObject 클래스로부터상속 GDI 객체의핸들을할당할수있는멤버변수를가짐 class CGdiObject : public CObject { HANDLE m_hobject; // GDI 객체에대한핸들 } 2

윈도우가 GDI 객체를만들어각객체의속성에기본값설정 선을그리는경우 시작점과끝점만제공하면선을그릴수있음 MoveTo( int x, int y ) // 지정한위치로이동 LineTo( int x, int y ) // 현재위치에서지정된위치까지선을그음 사각형을그리는경우 Rectangle( int x1, int y1, int x2, int y2 ) // 각진사각형 RoundRect( int x1, int y1, int x2, int y2, int x3, int y3 ) // 모서리가둥근사각형 3

CDC 클래스 - 디바이스컨텍스트 (Device Context, DC) 구조체 - HDC 는 DC 를가리키는핸들 4

class CDC : public CObject { HDC m_hdc; // DC에대한핸들 BOOL LineTo( int x, int y ); BOOL Rectangle( int x1, int y1, int x2, int y2 ); } 멤버변수 : HDC 멤버함수 : Rectangle() 등의그리기함수 CDC 클래스를이용한그리기 GDI 객체를가리키고있는 DC 를준비 CDC* pdc; pdc = GetDC(); // DC 요청 pdc->rectangle(0, 0, 100, 100); // 그리기관련함수 (GetDC와 ReleaseDC 사이 ) ReleaseDC(pDC); // DC 반환 CDC: http://msdn.microsoft.com/ko-kr/library/4acfw2ha(vs.80).aspx 5

그리기의전형적인형태 기본으로설정된속성값을바꾸고자할때기존에생성된객체의속성을바꾸는대신새로운객체생성 검은색선을회색으로바꾸려면.. 1 회색속성을가진펜객체생성 2 DC 는검은색펜객체를가리키던연결선을끊음 3 DC 는새로생성한회색펜객체를연결 6

SelectObject() 함수 - 2, 3 과정처리 - GDI 객체별로존재 - 기존 GDI 객체의주소값반환 CPen* SelectObject( CPen* ppen ); CBrush* SelectObject( CBrush* pbrush ); CFont* SelectObject( CFont* pfont ); CBitmap* SelectObject( CBitmap* pbitmap ); int SelectObject( CRgn* prgn ); 윈도우가생성해놓은 DC 값이바뀔수도있으므로 GetDC() 함수에의해할당된 DC 는독점적으로사용 사용이끝나면 ReleaseDC() 함수로사용하지않음을알림 7

출력작업이끝나면 DC 를이전상태로되돌림 - SelectObject() 함수를다시호출하여이전 GDI 객체복원 새로생성하여사용한객체는메모리에서제거 CDC* pdc; pdc = GetDC(); CPen* oldpen, pen; pen.createpen( PS_SOLID, 1, RGB(128,128,128) ); oldpen = pdc->selectobject( &pen ); pdc->rectangle( 0, 0, 100, 100 ); pdc->selectobject( oldpen ); pen.deleteobject( ); ReleaseDC( pdc ); // 회색펜생성 // 새로생성한회색펜선택 // 회색테두리를가진사각형그림 // 이전검은펜복구 // 생성한펜을제거 8

CClientDC 클래스를사용하여위코드를아래와같이대체가능 - 생성자에서 GetDC(), 소멸자에서 ReleaseDC() 호출 - 단, CClientDC 클래스는클라이언트영역만담당 CClientDC dc( this ); pen.createpen( PS_SOLID, 1, RGB(128,128,128) ); oldpen = dc. SelectObject( &pen ); dc.rectangle( 0, 0, 100, 100 ); dc.selectobject( oldpen ); pen.deleteobject( ); 9

실습 8.1 마우스클릭위치를중심으로스타일을갖는사각형을그려보자. 마우스클릭처리는 CMyView 클래스의 WM_LBUTTONDWN 메시지핸들러에서처리 10

화면출력준비 / 사각형그리기는 Rectangle() 함수이용 void CMyView::OnLButtonDown( UINT nflags, CPoint point ) { CDC* pdc; pdc = GetDC( ); // DC 준비 MyView.cpp CRect rt; rt.left = point.x - 50; rt.top = point.y - 50; rt.right = point.x + 50; rt.bottom = point.y + 50; pdc->rectangle( rt ); // 사각형그림 ReleaseDC(pDC); // DC 반환 } CView::OnLButtonDown( nflags, point ); 11

브러쉬객체생성은 CreateSolidBrush() 함수사용 MyView.cpp void CMyView::OnLButtonDown( UINT nflags, CPoint point ) { CPen pen, *oldpen; // 펜객체선언 pen.createpen( PS_SOLID, 5, RGB(0,0,255) ); // 파란펜생성 oldpen = pdc->selectobject( &pen ); // 파란펜선택 & 이전펜저장 CBrush br, *oldbr; // 브러시객체선언 br.createsolidbrush( RGB(255,0,0) ); // 빨간브러쉬생성 oldbr = pdc->selectobject( &br ); // 빨간브러쉬선택 & 이전브러쉬저장 pdc->rectangle(rt); } pdc->selectobject(oldpen); // 이전펜으로복귀 pdc->selectobject(oldbr); // 이전브러쉬로복귀 pen.deleteobject(); // 펜객체제거 br.deleteobject(); // 브러쉬객체제거 12

참고 자주사용하는 GDI 객체는미리생성하고상수형태로제공 BLACK_BRUSH, DKGRAY_BRUSH, GRAY_BRUSH LTGRAY_BRUSH, NULL_BRUSH, WHITE_BRUSH BLACK_PEN, NULL_PEN, WHITE_PEN virtual CGdiObject* SelectStockObject( int nindex ); 13

WM_PAINT 메시지 실습 8.2 [ 실습 8.1] 에이어서윈도우가다른윈도우에가려졌다가다시나타났을때사각형이지워지지않도록해보자. WM_LBUTTONDOWN 메시지핸들러코드를 OnDraw() 함수로이동 DC 는 OnDraw() 함수의인자에포함된것을사용 출력위치는 WM_LBUTTONDOWN 메시지핸들러의인자로넘어온좌표를 OnDraw() 에서사용 멤버변수로선언 14

class CMyView : public CView { private: CPoint m_point; // 마우스클릭위치저장 } CMyView::CMyView( ) { m_point = CPoint( -100, -100 ); // 화면에서보이지않도록초기화 } void CMyView::OnDraw( CDC* pdc ) { CMyDoc* pdoc = GetDocument( ); ASSERT_VALID( pdoc ); MyView.h MyView.cpp CRect rt; rt.left = m_point.x - 50; rt.top = m_point.y - 50; rt.right = m_point.x + 50; rt.bottom = m_point.y + 50; 15

CPen pen, *oldpen; pen.createpen( PS_SOLID, 5, RGB(0,0,255) ); oldpen = pdc->selectobject( &pen ); CBrush br, *oldbr; br.createsolidbrush( RGB(255,0,0) ); oldbr = pdc->selectobject( &br ); pdc->rectangle( rt ); pdc->selectobject( oldpen ); pdc->selectobject(o ldbr ); pen.deleteobject(); br.deleteobject(); } void CMyView::OnLButtonDown( UINT nflags, CPoint point ) { m_point = point; // 현재마우스위치저장 CView::OnLButtonDown( nflags, point ); } 16

프로그램실행후왼쪽버튼을눌러도반응없음 명시적으로 WM_PAINT 메시지를발생시키는 UpdateWindow() 함수호출 void CMyView::OnLButtonDown( UINT nflags, CPoint point ) { m_point = point; // 현재마우스위치저장 UpdateWindow( ); // 명시적으로 WM_PAINT 메시지발생 CView::OnLButtonDown( nflags, point ); } MyView.cpp 17

이전에그려졌던것과비교해서무효한영역이있을때만새로그림 무효화영역을임의로만들기위해서는 CWnd 클래스의 Invalidate() 또는 InvalidateRect() 함수를사용 void Invalidate( BOOL berase = TRUE ); void InvalidateRect( LPCRECT lprect, BOOL berase = TRUE ); MyView.cpp void CMyView::OnLButtonDown( UINT nflags, CPoint point ) { m_point = point; // 현재마우스위치저장 Invalidate(); // 윈도우영역을무효화시킴 UpdateWindow( ); // 명시적으로 WM_PAINT 메시지발생 ( 생략가능 ) CView::OnLButtonDown( nflags, point ); } 18

참고 클릭한모든마우스좌표에대한사각형을다시그리고자한다면? 집합클래스 (Collection Class) 사용 : 배열 (array), 리스트 (list), 맵 (map) CArray CByteArray CArray<CPoint, CPoint&> array; CByteArray array; CArray<CPoint, CPoint&> array; array.setsize( 5 ); for( int i=0; i<5; i++ ) { CPoint pt( i, i*5 ); array[i] = pt; } 19

비트맵 비트맵객체는픽셀단위로표현된영상을다룸 리소스편집기를이용해비트맵을생성및출력 실습 8.3 마우스클릭위치에문자열을출력하는프로그램을작성하자. 단, 출력할문자열은리소스로등록한것을사용하고도큐먼트 - 뷰구조에충실하게작성한다. 20

도큐먼트 - 뷰구조에따른코딩 리소스편집기에서문자열리소스추가 - 리소스뷰탭에서 String Table 을선택 - 문자열테이블의마지막빈칸을클릭 21

속성창 - 문자열의아이디 IDS_MYSTRING 입력 - Caption 리소스편집기문자열입니다 입력 22

도큐먼트 - 뷰구조 - 도큐먼트 데이터처리 - 뷰 출력담당 도큐먼트클래스에리소스에있는문자열을저장하기위한변수선언 class CMyDoc : public CDocument { public: CString m_strmsg; } MyView.h 리소스의문자열을읽어오는함수 CString::LoadString( UINT nid ); 23

도큐먼트 데이터처리 사용할초기데이터의로딩은도큐먼트가초기화될때하는것이적절 CMyDoc::OnNewDocument( ) 함수에서처리 BOOL CMyDoc::OnNewDocument( ) { if (!CDocument::OnNewDocument() ) return FALSE; MyDoc.cpp // TODO: add reinitialization code here // (SDI documents will reuse this document) m_strmsg.loadstring( IDS_MYSTRING ); // 리소스에서문자열을읽어옴 } return TRUE; 24

뷰 - 출력 마우스왼쪽버튼을누르면출력되도록 WM_LBUTTONDOWN 메시지핸들러에코드추가 GetDocument() 도큐먼트객체주소획득 void CMyView::OnLButtonDown( UINT nflags, CPoint point ) { CString strmsg; CMyDoc* pdoc; pdoc = GetDocument( ); strmsg = pdoc->m_strmsg; MyView.cpp CClientDC dc( this ); dc.textout( point.x, point.y, strmsg, strmsg.getlength() ); } CView::OnLButtonDown( nflags, point ); 25

실습 8.4 마우스클릭위치에다음그림과같은영상을출력해보자. 26

비트맵리소스편집 비트맵도문자열과같이하나의리소스 리소스편집기사용 리소스추가대화상자 - 리소스뷰탭의 My.rc 에서마우스오른쪽버튼을눌러컨텍스트메뉴를활성화 - 리소스추가 (Insert..) 항목클릭 27

비트맵을선택하고 New 버튼클릭 비트맵편집창 편집내용은 IDB_BITMAP1 로설정 28

비트맵클래스를통해비트맵리소스를읽어옴 BOOL LoadBitmap( UINT nidresource ) 비트맵영상은화면에보이지않게일반메모리에먼저옮겨진후, 화면메모리로한꺼번에복사하여빠르게출력 메모리로비트맵을선택하는방법은메모리 DC 이용 CBitmap bmp; bmp.loadbitmap( IDB_BITMAP1 ); CDC* pdc; // 화면 DC pdc = GetDC( ); CDC memdc; // 메모리 DC memdc.createcompatibledc( pdc ); // 화면 DC 와호환이되도록생성 memdc.selectobject( &bmp ); 29

메모리 DC 의형식은화면 DC 와호환되도록 CreateCompatibleDC() 함수를이용해생성 비트맵관련정보 BITMAP 구조체에저장 typedef struct tagbitmap { LONG bmtype; //0으로설정 LONG bmwidth; // 비트맵의픽셀단위가로크기 LONG bmheight // 비트맵의픽셀단위세로크기 LONG bmwidthbytes; // 비트맵의바이트단위가로크기 ( 짝수 ) WORD bmplanes; // 컬러판의수 WORD bmbitspixel; // 필셀당할당된비트수 LPVOID bmbits; // 영상이저장된시작주소 } BITMAP; 30

BITMAP 정보는비트맵클래스의 GetObject() 함수를통해얻어올수있다 CBitmap bmp; bmp.loadbitmap( IDB_BITMAP1 ); BITMAP bm; bmp.getobject( sizeof(bm), &bm ); // 비트맵영상정보얻기 int width, height; width = bm.bmwidth; height = bm.bmheight; 31

메모리 DC 의내용을화면 DC 로복사 BitBlt() void CMyView::OnLButtonDown(UINT nflags, CPoint point) { CBitmap bmp; bmp.loadbitmap( IDB_BITMAP1 ); MyView.cpp CDC* pdc; CDC memdc; pdc = GetDC( ); memdc.createcompatibledc( pdc ); // 복사를위해화면 DC 와호환되도록생성 memdc.selectobject( &bmp );// 메모리에그림 BITMAP bm; bmp.getobject( sizeof(bm), &bm ); // 비트맵관련정보획득 32

pdc->bitblt( point.x, // 출력가로위치 point.y, // 출력세로위치 bm.bmwidth, // 비트맵가로크기 bm.bmheight, // 비트맵세로크기 &memdc, // 원본 ( 메모리 ) DC의주소 0, // 복사시작할비트맵의가로좌표 0, // 복사시작할비트맵의세로좌표 SRCCOPY // 원본을그대로복사 ); memdc.deletedc( ); // 메모리 DC 해제 ReleaseDC( pdc ); // 화면 DC 해제 } CView::OnLButtonDown(nFlags, point); 33

실습 8.5 비트맵을다시작성하지않고비트맵을확대해보자. 34

비트맵크기변경출력 비트맵크기변화는메모리 DC 의내용을화면 DC 로복사하는과정에서 CDC 클래스의 StretchBlt() 함수를통해조정가능 BOOL StretchBlt( int x, // 출력가로위치 int y, // 출력세로위치 int nwidth, // 출력비트맵가로크기 int nheight, // 출력비트맵세로크기 CDC* psrcdc, // 원본 ( 메모리 ) DC의주소 int xsrc, // 복사시작할비트맵의가로좌표 int ysrc, // 복사시작할비트맵의세로좌표 int nsrcwidth, // 원본비트맵가로크기 int nsrcheight, // 원본비트맵세로크기 DWORD dwrop // 그리기모드 ); 35

메모리 DC 의내용을확대하여화면 DC 로복사 StretchBlt() void CMyView::OnLButtonDown(UINT nflags, CPoint point) { CBitmap bmp; bmp.loadbitmap( IDB_BITMAP1 ); MyView.cpp CDC* pdc; CDC memdc; pdc = GetDC( ); memdc.createcompatibledc( pdc ); // 복사를위해화면 DC 와호환되도록생성 memdc.selectobject( &bmp );// 메모리에그림 BITMAP bm; bmp.getobject( sizeof(bm), &bm ); // 비트맵관련정보획득 36

pdc->stretchblt( point.x, // 출력가로위치 point.y, // 출력세로위치 bm.bmwidth*3, // 출력비트맵가로크기 bm.bmheight*3, // 출력비트맵세로크기 &memdc, // 원본 ( 메모리 ) DC의주소 0, // 복사시작할비트맵의가로좌표 0, // 복사시작할비트맵의세로좌표 bm.bmwidth, // 원본비트맵가로크기 bm.bmheight, // 원본비트맵세로크기 SRCCOPY // 원본을그대로복사 ); memdc.deletedc( ); // 메모리 DC 해제 ReleaseDC( pdc ); // 화면 DC 해제 } CView::OnLButtonDown(nFlags, point); 37

화면맵핑모드 맵핑모드 논리단위 X출증가방향 Y축증가방향 MM_TEXT 픽셀 오른쪽 아래 MM_LOMETRIC 0.1 mm 오른쪽위 MM_HIMETRIC 0.01 mm 오른쪽위 MM_LOENGLISH 0.1 inch 오른쪽위 MM_HIENGLISH 0.01 inch 오른쪽위 MM_TWIPS 1 / 1440 inch 오른쪽위 WW_ISOTROPIC 지정가능선택가능선택가능 MM_ANISOTROPIC 지정가능선택가능선택가능 MM_TEXT: 기본설정모드 화면좌측상단이 (0,0) 이고오른쪽으로갈수록 x 축값이증가하고아래로갈수록 y 축값이증가 MM_LOMETIC ~ MM_TWIPS 물리장치의종류에관계없이물리적길이가항상일정하도록설계 MM_ISOTROPIC, MM_ANISOTROPIC 프로그래밍가능한매핑모드 38

MM_ANISOTROPIC 을사용한방법 1 CRect rect; GetClientRect( &rect ); CDC* pdc; pdc = GetDC( ); pdc->setmapmode( MM_ANISOTROPIC ); // 맵핑모드설정 // 논리단위설정 pdc->setwindowext( 300, 300 ); // 물리단위설정 pdc->setviewportext( rect.width(), rect.height() ); pdc->ellipse( 0, 0, 300, 300 ); pdc->rectangle( 50, 50, 250, 250 ); ReleaseDC( pdc ); 39

MM_ANISOTROPIC 을사용한방법 2 CDC* pdc; pdc = GetDC( ); pdc->setmapmode( MM_ANISOTROPIC ); // 맵핑모드설정 // 디스플레이크기의 1/3 크기로논리단위설정 pdc->setwindowext( xdisplay/3, ydisplay/3 ); // 디스플레이크기그대로물리단위설정 pdc->setviewportext( xdisplay, ydisplay ); SetMapMode() 맵핑모드설정 xdisplay 및 ydisplay 디스플레이해상도 SetWindowExt() 화면출력단위가되는논리단위설정 SetViewPortExt() 물리단위화면크기설정 40

디스플레이해상도를얻는방법 xdisplay = pdc->getdevicecaps( HORZRES ); ydisplay = pdc->getdevicecaps( VERTRES ); // 픽셀단위의가로크기 // 픽셀단위의세로크기 마우스를클릭했을때인자로넘어오는마우스좌표는물리단위인픽셀단위 물리단위를논리단위로변환하는 DPtoLP( ) 함수를사용해해결 (CDC 클래스의멤버함수 ) void DPtoLP(LPPOINT lppoints, int ncount = 1) const; // 변환할점이여러개인경우 void DPtoLP(LPRECT lprect) const; // RECT 좌표변환 void DPtoLP(LPSIZE lpsize) const; // SIZE 좌표변환 void LPtoDP(LPPOINT lppoints, int ncount = 1) const; void LPtoDP(LPRECT lprect) const; void LPtoDP(LPSIZE lpsize) const; 41

SetViewPortOrg(), SetWindowOrg() 함수를이용하면좌표계의원점과축증가방향변경가능 MM_TEXT 모드에서다음코드는아래와같이화면의중심이원점이되도록변경 pdc->setviewportorg( xdisplay/2, ydisplay/2 ); 물리적인원점및논리적인원점 : 화면중심 42

논리적인원점설정을추가하여중앙으로변경된물리적인원점이화면의 -1/2 : 논리적인원점이오른쪽하단 pdc->setviewportorg( xdisplay/2, ydisplay/2 ); pdc->setwindoworg( -xdisplay/2, -ydisplay/2 ); -y -x 43