简介
组合框成为一个标准的工具栏功能。组合框是方便显示一个频繁访问设置的选择,或保持一个用户输入的历史(例如,最近的搜索模式)。
在工具栏嵌入一个标准的组合框是相当简单的。但是,结果可能会不看令人满意的,除非你执行几个步骤。在这篇文章中,我们将展示这些步骤,因此您将能够达到以下:添加到工具栏上的一个或多个组合框;调整组合框的字体;
使组合框响应用户命令;创建一个历史记录的组合框,其中包含最新的用户条目。组合框嵌入到工具栏
嵌入到一个组合框工具栏youll需要添加代码在CMainFrame::OnCreate中的消息处理程序。为了避免低层次的工具栏的细节OnCreate方法,可以将其封装在一个专用的方法CreateComboBox添加到您的自定义CToolBar类:class CToolBarWithCombo : public CToolBar
{
public:
CComboBox m_comboBox;
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CToolBarWithCombo)
//}}AFX_VIRTUAL
BOOL CreateComboBox(class CComboBox& comboBox,
UINT nIndex,
UINT nID,
int nWidth,
int nDropHeight);
// Generated message map functions
protected:
//{{AFX_MSG(CToolBarWithCombo)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
BOOL CToolBarWithCombo::CreateComboBox(CComboBox& comboBox,
UINT nIndex,
UINT nID,
int nWidth,
int nDropHeight)
{
// Create the combo box
SetButtonInfo(nIndex, nID, TBBS_SEPARATOR, nWidth);
CRect rect;
GetItemRect(nIndex, &rect);
rect.top = 1;
rect.bottom = rect.top + nDropHeight;
if (!comboBox.Create(CBS_DROPDOWN|WS_VISIBLE|WS_TABSTOP|WS_VSCROLL,
rect, this, nID))
{
TRACE("Failed to create combo-box\n");
return FALSE;
}
return TRUE;
}
然后你可以调用CreateComboBox方法之后创建您的自定义工具栏(里面的CMainFrame::OnCreate中):{C}
另一种方法是重写CToolBarWithCombo:OnCreate和地方的CreateComboBox有呼叫。字体调整
默认情况下,组合框分配系统字体看起来并不很好的工具栏。因此,下一步是使组合框的更好看。您可以直接添加字体选择代码CreateComboBox方法,但由于有更多的功能,我们计划添加到我们的组合框,以及从CComboBox派生一个新类:class CSmartComboBox : public CComboBox
{
protected:
CFont m_font;
public:
CSmartComboBox();
LONG m_lfHeight;
LONG m_lfWeight;
CString m_strFaceName;
BOOL CreateFont(LONG lfHeight, LONG lfWeight, LPCTSTR lpszFaceName);
// Generated message map functions
protected:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
DECLARE_MESSAGE_MAP()
};
CSmartComboBox::CSmartComboBox()
{
m_lfHeight = -10;
m_lfWeight = FW_NORMAL;
m_strFaceName = _T("MS Sans Serif");
m_nMaxStrings = 10;
}
BEGIN_MESSAGE_MAP(CSmartComboBox, CComboBox)
ON_WM_CREATE()
END_MESSAGE_MAP()
int CSmartComboBox::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CComboBox::OnCreate(lpCreateStruct) == -1)
return -1;
if( !CreateFont(m_lfHeight, m_lfWeight, m_strFaceName) )
{
TRACE0("Failed to create font for combo box\n");
return -1; // fail to create
}
return 0;
}
BOOL CSmartComboBox::CreateFont(LONG lfHeight, LONG lfWeight, LPCTSTR lpszFaceName)
{
// Create a font for the combobox
LOGFONT logFont;
memset(&logFont, 0, sizeof(logFont));
if (!::GetSystemMetrics(SM_DBCSENABLED))
{
// Since design guide says toolbars are fixed height so is the font.
logFont.lfHeight = lfHeight;
logFont.lfWeight = lfWeight;
CString strDefaultFont = lpszFaceName;
lstrcpy(logFont.lfFaceName, strDefaultFont);
if (!m_font.CreateFontIndirect(&logFont))
{
TRACE("Could Not create font for combo\n");
return FALSE;
}
SetFont(&m_font);
}
else
{
m_font.Attach(::GetStockObject(SYSTEM_FONT));
SetFont(&m_font);
}
return TRUE;
}
现在的组合框可以方便地进行调整,以反映应用程序的风格。添加响应用户命令
一旦组合框嵌入到工具栏,它的属性,可以在传统的方式访问。但为了提供迅速响应用户命令,嵌入式组合框需要配合其容器,即工具栏。然后,用户将能够键入一些文字组合框,按下"Enter",以及相应的命令发送到应用程序。
,我们会证明这一点有两个组合嵌入工具栏框与应用程序的步骤。这一点很重要,以验证该命令是正确的组合框获取。class CToolBarWithCombo : public CToolBar
{
public:
CSmartComboBox m_comboBox1;
CSmartComboBox m_comboBox2;
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CToolBarWithCombo)
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
//}}AFX_VIRTUAL
// The rest of the code is skipped
}
BOOL CToolBarWithCombo::OnCommand(WPARAM wParam, LPARAM lParam)
{
if( wParam == IDOK && lParam == 0 )
{
CString strText;
CString strCommand;
CComboBox* rgComboBox[] = {&m_comboBox1, &m_comboBox2};
for( int index = 0;
index < sizeof(rgComboBox) / sizeof(rgComboBox[0]);
++index )
{
if( rgComboBox[index]->GetEditSel() != 0 )
{
rgComboBox[index]->GetWindowText(strText);
strCommand.Format(_T("Command from ComboBox[%d]: %s"),
index+1,
(LPCTSTR)strText);
AfxMessageBox(strCommand);
rgComboBox[index]->AddString(strText);
rgComboBox[index]->SetWindowText(_T(""));
}
}
}
return CToolBar::OnCommand(wParam, lParam);
}
正如你可以看到,找到组合框具有焦点的伎俩是调用的GetEditSel功能。除非游标放置在一个组合框,该函数将返回0。管理组合框条目
最后我们改进的是创建一个组合框,将管理最近的用户条目。这种组合框通常人口与最近的搜索模式历史,已拨电话号码等,它们具有以下共同的特点:项目的最大数量是有限的,一旦达到此数量,新条目取代了最早的条目;条目被添加到列表的顶部;列表中不包含重复。
下面是代码,你会需要添加到CSmartComboBox:class CSmartComboBox : public CComboBox
{
// Only new code is shown
public:
int m_nMaxStrings;
int AddString(LPCTSTR str);
int InsertString(int index, LPCTSTR str);
};
int CSmartComboBox::AddString(LPCTSTR str)
{
if( _tcslen(str) == 0 )
return -1;
int oldIndex = FindStringExact(-1, str);
if( oldIndex >= 0 )
DeleteString(oldIndex);
if( GetCount() == m_nMaxStrings )
DeleteString(m_nMaxStrings-1);
return CComboBox::InsertString(0, str);
}
int CSmartComboBox::InsertString(int index, LPCTSTR str)
{
if( _tcslen(str) == 0 )
return -1;
int oldIndex = FindStringExact(-1, str);
if( oldIndex >= 0 )
{
DeleteString(oldIndex);
if( index >= oldIndex )
--index;
}
if( GetCount() == m_nMaxStrings )
DeleteString(m_nMaxStrings-1);
return CComboBox::InsertString(index, str);
}
如下这篇文章中的示例项目,包含源代码和测试的应用程序,演示嵌入式组合框。