您的位置:首页 > 其它

GDI绘图中的资源释放

2013-01-21 17:13 204 查看
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的画笔、画刷、位图等资源,必须将其选出后才能进行资源释放,否则不成功。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: