Splash屏幕开发(适合新手)

                   
我们在执行一个Windwos应用程序后,程序通常会首先显示出一个Splash屏幕。应用程序开发人员可利用该屏幕显示与程序有关的重要信息,如程序的名称、版本及徽标、或其他形式的商标(或产品)标记。Splash屏幕用于使用确认应用程序已经启动,同时还可以避免程序在启动以及完成初始化任务的过程中引起的烦躁。
通常需要开发的最重要的组件是基本的Splash屏幕窗体。该窗体将具有Splash屏幕的物理特性(如无控制框、无标题栏、位于计算机屏幕的中间等)。可以通过代码提供下面三种关闭Splash屏幕的方式:
1. 当用户单击它时关闭
2. 经过一定时间后关闭
3. 通过Splash屏幕之外的代码告诉它不显示时关闭
为给应用程序添加一个Splash屏幕,应创建一个继承于基本窗体的窗体,并给窗体添加与应用程序对应的外观与功能。所创建的Splash屏幕会继承所有这些功能,为使Splash屏幕能够完成所有工作且不会阻塞希望在程序启动例程中运行的代码,Splash屏幕需要在一个线程上运行,并与运行应用程序其余代码的主线程分离。窗体可以创建线程,但窗体不能在它所创建的线程上运行。为使窗体在线程上运行。为使窗体在线程上运行,首先应创建线程,而后窗体就可以在线程上实例化。本实验将创建一个SplashScreenController类,以放置完成此任务的代码。SplashScrrenController类是重点内容。该类将包装SplashScreen窗体,并封装所有线程创建过程与处理逻辑。根据功能需要,SplashScreenController类将只提供Show()和Hide()方法。由于此处涉及的内容只是简单的方法调用,因此我们开发人员很容易理解。Show()方法将创建一个线程,并将splash屏幕在该线程上运行。Hide()方法将调用要在线程上运行的SplashScreen窗体,以隐藏窗体并结束线程。如果需要给splash屏幕加入更多的方法,则应在SplashScreenController类中包装它们并以方法的形式提供并不需要在同一时间显示多个splash屏幕。通过提供一个私有构造函数,并使Show()和Hide()方法为Shared方法,可以使SplashScreenControll为不可实例化的类,这样即可实现在同一时间不显示多个splash屏幕。然后,加入对应的代码就可以防止SplashScreenController类创建了一个线程后再创建另一个线程。
具体实现:
1. 在一个新解决方案中,创建一个名为SplashScreen的类库项目,所创建的项目有两个组件:一个是用于提供基本splash屏幕的Windows Form类,另一个是用于提供线程创建支持的非可视化类SplashScreenController类。首先开发splash屏幕窗体。向名为SplashScreen的项目添加一个取名为(SplashScreen.vb)Windons Form,从Windows Form工具箱中向窗体添加一个计时器,将其名称更该为Timer,并设置如下属性:
SplashScreen.ControlBox=False
SplashScreen.FormBorderStyle=None
SplashScreen.StartPostion=CenterScreen
SplashScreen.TopMost=True
Timer.Modifiers=Protected
这些设置将去掉窗体的边框、标题栏、关闭按钮以及最大、最小化按钮,使其显示成Splash屏幕的形式。将StartPosion设置成CenterScreen可确保窗体被加载并显示在屏幕的中间位置;将TopMost设置成True可保证Splash窗体不会由其他窗体或其他应用程序覆盖;将Timer的Modifiers设置成Protected,可允许继承自该窗体的各个窗体操作Timer控件。
2.下面就是窗体设计器的代码
Namespace nc.UI
Public Class SplashScreen
Inherits System.Windows.Forms.Form
Private cycleCount As Integer = 1
Private maxDisplayTime As Integer = 0
下面给出的HideSplashScreen()方法将由后面介绍的SplashScreenController类激活,它的功能是关闭Splash屏幕。通过关闭窗体可实现此目的。代码如下:
Public Sub HideSplashScreen()
Close()
End Sub
下面的事件处理程序将实现第一种关闭Splash屏幕的方法,调用由.NET Framework所提供的HideSplashScreen()的方法------单击窗体时关闭屏幕。
Private Sub SplashScreen_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Click
            HideSplashScreen()
End Sub
下面的属性和事件处理程序将在窗体上实现超时处理,并为窗体提供一种机制,通过该机制可以跟踪窗体打开了多长时间,以及何时达到所设置的时间并关闭Splash屏幕。
Public WriteOnly Property MaximumDisplayTime() As Integer
            Set(ByVal Value As Integer)
                maxDisplayTime = Value
                Timer.Interval = 1000
                If Value > 0 Then
                    Timer.Start()
                End If
            End Set
End Property
Private Sub Timer_Tick(ByVal sender As System.Object, ByVal e As

System.EventArgs) Handles Timer.Tick
            cycleCount += 1
            If cycleCount > maxDisplayTime Then
                HideSplashScreen()
            End If
        End Sub
    End Class
