WinAPI

Date:     Updated:

카테고리:

Chapter 06 그래픽

06-1 DC의 정보 수정

  • 윈도우즈 프로그램에서의 모든 출력은 GDI를 통해서 화면과 프린터로 나가게 되어 있다
  • GDI 오브젝트란 그래픽 출력에 사용되는 도구를 말하며 펜, 브러시, 비트맵, 폰트 등등이 모두 GDI 오브젝트이다
  • GDI가 그래픽을 출력할 때는 GDI 오브젝트를 사용한다
  • GDI 오브젝트를 모아놓은 것이 DC이며 GDI는 현재 DC에 선택되어 있는 GDI 오브젝트를 사용한다
  • GDI 오브젝트는 GDI가 그래픽 출력을 위해 사용하는 도구임과 동시에 사용자가 GDI의 출력을 조정할 수 있는 도구이기도 하다
  • 우리는 GDI 오브젝트를 생성하는 함수를 부르고 이 함수가 리턴하는 핸들을 받아서 사용하기만 하면 된다
  • 스톡 오브젝트는 윈도우즈가 기본적으로 제공하는 GDI 오브젝트를 말하는데 사용하고 난 후에 파괴할 필요가 없다
// 이 코드는 BeginPaint로 DC를 얻은 후 사각형을 그리고 EndPaint로 그리기를 종료한다
// 이 때 사용되는 GDI 오브젝트는 모두 디폴트 GDI 오브젝트이다
hdc = BeginPaint(hWnd, &ps);
Rectangle(hdc, 50, 50, 300, 200);
EndPaint(hWnd, &ps);
HBRUSH MyBrush, OldBrush;
// GetStockObject 함수는 원하는 타입으로 캐스팅이 필요하다
MyBrush = (HBRUSH)GetStockObject(GRAY_BRUSH);
// OldBrush는 원래의 브러시를 잠시 저장하기 위한 용도로 사용된다 hdc는 DC의 핸들이다
// SelectObject가 리턴하는 값은 새로 선택되는 오브젝트 이전에 선택되어 있던 같은 종류의 오브젝트 핸들이다
OldBrush = (HBRUSH)SelectObject(hdc, MyBrush);
// 그리기를 하고 난 후에는 SelectObject를 한 번 더 호출하여 원래의 GDI 오브젝트인 OldBrush를 복구해야 한다
SelectObject(hdc, OldBrush);
  • 윈도우즈에서는 색생값을 표현하기 위해 COLORREF라는 데이터형을 사용한다
  • 펜을 사용하고자 할 때는 CreatePen() 함수를 이용해 직접 만들어서 사용해야 한다, 새로 만든 펜의 핸들이 리턴되면 이 값을 잘 보관해 두어야 만들어진 펜을 사용할 수 있으면 다 사용한 후 파괴할 수도 있다
  • GDI 오브젝트는 사용한 후 반드시 삭제해야 한다 왜냐하면 GDI 오브젝트도 메모리를 사용하기 때문이다
  • DC에 현재 선택되어 있는 GDI 오브젝트는 삭제할 수 없다 그래서 GDI 오브젝트를 만들어 사용할 때는 항상 같은 타입의 Old 핸들을 하나 더 선언해야 한다
  • GDI 오브젝트를 만들고 사용하는 일반적인 절차는 다음과 같다 핸들선언 -> GDI 오브젝트 만듬 -> DC에 선택하되 이때 이전 핸들을 반드시 저장해 두어야 한다 -> 사용한다 -> 선택을 해제한다 -> 삭제한다 펜뿐만 아니라 모든 GDI 오브젝트는 일반적으로 이런 절차를 거쳐 만들어지고 사용된다
  • DC에 펜, 브러시 등의 오브젝트가 없는 상황을 가정할 수 없기 때문에 UnSelectObject 따위의 함수는 존재할 수 없으며 DC에는 항상 선택된 오브젝트가 있어야 한다
