CMFCToolBarを複数持つアプリケーションの配置保存について

[戻る]
週休十日 2010/03/18(木) 09:25:15
はじめまして。
開発環境はWindowsXP Professional SP3 / Visual Studio 2008 SP1 MFCです。
CMFCToolBarを複数追加したときに配置の保存が正しくできません。
具体的には二度目以降に起動した場合、デフォルトのツールバーが最後に作成された
ツールバーの位置に入れ替わって表示されてしまいます。
現象は以下の手順で確認しました。

1.SDIのMFC標準形式のプロジェクトを作成
2.リソースにツールバー(IDR_TOOLBAR1とする)を追加し、適当にツールボタンを追加
3.CMainFrameクラス(MainFrm.h)に
CToolBar m_wndToolBar1;
を追加
4.CMainFrame::OnCreate(CMainFrm.cpp)に以下を追加

// m_wndToolBarの作成処理の下に
if (!m_wndToolBar1.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE 
| CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) 
|| !m_wndToolBar1.LoadToolBar(IDR_TOOLBAR1))
{
    TRACE0("ツール バーの作成に失敗しました。\n");
    return -1;      // 作成できませんでした。
}

// m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);の下に
m_wndToolBar1.EnableDocking(CBRS_ALIGN_ANY);

// DockPane(&m_wndToolBar);の下に
DockPane(&m_wndToolBar1);

5.ビルドして実行
6.2で追加したツールバーを移動してアプリケーション終了
7.もう一度アプリケーションを起動

実際に作成しているアプリケーションではツールバーを4つ配置していますが、
上記の例のように2つでも現象は再現します。
ツールバーの配置を正しく保存するにはどうしたらいいのでしょうか。

ryo 2010/03/18(木) 10:01:23
たぶん、IDがかぶってる

if (!m_wndToolBar1.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE 
| CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) 

↓

if (!m_wndToolBar1.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE 
| CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC,
 CRect(1,1,1,1),IDR_TOOLBAR1) 

でどうかな

#配置位置はレジストリに記録されてるので、
#試す前にいったん削除をしておくと安心

仲澤@失業者 2010/03/18(木) 10:11:32
ウインドウプレイスメントを含む情報は、メインアプリケーションの
InitInstance()内などで設定されているレジストリに保管されています。
デフォルトでは

 SetRegistryKey( _T("アプリケーション ウィザードで生成された・・・ョン"));

等となっています。
ツールバーやステータスバーなどのメインフレームに付随する
ペインのコードを変更した場合は、「必ず」当該のキー直下の
対象*.exe名称のキーの下を全て削除しないと、立ち上がり時に
誤った情報が読み込まれることがあります。
まず、これを試してみましょう。

週休十日 2010/03/18(木) 13:35:33
回答ありがとうございます。

ryoさま

> if (!m_wndToolBar1.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE 
> | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC,
>  CRect(1,1,1,1),IDR_TOOLBAR1) 

> でどうかな

正常に保存できるようになりました!
ツールバーをフローティングにした時にツールバーのタイトルが
同じになってしまうという現象も後になって気付いたのですが、
これも解消することができました。
ありがとうございました。


仲澤@失業者さま

今まではアプリケーションを初期状態で起動したい場合には
わざわざAppクラスのLoadState()をオーバーライドしてTRUEを
返して起動していました。
教えていただいたレジストリキーを削除すればコードをわざわざ
変更しなくても初期状態で起動できるため、とても楽にテストを
することができました。導入先でアプリケーションを初期状態で
起動したいときにも役に立ちそうです。
ありがとうございました。


#実際に作成しているアプリケーションでも正常に保存できるようになりました。

週休十日 2010/03/18(木) 13:36:30
[[解決]]
解決チェック入れ忘れましたorz

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