Recent

Author Topic: function CheckDC error on closing a Form  (Read 1907 times)

Jeff_t

  • New Member
  • *
  • Posts: 17
function CheckDC error on closing a Form
« on: September 25, 2025, 02:33:38 pm »
I have a simple form with a button and a TPaintBox
In the PaintBox's Paint event, I draw on the canvas, having used from TColors on the way

If I close the Form using the close gadget, I get an exception in function CheckDC - almost as if it's still trying to draw after the TPaintBox has been destroyed.
Have I missed something important?

Thaddy

  • Hero Member
  • *****
  • Posts: 18356
  • Here stood a man who saw the Elbe and jumped it.
Re: function CheckDC error on closing a Form
« Reply #1 on: September 25, 2025, 03:05:40 pm »
Did you not use beginpaint/endpaint?
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

Jeff_t

  • New Member
  • *
  • Posts: 17
Re: function CheckDC error on closing a Form
« Reply #2 on: September 25, 2025, 03:12:10 pm »
Quote
Did you not use beginpaint/endpaint?

I did not.
Haven't seen that mentioned in any online examples , such as this one from Lazarus Wiki

 
Code: Pascal  [Select][+][-]
  1. procedure TMyDrawingControl.Paint;
  2. var
  3.   x, y: Integer;
  4.   Bitmap: TBitmap;
  5. begin
  6.   Bitmap := TBitmap.Create;
  7.   try
  8.     // Initializes the Bitmap Size
  9.     Bitmap.Height := Height;
  10.     Bitmap.Width := Width;
  11.  
  12.     // Draws the background
  13.     Bitmap.Canvas.Pen.Color := clWhite;
  14.     Bitmap.Canvas.Rectangle(0, 0, Width, Height);
  15.  
  16.     // Draws squares
  17.     Bitmap.Canvas.Pen.Color := clBlack;
  18.     for x := 1 to 8 do
  19.       for y := 1 to 8 do
  20.         Bitmap.Canvas.Rectangle(Round((x - 1) * Width / 8), Round((y - 1) * Height / 8),
  21.           Round(x * Width / 8), Round(y * Height / 8));
  22.        
  23.     Canvas.Draw(0, 0, Bitmap);
  24.   finally
  25.     Bitmap.Free;
  26.   end;
  27.  
  28.   inherited Paint;
  29. end;

I'm on a Mac.

A search for BeginPaint gave me this:

Quote
In the Lazarus IDE and Free Pascal's LCL (Lazarus Component Library), BeginPaint is a low-level Windows API function, accessed via the LCLIntf unit, used in conjunction with EndPaint to manage the process of drawing or updating a control's visual appearance. It prepares a window for painting, fills a PAINTSTRUCT structure with painting information, and is often called from the OnPaint event handler or overridden Paint method to ensure that custom drawing persists correctly.

So is it needed on all OS's?

Thaddy

  • Hero Member
  • *****
  • Posts: 18356
  • Here stood a man who saw the Elbe and jumped it.
Re: function CheckDC error on closing a Form
« Reply #3 on: September 25, 2025, 03:23:41 pm »
try
Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormPaint(Sender: TObject);
  2. var
  3.   P: Array[0..4] of TPoint;
  4.   i: Integer;
  5.   phi: Double;
  6.  
  7. begin
  8.   form1.canvas.LockCanvas;
  9.   for i := 0 to 4 do
  10.   begin
  11.     phi := 2.0 * pi / 5 * i + pi * 0.5;;
  12.     P[i].X := round(100 * cos(phi) + 110);
  13.     P[i].Y := round(100 * sin(phi) + 110);
  14.   end;
  15.   Canvas.Brush.Color := clRed;
  16.   Canvas.Polygon(P);
  17.   form1.canvas.UnlockCanvas;
  18. end;
