程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 給程序添加啟動畫面,程序添加啟動畫面

給程序添加啟動畫面,程序添加啟動畫面

編輯:C#入門知識

給程序添加啟動畫面,程序添加啟動畫面


如果程序在裝載時需要進行較長時間的處理,最好使用啟動畫面,一方面美化程序,一方面可以不使用戶面對著一片空白的程序界面。 
我手頭上一個小項目主界面啟動時需要檢查用戶文件及運行環境是否有效,需要一段時間處理,因此想到要添加一個啟動畫面,在網上搜了一陣,發現下面兩個方案: 

1、用C#給程序加啟動畫面並只允許一個應用程序實例運行 
http://www.zahui.com/html/14/36790.htm 
2、HOW TO:濺射屏幕(Splash Screen),也叫程序啟動畫面的制作(.NET2003) 
http://lzmtw.cnblogs.com/archive/2005/10/31/265782.html 

第一個方案在實現與界面分離上做得不夠好,啟動界面(一個窗體)依賴於特定窗體,主窗體還必須添加一個PreLoad方法完成裝載任務,只能在代碼級重用。而且那個只允許一個實例的寫法也太.... 

第二個方案框架很好,但細微處理可能存在一點問題,需要判斷主窗體的WindowState,整個代碼也較復雜。 

我改動了一下,基本結構仿照第二個方案。 

功能:為程序添加啟動界面,顯示啟動界面的同時加載主窗體,主窗體加載完畢後關閉啟動界面,顯示主窗體。啟動畫面停留的時間是設定的時間和主窗體裝載所需時間兩個的最大值。啟動畫面在另一個線程上運行。 
plus:我的水平還很差,見笑。 

程序代碼如下: 

//啟動窗體虛基類,繼承自ApplicationContext 
using System.Windows.Forms; 
using System.Threading; 
using System; 

//啟動畫面虛基類,啟動畫面會停留一段時間,該時間是設定的時間和主窗體構造所需時間兩個的最大值 
public abstract class SplashScreenApplicationContext : ApplicationContext 

    private Form _SplashScreenForm;//啟動窗體 
    private Form _PrimaryForm;//主窗體 
    private System.Timers.Timer _SplashScreenTimer; 
    private int _SplashScreenTimerInterVal = 5000;//默認是啟動窗體顯示5秒 
    private bool _bSplashScreenClosed = false; 
    private delegate void DisposeDelegate();//關閉委托,下面需要使用控件的Invoke方法,該方法需要這個委托 

    public SplashScreenApplicationContext() 
    { 
        this.ShowSplashScreen();//這裡創建和顯示啟動窗體 
        this.MainFormLoad();//這裡創建和顯示啟動主窗體 
    } 

    protected abstract void OnCreateSplashScreenForm(); 

    protected abstract void OnCreateMainForm(); 

    protected abstract void SetSeconds(); 

    protected Form SplashScreenForm 
    { 
        set 
        { 
            this._SplashScreenForm = value; 
        } 
    } 

    protected Form PrimaryForm 
    {//在派生類中重寫OnCreateMainForm方法,在MainFormLoad方法中調用OnCreateMainForm方法 
        //  ,在這裡才會真正調用Form1(主窗體)的構造函數,即在啟動窗體顯示後再調用主窗體的構造函數 
        //  ,以避免這種情況:主窗體構造所需時間較長,在屏幕上許久沒有響應,看不到啟動窗體       
        set 
        { 
            this._PrimaryForm = value; 
        } 
    } 

    protected int SecondsShow 
    {//未設置啟動畫面停留時間時,使用默認時間 
        set 
        { 
            if (value != 0) 
            { 
                this._SplashScreenTimerInterVal = 1000 * value; 
            } 
        } 
    } 

    private void ShowSplashScreen() 
    { 
        this.SetSeconds(); 
        this.OnCreateSplashScreenForm(); 
        this._SplashScreenTimer = new System.Timers.Timer(((double)(this._SplashScreenTimerInterVal))); 
        _SplashScreenTimer.Elapsed += new System.Timers.ElapsedEventHandler(new System.Timers.ElapsedEventHandler(this.SplashScreenDisplayTimeUp)); 

        this._SplashScreenTimer.AutoReset = false; 
        Thread DisplaySpashScreenThread = new Thread(new ThreadStart(DisplaySplashScreen)); 

        DisplaySpashScreenThread.Start(); 
    } 

    private void DisplaySplashScreen() 
    { 
        this._SplashScreenTimer.Enabled = true; 
        Application.Run(this._SplashScreenForm); 
    } 

    private void SplashScreenDisplayTimeUp(object sender, System.Timers.ElapsedEventArgs e) 
    { 
        this._SplashScreenTimer.Dispose(); 
        this._SplashScreenTimer = null; 
        this._bSplashScreenClosed = true; 
    } 

    private void MainFormLoad() 
    { 
        this.OnCreateMainForm(); 
     
        while (!(this._bSplashScreenClosed)) 
        { 
            Application.DoEvents(); 
        } 

        DisposeDelegate SplashScreenFormDisposeDelegate = new DisposeDelegate(this._SplashScreenForm.Dispose ); 
        this._SplashScreenForm.Invoke(SplashScreenFormDisposeDelegate); 
        this._SplashScreenForm = null;     


        //必須先顯示,再激活,否則主窗體不能在啟動窗體消失後出現 
        this._PrimaryForm.Show(); 
        this._PrimaryForm.Activate(); 
         
        this._PrimaryForm.Closed += new EventHandler(_PrimaryForm_Closed); 

    } 

    private void _PrimaryForm_Closed(object sender, EventArgs e) 
    { 
        base.ExitThread(); 
    } 


