locked
Double Buffering GDI Leak RRS feed

  • Question

  • It seems that whenever my application loses focus (to another application or MessageBox), it starts GDI leaking, and does not stop. Does anyone have any insight on why this is happening?

    Here's a bit of the buffered code:

    			case WM_PAINT: 
    				{
    					RECT rc;
    					PAINTSTRUCT ps;
    
    					HBRUSH bgBrush = CreateSolidBrush(RGB(255,255,255));
    
    					GetClientRect(hwnd,&rc);
    
    					HDC mhdc = BeginPaint(hwnd,&ps);
    					HDC hdc = CreateCompatibleDC(mhdc);
    
    					HBITMAP bmp = CreateCompatibleBitmap(mhdc, rc.right, rc.bottom);
    
    					SelectObject(hdc,bmp);
    					FillRect(hdc, &rc, bgBrush);
    
    					if (thisObj->xScrollOn) {
    						TRIVERTEX        vert[2] ;
    						GRADIENT_RECT    gRect;
    						vert [0] .x      = 0;
    						vert [0] .y      = 0;
    						vert [0] .Red    = 0xf700;
    						vert [0] .Green  = 0xf700;
    						vert [0] .Blue   = 0xf700;
    						vert [0] .Alpha  = 0x0000;
    
    						vert [1] .x      = rc.right;
    						vert [1] .y      = rc.bottom; 
    						vert [1] .Red    = 0xff00;
    						vert [1] .Green  = 0xff00;
    						vert [1] .Blue   = 0xff00;
    						vert [1] .Alpha  = 0x0000;
    
    						gRect.UpperLeft  = 0;
    						gRect.LowerRight = 1;
    						GradientFill(hdc,vert,2,&gRect,1,GRADIENT_FILL_RECT_V);
    					} else {
    						rc.left = 5;
    					}
    
    					rc.left = thisObj->xScroll; 
    					TCHAR * lpString = (TCHAR*)malloc((GetWindowTextLength(hwnd)+1)*sizeof(TCHAR));
    					GetWindowText(hwnd, lpString, GetWindowTextLength(hwnd)+1);
    					SetBkMode(hdc,TRANSPARENT);
    					DrawText(hdc,lpString,wcslen(lpString),&rc,DT_SINGLELINE|DT_VCENTER);
    					free(lpString);
    
    					if (thisObj->xScrollOn) {
    						HPEN blackPen = CreatePen(PS_SOLID,2,RGB(210,210,210));
    						SelectObject(hdc,blackPen);
    						rc.left = 0;
    						if (thisObj->xScroll < 0) {
    							MoveToEx(hdc,1,0,0);
    							LineTo(hdc,1,rc.bottom);
    						}
    						if (thisObj->xScroll > -(thisObj->xWidth-rc.right)) {
    							MoveToEx(hdc,rc.right-rc.left-1,0,0);
    							LineTo(hdc,rc.right-rc.left-1,rc.bottom);
    						}
    						DeleteObject(blackPen);
    					}
    
    					BitBlt(mhdc, 0, 0, rc.right, rc.bottom, hdc, 0, 0, SRCCOPY);
    					DeleteObject(bmp);
    					DeleteObject(bgBrush);
    					DeleteDC(hdc);
    					EndPaint(hwnd,&ps);
    				}
    				break;

    Friday, December 18, 2009 12:41 AM

Answers

  • I usually store the previously selected bitmap from the memory DC and select it back before destroying the memory DC. Something like:

    HBITMAP hOldBmp = SelectObject(hdc, bmp);

    Before cleaning up:

    SelectObject(hdc, hBmpOld);
    DeleteObject(bmp);
    ...

    This technique must be used for all DC "selectable" objects. I hope this helps.

    João Paulo Figueira (Device Application Development MVP)
    • Marked as answer by ZHE ZHAO Thursday, December 24, 2009 3:28 AM
    Friday, December 18, 2009 9:31 AM