MDIの子ウィンドウを最大化した時のキャプション書式を変更したい

[戻る]
AR 2016/02/20(土) 16:06:13
 VS2010〜2015 MFC使用、MDIで、子ウィンドウを最大化したときの状態です。

 ウィザードで作成したスケルトンのタイトルバー文字列を
「アプリ名 - [子ウィンドウのタイトル]」
という書式になっているのを
「子ウィンドウのタイトル - アプリ名」
と変更したいと考えています。([]を取りたい、前後を入れ替えたい)

 一応、試したコードは以下の通りです。

BOOL CChildFrame::PreCreateWindow(CREATESTRUCT& cs)
{
  cs.style &= ~(FWS_PREFIXTITLE | FWS_ADDTOTITLE);//単純化するためにフラグを落とす
  if( !CMDIChildWndEx::PreCreateWindow(cs))
    return FALSE;
  return TRUE;
}
void CChildFrame::OnUpdateFrameTitle(BOOL bAddToTitle)
{
  SetWindowText(L"子ウィンドウのタイトル");
}


BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
  cs.style &= ~(FWS_PREFIXTITLE | FWS_ADDTOTITLE);//単純化するためにフラグを落とす
  if (!CMDIFrameWndEx::PreCreateWindow(cs))
     return FALSE;
  return TRUE;
}
void CMainFrame::OnUpdateFrameTitle(BOOL bAddToTitle)
{
  SetWindowText(L"アプリ名");
}

・子ウィンドウを最大化した結果
 アプリ名 - [子ウィンドウのタイトル]

・子ウィンドウを最大化した結果(参考)
 メインフレーム:アプリ名
 子ウィンドウ :子ウィンドウのタイトル


 具体的に、タイトルバーの文字列を生成しているのはMFC内部の
void CFrameWnd::UpdateFrameTitleForDocument(LPCTSTR lpszDocName)
 と考えてるのですが、virtualではないのでオーバーライドもできません。

 結構いろんなMDIアプリがタイトルバーを変更しているように見受けられますので可能
なんじゃないかと考えてますが、ご存知の方がいらっしゃいましたらよろしくお願いします。

AR 2016/02/20(土) 16:10:13
 すみません、訂正です。

・子ウィンドウを最大化した結果
 アプリ名 - [子ウィンドウのタイトル]

・子ウィンドウを最大化を「解除」した結果(参考)
 メインフレーム:アプリ名
 子ウィンドウ :子ウィンドウのタイトル

仲澤@失業者 2016/02/29(月) 15:16:39
かめレスですみません。

1.MDI子Wndが最大化されていない場合に、メインフレームのタイトルに
 MDI子Wndのタイトルを追加しない。

の件ですが、VS2013の場合でメインフレームが  public CMDIFrameWndEx の場合なら、
OnUpdateFrameTitle()をオーバーライドして、空にするだけでできましたけど、
何か勘違いしているのでしょうか。

class MainFrame : public CMDIFrameWndEx
{
  :
  virtual void OnUpdateFrameTitle(BOOL bAddToTitle)
  {
    // 何もしない
  }
 :
};

AR 2016/02/29(月) 17:33:11
 すみません、説明が悪く、分かりにくかったと思います。
 まずMDIの最大化/最大化解除状態の二つのステータスが必要という前提です。

 ご指摘いただいた、コードだと

 子ウィンドウ最大化していない状態
 MFCApplication - MFCApplication1
  ↓
 MFCApplication※1
 になる認識です。

 ※1を子ウィンドウ最大化すると
 MFCApplication - [MFCApplication1]
 となりますが、この書式を変えたいのです。


 子ウィンドウにタイトル空をセットして、CMDIFrameWndEx::OnUpdateFrameTitle()を
オーバーライドすれば任意の文字列を指定可能ですが、最大化を解除したら子ウィンドウ
にタイトルが無いわけで、これはこれで判別できなくて困ります。
 子ウィンドウが最大化されているか否かを判定して処理を分けたりもしてみたのです
が、あまり綺麗な処理とはいえないのでご相談という経緯です。

仲澤@失業者 2016/03/01(火) 10:51:43
ぴゅあにウィザードしたコードで、OnUpdateFrameTitle(BOOL bAddToTitle)
を空でオーバーライドしただけだと、[]は付かないようですね。
つまり、FWS_PREFIXTITLE と FWS_ADDTOTITLE のフラグの調整はしてない状態です。

もっとも、最終的にフレームのタイトルを決定しているのは、MDIの子ウィンドウ。
つまり、CMDIChildWnd::OnSize()やアクティベートのタイミングで、
メインフレームに対してタイトルの設定をしています。
これらは、オーバーライドできるので、どうとでも好きしたらどうでしょう。

