우리는 지금까지 GDI 오브젝트를 사용할 때마다 항상 같은 타입의 Old 핸들을 선언하고 SelectObject로 선택할 때 밀려 나온 이전에 사용되었던 객체를 Old에 대입받아 두었다가 파괴하기 전에 Old를 다시 DC에 선택하였다.
지금부터 이런 식의 코드가 왜 필요한지 연구해 보도록 하자.
아래의 코드는 마우스 왼쪽 버튼을 누를 때 굵기 2의 파란색 펜을 만들고 DC에 선택하여 사용하기를 1000번 반복하는 코드이다.
case WM_LBUTTONDOWN:
hdc = GetDC(hWnd);
for(int i=0; i<1000; i++){
hPen = CreatePen(PS_SOLID, 2, RGB(0, 0, 255));
SelectObject(hdc, hPen);
}
ReleaseDC(hWnd, hdc);
return 0;펜을 만들기만 할 뿐 파괴하지 않기 때문에 이 프로그램은 한참 실행하다 보면 리소스 영역이 바닥나서 펜은 물론이고 브러쉬, 폰트 등의 GDI 오브젝트는 더 이상 생성하지 못하게 된다. GDI 오브젝트를 저장하는 리소스 영역은 메인 메모리와는 다른 특수한 영역인데 이 영역의 크기가 그리 크지 못해 오브젝트를 많이 만들면 금방 가득차 버린다.
그러면 DeleteObject를 넣어보도록 하자
case WM_LBUTTONDOWN:
hdc = GetDC(hWnd);
for(int i=0; i<1000; i++){
hPen = CreatePen(PS_SOLID, 2, RGB(0, 0, 255));
SelectObject(hdc, hPen);
DeleteObejct(hPen);
}
ReleaseDC(hWnd, hdc);
return 0;이 코드의 문제점은 뭐라고 생각하는가?
그렇다. DC에 선택된 오브젝트는 삭제할 수 없는 규칙 때문에 이 코드는 정상적으로 작동되지 않는다.
왜냐하면, 현재 DC에 선택되어있는 펜 오브젝트를 지워버리면 이후에 선을 그을 수 없게 되기 때문이다.
펜이나 브러쉬같은 기본적인 오브젝트는 디폴트이든 만든 것이든 하나는 꼭 DC에 선택되어 있어야 한다.
정상적인 코드를 짜기 위해서는 현재 선택되어있는 오브젝트를 해제해야 할 필요가 있는데, 그러기 위해서는 같은 타입의 다른 펜을 선택하는 방법뿐이다.
펜뿐만 아니라 브러쉬나 폰트 등도 마찬가지로 위와 같은 규칙이 적용된다.
현재 DC에 선택되어있는 오브젝트를 밀어내기 위해, StockObject를 선택하는 방법을 사용해보자.
case WM_LBUTTONDOWN:
hdc = GetDC(hWnd);
for(int i=0; i<1000; i++){
hPen = CreatePen(PS_SOLID, 2, RGB(0, 0, 255));
SelectObject(hdc, hPen);
SelectObject(hdc, StockObject(BLACK_PEN));
DeleteObject(hPen);
}
ReleaseDC(hWnd, hdc);
return 0;이렇게 하면 검정색 스톡펜이 선택될 때 hPen이 선택 해제되므로 정상적인 삭제가 가능하고, 리소스 누출을 막을 수 있다.
하지만
위와 같은 상황에서 초록색 펜으로 복구되지 않고, 이후부터 검정색으로만 그려질 것이다.
그래서 원래 선택된 오브젝트를 저장했다가 다시 복구하기 위한 Old오브젝트가 필요하다.
case WM_LBUTTONDOWN:
hdc = GetDC(hWnd);
for(int i=0; i<1000; i++){
hPen = CreatePen(PS_SOLID, 2, RGB(0, 0, 255));
OldPen = (HPEN)SelectObject(hdc, hPen);
DeleteObject(SelectObject(hdc, OldPen));
}
ReleaseDC(hWnd, hdc);
return 0;Old오브젝트를 사용하여 DC를 원래대로 돌려놓는 습관을 가지는 것이 좋은데 이는 GDI 오브젝트뿐만 아니라 거의 모든 자원에 대해서도 마찬가지이다.
-------------------------------------------------------------------------------
'API' 카테고리의 다른 글
| 그리기 모드(코드) (0) | 2018.01.24 |
|---|---|
| 그리기 모드 (0) | 2018.01.24 |
| 브러쉬 만들기 (0) | 2018.01.22 |
| 나만의 펜을 만들어 보자! (0) | 2018.01.20 |
| StockObject를사용한 GDI브러쉬 색 변경 (0) | 2018.01.14 |