奇趣技术网 收藏本站
设为主页
商务合作
首页 新闻中心 行业动态 软件新闻 安全资讯 病毒预警 漏洞发布 操作系统 Dos Win9x Win2000 WinXP Win2003 WinVista Linux Unix
数据库 DB2 Access MSSQL MySQL Oracle Sybase 编程技术 ASP PHP JSP CGI/Perl XML .Net C/C++/C# VB VC Delphi Java 汇编
安全技术 安全教学 工具介绍 漏洞利用 病毒防范 入侵检测 防火墙 安全防范 汉化破解 攻击实例 加密解密 技术论坛
中华网络安全联盟 >> 程序开发 >> Delphi >> 软件启动画面中启动状态的显示
程序开发
Asp
PHP
JSP
CGI/Perl
XML
.Net
C/C++/C#
Visual Basic
Visual C++
Delphi
Java
汇编语言
  • Delphi实现网页表单数

  • 用Delphi开发Web服务数

  • Delphi中利用钩子实现

  • 一个判断定文件是否为

  • 把Flash文件转换为Exe

  • 用Delphi实现文件下载

  • Delphi中保存图像列表

  • 基于Delphi的接口编程

  • 软件启动画面中启动状态的显示
    字体:

    中华网络安全联盟    作者:佚名    来源:网络转载    时间:2006-3-22

    我们平时看到的很多软件(PhotoShop,3DMax)都会在启动画面中显示当前正在启动哪个模块,并在模块加载失败时给予提示,这样的好处是,可以让比较专业的软件使用者知道当前软件加载了哪些模块,或者在软件发生启动错误时,让用户得以反馈是启动的哪个模块时发生了,以及在长时间的软件启动过程中,让用户知道软件还在工作,避免用户对其失去信息。。。

    好了,说了那么多废话,就来看看我是怎么制作这样一个程序的,由于本人平时基本上都用Delphi来开发,所以以下代码也都是Delphi的,但是基本框架有了,相信要用其它语言实现也不会很难。另外,以下这些代码是我在过去的历次开发过程中组部提炼出来的,虽然还无法达到不修改即使用的地步,但是要修改的内容也不会很多。。

    我的这个类叫做TAppLoader,首先要做的是,让它接管部分程序的初始化工作。
    将工程dpr文件中的启动代码写成这样:
    var
      GAppLoader:TAppLoader;

    begin
      Application.Initialize;
      GAppLoader:=TAppLoader.Create();
      try
        if GAppLoader.DoLoad() then begin
          Application.Run;
        end;
      finally
        GAppLoader.Free;
      end;
    end.
    可以看到,所有的启动代码都在TAppLoader.DoLoad()函数中了,如果这个函数失败,则会返回false,此时就跳过Application.Run();过程,直接跳出程序。
    接下来,来看一下这个类的定义:
      TAppLoader = class (TObject)
      private
        FSplashForm: TfrmSplash;
        FManagerList:TList;
      protected
        procedure InitializeManager(var AManager;AManagerClass:TCustomManagerClass);
        procedure OnAppLoading(ASender:TObject;AEvent:String;ADelay:Integer=5);
      public
        constructor Create();
        destructor Destroy(); override;
        function DoLoad: Boolean;
      end;

    除了刚才说到的DoLoad()函数外,还可以看到这么两个函数:InitializeManager()和OnAppLoading()。
    在说明InitializeManager()函数前,需要先介绍这么一个类:
      TCustomManagerClass = class of TCustomManager;

      TCustomManager = class(TObject)
      private
        FOnAppLoading:TAppLoadingEvent;
      protected
        procedure Initialize();virtual;abstract;
        procedure Finalize();virtual;abstract;
        procedure DoAppLoading(AEvent:String);
        property OnAppLoading:TAppLoadingEvent read FOnAppLoading write FOnAppLoading;
      public
        constructor Create();virtual;
      end;
    在我的程序中,将所有的全局的资源管理类都叫做TxxxManager,而TCustomManager就定义了这些类的一些基本行为。说道这里,可能还有必要解释一下什么是资源管理类,说白了,也就是将整个软件运行期需要经常访问的资源、使用的功能都集中起来管理,比如我将数据库连接叫做:TDataManager,将串口通讯功能类叫做:TCommManager,等等。。。

    这个基类定义了Initialize()和Finalize()两个虚方法,是用来让TAppLoader启动或关闭服务用的,这两个方法不同与构造与析构函数,它们初始化的不是类本身的资源,而是一些外部连接资源,(比如网络连接,文件句柄,串口端口等等),它们可以允许在不销毁对象的前提下,进行重新连接,也就是说,除了在TAppLoader中会调用Initialize()和Finalize()方法,你也可以在软件的使用过程中调用这两个方法,(比如用户选择了新的串口端口号)。

    接着,可以看到TCustomManager中有一个OnAppLoading事件,在Initialize()的过程中,实际的Manager类就可以调用该方法,在启动画面上显示文字了。该事件实际会调用TAppLoader.OnAppLoading()方法,它的代码如下:
    procedure TAppLoader.OnAppLoading(ASender:TObject;AEvent:String;
            ADelay:Integer);
    begin
      if Assigned(FSplashForm) then begin
        if Assigned(ASender) then begin
          FSplashForm.lbl1.Caption:=ASender.ClassName+': '+AEvent;
        end
        else begin
          FSplashForm.lbl1.Caption:=AEvent;
        end;
        FSplashForm.Update;
        if ADelay>0 then
          Sleep(ADelay);
      end;
    end;
    其中FSplashForm就是启动画面了,在TAppLoader.DoLoad()中调用各个Manager的Initialize()方法时,这些Manager会根据自身当前初始化的内容,回调这个OnAppLoading()函数,此时就可以在启动画面上显示文字了。

    实际的Manager类中只要调用DoAppLoading()方法,就可以将文字显示到启动画面上了,如:
    procedure TFileImageManager.Initialize();
    var
      Directory:String;
      FindHandle:THandle;
      FindFileData:TWin32FindData;
    begin
      Directory:=ExtractFilePath(ParamStr(0))+'decoders\';
      FindHandle:=FindFirstFile(PChar(Directory+'*.dcd'),FindFileData);
      if FindHandle = INVALID_HANDLE_VALUE then
        exit;
      repeat
        if (FindFileData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY)<>FILE_ATTRIBUTE_DIRECTORY then begin
          DoAppLoading('Loading ' + FindFileData.cFileName);
          AddDecoder(Directory+FindFileData.cFileName);
        end;
      until not FindNextFile(FindHandle,FindFileData);
      Windows.FindClose(FindHandle);
    end;

    TAppLoader中还有这么一个函数:
    procedure TAppLoader.InitializeManager(var AManager;AManagerClass:TCustomManagerClass);
    var
      Instance: TCustomManager;
    begin
      Instance := TCustomManager(AManagerClass.NewInstance);
      TCustomManager(AManager) := Instance;
      try
        Instance.Create();
        FManagerList.Add(@AManager);
        Instance.OnAppLoading:=OnAppLoading;
        Instance.Initialize();
        Instance.OnAppLoading:=nil;
      except
        TCustomManager(AManager):= nil;
        raise;
      end;
    end;
    它用来启动一个Manager,并将其加入TAppLoader的一个FManagerList列表中,在TAppLoader析构时,它会自动按照这个列表,来释放所有的Manager。
    在Manager的Initialize()结束后,比较保险的是将它的OnAppLoading重新设为空,这样如果在程序运行过程中,由其它功能来调用Manager的Initialize()时,就不会再回调到显示启动文字的部分了。

    最后,看一下DoLoad()函数:
    function TAppLoader.DoLoad: Boolean;
    begin
      Result:=false;
      Application.Title:='Ultra Album';
      FSplashForm:=TfrmSplash.Create(nil);
      try
        try
          FSplashForm.Show;
          OnAppLoading(nil,'Starting...');
          Sleep(100);

          InitializeManager(GOptionManager,TOptionManager);
          InitializeManager(GRdItemClassManager,TRdItemClassManager);
          InitializeManager(GImageManager,TFileImageManager);
          InitializeManager(GThemeManager,TFileThemeManager2);
          InitializeManager(GMaskManager,TFileMaskManager);

          OnAppLoading(nil,'Ending...',0);

          Application.CreateForm(TfrmMain, frmMain);
          if ParamCount>=1 then begin   //deal with the filename in the parameter
            FSplashForm.Hide;
            frmMain.Show;
            frmMain.DoOpenFile(ParamStr(1));
          end;

          Result:=true;
        except
          on E:Exception do begin
            MessageBox(Application.Handle,PChar(E.ClassName+':'+#13+#10+E.Message),
                PChar(Application.Title),MB_ICONERROR);
          end;
        end;
      finally
        FreeAndNil(FSplashForm);
      end;
    end;
    这个函数是我的一个软件中的代码,它首先构造并显示一个启动画面,然后使用InitializeManager()分别初始化了5个Manager类,其中的GOptionManager,GRdItemClassManager。。。都是全局对象,在今后需要访问时,都使用这个全局对象来进行访问,这里我没有使用Singleton模式,因为我觉得这几个对象都必须在程序主窗体创建前完全初始化,而Singleton的设计思路是在对象第一次使用时才创建它的实例,在我的这个使用中不需要这样的功能。当然,你也可以自己改造这些Manager类成为Singleton的,改动代码不会很多。
    最后,再将程序的主界面创建出来,可以看到这个主界面的创建代码就是我们从dpr文件中删除的那行。

    字体:
     
    设为主页 收藏本站 联系我们 友情连接 商务合作 网友留言
    Copyright©2006-2008 中华网络安全联盟 All rights reserved.