* * *

Author Topic: Cloning contents from a tabsheet into another one (not the hard way!)  (Read 1308 times)

Raul_ES

  • New member
  • *
  • Posts: 13
Re: Cloning contents from a tabsheet into another one (not the hard way!)
« Reply #15 on: July 12, 2017, 05:51:07 pm »
I managed to created my very own frames thanks to  you guys  :D

check this example code:

Raúl
Student of Computer Science - UOC

taazz

  • Hero Member
  • *****
  • Posts: 3954
Re: Cloning contents from a tabsheet into another one (not the hard way!)
« Reply #16 on: July 12, 2017, 06:13:31 pm »
looks logical. You do know that the name is only useful for the streaming mechanism right? if you do not plan to stream the contents of your frame then leaving the name empty will work as well. There are a number of tricks you can do also, for example

Code: Pascal  [Select]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ComCtrls,
  9.   StdCtrls, Grids, Unit2;
  10.  
  11. type
  12.  
  13.   { TTabSheetFrame }
  14.  
  15.   TTabSheetFrame = class(TTabSheet)
  16.   private
  17.     FMyFrame: TFrame1;
  18.     procedure SetMyFrame(aValue: TFrame1);
  19.   public
  20.     constructor Create(TheOwner: TComponent); override;
  21.     property MyFrame : TFrame1 read FMyFrame;
  22.   end;
  23.  
  24.   { TForm1 }
  25.  
  26.   TForm1 = class(TForm)
  27.     Button1: TButton;
  28.     Button2: TButton;
  29.     Label2: TLabel;
  30.     PageControl1: TPageControl;
  31.     StringGrid1: TStringGrid;
  32.     procedure Button1Click(Sender: TObject);
  33.     procedure Button2Click(Sender: TObject);
  34.   private
  35.  
  36.   public
  37.  
  38.   end;
  39.  
  40. var
  41.   Form1: TForm1;
  42.  
  43. implementation
  44.  
  45. {$R *.lfm}
  46.  
  47. { TForm1 }
  48.  
  49. procedure TForm1.Button2Click(Sender: TObject);
  50. begin
  51.    Form1.Close;
  52. end;
  53.  
  54. procedure TForm1.Button1Click(Sender: TObject);
  55. var
  56.     k: integer;
  57.     lNewTabSheet: TTabSheet;
  58.     lNewFrame: TFrame1;
  59. begin
  60.     k := PageControl1.PageCount + 1;
  61.     if k <= 5 then
  62.       begin
  63.         lNewTabSheet := TTabSheetFrame.Create(PageControl1);
  64.         lNewTabSheet.PageControl := PageControl1;
  65.         with lNewTabSheet do
  66.           begin
  67.             Name := 'tab' + IntToStr(k);
  68.             Caption := 'Operation #' + IntToStr(k);
  69.           end;
  70. end;
  71.  
  72. { TTabSheetFrame }
  73.  
  74. constructor TTabSheetFrame.Create(TheOwner: TComponent);
  75. begin
  76.   inherited Create(TheOwner);
  77.   FMyFrame:=TFrame1.Create(TheOwner{or Self});
  78.   FMyFrame.Parent := Self;
  79.   FMYFrame.Align := alClient;
  80. end;
  81.  
  82.  
  83. end.
  84.  
  85.  
single creation for both ttabsheet and frame.

And of course the most unexpected.
Code: Pascal  [Select]
  1. { TTabSheetFrame }
  2.  
  3. constructor TTabSheetFrame.Create(TheOwner: TComponent);
  4. begin
  5.   FMyFrame:=TFrame1.Create(TheOwner);
  6.   inherited Create(FMyFrame);
  7.   FMyFrame.Parent := Self;
  8.   FMYFrame.Align := alClient;
  9. end;
  10.  
Now when you call
Code: Pascal  [Select]
  1.    TTabSheetFrame(PageControl1.Page[0]).MyFRame.Free;
  2.  
it will automatically destroy the TTabsheet too. Well This one needs testing I'm not comfortable using in production code but it shows how the owner mechanism works.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

Raul_ES

  • New member
  • *
  • Posts: 13
