Recent

Author Topic: Problem with placement of TImages  (Read 1380 times)

Tomi

  • Full Member
  • ***
  • Posts: 119
Problem with placement of TImages
« on: March 27, 2022, 04:12:26 pm »
Hello!

I would like draw a green and a blue rectangles on the Form side by side and I would like increase and decrease these with the correct ratio when the user resize the window.
But my code is totally wrong and I don't understand, why? Rectangles are draw on incorrect coordinates and with black color and the program often throws an error when resizing the window.
But here is my initial piece of code:
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     Kep3d: TImage;
  16.     Alaprajz: TImage;
  17.     procedure FormCreate(Sender: TObject);
  18.     procedure FormResize(Sender: TObject);
  19.   private
  20.  
  21.   public
  22.  
  23.   end;
  24.  
  25. var
  26.   Form1: TForm1;
  27.  
  28. implementation
  29.  
  30. {$R *.lfm}
  31.  
  32. { TForm1 }
  33.  
  34. procedure TForm1.FormResize(Sender: TObject);
  35. begin
  36.   Kep3d.left:=Form1.left+8;
  37.   Kep3d.top:=Form1.top+8;
  38.   Kep3d.width:=Kep3d.width*round(Form1.width/Kep3d.width);
  39.   Kep3d.height:=Kep3d.height*round(Form1.height/Kep3d.height);
  40.   Kep3d.canvas.brush.color:=clGreen;
  41.   Kep3d.canvas.brush.style:=bsSolid;
  42.   Kep3d.canvas.rectangle(Kep3d.left,Kep3d.top,Kep3d.width,Kep3d.height);
  43.   Alaprajz.left:=Kep3d.left+Kep3d.width+8;
  44.   Alaprajz.top:=Form1.top+8;
  45.   Alaprajz.width:=Alaprajz.width*round(Form1.width/Alaprajz.width);
  46.   Alaprajz.height:=Alaprajz.height*round(Form1.height/Alaprajz.height);
  47.   Alaprajz.canvas.brush.color:=clBlue;
  48.   Alaprajz.canvas.brush.style:=bsSolid;
  49.   Alaprajz.canvas.rectangle(Alaprajz.left,Alaprajz.top,Alaprajz.width,Alaprajz.height);
  50. end;
  51.  
  52. procedure TForm1.FormCreate(Sender: TObject);
  53. begin
  54.   Kep3d.left:=Form1.left+8;
  55.   Kep3d.top:=Form1.top+8;
  56.   Kep3d.width:=Kep3d.width*round(Form1.width/Kep3d.width);
  57.   Kep3d.height:=Kep3d.height*round(Form1.height/Kep3d.height);
  58.   Kep3d.canvas.brush.color:=clGreen;
  59.   Kep3d.canvas.brush.style:=bsSolid;
  60.   Kep3d.canvas.rectangle(Kep3d.left,Kep3d.top,Kep3d.width,Kep3d.height);
  61.   Alaprajz.left:=Kep3d.left+Kep3d.width+8;
  62.   Alaprajz.top:=Form1.top+8;
  63.   Alaprajz.width:=Alaprajz.width*round(Form1.width/Alaprajz.width);
  64.   Alaprajz.height:=Alaprajz.height*round(Form1.height/Alaprajz.height);
  65.   Alaprajz.canvas.brush.color:=clBlue;
  66.   Alaprajz.canvas.brush.style:=bsSolid;
  67.   Alaprajz.canvas.rectangle(Alaprajz.left,Alaprajz.top,Alaprajz.width,Alaprajz.height);
  68. end;
  69.  
  70. end.
« Last Edit: April 01, 2022, 10:44:22 am by Tomi »

af0815

  • Hero Member
  • *****
  • Posts: 1291
Re: Problem with placement of TImages
« Reply #1 on: March 27, 2022, 05:36:50 pm »
Why not with Anchors ? And the redrawn of the Images in OnPaint of the Images ?

The second, create two Bitmaps one green, one blue and combine this with the images, so you must not redrawn anything.
« Last Edit: March 27, 2022, 05:42:55 pm by af0815 »
regards
Andreas

Tomi

  • Full Member
  • ***
  • Posts: 119
Re: Problem with placement of TImages
« Reply #2 on: March 27, 2022, 05:59:40 pm »
Thanks, Andreas, I will try it.
I need two canvases in my program, because I would like draw two different things same time. These two Images represent those canvases, and I would like colorize them to make visible on main Form.

wp

  • Hero Member
  • *****
  • Posts: 11923
