Home
Manage Your Code
Snippet: Compact Framework 1.0: Splash Screen (C#)
Title: Compact Framework 1.0: Splash Screen Language: C#
Description: A useful splash screen for any Compact Framework 1.0 application! :) Views: 687
Author: Diego Guidi Date Added: 5/3/2006
Copy Code  
1using System;
2using System.Drawing;
3using System.Drawing.Imaging;
4using System.Collections;
5using System.ComponentModel;
6using System.Windows.Forms;
7using System.Reflection;
8using System.IO;
9using System.Runtime.InteropServices;
10
11namespace TerraNova.PocketShArc
12{
13	/// <summary>
14	/// Summary description for SplashForm.
15	/// </summary>
16	public class SplashForm : System.Windows.Forms.Form
17	{
18		public static System.Drawing.Image GetImage(string name) 
19		{
20			System.Reflection.Assembly ea = System.Reflection.Assembly.GetExecutingAssembly();
21			string resourceName = "TerraNova.Resources.Images." + name;
22			Stream stream = ea.GetManifestResourceStream(resourceName);
23			return new System.Drawing.Bitmap(stream);
24		}
25
26		/// <summary>
27		/// A hack constant specifying how many cells the animation has
28		/// </summary>
29		const int kNumAnimationCells = 8;
30
31		/// <summary>
32		/// Splash screen background bitmap
33		/// </summary>
34		Bitmap bmpSplash = null;
35
36		/// <summary>
37		/// Splash screen animation bitmap
38		/// </summary>
39		Bitmap bmpAnim = null;
40
41		/// <summary>
42		/// Current screen position of the animation
43		/// </summary>
44		Rectangle animPos = new Rectangle(0,0,0,0);
45
46		/// <summary>
47		/// Graphics object used to render splash screen.
48		/// Cached for performance.
49		/// </summary>
50		Graphics g = null;
51
52		/// <summary>
53		/// The region of the screen filled by the background.
54		/// Cached for performance.
55		/// </summary>
56		Rectangle splashRegion = new Rectangle(0,0,0,0);
57
58		/// <summary>
59		/// The source region of the background draw.
60		/// Cached for performance.
61		/// </summary>
62		Rectangle splashSrc = new Rectangle(0,0,0,0);
63
64		/// <summary>
65		/// Image attributes specifying transperancy color.
66		/// Cached for performance.
67		/// </summary>
68		ImageAttributes attr = new ImageAttributes();
69
70		/// <summary>
71		/// Timer used to update the screen at regular intervals.
72		/// </summary>
73		System.Threading.Timer splashTimer = null;
74
75		/// <summary>
76		/// Source region for redrawing the background.
77		/// Cached for performance.
78		/// </summary>
79		Rectangle redrawSrc = new Rectangle(0,0,0,0);
80
81		/// <summary>
82		/// Current cell being displayed in the animation.
83		/// </summary>
84		int curAnimCell = 0;
85
86		/// <summary>
87		/// The number of updates that the splash screen timer triggered.
88		/// </summary>
89		int numUpdates = 0;
90
91		/// <summary>
92		/// Time between screen updates (ms)
93		/// </summary>
94		int timerInterval_ms = 0;
95
96		/// <summary>
97		/// Constructor for the splash screen form.  Creates the background
98		/// and animation Bitmap objects
99		/// </summary>
100		/// <param name="timerInterval">Length of time between screen updates (ms)</param>
101		public SplashForm(int timerInterval)
102		{
103			// Store the timer interval
104			timerInterval_ms = timerInterval;
105
106			// Load the embedded splash image resources			
107			bmpSplash = new Bitmap(GetImage("ShArc.bmp"));
108			bmpAnim = new Bitmap(GetImage("anim.bmp"));
109
110			//
111			// Required for Windows Form Designer support
112			//
113			InitializeComponent();
114
115		}
116
117		/// <summary>
118		/// Clean up any resources being used.
119		/// </summary>
120		protected override void Dispose(bool disposing)
121		{
122			base.Dispose(disposing);
123		}
124		#region Windows Form Designer generated code   ...		#endregion
139
140		/// <summary>
141		/// Return the amount of time the splash screen has been displayed in
142		/// milliseconds.  This is based on the number of times the timer has
143		/// triggered and the interval of the timer.  This is not completely
144		/// accurate but good enough for the purposes of this function.
145		/// </summary>
146		/// <returns></returns>
147		public int GetUpMilliseconds()
148		{
149			return numUpdates * timerInterval_ms;
150		}
151
152		/// <summary>
153		/// The form is ready to be displayed so initialize all of the
154		/// splash screen data and draw the first frame.
155		/// </summary>
156		/// <param name="sender">Sending object</param>
157		/// <param name="e">Event arguments</param>
158		private void SplashForm_Load(object sender, System.EventArgs e)
159		{
160			// Make the form full screen
161			this.Text = "";
162			this.MaximizeBox = false;
163			this.MinimizeBox = false;
164			this.ControlBox = false;
165			this.FormBorderStyle = FormBorderStyle.None;
166			this.WindowState = FormWindowState.Maximized;
167			this.Menu = null;
168
169			// Center the splash screen background
170			splashRegion.X = (Screen.PrimaryScreen.Bounds.Width - bmpSplash.Width) / 2;
171			splashRegion.Y = (Screen.PrimaryScreen.Bounds.Height - bmpSplash.Height) / 2;
172			splashRegion.Width = bmpSplash.Width;
173			splashRegion.Height = bmpSplash.Height;
174
175			// Set up the rectangle from which the background will be drawn
176			splashSrc.X = 0;
177			splashSrc.Y = 0;
178			splashSrc.Width = bmpSplash.Width;
179			splashSrc.Height = bmpSplash.Height;
180
181			// Set up the destination region of the animatino draw 
182			animPos.X = splashRegion.X - bmpAnim.Width / kNumAnimationCells;
183			animPos.Y = splashRegion.Y + splashRegion.Height - bmpAnim.Height;
184			animPos.Width = bmpAnim.Width / kNumAnimationCells;
185			animPos.Height = bmpAnim.Height;
186			
187
188			// Initialize the draw region used to optimize animation updates
189			redrawSrc.Width = bmpAnim.Width / kNumAnimationCells;
190			redrawSrc.Height = bmpAnim.Height;
191
192			// Cache the transparent color
193			attr.SetColorKey(bmpAnim.GetPixel(0,0), bmpAnim.GetPixel(0,0));
194		
195			// Create the graphics object and set its clipping region
196			g = CreateGraphics();
197			g.Clip = new Region(splashRegion);
198
199			// Draw the screen once with the full background update
200			// No need to use Application.DoEvents to force OnPaint.
201			Draw(true, false);
202
203			// Start a timer that will call Draw every 200 ms
204			System.Threading.TimerCallback splashDelegate = new System.Threading.TimerCallback(this.Draw);
205			this.splashTimer = new System.Threading.Timer(splashDelegate, null, timerInterval_ms, timerInterval_ms);
206		}
207
208		/// <summary>
209		/// If a paint event is generated then redraw the splash screen
210		/// </summary>
211		/// <param name="e"></param>
212		protected override void OnPaint(PaintEventArgs e)
213		{
214			Draw(true, false);
215		}
216
217		/// <summary>
218		/// Do not respond to paint background events
219		/// </summary>
220		/// <param name="e"></param>
221		protected override void OnPaintBackground(PaintEventArgs e){}
222
223		/// <summary>
224		/// Kill this form
225		/// </summary>
226		/// <param name="o">Not used</param>
227		/// <param name="e">Not used</param>
228		public void KillMe(object o, EventArgs e)
229		{
230			// Stop the timer first so there are no racing issues
231			splashTimer.Dispose();
232
233			// Shut down the form
234			this.Close();
235		}
236
237		/// <summary>
238		/// Draw the screen.  This is the callback for the timer
239		/// </summary>
240		/// <param name="state">Not used - timer data</param>
241		protected void Draw(Object state)
242		{
243			numUpdates++;
244
245			Draw(false, true);
246		}
247
248		/// <summary>
249		/// Draw the screen
250		/// </summary>
251		/// <param name="bFullImage">true if the entire background should be updated</param>
252		/// <param name="bUpdateAnim">true if the animation position and cell should be updated</param>
253		protected void Draw(bool bFullImage, bool bUpdateAnim)
254		{
255			if (g == null)
256				return;
257
258			// Make sure it is safe to access the form
259			lock (this)
260			{
261				// Draw the background
262				if (bFullImage)
263				{
264					g.DrawImage(bmpSplash, splashRegion, splashSrc, GraphicsUnit.Pixel);
265				}
266				else if (bUpdateAnim)
267				{
268					// If not drawing the full background then only upate the
269					// location of the animation
270					redrawSrc.X = animPos.X - splashRegion.X;
271					redrawSrc.Y = animPos.Y - splashRegion.Y;
272					g.DrawImage(bmpSplash, animPos, redrawSrc, GraphicsUnit.Pixel);
273				}
274
275				if (bUpdateAnim)
276				{
277					// Update the current animation cell
278					curAnimCell++;
279					if (curAnimCell >= kNumAnimationCells)
280						curAnimCell = 0;
281
282					// Move the animation (yes hard-coded for the example)
283					animPos.X += 5;
284					if (animPos.X > splashRegion.X + splashRegion.Width)
285						animPos.X = splashRegion.X - bmpAnim.Width / kNumAnimationCells;
286				}
287
288				// Draw the animation
289				g.DrawImage(bmpAnim, animPos, curAnimCell * bmpAnim.Width / kNumAnimationCells, 0, bmpAnim.Width / kNumAnimationCells, bmpAnim.Height, GraphicsUnit.Pixel, attr);
290			}
291		}
292	}
293}
294
Usage
static private void StartSplash()
{		
	splash = new SplashForm(50);
	Application.Run(splash);
}

static private void CloseSplash()
{
	if (splash == null) return;

	splash.Invoke(new EventHandler(splash.KillMe));
	splash.Dispose();
	splash = null;
}
			
private void MainForm_Load(object sender, System.EventArgs e)
{			
	// Show SplashForm
	Thread splashThread = new Thread(new ThreadStart(StartSplash));
	splashThread.Start();			
	Thread.Sleep(SleepTime);						
	CloseSplash();
}