DC의 정보 수정
GDI 오브젝트
GDI : 윈도우즈 프로그램에서의 모든 출력담당, 화면 처리와 그래픽 및 프린터 담당
현재 DC에 선택되어 있는 GDI오브젝트를 사용
GDI 오브젝트(GDI Object) : 그래픽 출력에 사용되는 도구(펜, 브러시, 비트맵, 폰트 등)
DC : 구조체이며, 사용할 GDI 오브젝트들을 선택하여 사용함. GDI모듈에 의해 관리
1. GDI오브젝트를 생성하는 함수 호출하고 이 함수가 리턴하는 핸들을 받아서 사용
2. DC에 필요한 GDI오브젝트를 선택
3. 현재 DC에 선택되어 있는 GDI 오브젝트를 사용하여 원하는 모양과 속성으로 그래픽을 출력
스톡 오브젝트(Stock Object)
윈도우즈에서 기본적으로 제공하는 GDI오브젝트
운영체제가 부팅할 때부터 미리 만들어 놓아 언제든지 사용 할 수 있고 사용하고 파괴할 필요 없음
HGDIOBJ GetStockObject(int fnObject);
스톡 오브젝트 얻기
1번째 인수 : 사용하고자 하는 스톡 오브젝트를 지정
여러 종류의 스톡 오브젝트를 리턴하므로 대입하기 전에 원하는 타입으로 캐스팅해야 함
HGDIOBJ SelectObject(HDC hdc, HGDIOBJ hgdiobj);
스톡 오브젝트 선택
1번째 인수 : DC의 핸들
2번째 인수 : GDI 오브젝트의 핸들
반환값 : 이전에 선택되어 있던 같은 종류의 오브젝트 핸들
색상
typedef DWORD COLORREF;
|
B |
G |
R |
#define RGB(r,g,b) ((COLORREF)(((BYTE)(r) | ((WORD)((BYTE)(g))<<8)) | (DWORD)(BYTE)(b))<<16)))
#define GetRValue(rgb) ((BYTE)(rgb))
#define GetGValue(rgb) ((BYTE)(((WORD)(rgb))>>8))
#define GetBValue(rgb) ((BYTE)((rgb)>>16))
펜
선을 그을 때 사용
윈도우가 제공하는 스톡 펜은 흰색, 검정색, 투명색 세가지 뿐
파란색, 노란색 등의 원색 펜을 사용하고자 할 때는 직접 만들어서 사용
HPEN CreatePen(int fnPenStyle, int nWidth, COLORREF crColor);
1번째 인수 : 그려질 선의 모양(선의 굵기가 1일 때만 효과있음)
2번째 인수 : 선의 폭
3번째 인수 : 선의 색상
리턴값 : 새로 만든 펜의 핸들
BOOL DeleteObject(HGDIOBJ hObject);
GDI 오브젝트 삭제
삭제하고자 하는 GDI 오브젝트의 핸들만 인수로 넘겨주면 됨
DC에 현재 선택되어 있는 GDI 오브젝트는 삭제할 수 없음
GDI오브젝트 만들고 사용하는 절차
브러시
채워지는 면을 채색하는 용도
스톡 브러시에 회색, 흰색, 검정색 등의 단색 브러시가 있음
이 외의 브러시는 직접 만들어야 함
HBRUSH CreateSolidBrush(COLORREF crColor);
단색의 브러시를 만듦
HBRUSH CreateHatchBrush(int fnStyle, COLORREF clrref);
색상뿐 아니라 무늬도 지정가능한 브러시를 만듦
Old의 의미
코드의 일부는 언제든지 다른 함수로 분리될 수 있고 함수 호출문 앞뒤로 다른 오브젝트를 선택해서 사용할 수도 있으며 직접 만들지 않은 DC를 인수로 전달받을 때는 원래 어떤 오브젝트가 선택되어 있는지 알수 없는 상황이 발생 할 수 있음
꼭 이전의 GDI오브젝트를 DC에 선택하게 해서 지우려는 GDI오브젝트를 DC에서 선택 해제를 하고 GDI오브젝트를 삭제해야 함
투명 오브젝트
스톡 오브젝트 중 NULL_BRUSH(=HOLLOW_BRUSH)와 NULL_PEN은 그리기를 하지 않는 오브젝트
GDI의 그리기 함수들은 항상 선택된 오브젝트를 무조건 사용
둘 중 하나만 그리고 싶을 때는 그리고 싶지 않는 부분에 대해 투명 오브젝트를 선택
그리기 모드의 종류
윈도우즈의 디폴트 그리기 모드 = R2_COPYPEN 모드(그려지는 그림이 기존 그림을 덮어버림)
int SetROP2(HDC hdc, int fnDrawMode);
그리기 모드를 변경하는 함수
첫번째 인수 : 그리기 모드를 변경하고자 하는 DC의 핸들
두번째 인수 : 그리기 모드 값을 설정
int GetROP2(HDC hdc);
현재 설정된 그리기 모드를 구하는 함수
첫번째 인수 : 그리기 모드를 조사하고자 하는 DC의 핸들
비트맵
복잡한 그림을 출력해야 할 경우 비트맵을 사용
메모리 DC
비트 맵은 크기가 크고 출력속도가 느려서 곧바로 출력하면 안됨
준비를 거친 후 출력해야 함
준비 동작을 취한 후 출력하면 여러번 출력할 때 이미 준비된 데이터를 전송하기만 하면 되므로 출력 속도가 빠르고 예비 동작을 미리 취할 수 있음
메모리 DC : 화면 DC와 동일한 특성을 가짐, 그 내부에 출력 표면을 가진 메모리 영역
화면 DC에서 사용할 수 있는 모든 출력을 메모리 DC에서도 할 수 있음
메모리 DC에 먼저 그림을 그림을 그린 후 사용자 눈에 그려지는 과정은 보여주지 않고 그 결과만 화면으로 고속 복사하는 방법(더블 버퍼링)사용
비트맵은 메모리 DC만 비트맵을 선택가능(화면 DC는 선택 불가능)
HDC CreateCompatibleDC(HDC hdc);
메모리 DC생성 함수
인수로 화면 DC의 핸들을 주면 이 화면 DC와 동일한 특성(사용하는 색상수, 생삭면이 같음)을 가지는 DC를 메모리에 만들어 그 핸들을 리턴
비트맵 이용절차
메모리DC 생성 -> 비트맵 읽어옴(LoadBitMap()함수) ->
메모리 DC선택(SelectObject()함수) -> 비트맵화면DC로 옮기기(BitBlt()함수, StretchBlt()함수)
-> 비트맵 해제(DeleteObject()함수) -> 메모리DC 해제(DeleteDC()함수)
HBITMAP LoadBitmap(HINSTANCE hInstance, LPCTSTR lpBitmapName);
첫번째 인수 : 비트맵 리소스를 가진 인스턴스의 핸들
두번째 인수 : 비트맵 리소스의 이름
BitBlt
DC간의 영역끼리 고속 복사를 수행
BOOL BitBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HDC hdcSrc, iunt nXSrc, int nYSrc, DWORD dwRop);
첫번째 인수 : 복사대상 DC(화면DC)
2,3,4,5번째 인수 : 복사 대상의 x좌표, y좌표, width넓이, height높이
6번째 인수 : 복사원의 DC(메모리DC)
7,8번째 인수 : 복사원의 좌표(메모리DC)
9번째 인수 : 래스터 연산 방법을 지정
폭과 높이는 복사 대상에서 한 번만 지정하고 복사원에서는 이 값을 그대로 사용
비트맵 출력 후 비트맵 자체(DeleteObject()함수)와 메모리 DC(DeleteDC()함수)를 해제해야 함
비트맵을 지우기 전에 선택 해제를 먼저 해야하므로 OldBitmap변수가 필요
StretchBlt
DC간에 비트맵을 전송, 확대 및 축소가 가능
BOOL StretchBlt(HDC hdcDest, int nXOriginDest, int nYOriginDest, int nWidthDest, int nHightDest,
HDC hdcSrc, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc, DWORDdwRop);
복사대상과 복사원이 모두 폭과 높이를 가짐
복사원의 지정한 영역이 복사대상의 지정한 영역의 크기만큼 확대되어 출력되며 복사대상의 영역이 복사원보다 더 좁다면 축소가 발생
원칙적으로 비트맵 출력 절차중 LoadBitmpa()함수가 가장 느림, 비트맵은 WM_CREATE에서 미리 읽어 두고 WM_PAINT에서는 출력만 함, WM_DESTROY에서 해제
GetObject(HBITMAP hBit, int size, BITMAP* bit)
핸들로부터 펜, 브러시, 비트맵 등의 GDI오브젝트 정보를 조사하는 함수
BITMAP구조체의 bmWidth, bmHeight 멤버를 읽으면 비트맵 크기를 구할 수 있음
폰트
CreateFont
HFONT CreateFont( int nHeight, int nWidth, int nEscapement, int nOrientation, int fnWeight,
DWORD fdwItalic, DWORD fdwUnderline, DWORD fdwStrikeOut, DWORD fdwCharSet,
DWORD fdwOutputPrecision, DWORD fdwClipPrecision, DWORD fdwQuality,
DWORD fdwPitchAndFamily, LPCTSTR lpszFace );
필요가 있는 인수는 문자의 크기를 지정하는 nHeight와 글꼴 모양을 지정하는 lpszFace정도
나머지 인수는 디폴트나 폰트 열거툴로 조사한 정보를 사용하면 됨
HFONT CreateFontIndirect( CONST LOGFONT *lplf);
LOGFONT 구조체를 사용하여 폰트를 정의하고 위의 함수로 폰트를 만듦
LOGFONT 구조체는 CreateFont함수의 인수 전체를 멤버로 가지는 구조체, 이 구조체에 원하는 값을 먼저 대입한 후 CreateFontIndirect()함수로 이 구조체의 번지를 넘기면 됨
LOGFONT 구조체의 장점
1. 전달되는 인수의 개수가 적으므로 호출 속도가 빠르다
2. 여러 벌의 폰트를 만들어야 할 때 LOGFONT의 멤버중 일부만을 변경하여 재사용 가능
3. LOGFONT 구조체 배열을 사용하면 사용할 폰트의 목록을 미리 작성가능
Win32 API에서 함수명 뒤에 Indirect가 붙은 함수들은 공통적으로 구조체의 포인터를 인수로 취하는 특징 있음
텍스트의 색상
SetTextAlign()함수
문자열 정렬 상태를 지정
COLORREF SetTextColor( HDC hdc, COLORREF crColor );
Text의 Color를 설정하는 함수
COLORREF SetBkColor( HDC hdc, COLORREF crColor );
글자 뒤쪽의 배경 색상을 지정
COLORREF GetTextColor( HDC hdc);
현재 설정된 문자색을 조사
COLORREF GetBkColor( HDC hdc );
현재 설정된 배경색을 조사
int SetBkMode( HDC hdc, int iBkMode );
배경색상을 사용할 방법을 설정
인수 | 설명 |
OPAQUE | 불투명한 배경을 사용한다. 그래서 배경 색상에 의해 뒷쪽의 그림이 지워진다. 이 모드가 디폴트이다. |
TRANSPARENT | 투명한 배경색상을 사용한다. 그래서 문자를 출력한 후에도 배경이 바뀌지 않는다. 즉 문자 사이 사이의 여백에 있는 원래 배경이 지워지지 않는다. |
디폴트는 OPAQUE