[MFC 윈도우 프로그래밍] 5. Display Monitor

2023. 9. 25. 19:24MFC 윈도우 프로그래밍

GDI와 디바이스 컨텍스트

 

윈도우 운영체제에서 출력 시스템을 설계시 고려 사항

 

-장치 변경에 따른 프로그램 수정 없음 (Device Independent)

 

모니터, 비디오 카드, 프린터 등 출력에 사용되는 주변 장치가

변경되더라도 프로그램을 수정할 필요가 없어야 한다.

 

-프로그램 출력 영역을 제약한다.

 

여러 프로그램이 화면을 분할해서 사용한다.

각각의 프로그램이 출력하는 영역에 제약을 가해야 한다.

화면이나 기타 출력 장치에 직접 접근하거나 독점해서 사용하는 것을

운영체제 수준에서 막아야한다.

 

GDI ( Graphics Device Interface)란?

 

윈도우 운영체제의 하위 시스템 중 하나로 DLL로 존재한다.

응용 프로그램의 요청을 받아, 실제 출력 장치인 모니터가 프린터에  출력하는 역할을 담당

 

즉 응용프로그램이 똑같은 코드를 주면, GDI가 장치에 따라 출력하게 만들어준다.

 

윈도우 응용 프로그램이 화면에 출력시 고려 사항

 

- 클라이언트 영역에 출력하려면 출력 대상 윈도우의 위치를 알아야 한다.

- 화면에 윈도우가 여러개 있을 때, 출력 결과가 다른 윈도우 영역을 침범하지 않아야 한다.

- 현재 출력할 화면이 다른 윈도우에 가려졌다면 출력할 수 없어야 한다.

 

DC ( Device Context ) 란?

 

GDI가 생성하고 관리하는 데이터 구조체이다.

우리는 이 구조체를 이용해서 필요한 명령을 하고 GDI에게 요청할 것이다.

 

멀티태스킹 GUI 환경에서 발생할 수 있는 복잡한 상황들을 신경쓰지 않고 장치에 자유롭게 출력 가능하다.

 

윈도우 응용 프로그램의 출력 과정

 

응용 프로그램 <==> 디바이스 컨텍스트 <==>  GDI <==> 장치 드라이버 <==> 출력 장치

 

무효 영역의 개념

 

윈도우가 겹쳐지는 상황에서 뒤에 있던 윈도우를 클릭하면 가려졌던 부분이 앞으로 나온다.

 

만약, 프로그램을 잘못짠다면 여기에서 오류가 떠 제대로 그려지지 않을 수도 있다.

 

코드에서는 BeginPaint()와 EndPaint()가 각각 생성자와 소멸자에 숨겨져 있다.

 

WM_PAINT 메시지 발생 상황

 

- 윈도우가 생성될 때

- 윈도우의 크기가 변경될 때

- 윈도우가 최소화 혹은 최대화 되었을때

- 다른 윈도우가 가렸다가 드러날 떄

 

CDC 안의 내용물

 

- CPaintDC

클라이언트 영역에 출력할 때

(WM_PAINT 메시지 핸들러에서만 사용)

 

- CClientDC

클라이언트 영역에 출력할 때

(WM_PAINT 메시지 핸들러를 제외한 다른 모든 곳에서 사용)

 

- CWindowDC

윈도우 전체 영역 (클라이언트 영역 + 비클라이언트 영역)에 출력할 때

CWindowDC는 (프로그램 전체) 왼쪽 위가 좌표 시작 (0,0)이고,

CPaintDC / CClientDC의 클래스는 클라이언트 위치 (흰색) 에서의 왼쪽 위가 좌표 시작이다.

 

- CMetaFileDC

메타파일 (Metafile)에 출력할 때

(GDI 명령을 저장할 수 있는 파일 메타파일이라고 함)

 

그리기 함수

- GetPixel() : 화면 (x,y) 지점의 색을 얻는다.

- SetPixel() : 화면 (x,y) 지점의 특정 색상의 점을 찍고, 원래 점의 색을 리턴한다.

- SetPixelV() : SetPixel() 함수와 출력은 같지만, 원래 점의 색을 리턴하지 않으므로 속도가 좀더 빠르다.

 

- MoveTo() : 현재 위치를 (x,y) 위치로 옮긴다.

- LineTo() : 현재 위치에서 (x,y) 위치까지 선을 그리고, 현재 위치를 (x,y)로 변경한다.

- Polyline() : POINT 구조체 배열로 전달된 점들을 차례로 이어서 선을 그린다.

 

도형

- Rectangle() : 직사각형을 그린다.

- Ellipse() : 직사각형에 내접하는 타원을 그린다.

- RoundRect() : 테두리가 둥근 직사각형을 그린다.

- Polygon() : POINT 구조체 배열로 전달된 점들을 차례로 이어서 다각형을 그린다.

 

텍스트

- TextOut() : (x,y) 위치에 문자열을 출력한다.

- DrawText() : 직사각형 영역 내부에 문자열을 출력한다.

- SetTextColor() : 글자의 색을 바꾼다.

- SetBkColor() : 글자의 배경색을 바꾼다.

- SetTextAlign() : 기준 위치에 대한 문자열 정렬 방식을 설정한다.

 

매핑 모드

논리적인 위치하고 물리적인 위치와 매핑을 할 수 있다.

 

MM_TEXT

 

디바이스 컨텍스트 최초 생성시 자동 설정된 매핑 모드

논리 단위와 장치 단위가 1:1로 대응

 

MM_LOMETRIC ~ MM_TWIPS

 

논리 단위가 장치 단위로 변환될 때, 출력장치의 종류에 관계 없이

물리적 길이가 항상 일정하도록 설계되어 있다.

장치 독립적인 출력 가능하다.

 

MM_ISOTROPIC, MM_ANISOTROPIC

 

논리 단위와 장치 단위의 변환 관계를 사용자가 정의 가능하다.

 

좌표 변환

 

논리 좌표 <==> 장치 좌표

CDC 안에 LPtoDP 와 DPtoLP 함수가 있다.

 

스크린 좌표 <==> 클라이언트 좌표

Cwnd 안에 ScreenToClient 함수와 ClientToScreen 함수가 있다.

 

속성 함수

그리기 모드

GDI 객체 

 

GDI에서 출력할 때 사용하는 도구

 

 

사용 방법

 

1. GDI 객체를 스택에 생성한다.

2. 생성된 GDI 객체를 CDC::SelectObject() 함수에 전달하여 디바이스 컨텍스트에 선택한다.

3. CDC 클래스 멤버 함수를 호출하여 출력한다.