CToolBarについて

[戻る]
ひろ 2002/02/21(木) 23:26:00
CToolBarにつきまして質問があります。
CToolBarをCreateExで作成してイメージリストにビットマップを読み込み、
SetButtonInfoでIDとイメージリスト番号を設定した後で、
SetButtonTextにより、ボタンにテキストを設定していますが、
メニューの選択により、ボタンのテキストの表示非表示を
切り替えたいと思っております。
単純にSetSizesでボタンのサイズを変更し、RecalcLayoutでレイアウト変更と
思ったのですが、うまく動きません。
一度ツールバーを削除してから生成しなければいけないのでしょうか?
環境はWindows2000でVC++6.0です。
初心者で申し訳ありませんが、宜しくお願い致します。

TAD [E-Mail] 2002/03/03(日) 10:08:09
私もつい最近、ツールバーにテキストを表示/非表示できるプログラムを作りました。(苦労し
ましたが)
「うまく動きません」とのことですが、どううまく動かないのでしょうか?
例えば、テキストが表示されないのか、テキストは表示されるがツールバーのサイズが変更され
ないのか分かりません。
そこのところをもう少し詳しく教えていただけると、回答できると思います。

ひろ 2002/03/07(木) 23:23:52
TAD様
返事が遅くなり大変申し訳ございません。
すみません、根本的な問題点を記述していませんね。。。
具体的に説明させていただきます。

以下が主な処理の流れです。

●アプリケーション起動時
ボタンのイメージはビットマップをイメージリストに読み込んでから、
ツールバーコントロールに設定しています。
その後の処理です。

// ボタン情報設定
m_wndToolBar.SetButtonInfo(0, ID_NEW_FILE,
             TBSTYLE_BUTTON | TBSTYLE_AUTOSIZE, nImage);
// ボタン名設定
m_wndToolBar.SetButtonText(0, _T("新規作成"));
// ボタンサイズ取得
m_wndToolBar.GetItemRect(0, &rectToolBar);
// ボタンサイズ設定
m_wndToolBar.SetSizes(rectToolBar.Size(), CSize(16,16));
// ボタンスタイル設定
m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle()
             | CBRS_TOOLTIPS | CBRS_FLYBY);

この後、ボタン名非表示を選択された場合に
強引に以下の処理をします。
// ボタンサイズ設定
m_wndToolBar.SetSizes(CSize(23,23), CSize(16,16));
RecalcLayout();

この処理ですと、ツールバーの高さと幅は変更されず、
ボタンのサイズだけがイメージのサイズになります。

また、ボタン名を設定せずに起動しまして、
上記のような処理をいたしますと、
ボタン名がボタンイメージの下にかすかに表示
されるだけでして、ツールバー自体のサイズが
変更されません。

わかりにくい例で申し訳ございません。
もし回答いただけるようでしたら、よろしくお願いいたします。

TAD [E-Mail] 2002/03/08(金) 05:54:32
>TAD様
>返事が遅くなり大変申し訳ございません。

私の最初の回答も質問の日からかなりすぎていましたので、
既に解決していたら無意味だな、と思いながら書きました。

ひろさんは、CToolBar クラスをそのまま使っていると思いますが、
レイアウトを動的に変更させるためには、派生クラスを作成する必要があります。
というのは、CToolBar クラスの protected メンバ変数、
m_bDelayedButtonLayout を操作する必要があるからです。
この変数は、BOOL 型で、ボタンのサイズなどを変更したときに、
フレームの RecalcLayout を呼び出す前に、TRUE にする必要があります。

実際には、派生クラスのメンバに、テキストの表示/非表示の関数を作り、
以下のようにツールバーのサイズを調整します。

SetSizes(sizeButton, CSize(16, 15));
m_bDelayedButtonLayout = TRUE;         // ここが重要
GetDockingFrame()->RecalcLayout();

私の場合は、表示/非表示を切り替えるたびに、
CToolBarCtrl::GetButton などのメンバ関数を使って、
取得、削除、挿入をすべてのボタンに対して行ない、
テキストを表示する場合は、CToolBarCtrl::AddStrings で追加し直しています。
(SetButtonText は未使用)
これだと、表示/非表示、どちらの場合でも GetItemRect が使えます。
参考にしてみてください。

ひろ 2002/03/09(土) 21:20:32
TAD様
とてもわかりやすいご回答ありがとうございました。
開発環境が会社にしかないもので、
土日はテストができませんので、
来週早速参考にさせていただきます。

試験をすればわかると思うのですが、
ひとつだけ気になった点がありまして、
m_bDelayedButtonLayout = TRUE;
とした後で m_bDelayedButtonLayout 変数は
また FALSE になることがあるのでしょうか?
もし時間がございましたらまたご教授ください。

よろしくお願いいたします。

TAD [E-Mail] 2002/03/10(日) 06:31:28
MFC の CToolBar クラスのソースを見てみました。
CToolBar::OnPaint などで、m_bDelayedButtonLayout が TRUE なら、
CToolBar::Layout が呼ばれますが、Layout 関数の先頭に、以下の記述がありました。

ASSERT(m_bDelayedButtonLayout);
m_bDelayedButtonLayout = FALSE;

つまり、m_bDelayedButtonLayout が TRUE であることを確認してから、
FALSE にリセットしています。

ということなので、レイアウトを変更するたびに、
m_bDelayedButtonLayout = TRUE;
と、する必要がありますね。

>開発環境が会社にしかないもので、
>土日はテストができませんので、
>来週早速参考にさせていただきます。

吉報をお待ちしておりまーす。

ひろ 2002/03/11(月) 23:39:03
TAD様
調べていただきありがとうございます。
本日は所用に追われてしまい、
コーディング作業ができませんでした。
明日こそは試させていただきたいと思います。

>吉報をお待ちしておりまーす。

がんばりまーす。

ひろ 2002/03/13(水) 00:49:32
[[解決]]
TAD様
参考にさせていただいて
無事解決いたしました。
ありがとうございました。

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