End Namespace
此时将计时器设置成每秒激活Tick事件一次。上面的代码中,位于Timer_Tick()中的代码用于计算已经执行了多长时间(由于将计时器设置成每秒滴答一次,因此与Splash屏幕显示了多少秒等同)。当Splash屏幕显示的时间超过最大允许时间时,将调用HideSplashScreen()方法。以上介绍的内容就是基类SplashScreen类。该类本身并不做多少工作,但可以通过它创建各种子类,这些子类继承了基类的所有成员(行为)。
3.现在向SplashScreen的项目中添加一个名为SplashScreenControl.vb的新类文件,并替换为下面的代码:
Imports System
Imports System.Threading
Namespace nc.UI
当从另一个线程在Splash屏幕上激活Hide()方法时,将使用这种委托类型。
Public Delegate Sub HideMethod()   ‘声明一个委托类型的方法HideMethod()
以下是SplashScreenControl类的代码。
Public Class SplashScreenControl
下面是为线程和Splash屏幕窗体声明了私有共享变量。由于这些变量是Private(私有的),因此只有类中的代码才能使用它们。又由于这些变量是Shared(共享的)类型,因此不需要类实例化就可以引用它们。这些Private Shared变量以及后面要介绍的Public Shared方法使类为不可实例化类。
        Private Shared splashThread As Thread
        Private Shared mySplashScreen As SplashScreen
        Private Shared maxDisplayTime As Integer
下一步是添加显示Splash屏幕的代码,代码如下:
        Private Shared Sub ShowForm()
            mySplashScreen.MaximumDisplayTime = maxDisplayTime
            mySplashScreen.ShowDialog()
        End Sub
这是一个非常简单的方法。它只是简单地设置了Splash超时(如果有的话),然后再显示出窗体。由于窗体是以对话框形式显示的,因此它会显示在屏幕上,直到关闭为止。该方法需要在线程上执行,因此Splash屏幕要在线程上启动。在启动线程之前,程序代码需要保证Splash屏幕已准备在mySplashScreen变量中显示,且在maxDisplayTime变量中已经存储了适当的屏幕超时值。
下面是用于建立线程的公有方法Show()。该方法用了两个形参:继承了SplashScreen的窗体的实例和指定窗体超时的整数值,如下所示:
 Public Shared Sub show(ByRef aSplashScreen As SplashScreen, ByRef MaxSecondsToDisplaySplash As Integer)
首先,Show()要检查线程是否已经启动。如果已经启动,将抛出一个异常,如下面的代码所示:
If Not splashThread Is Nothing Then
      Throw New InvalidOperationException("Splash screen already showing")
End If
下一步,建立一个启动时将执行ShowForm()方法的线程,其中包括给线程设置名称,以便于程序调试;同时将其设置为后台运行。前台线程会防止过程终止,后台线程则不具备此功能。如果所有前台线程终止而后台线程任然存在的话,则会忽略掉后台线程。对于我们编程人员来说,这意味着如果启动过程中主线程出故障或终止时,Splash屏幕将会消失。
            splashThread = New Thread(AddressOf ShowForm)
            splashThread.Name = "SplashScreenWorker"
            splashThread.IsBackground = True
ShowForm()方法的两个参数的值存储在类的共享变量中,因此它们可由线程访问。这里并没有设置mySplashScreen.MaximumDisplayTime,因为代码正在主线程上执行;而且我们设置的值对线程来说是无效的。
            mySplashScreen = aSplashScreen
            maxDisplayTime = MaxSecondsToDisplaySplash
最后是启动线程。线程以运行状态放置,且当线程计划执行时,通过运行ShowForm()方法开始。
            SplashThread.Start()
        End Sub
SplashScreenControl类中有一个更为重要的方法需要实现,即Hide()方法。Hide()方法允许从主线程中调用,以执行将在线程中运行的代码,此时就是使Splash屏幕消失的指令。Form的Invoke()方法则是实现此功能的关键。该方法的功能是:在拥有此控件的基础窗口句柄的线程上执行指定的委托。
Public Shared Sub Hide()
Dim hideSplashScreen As New HideMethod(AddressOfmySplashScreen.HideSplashScreen)
            Try
                mySplashScreen.Invoke(hideSplashScreen)
            Catch
            End Try
            mySplashScreen = Nothing
   End Sub
在上面的代码中,HideMethod以委托的形式声明,同时分配和实例化了一个包含HideMethod委托的变量,且给它分配了要执行的代码的位置------mySplashScreen对象的HideSplashScreen()方法。然后是调用mySplashScreen.Invoke()方法,传递存放HideMethod委托变量。Invoke()在拥有控件的底层窗口局柄的线程上执行委托。对于编程人员来说,这意味着将在mySpalshScreen线程上执行HideSplashScreen()方法。现已经提供了使Splash屏幕消失的第三种方式:即利用主线程上运行的代码,通过调用Hide()方法来使屏幕消失。
    End Class
End Namespace
现已经完成对Splash屏幕的创建
下面是演示结果:(这个图做得有点丑^_^)

posted on 2005-11-22 09:54  kim  阅读(1315)  评论(0)    收藏  举报

导航