Re: Problem with placement of TImages
« Reply #3 on: March 27, 2022, 06:28:27 pm »
Just to paint two colored rectangles I would not use TImage, it's too overloaded with features that you do not need here. A simple TPaintbox is enough, or even the form's Canvas is sufficient.

Let me continue with two paintboxes. Align then to the left side of the form by setting their Align = alLeft - this way they automatically resize in height, when the form's height is changed.

Do not paint the rectangles in the OnCreate and OnResize event - this is outside the normal painting cycle and leads to many "surprises". Suppose the user drags another window over this form. Then the OS needs to repaint the form but does not know how to draw the rectangles. Always put user code for painting in the OnPaint event:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.PaintBox1Paint(Sender: TObject);
  2. var
  3.   pb: TPaintbox;
  4. begin
  5.   pb := Sender as TPaintbox;
  6.   pb.Canvas.Brush.Color := pb.Color;
  7.   pb.Canvas.FillRect(0, 0, pb.Width, pb.Height);
  8. end;

Tomi

  • Full Member
  • ***
  • Posts: 119
Re: Problem with placement of TImages
« Reply #4 on: March 28, 2022, 10:02:31 am »
Hello Wp and thank you for your answer!
I have changed my code, but something is still wrong, because the Form doesn't show the two colorized rectangles.
Here is the code:
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     Kep3d: TPaintBox;
  16.     Alaprajz: TPaintBox;
  17.     procedure FormCreate(Sender: TObject);
  18.     procedure FormResize(Sender: TObject);
  19.   private
  20.  
  21.   public
  22.  
  23.   end;
  24.  
  25. var
  26.   Form1: TForm1;
  27.  
  28. implementation
  29.  
  30. {$R *.lfm}
  31.  
  32. { TForm1 }
  33.  
  34. procedure TForm1.FormResize(Sender: TObject);
  35. begin
  36.   Kep3d.left:=Form1.left+8;
  37.   Kep3d.top:=Form1.top+8;
  38.   Kep3d.width:=Kep3d.width*round(Form1.width/Kep3d.width);
  39.   Kep3d.height:=Kep3d.height*round(Form1.height/Kep3d.height);
  40.   //
  41.   Alaprajz.left:=Kep3d.left+Kep3d.width+8;
  42.   Alaprajz.top:=Form1.top+8;
  43.   Alaprajz.width:=Alaprajz.width*round(Form1.width/Alaprajz.width);
  44.   Alaprajz.height:=Alaprajz.height*round(Form1.height/Alaprajz.height);
  45. end;
  46.  
  47. procedure TForm1.FormCreate(Sender: TObject);
  48. begin
  49.   Kep3d.canvas.brush.color:=clGreen;
  50.   Kep3d.canvas.fillrect(Kep3d.left,Kep3d.top,Kep3d.width,Kep3d.height);
  51.   Alaprajz.color:=clBlue;
  52.   //with Alaprajz do invalidate;
  53. end;
  54.  
  55. end.
I'm totally confused with using of windows: I set one of these PaintBoxes to Form1+8 screen coordinates, but it shows  that at 518.
« Last Edit: March 28, 2022, 10:42:49 am by Tomi »

wp

  • Hero Member
  • *****
  • Posts: 11923
Re: Problem with placement of TImages
« Reply #5 on: March 28, 2022, 10:47:31 am »
You do not assign a handler for the OnPaint event to the paintboxes. Without it they don't know how to paint themselves.

You do not use the Align property to glue the paintboxes to the left of the form. you don't need OnResize if you do this.

Don't use the form instance variable (Form1) inside the code of the class (TForm1) - your program will stop working if you'd rename the instance or create another instance with a different name.

I don't understand the calculation of the paintbox widths in your code. What do you want to achieve by it?

Here is the code of my example, now everything is set at runtime:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. begin
  3.   Kep3d.Align := alLeft;
  4.   Kep3d.BorderSpacing.left := 8;
  5.   Kep3d.BorderSpacing.Top := 8;
  6.   Kep3d.BorderSpacing.Right := 4;
  7.   Kep3d.BorderSpacing.Bottom := 8;
  8.   Kep3d.Color := clGreen;
  9.   Kep3d.OnPaint := @Paintbox_Paint;
  10.  
  11.   Alaprajz.Align := alLeft;
  12.   Alaprajz.BorderSpacing.Left := 4;
  13.   Alaprajz.BorderSpacing.Top := 8;
  14.   Alaprajz.BorderSpacing.Right := 8;
  15.   Alaprajz.BorderSpacing.Bottom := 8;
  16.   Alaprajz.Color := clBlue;
  17.   Alaprajz.OnPaint := @Paintbox_Paint;
  18. end;
  19.  
  20. procedure TForm1.Paintbox_Paint(Sender: TObject);
  21. var
  22.   paintbox: TPaintbox;
  23. begin
  24.   paintbox := Sender as TPaintbox;
  25.   paintbox.Canvas.Brush.Color := paintbox.Color;
  26.   paintbox.Canvas.FillRect(0, 0, paintbox.Width, paintbox.Height);
  27. end;

