[C#] Splash Window 띄우기

2013. 12. 27. 10:58Coders

오늘은 C# 에서 Splash Window 를 띄우는 코딩을...

어쩌다 보니 아직 공통 컨트롤로서 확립되지 않아 자주 만들게 되는데, 간단하게 정리해도 좋지 싶어서 포스팅 합니다.


디자인 코드는 따로 넣지 않았습니다. 디자인은 대충 폼 만들고, FormBorderStyle 을 None 등의 값을 주고, Label 하나 올려서 "기다려 주세요..." 정도 써 넣으면 되고요, PictureBox 올려서 ajax loader gif 그림 올리면 뭐 대충 완성이거든요.


ajax loader 는? 이런 걸 말 합니다. => 링크

중요한 건, 제대로 보여주기 위해, Thread 를 따로 만들어서 띄운다. 입니다.

그리고, 호출하고, 닫는 애를 Static Method 로 만들어 두었기 때문에 호출하는 곳에서는 그냥

SplashWnd.SplashShow(); 로 띄우고,

SplashWnd.SplashClose(this); 로 닫으면 됩니다.(this 는 WinForm)

잘 응용하면, 중간에 진행 상태(ProgressBar)를 넣을 수도 있고, 텍스트도 바꿔치기 할 수 있겠죠.


소스 나갑니다.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Runtime.InteropServices;

namespace WithSoju.Common.Forms
{
	/// 
	/// 스플래쉬 윈도우
	/// 
	public partial class SplashWnd : Form
	{
		#region Static Function

		/// 
		/// 스플래쉬 닫을 때 true로 세팅하는 값
		/// 
		private static bool isCloseCall = false;

		/// 
		/// 스플래쉬 띄우기
		/// 
		public static void SplashShow()
		{
			System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess();
			Control mainWindow = Control.FromHandle(process.MainWindowHandle);

			isCloseCall = false;
			Thread thread = new Thread(new ParameterizedThreadStart(ThreadShowWait));
			thread.Start(new object[] { mainWindow });
		}

		/// 
		/// 스플래쉬 닫기
		/// 
		/// 스플래쉬를 닫은 후 맨 앞으로 가져올 폼
		public static void SplashClose(Form formFront)
		{
			//Thread의 loop 를 멈춘다.
			isCloseCall = true;

			//주어진 폼을 맨 앞으로
			SetForegroundWindow(formFront.Handle);
			formFront.BringToFront();
		}

		/// 
		/// 윈도우를 맨 앞으로 가져오기 위한 Win32 API 메서드
		/// 
		/// 윈도우 핸들
		/// 
		[DllImport("user32.dll")]
		private static extern bool SetForegroundWindow(IntPtr hWnd);

		/// 
		/// 스플래쉬를 띄우기 위한 Parameterized Thread Method
		/// 
		/// 메인 윈도(위치를 잡기 위해)
		private static void ThreadShowWait(object obj)
		{
			object[] objParam = obj as object[];
			SplashWnd splashWnd = new SplashWnd();
			Control mainWindow = objParam[0] as Control;

			if (mainWindow != null)
			{
				//메인 윈도를 알 때에는 메인 윈도의 중앙
				splashWnd.StartPosition = FormStartPosition.Manual;
				splashWnd.Location = new Point(
					mainWindow.Location.X + (mainWindow.Width - splashWnd.Width) / 2,
					mainWindow.Location.Y + (mainWindow.Height - splashWnd.Height) / 2);
			}
			else
			{
				//메인 윈도를 모를 땐 스크린 중앙
				splashWnd.StartPosition = FormStartPosition.CenterScreen;
			}

			splashWnd.Show();
			splashWnd.BringToFront();

			//닫기 명령이 올 때 가지 0.01 초 단위로 루프
			while (!isCloseCall)
			{
				Application.DoEvents();
				Thread.Sleep(10);
			}

			//닫는다.
			if (splashWnd != null)
			{
				splashWnd.CloseForce();
				splashWnd = null;
			}
		}

		#endregion Static Function


		#region SplashWnd Member, Function, Event

		/// 
		/// 값이 true 이면 창이 닫히지 않음.
		/// 
		private bool cannotClose = true;

		/// 
		/// 생성자
		/// 
		public SplashWnd()
		{
			InitializeComponent();

			//투명도는 줘도 되고 안 줘도 되고
			this.Opacity = 0.7f;
		}

		/// 
		/// 사용자가 ALT+F4 등의 키로 닫는 걸 방지
		/// 
		/// 
		protected override void OnClosing(CancelEventArgs e)
		{
			if (cannotClose)
			{
				e.Cancel = true;
				return;
			}

			base.OnClosing(e);
		}

		/// 
		/// 이 메서드를 호출해야만 창이 닫힌다.
		/// 
		public void CloseForce()
		{
			//OnClose 에서 닫힐 수 있도록 세팅
			cannotClose = false;
			this.Close();
		}

		#endregion SplashWnd Member, Function, Event
	}
}