2.4 让界面更友好一些
经过上面的改进,我们有了一个共用的设置类,我们可以通过这个共用的设置类来访问诸如数据库连接等一些MIS的基本属性。现在我们再来运行一下程序,不过这次我们先把SQL Server关闭一下,然后再来看是什么样的效果,我们会发现,当你运行程序时,程序会等了好久都没有反应。当然最后会出现一个报错说找不到SQL Server数据库服务。
设想一下,当你的程序发布给最终用户用的时候,如果用户点击了程序,发现很久都没有反应,他可能会再多点击几下,这样的话,给最终用户的使用感受就非常的不好。因此,我们将在这一小节里面加一个欢迎的窗口(TfrmWelcome),一旦用户运行程序,该窗口就马上显示出来,同时告诉用户正在连接数据库(当然,这个窗体还可以显示你公司,或者你自己设计的一些有标志性的Logo,就像我的FlexQue一样)。好了,我们现在来添加一个新的窗体,并把这个窗体设置为无边框型。(BorderStyle设为bsNone),另外,我们在这个窗体上添加一个Label,用于显示一些消息,最后,把这个Form的名字改为frmWelcome,保存为WelcomeForm.pas。
因为我们想把建立数据库连接这一任务能在TfrmWelcome上显示。所以我们修改一下已有的代码,首先修改BaseConfUnit.pas中的,我们把BuildConnection;的调用从Create方法中删除。让外面的过程来调用BuildConnection这一方法。然后,在MDI_Tutorial,dpr中增加几行代码:
……
GBaseConf := TBaseConf.Create;
frmWelcome := TfrmWelcome.Create(nil);
frmWelcome.ShowModal;
frmWelcome.Free;
frmLogin := TfrmLogin.Create(Application);
……
同时,记得把Application.CreateForm(TfrmWelcome, frmWelcome);这一句删除掉。
最后,我们来编写WelcomeForm的代码,代码如下:
unit WelcomeForm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TfrmWelcome = class(TForm)
Label1: TLabel;
procedure FormCreate(Sender: TObject);
end;
var
frmWelcome: TfrmWelcome;
implementation
uses
BaseConfUnit;
{$R *.dfm}
procedure TfrmWelcome.FormCreate(Sender: TObject);
begin
Label1.Caption := '正在建立数据库连接';
Label1.Repaint;
GBaseConf.BuildConnection;
end;
end.
当程序运行后,我们发现并不是我们想像的那样,欢迎窗口并没有显示出来!这是为什么呢?我们来看一下程序,其实我们把数据库连接设置的调用放在FormCreate中是不合适的,因为FormCreate事件是当Form被创建时所产生的事件,那时候Form还没有被显示出来,所以我们是看不到欢迎信息的,那么我们把这个创建调用放到其它事件,例如FormShow中行吗?其实也是不行的,不信你可以试试看,原因跟刚才的差不多。其实在TForm里面的基本事件没有一个是合适的,那怎样解决这个问题呢?我自己想到两个方法(看看其它朋友有没有更好的方法了):第一,采用一个定时器,该定时器定时为1秒,当定时器响应事件被触发时就关闭定时器,然后再调用数据连接方法。因为定时器要等1秒,窗体一般都能初始化完毕并显示完毕了,这样就可以完成这件事情了。另一种方法是使用Windows的消息机制,因为PostMessage可以产生异步的效果,所以利用它就可以完成这个事情,现在让我们来看一下第二种方法的代码,代码如下:
unit WelcomeForm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TfrmWelcome = class(TForm)
Label1: TLabel;
procedure FormShow(Sender: TObject);
private
procedure doit(var i :integer); message WM_USER + 100;
end;
var
frmWelcome: TfrmWelcome;
implementation
uses
BaseConfUnit;
{$R *.dfm}
procedure TfrmWelcome.doit(var i: integer);
begin
Label1.Caption := '正在建立数据库连接';
Label1.Repaint;
GBaseConf.BuildConnection;
Close;
end;
procedure TfrmWelcome.FormShow(Sender: TObject);
begin
PostMessage(WindowHandle, WM_USER + 100, 0, 0);
end;
end.
如果没有错误的话,我们的程序应该能显示那个欢迎的窗口了。但如果数据库没有准备好的话,还是那个不友好的报错,所以这里要进行一下大的改动,做法是利用try…except机制来捕获异常,并把数据库接连的结果返回给主程序。所以最后的版本是这样的,首先来看WelcomeForm.pas中的代码:
{
MDI Tutorial v2.4
Written by flexitime.
}
unit WelcomeForm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TfrmWelcome = class(TForm)
Label1: TLabel;
procedure FormShow(Sender: TObject);
private
FRetValue : boolean;
procedure doit(var i :integer); message WM_USER + 100;
public
property RetValue : boolean read FRetValue;
end;
var
frmWelcome: TfrmWelcome;
implementation
uses
BaseConfUnit;
{$R *.dfm}
procedure TfrmWelcome.doit(var i: integer);
begin
Label1.Caption := '正在建立数据库连接';
Label1.Repaint;
try
GBaseConf.BuildConnection;
FRetValue := true;
except
on E : Exception do
begin
Label1.Caption := '连接失败!';
MessageBox(WindowHandle, '数据库连接失败!', 'MDI_Tutorial', MB_ICONWARNING or MB_OK);
end;
end;
Close;
end;
procedure TfrmWelcome.FormShow(Sender: TObject);
begin
FRetValue := false;
PostMessage(WindowHandle, WM_USER + 100, 0, 0);
end;
end.
MDI_Tutorial.dpr中的代码如下:
……
var
ret : boolean;
begin
Application.Initialize;
GBaseConf := TBaseConf.Create;
frmWelcome := TfrmWelcome.Create(nil);
frmWelcome.ShowModal;
ret := frmWelcome.RetValue;
frmWelcome.Free;
if ret then
begin
frmLogin := TfrmLogin.Create(Application);
frmLogin.ShowModal;
if frmLogin.RetValue then
begin
Application.CreateForm(TfrmMain, frmMain);
end;
frmLogin.free;
Application.Run;
end;
GFormClassMgr.Free;
GBaseConf.Free;
end.
如果程序没有拼写错误的话,那么就应该能正常的运行的。当然现在我的程序只是一个示意的程序,你可以加上图片等等,这样就会漂亮很多了。
2.5 整理框架
……撰写中……