posted by nsakura 2010. 7. 21. 15:08

어제부로 리소스는 끝났습니다.

참으로 간단하고 그렇게 어렵지도 않았지요.

오늘부터는 그래픽에 대해 알아보도록 합니다.

포스트에 앞서 일일히 코드를 다 붙여넣는건 상당히 귀찮다. 그리고 이때까지 복사하기를 한건.

눈에 익으라고 그렇게 복사하기 한것이다.

이제 이쯤 되었으니 메인함수는 거의 변함이 없다는걸 알수있고 몇몇 사람들은 이미 복사해서 사용하고있을수도 있다.

즉 내가 말하는건 왠만해서 WinMain은 변화된부분만

그리고 WndProc만 적기로 했다. [사실 나도 귀찮다.]

이점 유의하시고 보기 바란다.

우리가 앞에 출력부분에서 DC를 조금 배웠을 것이다.

그럼 GDI에 대해 좀더 알아보도록하자

GDI (Graphic Device Interface)

GDI는 화면, 프린터 등의 모든 출력 장치를 제어하는 윈도우즈의 핵심 모듈 이다.

GDI Object란 그래픽 출력에 사용되는 도구를 말하는데

이에는 [펜 브러시 비트맵 폰트 등등 이 모두 GDI 오브젝트 이다.]

현실세계의 필통과 이라고 생각하면 편할지도 모르겠다.

GDI Object는 모두 핸들로 관리되므로 우리는 다만 GDI 오브젝트를 생성하는 함수를 부르고 이 함수가 리턴하는 핸들을 받아서

사용하기만 하기만 하면된다.

[ps 마소는 api의 내부는 공개하지 않습니다. 우리는 사용만할뿐]

GetDC나 BeginPaint 함수에  의해 처음 만들어졌을 때 디폴트로 선택한 GDI 오브젝트는 다음과 같다.

 펜  HPEN   선을 그릴 때 사용한다  검정색의 가는 실선 
 브러쉬  HBRUSH  면을 채울 때 사용한다  흰색
 폰트  HFONT  문자 출력에 사용되는 글꼴  시스템 글쫄 
 비트맵  HBITMAP  비트맵 이미지  선택되지 않음
 팔레트  HPANLETTE  팔레트  선택되지 않음
 리전  HRGN  화면상의 영역  선택되지 않음


StockObject

스톡 오브젝트는 윈도우가 기본적으로 제공하는 GDI 오브젝트를 말하는데

자주 사용되서 OS가 부팅할 때부터 미리 만들어 놓는다. 우리가 부탁한것도 아니기 때문에 다사용하고나서도 굳이 반납할필요는 없다.

알아서 반납이 된다.

다음 함수로 핸들을 얻어 사용하면 되다

HGDIOBJ GetStockObject(int fnObject)

뭐 인수에는 사용하고자하는 스톡 오브젝트를 지정하는데 ...

스톡 오브젝트는 다음과 같다.

 BLACK_BRUSH  검정 브러시
 GRAY_BRUSH  회색 브러시
 NULL_BRUSH  투명 브러시
 WHITE_BRUSH  흰색 브러시
 DKGRAY_BRUSH  짙은 회색 브러시
 LTGRAY_BRUSH  옅은 회색 브러시
 DC_BRUSH  색상 브러시. SetDCBrushColor 함수로 설정한다.
 BLACK_PEN  검정색 펜
 WHITE_PEN  흰색 펜
 NULL_PEN  투명 펜
 DC_PEN  색상 펜. SetDCPenColor 함수로 설정한다.
 ANSI_FIXED_FONT  고정폭 폰트
 ANSI_VAR_FONT  가변폭 폰트
 DEFAULT_PALETTE  시스템 팔레트


자 실습의 시간이 돌아왔다.

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam){
 HDC hdc;
 PAINTSTRUCT ps;
 switch(iMessage){
 case WM_DESTROY:
  PostQuitMessage(0);
  return 0;
 case WM_PAINT:
  hdc=BeginPaint(hWnd,&ps);
  Rectangle(hdc,10,10,400,100);
  EndPaint(hWnd,&ps);
 }

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

}

어디서 많이 본 코드가 아닌가?

그냥 간단하게 사각형을 그리는 코드가 되겠습니다.

이번에 할 것은 면을 다른 색으로 바꾸어보자.

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam){
 HDC hdc;
 PAINTSTRUCT ps;
 HBRUSH testbrush,savebrush;
 switch(iMessage){
 case WM_DESTROY:
  PostQuitMessage(0);
  return 0;
 case WM_PAINT:
  hdc=BeginPaint(hWnd,&ps);
  testbrush=(HBRUSH)GetStockObject(GRAY_BRUSH);
  savebrush=(HBRUSH)SelectObject(hdc,testbrush);

  Rectangle(hdc,10,10,400,100);
  SelectObject(hdc,savebrush);
  EndPaint(hWnd,&ps);
 }

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

}

일단은 브러시 핸들을 저장할 변수를 선언하는데 하나는 사용할변수 하나는 임시 저장할 변수.

이렇게 만들어둡니다.

GetStockObject 함수로 회색 브러시를 얻되 hbrush에 형 변수에 대입하기위해 캐스팅을 했다.

SelectObject 가 리턴하는 값은 새로 선택된 오브젝트 이전에 선택되어있던 같은 종류의 오브젝트의 핸들이다.

오브젝트 핸들이다. 예를들어 펜을 선택하면 이전에 쓰던 펜을 브러쉬라면 이전에 쓰던 브러쉬이다.

이해가 안된다면 코드를 잠깐 더 수정해서.

 case WM_PAINT:
  hdc=BeginPaint(hWnd,&ps);
  testbrush=(HBRUSH)GetStockObject(GRAY_BRUSH);
  savebrush=(HBRUSH)SelectObject(hdc,testbrush);
  Rectangle(hdc,10,10,400,100);
  SelectObject(hdc,savebrush);
  Rectangle(hdc,10,200,400,100);
  SelectObject(hdc,testbrush);
  Rectangle(hdc,10,300,400,200);

  EndPaint(hWnd,&ps);
 }

이렇게 바꿔보길 바란다.

그런데 왜 이렇게 이전것을 저장해두어야하는지는 차후에 설명하겠다.

참고로 결과는


이렇게 결과가 나올것이다.