AR 2016/03/01(火) 16:30:32
>ぴゅあにウィザードしたコードで、OnUpdateFrameTitle(BOOL bAddToTitle)
>を空でオーバーライドしただけだと、[]は付かないようですね。

 CMainFrameでオーバーライドしても[]が付与されるものと認識しています。
 条件を揃える意味でウィザードで生成直後のコードで試してみました。(VS2015/VS2012)

●CMDIFrameWnd(タブ無し)
MainFrm.hに以下を追記
virtual void OnUpdateFrameTitle(BOOL bAddToTitle) {};

子ウィンドウ最大化すると
test - [test1]


●CMDIFrameWndEx(タブ無し)
MainFrm.hに以下を追記
virtual void OnUpdateFrameTitle(BOOL bAddToTitle) {};

子ウィンドウ最大化すると
testEx - [testEx1]

 CMDIChildWndExないしCMDIChildWndの派生クラスでOnUpdateFrameTitle(BOOL
bAddToTitle)をオーバーライドすると[]は消えるのですが、最大化を解除すると子ウィン
ドウのタイトル無しになって具合が悪いという次第です。
 SetWindowTextなどで子ウィンドウのタイトルテキストをセットしようとしても無視さ
れますし。

仲澤@失業者 2016/03/01(火) 17:33:04
残念ながら、自分の環境(VS2013とVS2010)ではMDIチャイルドの
タイトルが空欄になることはありません。
問題はそこにあるような気がします。

まず、MDIChildWndのフレームのタイトルは、それが対象としているドキュメントに保持
されています。
MDIChildWndは GetActiveDocument();でそのドキュメントを参照し、タイトルを取得しま
す。
これを設定しているのは(ただし、オーバーライドしていなければ)

-----winmdi.cpp[923付近]-----
CMDIChildWnd::OnUpdateFrameTitle(BOOL bAddToTitle)
{
  if (bAddToTitle){
   // この中で設定している
  }
}

です。従って、MDIChildのタイトルが空欄になる条件とは、

 1.上記関数の引数bAddToTitleがFALSEの場合
 2.そもそもドキュメントのタイトル CDocument::m_strTitle が空欄の場合

となります。

AR 2016/03/01(火) 19:45:28
[[解決]]
>タイトルが空欄になることはありません。
>問題はそこにあるような気がします。

 VS2010でも試してみましたがこちらの状況も変わらずです。
 ウィザードでの生成手順が違うのかもしれません。
 うろ覚えですがVS2008 feature packの前後で、この辺りの制御が変わった気がしてい
たのでVS2010〜という範囲に設定していました。

 念のため、かみ合ってないようなので言い方の順番を変えますが
CMDIChildWnd::OnUpdateFrameTitle(BOOL bAddToTitle)
 をオーバーライドして、全く処理しないようにし、子ウィンドウのタイトルを表示させ
ないようにすると、勝手に子ウィンドウのタイトルを拾ってメインフレームのタイトルに
[]を付けることはなくなります。
 ただし、最大化を解除した場合に子ウィンドウのオーバーライドして未処理になってい
るため、タイトルは当然表示されません。
 最大化を解除した状態での子ウィンドウのタイトル無しは困るので、これ以外の方法で
[]を除去する方法が無いか?ということです。


 ただ、タイトルバー文字列を作っているのが
 void CFrameWnd::UpdateFrameTitleForDocument(LPCTSTR lpszDocName)
 だと思っていたんですが、よくよく見るとこの関数では[]を付与してなかったです。
 (「連番:アプリ名 - ドキュメント名」のような書式)

 MFCのソースの読み込みが足らなかっただけという気がしてきましたので、まずは一旦
クローズしようと思います。
 お付き合いありがとうございました。

ITO 2016/03/03(木) 13:05:49
https://support.microsoft.com/ja-jp/kb/99182
これは、やってみましたか?

AR 2016/03/03(木) 13:51:47
 該当のページは「MFC ベースの MDI 子ウィンドウのタイトルを変更する方法」なので
目的が違います。
 MDI子ウィンドウを最大化したときには、子ウィンドウのタイトルバーは表示されない
わけで、キャプションとはメインフレームのタイトルバーの文字列を指しています。

 上記の記述にあわせると
「MFC ベースの MDI 子ウィンドウを最大化した時のメインフレームのタイトルを変更す
る方法」
 といった感じになります。

ITO 2016/03/04(金) 12:56:58
>「MFC ベースの MDI 子ウィンドウを最大化した時のメインフレームのタイトルを変更
>する方法」
なるほど、難しいですね。
失礼しました。

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