GDI(Graphics Device Interface)
:: 운영체제의 한 부분으로 출력을 담당한다(Gdi.dll)
:: GDI는 하드웨어에 관련된 사항들을 통제한다.
DC(Device Context)
:: 출력하기 위한 장치(화면, 프린터)의 특성을 저장하는 구조체
:: 명령 흐름 : Application → DC → GDI → 출력
- DC를 사용하는 그래픽 오브젝트
비트맵, 브러쉬, 펜, 팔레트, 폰트, Region, Path 등
- DC의 데이터 형 = 핸들
HDC
typedef HANDLE HDC;
typedef PVOID HANDLE;
typedef void * PVOID;
결국 HDC는 주소값을 저장하긴 하지만 데이터 타입이 지정되지 않은 것이다.
따라서 이를 양의 정수(아이디)로서 이해하는 것이 좋다.
※ 화면 DC에 관련된 함수
BeginPaint(), EndPaint(), GetDC(), ReleaseDC() 등
<BeginPaint, EndPaint>
이 함수들은 WM_PAINT 메시지 처리에서만 사용가능하다
(WM_PAINT : 클라이언트 영역이 지워지거나 새로이 출력하고자 할 때, 윈도우끼리 겹쳐있다가 활성화되었을 때, 최소화되었다가 다시 최대화될 때 등 클라이언트 영역을 다시 실행할 때 나타나는 메세지)
HDC BeginPaint(HWND hWnd, LPPAINTSTRUCT lpPaint);
BOOL EndPaint(HWND hWnd, const PAINTSTRUCT *lpPaint);
실제로 프로젝트 생성시 자동생성되는 코드에서 기본적으로 잘 세팅되어 있다.
<GetDC, ReleaseDC>
GetDC()로 DC를 얻은 후에는 ReleaseDC()를 통해 반드시 운영체제에 반납해줘야 한다.
getdc, releasedc 같은 경우 지정된 장소가 없어서 아무곳에서나 선언 가능하다.
HDC GetDC(HWND hWnd);
int ReleaseDC(HWND hWnd, HDC hDC);
일반적인 WM_PAINT 메세지 외에선 GetDC, ReleaseDC를 통해 출력할 수 있다.
※ 문자 출력
문자 출력을 위한 함수 = Textout
BOOL TextOut(HDC hdc, int nXStart, int nYStart, LPCTSTR lpString, int cbString);
<필요한 것>
- hcd
- x와 y 좌표(0,0)~(299,299)
- 출력하고자 하는 문자열을 담고 있는 문자열 포인터
sprintf (메모리의 char형 배열에 출력) 사용
- 출력하고자 하는 문자열의 길이
strlen (문자열의 길이 측정) 사용
GetDC(), ReleaseDC()를 이용해서도 화면에 출력할 수 있다.
기존에 만들어 뒀던 Test() 함수에 출력 내용에 대한 코드를 작성해준다.
WM_LBUTTONDOWN은 마우스 버튼을 클릭했을 때 실행되는 메시지이다.
이 메세지 발생시 Test 함수가 작동되도록 코드를 작성한다.
※ 출력 색상 설정
:: 삼원색(R,G,B) 이용
:: 색상 범위 : 0 ~ 255, DWORD(unsigned long)로 다룬다.
→ 색상 관련 매크로 함수 = RGB(), GetRValue(DWORD rgb), GetGValue(DWORD rgb), GetBValue(DWORD rgb)
COLORREF RGB(
BYTE byRed,
BYTE byGreen,
BYTE byBlue
);
COLORREF는 DWORD를 재정의한 데이터 형이다(똑같다)
+ 점(dot) 출력 함수 = SetPixel()
SetPixel(
HDC hdc,
int X, int Y,
COLORREF crColor
);
+ 점(dot) 출력 함수 = GetPixel()
화면 DC에 출력된 색상값을 구하는 함수
GetPixel(
HDC hdc,
int nXPos, int nYPos
);
※ 문자열 출력 관련 함수
SetTextColor() :: 출력할 문자열의 색상 설정
COLORREF SetTextColor (
HDC hdc.
COLORREF crColor
);
SetBkColor() :: 글자의 배경 색상 설정
COLORREF SetBkColor (
HDC hdc,
COLORREF crColor
);
InvalidateRect()
:: 화면의 일부(RECT 구조체 사용) 또는 전체(NULL, 0)를 다시 출력할 때 사용
-> WM_PAINT 메시지 발생(BeginPaint ~ EndPaint 영역 실행)
-> 무효화 영역 또는 업그레이드 영역 (다시 그리고자 하는 영역) 지정 가능
BOOL InvalidateRect(HWND hWnd, const RECT *lPRect, BOOL bErase);
typedef struct_RECT{ //구조체 원형
LONG left;
LONG top;
LONG right;
LONG bottom;
} RECT *PRECT;
+ BOOL bErase
: true면 그리고자 하는 일부 영역(클라이언트 영역)을 싹 다 지우고 다시 그림
false면 그 영역에 지우지 않고 계속해서 그림
&rect 자리에 0이 들어간다면 전체영역을 다시 그릴 것이고
FALSE 자리에 TRUE가 온다면 선택된 영역에 겹쳐서 그려지는게 아니라 새롭게(안 겹치게) 그려질 것이다.