使用方法:定義一個啟動類,應用程序從啟動類啟動,該類會使用繼承自啟動窗體虛基類的一個啟動窗體類,在該類中定義啟動窗體和主窗體。啟動窗體和主窗體的代碼略去,注意要刪除機器生成的窗體代碼的Main方法部分。 

    public class StartUpClass 
    { 
        [STAThread] 
        static void Main() 
        { 
            Application.Run(new mycontext()); 
        } 
    } 

    //啟動窗體類(繼承自啟動窗體虛基類),啟動畫面會停留一段時間,該時間是設定的時間和主窗體構造所需時間兩個的最大值 
    public class mycontext : SplashScreenApplicationContext 
    { 
        protected override void OnCreateSplashScreenForm() 
        { 
            this.SplashScreenForm = new FormStart();//啟動窗體 
        } 

        protected override void OnCreateMainForm() 
        { 
            this.PrimaryForm = new FormMain();//主窗體 
        } 

        protected override void SetSeconds() 
        { 
            this.SecondsShow = 2;//啟動窗體顯示的時間(秒) 
        } 
    } 


程序在vs2003下調試通過 


HOW TO:濺射屏幕(Splash Screen),也叫程序啟動畫面的制作(.NET2003) Posted on 2005-10-31 20:40 水如煙(LzmTW) 閱讀(1800) 評論(1)  編輯 收藏 網摘 所屬分類: n、HOW TO系列  --> 
Author:水如煙(LzmTW) 

     看到有人提起,就想動手做做。可能要花兩天時間,因為時間是零零碎碎的。 
     哎,很多常用的東西,在2005版已經有了。當初看到好多人寫基於2003的控件,這2005一出哪,全都沒用了。心血白費了。這微軟未免也太缺德了。應該說,2003是.NET的試用版,到了2005才算是正式版吧。或許基於2005的自寫控件、組件壽命會長一些。否則,不罵娘才怪。 
     現在寫寫,也算是練練習吧。 

     濺射屏幕,即SplashScreenForm,有以下特點: 
     首先,程序是主窗體程序; 
     其次,SplashScreenForm在主窗體加載完畢後退出。 

     一般來說,SplashScreenForm比較簡潔,窗體的內容只是顯示程序主題、版權等信息;復雜些的,顯示主程序的加載項目情況。 
     微軟的SplashScreenForm向來簡潔,Adobe的復雜些,就畫窗體也花了一番心思。以下做的,以微軟的作標准。 

     按照功能實現與界面分離的原則,這個類當然不能依賴於某個特定的SplashScreenForm或MainForm。參考了.NET2005的做法,繼承了System.Windows.Forms.ApplicationContext做了一個SplashScreenApplicationContextClass基類。具體使用時,再繼承這個類賦與特定參數,交Application.Run(ApplicationContext)來運行。因為基礎知識不好,好多東西只知道用而不知為什麼這樣用,免不了的會出現這樣那樣的問題,請指正。 

     總體思路是:濺射屏幕顯示的同時加載主窗體,主窗體加載完畢後關閉濺射屏幕,程序交給主窗體。濺射屏幕顯示的時間由兩個因素決定,一個是事前設定的濺射屏幕顯示的時間,一個是主窗體加載所需要的時間,實際顯示時間是兩者中的最大值。 

     SplashScreenApplicationContextClass為什麼要做為基類設計並要實現?主要考慮到主窗體在初始化時就需要時間,Sub New()是需要時間的,並非所有的程序都將初始事項放到Load()裡頭。 

     
類:     

