スプラッシュウィンドウ より:
さて、これを実現するために、僕は今まで Program Class の Main()メソッドでスプラッシュウィンドウを開いていました。
しかし、Application.Run(); でメインフォームを開くまでは不用意なことはできません。
何故なら、Application.Run() によってメッセージポンプが起動されるため、この前に何らかの処理を行おうとすると、メッセージポンプが正常に働かない危険性があるらしいのです。
(この辺りは、僕も詳しくないので、詳細は MSDN 等でご自身で確認して下さい)
その他、関連:スプラッシュスクリーンに物申す、[Tips][WinForm]起動時間が長いウインドウの前フリウインドウ(スプラッシュスクリーン)
ということで、作ってみた。まず、Program.cs
namespace SplashWindowSample {
static class Program {
internal static ApplicationContext ThisContext;
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
ThisContext = new ApplicationContext(new FrmSplash());
Application.Run(ThisContext);
}
}
}
太字が、標準のコードに対して変更した行です。メイン フォームのすげ替えが出来るように、ApplicationContext を用意しました。こいつに、まず、スプラッシュ ウインドウをメイン フォームとして表示してもらいます。
次、スプラッシュ ウインドウの方。
namespace SplashWindowSample {
public partial class FrmSplash : Form {
public FrmSplash() {
InitializeComponent();
Application.Idle += new EventHandler(Application_Idle);
}
void Application_Idle(object sender, EventArgs e) {
Application.Idle -= Application_Idle;
FrmMain frm = new FrmMain();
frm.Shown += new EventHandler(frm_Shown);
Program.ThisContext.MainForm = frm;
frm.Show();
}
void frm_Shown(object sender, EventArgs e) {
this.Close();
}
}
}
コンストラクタで、「アプリケーションがアイドル状態になったとき」のイベントを拾うようにしました。なぜ?コンストラクタや Shown, Load イベントで時間のかかる処理をやると、場合によってはスプラッシュ ウインドウの描画が完了しないうちに時間がかかる処理に入ってしまったので。はい、描画が止まります。他のウインドウを、上に重ねないでください。
アイドル処理の最初で、登録したイベントを削除し、二度と通らないようにしておきます。そして、本当のメイン フォームを作成します。表示が完了したときに、スプラッシュウインドウを消せるように、イベントをハンドルします。メイン フォームのすげ替えを行ってから、表示させます。
ん。。。internal でも、ApplicationContext を外部公開するのはやだなぁ。まぁ、サンプルということで。
とりあえず、このソリューションに追加してみた(作りかけのプロジェクトもあるので注意)。サンプルは、あくまでサンプルです。この意味がわからない人は、使わないでください。
投稿日時 : 2007年1月12日 21:49