Recent

Author Topic: How to close a window while setting its return value as mrOk?  (Read 690 times)

sensui

  • Newbie
  • Posts: 3
I have created a login window and a main window. The problem is that when I call the Close method in the successful login branch, the return value of ShowModal for the login form is always 2 (which I assume corresponds to mrCancel), even though I have explicitly set the ModalResult of the login form to mrOk.

From what I found online, the Close function automatically sets the ModalResult to 2. I'm not sure if this information is accurate. If it is, then what is the correct way to implement a login window?

I mean I need to close the login window and return a mrOk to the lpr, so the lpr will create the main window. 

Thanks.

The login method:

Code: Pascal  [Select][+][-]
  1. ...
  2.   if (edtUsername.Text = 'admin') and (edtPassword.Text = 'admin') then
  3.   begin
  4.     ShowMessage('OK');
  5.     self.ModalResult := mrOk; // Signal successful login
  6.     Close;              // Close the login form, but it seems like this will change the modalresult.
  7.   end
  8.   else
  9. ...

In the lpr file, I have something like this:

Code: Pascal  [Select][+][-]
  1.   loginResult := FLogin.ShowModal();
  2.   ShowMessage('Login Result ' + IntToStr(loginResult));
  3.   if (loginResult = mrOk) then
  4.   begin
  5.     Application.CreateForm(TFMain, FMain);
  6.     Application.Run;
  7.   end;  



jamie

  • Hero Member
  • *****
  • Posts: 6953
Re: How to close a window while setting its return value as mrOk?
« Reply #1 on: May 21, 2025, 11:01:14 pm »
I believe you simply set the modelResults and you don't call the CLOSE afterwards.

Setting the results should do the rest for you.

if you call close instead, then the assigned in properties results are called.

I could be wrong but that is what's on the top of my head.
The only true wisdom is knowing you know nothing

n7800

  • Sr. Member
  • ****
  • Posts: 358
Re: How to close a window while setting its return value as mrOk?
« Reply #2 on: May 22, 2025, 01:49:44 am »
I believe you simply set the modelResults and you don't call the CLOSE afterwards.

Correct, Close for non-modal forms. Modal forms are closed via ModalResult (except for the mrNone value).

However, it does not exit the procedure (it is just a method call), and execution continues. That is why exit is needed after it.

In your case, it was not there, and therefore Close was called after ModalResult, which returned the wrong result.

sensui

  • Newbie
  • Posts: 3
Re: How to close a window while setting its return value as mrOk?
« Reply #3 on: May 22, 2025, 09:39:37 am »
I believe you simply set the modelResults and you don't call the CLOSE afterwards.

Correct, Close for non-modal forms. Modal forms are closed via ModalResult (except for the mrNone value).

However, it does not exit the procedure (it is just a method call), and execution continues. That is why exit is needed after it.

In your case, it was not there, and therefore Close was called after ModalResult, which returned the wrong result.

Thanks for replies.
But I found that simply setting `ModalResult := mrOk` does not close the window. I also tried setting the default `ModalResult` property of `btnLogin` to `mrOk`, but that didn't work either. 
I can't help but wonder if there's something wrong with my form. I'm using a regular form created through a unit.

Code: Pascal  [Select][+][-]
  1. unit ULogin;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls,
  9.   UMain;
  10.  
  11. type
  12.  
  13.   TFLogin = class(TForm)
  14.     btnLogin: TButton;
  15.     btnCancel: TButton;
  16.     btnOK: TButton;
  17.     edtUsername: TEdit;
  18.     edtPassword: TEdit;
  19.     lblMsg: TLabel;
  20.     lblUsername: TLabel;
  21.     lblPwd: TLabel;
  22.     procedure btnCancelClick(Sender: TObject);
  23.     procedure btnLoginClick(Sender: TObject);
  24.  
  25.   private
  26.  
  27.   public
  28.  
  29.   end;
  30.  
  31. var
  32.   FLogin: TFLogin;
  33.  
  34. implementation
  35.  
  36. {$R *.lfm}
  37.  
  38. { TFLogin }
  39.  
  40. procedure TFLogin.btnLoginClick(Sender: TObject);
  41. begin
  42.  
  43.   if (edtUsername.Text = 'admin') and (edtPassword.Text = 'admin') then
  44.   begin
  45.  
  46.     self.ModalResult := mrOK; // Signal successful login
  47.  
  48.   end
  49.   else
  50.   begin
  51.     ShowMessage('Wrong');
  52.     edtPassword.Clear;
  53.     edtPassword.SetFocus;
  54.   end;
  55. end;
  56.  
  57.  
  58. procedure TFLogin.btnCancelClick(Sender: TObject);
  59. begin
  60.   ModalResult := mrCancel; // Or any other ModalResult that is not mrOk
  61.   Close;
  62. end;
  63.  
  64. end.
  65.  

egsuh

  • Hero Member
  • *****
  • Posts: 1617
Re: How to close a window while setting its return value as mrOk?
« Reply #4 on: May 22, 2025, 10:00:28 am »
I think your login form is not in modal state, so setting its modalresult would not have any effect.
Can you post the whole lpr file?

cdbc

  • Hero Member
  • *****
  • Posts: 2208
    • http://www.cdbc.dk
Re: How to close a window while setting its return value as mrOk?
« Reply #5 on: May 22, 2025, 11:28:21 am »
Hi
Attached is a small project that demonstrates this 'ModalResult'-business...  8-)
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 3.6 up until Jan 2024 from then on it's both above &: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 4.99

sensui

  • Newbie
  • Posts: 3
Re: How to close a window while setting its return value as mrOk?
« Reply #6 on: May 22, 2025, 05:49:25 pm »
Hi
Attached is a small project that demonstrates this 'ModalResult'-business...  8-)
Regards Benny

After studying your code, I found that I had registered the login window as the main window, so it couldn't be closed automatically....

Thanks a lot. 👍

btw, I need to put
Code: Pascal  [Select][+][-]
  1. Application.Initialize;
before the
Code: Pascal  [Select][+][-]
  1. TFLogin.Create(nil) do begin
in the code you provided.

 

TinyPortal © 2005-2018