none
ダイアログがアクティブ化できない

    質問

  • MFCで作成したダイアログを表示させた際、Win10環境のみ最前面に出ず、アクティブ化もされません。

    ビルドはVisual Studio2015で行っています。

    SetActiveWindowを使用する、レジストリを弄るといった方法は試しましたがうまくいきませんでした。

    どなたかご存知の方がいらしたらご教授下さい。

    2017年10月3日 7:39

回答

  • ダイアログに限らず、CWndクラスの表示Z-Orderは、原則として次のような配置になります。

    1.ウインドウ作成時に指定された親ウインドウ
      (DLGの場合はコンストラクタで指定している。但しデフォルト引数=NULLとなっているので注意が必要)
     のZ-Orderの前面に配置されます。つまり、親のCWndが指定された場合、子のCWndはその前面側に配置されます。

    2.メインフレームはデスクトップを親として作成されるので、その前面に配置されます。
     デスクトップの裏に配置されることはありません。

    3.異なる親を持つ、子のCWnd間のZ-Orderは、その親の間のZ-Orderに依存して配置されます。

    以上を勘案すると、問題となっているDLGは3.の関係になっているのではないか、という疑いを持ちます。
    例えば、

    (A)一方がメインフレームを親とし、他方がデスクトップを親としている。
    (B)両者ともスクトップを親としている。この場合Z-Orderは後着が前面になるはずです。

    一般に、モーダルDLG同士の、Z-Orderを確実に制御するには、
    一方のDLGを他方のDLGの子として生成します。

    ちなみに、親にNULLを指定した場合でも、それがDLGである場合は、MFCの内部コードが、
    やや涙ぐましい努力で親フレームを探して親としてくれます。
    ただし、見つからなければ(親フレームが生成完了する前にDLGが生成された場合など)デスクトップが親になります。


    • 編集済み 仲澤@失業者 2017年10月4日 4:13
    • 回答としてマーク water00000 2017年10月4日 5:21
    • 回答としてマークされていない water00000 2017年10月4日 5:22
    • 回答としてマーク water00000 2017年10月4日 5:27
    2017年10月4日 4:07

すべての返信

  • 自分が関わっているMFCアプリケーションでは、
    CDialogから派生し、リソーステンプレートではDIALOGEXを使用し、
    CDialog::DoModal()を使用していますが、
    そのような症状は報告されていません。

    また、

    1.「最前面に出ない」とは、メインがZ-Top状態なのにDLGがその背面になる。
    2.「アクティブ化できない」とは、操作可能な状態ににならない。

    ということでしょうか。

    もう少し詳しい前提条件(構成の内容、リソーステンプレートのコード等)、
    また、再現させるための最小限のコードが必要になるかもしれません。

    2017年10月3日 8:07
  • >仲澤さん

    返信が遅れ申し訳ありません。

    情報をありがとうございます。

    1,2に関しましては、

    1.ログイン画面ダイアログを表示させる際に他のダイアログの背面に表示される

    2.ダイアログ、入力欄を選択するまで操作可能な状態にならない

    となっています。

    コードの開示等は出来ないため頂いた情報を元に再度調査してみます。


    2017年10月4日 2:17
  • ダイアログに限らず、CWndクラスの表示Z-Orderは、原則として次のような配置になります。

    1.ウインドウ作成時に指定された親ウインドウ
      (DLGの場合はコンストラクタで指定している。但しデフォルト引数=NULLとなっているので注意が必要)
     のZ-Orderの前面に配置されます。つまり、親のCWndが指定された場合、子のCWndはその前面側に配置されます。

    2.メインフレームはデスクトップを親として作成されるので、その前面に配置されます。
     デスクトップの裏に配置されることはありません。

    3.異なる親を持つ、子のCWnd間のZ-Orderは、その親の間のZ-Orderに依存して配置されます。

    以上を勘案すると、問題となっているDLGは3.の関係になっているのではないか、という疑いを持ちます。
    例えば、

    (A)一方がメインフレームを親とし、他方がデスクトップを親としている。
    (B)両者ともスクトップを親としている。この場合Z-Orderは後着が前面になるはずです。

    一般に、モーダルDLG同士の、Z-Orderを確実に制御するには、
    一方のDLGを他方のDLGの子として生成します。

    ちなみに、親にNULLを指定した場合でも、それがDLGである場合は、MFCの内部コードが、
    やや涙ぐましい努力で親フレームを探して親としてくれます。
    ただし、見つからなければ(親フレームが生成完了する前にDLGが生成された場合など)デスクトップが親になります。


    • 編集済み 仲澤@失業者 2017年10月4日 4:13
    • 回答としてマーク water00000 2017年10月4日 5:21
    • 回答としてマークされていない water00000 2017年10月4日 5:22
    • 回答としてマーク water00000 2017年10月4日 5:27
    2017年10月4日 4:07
  • >中澤さん

    丁寧な説明ありがとうございます。

    どこに着目すればよいかもわからない状況だったため、大変助かりました。

    (A)(B)どちらかではないか確認してみます。

    2017年10月4日 5:27