🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: borland.public.cppbuilder.nativeapi
Article #36

Some HDC questions

#36
From: UO
Date: Tue, 05 Aug 2008 15:54
137 lines
4884 bytes
Hi,

I have some inconsistent knowledge about device contexts from different 
textbooks.

1st question:
One of them is Petzold's book.
It says: "Except for a device context created with a call to CreateDC you 
should not keep a device context handle
around from one message to another. "
Here, does the word "CreateDC" include "CreateCompatibleDC?"
I've seen some examples in the book:  CreateCompatibleDC is called in 
WM_CREATE,  used in WM_PAINT,
and destroyed in WM_DESTROY, which is what I had been doing until I read 
Petzold's book.

What about GetDC/GetWindowDC?
I've been using it as:
1) g_hdc = GetDC(hwnd); (in WM_CREATE)
2) use it elsewhere, (currently only for CreateCompatibleDC and 
GetDeviceCaps)
3) ReleaseDC(hwnd, g_hdc); (in WM_DESTROY)
Is my way correct?

-------------------------------
2nd question, about GDI memory leaks:

Until I started reading Petzold's book I had used SelectObject() as:

hBrush = CreateSolidBrush(RGB(0xFF, 0x00, 0x00));
RECT rect;

case WM_PAINT:
    hdc = GetDC(hwnd);
    hBrushOld = SelectObject(hdc, hBrush);
    GetClientRect(&rect);
    Rectangle(hdc, 10, 20, 30, 40);
    SelectObject(hdc, hBrushOld); //1
break;

When do I have to save / restore old attributes, here the hBrushOld?
Is the line marked with //1 necessary?


Another book gives the following code for BitBlt function as an example:
// Create a DC that matches the device.
hdcMem = CreateCompatibleDC (hdc);

// Select the bitmap into the compatible device context.
hOldSel = SelectObject (hdcMem, hBitmap);

// Get the bitmap dimensions from the bitmap.
GetObject (hBitmap, sizeof (BITMAP), &bmp);

// Copy the bitmap image from the memory DC to the screen DC.
BitBlt (hdc, rect.left, rect.top, bmp.bmWidth, bmp.bmHeight,
        hdcMem, 0, 0, SRCCOPY);

// Restore original bitmap selection and destroy the memory DC.
SelectObject (hdcMem, hOldSel); //2
DeleteDC (hdcMem);Is the line marked with //2 necessary? This book restores 
all GDI objects, not just bitmaps.
For example:

    PAINTSTRUCT ps;
    RECT rect;
    HDC hdc;
    POINT ptArray[6];
    HBRUSH hBr, hOldBr;
    TCHAR szText[128];

    GetClientRect (hWnd, &rect);
    hdc = BeginPaint (hWnd, &ps);

    // Draw ellipse.
    hBr = (HBRUSH) GetStockObject (DKGRAY_BRUSH);
    hOldBr = (HBRUSH) SelectObject (hdc, hBr);
    Ellipse (hdc, 10, 50, 90, 130);
    SelectObject (hdc, hOldBr);

    // Draw round rectangle.
    hBr = (HBRUSH) GetStockObject (LTGRAY_BRUSH);
    hOldBr = (HBRUSH) SelectObject (hdc, hBr);
    RoundRect (hdc, 95, 50, 150, 130, 30, 30);
    SelectObject (hdc, hOldBr);


Another material, a tutorial actually, gives the following code:
case WM_PAINT:
{
  BITMAP bm;
  PAINTSTRUCT ps;
  HDC hdc = BeginPaint(hwnd, &ps);
  HDC hdcMem = CreateCompatibleDC(hdc);
  HBITMAP hbmOld = SelectObject(hdcMem, g_hbmBall);
  GetObject(g_hbmBall, sizeof(bm), &bm);
  BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
  SelectObject(hdcMem, hbmOld); //3
  DeleteDC(hdcMem);
  EndPaint(hwnd, &ps);
}

The default bitmap is restored again.

In the Petzold's book I couldn't see restoring GDI objects for a given DC.
So, when is it necessary to restore default attributes? When does a memory 
leak occur?


I know, GDI objects should not be deleted when they are selected in a device 
contexts.
Assume the following code:

hBitmap = LoadFromFile(...);
hdcMem = CreateCompatibleDC(...);
SelectObject(hdc, hBitmap);
BitBlt(hdc,...,hdcMem...)
//...
DeleteDC(hdcMem);
DeleteObject(hBitmap);
PostQuitMessage(0);

Is it ok to delete hdcMem while hBitmap is selected into hdcMem(this is what 
Petzold's book does)
or should I use the following code?

hBitmap = LoadFromFile(...);
hdcMem = CreateCompatibleDC(...);
hBitmapOld = (HBITMAP)SelectObject(hdc, hBitmap);
BitBlt(hdc,...,hdcMem...)
//...
SelectObject(hdcMem, hBitmapOld); //////////////////
DeleteDC(hdcMem);
DeleteObject(hBitmap);
PostQuitMessage(0);

Thanks...
Technical Details
Message-ID: <489877b5$1@newsgroups.borland.com>
Path: arc1-ca.pugleaf.net!g2news2.google.com!news4.google.com!feeder.news-service.com!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail

Show Full Headers
Complete Article Headers
X-Google-Thread: 10cc67,fa1b3304c969ec75,start
X-Google-Attributes: gid10cc67,domainid0,public,usenet
X-Google-Language: ENGLISH,ASCII-7-bit
From: "UO" <uo@uott>
Newsgroups: borland.public.cppbuilder.nativeapi
Subject: Some HDC questions
Date: Tue, 5 Aug 2008 18:54:34 +0300
Lines: 139
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2900.3138
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.3198
X-RFC2646: Format=Flowed; Original
NNTP-Posting-Host: 81.213.76.81
Message-ID: <489877b5$1@newsgroups.borland.com>
X-Trace: newsgroups.borland.com 1217951669 81.213.76.81 (5 Aug 2008 08:54:29 -0700)
Path: arc1-ca.pugleaf.net!g2news2.google.com!news4.google.com!feeder.news-service.com!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail