モードレスダイアログの最大化状態が解除される

[戻る]
亀山 2013/02/12(火) 14:44:08
Windows7、VS2008です。

以下は問題を発生させる部分のみのサンプルです。
MFCダイアログベースのプロジェクトをデフォルトのまま新規作成し、
メインダイアログとバージョン情報ダイアログの両方に
最大化ボタンと最小化ボタンを付け、
バージョン情報ダイアログをDoModal()で出すところを、

    if ((nID & 0xFFF0) == IDM_ABOUTBOX)
    {
        //CAboutDlg dlgAbout;
        //dlgAbout.DoModal();
        CAboutDlg* pDlg = new CAboutDlg;
        pDlg->Create(CAboutDlg::IDD, this);
        pDlg->ShowWindow(SW_SHOW);
    }

と書き換え、とりあえず一度だけモードレスで出すようにしました。
その後のことは今回は関係ありません。

この状態でビルドして、バージョン情報ダイアログを出し、
メインダイアログとバージョン情報ダイアログを別々のモニタに最大化させ、
メインダイアログのタイトルバーを右クリックして最小化させます。
このとき、バージョン情報ダイアログも自動で最小化されます。

その後、タスクバーのダイアログの部分をクリックすると
メインダイアログは最大化したまま復元しますが、
バージョン情報ダイアログのほうは元のサイズに戻ってしまいます。

モードレスダイアログに最大化の機能を載せるためには、
なにか他に自身で扱わなければいけないものがあるのでしょうか?

仲澤@失業者 2013/02/12(火) 16:32:35
(ずいぶん昔からの)Windowsの仕様かもしれません。
似ていますが、ちょっと違った現象として、
 (a).当該のVerDLGを表示して、アイコン化する
 (b).親DLGをアイコン化してから復帰させると
  VerDLGがアイコンでなく、ノーマルサイズに表示される。
というものがあります。
この仮定が正しい場合、ご要望は

 1.デスクトップでない親を持つモードレスDLGのアイコン化と復帰の動作を
  Windowsのデフォルトの動作と異なる動作にしたい。

ということになるかと思います。
この場合は、

 2.アイコン化、最大化、通常の表示状態を記憶し、
  「復帰」等のタイミングで望みの表示状態に復帰する動作を自前で実装する。

ことになるのではないでしょうか。

仲澤@失業者 2013/02/12(火) 16:44:02
orz...え〜と
シングルモニターなのでテストできませんが、
かつ、ただの思いつきなのですが、

DLGリソースの「Border」プロパティを
「ダイアログ枠」->「サイズ変更枠」

は、一応、試してみるべきかもしれません(vv;)。

亀山 2013/02/12(火) 19:14:44
[[解決]]
仲澤@失業者さん、ありがとうございます。

CAboutDlg::OnShowWindow()を以下のようにしたところ、
バージョン情報ダイアログも正しく最大化された状態で戻りました。

void CAboutDlg::OnShowWindow(BOOL bShow, UINT nStatus)
{
    if (bShow && nStatus == SW_PARENTOPENING) {
        ShowWindow(SW_SHOWNA);
    }

    CDialog::OnShowWindow(bShow, nStatus);

    // TODO: ここにメッセージ ハンドラ コードを追加します。
}

「TODO:」はCDialog::OnShowWindow()の下に書かれていましたが、
CDialog::OnShowWindow()の中で最大化が解除されるようで、
そのあとに書くとだめでした。

OnShowWindow()の中でShowWindow()を呼ぶのも気持ち悪いですが、
とりあえずは動いていそうなので、いったんこれでやってみます。
なにか危険なケースが考えられるようであれば、指摘いただけると嬉しいです。

亀山 2013/02/12(火) 19:19:17
一つお返事を忘れてしまいました。

> DLGリソースの「Border」プロパティを
> 「ダイアログ枠」->「サイズ変更枠」
> 
> は、一応、試してみるべきかもしれません(vv;)。

これも試してみましたが、結果は同じでした。
モードレスダイアログは最大化するものではないという仕様なのかもしれません。

ただ、最近はマルチモニタが珍しくなくなっているため、
モードレスダイアログを最大化できるようにする必要が出てきました。

仲澤@失業者 2013/02/13(水) 10:22:01
特に問題は見つけられません。

モードレスDLGは、DLGテンプレートを使って画面を構成できる点は
モーダルDLGと変わりありませんが、その性質はむしろ通常のポップアップ
ウインドウに近い動作をします。

従って、まんまのモードレスDLGを使うより

 1.モードレスDLGを、子ウインドウとして、クライアントエリア全体に
  貼り付けた、通常のウインドウ

として、実装したほうが便利な場合が多いです。
時間のあるときなどに検討してみてはどうでしょう。

亀山 2013/02/13(水) 14:18:58
>  1.モードレスDLGを、子ウインドウとして、クライアントエリア全体に
>   貼り付けた、通常のウインドウ
> 
> として、実装したほうが便利な場合が多いです。
> 時間のあるときなどに検討してみてはどうでしょう。

CFrameWndの中にあるCFormViewのような構造ということですね。
次回モードレスダイアログを作るときには、その構造も挑戦してみたいと思います。

古いスレッドには追加発言できません。