应用程序终止没有明显的原因

时间:2015-02-11 04:18:54

标签: delphi delphi-xe7

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

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

“登录”程序:

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;

或许设置为true?

编辑:

我在create event上编辑了项目文件和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.

我似乎没有让应用程序关闭....(它仍然可以,呃......)

EDIT2:

试过这种方式。我将AdvGlowButton1设置为ModalResult = mrNone,将Form样式设置为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按钮(登录按钮)时关闭。我想到的另一件事是遗漏了,你如何在这个登录表单上提示关闭应用程序,因为它只需要模态结果?

2 个答案:

答案 0 :(得分:2)

就像@SertacAkyuz暗示一样,一个选择是ShowModal不会返回mrOK。检查此按钮的ModalResult值和/或OnClick此按钮的事件处理程序,以查看mrOK是否是在这些情况下返回的ModalResult ...

如果单击某个按钮,则会触发OnClick事件,如果该按钮的ModalResult设置为任何值,则Form的ModalResult将设置为该值。当事件(如OnClick事件)结束时,表单检查其ModalResult值,如果将其设置为0(零)以外的任何值,则表单将关闭,并返回值作为ShowModal函数的结果。 / p>

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

答案 1 :(得分:1)

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

所以我建议下一步改变:

首先删除按钮的模态结果。按钮模态结果propery主要用作转发信息的方式,因为点击哪个特定按钮导致模态形式的关闭。

然后更改按钮事件代码,使其仅在代码正确时设置表单模态结果,否则应显示输入的passowrd为incorect的消息。像这样:

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;

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

在您当前的设计中,您可以在应用程序开始时创建所有表单。现在,当您开始隐藏主表单时,这仍然意味着您的用户无法访问它。

使用特殊的软件用户可以找到主窗体窗口的句柄并显示它,而无需完成登录过程。

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

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

Delphi Change main form while application is running