为什么关闭主窗口后程序还在运行

pooyui 2008-01-29 08:18:30
登录进入主窗口后,我按主窗口右上角的关闭按钮,只能关闭主窗口,不能关闭程序
登录窗口代码如下
implementation
uses unit2;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
with adoquery1 do
begin
close;
sql.clear;
sql.add('select * from users where id=:strid and pwd=:strpwd');
adoquery1.Parameters.ParamByName('strid').value:=edit1.Text;
adoquery1.Parameters.ParamByName('strpwd').value:=edit2.text;
open;
end;
if ADOQuery1.recordcount=0 then
begin
showmessage('密码错误');
end
else
begin
form2.show;
self.hide;
end;
end;

end.
工程文件我没有修改代码为
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.CreateForm(TForm2, Form2);
Application.Run;
end.
请问我想在进入主窗口后点关闭按钮就关闭程序应该怎么改,我这个只能关闭登录窗口才能关闭程序,谢谢!
...全文
454 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
fewind2100 2008-02-13
  • 打赏
  • 举报
回复
在form2的close时间中加入
application.terminate;
就可以了
pooyui 2008-01-30
  • 打赏
  • 举报
回复
是呀,是设成登录窗口了,但是设作主窗口为main form话,按照我那样写代码的话一运行就会先打开主窗口了,这怎么办呀
Ascn 2008-01-30
  • 打赏
  • 举报
回复
》》大侠,我是刚学delphi的,以前是学pb的,老师要我们转学delphi,实在是看不懂这么复杂的代码呀

不好意思。我为了发贴方便,没有修改和加注释。我可以说一下思路:
1、首先,我不用某个窗口来作为Main Form,即让Application不自动创建某个Form(Application自动创建的第一个Form就是Main Form,它一旦关闭就意味着应用程序结束),而是只自动创建一个DataModule,并把它作为Main Form。DataModule也具有Form的一些属性。

2、在DataModule(以下简称DM)中增加函数(DM中除了可以放置数据库相关组件外,也可以定义DM的公开成员函数),名称为Login。该函数直接调用frmLogin登录窗口中的函数。在DM的源代码的implementation语句后面增加:
uses
Forms, GVars, Login; //注意:Forms是因为要用到某些Form属性,GVars是我定义的公共Unit,用于全局的变量和函数定义,Login是登录窗口的文件名,此处需要添加。
DM中的Login函数只需要调用登录窗口中的用于创建窗口的函数就可以了。不需要取得返回值或其他处理。

3、在登录窗口中,定义两个全局函数。其中一个用于窗口的创建,另一个用于检测密码和用户名的合法性。将检测密码独立定义的目的是因为在窗口的登录按钮中要调用。而用于创建窗口的函数可以不用象我那么复杂,只需要创建就行了,参数也不必要那么多。我是因为曾经由其他应用程序来直接以命令行参数方式来调用本应用程序,所以才需要。登录函数中也不必象我那么复杂。只需要判断合法和非法后分别返回不同的值就行了,判断返回值的事情交给登录按钮去处理。

4、在应用程序的源代码中(Project-View Source菜单),改为如上我的应用代码一样就可以了。这样的话,系统不会把frmMain或者frmLogin作为主窗口,当关闭frmLogin时不会影响到应用程序。

5、我一般都是这样处理,只自动创建DM,对于其他窗口,每个窗口都定义一个全局函数,该函数用于创建本窗口,并作一些初始化等操作。

6、如果有其他问题,可以再讨论,呵呵
leeweijkd 2008-01-30
  • 打赏
  • 举报
回复
学习
pooyui 2008-01-30
  • 打赏
  • 举报
回复
大侠,我是刚学delphi的,以前是学pb的,老师要我们转学delphi,实在是看不懂这么复杂的代码呀
Ascn 2008-01-30
  • 打赏
  • 举报
回复
我的办法是:

创建DataModule,把它作为Main Form,而且仅有它为自动创建,其他的所有窗口,在工程的options中全部弄到右边列表中去。
1、有DataModule和窗口:Dm(DataModule), frmLogin(Form), frmMain(Form)
2、修改Application的Source Code:

Application.Initialize;
Application.Title := '管理系统';
Application.CreateForm(TDM, DM);
if DM.Login = 1 then
Application.CreateForm(TfrmMain, frmMain)
else
Application.Terminate;
Application.Run;

3、其中,在Dm有个Login函数:

function TDM.Login: Integer;
var
sUser, sPwd: string;
begin
sUser := '';
sPwd := '';
Result := UserLogin(sUser, sPwd, True, True); //因User为'', 后面两个参数忽略
end;

4、在frmLogin中有UserLogin函数,该函数可以显示登录错误的信息,也可以不显示。因为我的应用要求特殊,所以有这些参数。可以修改来适合您自己用。
注意:在
var
frmLogin: TfrmLogin;
之前定义全局的函数:
function UserLogin(var aUser, aPwd: string; aCheck, aShowMsg: Boolean): Integer;
function CheckUser(var aUser, aPwd: string; aCheck, aShowMsg: Boolean): Integer;


function UserLogin(var aUser, aPwd: string; aCheck, aShowMsg: Boolean): Integer;
begin
Result := 0;
if aUser = '' then
begin
with TfrmLogin.Create(Application) do
begin
lcbUser.Text := DM.RegIniFile.ReadString('Config', 'UserCode', '');
if ShowModal <> mrOK then
Application.Terminate
else
Result := 1;
end;
end
else
Result := CheckUser(aUser, aPwd, aCheck, aShowMsg);
end;

function CheckUser(var aUser, aPwd: string; aCheck, aShowMsg: Boolean): Integer;
var
s1, s2: string;
begin
Result := 0;

