谈GDI绘图中的资源释放

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

你可能感兴趣的:(command,null,callback,menu)