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?
 
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
0
 
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?
0
 
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 ).
0
Cloud Class® Course: Amazon Web Services - Basic

Are you thinking about creating an Amazon Web Services account for your business? Not sure where to start? In this course you’ll get an overview of the history of AWS and take a tour of their user interface.

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

Why?  What are these methods, how will they help.
0
 
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.

0
 
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;
0
 
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).
0
 
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
0
 
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.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.