Drawing problems: EOutOfResources,EInvalidOperation

I get the following exceptions when my program calls the Tcanvas.draw and Tcanvas.copyrect methods

Exception Type   : EInvalidOperation
Message: Canvas does not allow drawing

Exception Type   : EOutOfResources
Message: Error creating window device context

This program is distributed to many differrent users on many differrent machines.  It does not occur on most machines.

There are no memory leaks in my program.  I have verified this with a memory monitoring tool.  Also, the reports I get show that I there is plenty of available RAM and disk space at the time the exception is raised.

The user interface uses many small offscreen Tbitmaps.  None of them are bigger than 200X300.  I also use some temporary Tbitmaps that are created and destroyed during Paint operations.

All of the drawing is done in the main thread of the program.

Any thoughts on what could be the cause of this problem?
LVL 2
wolsenAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

delphizedCommented:
Do you use some strange (unusual)  method to obtain the canvas? (getwindowdc, getdc )? fi yes you should use releasedc.
Do you create fonts at runtime?.
Do you use a lot of visual components in your application?
your canvas is directed to the screen, correct?
cubudCommented:
Canvas does not allow drawing = Canvas.Handle is 0
EOutOfResources happens when you do use GetDC without ReleaseDC.  Win95/98 is much more forgiving, whereas NT will crash.


--
Pete
=============
Read or write technical articles
  http://www.HowToDoThings.com

Audio compression components, FastStrings library, DIB controls
  http://www.DroopyEyes.com

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
wolsenAuthor Commented:
Thank you both for your comments.

>Do you use some strange (unusual)  method to obtain the canvas? (getwindowdc, getdc )?
  I don't think so, but I am using a some 3rd party code that may be doing this.  I will have to check, and make sure that releaseDC is called appropriately.  This may be the problem.

>Do you create fonts at runtime?
 No.

Do you use a lot of visual components in your application?
Yes: several Timage components , several TGraphicControl descendents ( custom scroll bars, custom buttons ).  There are two Tdrawgrids, as well as two Twebbrowsers.  I am also using a transparent edit box component.  All of these components are arranged on several layers of TPanels that are seperated By TSplitters, so that the interface has many degrees of adjustability.

your canvas is directed to the screen, correct?
Some of the drawing is done to "offscreen" TBitmaps.  These bitmaps are later drawn to the screen during the paint events.  My program stores many offscreen bitmaps.  For example, the buttons store a bitmap for three differrent states ( regular, hover, press ).
CompTIA Security+

Learn the essential functions of CompTIA Security+, which establishes the core knowledge required of any cybersecurity role and leads professionals into intermediate-level cybersecurity jobs.

DragonSlayerCommented:
try looking at Dormant and FreeImage methods of TBitmap
wolsenAuthor Commented:
>try looking at Dormant and FreeImage methods of TBitmap

Why?  What are these methods, how will they help.
BTechoCommented:
>Win95/98 is much more forgiving, whereas NT will crash.

It can also be the other way around, Win9X resources are limited when compared to WinNT/2000/XP. You can have graphics apps work fine on NT systems while they crash on Win9x/ME. Visit this site http://www.aumha.org for more information, specificly this page http://aumha.org/win4/a/resource.htm

>>Do you use some strange (unusual)  method to obtain the canvas? (getwindowdc, getdc )?
> I don't think so, but I am using a some 3rd party code that may be doing this.  I will have to check, and make sure > that releaseDC is called appropriately.  This may be the problem.

If ReleaseDC ins't called when it should be , then that's a resource leak. Which can be felt more if you use Win9x for the reason I mentioned above, it has much more limited resources.


>>try looking at Dormant and FreeImage methods of TBitmap
>Why?  What are these methods, how will they help.

Description from Delphi help:

Use FreeImage to reduce the memory requirements of an application when color depth and pixel format are not an issue. Freeing the image releases the memory allocated for the bitmap image when it was originally loaded to disk. Consequently, some of the original pixel format of the bitmap is lost (for example, if you changed its format to a DIB) as well as the color depth of the bitmap.

When a bitmap is loaded into a bitmap object, the bitmap object creates an image of the loaded bitmap in memory. If the bitmap isn't changed, the memory image is used when saving the bitmap, to verify that the bitmap has not lost color depth or changed the pixel format.

wolsenAuthor Commented:
This is the only portion of the code that is using "GetDC".  
I don't see any red flags here, but I thought I would post the code, in case I missed something.

Everywhere else in the program,  I am doing all of the drawing with TCanvas methods.

From Transparent Components for Delphi 32  (Medialight Software Solutions):

...

procedure TTransEdit.RepaintWindow;
var
 DC: hDC;
 TmpBitmap, Bitmap: hBitmap;
begin
 if FTransparent then
 begin
  FPainting := true;
  HideCaret(Handle);
  DC := CreateCompatibleDC(GetDC(Handle));
  TmpBitmap := CreateCompatibleBitmap(GetDC(Handle), Succ(ClientWidth), Succ(ClientHeight));
  Bitmap := SelectObject(DC, TmpBitmap);
  PaintTo(DC, 0, 0);
  BitBlt(GetDC(Handle), BorderRec[BorderStyle], BorderRec[BorderStyle], ClientWidth, ClientHeight, DC, 1, 1, SRCCOPY);
  SelectObject(DC, Bitmap);
  DeleteDC(DC);
  ReleaseDC(Handle, GetDC(Handle));
  DeleteObject(TmpBitmap);
  ShowCaret(Handle);
  FPainting := false;
 end;
end;
DragonSlayerCommented:
the hBitmap variable, Bitmap, was never released via DeleteObject?

also, if you have, say, different states for buttons, etc, take a look at TImageList, which stores multiple images but only uses one bitmap handle (if we don't count the handle for image mask, of course).
cubudCommented:
try this

FPainting := True;
HideCaret(Handle);
DCHandle := GetDC(Handle);  **Don't keep calling GetDC!!
DC := CreateCompatibleDC(DCHandle);
TmpBitmap := CreateCompatibleBitmap(DCHandle, ClientWidth, ClientHeight);
GDIFlush; **I have had trouble when this is not here!!
OldBitmap := SelectObject(DC, TmpBitmap); **Remember the old bitmap
PaintTo(DC, 0, 0);
BitBlt(DCHandle, BorderRec[etc], etc, ClientWidth, ClientHeight, DC, 1, 1, SRCCOPY);
SelectObject(DC, OldBitmap); **Put the old bitmap back!!
DeleteObject(TmpBitmap);
DeleteDC(DC); **You wasn't deleting this
ReleaseDC(Handle, DCHandle); **You wasn't releasing this!!


--
Pete
=============
Read or write technical articles
 http://www.HowToDoThings.com

Audio compression components, FastStrings library, DIB controls
 http://www.DroopyEyes.com
wolsenAuthor Commented:
Experts,

Thanks for all your comments.  

cubud: I am waiting for feedback to see your suggestion fixes the problem.  I'll get back to this in a day or two.  

I will probably be splitting the points.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.