none
サブダイアログを呼び出した際のコントロールの表示処理の重さ RRS feed

  • 質問

  • いつも大変お世話になっております、鏑木と申します。
    現在、Windows CE 6.0にてVisual Studio 2005 のC++のダイアログベースのアプリケーションを
    開発しております。
    今回もダイアログの表示処理について、分らない箇所があったためこちらにて質問させて頂きます。
    どうぞよろしくお願い致します。

    質問させて頂きたい内容は
    メインダイアログからサブダイアログを呼び出す(モーダル表示)際に、ダイアログ自体はすぐ呼び出される
    のですが、サブダイアログ上のコントロールがダイアログ上に表示される処理が重く、サブダイアログが
    表示された瞬間はコントロールが表示される位置にコンロールではなく、コントロールと同じ大きさにきりぬかれた
    、サブダイアログを呼び出したメインダイアログ(下の絵)が表示されてしまいます。
    これが現在の開発環境であるCEの処理の影響も大きいのかなとも思っております。
    ダイアログに表示されているのは、時間ごとに受信したデータを波形として表示するピクチャーコントロールと
    幾つかのビットマップボタンです。そして、呼び出されるサブダイアログも同様のコントロールが配置されており、
    メインダイアログとの違いは、サブダイアログ全体にビットマップ画像を背景として表示させ、その上に各コントロール
    を配置させています。
    このような状況にて、現在の症状が発生しているのですが、この対処法として、お心当たりがある方がいらっしゃいました
    らご意見を頂けませんでしょうか?
    どうぞよろしくお願いいたします。
    開発環境は
    Windows CE 6.0 R2
    Visual Studio 2005
    です。
    ご回答をお待ちしております。
    2009年10月7日 2:28

回答

  • Atsushi777様のご回答を見ると、波形データの影響で今回のような症状が現れているという印象を受けたのですが
    ピクチャーコントロール上でタイマー処理にて波形を表示させたりする場合にはこのような症状は起きるのでしょうか?
    波形データがどうとかタイマーがどうとかではなくて、
    ピクチャーコントロールがすぐに描画されさえすれば、
    少なくても背景なりがコントロール部分に表示されることはないはずでは?
    ということを言っています。

    >コントロールが作成されたら、波形データを用意する前にまずはコントロールでUpdateWindow()すると、
    >背景だけが初期化されるのだと思うのですけれど。
    ここでいう背景というのは、ダイアログ上の各コントロールの背景のことでしょうか?それともダイアログの背景のことなのでしょうか?

    ダイアログの各コントロールの背景です。
    これがすぐに描画されないために、おかしな表示になっているわけですよね?
    • 回答としてマーク 鏑木肆星 2009年10月23日 2:38
    2009年10月8日 2:21
  • Atsushi777様のご回答を見ると、波形データの影響で今回のような症状が現れているという印象を受けたのですが
    ピクチャーコントロール上でタイマー処理にて波形を表示させたりする場合にはこのような症状は起きるのでしょうか?

    >コントロールが作成されたら、波形データを用意する前にまずはコントロールでUpdateWindow()すると、
    >背景だけが初期化されるのだと思うのですけれど。
    ここでいう背景というのは、ダイアログ上の各コントロールの背景のことでしょうか?それともダイアログの背景のことなのでしょうか?
    UpdateWindow()の処理について調べてみたいと思います。
    どーも、PATIOです。
    イベントドリブンのシステムでは基本的に処理は各イベントから呼び出される関数で処理されますが、
    画面更新等のOS側の処理は各関数から抜けた後、OS側に制御が戻ったタイミングで行なわれます。
    ですから、関数内で長い処理を行っていつまで経っても関数から抜けないと描画が滞ります。
    また、派生したコントロールクラス内に重い処理があっても同じような現象が起きます。

    表示が滞ると言うのは、イベント処理のワンスルー内に重い処理があって関数から抜けるのに
    時間が掛かっている所為だと思いますから、最初の初期表示の時にその重い処理をスキップするようにして
    とりあえず、空の状態でコントロールだけでも表示させてしまうと言うのもひとつの手だと思います。
    重い処理は初期表示の時はスキップして、タイマーイベントだけで処理させるとかですね。

    イベントドリブンのシステムではイベントから呼び出される関数内で重い処理や長い処理を行うのは
    基本的にNGです。これらの処理は画面処理とは別のところ(バックグランド)で行い、
    処理結果だけを画面側に反映するような考え方が必要になります。
    最近ではマシンパワーに任せて重い処理をイベントから呼び出される関数内でするケースも
    あるみたいですが、基本的にはそういう処理はマルチスレッド化してバックグラウンドに持って行くのが
    セオリーだと思います。


    解決した時は、参考になったレスポンスの所にある[回答としてマーク]ボタンをクリックしてスレッドを締めましょう。
    • 回答としてマーク 鏑木肆星 2009年10月23日 2:38
    2009年10月8日 2:45

