none
モードレスダイアログの表示順番を調べたい RRS feed

  • 質問

  • いつもお世話になっております
    VS2008 でC++/CLIを使ってフォームアプリを作成しています
    モードレスダイアログの表示順番を調べたいと思っています
    ネットで検索してみましたが、情報が見つからず困っています
    (キーワードは、C++/CLI、C#、.NET、Form、表示順 等)

    やりたいことは、MainFormからFormA、FormB、FormC...と複数のモードレスダイアログを開き、
    MainFormの画面を操作したときに、FormA,FormB,FormCの中で1番トップにあるダイアログに対して処理を行いたい、と思っています
    このようなダイアログの表示順番を調べる方法をご教授頂けないでしょうか?

    2012年5月25日 0:49

回答

  •  「アクティブだったWindowのハンドルを求める方法」のような事をして、直前に表示していたフォームを憶えておく、のようなことをすれば良いと思います。

     なお、フォームの表示順は「Z オーダー」といいます(画面上の平面位置である X, Y 軸と、奥行きの Z 軸)。そこで、検索文字列を「ウィンドウ order c++」に変えて検索すると、「ウィンドウを列挙したときのZオーダー」が見つかりました。このスレッド中で言及されている GetWindow 関数の URL は、リンクが切れています。ご注意下さい。


    Jitta@わんくま同盟

    • 回答としてマーク BB-X LARISSA 2012年5月26日 12:43
    2012年5月25日 14:29
  • これも過去に似たような事をやった事があったので(ネイティブアプリでですが)


    WinAPIだとJittaさんのあげられているようにフック系やEnum何々Windows系やGetWindow関数など

    色々と候補はあるのですが

    .NET Frameworkではどうかについては詳しく知らなかったので、コメントを控えていました

    コメントを見た感じやっぱりそのものズバリはないようですね。


    ただ、それらAPIもそれぞれに微妙な制約があったり、例え特定の環境で正常に動いたとしても確実性という点で疑問符(MSDNに明記されていないゆえに、という意味)

    だったり、ちょこっとした事をやりたいだけなのにシステムグローバルな方法で無駄にコストをかけすぎてしまったり、ちょっと気の利いた事をやろうとしたときに仕様上うまくかみ合わず微妙だということになったりする可能性があります。てゆーか高いです。


    なので、私としても自分で記録しておくのが最も確実でシンプルかと思います。


    以前実際に大規模アプリを作っていた時、特定の派生クラスとなる複数のウインドウのZオーダーを正確に把握する必要が生じたときがあったのですが

    その時もやはり自分でウインドウのZ順を記録する方法をとっていました。(そしてそれはその状況下では、最もすんなりいく方法でした)


    ただし、そのためだけにフックをしかけるというのは、少々コストがオーバーな気がしなくもないです。

    その時はウインドウ移動時にZ順が絡むだけであったので、ネイティブサイドのウインドウメッセージのWM_NCLDOWNとかの制御中でちょこっと入れ替えるのみで十分でしたが


    今回の要件で、同様にして

    しかも特定のフォームのうち1番トップにあるものを知りたい

    だけである場合は、これはMainFormが影響を与える側となり、また

    普通に2008 でC++/CLIでフォームを作ったらSystem::Windows::Forms::Formを継承してると思いますので


    ・MainFormに一つFormのハンドル(あるいは目的のフォームがさらに自分のカスタマイズ済みクラスから派生しているなら、その基底クラスのハンドル)をprivateメンバ変数として一つ持たせておくとかしといて

    ・FormA、FormB、FormC...の例えばActivatedが発生したときにMainFormのそのメンバを更新出来るような機構を作っておくとかすればそれだけで済んでしまうように感じます。

    • 回答としてマーク BB-X LARISSA 2012年5月26日 12:43
    • 編集済み mr.setup 2012年5月26日 14:11
    2012年5月25日 22:07

すべての返信

  •  「アクティブだったWindowのハンドルを求める方法」のような事をして、直前に表示していたフォームを憶えておく、のようなことをすれば良いと思います。

     なお、フォームの表示順は「Z オーダー」といいます(画面上の平面位置である X, Y 軸と、奥行きの Z 軸)。そこで、検索文字列を「ウィンドウ order c++」に変えて検索すると、「ウィンドウを列挙したときのZオーダー」が見つかりました。このスレッド中で言及されている GetWindow 関数の URL は、リンクが切れています。ご注意下さい。


    Jitta@わんくま同盟

    • 回答としてマーク BB-X LARISSA 2012年5月26日 12:43
    2012年5月25日 14:29
  • これも過去に似たような事をやった事があったので(ネイティブアプリでですが)


    WinAPIだとJittaさんのあげられているようにフック系やEnum何々Windows系やGetWindow関数など

    色々と候補はあるのですが

    .NET Frameworkではどうかについては詳しく知らなかったので、コメントを控えていました

    コメントを見た感じやっぱりそのものズバリはないようですね。


    ただ、それらAPIもそれぞれに微妙な制約があったり、例え特定の環境で正常に動いたとしても確実性という点で疑問符(MSDNに明記されていないゆえに、という意味)

    だったり、ちょこっとした事をやりたいだけなのにシステムグローバルな方法で無駄にコストをかけすぎてしまったり、ちょっと気の利いた事をやろうとしたときに仕様上うまくかみ合わず微妙だということになったりする可能性があります。てゆーか高いです。


    なので、私としても自分で記録しておくのが最も確実でシンプルかと思います。


    以前実際に大規模アプリを作っていた時、特定の派生クラスとなる複数のウインドウのZオーダーを正確に把握する必要が生じたときがあったのですが

    その時もやはり自分でウインドウのZ順を記録する方法をとっていました。(そしてそれはその状況下では、最もすんなりいく方法でした)


    ただし、そのためだけにフックをしかけるというのは、少々コストがオーバーな気がしなくもないです。

    その時はウインドウ移動時にZ順が絡むだけであったので、ネイティブサイドのウインドウメッセージのWM_NCLDOWNとかの制御中でちょこっと入れ替えるのみで十分でしたが


    今回の要件で、同様にして

    しかも特定のフォームのうち1番トップにあるものを知りたい

    だけである場合は、これはMainFormが影響を与える側となり、また

    普通に2008 でC++/CLIでフォームを作ったらSystem::Windows::Forms::Formを継承してると思いますので


    ・MainFormに一つFormのハンドル(あるいは目的のフォームがさらに自分のカスタマイズ済みクラスから派生しているなら、その基底クラスのハンドル)をprivateメンバ変数として一つ持たせておくとかしといて

    ・FormA、FormB、FormC...の例えばActivatedが発生したときにMainFormのそのメンバを更新出来るような機構を作っておくとかすればそれだけで済んでしまうように感じます。

    • 回答としてマーク BB-X LARISSA 2012年5月26日 12:43
    • 編集済み mr.setup 2012年5月26日 14:11
    2012年5月25日 22:07
  • ありがとうございます

    紹介頂いた直前に表示していたフォームを覚えていくやり方で、Zオーダーを実装できました!”

    APIなどを駆使して実装するものだと思い込んでいたので、小難しく考えていました

    非常に助かりました

    2012年5月26日 12:48
  • ありがとうございます

    APIの制約や確実性を考慮して、自作したほうが良いとのことで

    ご紹介頂いた手法(FormA,B,CのActivatedでオーダー更新)が非常にシンプルで、無事に実装できました

    非常に助かりました

    2012年5月26日 12:51
  •  役に立ったようで良かったです。

     ところで、「フォーム」と検索されていたところを「ウィンドウ」と変えました。このように、単語をちょっと変えるだけで見つけやすくなります。今度は、他の言い回しがないかというところにも気をつけて検索してみてください。

     なお、「検索術」ということでは、古いもので恐縮ですが、「MSDN Library 活用法」(wankuma.com)にある ppt をご覧ください。必ず役に立つはずです。


    Jitta@わんくま同盟

    2012年5月27日 10:35