Imports System.Windows.Forms 
Imports System.Threading 
Public MustInherit Class SplashScreenApplicationContextClass 
    Inherits System.Windows.Forms.ApplicationContext 

    Private _SplashScreenForm As Form 
    Private _SplashScreenTimer As System.Timers.Timer 
    Private _SplashScreenTimerInterVal As Integer = 5000 
    Private _MainFormFinshLoad As Boolean = False 
    Private _MainFormWindowState As Windows.Forms.FormWindowState 
    Private _CloseSplashScreen As Boolean = False 

    Private Delegate Sub DisposeDelegate() 

    Protected WriteOnly Property SplashScreenForm() As Form 
        Set(ByVal Value As Form) 
            Me._SplashScreenForm = Value 
        End Set 
    End Property 

    Protected WriteOnly Property SecondsShow() As Integer 
        Set(ByVal Value As Integer) 
            If Value <> 0 Then 
                Me._SplashScreenTimerInterVal = 1000 * Value 
            End If 
        End Set 
    End Property 


    Sub New() 

        Me.ShowSplashScreen() 
        Me.MainFormLoad() 

    End Sub 

    Private Sub DoEvents() 
        Application.DoEvents() 
    End Sub 

    Protected MustOverride Sub OnCreateSplashScreenForm() 

    Protected MustOverride Sub OnCreateMainForm() 

    Protected MustOverride Sub SetSeconds() 

    Private Sub ShowSplashScreen() 
        Me.SetSeconds() 
        Me.OnCreateSplashScreenForm() 
        Me._SplashScreenTimer = New System.Timers.Timer(CType(Me._SplashScreenTimerInterVal, Double)) 
        AddHandler _SplashScreenTimer.Elapsed, New System.Timers.ElapsedEventHandler(AddressOf Me.SplashScreenDisplayTimeUp) 
        Me._SplashScreenTimer.AutoReset = False 
        Dim DisplaySpashScreenThread As New Thread(New ThreadStart(AddressOf Me.DisplaySplashScreen)) 
        DisplaySpashScreenThread.Start() 
    End Sub 

    Private Sub DisplaySplashScreen() 
        Me._SplashScreenTimer.Enabled = True 
        Application.Run(Me._SplashScreenForm) 
    End Sub 

    Private Sub SplashScreenDisplayTimeUp(ByVal sender As System.Object, ByVal e As System.timers.ElapsedEventArgs) 
        Me._SplashScreenTimer.Dispose() 
        Me._SplashScreenTimer = Nothing 
        Me._CloseSplashScreen = True 
    End Sub 

    Private Sub MainFormLoad() 
        Me.OnCreateMainForm() 
        _MainFormWindowState = Me.MainForm.WindowState '保存主窗體狀態 
        Me.MainForm.WindowState = FormWindowState.Normal '非Normal情形下,主窗體會Show出來
        AddHandler Me.MainForm.Load, New EventHandler(AddressOf Me.MainFormLoadingDone) 
    End Sub 

    Private Sub MainFormLoadingDone(ByVal sender As Object, ByVal e As EventArgs) 
        RemoveHandler Me.MainForm.Load, New EventHandler(AddressOf Me.MainFormLoadingDone) 
        Do While Not Me._CloseSplashScreen 
            Me.DoEvents() 
        Loop 
        Me.HideSplashScreen() 
    End Sub 

    Private Sub HideSplashScreen() 
        MainFormActivate() 
        '先激活主窗體再關閉啟動窗體,是為了保證程序為當前活動程序 
        Dim SplashScreenFormDisposeDelegate As DisposeDelegate = New DisposeDelegate(AddressOf Me._SplashScreenForm.Dispose) 
        Me._SplashScreenForm.Invoke(SplashScreenFormDisposeDelegate) 
        Me._SplashScreenForm = Nothing 
    End Sub 

    Private Sub MainFormActivate() 
        If _MainFormWindowState = FormWindowState.Minimized Then _MainFormWindowState = FormWindowState.Normal 
        If Me.MainForm.WindowState <> _MainFormWindowState Then Me.MainForm.WindowState = _MainFormWindowState 
        Me.MainForm.Activate() 
    End Sub 
End Class 



使用:(SplashScreenForm我還是隨便用一個Form來代替) 

Public Class App 

    Public Shared Sub Main() 
        Dim t As New MyContext 
        Application.Run(t) 
    End Sub 

End Class 

Public Class MyContext 
    Inherits SplashScreenApplicationContextClass 

    Protected Overrides Sub OnCreateMainForm() 
        Me.MainForm = New Form2 
    End Sub 

    Protected Overrides Sub OnCreateSplashScreenForm() 
        Me.SplashScreenForm = New Form1 
    End Sub 

    Protected Overrides Sub SetSeconds() 
        Me.SecondsShow = 3 '顯示3秒,若是0則取默認值5秒 
    End Sub 

End Class 


怎給一個已生成的EXE程序添加啟動畫面?

如果要不解開程序源碼就加啟動畫面
也許只有做成資源文件後內嵌了

補充:
你可以用Delphi來制作一個資源文件
假設你的Exe文件是abc.exe
那麼資源文件可以寫成
Abc ExeFile Abc.exe
然後進行編譯
編譯後使用資源流進行獲取,多做一個OLE Container
讓程序運行就行了
 

怎,給一個c#編寫的小程序加個啟動畫面?

建個Form
樣式設置成None的 裡面用Image放個加載圖片 下面顯示進度條 ,你操作進度條就好了 你可以選擇用進程啊或者BackgroundWorker做這個進度條.
加載時候 有個Opacity(好像是這個吧? 我也記不清了)慢慢變談 完成後就為0 然後銷毀進程 關掉當前Form 顯示主Form
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved