Thread View: borland.public.cppbuilder.nativeapi
8 messages
8 total messages
Started by UO
Tue, 05 Aug 2008 15:54
Some HDC questions
Author: UO
Date: Tue, 05 Aug 2008 15:54
Date: Tue, 05 Aug 2008 15:54
137 lines
4884 bytes
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...
Re: Some HDC questions
Author: Remy Lebeau (TeamB)
Date: Tue, 05 Aug 2008 17:46
Date: Tue, 05 Aug 2008 17:46
67 lines
2790 bytes
2790 bytes
"UO" <uo@uott> wrote in message news:489877b5$1@newsgroups.borland.com... > Here, does the word "CreateDC" include "CreateCompatibleDC?" CreateDC() and CreateCompatibleDC() are unique and unrelated functions. But in this particular context, you are being warned the same thing. Do not hold on to any HDC that you do not explicitally create yourself. > What about GetDC/GetWindowDC? Do not hold on to those HDCs between messages. > Until I started reading Petzold's book I had used SelectObject() as: That is the correct way to use it. Always re-select any previous GDI resources you replace when you are done using them. > case WM_PAINT: > hdc = GetDC(hwnd); You should be looking at the wParam value. If not 0, it contains an HDC that you need to draw to instead. > SelectObject(hdc, hBrushOld); //1 > When do I have to save / restore old attributes, here the hBrushOld? When you are done using them before exiting. > Is the line marked with //1 necessary? Yes. > Another book gives the following code for BitBlt function as an example: <snip> > Is the line marked with //2 necessary? Yes, for the same reason. > This book restores all GDI objects, not just bitmaps. That is the correct thing to do. If you replace any GDI object with your own, restore the old one when you are done. > Another material, a tutorial actually, gives the following code: <snip> > The default bitmap is restored again. As it should be. > So, when is it necessary to restore default attributes? Always. > Assume the following code: <snip> > Is it ok to delete hdcMem while hBitmap is selected into hdcMem No. > or should I use the following code? Yes. Gambit
Re: Some HDC questions
Author: UO
Date: Tue, 05 Aug 2008 19:16
Date: Tue, 05 Aug 2008 19:16
39 lines
1984 bytes
1984 bytes
"Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message
news:489892df$1@newsgroups.borland.com...
>Do not hold on to any HDC that you do not explicitally create yourself.
Then, yes, CreateCompatibleDC/DeleteDC can be used between messages
> That is the correct way to use it. Always re-select any previous GDI
> resources you replace when you are done using them.
>
>> case WM_PAINT:
>> hdc = GetDC(hwnd);
>
> You should be looking at the wParam value. If not 0, it contains an HDC
> that you need to draw to instead.
Sorry, my mistake. The code should be:
case WM_PAINT:
hdc = BeginPaint(hdc, &ps);
hBrushOld = SelectObject(hdc, hBrush);
GetClientRect(&rect);
Rectangle(hdc, 10, 20, 30, 40);
SelectObject(hdc, hBrushOld); //1
EndPaint(hdc, &ps);
break;
>> So, when is it necessary to restore default attributes?
>
> Always.
It's quite weird that a textbook which is considered as "classic" or "best"
by many people,
can contain so arguable material.
Thanks again...
Re: Some HDC questions
Author: Remy Lebeau (TeamB)
Date: Tue, 05 Aug 2008 20:49
Date: Tue, 05 Aug 2008 20:49
21 lines
1630 bytes
1630 bytes
"UO" <uo@uott> wrote in message news:4898a6fd$1@newsgroups.borland.com...
> Sorry, my mistake. The code should be:
Your code is still not looking at the wParam value. And it is passing an
invalid HWND to both BeginPaint() and EndPaint() as well. Try this instead:
case WM_PAINT:
if( wParam == 0 )
hdc = BeginPaint(hwnd, &ps);
else
hdc = reinterpret_cast<HDC>(wParam);
...
if( wParam == 0 )
EndPaint(hwnd, &ps);
break;
Gambit
Re: Some HDC questions
Author: Alan Bellingham
Date: Tue, 05 Aug 2008 22:29
Date: Tue, 05 Aug 2008 22:29
19 lines
1738 bytes
1738 bytes
"UO" <uo@uott> wrote: >It's quite weird that a textbook which is considered as "classic" or "best" >by many people, can contain so arguable material. Petzold (at least the earliest editions) were the best purely by dint of being pretty much the *only* books with the requisite information in. They were lousy so far as the quality of their C++ went, but they did give examples which worked, even if the results were not production code quality. (Once you've got something which makes the APIs work, it's your job to see how it works, and then produce the good stuff. Not everyone did ...) Alan Bellingham -- Team Browns <url:http://www.borland.com/newsgroups/> Borland newsgroup descriptions <url:http://www.borland.com/newsgroups/netiquette.html> netiquette
Re: Some HDC questions
Author: UO
Date: Wed, 06 Aug 2008 06:42
Date: Wed, 06 Aug 2008 06:42
14 lines
1605 bytes
1605 bytes
"Alan Bellingham" <alanb@episys.com>, haber iletisinde sunlari yazdi:brkh94lo4g60fric1ii9g9uki4af7bul9m@4ax.com... > "UO" <uo@uott> wrote: > > (Once you've got something which makes the APIs work, it's your job to > see how it works, and then produce the good stuff. Not everyone did ...) The main concern of my messages was gdi memory leak. I think it is quite hard to produce a memory leak and "see how it works" in recent Windows systems. So, I still think everyone needs theoretical-correct information, a theoretical-correct book. UO
Re: Some HDC questions
Author: UO
Date: Wed, 06 Aug 2008 07:36
Date: Wed, 06 Aug 2008 07:36
43 lines
2134 bytes
2134 bytes
"Remy Lebeau (TeamB)" <no.spam@no.spam.com>, haber iletisinde �unlar�
yazd�:4898bd3c$1@newsgroups.borland.com...
>
> "UO" <uo@uott> wrote in message news:4898a6fd$1@newsgroups.borland.com...
>
>> Sorry, my mistake. The code should be:
>
> Your code is still not looking at the wParam value. And it is passing an
> invalid HWND to both BeginPaint() and EndPaint() as well. Try this
> instead:
>
> case WM_PAINT:
> if( wParam == 0 )
> hdc = BeginPaint(hwnd, &ps);
>
> else
> hdc = reinterpret_cast<HDC>(wParam);
> ...
> if( wParam == 0 )
> EndPaint(hwnd, &ps);
> break;
>
>
> Gambit
Sorry, I've made a typing mistake again. It should:
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
hBrushOld = SelectObject(hdc, hBrush);
GetClientRect(&rect);
Rectangle(hdc, 10, 20, 30, 40);
SelectObject(hdc, hBrushOld); //1
EndPaint(hwnd, &ps);
break;
(But appearently you understood what I meant)
I'm not using common controls currently.
Anyway, should I use a ReleaseDC() or something after
"hdc = reinterpret_cast<HDC>(wParam);" ?
UO
Re: Some HDC questions
Author: Remy Lebeau (TeamB)
Date: Wed, 06 Aug 2008 16:37
Date: Wed, 06 Aug 2008 16:37
11 lines
1417 bytes
1417 bytes
"UO" <uo@uott> wrote in message news:48995465$1@newsgroups.borland.com... > Anyway, should I use a ReleaseDC() or something after > "hdc = reinterpret_cast<HDC>(wParam);" ? No. The sender of the message owns that HDC and will release it accordingly after the WM_PAINT message handler exits. Gambit
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads