Download presentation
Presentation is loading. Please wait.
1
윈도우의 화면 출력 원리를 이해한다. CDC 클래스를 이용한 화면 출력 기법을 배운다. 각종 GDI 객체를 생성하고 사용하는 방법을 익힌다.
2
GDI와 디바이스 컨텍스트 (1/5) 출력 시스템을 설계할 때 고려할 사항
모니터, 비디오 카드, 프린터 등 출력에 사용되는 주변 장치가 변경되는 경우에도 프로그램을 수정할 필요가 없어야 한다. 여러 프로그램이 화면을 분할해서 사용하므로 하나의 프로그램이 출력을 하는데 있어서 제약을 가해야 한다. 즉 화면이나 기타 출력 장치를 직접 접근(Direct Access)하거나 독점해서 사용하는 것을 운영체제 차원에서 막아야 한다.
3
GDI와 디바이스 컨텍스트 (2/5) GDI(Graphics Device Interface)
운영체제의 하위 시스템 중 하나로 DLL로 존재 응용 프로그램의 요청을 받아서 실제 출력 장치에 대한 출력을 담당 응용 프로그램 GDI 출력 장치 (화면, 프린터 등) 장치 독립적 장치 의존적
4
GDI와 디바이스 컨텍스트 (3/5) 화면 출력할 때 고려할 사항
클라이언트 영역에 출력하려면 화면에 해당하는 윈도우 위치를 알아야 한다. 화면에 여러 개의 윈도우가 있을 때 출력 결과가 다른 윈도우의 영역을 침범하지 않아야 한다. 현재 출력할 화면이 다른 윈도우에 가려졌다면 출력을 할 수 없어야 한다.
5
GDI와 디바이스 컨텍스트 (4/5) 디바이스 컨텍스트(DC, Device Context) 윈도우 응용 프로그램의 출력 과정
멀티태스킹(멀티스레딩) GUI 환경에서 발생할 수 있는 여러 상황을 고려한 출력 가능 윈도우 응용 프로그램의 출력 과정 출력하기 전에 윈도우 운영체제에게 디바이스 컨텍스트를 요청한다. 운영체제의 GDI는 내부적으로 디바이스 컨텍스트를 만든 후 디바이스 컨텍스트 핸들(HDC 타입, 32비트 포인터)을 해당 프로그램에게 돌려준다.
6
GDI와 디바이스 컨텍스트 (5/5) 윈도우 응용 프로그램의 출력 과정 (cont'd)
응용 프로그램은 자신이 받은 핸들을, 출력 관련 API 함수를 호출할 때 사용한다. 출력 관련 API 함수를 호출하면 GDI가 이를 처리한다. GDI는 해당 프로그램이 넘겨준 디바이스 컨텍스트 핸들로 내부 데이터를 참조하여 다양한 상황을 고려해서 출력한다. 응용 프로그램 디바이스 컨텍스트 GDI 장치 드라이버 출력 장치 (화면, 프린터 등)
7
무효 영역 (1/3) 화면을 다시 그려야 하는 상황
8
무효 영역 (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)); }
9
무효 영역 (3/3) WM_PAINT 메시지 발생 상황 무효 영역 생성 윈도우가 생성될 때 윈도우의 크기가 변경될 때
최소화 또는 최대화 되었을 때 다른 윈도우가 가렸다가 드러날 때 무효 영역 생성 void CWnd::Invalidate (BOOL bErase = TRUE); void CWnd::InvalidateRect (LPCRECT lpRect, BOOL bErase = TRUE);
10
출력 방법 비교 SDK MFC 윈도우 운영체제에게 디바이스 컨텍스트를 요청한다.
운영체제로부터 받은 디바이스 컨텍스트 핸들을 사용하여 출력을 한다. 운영체제에게 디바이스 컨텍스트 사용이 끝났음을 알린다. MFC 디바이스 컨텍스트 객체를 생성한다. 객체의 멤버 함수를 호출하여 출력한다.
11
다양한 디바이스 컨텍스트 클래스 메타 파일(Metafile)에 출력할 때 CMetaFileDC
윈도우의 전체 영역(클라이언트 영역 + 비 클라이언트 영역)에 출력할 때 CWindowDC 클라이언트 영역에 출력할 때 (WM_PAINT 메시지 핸들러를 제외한 다른 모든 곳에서 사용) CClientDC (WM_PAINT 메시지 핸들러에서만 사용) CPaintDC 용도 클래스 이름
12
CPaintDC 클래스 클래스 계층도 CPaintDC 사용 예 void CChildView::OnPaint() {
CPaintDC dc(this); // ... }
13
CClientDC 클래스 CClientDC 사용 예
void CChildView::OnLButtonDown(UINT nFlags, CPoint point) { CClientDC dc(this); // ... }
14
CWindowDC 클래스 CWindowDC 사용 방법 원점 위치 CPaintDC, CClientDC 클래스와 동일
15
CMetaFileDC 클래스 메타 파일(Metafile) CMetaFileDC 사용 방법 GDI 명령어를 저장할 수 있는 파일
CMetaFileDC 객체를 만든 후 CMetaFileDC::Create() 호출 메타 파일 객체를 일반적인 디바이스 컨텍스트 객체로 간주하고 출력 관련 멤버 함수를 호출 CMetaFileDC::Close()를 호출하면 윈도우 운영체제가 내부적으로 메타 파일을 만든 후 메타 파일 핸들(HMETAFILE 타입)을 리턴 CDC::PlayMetaFile()로 메타 파일을 실행
16
그리기 함수 (1/3) 점 찍기 SetPixel과 기능은 동일하지만 SetPixel 함수와 달리 원래의 점의 색을 리턴하지 않으므로 속도가 더 빠르다. SetPixelV() 화면의 특정 위치에 원하는 색의 점을 찍으며 원래의 점의 색을 리턴한다. SetPixel() 화면의 특정 위치에 해당하는 점의 색을 얻는다. GetPixel() 기능 이름
17
그리기 함수 (2/3) 선 그리기 현재 위치로부터 특정 위치까지 선을 그린 후 현재 위치를 갱신한다. LineTo()
현재 위치를 옮긴다. MoveTo() 기능 이름
18
그리기 함수 (3/3) 도형 그리기 사각형에 내접하는 타원을 그린다. Ellipse() 사각형을 그린다. Rectangle()
기능 이름
19
텍스트 함수 텍스트 출력 함수 기준 위치에 대한 문자열의 정렬 방식을 정한다. SetTextAlign()
문자의 배경색을 바꾼다. SetBkColor() 문자의 색을 바꾼다. SetTextColor() 사각형을 기준으로 문자열을 출력한다. DrawText() 특정 위치에 문자열을 출력한다. TextOut() 기능 이름
20
매핑 모드 +x 매핑 모드 단위 x축 y축 MM_TEXT 1 픽셀 +y MM_LOMETRIC 0.1 mm -y
MM_HIMETRIC 0.01 mm MM_LOENGLISH 0.01 인치 MM_HIENGLISH 0.001 인치 MM_TWIPS 1/1440 인치 MM_ISOTROPIC 사용자 정의(가로, 세로 길이 동일) 사용자 정의 MM_ANISOTROPIC
21
좌표 변환 (1/2) 스크린 좌표와 클라이언트 좌표 스크린 좌표의 원점 클라이언트 좌표의 원점
22
좌표 변환 (2/2) 좌표 변환 함수 장치 좌표 클라이언트 좌표 스크린 좌표 논리 좌표 ScreenToClient
ClientToScreen DPtoLP LPtoDP
23
속성 함수 속성 초기값 텍스트 색상 검정색 배경 색상 흰색 배경 모드 OPAQUE 매핑 모드 MM_TEXT 그리기 모드
R2_COPYPEN 현재 위치 (0, 0) 펜 BLACK_PEN 브러시 WHITE_BRUSH 폰트 SYSTEM_FONT 비트맵 없음 팔레트 영역 속성을 얻는 함수 GetTextColor() GetBkColor() GetBkMode() GetMapMode() GetROP2() GetCurrentPosition() SelectObject() SelectPalette() 속성을 변경하는 함수 SetTextColor() SetBkColor() SetBkMode() SetMapMode() SetROP2() MoveTo()
24
그리기 모드 그리기 모드 연산 R2_NOP D = D R2_NOT D = ~D R2_BLACK D = BLACK
R2_WHITE D = WHITE R2_COPYPEN D = S R2_NOTCOPYPEN D = ~S R2_MERGEPENNOT D = ~D | S R2_MASKPENNOT D = ~D & S R2_MERGENOTPEN D = ~S | D R2_MASKNOTPEN D = ~S & D R2_MERGEPEN D = D | S R2_NOTMERGEPEN D = ~(D | S) R2_MASKPEN D = D & S R2_NOTMASKPEN D = ~(D & S) R2_XORPEN D = S ^ D R2_NOTXORPEN D = ~(S ^ D)
25
GDI 객체 (1/3) GDI 객체 종류 GDI에서 출력할 때 사용하는 도구 GDI 객체 용도 클래스 이름 펜 선을 그릴 때
CPen 브러시 면의 내부를 채울 때 CBrush 폰트 문자를 출력할 때 CFont 비트맵 픽셀의 집합으로 이루어진 그림을 다룰 때 CBitmap 팔레트 출력될 색의 집합을 다룰 때 CPalette 영역 다양한 형태의 면을 정의할 때 CRgn
26
GDI 객체 (2/3) 클래스 계층도
27
GDI 객체 (3/3) GDI 객체 사용 방법 GDI 객체를 스택에 생성한다.
생성된 GDI 객체를 디바이스 컨텍스트에 선택하고 이전에 선택되어 있던 같은 종류의 GDI 객체의 주소를 저장해둔다(CDC::SelectObject() 사용). GDI 함수를 사용하여 출력을 한다. 이전의 GDI 객체를 디바이스 컨텍스트에 선택함으로써 기존에 선택된 GDI 객체를 선택 해제한다(CDC::SelectObject() 사용). GDI 객체가 범위(Scope)를 벗어나면 소멸자가 자동으로 호출되면서 파괴된다.
28
펜 (1/2) 생성 방법 펜 스타일 // 방법 1 CPen pen(PS_SOLID, 2, RGB(255, 0, 0));
// 방법2 CPen pen; pen.CreatePen (PS_SOLID, 2, RGB (255, 0, 0));
29
펜 (2/2) 사용 예 1 사용 예 2 CPaintDC dc(this);
CPen pen(PS_SOLID, 1, RGB(0, 0, 255)); CPen *pOldPen = dc.SelectObject(&pen); dc.Rectangle(100, 100, 200, 200); dc.SelectObject(pOldPen); CPaintDC dc(this); CPen pen(PS_SOLID, 1, RGB(0, 0, 255)); dc.SelectObject(&pen); dc.Rectangle(100, 100, 200, 200);
30
브러시 (1/2) 종류 브러시 종류 생성 예 솔리드(Solid, 속이 채워짐)
CBrush brush(RGB(255, 0, 0)); 해치(Hatch, 교차된 평행선 무늬) CBrush brush(HS_DIAGCROSS, RGB(255, 0, 0)); 패턴(Pattern, 비트맵의 반복 무늬) CBitmap bitmap; bitmap.LoadBitmap(IDB_BITMAP1); CBrush brush(&bitmap);
31
브러시 (2/2) 사용 예 1 사용 예 2 CPaintDC dc(this);
CBrush brush(RGB(255, 0, 0)); CBrush *pOldBrush = dc.SelectObject(&brush); dc.Ellipse(100, 100, 200, 200); dc.SelectObject(pOldBrush); CPaintDC dc(this); CBrush brush(RGB(255, 0, 0)); dc.SelectObject(&brush); dc.Ellipse(100, 100, 200, 200);
32
폰트 (1/2) 생성 방법 CFont 객체 생성 CFont 객체에 대해 Create*() 함수를 호출 CFont font;
font.CreateFont(...); // font.CreateFontIndirect(...); // font.CreatePointFont(...); // font.CreatePointFontIndirect(...);
33
폰트 (2/2) 사용 예 CPaintDC dc(this); CFont font;
font.CreatePointFont(400, "Arial"); dc.SelectObject(&font); dc.TextOut(10, 10, CString("Hello"));
34
내장 객체 CDC::SelectStockObject() 함수를 사용하여 디바이스 컨텍스트에 선택한다. 이름 용도
BLACK_PEN 폭이 1 픽셀인 검정색 펜 WHITE_PEN 폭이 1 픽셀인 흰색 펜 NULL_PEN 투명 펜 BLACK_BRUSH 검정색 브러시 DKGRAY_BRUSH 어두운 회색 브러시 GRAY_BRUSH 회색 브러시 LTGRAY_BRUSH 밝은 회색 브러시 HOLLOW_BRUSH 또는 NULL_BRUSH 투명 브러시 SYSTEM_FONT 윈도우 운영체제가 사용하는 폰트 예) 메뉴, 대화상자, ... CDC::SelectStockObject() 함수를 사용하여 디바이스 컨텍스트에 선택한다.
35
비트맵 (1/5) 비트맵 정보 int CBitmap::GetBitmap (BITMAP* pBitMap) ;
typedef struct tagBITMAP { int bmType; int bmWidth; // 비트맵의 폭(픽셀 단위) int bmHeight; // 비트맵의 높이(픽셀 단위) int bmWidthBytes; BYTE bmPlanes; BYTE bmBitsPixel; LPVOID bmBits; } BITMAP;
36
비트맵 (2/5) 비트맵 정보 출력 CBitmap bitmap; bitmap.LoadBitmap(IDB_BITMAP1);
BITMAP bmpinfo; bitmap.GetBitmap(&bmpinfo); TRACE("가로 = %d, 세로 = %d\n", bmpinfo.bmWidth, bmpinfo.bmHeight);
37
비트맵 (3/5) 비트맵 출력 절차 CDC::CreateCompatibleDC() 함수를 이용하여 메모리 디바이스 컨텍스트를 만든다. CDC::SelectObject() 함수를 이용하여 비트맵을 메모리 디바이스 컨텍스트에 선택한다. CDC::BitBlt() 또는 CDC::StretchBlt() 함수를 이용하여 화면에 출력한다.
38
비트맵 (4/5) 비트맵 출력 함수 BOOL BitBlt (int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, DWORD dwRop) ; (스크린 디바이스 컨텍스트) pSrcDC (메모리 디바이스 컨텍스트) x y nWidth nHeight xSrc ySrc
39
비트맵 (5/5) 비트맵 출력 함수 (cont'd)
BOOL StretchBlt (int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, DWORD dwRop) ; pSrcDC (메모리 디바이스 컨텍스트) ySrc nSrcWidth xSrc nSrcHeight (스크린 디바이스 컨텍스트) y nWidth x nHeight
Similar presentations