Or
Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormPaint(Sender: TObject);
  2. var
  3.   P: Array[0..4] of TPoint;
  4.   i: Integer;
  5.   phi: Double;
  6.  
  7. begin
  8.   form1.BeginFormUpdate;
  9.   for i := 0 to 4 do
  10.   begin
  11.     phi := 2.0 * pi / 5 * i + pi * 0.5;;
  12.     P[i].X := round(100 * cos(phi) + 110);
  13.     P[i].Y := round(100 * sin(phi) + 110);
  14.   end;
  15.   Canvas.Brush.Color := clRed;
  16.   Canvas.Polygon(P);
  17.   form1.EndFormUpdate;
  18. end;
Both are blocking calls, I guess the second would also work on mac.
« Last Edit: September 25, 2025, 03:28:33 pm by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

Jeff_t

  • New Member
  • *
  • Posts: 17
Re: function CheckDC error on closing a Form
« Reply #4 on: September 25, 2025, 03:38:53 pm »
Well, Lock and Unlock didn't affect things.
BeginPaint and EndPaint  report not available on my canvas

Invalid Access exception.

The problem line appears to be this:

if TObject(dc) is TCocoaContext

dc does have a longint value at this point, and that line is quite happy when the form opens.


If I remove all code from the Paint, it works.
The presence of these lines (which do produce the required rectangle) brings the error back

Code: Pascal  [Select][+][-]
  1.                 // Set the fill color
  2.                 Canvas.Brush.Color :=palette[cul1].palRGB;  //palRGB is a prefilled TColor
  3.                   // Draw the rectangle
  4.                 Canvas.Rectangle(R);   //R is a prefilled TRect


« Last Edit: September 25, 2025, 03:47:51 pm by Jeff_t »

Jeff_t

  • New Member
  • *
  • Posts: 17
Re: function CheckDC error on closing a Form
« Reply #5 on: September 25, 2025, 10:14:20 pm »
The exact same code works perfectly if pasted into the Form's Onpaint event.
Confused.

korba812

  • Sr. Member
  • ****
  • Posts: 482
Re: function CheckDC error on closing a Form
« Reply #6 on: September 25, 2025, 11:07:15 pm »
It seems that you are drawing on form canvas. Try drawing on the PaintBox canvas.

Jeff_t

  • New Member
  • *
  • Posts: 17
Re: function CheckDC error on closing a Form
« Reply #7 on: September 26, 2025, 08:12:05 am »
Quote
It seems that you are drawing on form canvas.

If I was drawing on the form's canvas, the drawing would be relative to the top left corner of the form, yes?
It is not - when I draw in the PaintBox methods, drawing begins top left corner of the Paintbox.
But if I prefix the  calls to   Canvas.<something>   with the name of the Paintbox, all seems well.
eg if the Paintbox is named Brian, then using Brian.Canvas.Rectangle() is OK

This is hugely unintuitive,  as I would have expected any reference to an unqualified 'Canvas'
within a method of the TPaintBox , to refer to the TPaintbox, not the form.

cdbc

  • Hero Member
  • *****
  • Posts: 2467
    • http://www.cdbc.dk
Re: function CheckDC error on closing a Form
« Reply #8 on: September 26, 2025, 08:35:38 am »
Hi
In the code-editor, if you hover the mouse over the method-name, 'Code-Tools'*) will show you to whom the method belongs...

*) If you [Ctrl] + Click on the method-name, code-tools will take you to its
    declaration.
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE6 -> FPC 3.2.2 -> Lazarus 4.0 up until Jan 2025 from then on it's both above &: KDE6/QT6 -> FPC 3.3.1 -> Lazarus 4.99

wp

  • Hero Member
  • *****
  • Posts: 13216
Re: function CheckDC error on closing a Form
« Reply #9 on: September 26, 2025, 11:50:30 am »
I have a simple form with a button and a TPaintBox
Code: Pascal  [Select][+][-]
  1. procedure TMyDrawingControl.Paint;
  2. [...]
  3.  
Your introductory statement about issues in drawing on a Paintbox and the code shown later are contradictory because that code is for a custom control, TMyDrawingControl. Are you sure that your issues are not rooted somewhere in that custom control? I've never seen issues that you are reporting for a plain TPaintbox. Just tested again on a mac-VM, and the Paintbox is working fine.

 

TinyPortal © 2005-2018