그 동안 윈도우에 여러가지 그래픽을 출력할때 습관적으로 Old를 같이 써왔습니다.
왜 Old를 같이 써야하는지... 이유도 모르고 말이죠...(적어도 지금까지의 저는 그랬습니다...)
그래픽을 출력하는 함수와 순서 부분부터 OLD를 사용하는 부분까지 자세히 분석해보겠습니다.
HDC hdc; PAINTSTRUCT ps; HBRUSH MyBrush , OldBrush; switch (iMessage) { case WM_PAINT: { hdc = BeginPaint(hWnd , &ps); MyBrush = (HBRUSH)GetStockObject(GRAY_BRUSH); OldBrush = (HBRUSH)SelectObject(hdc , MyBrush); Rectangle(hdc , 100 , 100, 200 , 200); SelectObject(hdc , OldBrush); DeleteObject(MyBrush); EndPaint(hWnd, &ps); break; } |
HDC hdc
윈도우에서 그리기 처리를 하려면 GDI(Graphics Device Interface) 함수를 사용해야 하는데 DC를 참조
합니다. 즉, 윈도우 화면처리와 그래픽을 담당하는 핸들값입니다.
그럼 DC는 왜 필요할까요? DC(Device Context)는 그리기등의 출력에 필요한 모든 정보를 가지는 데이터
구조체 입니다. 즉 선의 굵기, 색상 , 무늬 등의 모든 출력에 필요한 정보들을 가지고 있습니다.
또한 DC는 그려질 윈도우 화면의 정보 및 좌표 정보도 가지고 있기 때문에 그려질 영역(윈도우)에 대한 정보
또한 별도로 설정해주지 않아도 되게 됩니다.
이런 DC(Device Context)가 없다면 Rectangle와 같은 함수를 사용할때 사각형의 색상, 굵기 등을 지정해야
할 것 입니다. 이렇게 말이죠...
Rectangle(HINSTANCE = hInstance ,Color = RED , Border = 1 , L = 100 , Y = 100, R = 200 , B = 200);
하지만 DC에 미리 이런 설정들을 담아둔다면, 해당 DC의 값만 가지고 그리기와 같은 처리가 용이하기 때문에
DC(Device Context)를 사용합니다.
PAINTSTRUCT ps
응용 프로그램을 위한 정보 구조체입니다.
해당 정보를 통해 응용프로그램 윈도우 사용자의 클라이언트 영역에 페인트를 사용할 수 있게 합니다.
HBRUSH MyBrush , OldBrush
브러시를 사용하는 GDI 오브잭트의 핸들 값입니다.
해당 오브잭트를 생성하는 함수정도로 생각하면 되며, 자세한 구조정보는 확인하지 않아도 해당 함수가 반환해주는 리턴값(핸들)을 가지고 사용하면 됩니다.
비슷한 함수로 HPEN , HFONT , HBITMAP , HPALETTE , HRGN 등이 있습니다.
hdc = BeginPaint(hWnd , &ps)
윈도우 환경에서 화면이나 프린터로 출력을 하려면 DC(Device Context)를 먼저 구해야 합니다.
WM_PAINT 메세지에서 DC를 구하는 방법으로는 BeginPaint, EndPaint 함수쌍을 이용해서 DC를 구합니다.
(이 외로는 GetDC, ReleaseDC를 사용 할 수 있습니다.)
MyBrush = (HBRUSH)GetStockObject(GRAY_BRUSH)
GDI BRUSH 오브잭트 MyBrush의 속성을 지정합니다.
GetStockObject는 윈도우에서 기본적으로 제공하는 GDI 오브잭트입니다.
해당 오브잭트는 GDI BRUSH 와 동일한 타입이 아니므로 동일한 타입으로 사용하기 위해서 (HBRUSH)를 같이
사용하여 , HBRUSH로 캐스팅합니다.
이 부분만가지고 실행할 경우 검은색으로만 칠해집니다. GDI에서 사용할 SelectObject 가 지정되어 있지
않기 때문입니다.
OldBrush = (HBRUSH)SelectObject(hdc , MyBrush)
OldBrush에 MyBrush의 DC 핸들값을 대입합니다.
SelectObject 함수는 GDI 에서 사용할 오브잭트를 DC에 선택하는 함수입니다.
위 코드로 인해서 DC에 GDI의 오브잭트 MyBrush가 선택되었고, 그래픽을 출력할때 선택된 오브잭트를 사용합니다.
Rectangle(hdc , 100 , 100, 200 , 200)
설정된 DC로 정사작형을 그립니다.
SelectObject(hdc , OldBrush)
MyBrush의 핸들 값을 가진 OldBrush를 선택합니다.
DeleteObject(MyBrush);
MyBrush를 삭제합니다.
[추가 ] - SelectObject (출처 - MSDN)
주소 - https://msdn.microsoft.com/ko-kr/library/windows/desktop/dd162957(v=vs.85).aspx
SelectObject 는 매크로 함수로 지정된 디바이스 컨텍스트(DC)로 오브잭트를 선택합니다.
새로운 객체가 동일한 유형의 이전 객체를 대채합니다.
HGDIOBJ SelectObject( _In_ HDC hdc, _In_ HGDIOBJ hgdiobj ); |
매개 변수 |
의미 |
hdc |
DC의 핸들값 입니다. |
hgdiobj |
오브잭트에 대한 핸들을 선택합니다. 지정된 오브잭트는 다음과 같은 기능중 하나를 사용하여 작성해야합니다. 자세한 정보는 위 주소로 가서 확인해주세요. |
'프로그래밍 관련 > Win API' 카테고리의 다른 글
WIndows API - #9-3 그래픽 처리 - (비트맵 출력) (1) (0) | 2015.09.06 |
---|---|
WIndows API - #9 -2. 그래픽 처리 (Old를 같이 쓰는 이유) (2) (0) | 2015.09.03 |
WIndows API - #8. 충돌 처리 (사각형 , 원형 , 마우스) - 작성 중.. (0) | 2015.09.01 |
WIndows API - #7. 키보드, 마우스 입력, 좌표 (InvalidateRect) (0) | 2015.09.01 |
WIndows API - #6. API 문자열 출력 함수들에 관하여.. (0) | 2015.08.24 |