hdc = GetDC(hWnd);
hPen = CreatePen(PS_SOLID, 2, RGB(255,0,0));
OlePen = (HPEN)SelectObject(hdc, hPen);
// 그리기 코드
SelectObject(hdc, OldPen);
DeleteObject(hPen);
ReleaseDC(hWnd, hdc);
  • 위의 코드는 hPen을 선택할 때 SelectObject() 함수가 리턴되는 펜의 핸들을 OldPen에 저장해 두었다가 hPen을 다 사용한 후 OldPen을 다시 복구 시킴과 동시에 hPen을 DC에서 밀어낸다 이렇게 되면 hPen을 무사히 삭제할 수 있다
  • 코드의 범용성을 위해서는 항상 Old 오브젝트를 사용하여 DC를 원래대로 돌려놓는 습관을 가지는 것이 좋은데 이는 비단 GDI 오브젝트뿐만 아니라 거의 모든 자원에 대해서도 마찬가지이다
  • GDI의 그리기 함수들은 항상 선택된 오브젝트를 무조건 사용하도록 되어 있으며 테두리만 따로 그리는 함수, 안만 채우는 함수가 별도로 제공되지 않는다 그래서 둘 중 하나만 그리고 싶을 때는 그리고 싶지 않는 부분에 대해 투명 오브젝트를 선택해 놓고 그려야 한다

06-2 그리기 모드

  • SetROP2() 함수는 그리기 모드를 변경하는 함수이다
  • GetROP2() 함수는 현재 설정된 그리기 모드를 구하는 함수이다
  • 이동중에 계속 선의 모양을 보여주기 위해서는 그리기 모드라는 것이 반드시 필요하다

06-3 비트 맵

  • 윈도우즈는 비트맵을 곧바로 화면 DC로 출력하는 함수는 제공하지 않는다
  • 비트맵 파일을 읽고 싶으면 반드시 열기, 읽기, 닫기의 과정을 거쳐야 한다
  • 비트맵은 화면으로 직접 출력할 수 없으며 반드시 메모리 DC에 미리 준비해 놓고 사용해야 한다
  • 메모리 DC란 화면 DC와 동일한 특성을 가지며 그 내부에 출력 표면을 가진 메모리 영역이다
  • 메모리 DC에 먼저 그림을 그린 후 사용자 눈에 그려지는 과정은 보여주지 않고 그 결과만 화면으로 고속 복사하는 방법(더블 버퍼링)을 많이 사용한다
  • 비트맵도 일종의 GDI 오브젝트이지만 화면 DC에는 선택할 수 없으며 메모리 DC만이 비트맵을 선택할 수 있다 그래서 메모리 DC에 먼저 비트맵을 읽은 후 화면 DC로 복사하는 것이다
  • 메모리 DC를 만들 때는 CreateCompatibleDC() 함수가 사용된다
  • 메모리 DC를 만든 후에는 비트맵을 읽어오고 이 비티맵을 메모리 DC에 선택한다 선택할 때는 여타의 GDI 오브젝트와 마찬가지로 SelectObject() 함수를 사용하며 비트맵을 읽어올 때는 LoadBitmap() 함수를 사용한다
  • 읽어온 비트맵을 SelectObject() 함수로 메모리 DC에 선택하면 메모리 DC의 표면에는 리소스에서 읽어온 비트맵이 그려져 있을 것이다 그럼 남은 일은 메모리 DC에 그려진 비트맵을 화면으로 복사하는 것 뿐이다
  • BitBit() 함수는 DC간의 영역끼리 고속 복사를 수행한다( 메모리 DC의 표면에 그려져 있는 비트맵을 화면 DC로 복사함으로써 비트맵을 화면으로 출력한다 )
  • StretchBit() 함수 또한 DC간에 비트맵을 전송하는데 확대 및 축소가 가능하다는 점이 다르다


맨 위로 이동하기

댓글남기기