検索等が行えるように、アプリケーションにコンボボックスや
エディットボックスを持ったツールバーを追加したいと考えています。
開発環境はXP(SP3) VisualStudio2008 MFCです。
過去ログで同じような記事があったのですが、
提示されていたリンクが無効であったため解決には至りませんでした。
下記のMicrtosoft提供のページを参考にして、
実装を試みていたのですが、どうにもうまくいきません。
http://msdn.microsoft.com/ja-jp/library/bb983718(v=VS.90).aspx
以下、試していたコードです。
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWndEx)
:
ON_REGISTERED_MESSAGE(AFX_WM_RESETTOOLBAR, OnResetToolbar)
END_MESSAGE_MAP()
LRESULT CMainFrame::OnResetToolbar(WPARAM wParam, LPARAM lParam)
{
if(wParam != IDR_TOOLBAR1)
return 0L; //検索ツールバーでない場合
//CMFCToolBarComboBoxButtonの派生クラス
CFindComboButton btnCombo(ID_EDIT_FIND_COMBO, 0);
//m_pComboはCComboBoxの派生クラスへのポインタ
m_pCombo = (CFindComboBox *)btnCombo.CreateCombo(&m_wndFindToolBar,
CRect(2, 2, 50, 16));
//m_wndFindToolBarはCMFCToolBarクラスのインスタンス
m_wndFindToolBar.ReplaceButton(ID_EDIT_FIND_COMBO, btnCombo);
m_pCombo->SetWindowTextA(test);
m_pCombo->AddString(test2);
return 0L;
}
ツールバーにコンボボックスが表示されるまではよいのですが、
元のボタンの上にコンボボックスが表示されていたり
(ReplaceButtonを実行すれば元のボタンは消えると思っていたのですが)、
コンボボックスへの操作ができなかったりという状況です。
(上記の例ではtset"test2が表示されない)
Microsoftのサイトのような方法でなくてもよいので、
実装の方法を教えていただけないでしょうか。
よろしくお願いします。
私の場合、VC++2005ですが、以下のような感じでやっています。
リソースエディタで、ツールバー(IDR_MAINFRAME)にID_COMBOBOXのボタンをあらかじめ
追加しておき、実行時にボタンからコンボボックスに切り替えています。
なお、Windowsのバージョン違いや表示モードの違いを吸収するためには、
適当な幅とか高さと書いてある部分は、ツールバーサイズやフォントサイズ等から、
計算して求めた方が良いです。
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
// ツールバーの作成
if (!m_wndToolBar.CreateEx(this, 0, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0(ツール バーの作成に失敗しました。\n);
return -1; // 作成できませんでした。
}
// ツールバーにコンボボックスを追加
int Idx = m_wndToolBar.CommandToIndex(ID_COMBOBOX);
m_wndToolBar.SetButtonInfo(Idx, ID_COMBOBOX,
TBBS_SEPARATOR, 85); // 適当なコンボボックス幅になるように調整します
CRect Rect;
m_wndToolBar.GetItemRect(Idx, &Rect);
Rect.top = 1; // 適当な高さ位置になるように調整します
Rect.bottom = Rect.top + 150; // 適当なコンボリストの長さになるように調整し
ます
if(!m_wndToobarCombo.Create(
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP,
Rect, &m_wndToolBar, ID_SELECT_MACHINE ))
{
TRACE0(Failed to create combo-box\n);
return FALSE;
}
m_wndToobarCombo.SetFont(m_wndToolBar.GetFont());
m_wndToobarCombo.AddString(_T(Item1));
m_wndToobarCombo.AddString(_T(Item2));
:
m_wndPatternCombo.ShowWindow(SW_SHOW);
}
bunさん
お返事ありがとうございます。
提示していただいた例を参考にコードを書いてみたところ、
ツールバー上のコンボボックスの操作ができました。
メッセージも拾うことができたので、一通りのことができそうです。
しかし、コンボボックスを含んでいるツールバーの
サイズ変更が思うようにできないため、
コンボボックスの右端が切れた状態で表示されてしまいます。
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
:
:
CRect TBRect;
m_wndFindToolBar.GetClientRect(&TBRect);
TBRect.right *= 5;
HDWP Pos = BeginDeferWindowPos(1);
m_wndFindToolBar.MoveWindow(TBRect, TRUE, Pos);
}
上記のようにCBasePane::MoveWindow()関数でサイズ変更を
試みているのですが、変化が見られない状態です。
(m_wndFindToolBar.AdjustLayout()関数も試してみましたが、変化なし)
ちょっと分かりづらいですが、
今回のコードはID_COMBOBOXのボタンを幅を持ったセパレータに置き換えて、
その上にコンボボックスを表示しています。
なので、セパレータの幅とコンボボックスの幅を合わせないとツールバーを
はみ出してしまいます。
以下のコードの 85 と、
m_wndToolBar.SetButtonInfo(Idx, ID_COMBOBOX,
TBBS_SEPARATOR, 85); // 適当なコンボボックス幅になるように調整します
以下のコードの Rect の幅を合わせるとそれらしい感じになるかと思います。
if(!m_wndToobarCombo.Create(
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP,
Rect, &m_wndToolBar, ID_SELECT_MACHINE ))
bunさん
回答ありがとうございます。
msdnライブラリで調べたところ、SetButtonInfo()関数の第4引数iImageは
イメージのインデックスとなっているのですが、
この値はツールバー幅と関係あるのでしょうか?
この引数に1を入れても500を入れても表示されるツールバーの幅に
変化がありませんでした。
m_wndFindToolBar.Create()のRectで指定した数値については、
コンボボックスの幅の変化が確認できています。
ツールバーのなんらかのプロパティを有効にすれば、
iImageの値によって幅に変化があるのでしょうか?
別の方法も試してみたのですが、これもちょっと問題があります(↓下記)
m_wndFindToolBar.SetSizes()関数の第1引数でボタンサイズを指定すると、
ボタンの幅が変化するのですが、この関数を使用すると、
全てのツールバーの全てのボタンの幅が変化してしまいます(staticメンバ)。
単独のボタンに対して同様の操作ができるような関数を探して
いたのですが、CMFCToolBarのメンバには存在しないようでした。
あれ、おかしいですねぇ。
私のところではうまくいっています。
なお、以下の件は、
> msdnライブラリで調べたところ、SetButtonInfo()関数の第4引数iImageは
> イメージのインデックスとなっているのですが、
> この値はツールバー幅と関係あるのでしょうか?
MSDNをもうすこし下まで読み進めると、以下の文章があるはずです。
> スタイルに TBBS_SEPARATOR としたときは区切り記号になり、
> iImage に設定する値は、ピクセル単位で表現した区切り記号の幅になります。
> MSDNをもうすこし下まで読み進めると、以下の文章があるはずです。
VisualStudioのヘルプで、CToolBar::SetButtonInfo()の解説に記述が見つかりました。
普段はWebサイトの方で調べているので見つからなかったようです。
CMFCToolBar::SetButtonInfo()に関する記述は見つからなかったのですが、
おそらく本来は同様にして使えるんでしょうね。
bunさんの環境では、TBBS_SEPARATORスタイルに設定したボタンは残っているでしょう
か?
私の環境では、アイコンが表示されたままになっています。
(コンボボックスの下に一部が見えている状態)
消えているのならSetButtonInfo()が思うように動作していないと考えたのですが。
関係あるかわかりませんが、私が追加したツールバーには
2つのボタン(アイコン)があるのですが、
1つ目のボタンについてSetButtonInfo()⇒GetItemRect()をした際には、
Rectのtop,bottomに0が、left,rightに1が入った状態で取得されます。
一方、2つ目のボタンについて関数を実行した場合、
Rectはおそらく正しいと思われる値が入ってきます。
(leftとrightの差が、iImageで指定した値になっています)
ただ、どちらの場合もツールバーの幅に変化がないです。
こちらではボタンはありません。
セパレータに変換しているので、セパレータの縦棒が表示されている
だけです。
その上にコンボボックスが重なっているので、実際には何も見えてい
ないです。
bunさん
お返事ありがとうございます。
やはりこちらの環境ではSetButtonInfo()が期待した働きをしていないようですね。
今日は他のことをやってましたので、明日以降にもう少し調べてみたいと思います。