aPwd := Trim(aPwd);
if Length(Trim(aUser)) > 0 then
s2 := Trim(aUser)
else
begin
aUser := Trim(aUser);
if aShowMsg then
begin
Result := -1;
MessageBox(Application.Handle, '请输入正确的登录名', '提示信息', MB_OK or MB_ICONWARNING);
end;
Exit;
end;

with TADOQuery.Create(frmLogin) do
try
Connection := DM.conn;
SQL.Text := 'Select * from userinfo where usercode = ''' + s2 + '''';
Open;
First;
if not Eof then
begin
s1 := FieldByName('userpwd').AsString;

if aCheck then
begin
if UpperCase(s1) = UpperCase(aPwd) then
begin
aUser := FieldByName('username').AsString;
aPwd := FieldByName('sec_word').AsString;
Result := 1;
Exit;
end
else
begin
if aShowMsg then
begin
Result := -2;
MessageBox(Application.Handle,
'密码无法通过验证,请重新输入', '提示信息', MB_OK or MB_ICONWARNING);
end;
Exit;
end; //if UpperCase(s1) = UpperCase(aPwd) then
end
else
begin
aUser := FieldByName('username').AsString;
aPwd := FieldByName('sec_word').AsString;
Result := 1;
Exit;
end; //if aCheck then
end; //if not Eof then
finally
Close;
Free;
end; //try

{ Now, found nothing. Because no the User }
if aShowMsg then
begin
Result := -3;
MessageBox(Application.Handle, '非法用户,请检查输入是否正确', '提示信息', MB_OK or MB_ICONWARNING);
end;
end;

5、在“登录”按钮中代码如下:

procedure TfrmLogin.RzBitBtn1Click(Sender: TObject);
var
u, p, t: string;
n: integer;
begin
u := Trim(lcbUser.Text);
p := Trim(edPwd.Text);

t := u; //检测密码函数不返回登录名,必须预先取得
n := CheckUser(u, p, True, True); //检测密码时,用户名称和权限分别从u和p中返回
Case n of
1: begin
GVar.GUserCode := t;
GVar.GUserName := u;
GVar.GSecWord := p;
DM.RegIniFile.WriteString('Config', 'UserCode', t);
Dm.Log('登录进入系统');
RzBitBtn4.Click;
Exit;
end;
-1, -3: lcbUser.SetFocus;
-2: edPwd.SetFocus;
Else //0
//Nothing
end;
FTry := FTry + 1;
if FTry >= 3 then
begin
if not FLog then Dm.Log('试图进入本系统,错误已经达到三次以上', t, u);
FLog := True;
MessageBox(Handle, '试图登录进入本系统的次数已经达到三次,'
+ '这一情况已经被记录到系统日志中!', '提示信息', MB_OK or MB_ICONSTOP);
end;
end;

6、以上代码仅供参考。因我的应用中用了Raise和devExpress组件,直接复制过去可能无法使用。而且我的登录代码由于我的应用的特殊需求写得过于复杂了些,你可以按自己需求而简化。
pooyui 2008-01-30
  • 打赏
  • 举报
回复
回6楼,这样也不行呀,因为我那样写代码是把form1当成了main form,如果我一关闭form1的话就会关闭整个程序了,根本就打不开主窗口页面
sanguomi 2008-01-30
  • 打赏
  • 举报
回复
form1.hide;
form2.show;
form1.close;
pooyui 2008-01-30
  • 打赏
  • 举报
回复
回三楼,我知道这样可以,但是这样的话那不是要一直开着登录窗口吗,如果不是把登录窗口隐藏而是关闭的话就会整个程序关闭了,我是想让登录窗口先出来,而把主窗口当成main form,请问各位要怎么样改才行呀
阿三 2008-01-30
  • 打赏
  • 举报
回复
问题出在
form2.show;
self.hide;
因为你将form1仅仅是隐藏了.
pooyui 2008-01-30
  • 打赏
  • 举报
回复
谢谢你的指点,我自己慢慢研究一下,真的很感谢你这么耐心
woaiwd 2008-01-30
  • 打赏
  • 举报
回复
1.你打开你的程序,点击菜单上的Project->Options;
2.在打开的菜单上可以看见Auto-Create forms;
3你把你的登录窗口调整到你的主窗口的前面;
4.登录代码还用你自己的,再有你代码中有些多余的东西

with ADOQuery1 do
begin
Close;
SQL.Clear;
SQL.Add('select * from users where id=:strid and pwd=:strpwd');
ADOQuery1.Parameters.ParamByName('strid').Value:=Edit1.Text;
ADOQuery1.Parameters.ParamByName('strpwd').Value:=Edit2.Text;
open;
end;

可以改为

with ADOQuery1 do
begin
Close;
SQL.Clear;
SQL.Add('select * from users where id=:strid and pwd=:strpwd');
Parameters.ParamByName('strid').Value:=Edit1.Text;
Parameters.ParamByName('strpwd').Value:=Edit2.Text;
Open;
end;

5.然后用三楼说的方法,在主窗口的onClose事件中写入

procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Application.Terminate;;
end;

就不会出现你说的问题了。
taxpayer 2008-01-30
  • 打赏
  • 举报
回复
form2的close事件写 application.terminate
董董 2008-01-29
  • 打赏
  • 举报
回复
在Delphi的IDE中,打开Project/Options,在项目选项窗口中,看看"Main form"的设置窗口,是不是你的主程序窗口。我怀疑可能是因为你把登录窗口设置成Main form了。

2,497

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 数据库相关
社区管理员
  • 数据库相关社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