Recent

Author Topic: Automatic presentation of nested form  (Read 4193 times)

nicanor

  • New Member
  • *
  • Posts: 17
Automatic presentation of nested form
« on: March 09, 2021, 04:28:00 pm »
Hi,
I want to make a Form2 automatically shown, with ShowModal, (without depending on user action, click, keypress etc.), so that Form2.owner = Form1, Form2.parent = Form1 and Form2.BorderStyle = bsNone. I would like Form2 to be shown inside Form1, at such a point that Form1 was idle, waiting for user action, not on Form1's onShow. Is there any way to do this?

FTurtle

  • Sr. Member
  • ****
  • Posts: 292
Re: Automatic presentation of nested form
« Reply #1 on: March 09, 2021, 04:32:57 pm »
Why not to use TFrame?

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: Automatic presentation of nested form
« Reply #2 on: March 09, 2021, 06:36:16 pm »
Hi,
I want to make a Form2 automatically shown, with ShowModal, (without depending on user action, click, keypress etc.), so that Form2.owner = Form1, Form2.parent = Form1 and Form2.BorderStyle = bsNone. I would like Form2 to be shown inside Form1, at such a point that Form1 was idle, waiting for user action, not on Form1's onShow. Is there any way to do this?

Hmmm

Form1 is 99.99 % of the time idle, so you see only Form2.
And you cannot reach Form1, because you want Form2 to be shown with showmodal.

That design look like nonsense, but perhaps you tell a little bit more to understand your aim.

Winni

nicanor

  • New Member
  • *
  • Posts: 17
Re: Automatic presentation of nested form
« Reply #3 on: March 09, 2021, 07:51:54 pm »
Thank you very much for the answers!
UsingTFrame was one of the options at the beginning of the project ... Maybe I didn't make a good decision... anyway... I want to implement a desktop project whose behavior is similar to a "web application".
I plan to use a main Form as a kind of base where I intend to present all the other forms with the other features of the system.
The first feature I want to introduce is a login interface. For this I implemented a simple structure that has the form frmLogin as a view.
My proposal is to present this login form inside the main form (I do not want the Login form to be presented before the Main Form) ... then, allow the user to proceed with the login and then immediately, if the login was successful, present another form, which I called "Home", and which contains a dashboard with synthetic data from the system on cards (panels) which, in turn, will function as a main menu for the other functionalities and their respective views.
The main form would function as a kind of simple browser that will allow the user to go back and forth between the forms he is opening. The general appearence would be similar to that of the gnome Nautilus.
I am stuck in this initial process, which is to define an appropriate place to present the Login Form and then present the Home Form, these two presentations would be automatic, independent of the user's action.
I already tried to use DoShow / OnShow from the main form to present the Login form and then I extended the Notification procedure (from the main form) to detect that frmLogin has been removed and thus start frmHome. But, the problem with this implementation is that I have to use frmLogin.Show in frmMain.OnShow ... but, with my level of knowledge, this complicates the control over the creation and destruction of objects associated with Login and Home .
Apologies for the text size

MarkMLl

  • Hero Member
  • *****
  • Posts: 6682
Re: Automatic presentation of nested form
« Reply #4 on: March 09, 2021, 08:46:17 pm »
Why not use a tabbed notebook with the tabs hidden, each page containing an appropriate TFrame, and something on each frame to switch to a different page? Fairly standard "wizard" design.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

nicanor

  • New Member
  • *
  • Posts: 17
Re: Automatic presentation of nested form
« Reply #5 on: March 10, 2021, 02:34:00 pm »
Yes...
I have another projects working with this idea.
I just to want to explore other possibilities of implementations...
...So... May I understand that there's not a way to control presentation of forms in this way wanted for me?

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Automatic presentation of nested form
« Reply #6 on: March 10, 2021, 02:57:31 pm »
I would like Form2 to be shown inside Form1, at such a point that Form1 was idle, waiting for user action, not on Form1's onShow. Is there any way to do this?
Assuming Form1 is your Lazarus main form, and you leave Application.ShowMainForm at its default of True, you have several options for showing other forms such as Form2.
Yet you do not want Form2 shown in response to user action. So what do you want to trigger its display?
If not the showing of Form1, there are not many other options. You could have a timer, for instance, which showed Form2 after a specific interval from the showing of Form1.

Or you could poll the value of Time, and show Form2, say, if the day had reached 4 o'clock...

BasicOne

  • New Member
  • *
  • Posts: 15