Re: Cloning contents from a tabsheet into another one (not the hard way!)
« Reply #17 on: July 12, 2017, 07:35:08 pm »
Ok. This is getting more complex...I think I'm going to blow a circuit in my brain. How to manage procedures and properties between the frame and the owner.

Code: Pascal  [Select]
  1. procedure TFrame1.BitBtn2Click(Sender: TObject);
  2. begin
  3.   // implement close active tabsheet method
  4.  
  5.   // Change the caption of the window (or a label or whatever) to say that
  6.   // tab number x has been deleted.
  7.    Form1.Caption := 'Deleting tab ' + InttoStr(PageControl1.ActivePageIndex);
  8.  
  9.    // delete the tabsheet
  10.    PageControl1.Page[PageControl1.ActivePageIndex].Destroy;
  11.  
  12. end;
  13.  

This code belongs to Unit2, the frame code. It gives the obvious error that Form1 and PageControl1 have not been declared (they belong to Unit1, the Form control). What I am doing wrong?
Raúl
Student of Computer Science - UOC

Raul_ES

  • New member
  • *
  • Posts: 13
Re: Cloning contents from a tabsheet into another one (not the hard way!)
« Reply #18 on: July 12, 2017, 07:37:49 pm »
Thanks taazz, I'm going to experiment with your code! Now I think I need a break...
Raúl
Student of Computer Science - UOC

taazz

  • Hero Member
  • *****
  • Posts: 3954
Re: Cloning contents from a tabsheet into another one (not the hard way!)
« Reply #19 on: July 12, 2017, 07:51:05 pm »
Thanks taazz, I'm going to experiment with your code! Now I think I need a break...
erm let it be for now its a bit ahead still sorry.
Ok. This is getting more complex...I think I'm going to blow a circuit in my brain. How to manage procedures and properties between the frame and the owner.

Code: Pascal  [Select]
  1. procedure TFrame1.BitBtn2Click(Sender: TObject);
  2. begin
  3.   // implement close active tabsheet method
  4.  
  5.   // Change the caption of the window (or a label or whatever) to say that
  6.   // tab number x has been deleted.
  7.    Form1.Caption := 'Deleting tab ' + InttoStr(PageControl1.ActivePageIndex);
  8.  
  9.    // delete the tabsheet
  10.    PageControl1.Page[PageControl1.ActivePageIndex].Destroy;
  11.  
  12. end;
  13.  

This code belongs to Unit2, the frame code. It gives the obvious error that Form1 and PageControl1 have not been declared (they belong to Unit1, the Form control). What I am doing wrong?
where did you wrote this code? the frame? how about going on the form selecting the button inside the frame you have there and adding a new event for the buttons click (double the button for short).
Then write the code there. Keep in mind that the button's event inside the form will not automatically link when creating the frame dynamically you need to do it manually something along the lines of
Code: Pascal  [Select]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ComCtrls,
  9.   StdCtrls, Grids, Unit2;
  10.  
  11. type
  12.  
  13.   { TForm1 }
  14.  
  15.   TForm1 = class(TForm)
  16.     Button1: TButton;
  17.     Button2: TButton;
  18.     Label2: TLabel;
  19.     PageControl1: TPageControl;
  20.     StringGrid1: TStringGrid;
  21.     procedure Button1Click(Sender: TObject);
  22.     procedure Button2Click(Sender: TObject);
  23.   private
  24.  
  25.   public
  26.     procedure FrameButton2Click(Sender:TObject);
  27.  
  28.   end;
  29.  
  30. var
  31.   Form1: TForm1;
  32.  
  33. implementation
  34.  
  35. {$R *.lfm}
  36.  
  37. { TForm1 }
  38.  
  39. procedure TForm1.FrameButton2Click(Sender:TObject);
  40. begin
  41.   Caption := 'Deleting tab ' + InttoStr(PageControl1.ActivePageIndex);
  42.   PageControl1.Page[PageControl1.ActivePageIndex].Destroy;
  43. end;
  44.  
  45. procedure TForm1.Button2Click(Sender: TObject);
  46. begin
  47.    Form1.Close;
  48. end;
  49.  
  50. procedure TForm1.Button1Click(Sender: TObject);
  51. var
  52.     k: integer;
  53.     lNewTabSheet: TTabSheet;
  54.     lNewFrame: TFrame1;
  55. begin
  56.     k := PageControl1.PageCount + 1;
  57.     if k <= 5 then
  58.       begin
  59.         lNewTabSheet := PageControl1.AddTabSheet;
  60.         with lNewTabSheet do
  61.           begin
  62.             Name := 'tab' + IntToStr(k);
  63.             Caption := 'Operation #' + IntToStr(k);
  64.           end;
  65.  
  66.         lNewFrame := TFrame1.Create(Form1);
  67.         with lNewFrame do
  68.           begin
  69.             Name := 'Frame' + IntToStr(k+1);  // <--- Here
  70.             Parent := lNewTabSheet;
  71.             Align := alClient;
  72.             BitBtn2.click := @framebutton2Click;
  73.           end;
  74.       end;
  75. end;
  76.  
  77. end.
  78.  
  79.  
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

