申请无故终止
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
我已经使用可用表单 (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