Cハ作成起動画面


記事のソース:http://www.codeproject.com/Articles/3542/How-to-do-Application-Initialization-while-showing?rp=/KB/cs/AppLoadingArticle/AppLoading1.zip
Version A(Quick'n Dirty): Download demo project-32 KbVersion B(Multi Threaded): Download demo project-32 KbC#创建启动画面_第1张图片
Update 28.01.03
This artic has been udated with クリスAustin's suggaestion(Thanks Chris!And thanks to) Phil Bolduc for the fix on Chris'stuff;)and an alternative(multithreaded)appapph has been added,based on Jabes idea(Thanks Jabes!)
Introduction
This articales shows how to display a splash screen during your appication initiazation.This article assis that You famirr with C碊and the Vs.NET IDE.
Background
I had put the lot of my initiazation code into the main forms  OnLoad() Everride.The code parsed configration files、created control and the such.When mmyapaplication startup、it looked like a mess:The man aaaapaplication form jusdn't pop up pniniely Spready Spready Spreadytoused Stadedededededededededededededededededettttttttttttttttttttttttttttttttttshshshshshshshshsh.dededededededededededededededededededededededededededewas shown,I wanted to do my initialization and once that was done、I'd hide the splash screen and show the main appication window.This article contains various apphes on how it can be realzed.
Version A:Quick'n Dirty
This version was the quick and dirty solution I came up with.Crediits to クリスAustin for suggaesting the usage of theApplicationContext クラス.
Preparations
Create a new empty Windows FormsプロジェクトAdd a new Form.1.Moving the Appplications entry procedure
This is not required、but helps a begining developer undent that the  Main() entry point and the Form 1 class into which it is put by default are not necessary coupled.So let's create a new class cared Ap Loader and put the ntry point in the.Onece done,the class shast shound shound look like
public class AppLoader
{
	public AppLoader()
	{
	}
	[STAThread]
	static void Main()
	{
	}
}
Once copleted、remove the code from your Form 1.cs so thyou don't end up having 2 entry points.
2.Creating the Splash Sreen
Just create a new Windows Form,place a PictureBox on it and set a couble of properties just to make it look nivere.The form shound be centred on the screen(StartPosition),be topmost(TopMost)and shoudn'harde.  FormBorderStyle property to Fill and set the  Dock property to your splashイメージ.That's it.In real life,you might want to write some code to display the appication name,it's version,the registered user and a copyright notice,etc.
3.Modifying the MainForm's code
Now we need to some modifications to the Form 1 class.Since some initialization code can be put into the class constructor(such as reading files,etc.)some can't(like creating controls)since  Image is not available in the constructor.So you can't for example add controls to a forms  this collection.Lets add a new public method(e.g.  Controls).This function shound look somewhat like this:
public void PreLoad()
{
	if (_Loaded)
	{
		//	just return. this code can't execute twice!
		return;
	}

	//	do your initialization here
	//	...

	//	flag that we have loaded all we need.
	_Loaded = true;
}
The  public void PreLoad(){...} variable is a prvate book,which shound be initialized to  _Loaded・You definitely SHuld check this flagn your main forms  false override.For example:
protected override void OnLoad(System.EventArgs e)
{
	if (!_Loaded)
	{
		//	good idea to throw an exception here. 
        //    the form shouldn't be shown w/o being initialized!
		return;
	}
}
4.Modifying the AppLoader class
Here is the code for the  OnLoad() class.See the comments for information.
public class AppLoader
{
	private static ApplicationContext context;
	private static SplashForm sForm = new SplashForm();
	private static MainForm mForm  = new MainForm();
	[STAThread]

	static void Main(string[] args)
	{
		//	first we retrieve an application context for usage in the 
        //    OnAppIdle event handler
		context = new ApplicationContext();

		//	then we subscribe to the OnAppIdle event...
		Application.Idle += new EventHandler(OnAppIdle);

		//	...and show our SplashForm
		sForm.Show();

		//	instead of running a window, we use the context
		Application.Run(context);
	}