Tomi

  • Full Member
  • ***
  • Posts: 119
Re: Problem with placement of TImages
« Reply #6 on: March 28, 2022, 07:38:38 pm »
"I don't understand the calculation of the paintbox widths in your code. What do you want to achieve by it?"

I would like increase or decrease correctly the size of paintboxes when the user resize the program window. So, when the window became bigger, paintboxes also became bigger keep the ratio, and similar when the window became smaller, paintboxes also became smaller.
Unfortunately my calculation sometimes throws a runtime error.
I need two paintboxes: the user can drawing on the first paintbox, and the program shows this draw on the second paintbox, with some modifications.
Maybe two simple rectangles would be enough for this, but I think, it is much better to use an Image or Paintbox. The most important for me to make visible these areas with some background color.

wp

  • Hero Member
  • *****
  • Posts: 11923
Re: Problem with placement of TImages
« Reply #7 on: March 28, 2022, 10:07:24 pm »
Which fraction of the form will be covered by the paintboxes (images)? If you want to fully cover the form by both paintboxes having equal sizes you could activate the ChildSizing property of the form:
  • Drop the paintboxes on the form and add their OnPaint handler as described in the previous messages. So not set any other properties.
  • Select the form and go to its ChildSizing property
  • Set ControlsPerLine = 2
  • Set EnlargeHorizontal and EnlargeVertical to crsHomogeneousChildResize
  • Set Layout to cclLeftToRightThenTopToBottom
  • Set LeftRightSpacing and TopBottomSpacin to 8 (or whatever you want as margin around the boxes)
  • Set HorizontalSpacing to 8 (or whatever distance you want to have between them)
Now each paintboxes always fills a half of the form.

If you need to have other controls on the form besides the paintboxes put the paintboxes into a client-aligned panel and apply the ChildSizing properties to the panel.

Tomi

  • Full Member
  • ***
  • Posts: 119
Re: Problem with placement of TImages
« Reply #8 on: March 30, 2022, 10:36:24 am »
Interesting: the FormResize is executed when the program started. I didn't know it and it caused malfunction to my program, because the first PaintBox was bigger and overlie the other PaintBox.
Now, the sight of the program became much better, but I have to work out the correct scaling method of PaintBoxes when the user resize the window. But for this, I will try built in your concept, Wp.

Tomi

  • Full Member
  • ***
  • Posts: 119
Re: Problem with placement of TImages
« Reply #9 on: April 01, 2022, 10:42:58 am »
PROBLEM SOLVED!  :D
I did it with some percentage calculations:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormResize(Sender: TObject);
  2. var ablakxszazalek,ablakyszazalek: real;
  3. begin
  4.   Kep3d.left:=8;
  5.   Kep3d.top:=8;
  6.   //Kep3d.width:=regikep3dszel*round(Form1.width/regiform1szel); //These 2 lines are wrong!
  7.   //Kep3d.height:=regikep3dmag*round(Form1.height/regiform1mag);
  8.   ablakxszazalek:=(100*Form1.width)/regiform1szel; //Resizing PaintBoxes with correct ratio
  9.   ablakyszazalek:=(100*Form1.height)/regiform1mag; //windowypercent := (100*Form1.height)/oldform1height
  10.   Kep3d.width:=round((regikep3dszel*ablakxszazalek)/100);
  11.   Kep3d.height:=round((regikep3dmag*ablakyszazalek)/100);
  12.   //
  13.   Alaprajz.left:=Kep3d.left+Kep3d.width+8;
  14.   Alaprajz.top:=Kep3d.top;
  15.   Alaprajz.width:=Kep3d.width;
  16.   Alaprajz.height:=Kep3d.height;
  17.   //
  18.   regiform1szel:=Form1.width;
  19.   regiform1mag:=Form1.height;
  20.   regikep3dszel:=Kep3d.width;
  21.   regikep3dmag:=Kep3d.height;
  22. end;
  23.  
  24. procedure TForm1.FormCreate(Sender: TObject);
  25. begin
  26.   regiform1szel:=Form1.width; //old form1 width
  27.   regiform1mag:=Form1.height; //old form1 height
  28.   regikep3dszel:=Kep3d.width; //and similar with kep3d
  29.   regikep3dmag:=Kep3d.height;
  30. end;

 

TinyPortal © 2005-2018