申请无故终止

Application terminates for no apparent reason

我已经使用可用表单 (Form4) 和 MainForm 设置了我的登录程序。 在可用表格 (form4) 上,我有:

var
  Form4: TForm4;
  procedure Login;
implementation
.....

'Login' 过程如下:

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

然后在同一个表单上我有一个登录按钮:

procedure TForm4.AdvGlowButton1Click(Sender: TObject);  //the buton's property is ModalResult=mrOK
begin
DataModule2.LOGIN_QUERY.Active:=false;
DataModule2.LOGIN_QUERY.SQL.Clear;
DataModule2.LOGIN_QUERY.SQL.Add('select user,passsword from users where user='+QuotedStr(cxlookupcombobox1.text)+' and password='+QuotedStr(cxTextEdit1.Text));
DataModule2.LOGIN_QUERY.Open;
if DataModule2.LOGIN_QUERY.FieldByName('password').AsString<>''
then   ModalResult := mrOK  else
ModalResult := mrNone;
end;

项目源码是这样的:

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := False;
  Application.CreateForm(TDataModule2, DataModule2);
  Application.CreateForm(TMainForm, MainForm);
  Application.CreateForm(TForm7, Form7);
  Application.CreateForm(TARCHIVE, ARHCIVE);
  Application.CreateForm(TForm10, Form10);
  Application.CreateForm(TForm1, Form1);
  Application.CreateForm(TForm6, Form6);
  Application.CreateForm(TForm5, Form5);
  Application.CreateForm(TForm9, Form9);
  Application.CreateForm(TForm12, Form12);
  Application.CreateForm(TForm12, Form12);
  Application.CreateForm(TAboutBox, AboutBox);
  Login;
  Application.Run;
end.

然而,有时当单击 Form4 上的登录按钮时,应用程序 无故终止。为什么会这样? 应该

Application.MainFormOnTaskbar := False;

也许设置为真?

编辑:

我在创建事件时编辑了项目文件和 form4:

procedure TForm4.FormCreate(Sender: TObject);
begin
AdvGlowButton1.ModalResult := mrOK;
end;

并更改了项目源:

{$R *.res}
 var
  MainForm: TMainForm;

begin
  Application.Initialize;
  Application.CreateForm(TMainForm, MainForm);
  Application.MainFormOnTaskbar := False;
  Application.CreateForm(TDataModule2, DataModule2);
  Application.CreateForm(TForm7, Form7);
  Application.CreateForm(TARCHIVE, ARCHIVE);
  Application.CreateForm(TForm10, Form10);
  Application.CreateForm(TForm1, Form1);
  Application.CreateForm(TForm6, Form6);
  Application.CreateForm(TForm5, Form5);
  Application.CreateForm(TForm9, Form9);
  Application.CreateForm(TForm12, Form12);
  Application.CreateForm(TForm12, Form12);
  Application.CreateForm(TAboutBox, AboutBox);
  Login;
  Application.Run;
end.

而且我似乎没有关闭应用程序....(它仍然关闭,呃...)

编辑2:

试过这种方法。我将 AdvGlowButton1 设置为 ModalResult=mrNone 并将表单样式设置为 fsdialog:

procedure TForm4.AdvGlowButton1Click(Sender: TObject);  //the buton's property is ModalResult=mrOK
begin
DataModule2.LOGIN_QUERY.Active:=false;
DataModule2.LOGIN_QUERY.SQL.Clear;
DataModule2.LOGIN_QUERY.SQL.Add('select user,passsword from users where user='+QuotedStr(cxlookupcombobox1.text)+' and password='+QuotedStr(cxTextEdit1.Text));
DataModule2.LOGIN_QUERY.Open;
if DataModule2.LOGIN_QUERY.FieldByName('password').AsString<>''
then   ModalResult := mrOK  else
dxStatusBar1.Panels[1].Text :='Wrong password !';
end;

这在大多数情况下都有效,但有时当我启动应用程序并点击 AdvGlowButton1 按钮(登录按钮)时它会关闭。我发现的另一件事丢失了,你如何提示关闭此登录表单上的应用程序,因为它只需要模态结果?

就像@SertacAkyuz 暗示的那样,一种选择是 ShowModal 不会 return mrOK。检查此按钮的 ModalResult 值 and/or 此按钮的 OnClick 事件处理程序,以查看 mrOK 是否是在这些情况下 returned 的 ModalResult...

如果单击按钮,则会触发 OnClick 事件,如果该按钮的 ModalResult 设置为任何值,则窗体的 ModalResult 将设置为该值。当一个事件(如 OnClick 事件)结束时,表单检查其 ModalResult 值,如果它被设置为 0(零)以外的任何值,则表单关闭并且该值是 returned 作为结果ShowModal 函数。

因此,根据您提供的信息,这似乎是一种可能的情况 - 表单的 ModalResult 设置为某个不正确的值。然后表单关闭,然后您的 IF ShowModal 测试终止应用程序(因为它没有 return mrOK)。

根据您的代码,输入错误的密码也会导致您的应用程序终止,因为在这种情况下,返回的模态结果将是 mrNone,您只希望 mrOK 继续您的应用程序。

所以我建议接下来的更改:

首先删除按钮的模态结果 属性。按钮模态结果 属性 主要仅用作转发信息的一种方式,即单击哪个特定按钮导致模态窗体关闭。

然后更改您的按钮事件代码,以便它仅在代码正确时设置表单模式结果,否则它应该显示一条消息,表明输入的密码不正确。像这样:

procedure TForm4.AdvGlowButton1Click(Sender: TObject);  //the buton's property is ModalResult=mrOK
begin
  DataModule2.LOGIN_QUERY.Active:=false;
  DataModule2.LOGIN_QUERY.SQL.Clear;
  DataModule2.LOGIN_QUERY.SQL.Add('select user,passsword from users where user='+QuotedStr(cxlookupcombobox1.text)+' and password='+QuotedStr(cxTextEdit1.Text));
  DataModule2.LOGIN_QUERY.Open;
  if DataModule2.LOGIN_QUERY.FieldByName('password').AsString<>'' then
    //Close the modal form with returning of mrOK as modal result
    ModalResult := mrOK  
  else
  begin
    //No modal result should be set here or it would lead to closure of login form
    MessageDlg('Entered password is incorect!',mtError, mbOKCancel, 0);
  end;
end;

这是针对您的特定问题的直接解决方案。但我建议您认真重新考虑整个登录系统的设计。为什么?

在您当前的设计中,您在应用程序开始时创建所有表单。现在,虽然您确实从隐藏的主窗体开始,但这并不意味着您的用户无法访问它。

使用特殊的软件用户可以找到您的主表单的句柄 window 并显示它,而无需通过您的登录过程。

因此,避免这种情况的正确方法是先创建登录表单,然后仅在成功登录后才创建其余表单。但这意味着您的登录表单实际上将成为您应用程序的主要表单,因此您应该非常小心不要关闭它,因为它会导致整个应用程序关闭。

您可以在我对另一个问题的回答中查看如何实施这种方法的示例:

Delphi Change main form while application is running