GDI绘图中经常会创建一些画刷、画笔和位图等资源,通常这些资源通过调用函数CreateSolidBrush、CreatePen、CreateCompatibleBitmap等方法创建。这些资源在使用完成以后必须通过调用DeleteObject()函数释放资源,否则会发生资源泄漏,最终导致系统资源被耗光,不能再次成功创建资源。
考虑下面一段代码:
HBITMAP hBmpLayer1,hBmpOldLayer1;
HBITMAP hBmpLayer0,hBmpOldLayer0;
HDC hDcLayer1 = 0;
HDC hDcLayer0 = 0;
int mouseX =0,mouseY =0;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_CREATE:
{
RECT rt;
rt.left = 0;
rt.right = 20;
rt.top = 0;
rt.bottom = 20;
hDcLayer1 = CreateCompatibleDC(GetDC(NULL));
hBmpLayer1 = CreateCompatibleBitmap(GetDC(NULL),20,20);
hBmpOldLayer1 = (HBITMAP)SelectObject(hDcLayer1,hBmpLayer1);
FillRect(hDcLayer1,&rt,CreateSolidBrush(0));
rt.left =2;
rt.top = 2;
rt.bottom =17;
rt.right =17;
FillRect(hDcLayer1,&rt,CreateSolidBrush(0xff00ff));
return DefWindowProc(hWnd, message, wParam, lParam);
}
case WM_PAINT:
RECT rt;
int i,k,x,y,error;
HPEN hPen,hOldPen;
HBRUSH hBrshBlack,hBrsh;
hdc = BeginPaint(hWnd, &ps);
if(!hdc)
{
error = GetLastError();
}
// TODO: Add any drawing code here...
GetClientRect(hWnd, &rt);
if(hDcLayer0 != NULL)
{
SelectObject(hDcLayer0,hBmpOldLayer0);
DeleteDC(hDcLayer0);//释放资源
DeleteObject(hBmpLayer0);//释放资源
hDcLayer0 = NULL;
hBmpLayer0 = NULL;
hBmpOldLayer0 = NULL;
}
hDcLayer0 = CreateCompatibleDC(hdc);
if(!hDcLayer0)
{
error = GetLastError();
}
hBmpLayer0 = CreateCompatibleBitmap(hdc,rt.right-rt.left,rt.bottom-rt.top);
if(!hBmpLayer0)
{
error = GetLastError();
}
hBmpOldLayer0 = (HBITMAP)SelectObject(hDcLayer0,hBmpLayer0);
if(!hBmpOldLayer0)
{
error = GetLastError();
}
hBrshBlack = CreateSolidBrush(0);
FillRect(hDcLayer0,&rt,hBrshBlack);
x=rt.left;
y=rt.top+(rt.bottom-rt.top)/2;
hPen = CreatePen(PS_SOLID, 1, RGB(0xff,0x0,0x0));
hOldPen = (HPEN)SelectObject(hDcLayer0 ,hPen);//选入画笔
MoveToEx(hDcLayer0 ,x,y,NULL);
LineTo(hDcLayer0 ,rt.right,y+5);//绘图
SelectObject(hDcLayer0 ,hOldPen);//选出画笔
DeleteObject(hPen);//释放资源
hPen = CreatePen(PS_SOLID, 1, RGB(0x0,0xff,0x0));
hOldPen = (HPEN)SelectObject(hDcLayer0 ,hPen);
MoveToEx(hDcLayer0 ,x,y+10,NULL);
LineTo(hDcLayer0 ,rt.right,y+10);//绘图
SelectObject(hDcLayer0 ,hOldPen);//选出画笔
DeleteObject(hPen);
hPen = CreatePen(PS_SOLID, 1, RGB(0x0,0x0,0xff));
hOldPen = (HPEN)SelectObject(hDcLayer0 ,hPen);//选入画笔
MoveToEx(hDcLayer0 ,x,y-10,NULL);
LineTo(hDcLayer0 ,rt.right,y-10);//绘图
SelectObject(hDcLayer0 ,hOldPen);//选出画笔
DeleteObject(hPen);//释放画笔资源
DeleteObject(hBrshBlack);//释放画刷资源
error = BitBlt(hdc,0,0,rt.right,rt.bottom,hDcLayer0,0,0,SRCCOPY);
if(!error)
error =GetLastError();
TransparentBlt(hdc,mouseX,mouseY,20,20,hDcLayer1,0,0,20,20,0);
EndPaint(hWnd, &ps);
break;
case WM_MOUSEMOVE:
{
mouseX = lParam&0xffff;
mouseY = lParam>>16;
InvalidateRect(hWnd,NULL,FALSE);
break;
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
如果将程序中释放资源的部分去掉,那么在鼠标移动一段时间以后,画面将变成黑白图像,其原因就是多次创建资源而没有释放,导致资源耗尽,无法再次分配资源。
对于DC资源,如果使用CreateCompitableDC()方法创建,则在使用完成后需要使用DeleteDC()释放资源。
如果是通过GetDC()方法获取的资源,则需要调用ReleaseDC()释放资源。
对于已选入了DC的画笔、画刷、位图等资源,必须将其选出后才能进行资源释放,否则不成功。
转自:http://itbeebee.blog.sohu.com/51692337.html