Delphi 登录表单

6
在我的Delphi程序中,我有一个登录表单,并且在主表单创建之前显示,但我面临的问题是我想要将登录检查处理在主表单中进行,这意味着登录表单将使用主表单进行检查和处理。
请阅读以下代码中的注释: procedure LogInButtonClick(Sender: TObject);
这里是TLoginForm代码(来自delphi.about.com):
    unit login;

 interface

 uses
   Windows, Messages, SysUtils, Variants, Classes,
   Graphics, Controls, Forms, Dialogs, StdCtrls;

 type
   TLoginForm = class(TForm)
     LogInButton: TButton;
     pwdLabel: TLabel;
     passwordEdit: TEdit;
     procedure LogInButtonClick(Sender: TObject) ;
   public
     class function Execute : boolean;
   end;

 implementation
 {$R *.dfm}

 class function TLoginForm.Execute: boolean;
 begin
   with TLoginForm.Create(nil) do
   try
     Result := ShowModal = mrOk;
   finally
     Free;
   end;
 end;

 procedure TLoginForm.LogInButtonClick(Sender: TObject) ;
 begin
   if passwordEdit.Text = 'delphi' then
   {
   Here how it's possible to use :
    if MainForm.text=passwordEdit.Text then 
    ModalResult := mrOK
    }

     ModalResult := mrOK
   else
     ModalResult := mrAbort;
 end;

 end. 

这里是主程序初始化流程:

program PasswordApp;

 uses
   Forms,
   main in 'main.pas' {MainForm},
   login in 'login.pas' {LoginForm};

 {$R *.res}

 begin
   if TLoginForm.Execute then
   begin
     Application.Initialize;
     Application.CreateForm(TMainForm, MainForm) ;
     Application.Run;
   end
   else
   begin
     Application.MessageBox('You are not authorized to use the application. The password is "delphi".', 'Password Protected Delphi application') ;
   end;
 end.

谢谢


你的问题毫无意义。你想从“LoginForm”访问“MainForm”,但是你的项目代码显示在“LoginForm”成功显示之后才创建“MainForm”。你不能两全其美。如果你在“LoginForm”尝试访问它之前不创建“MainForm”,你就无法访问“MainForm”上的内容。 - Ken White
是的,因为我真的需要它来使用主表单进行检查,然后继续。 - Sdean
4
你可以使用一个DataModule来检查任何你想要的东西,并在登录窗体和主窗体之间共享该DataModule。 - jachguate
2
视觉控件(表单、编辑等)的意图是交互而不是存储数据。一旦你意识到这一点,你就再也不会遇到这个问题了;o) - Sir Rufo
3个回答

13
如果您需要先创建主表单,请首先创建它:
begin
  Application.Initialize;
  Application.CreateForm(TMainForm, MainForm);//created, but not shown
  if TLoginForm.Execute then//now the login form can refer to the main form
    Application.Run//this shows the main form
  else
    Application.MessageBox('....');
end;
那是你所问问题的直接而天真的回答。更广泛地思考,我鼓励你将登录测试移出主表单,在某个可以被任何需要的高级代码使用的地方放置它。你目前正在努力实现的设计具有不健康的耦合性。

2
不会。只有在登录成功后,主窗体才会显示。请阅读代码中的注释。 - David Heffernan
@user1998327:在调用Application.Run之前,主窗体不会显示。但是如果需要的话,您可以将Application.ShowMainForm设置为False,然后在登录成功后手动调用MainForm.Show - Remy Lebeau
这意味着,我可以使用 " if MainForm.text=passwordEdit.Text then ModalResult := mrOK " - Sdean
@David Heffernan 非常感谢,我会测试并给你回信。 - Sdean

5

通常我会在MainFormOnCreate方法或者DataModuleOnCreate方法中执行此操作,如果您有一个DataModule的话。例如:

TMainForm.OnCreate(Sender: TObject);
var F: TLoginForm;
begin
  F := TLoginForm.Create(Self);
  try
    F.ShowModal;
  finally F.Free;
  end;
end;

我不太喜欢过多地修改 DPR 文件。这个方法可以按正确的顺序显示表单,如果 TMainForm 是由 Delphi 自动创建的,则当 OnCreate 触发时,MainForm 变量已经被赋值并准备好使用。

PS: 访问 MainForm 变量实际上是不好的设计,但如果你想要它,它就在那里。


你如何停止对 Application.Run 的调用? - David Heffernan
通常我会非常直接地这样写:TerminateProcess(GetCurrentProcess, 1) - 这个方法非常好用 :) - Cosmin Prund
没问题。使用 Halt 更符合 Pascal 风格。 - David Heffernan

0

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