- PR -

スプラッシュウィンドウのフリーズ

投稿者投稿内容
未記入
大ベテラン
会議室デビュー日: 2005/08/25
投稿数: 145
投稿日時: 2007-12-17 19:14
すごい起動が遅くて重いソフトなのでスプラッシュウィンドウをつけようと
以下のようなコードを書きましたが
そのスプラッシュウィンドウもWindowStateをNoneにしているのに
枠が表示されてしまい、応答なしと表示される始末です。
どなたか良い改善策をご存知の方教えていただけるとありがたいです。

using (SPForm sp = new SPForm())
{
sp.Show();
Application.DoEvents();
using (Form1 fr1 = new Form1())//ここがものすごく重いです。
{
Application.DoEvents();
fr1.Show();
Application.DoEvents();
sp.Close();
}
}


[ メッセージ編集済み 編集者: 未記入 編集日時 2007-12-17 19:15 ]
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2007-12-17 19:41
引用:

未記入さんの書き込み (2007-12-17 19:14) より:
すごい起動が遅くて重いソフトなのでスプラッシュウィンドウをつけようと
以下のようなコードを書きましたが
そのスプラッシュウィンドウもWindowStateをNoneにしているのに
枠が表示されてしまい、応答なしと表示される始末です。
どなたか良い改善策をご存知の方教えていただけるとありがたいです。

using (SPForm sp = new SPForm())
{
sp.Show();
Application.DoEvents();
using (Form1 fr1 = new Form1())//ここがものすごく重いです。
{
Application.DoEvents();
fr1.Show();
Application.DoEvents();
sp.Close();
}
}


[ メッセージ編集済み 編集者: 未記入 編集日時 2007-12-17 19:15 ]



マルチ スレッドにしてあげる。

このコードは、何時(どのタイミングで)実行されるのでしょう?

単純簡単にやるなら、
スプラッシュ ウィンドゥをメイン フォームにする
Application.Run のてまえで、Application.Idle イベントをハンドルする処理をいれる。
Application.Idle イベント ハンドラで、まず、イベント通知を削除する。
時間のかかるフォームを作る。
メイン フォームを入れ替える。


こんな感じです。
ブログに書いたことがあるような気もする...
http://blogs.wankuma.com/jitta/archive/2007/01/12/55937.aspx

[ メッセージ編集済み 編集者: Jitta 編集日時 2007-12-17 19:46 ]
未記入
大ベテラン
会議室デビュー日: 2005/08/25
投稿数: 145
投稿日時: 2007-12-17 20:35
DirectXなので以下のようなコードになります。
余計な部分ははしょって書いたので戸惑わせてしまいました。
すいません。

Application.Idleというのがあるのですか。
ありがとうございます。
ちょっと調べてみましたが何だか危なげというか
メモリリークとうい危険もあるようなので
もうちょっと勉強してみたいと思います。

using (SPForm sp = new SPForm())
{
sp.Show();
Application.DoEvents();
using (Form1 fr1 = new Form1())//ここがものすごく重いです。
{
Application.DoEvents();
fr1.Show();
Application.DoEvents();
sp.Close();

while (fr1.Created)
{
//描画する
fr1.Render();
Application.DoEvents();
}
}
}
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2007-12-18 11:06
引用:

未記入さんの書き込み (2007-12-17 20:35) より:

Application.DoEvents();
Application.DoEvents();
Application.DoEvents();


DoEvents メソッドがこのタイミングで必要でしょうか? InValidate メソッド -> Update (Refresh) メソッドならわかりますけども。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
未記入
大ベテラン
会議室デビュー日: 2005/08/25
投稿数: 145
投稿日時: 2008-01-13 00:36
Jittaさんご回答ありがとうございます。

ただ、Application.Idleがどういうタイミングで発生するイベントか
MSDNを読んでもよくわからないのです。
よろしければご説明いただければ嬉しいです。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2008-01-16 23:01
 ん〜?確かに、MSDN の説明、わかりにくいですね。
引用:

アプリケーションが処理を完了し、アイドル状態に入ろうとすると発生します。
Occurs when the application finishes processing and is about to enter the idle state.


 「処理を完了」って、何だよ...って感じですね。
 この「処理」は、描画やユーザ(開発者)指定の処理を指しています。それらが完了し、メッセージ バッファに処理すべきメッセージがなくなった状態を指しています。ここで Idle イベントが発生し、ハンドラの処理後、メッセージを受け取るまでアイドル状態になります。
 しかし、Application.Run されていないなら、Idle イベントは発生しません。起動していないので、「待ち」状態というものがありません。

 ところで、再度、「このコードは、何時(どのタイミングで)実行されるのでしょう?」
 「どのタイミングで」というのは、「起動直後」とか、「フォームが出ているときにユーザが何かの指示をしたとき」いう、時間軸が必要です。2007-12-17 20:35 の投稿では、時間軸がわかりません。
 「スプラッシュなんだから、起動時ってわかるだろう?」というご意見ももっともですが、起動後といっても、様々な「タイミング」があります。具体的には、main エントリに入ってからどの段階で実行されるのかを知りたかったのですが。
 もっと具体的に書くと、DirectX だと、Application.Run でメッセージポンプを起動するようなことはできないのでしょうか。while 文でぶん回しながら Form.Render を呼んであげないといけないのでしょうか?そうでないなら、次のようなコードでいけると思います。(未確認)
コード:
static class Program {
    static ApplicationContext ThisContext;

    static void Main() {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        // スプラッシュ フォームを作る
        ThisContext = new ApplicationContext(new SPForm());
        // Idle イベント ハンドラを追加する
        Application.Idle += new EventHandler(ChangeMainForm);
        // アプリケーションを開始する
        Application.Run(ThisContext);
    }

    void ChangeMainForm(object sender, EventArgs e) {
        // イベント ハンドラを削除する
        Application.Idle -= new EventHandler(ChangeMainForm);
        // 本当のメイン フォームを作る
        Form1 fr1 = new Form1();
        // スプラッシュを待避して、
        Form spf = ThisContext.MainForm;
        // メイン フォームを差し替え、
        ThisContext.MainForm = fr1;
        fr1.Show();
        // スプラッシュ フォームを閉じる
        spf.Close();
    }
}


未記入
大ベテラン
会議室デビュー日: 2005/08/25
投稿数: 145
投稿日時: 2008-01-16 23:13
Jittaさん。パーフェクトな回答過ぎて嬉しい限りです。
本当にありがとうございます。

DirectXはWhileぶんまわししなきゃならないんです。
これで、画像を毎回変えて動くように見せているので。
なので、世の中に出回っているスプラッシュウィンドウの
やり方だとできないのです。

Application.Runするとそこで処理が止まってしまうので。
何かいい方法が無いかと考えあぐねております。

[ メッセージ編集済み 編集者: 未記入 編集日時 2008-01-16 23:23 ]

[ メッセージ編集済み 編集者: 未記入 編集日時 2008-01-16 23:30 ]
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2008-01-17 19:09
じゃぁ、最初に書いた、スレッドを分ける。

あるいは、プロセスを分けるのが簡単かも?スプラッシュ プロセスに対してメッセージを送り、終わってもらえばいい。

スキルアップ/キャリアアップ(JOB@IT)