	private static void OnAppIdle(object sender, EventArgs e)
	{
		if(context.MainForm == null)
		{
			//	first we remove the eventhandler
			Application.Idle -= new EventHandler(OnAppIdle);

			//	here we preload our form
			mForm.PreLoad();

			//	now we set the main form for the context...
			context.MainForm = mForm;

			//	...show it...
			context.MainForm.Show();

			//	...and hide the splashscreen. done!
			sForm.Close();
			sForm = null;
		}
	}
}
Version B:Multihreaded
This version entirely based on Jabes idea.For more information read the Messages below.Thanks again to Jabes for letting me use stuff in this artic!
In this version,the Splash Form is shown in a separate thread and displays the current loading status.You will want to muti-thread splash screen_if it is go to on-screen forantime;by running the splash screen from its own message pmp、screen redraws and other windows messages are processed corectly giving a more professional imprestion.
Preparations
Create a new empty Windows FormsプロジェクトAdd a new Form.Repeat the steps from the previous Section which create the AppLoader clast containing the ntry point for the.Leave the Method Body for  AppLoader emppty for now.Don't forget to remove the  Main() method from the Form 1 code!1.Modify the Splash Form
In order to display the loading status on the form,we need to place a label on the form.For our example we call it l Status Info.Addit a create a get/set Prottynamed Status Info.AthefterStatus Info which maps directly to the Property.The Property implement shound look like this:
public string StatusInfo {
	set {
		_StatusInfo = value;
		ChangeStatusText();
	}
	get {
		return _StatusInfo;
	}
}
Main() is a helper function which will be caled each time the Stuts Info shound be udated.It's implemention shound look like this:
public void ChangeStatusText() {
	try {
		if (this.InvokeRequired) {
			this.Invoke(new MethodInvoker(this.ChangeStatusText));
			return;
		}

		lStatusInfo.Text = _StatusInfo;
	}
	catch (Exception e) {
		//	do something here...
	}
}
The check for the  ChangeStatusText() property is necessary because controlls are not thread safe.So if you cal a method on a control from a different thread(then the one which created the control)without masharing the cal into the properthread,weinghant.
That's it.Let's create the Splasher clast which mantains Thread creation,start and stop.
2.Creating the Splasher class
The static members  InvokeRequired、  Show() and the  Close() property can be used as their names suggaest to show and close the Splash Window as to udate the loading status displayed on the Splash Form(using the)  StatusProperty previously created).
Here is what the implemention of the class look s like:
public class Splasher
{
	static SplashForm MySplashForm = null;
	static Thread MySplashThread = null;

	//	internally used as a thread function - showing the form and
	//	starting the messageloop for it
	static void ShowThread()
	{
		MySplashForm = new SplashForm();
		Application.Run(MySplashForm);
	}

	//	public Method to show the SplashForm
	static public void Show()
	{
		if (MySplashThread != null)
			return;

		MySplashThread = new Thread(new ThreadStart(Splasher.ShowThread));
		MySplashThread.IsBackground = true;
		MySplashThread.ApartmentState = ApartmentState.STA;
		MySplashThread.Start();
	}

	//	public Method to hide the SplashForm
	static public void Close()
	{
		if (MySplashThread == null) return;
		if (MySplashForm == null) return;

		try
		{
			MySplashForm.Invoke(new MethodInvoker(MySplashForm.Close));
		}
		catch (Exception)
		{
		}
		MySplashThread = null;
		MySplashForm = null;
	}

	//	public Method to set or get the loading Status
	static public string Status
	{
		set
		{
			if (MySplashForm == null)
			{
				return;
			}

			MySplashForm.StatusInfo = value;
		}
		get
		{
			if (MySplashForm == null)
			{
				throw new InvalidOperationException("Splash Form not on screen");
			}
			return MySplashForm.StatusInfo;
		}
	}
}
Ok、let’s look at what we have here:
The  StatusInfo method will create a new Thread using the static  Show() function as a target.This function will simply show the Form and start a Message Loop for it.The  ShowThread method will again masharl a call to the Splash Forms  Close() method into the apprate thread thus causing the form to close.The  Close() Property can be used to retrieve or udate the Status Info displayed on the Splash Sreen.
Here are some simple examples of their usage:
...
	//	note that there is no instance required since those functions are static
	Splasher.Show();	//	shows the SplashScreen
        //	sets the status info displayed on the SplashScreen
	Splasher.Status = "Initializing Database Connection...";	
	Splasher.Close();	//	closes the SplashScreen
...
Modifying the AppLoader class
In order to use the Splasher class we to modify our App Loader class appraph:
public class AppLoader
{
	public AppLoader()
	{

	}
	[STAThread]
	static void Main(string[] args)
	{
		Splasher.Show();
		DoStartup(args);
		Splasher.Close();
	}

	static void DoStartup(string[] args)
	{
		//	do whatever you need to do
		Form1 f = new Form1();
		Application.Run(f);
	}
}
First we show the  Status and set the initial  SplashForm text.The n we call  StatusInfoa good place to put any initialization code which doesn't require a form to be created.
Why moving the Startup Code into an extra function you might ask.The answer is simple:Since the Jitter works on a per function basis,it won't need to to to to to to to to to much code before your Splash-Screen is acturythe.sh.sh.sh.sh.sh score sh.sh score sh.sh.
To ensure that after you mail form is loaded、it actually gets focused;you might want to put the follwing statement into the Form 1  DoStartup() override:
this.Activate();