Recent

Author Topic: Form inside form  (Read 1584 times)

bpp

  • New Member
  • *
  • Posts: 14
Form inside form
« on: May 25, 2020, 11:22:22 pm »
Hi,

I'm trying to implementing a interface like "form opened inside in another form"
To do that, I'm use only a main form, and all forms will be opened inside a panel.

It is the best way to implement something like this?

Should I work with frames instead forms? (https://wiki.lazarus.freepascal.org/Frames)

lucamar

  • Hero Member
  • *****
  • Posts: 2917
Re: Form inside form
« Reply #1 on: May 25, 2020, 11:32:06 pm »
Forms are not really "ready" yet for this, though it can be done. In your place I would use frames; in fact I use them rather extensively for my own needs, even if just for a single program.

I tried/tested with forms but they were not quite as handy as frames. :)
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.8/FPC 3.0.4 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

jamie

  • Hero Member
  • *****
  • Posts: 3064
Re: Form inside form
« Reply #2 on: May 26, 2020, 01:58:27 am »
The problem with forms are they don't read in the resource values when you create them at runtime because you never made any resource for them...

 This means you need to do all the grunt work...

 Its best to use CreateNew(Owner) instead of create..

 I have done it... many times for a MDI like application.

 There are some hickups however..

The only true wisdom is knowing you know nothing

af0815

  • Hero Member
  • *****
  • Posts: 549
Re: Form inside form
« Reply #3 on: May 26, 2020, 07:09:15 am »
I'm trying to implementing a interface like "form opened inside in another form"
is normally called MDI. And this is normally a blind side of Lazarus, because it is normally not implemented by differnt widgetsets nativly. Only windows have IMHO in the past a native Interface for this.

Look for "MDI Lazarus" at google or forumsearch

https://forum.lazarus.freepascal.org/index.php?topic=34137.0
https://wiki.freepascal.org/MultiDoc

and similar
regards
Andreas

bpp

  • New Member
  • *
  • Posts: 14
Re: Form inside form
« Reply #4 on: May 26, 2020, 01:01:17 pm »
Quote
The problem with forms are they don't read in the resource values when you create them at runtime because you never made any resource for them...

Can you show me a example? i will understand better

I think I don’t need a something too complex as MDI. I just need a menu to open forms in a single MainForm, once at time.

Thanks

lucamar

  • Hero Member
  • *****
  • Posts: 2917
Re: Form inside form
« Reply #5 on: May 26, 2020, 02:53:31 pm »
I think I don%u2019t need a something too complex as MDI. I just need a menu to open forms in a single MainForm, once at time.

I think that what you want can be more easily done by using frames. You design them mostly as if they were forms, can create and use them embedded like you describe, and won't give you any of the problems you might find when trying to embed standard forms. It's a win-win situation ;)


The problem with forms are they don't read in the resource values when you create them at runtime because you never made any resource for them...

That depends quite a lot on how you make the children forms at design-time, doesn't it? If you design them normally, though taking them out from the auto-create list, the form resource(s) will be added to the binary, so you can then create the instances at run-time, when needed, by calling
Code: [Select]
Application.CreateForm() or
Code: [Select]
SomeForm := TSomeForm.Create(Application) or whatever other "normal" method you want. I do that quite a lot for custom dialogs, to the point of adding to the "dialog" form's unit functions like:

Code: Pascal  [Select][+][-]
  1. function ShowMyDialog(AParam: SomeType): Boolean;
  2. begin
  3.   if not Assigned(MyDialog) then
  4.     Application.CreateForm(TMyDialog, MyDialog);
  5.   {... Do something with AParam ...}
  6.   Result := MyDialog.Execute;
  7. end;
  8.  
  9. function TMyDialog.Execute: Boolean;
  10. begin
  11.   { For example ...}
  12.   Result := ShowModal = mrClose;
  13. end;
« Last Edit: May 26, 2020, 03:00:42 pm by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.8/FPC 3.0.4 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

winni

  • Hero Member
  • *****
  • Posts: 1427
Re: Form inside form
« Reply #6 on: May 26, 2020, 02:56:56 pm »
Hi!

Using two Forms is a little bit special, if you want to embed the second.

Just develop your second Form as if it is a app on its own.

The you need that recursive uses:

Unit1 uses Unit2 in the Interface
Unit2 uses Unit1 in the Implementation


Then you have to connect Form2 to the Panel in Form1:

Code: Pascal  [Select][+][-]
  1. procedure TForm2.FormCreate(Sender: TObject);
  2. begin
  3. Form2.Parent := Form1.Panel1;
  4. Form2.left := ...
  5. Fom2.top := ...
  6. end;

Works without problems

Background: I had a little application (Form2) that I wanted to embed in Form1.
Instead of doing all  the stuff again I embedded Form2 in the sidebar of Form1.

Just renaming  the second Form plus the above code and it was done.

Winni

eljo

  • Sr. Member
  • ****
  • Posts: 407
Re: Form inside form
« Reply #7 on: May 26, 2020, 04:51:30 pm »
MDI is broken in lcl for all widgetsets except QT. There are some "mdi" components but they are not anything more than what you have already. So forget MDI.

I use frames extensively and I would suggest frames if they did not have a minor refresh problem.
In any case if you are going to dynamically create them then both frames and forms are good candidates.

madref

  • Hero Member
  • *****
  • Posts: 786
  • ..... A day not Laughed is a day wasted !!
    • Nursing With Humour
Re: Form inside form
« Reply #8 on: May 26, 2020, 05:24:15 pm »
it's doable. but requires some programming


Method 1:

1) Make sure all forms are created at runtime.
2) Open your first form
3) let the first form open your second form
4) and this is important SET your form-style to StayOnTop
Code: Pascal  [Select][+][-]
  1. Form2.FormStyle := fsStayOnTop;