Raul_ES

  • New member
  • *
  • Posts: 13
Re: Cloning contents from a tabsheet into another one (not the hard way!)
« Reply #20 on: July 12, 2017, 11:56:26 pm »
Thank you taazz.

Actually, is the Lazarus IDE itself that places the procedure TFrame1.BitBtn2Click(Sender: TObject) inside the frame source code file, not in the Form1, when double-clicking on the designer. So I thought that's the place should be. It would be possible to achieve the same using this approach instead?


And excuse my dummy question, In this piece of code:

Code: Pascal  [Select]
  1. BitBtn2.click := @framebutton2Click;

What does the @ mean? it has something to do with @override?


thanks!
Raúl
Student of Computer Science - UOC

taazz

  • Hero Member
  • *****
  • Posts: 3954
Re: Cloning contents from a tabsheet into another one (not the hard way!)
« Reply #21 on: July 13, 2017, 03:50:47 am »
Thank you taazz.

Actually, is the Lazarus IDE itself that places the procedure TFrame1.BitBtn2Click(Sender: TObject) inside the frame source code file, not in the Form1, when double-clicking on the designer. So I thought that's the place should be. It would be possible to achieve the same using this approach instead?
Yes. a frame should be seen as a single entity what ever you write in there should only be about the frame it self,  behavior rules etc that cavern the controls and their interaction with each other nothing more.
And excuse my dummy question, In this piece of code:
Code: Pascal  [Select]
  1. BitBtn2.click := @framebutton2Click;

What does the @ mean? it has something to do with @override?
it is a way to instruct the compiler that you do not want to execute the method and assign the results but you want to assign the method it self as a value to the event.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

jc99

  • Hero Member
  • *****
  • Posts: 509
    • My private Site
Re: Cloning contents from a tabsheet into another one (not the hard way!)
« Reply #22 on: July 15, 2017, 02:06:54 am »
And excuse my dummy question, In this piece of code:

Code: Pascal  [Select]
  1. BitBtn2.click := @framebutton2Click;

What does the @ mean? it has something to do with @override?

The @-operator generally gives you the address/reference of something instead of the object/variable.
The opposite operator is the ^-dereferencing operator that takes a (typed) address(pointer) and gives you the value.
example:
Code: Pascal  [Select]
  1.  
  2. var i:integer;
  3.      p:^integer; // p is declared as a pointer to integer;
  4.                        // normally pointer-variables are 'p'-prefixed
  5. begin
  6.    i := 5;    // This initializes the variable i
  7.    p := @i;   // This sets p to the address of i
  8.    i := 6;    // Now as a test you change i to 6
  9.    write(p^); // Surprise: This writes 6 and not 5
  10.    p^ := 7;   // Here you set the dereferenced address to 7
  11.    write(i);  // This will output the 7
  12. end;
  13.  
I hope this clarifies something ...
« Last Edit: July 15, 2017, 02:09:24 am by jc99 »
OS: Win XP x64, Win 7, Win 7 x64, Win 10, Win 10 x64, Suse Linux 13.2
Laz: 1.2 - 1.6.4, 1.8rc3
https://github.com/joecare99/public
'~|    /''
,_|oe \_,are

Raul_ES

  • New member
  • *
  • Posts: 13
Re: Cloning contents from a tabsheet into another one (not the hard way!)
« Reply #23 on: July 19, 2017, 06:05:41 pm »
Thanks Joe!
Raúl
Student of Computer Science - UOC

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus