#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2012
    Posts
    11
    Rep Power
    0

    Exclamation Login Screen Problem


    Hi. I'm creating an application and I am currently in the process of creating the login screen. I have searched the forums for a similar problem, but cannot find one.

    I have a basic 'Main' form and a basic 'Login' form. My login form consists of two edit boxes (username and password) and two buttons (login and exit).

    I would like the main form to remain as the main form but to only open once the login requirements have been met.

    Here is the code for my login button click procedure.
    Code:
    procedure TfrmLogin.btnLoginClick(Sender: TObject);
     begin
     if (frmLogin.edtUsername.Text = 's') and (frmLogin.edtPassword.Text = 'b') 
    then 
    begin
     ValidateLog := true;
     MessageDlg ('Correct', mtWarning, [mbYes], 0) 
    end 
    else
     begin 
    MessageDlg ('Invalid Login', mtWarning, [mbYes], 0); 
    ValidateLog := false; 
    end; 
    end;
     end;
    I have placed called this procedure before my Main form is created, within the program source code.
    Code:
    begin 
    ValidateLog := false; 
    Application.Initialize;
     frmLogin := TfrmLogin.Create(Application); 
    frmLogin.ShowModal;
     repeat 
    frmLogin.btnLoginClick(Application);
     until ValidateLog = True;
      Application.MainFormOnTaskbar := True;
      Application.CreateForm(TfrmMain, frmMain);
      Application.Run;
    end.
    The login form runs before everything else and comes up with the 'Invalid Login' message if the login is incorrect. It also comes up with the 'Correct' Message if the login is correct.

    However my problem is that the program does not continue to run and create the main form, it just stays on the login form. I would appreciate any help. Please tell me if i am going about this in the completely wrong way.

    Thanks, A.
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2008
    Posts
    350
    Rep Power
    7
    Here's an article that shows how to create a log in form with Delphi.

    http://delphi.about.com/od/windowsshellapi/a/password_login.htm
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2012
    Posts
    11
    Rep Power
    0
    Thanks for your reply.
    I used that tutorial to get me started.
    I'm still slightly confused.

    The method shown in that link aborts the application if the login is incorrect. Could you please help me mend my code or the code within that tutorial so that when the login information is incorrect a simple error message is shown and the user is shown the login screen again.

    Thanks.
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2008
    Posts
    350
    Rep Power
    7
    Your problem is that you create your log in form, and display it using the showmodal method. Until the login form is closed (which you never do), it remains the focused form of your application.

    I really suggest you create the log in form as the article outlines.

    From the article (a bit altered),

    this would be your log in form's code:

    Code:
    unit login;
     
     interface
     
     uses
       Windows, Messages, SysUtils, Variants, Classes,
       Graphics, Controls, Forms, Dialogs, StdCtrls;
     
     type
       TfrmLogin = class(TForm)
         LogInButton: TButton;
         ExitButton: TButton;
         pwdLabel: TLabel;
         passwordEdit: TEdit;
         procedure LogInButtonClick(Sender: TObject);
         procedure ExitButtonClick(Sender: TObject);
       public
         class function Execute : boolean;
         //notice the word "Class" before the function
         //This is important, and won't work correctly 
         //if you don't include it
       end;
     
     implementation
     {$R *.dfm}
     
     class function TfrmLogin.Execute: boolean;
     //notice Class here also!!!
     begin
       with TfrmLogin.Create(nil) do
       try
         Result := ShowModal = mrOk;  
         //Execute Function Return True or False depending on 
         //whether btnLongClick sets ModalResult to mrOK or mrAbort
         //Result is true only if username/password are correct
       finally
         Free; //This closes your form
       end;
     end;
     
     procedure TfrmLogin.LoginButtonClick(Sender: TObject);
     var
       PassesThrough: Integer;
     begin
       PassesThrough := 0;
       repeat
          if (edtUsername.Text = 's') and (edtPassword.Text = 'b') then
             ModalResult := mrOK
          else
          begin
             ModalResult := mrAbort;
             edtUsername.Clear;
             edtPassword.Clear;
          end;
          Inc(PassesThrough);
       until (ModalResult = mrOK) or (PassesThrough < 3);
       //only allow a few opportunities to get the username/password correct
     end;
     
     procedure TfrmLogin.ExitButtonClick(Sender: TObject);
     begin
        ModalResult := mrCancel;
     end;
    
     end.
    Then your program's source
    Code:
     begin
       if TfrmLogin.Execute then
       begin
         //only start your application if Execute returned True
         //which only happens if the Log In Form's Modal Result
         //is mrOK.
         Application.Initialize;
         Application.CreateForm(TMainForm, MainForm) ;
         Application.Run;
       end
       else
          MessageDlg('Invalid Credentials Provided!', mtError, [mbOK], 0);
     end.
    I haven't tested the code, so there may be errors.

    Comments on this post

    • Master A agrees
    Last edited by majlumbo; September 5th, 2012 at 10:47 AM.
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2012
    Posts
    11
    Rep Power
    0
    Thanks for replying. I'll read some tutorials on class functions.

    I've implemented your altered method, but the repeat function doesn't seem to prevent the application from closing.

    I've tried altering bits of your code, such as changing the (PassesThrough < 3) to (PassesThrough > 3), but I am still confused as to what the problem could be.

    Btw, your annotations to your code really helped, thanks.

    Maybe i'm doing something wrong somewhere else in my code?
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2008
    Posts
    350
    Rep Power
    7
    Try modifying it like so, I was afraid that setting ModalResult would close the form, which apparently is what's happening
    Code:
     procedure TfrmLogin.LoginButtonClick(Sender: TObject);
     var
       PassesThrough: Integer;
       LocalModalResult: Boolean;
     begin
       PassesThrough := 0;
       LocalModalResult := False;
       repeat
          if (edtUsername.Text = 's') and (edtPassword.Text = 'b') then
             LocalModalResult := True
          else
          begin
             LocalModalResult := False;
             edtUsername.Clear;
             edtPassword.Clear;
          end;
          Inc(PassesThrough);
       until (LocalModalResult) or (PassesThrough > 3);
       if LocalModalResult then
          ModalResult := mrOK
       else
          ModalResult := mrAbort;
     end;
    Also, correct on PassesThrough > 3 not <.. Sorry
    Last edited by majlumbo; September 5th, 2012 at 11:05 AM.
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2012
    Posts
    11
    Rep Power
    0
    Still not working.
    I'm getting the error message which i've placed in the program code coming up. So that means the repeat function isn't working right? Or the Modalresult is getting passed to the Execute statement, without allowing the login screen to be shown again.
    Maybe i'm doing something wrong
  14. #8
  15. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2012
    Posts
    11
    Rep Power
    0
    I've also realised that the application freezes due to what looks like a continuous loop, when the PassesThrough Maximum is removed from the until line.
    Would this mean that the PassesThrough clause is allowing the loop to be broken?

    I think you've realised already, but i'm not anywhere near a pro at delphi... or pascal, but I tried to use recursion to recall the buttonclick procedure within itself.
    I'm getting an access violation error, so i'm doing something wrong. Is that worth thinking about, or is it a dead end?

    Thanks again for your help, A.
  16. #9
  17. No Profile Picture
    Contributing User
    Devshed Regular (2000 - 2499 posts)

    Join Date
    Jan 2006
    Location
    Carlsbad, CA
    Posts
    2,057
    Rep Power
    383
    I think your problem is that the code is in the button click method and there is no opportunity to edit the data between cycles.
    Try something like this (untested also)
    Code:
    //Up top
    type
       TfrmLogin = class(TForm)
       ....
       ....
       private
       FPassesThrough: Integer;
       function tryit: Boolean;
        ......
      
    // Below
    procedure TfrmLogin.LoginButtonClick(Sender: TObject);
    begin
       If TryIt := False then begin
          inc(FPassesThrough);
       end
       else begin
          ModalResult := mrOK;
       end;
       if FPassesThrough > 3 then begin
           MessageDlg('Invalid Credentials Provided!', mtError, [mbOK], 0);
           ModalResult := mrAbort;
       end;
    end;
    
    function TfrmLogin.tryit: Boolean;
    begin
      Result := False;
        if (edtUsername.Text = 's') and (edtPassword.Text = 'b') then begin
            Result := True;
        end;
    end;
    Clive
  18. #10
  19. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2008
    Posts
    350
    Rep Power
    7
    Thanks Clive,

    That's the downside of doing code all in your head. Looks good, but you miss the simplest thing...
  20. #11
  21. No Profile Picture
    Contributing User
    Devshed Regular (2000 - 2499 posts)

    Join Date
    Jan 2006
    Location
    Carlsbad, CA
    Posts
    2,057
    Rep Power
    383
    That's the downside of doing code all in your head. Looks good, but you miss the simplest thing...
    And don't I know it!!
  22. #12
  23. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2012
    Posts
    11
    Rep Power
    0
    It works!

    It does exactly what I was looking for.

    Thanks a lot to the both of you. This problem has been bugging me for so long.

    I really appreciate it, cheers.

IMN logo majestic logo threadwatch logo seochat tools logo