Method 2:
1) Make sure only form 1 is created at runtime
2) Open form 2 by pressing a button on form 2
Code: Pascal  [Select][+][-]
  1. procedure form1.button1click (sender:object);
  2. var f2: TFrom2;
  3. begin
  4.           f2 := TForm_Options.Create(Application);
  5.           f2.ShowYourForm;
  6. end;


In form2 you have a procedure called ShowYormForm
Code: Pascal  [Select][+][-]
  1. procedure Form2.ShowYourForm;
  2. begin
  3.   .....
  4.   .....
  5.   ShowModal;
  6. end;


Hope this helps
You treat a disease, you win, you lose.
You treat a person and I guarantee you, you win, no matter the outcome.

Lazarus 2.0.6 / FPC 3.0.4
Lazarus Trunc / FPC Trunc
Mac OS X Mojave

lucamar

  • Hero Member
  • *****
  • Posts: 2917
Re: Form inside form
« Reply #9 on: May 26, 2020, 05:31:40 pm »
it's doable. but requires some programming

[... etc ...]

That's is not quite what the OP wants, though: he wants to have a main form and open the rest of them embedded into it. Which can be done by setting the Parent of the embeded forms but (in my experience) leads to some difficult to resolve issues due, mostly, to forms not being really built to have a "parent".

Nothing, of course, that can't be solved with some "tricks" but, why use "tricks" when there's already a ready made solution (i.e. frames)?

And more so when he says he considers MDI to be "overkill" :)
« Last Edit: May 26, 2020, 05:33:51 pm by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.8/FPC 3.0.4 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

madref

  • Hero Member
  • *****
  • Posts: 786
  • ..... A day not Laughed is a day wasted !!
    • Nursing With Humour
Re: Form inside form
« Reply #10 on: May 26, 2020, 05:32:13 pm »
Also read this thread and take a look at all 3 Archives that are in this thread


https://forum.lazarus.freepascal.org/index.php/topic,48654.msg356846.html#msg356846
You treat a disease, you win, you lose.
You treat a person and I guarantee you, you win, no matter the outcome.

Lazarus 2.0.6 / FPC 3.0.4
Lazarus Trunc / FPC Trunc
Mac OS X Mojave

zoltanleo

  • Full Member
  • ***
  • Posts: 245
Re: Form inside form
« Reply #11 on: May 26, 2020, 11:58:34 pm »
Hi bpp.

Try to use  compoment TRxMDIPanel from "Rx Controls" tab of rxlib library by Alexey Logunov. Or You can try to read this topic https://forum.lazarus.freepascal.org/index.php/topic,42334.msg295340.html#msg295340
« Last Edit: May 27, 2020, 12:00:23 am by zoltanleo »
Win7 Ultim x64/Deb 10 amd64 GTK3:
Lazarus x32/x64 2.1(r.63122); FPC 3.3.1 (r.44724), FB 3.0.5

Sorry for my bad English, I'm using translator ;)

dbannon

  • Hero Member
  • *****
  • Posts: 1069
    • tomboy-ng, a rewrite of the classic Tomboy
Re: Form inside form
« Reply #12 on: May 27, 2020, 08:29:42 am »
Forms are not really "ready" yet for this, though it can be done. In your place I would use frames; in fact I use them rather extensively for my own needs, even if just for a single program.

I tried/tested with forms but they were not quite as handy as frames. :)

I watched this post thinking that Frames might be a great way to break up an overly large unit that has parts only related by the fact they they appear on the same form.

So I tried dropping a TFrame from the palette onto an existing form (actually onto a TTabSheet) but when I click the the form, I receive a dialog asking me to "Select a Frame" from a list of framePrinterSetup, framePageSetup (and kmemofrm).  So, reading the wiki page, https://wiki.lazarus.freepascal.org/Frames, I wondered if I needed to first create a frame using File->New-Frame, save and then do the palette drop thing.  However, I was again forced to choose between unsuitable choices of existing frames.

Can you please elaborate on how to get a "general purpose" frame onto an existing form ?

Davo 
Lazarus 2, Linux (and reluctantly Win10, OSX)
My Project - https://github.com/tomboy-notes/tomboy-ng

howardpc

  • Hero Member
  • *****
  • Posts: 3443
Re: Form inside form
« Reply #13 on: May 27, 2020, 10:46:24 am »
Can you please elaborate on how to get a "general purpose" frame onto an existing form
Frames are different from standard components in several ways, but a major difference is that they are always associated with a .lfm resource, without which they have no use or meaning. So creating them via code is not as straightforward as you might think.
The best approach is to create a new "general purpose" frame for your use before you use it: in other words there is really no such thing as a general purpose frame - no frame is really general purpose, except a new empty frame, which is where all frame creation has to start.
I've sometimes thought about making a little IDE wizard to quickly produce a nicely customised frame with a few clicks... but never made the effort, since it is not too difficult to do it the 'long' way and customise a new frame in the designer to fit what I need it for.

lucamar

  • Hero Member
  • *****
  • Posts: 2917
Re: Form inside form
« Reply #14 on: May 27, 2020, 12:26:48 pm »
Can you please elaborate on how to get a "general purpose" frame onto an existing form ?

You mean a "generic" frame you built, say, a year ago for another project and that you want to use in a new one? There are several ways to do that, but they all end up in adding the frame unit (and lfm) to your project, just as with a normal form.

I usually end up copying the frame sources to the new project's folder (in case it needs customization and to keep all dependencies in one place), but in any case you then go to the Project Inspector, select "Add files from the flesystem" and add the frame source (myframe.pas). After that the frame should be available to add to forms.


Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.8/FPC 3.0.4 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

 

TinyPortal © 2005-2018