Re: Automatic presentation of nested form
« Reply #7 on: March 10, 2021, 04:17:37 pm »
On Windows, you could use SetParent() of the windows unit. Maybe, you have to set visibility (false for all not used forms), border style, position and all the other properties of all your forms.

The first parameter is the handle of the child form, the second parameter is the handle of the parent. The form can be pinned to the desktop using the handle 0.

Within your code, the handle property may easily be used, but the function may also be used to place any form of an external application on a control, e.g. a panel or tab sheet of the lazarus application. To do this, I made the following procedure some time ago. Of course, the challange is then to get the form handle of the external application, e.g. via the api calls GetWindowText() ang GetWindow(), but this is another story...

By the way, if working within one Lazarus application, why not just set the tForm.Parent property and then control visibility via tForm.visible or tForm.Show and tFom.Hide?

Code: Pascal  [Select][+][-]
  1. procedure AttachWindow2Control(aWnd: Hwnd; aControl: TWinControl; setPlacement: boolean);
  2. var
  3.  WPM: WINDOWPLACEMENT;
  4. begin
  5.  Windows.SetParent(aWnd, aControl.Handle);
  6.  if setPlacement then
  7.  begin
  8.   SetWindowLong(aWnd, GWL_STYLE, GetWindowLong(aWnd, GWL_STYLE) and not WS_CAPTION);
  9.   WPM.Length := SizeOf(WPM);
  10.   GetWindowPlacement(aWnd, @WPM);
  11.   WPM.ShowCmd := SW_ShowMaximized;
  12.   WPM.rcNormalPosition := Classes.Rect(0, 0, aControl.Width, aControl.Height);
  13.   SetWindowPlacement(aWnd, @WPM);
  14.  end;
  15. end;
  16.  

nicanor

  • New Member
  • *
  • Posts: 17
Re: Automatic presentation of nested form
« Reply #8 on: March 10, 2021, 08:20:06 pm »
I think I may have found a way to control the automatic presentation of forms (in this specific scenario).
Basically I decided to hang a procedure in the Application OnIdle event.
Analyzing the Application.Run, I found that this procedure has a relatively simple code and that, at a certain point, it always passes through the execution of the Application.Idle procedure, after the Main Form is already completely displayed on the screen.
I realized that by creating some control attributes in my "systemmanager" class I can control whether it is necessary to present the login form at any time during the application's execution. In this way, a flag in the "systemmanager" class will signal the need for a new Login whenever necessary (either at the beginning of the execution, during the exchange of users or if a lot of downtime has passed) ... So, as Application.Idle runs all the time, then it will be in charge of presenting the login form.
The same principle I can use to present the Home form right afterwards.
Maybe it doesn't exactly look like an elegant implementation but it will work for now.
« Last Edit: March 11, 2021, 08:41:15 pm by nicanor »

nicanor

  • New Member
  • *
  • Posts: 17
Re: Automatic presentation of nested form
« Reply #9 on: March 11, 2021, 09:06:30 pm »
Everything was going well ... I created the presentation control flags and both forms (Login and Home) are being presented perfectly in sequence ... from within the procedure that I associated with Application.OnIdle.
Except that an undesirable side effect appeared: As I used Showmodal to present the login form, the navigation through the editing controls of this form, using the TAB key, does not work!
I debugged the code and found that, internally, in the treatment of TAB keystrokes, SetFocus functions are performed and change the ActiveControl of the Form that hosts the visual controls ... In this case, I realized that the ActiveControl that is being changed does not is that of the Login Form, which contains those controls, but that of the Main Form (which has been defined as Parent and Owner of the Login Form).
So I did a test using Show to present the Login Form and the TAB returned to work normally.
I do not have enough discernment to understand the reason for this adverse behavior with ShowModal.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6682
Re: Automatic presentation of nested form
« Reply #10 on: March 11, 2021, 10:26:18 pm »
Is it only the <Tab> that doesn't work? Do the <Enter> and <Escape> actions etc. work?

I converted some Delphi code I'd written years earlier which kicked off various things using an async event triggered once the message loop was running, and while the main form was OKish I had to jump through a lot of hoops to get dialog(ue)s etc. working. The slightly irritating thing was that an initial prototype using a much earlier version of Lazarus and the LCL had been more cooperative... I'm not saying it was a bug in either, because I think I'd pushed the boundaries of what was reasonable.

And it was /that/ experience which led me to suggest that you'd be better exploring frames etc. if possible, and not trying to be "clever".

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

 

TinyPortal © 2005-2018