posted by nsakura 2010. 7. 21. 16:40

예전 dos시절의 프로그램을 생각해보자

색상을 WHITE YELLOW RED등 매크로 상수로 색상을 표현했었다.

해봤자 16개 색상밖에 사용을 못하니.

하지만 윈도우에서는 다르다.

윈도우는 최대 천육백만가지의 색상값을 정의할수있으니 말이다.

그래서 윈도우즈에서 색상값을 표현하기 위해서는 COLORREF라는 데이터형을 사용하는데 다음과같이 정의 되어있다

typedef DWORD COLORREF;

보다싶이 COLORREF 형은 부호없는 32비트 크기의 정수형이며 8비트씩 R G B의 농도를 나타내며 상위 8비트는 사용하지

않는다.

하지만 상당히 불편하기 때문에. RGB 매크로 함수를 사용하며 이 매크로는 다음과 같이 정의

되어있다.

#define RGB(r,g,b)((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|((((DWORD)(BYTE)(b))<<16)))

각각의 인수는 R G B의 농도 이고 이 값을 조립하여 하나의 32 비트의 색상값을 만들어 낸다.

그외에 제공하는 색상관련 메크로 함수가 3개가 있다.

#define GetRValue(rgb) ((BYTE)(rgb))
#define GetBValue(rgb) ((BYTE)(((WORD)(rgb))>>8))
#define GetGValue(rgb) ((BYTE)((rgb)>>16))


이 메크로 함수들은 각 색상을 분리하는데 사용한다.

색상에 대해서는 그만 설명하고

펜을 실습을 해보자.

펜을 만드는 함수는  다음과 같다.

HPEN CretePen(int fnPenStyle, int nWidth, COLORREF crColor);


fnPenStyle

PS_SOLID  일반 선 

PS_DASH ----

PS_DOT ........

PS_DASHDOT _._._.

PS_DASHDOTDOT_.._.._

등이 있다,

nWidth

선의 폭을 설정한다.

crColor

선의 색을 설정한다.

그럼 예제를 통해 사용해보자.

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam){
 HDC hdc;
 PAINTSTRUCT ps;
 HPEN testpen,savepen;
 switch(iMessage){
 case WM_DESTROY:
  PostQuitMessage(0);
  return 0;
 case WM_PAINT:
  hdc=BeginPaint(hWnd,&ps);
  testpen=CreatePen(PS_DASHDOTDOT,1,RGB(125,88,255));
  savepen=(HPEN)SelectObject(hdc,testpen);

  Rectangle(hdc,100,100,400,400);
  SelectObject(hdc,savepen);
  DeleteObject(testpen);
  EndPaint(hWnd,&ps);
 }

 return (DefWindowProc(hWnd,iMessage,wParam,lParam));

}

GDI 오브젝트는 스톡오브젝트와 달리

사용했으면 반납을 해야한다.

즉 메모리를 사용했으면 다사용하고 반납을 해야한다는 것이다.

그 반납하는 함수가 바로

DeleteObject(testpen);

가 되겠습니다.

BOOL DeleteObject(HGDIOBJ hObject);

즉 반납하고자하는 GDI오브젝트의 핸들만 인수로 넘겨주면 된다.

주의할점은 현재 선택되어있는 GDI Object는 반납할수 없다.

그래서 사용한게 savepen을 이용한 것이다. 삭제하긱전에 savepen으로 교체하고

반납하면 된다.

그래서

  SelectObject(hdc,savepen);
  DeleteObject(testpen);

 좀더 고급스럽게 바꾸면

DeleteObject(SelectObject(savepen));

무엇을 사용할건지는 편한것을 사용하도록.

참고로 위의 코드의 결과는 다음과 같다.


위의 코드는 썰렁한 부분이 있는데 바로... 안쪽. 안쪽의 빈공간을 채우고 싶다는.. 욕구가 안생기는가...

브러쉬를 이용하면 색을 칠할수있는데

브러쉬를 만드는 함수는 두가지가있다.

HBRUSH CreateSolidBrush(COLORREF crColor);

이 함수는 단색 브러쉬만 만들수있고 색상만 인수로 전달한다.

다음 함수는

HBRUSH CreateHatchBrush(int fnStyle, COLORREF clrref);

인데 특징으로서는 색상뿐만 아니라. 무늬도 같이 지정할수있다. 지정할수 있는 무늬의 종류는 다음과 같다.

 HS_BDIAGONAL  좌하향 줄무늬
 HS_CROSS  바둑판 모양
 HS_DIAGCROSS  좌하향 및 우하향 줄무늬
 HS_FDIAGONAL 우하향 줄무늬
 HS_HORIZONTAL  수평선
 HS_VERTICAL  수직선


그럼 예제를 통해서 사용해보자 PEN에서 사용한 소스를 조금 수정해보자.

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam){
 HDC hdc;
 PAINTSTRUCT ps;
 HPEN testpen,savepen;
 HBRUSH testbrush,savebrush;

 switch(iMessage){
 case WM_DESTROY:
  PostQuitMessage(0);
  return 0;
 case WM_PAINT:
  hdc=BeginPaint(hWnd,&ps);
  
  testpen=CreatePen(PS_DASHDOTDOT,1,RGB(125,88,255));
  testbrush=CreateHatchBrush(HS_DIAGCROSS,RGB(225,128,150));
  
  savepen=(HPEN)SelectObject(hdc,testpen);
  savebrush=(HBRUSH)SelectObject(hdc,testbrush);
  
  Rectangle(hdc,100,100,400,400);
  
  DeleteObject(SelectObject(hdc,savepen));
  DeleteObject(SelectObject(hdc,savebrush));

  EndPaint(hWnd,&ps);
 }

 return (DefWindowProc(hWnd,iMessage,wParam,lParam));

}

코드의 결과는 다음과 같다.

[그림판으로 스샷을 찍으니.. 색상이 많이 죽네요.]