Board index » delphi » Freeing GDI Resources

Freeing GDI Resources

I checked www.mers.com/searchsite.html and couldn't find the answer to my
problem.  (Maybe I used the wrong phrasing).  Here goes...

I  have a word processor component I have written with D5 (based upon
TRxRichEdit) that slowly consumes all the available GDI/System resources on
Win9x systems.  I've narrowed the problem down to the routine(s) that draw
my rulers.  I have *VERY* carefully gone over my code and for every GetDC()
there is a ReleaseDC, for every CreatexxxBrush, there is a DeleteObject.
Basically the code looks something like this

Note: Ruler and r are TRect's declared and initialized elsewhere

procedure TWordProcessor.DrawHRuler;
var
    dc: hDC;
    Brush: hBrush;
begin
    dc := GetDC(Parent.Handle);  // ruler is drawn outside the Richedit and
on the parent
    Brush := CreateSolidBrush(ColorToRGB(clYellow));
    Rectangle(dc, Ruler.Left, Ruler.Top, Ruler.Right, Ruler.Bottom);
    // repaint the form at the end of the ruler
    DeleteObject(Brush);
    Brush := CreateSolidBrush(ColorToRGB(clBtnFace));
    FillRect(dc, r, Brush);
    DeleteObject(Brush);
    ReleaseDC(Parent.Handle, dc)
end;

If I run this program under Win9x with the resource meter running I can
watch the resources go down,  if I comment out the above code the resources
maintain a constant level.  What is wrong?  Am I missing something or is
this a Win9x bug?

Thanks in advance.
--

Roy Owen
Servant PC Resources, Inc.

 

Re:Freeing GDI Resources


You need to select the new brush into your DC, saving the old brush, then
restoring the old brush to the DC just before you release the DC.

See the new lines in your routine below.

Roy Green

Quote
"Roy Owen" <rwo...@servantpc.com> wrote in message

news:3afc0f2c$1_1@dnews...

procedure TWordProcessor.DrawHRuler;
var
   dc: hDC;
   Brush: hBrush;
   oldBrush : hBrush;
begin
   dc := GetDC(Parent.Handle);  // ruler is drawn outside the Richedit and
on the parent
   Brush := CreateSolidBrush(ColorToRGB(clYellow));
   oldBrush := SelectObject(dc, Brush);        // save previously selected
(or default) brush in oldBrush
   Rectangle(dc, Ruler.Left, Ruler.Top, Ruler.Right, Ruler.Bottom);
   // repaint the form at the end of the ruler
   SelectObject(dc, oldBrush);                      // select back the
previous brush before cleanup
   DeleteObject(Brush);
   Brush := CreateSolidBrush(ColorToRGB(clBtnFace));
   FillRect(dc, r, Brush);        // doesn't need to have the brush
selected, since it uses it directly
   DeleteObject(Brush);
   ReleaseDC(Parent.Handle, dc)
end;

Re:Freeing GDI Resources


Thanks! :)

--

Roy Owen
Servant PC Resources, Inc.

Quote
"Roy Green" <roygr...@mindspring.com> wrote in message

news:3afc2932_1@dnews...
Quote
> You need to select the new brush into your DC, saving the old brush, then
> restoring the old brush to the DC just before you release the DC.

> See the new lines in your routine below.

> Roy Green

> "Roy Owen" <rwo...@servantpc.com> wrote in message
> news:3afc0f2c$1_1@dnews...

> procedure TWordProcessor.DrawHRuler;
> var
>    dc: hDC;
>    Brush: hBrush;
>    oldBrush : hBrush;
> begin
>    dc := GetDC(Parent.Handle);  // ruler is drawn outside the Richedit and
> on the parent
>    Brush := CreateSolidBrush(ColorToRGB(clYellow));
>    oldBrush := SelectObject(dc, Brush);        // save previously selected
> (or default) brush in oldBrush
>    Rectangle(dc, Ruler.Left, Ruler.Top, Ruler.Right, Ruler.Bottom);
>    // repaint the form at the end of the ruler
>    SelectObject(dc, oldBrush);                      // select back the
> previous brush before cleanup
>    DeleteObject(Brush);
>    Brush := CreateSolidBrush(ColorToRGB(clBtnFace));
>    FillRect(dc, r, Brush);        // doesn't need to have the brush
> selected, since it uses it directly
>    DeleteObject(Brush);
>    ReleaseDC(Parent.Handle, dc)
> end;

Other Threads