为工具栏添加组合框
第一步:使用记事本方式打开.rc资源文件,并找到工具栏资源定义的位置,编辑该定义,并在要创建组合框位置处为工具栏资源添加2个分隔符,如下所示:
IDR_DEMO_TOOLBAR TOOLBAR DISCARDABLE 16, 15
BEGIN
SEPARATOR
SEPARATOR
BUTTON ID_WINDOW_NEWFORMVIEW
BUTTON ID_WINDOW_NEWSPLITTER
END
第二步:为 工具栏上 即将创建的 组合框 增加一个资源ID 例如:IDC_SHAPES_COMBO_BOX,(View->Resource Symbols)
第三步:使用ClassWizard创建一个新的CToolBar派生类CShapesToolBar,因为ClassWizard并不显式的支持创建由CToolBar派生的类,所以要选择“generic Cwnd”类型,由ClassWizard生成代码,然后编辑代码,用CToolBar替换所有出现CWnd的地方
第四步:为新的工具栏类增加一个CComboBox类型的成员变量,
CComboBox m_cmbShapes;//工具栏组合框
第五步:在工具栏类CShapesToolBar里手工重载虚函数CToolBar::Create().
头文件中:
BOOL Create(CWnd* pParentWnd,DWORD dwStyle=WS_CHILD|WS_VISIBLE|CBRS_TOP,UINT nID=AFX_IDW_TOOLBAR);
源文件中:
BOOL CShapesToolBar::Create(CWnd* pParentWnd,DWORD dwStyle,UINT nID)
{
// 1 - 创建工具栏并装载相关资源
if( !CToolBar::Create( pParentWnd, dwStyle, nID ) ||!LoadToolBar(IDR_DEMO_TOOLBAR) )
{
return FALSE;
}
// 2 - 扩大占位符
SetButtonInfo( 0, IDC_SHAPES_COMBO_BOX, TBBS_SEPARATOR, 100 );
// 3 - 获得目标坐标
CRect rect;
GetItemRect( 0, &rect );
// 4 - 扩大矩形以解决下落的高度
rect.bottom = rect.top + 100;
// 5 - 创建工具栏组合框
m_cmbShapes.Create( WS_CHILD | WS_VISIBLE | WS_VSCROLL | CBS_DROPDOWNLIST,
rect, this, IDC_SHAPES_COMBO_BOX );
// 6 - 为组合框添加若干项
m_cmbShapes.AddString( _T( "Square" ) );
m_cmbShapes.AddString( _T( "Circle" ) );
return TRUE;
}
第六步:参考新的工具栏类,而不是CToolBar类修改框架窗口类。
头文件中:
CShapesToolBar m_wndNewToolbar;
源文件中:
//新工具栏
if( !m_wndNewToolbar.Create( this, WS_CHILD | WS_VISIBLE | CBRS_TOP, IDR_DEMO_TOOLBAR ) )
{
TRACE0("Failed to create shapes toolbar/n");
return -1; // fail to create
}
m_wndNewToolbar.SetBarStyle(m_wndNewToolbar.GetBarStyle() |CBRS_TOOLTIPS
| CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
m_wndNewToolbar.EnableDocking(CBRS_ALIGN_ANY);
EkDockBarNextTo( &m_wndNewToolbar, &m_wndToolBar, AFX_IDW_DOCKBAR_TOP );//该函数见上一节
m_wndNewToolbar.SetWindowText( CString( LPCSTR( IDR_DEMO_TOOLBAR ) ) );
CToolBar::SetButtonInfo
void SetButtonInfo( int nIndex, UINT nID, UINT nStyle, int iImage );
参数:
nIndex | 要设置其信息的按钮或分隔线的索引。 | |||||||||||||||
nID | 要给按钮的命令ID设置的值。 | |||||||||||||||
nStyle | 新的按钮风格。下面的按钮风格是被支持的:
| |||||||||||||||
iImage | 按钮的图像在位图中的新索引。 |
说明:
此成员函数用来设置按钮的命令ID,风格和图像号。对于具有TBBS_SEPARATOR风格的分隔线,这个函数将分隔线的以像素为单位的宽度设置为保存在iImage中的值。
有关位图图像和按钮的更多信息,参见CToolBar概述和CToolBar::LoadBitmap。
现在已经正确的创建了工具栏连同工具栏嵌入的组合框。然而,创建了工具栏只是完成了工作的一半:如果期望组合框可用的话,则仍然需要为组合框控件处理CBN_SELCHANGEE和UPDATE_COMMAND_UI消息,下面来介绍如何具体实现:
处理CBN_SELCHANGEE和UPDATE_COMMAND_UI消息
第一步:在新的工具栏内手工为 CBN_SELCHANGECBN消息增加一个消息处理函数
1a:
afx_msg void OnSelChangeShapesComboBox(); // toolbar combo-box
1b:
ON_CBN_SELCHANGE(IDC_SHAPES_COMBO_BOX, OnSelChangeShapesComboBox)
1C:
void CShapesToolBar::OnSelChangeShapesComboBox()
{
// 将 CBN_SELCHANGE 消息转换为 WM_COMMAND 同时,将组合框的HWND转换为LPARAM
AfxGetMainWnd()->PostMessage(WM_COMMAND,MAKEWPARAM( IDC_SHAPES_COMBO_BOX, 0 ),
reinterpret_cast<LPARAM>( m_cmbShapes.GetSafeHwnd() ) );
}
第二步:在与组合框有相关数据的类中手工为WM_COMMAND_消息 和 UPDATE_COMMAND_UI消息添加句柄
2a:
afx_msg void OnSelChangeTBComboBox();
afx_msg void OnUpdateTBComboBox(CCmdUI* pCmdUI);
2b:
ON_COMMAND(IDC_SHAPES_COMBO_BOX, OnSelChangeTBComboBox)
ON_UPDATE_COMMAND_UI(IDC_SHAPES_COMBO_BOX, OnUpdateTBComboBox)
2c:
void CDrawDoc::OnSelChangeTBComboBox()
{
//从Lparam中找到组合框
HWND hWnd = reinterpret_cast<HWND>( AfxGetApp()->m_msgCur.lParam );
ASSERT( ::IsWindow( hWnd ) );
CComboBox* pCB = static_cast<CComboBox*>( CWnd::FromHandle( hWnd ) );
ASSERT_VALID( pCB );
ASSERT( pCB->GetDlgCtrlID() == IDC_SHAPES_COMBO_BOX );
// 更新文档
m_shape = static_cast< SHAPE >( pCB->GetCurSel() );
UpdateAllViews( NULL );
SetModifiedFlag( TRUE );
}
void CDrawDoc::OnUpdateTBComboBox(CCmdUI* pCmdUI)
{
// 从pCmdUI中找到组合框
CComboBox* pCB = static_cast<CComboBox*>( pCmdUI->m_pOther );
ASSERT( ::IsWindow( pCB->GetSafeHwnd() ) );
ASSERT( pCB->GetDlgCtrlID() == IDC_SHAPES_COMBO_BOX );
// 检验以防止闪烁
if( m_shape != pCB->GetCurSel() && !pCB->GetDroppedState() )
{
pCB->SetCurSel( m_shape );
}
}