ダイアログバーの作成

ダイアログバーはツールバーと似ているが、ボタンやエディットボックス、 コンボボックスなどのコントロールを表示させることが可能である。
ここでは、上図に示したようなダイアログバーを作成する。 このダイアログバーは、エディットビュー内にある文字列を検索するためのものである。

1.プロジェクトの作成
SDIのプロジェクトを新規作成する。このとき、ビューはCEditViewクラスに設定する。

2.CDialogBar型メンバ変数の追加
CFrameWndクラスの派生クラスであるCMainFrameクラスに、CDialogBar型のメンバ変数m_wndDlgBarを追加する。

3.ダイアログリソースの作成
リソースエディタを使い、ダイアログリソースを新規作成する。リソースIDはIDD_DIALOGBAR1とし、 プロパティのスタイルは「チャイルド」、境界線は「なし」とする。 上図を参考に、エディットボックスとボタンをダイアログに貼り付ける。 エディットボックスのIDはIDC_EDIT_SEARCH、ボタンのIDはIDC_BUTTON_SEARCHとする。

4.ダイアログバーの生成
CMainFrame::OnCreate関数を以下のように修正する。
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	(中略)

	// TODO: ツール バーをドッキング可能にしない場合は以下の3行を削除
	//       してください。
	m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
	EnableDocking(CBRS_ALIGN_ANY);
	DockControlBar(&m_wndToolBar);

	// ダイアログバーの生成
	if(!m_wndDlgBar.Create(this, IDD_DIALOGBAR1, WS_VISIBLE | CBRS_TOP,
		AFX_IDW_TOOLBAR))
	{
		TRACE0("Failed to create toolbar\n");
		return -1;      // 作成に失敗
	}
	m_wndDlgBar.EnableDocking(CBRS_ALIGN_ANY);
	EnableDocking(CBRS_ALIGN_ANY);
	DockControlBar(&m_wndDlgBar);
	m_wndDlgBar.SetWindowText("文字列の検索");

	return 0;
}
この時点でビルド、実行するとドッキング可能なダイアログバーが表示されるが、「検索」ボタンが不活性のままになっている。 ボタンを活性化するためには、このボタンに対するメッセージハンドラをCMainFrameクラスに作成する。 ただしClassWizardを使って作成することができないので、直接ソースへ以下のように書き込む。
// ヘッダファイルへの記述 --------------------
class CMainFrame : public CFrameWnd
{
(中略)

// 生成されたメッセージ マップ関数
protected:
	CDialogBar m_wndDlgBar;
	//{{AFX_MSG(CMainFrame)
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
	afx_msg void OnButtonSearch();
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

// ソースファイルへの記述 --------------------
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
	//{{AFX_MSG_MAP(CMainFrame)
	ON_WM_CREATE()
	ON_BN_CLICKED(IDC_BUTTON_SEARCH, OnButtonSearch)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()
・・・・・・

void CMainFrame::OnButtonSearch()
{
}
これで再度ビルド、実行すると「検索」ボタンは活性化されるようになる。

5.メニューを使ってダイアログバーを表示/非表示させる

左図のように、 ツールバーやステータスバーと同様にダイアログバーもメニューから表示/非表示を切り替えられるようにする。
リソースエディタでメニューリソースIDR_MAINFRAMEを開き、リソース上の「表示」メニューをクリックする。 するとポップアップメニューが表示されるので、一番下の空いたところをダブルクリックし「メニューアイテムプロパティ」 ダイアログボックスを表示させる。IDには「ID_VIEW_DIALOG_BAR」、キャプションには「文字列検索バー(&D)」 と入力してメニューを追加する。
メニューを追加したら次にClassWizardを開き、「メッセージマップ」タブを選択する。 クラス名は「CMainFrame」、オブジェクトIDは「ID_VIEW_DIALOG_BAR」を選択し、 COMMANDメッセージとUPDATE_COMMAND_UIメッセージに対するハンドラ関数OnViewDialogBarとOnUpdateViewDialogBarを作成する。
CMainFrameクラスのソースファイルを開き、メッセージハンドラを以下のように記述する。
void CMainFrame::OnViewDialogBar() 
{
	// TODO: この位置にコマンド ハンドラ用のコードを追加してください
	if( m_wndDlgBar.IsWindowVisible() )
		ShowControlBar(&m_wndDlgBar, FALSE, FALSE);
	else
		ShowControlBar(&m_wndDlgBar, TRUE, FALSE);
}

void CMainFrame::OnUpdateViewDialogBar(CCmdUI* pCmdUI) 
{
	// TODO: この位置に command update UI ハンドラ用のコードを追加してください
	pCmdUI->SetCheck(m_wndDlgBar.IsWindowVisible());
}
6.文字列の検索処理
ダイアログバーのエディットボックスに文字列を入力し「検索」ボタンを押すと、 エディットビュー内に入力した文字列と一致するものがあればその部分を選択するような処理を埋め込む。
「4」で追加したOnButtonSearch関数を以下のようにする。
void CMainFrame::OnButtonSearch()
{
	CEdit* pEdit;		// 検索文字列のエディットボックス
	CEdit* pEditMemo;	// エディットビューのエディットボックス
	CString strSearch;	// 検索文字列
	CString strMemo;	// エディットビューの文字列

	pEdit = (CEdit*)m_wndDlgBar.GetDlgItem(IDC_EDIT_SEARCH);
	pEditMemo = &((CEditView*)GetActiveView())->GetEditCtrl();

	// 検索文字列の取得し、英大文字があれば小文字に変換する
	pEdit->GetWindowText(strSearch);
	if( strSearch.IsEmpty() )
	{
		AfxMessageBox("検索する文字列を指定してください。");
		return;
	}
	strSearch.MakeLower();

	// エディットビューの文字列を取得し、英大文字があれば小文字に変換する
	pEditMemo->GetWindowText(strMemo);
	strMemo.MakeLower();

	// エディットビュー内での検索開始位置の決定
	int iFind = 0;
	iFind = int( HIWORD(pEditMemo->GetSel()) );

	// 文字列が見つかった場合にはその部分を選択表示する
	if( (iFind = strMemo.Find(strSearch, iFind)) == -1 )
	{
		AfxMessageBox("検索文字列と一致するものが見つかりませんでした。");
	}
	else
	{
		pEditMemo->SetSel(iFind, iFind + strSearch.GetLength());
	}
}

目次へ