Delphi应用程序的登录/注销功能 - 如何实现?

11

该应用程序有一个登录表单和一个主表单。

应用程序的DPR文件包含代码,以先加载登录表单,当登录表单返回成功登录时,创建和加载主表单。

当用户通过主表单中的菜单命令注销时,它应关闭主表单并加载登录表单。

仅当用户在主表单中选择退出(或者在登录表单中取消)时,应用程序才会退出。

是否可以使用应用程序的DPR文件中的代码来实现这一点?

以下是目前存在的代码:

program H;

uses
  Forms,
  SysUtils,
  Registry,
  MidasLib,
  Dialogs,
  Controls,
  uDatamod in 'uDatamod.pas' {datamod: TDataModule} ,
  uMain in 'uMain.pas' {fMain} ,
  uMtlUpd in 'uMtlUpd.pas' {fMtlUpd} ,
  uReportPrv in 'uReportPrv.pas' {fReportPrv} ,
  uCamera in 'uCamera.pas' {fCamera} ,
  uConfig in 'uConfig.pas' {fConfig} ,
  uFuncs in 'uFuncs.pas',
  uLogin in 'uLogin.pas' {fLogin} ,
  uAdmin in 'uAdmin.pas' {fAdmin};

// MidasLib is required.

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.Title := 'HTech';

  if ((ParamCount = 1) and (UpperCase(ParamStr(1)) = '/CONFIG')) or
    (getHServerHostName = EmptyStr) then
  begin
    Application.CreateForm(TfConfig, fConfig);

    Application.Run;
  end
  else
  begin
    if not testHServerConnection then
    begin
      ShowMessage('Error: Could not connect to HServer');

      Exit;
    end;

    Application.CreateForm(Tdatamod, Datamod);

    while not TerminateApplicationFlag do
    begin

      fLogin := TfLogin.Create(Application);
      try
        if fLogin.ShowModal = mrOk then
        begin
          LoggedInEmployeeID := fLogin.FEmployeeID;
          LoggedInEmployeeNm := fLogin.edtFirstName.Text + ' ' +
            fLogin.edtLastName.Text;
          AdminLogin := fLogin.FAdminUser;
          FinanceLogin := fLogin.FFinanceUser;
        end
        else
        begin

          FreeAndNil(fLogin);
          FreeAndNil(Datamod);
          Exit;
        end;
      finally
        // FreeAndNil(fLogin);
      end;

      if AdminLogin then
        Application.CreateForm(TfAdmin, fAdmin)
      else
      begin
        FreeAndNil(fLogin);
        if not Assigned(fMain) then
          Application.CreateForm(TfMain, fMain);
        fMain.FHServerHost := getHServerHostName;
      end;

      Application.Run;

    end;
  end;

end.
上面的代码问题在于,经过一次迭代后(用户在主表单中执行注销之后),应用程序退出(控制返回到操作系统),因为"fLogin.ShowModal"在不显示登录窗体的情况下退出。
以下是从主表单获取的代码:
Procedure LogoutProcedure;
  begin
    TerminateApplicationFlag := False;
    Close;
  end;

Procedure ExitProcedure;
  begin
    TerminateApplicationFlag := True;
    Close;
  end;

我遇到了困难,希望能得到任何建议或更正来让它工作起来。

提前感谢。

敬礼,
Steve Faleiro


6
从.dpr文件中显示登录表单,通过调用TLoginForm.Create进行创建。不要使用Application.CreateForm。使用ShowModal显示它。当它返回时,决定是否继续。如果继续,创建您的主窗体,这次使用Application.CreateForm。然后调用Application.Run。很抱歉这全部都是注释,但是一个过于热心的管理员已经关闭了问题,尽管我可以理解您的问题。 - David Heffernan
2
当然可以编写那个代码。开始打字吧! - Rob Kennedy
2
@David Heffernan:对于“过度热心的管理员”,我也给出+1,我也理解了问题。 - Alexander Malakhov
4
很高兴看到 Stack Overflow 社区能够协作,重新开放这个问题并提供帮助。大家干得好! - David Heffernan
1个回答

7
也许这个非常简单的解决方案就足够了:
项目文件:
program Project1;

uses
  Forms,
  FMain in 'FMain.pas' {MainForm},
  FLogin in 'FLogin.pas' {LoginForm};

{$R *.res}

var
  MainForm: TMainForm;

begin
  Application.Initialize;
  Application.CreateForm(TMainForm, MainForm);
  Login;
  Application.Run;
end.

主表单:
unit FMain;

interface

uses
  Classes, Controls, Forms, StdCtrls, FLogin;

type
  TMainForm = class(TForm)
    LogoutButton: TButton;
    procedure LogoutButtonClick(Sender: TObject);
  end;

implementation

{$R *.dfm}

procedure TMainForm.LogoutButtonClick(Sender: TObject);
begin
  Login;
end;

end.

登录表单:

unit FLogin;

interface

uses
  Classes, Controls, Forms, StdCtrls;

type
  TLoginForm = class(TForm)
    LoginButton: TButton;
    CancelButton: TButton;
    procedure FormCreate(Sender: TObject);
  end;

procedure Login;

implementation

{$R *.dfm}

procedure Login;
begin
  with TLoginForm.Create(nil) do
  try
    Application.MainForm.Hide;
    if ShowModal = mrOK then
      Application.MainForm.Show
    else
      Application.Terminate;
  finally
    Free;
  end;
end;

procedure TLoginForm.FormCreate(Sender: TObject);
begin
  LoginButton.ModalResult := mrOK;
  CancelButton.ModalResult := mrCancel;
end;

end.

现在,这个答案在Delphi 7中运行得很好,但我怀疑在更近期的版本中可能存在问题,因为Application.MainFormOnTaskbarApplication.ShowMainForm默认为True。当如此时,请尝试将它们设置为False


你的意思是:否则开始 Application.Minimize; Application.Terminate; end; 最后 Free; end; ??? 你仍然会看到屏幕抖动... - user763539
@NGLN,有没有想过如何防止屏幕抖动的方法? - user763539
@user763539,我仍然不确定你的问题是什么,因为我无法重现它。也许最好作为一个新问题来询问,以吸引更多愿意帮助的人。然后你可以全面地解释问题所在,比在这些简短的评论中更好地说明情况。 - NGLN
@NGLN 在你的例子中,主窗体在成功登录后显示(按钮的模态结果为OK)。但是,如果我关闭登录窗体而没有输入任何登录参数,则应用程序会在死亡之前尝试打开主窗体,因此它看起来像屏幕抖动(因为实际上主窗体只显示了一小部分)。我正在尝试避免这种尝试显示主窗体的情况。明白吗? - user763539
@user763539 是的,我有点理解,但我无法复现。不是在D7中,也不是在XE2中。我确实在登录表单显示之前通过在IDE中设置MainForm.Visible=True来复制了这个“抽搐”,但那似乎不像你描述的故障。为记录:您也将其设置为True吗?然后尝试将其设置回False。否则,请参考此问题提出新问题,因为我怀疑我们无法在这些评论中得到令人满意的解决方案。 - NGLN
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接