Board index » delphi » Canvas doesn't allow drawing

Canvas doesn't allow drawing

Hi !!

I have a fairly complex shaped window that I can move and resize. Its frame is made of
TShapes and TImages, which are resized immediately when the window itself is being
resized. Same goes for the shape of the window, set via SetWindowRgn (COMPLEXREGION).

I have slimmed down all drawing procedures as far as possible, but still get the message
"Canvas doesn't allow drawing" after a few seconds of resizing the window. Disabling
double-buffering increases the timespan until the error occurs, but doesn't solve the problem.

I have found several questions regarding this error, on the net, but no solution. When
using a TImage, I could lock its canvas, but would that work with a window (TMyFrame is a
TCustomPanel descandent) ? If you think so, how can get and lock its canvas ?

Any other solutions are welcome, of course !!

Daniel

---------
Resizing procedures (simplified):

procedure TMyFrame.MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X,
Y: Integer);
begin
   ReactOnFocus(Sender);    // bring window to front
   if (not Fixed) and (AResizable) then
   begin
     OnResize := nil;
     DragX := X;
     DragY := Y;
     AmResizing := true;
   end;
end;

procedure TMyFrame.MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
   if (AmResizing) then
   begin
     if (not Evaluating) then
     begin
       Evaluating := true;
       if (Width  + X-DragX > 50) then Width := Width + X-DragX else Width := 50;
       if (Height + Y-DragY > 50) then Height := Height + Y-DragY else Height := 50;
       ResizeAllSubComponents(Self);      // This function also uses SetWindowRgn
       Parent.Update;
       Evaluating := false;
     end;
   end;
end;

procedure TMyFrame.MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X,
Y: Integer);
begin
   if (AmResizing) then
   begin
     if (Width  + X-DragX > 50) then Width := Width + X-DragX else Width := 50;
     if (Height + Y-DragY > 50) then Height := Height + Y-DragY else Height := 50;
     AmResizing := false;
     OnResize := ResizeAllSubComponents;
   end;
end;

 

Re:Canvas doesn't allow drawing


Quote
> On the entry to the code you posted lock the canvas of the parent frame
> and lock any canvas of the contained controls as you manipulate them.

And how do I do that ? A TCustomPanel doesn't have a canvas property, and no lock routines.

Daniel G?rlich

Re:Canvas doesn't allow drawing


Quote

> I have found several questions regarding this error, on the net, but no solution. When
> using a TImage, I could lock its canvas, but would that work with a window (TMyFrame is a
> TCustomPanel descandent) ? If you think so, how can get and lock its canvas ?

Lock ANY canvas you are using. Be it the ImageList, the Window you are
drawing to or Bitmap.Canvas.  This is especially true for Win9x.  This
becomes very important when you are doing what I think you are doing,
during a drawing operation you call on other graphic objects to draw to
their canvas through callbacks or function calls.  The issue comes from
the VCL will only hold 5 DC at at time.  After that they are released
(or deleted) so on the return to a function call you try to paint on the
canvas again and the VCL has to reallocate the DC which you may have
saved and try to restore information that was from the previous DC.  By
locking the canvas the VCL won't release the DC.

On the entry to the code you posted lock the canvas of the parent frame
and lock any canvas of the contained controls as you maniuplate them.

Jim

Re:Canvas doesn't allow drawing


Quote
Daniel G?rlich wrote:

> > On the entry to the code you posted lock the canvas of the parent frame
> > and lock any canvas of the contained controls as you manipulate them.

> And how do I do that ? A TCustomPanel doesn't have a canvas property, and no lock routines.

Sure it does in TCustomControl, but it is protected you need to make it
public in your decendant.  If you are actually creating an instance of
TCustomPanel then you should not do that.  Either create a TPanel or
create a decendant of TCustomPanel, making the necessary properties
public/published

Jim

Other Threads