Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 489
  • Last Modified:

Canvas

Hi!
Sometimes I get a stupid mistake: "Canvas doesn't allow drawing". Usually it happens if another window covers a part of my window (but not always). What I do: I have some controls, on the canvas of which I perform some drawing. Does anybody know what to do?

Thanks.
0
shtern
Asked:
shtern
  • 8
  • 3
  • 2
  • +6
1 Solution
 
kubeerjaCommented:
can u show part of your code
0
 
shternAuthor Commented:
It's really long. There are a couple of self-made components, which perform a lot of drawing. It's a simple drawing on canvas: Canvas.Draw, BitBlt and so on.
0
 
DrDelphiCommented:
There are a few possible reasons for this.

1. The canvas on which you are trying to draw has been locked.

2. The handle to the canvas which you are drawing on (or attempting to anyway) is not valid.

 if you are moving things around on the form and using screen coordinates for the drawing, you might be actually trying to draw unto something which does not allow it. (such as a form's caption bar).
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
bryan7Commented:
listenning
0
 
nricoCommented:
You can eliminate (2) if you use Form.Canvas.Handle.
0
 
sagerydCommented:
Try using a TImage instead of painting directly on the form canvas. Might work better.

--johan
0
 
shternAuthor Commented:
I draw direct on the control's canvas, and use the coordinates inside of it, so it can't be the form's caption. Using TImage could be OK, but where is the difference? I have created my own component, something like TTreeView, but with other possibilities, and the drawing I perform is the drawing of nodes on it. Should I use TImage as background?

Except, it happens only if another window (e.g. Explorer) has covered a part of my window for a while. As my window becomes active again, this error occurs, but not always.
0
 
ITugayCommented:
Is it possible your try drawing in control was created, but not inserted in Z-order? I mean:

C:=TMyControl.Create(Self);
// you can't draw before next operator is executed.
InsertControl(C);
// now drawing available.

-----
Igor.
0
 
shternAuthor Commented:
It's not when the program starts. I can work any time with it, and then it happens. This control is on the main form, and it is always open.
0
 
ITugayCommented:
When you move some form over your component, it may force drawing of your component. Do you have the message at that moment?
----
Igor.
0
 
MaximWCommented:
It happens if you use a lot of graphics and your system GDI resources are low(=0).Optimizing of open DCs & bitmaps should help.
0
 
shternAuthor Commented:
MaximW, could you please tell me more about it. Yes, I use graphic, but not so much, and it happens on many computers with different resources. What do you mean with optimizing?
0
 
MaximWCommented:
If the problem is running out of GDI resources... try to look up
b : TBitmap;
b.Dormant;
b.ReleaseImage;

P.S. Sorry for so unclear advises, but i have the same problem to solve:).
0
 
shternAuthor Commented:
I don't understand why is it running out of resources. I have just some bitmaps (two or three) which I draw with Canvas.Draw as a Background and some TImage's, no more. But maybe it's a case.

But I haven't understood your last advise: where should I use it?

Sorry for such a question, but I've read in delphi help about it, and understood practically nothing.
0
 
MaximWCommented:
Hi
 regarding
 .Dormant
 .FreeImage

 as far as I know,  for  every TBitmap or TImage object you open, GDI locks an entry for HBITMAP(bmp handle) in the GDI table. The more bitmap objects you have open the less free entries remain.
So ,if you use a bitmap for drawing purpose only, something like this

 mb:= TBitmap.Create;
 mb.LoadFromResources(...
 .Canvas.Draw (x,y,mb);

and you need TBitmap object(not the image) itself for the future use, makes sense the following:
mb:= TBitmap.Create;
 mb.LoadFromResources(...
 .Canvas.Draw (x,y,mb);
 mb.Dormant;
 mb.FreeImage;
//it will release the GDI entry

even if you place it in the loop of ...200, you will have 200 TBitmap objects and the same level of GDI res. as it  has been before the loop.
As I have seen in Delphi help and some Delphi books, only .Dormant must do that keeping your image in memory stream instead of open image, and free GDI res , but it doesn't:-). Maybe i don't understand it good enough.
0
 
shternAuthor Commented:
Can you also explain me what does it change (except freeing resources)? Maybe, the quality will be not so good or what?
0
 
shternAuthor Commented:
Adjusted points from 100 to 200
0
 
sauliteCommented:
Before draw on window, bring it to front. Do this every time, before drawing
0
 
shternAuthor Commented:
Could you, please, be more exact? I have my program running. Then I run, e.g., Explorer. As I then go to my program again (e.g. Alt-Tab), this error happens. But (!) not always. Maybe it's really something with resources?
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 8
  • 3
  • 2
  • +6
Tackle projects and never again get stuck behind a technical roadblock.
Join Now