すべての返信

  • コントロールが作成されたらすぐに背景だけでいいから表示するといいのではないですか?

    2009年10月7日 5:13
  • 表示された瞬間はコントロールが表示される位置にコンロールではなく、コントロールと同じ大きさにきりぬかれた
    、サブダイアログを呼び出したメインダイアログ(下の絵)が表示されてしまいます。
    サブDLGがWS_CLIPCHILDRENだったりしてませんか。

    2009年10月7日 5:22
  • Atsushi777様、いつもご回答ありがとうございます。

    理解力が乏しく申し訳ございません。具体的にどういったことをすればよいのでしょうか?
    2009年10月7日 5:38
  • 仲澤@失業者 様、ご回答ありがとうございます。

    ダイアログのオプションを調べたところ、Clip ChilderenもClip Siblingsもどちらもfalse
    に設定しております。ためしに両方ともtrueにしてみましたが、特に動作は変わりませんでした。
    2009年10月7日 5:45
  • コードの詳細を知らないので何とも言えないところもありますが、
    WM_PAINTのハンドラで波形データが用意されていないときは何も表示しないというコードにしておいて、
    コントロールが作成されたら、波形データを用意する前にまずはコントロールでUpdateWindow()すると、
    背景だけが初期化されるのだと思うのですけれど。
    2009年10月7日 6:33
  • Atsushi777様、ご回答ありがとうございます。

    Atsushi777様のご回答を見ると、波形データの影響で今回のような症状が現れているという印象を受けたのですが
    ピクチャーコントロール上でタイマー処理にて波形を表示させたりする場合にはこのような症状は起きるのでしょうか?

    >コントロールが作成されたら、波形データを用意する前にまずはコントロールでUpdateWindow()すると、
    >背景だけが初期化されるのだと思うのですけれど。
    ここでいう背景というのは、ダイアログ上の各コントロールの背景のことでしょうか?それともダイアログの背景のことなのでしょうか?
    UpdateWindow()の処理について調べてみたいと思います。

    鏑木
    2009年10月8日 0:52
  • Atsushi777様のご回答を見ると、波形データの影響で今回のような症状が現れているという印象を受けたのですが
    ピクチャーコントロール上でタイマー処理にて波形を表示させたりする場合にはこのような症状は起きるのでしょうか?
    波形データがどうとかタイマーがどうとかではなくて、
    ピクチャーコントロールがすぐに描画されさえすれば、
    少なくても背景なりがコントロール部分に表示されることはないはずでは?
    ということを言っています。

    >コントロールが作成されたら、波形データを用意する前にまずはコントロールでUpdateWindow()すると、
    >背景だけが初期化されるのだと思うのですけれど。
    ここでいう背景というのは、ダイアログ上の各コントロールの背景のことでしょうか?それともダイアログの背景のことなのでしょうか?

    ダイアログの各コントロールの背景です。
    これがすぐに描画されないために、おかしな表示になっているわけですよね?
    • 回答としてマーク 鏑木肆星 2009年10月23日 2:38
    2009年10月8日 2:21
  • Atsushi777様のご回答を見ると、波形データの影響で今回のような症状が現れているという印象を受けたのですが
    ピクチャーコントロール上でタイマー処理にて波形を表示させたりする場合にはこのような症状は起きるのでしょうか?

    >コントロールが作成されたら、波形データを用意する前にまずはコントロールでUpdateWindow()すると、
    >背景だけが初期化されるのだと思うのですけれど。
    ここでいう背景というのは、ダイアログ上の各コントロールの背景のことでしょうか?それともダイアログの背景のことなのでしょうか?
    UpdateWindow()の処理について調べてみたいと思います。
    どーも、PATIOです。
    イベントドリブンのシステムでは基本的に処理は各イベントから呼び出される関数で処理されますが、
    画面更新等のOS側の処理は各関数から抜けた後、OS側に制御が戻ったタイミングで行なわれます。
    ですから、関数内で長い処理を行っていつまで経っても関数から抜けないと描画が滞ります。
    また、派生したコントロールクラス内に重い処理があっても同じような現象が起きます。

    表示が滞ると言うのは、イベント処理のワンスルー内に重い処理があって関数から抜けるのに
    時間が掛かっている所為だと思いますから、最初の初期表示の時にその重い処理をスキップするようにして
    とりあえず、空の状態でコントロールだけでも表示させてしまうと言うのもひとつの手だと思います。
    重い処理は初期表示の時はスキップして、タイマーイベントだけで処理させるとかですね。

    イベントドリブンのシステムではイベントから呼び出される関数内で重い処理や長い処理を行うのは
    基本的にNGです。これらの処理は画面処理とは別のところ(バックグランド)で行い、
    処理結果だけを画面側に反映するような考え方が必要になります。
    最近ではマシンパワーに任せて重い処理をイベントから呼び出される関数内でするケースも
    あるみたいですが、基本的にはそういう処理はマルチスレッド化してバックグラウンドに持って行くのが
    セオリーだと思います。


    解決した時は、参考になったレスポンスの所にある[回答としてマーク]ボタンをクリックしてスレッドを締めましょう。
    • 回答としてマーク 鏑木肆星 2009年10月23日 2:38
    2009年10月8日 2:45
  • Atsushi777様、ご回答ありがとうございます。

    ピクチャーコントロールなり、ボタンなり、ダイアログ上のコントロールがすぐに描画されれば、それらコントロールの
    背景をあまり見せずにできますね、確かにそのとおりです。
    コントロールの背景(裏画面)が表示されるために表示がおかしくなっております。

    鏑木
    2009年10月8日 5:21
  • PATIO様、いつもご回答ありがとうございます。

    サブダイアログを呼び出した際のOnInitDialog()内での処理中に、なんらかの重い処理が発生したために、ダイアログの
    描画処理が滞っているということですね。確かにそのとおりです。
    考えてみれば、外部からのデータ受信後に波形を描画する処理をしている場合は、サブダイアログの呼び出しが重く、
    外部からのデータ受信処理を外すと、サブダイアログの呼び出しは軽くなります。

    これから推測するに、サブダイアログ表示時にOnInitDialog()処理中に、データ受信処理や波形表示のメッセージ処理が
    割り込まれるためにダイアログの表示処理が滞ってしまった、と考えることができますね。

    早速、サブダイアログを表示後にデータ受信・波形描画処理メッセージの処理をするようにずらしてみたいと思います。
    2009年10月8日 5:25