扩展的 CComboBox
一个组合框控件,显示一个下拉窗口以帮助用户。
引言
我经常需要一个组合框,它可以根据我的意图提供建议,但我没有找到符合我需求的东西,所以我决定自己实现一个并分享它。我试图让它保持简单、标准且易于使用。
描述
我的类,CComboBoxExt
(ComboBox Extended),派生自标准的CComboBox
(此解决方案的一个原因是保留标准的外观和行为),我在其中使用内部的CItemData
类来保存和处理所有组合框项的数据。
class CItemData : public CObject { // Attributes public: DWORD m_dwItemData; CString m_sItem; BOOL m_bState; // Implementation public: CItemData(); CItemData(DWORD dwItemData, LPCTSTR lpszString, BOOL bState); virtual ~CItemData(); };
内部功能通过以下方式解决:每次用户向组合框添加字符串时,都会创建一个新的CItemData
项,该项保留有关组合框项的所有信息。当用户从组合框中删除字符串时,它会删除与之关联的CItemData
对象。当用户在编辑框中键入字母时,组合框会删除与键入字母不匹配的项,但仅从组合框中删除,而不从关联的CItemData
对象中删除。
另一个特点是组合框的列表是子类化的。
void CComboBoxExt::PreSubclassWindow()
{
// TODO: Add your specialized code here and/or call the base class
COMBOBOXINFO cbi = {0};
cbi.cbSize = sizeof(COMBOBOXINFO);
BOOL bRet = SendMessage(CB_GETCOMBOBOXINFO, 0, (LPARAM)&cbi);
if(bRet && NULL != cbi.hwndList)
m_ListBox.SubclassWindow(cbi.hwndList);
....
CComboBox::PreSubclassWindow();
}
m_ListBox
的类型是CComboBoxExtList
,派生自CListBox
。
特点
ComboBoxExt
可以三种不同的方式运行。
MODE_STANDARD
,在这种模式下,列表功能类似于标准的CComboBox
控件。MODE_DROPDOWN
,在这种模式下,组合框会显示一个下拉列表,其中包含以编辑框中键入的字母开头的项。这种工作模式
MODE_DROPDOWN
可以通过CComboBoxExt::SetMode(CComboBoxExt::MODE_DROPDOWN);
方法激活。MODE_AUTOCOMPLETE
,在这种模式下,组合框会显示一个下拉列表,该列表与编辑框中键入的字母匹配,并自动完成与编辑框中键入的字母匹配的单词。这种工作模式
MODE_AUTOCOMPLETE
可以通过CComboBoxExt::SetMode(CComboBoxExt::MODE_AUTOCOMPLETE);
方法激活。
控件可以根据插入的最长项调整下拉列表的宽度,这项功能可以通过CComboBoxExt::AdjustDroppedWidth();
方法使用。
此外,还可以使用CComboBoxExt::AlertBkg();
和CComboBoxExt::AlertText();
方法更改编辑框文本或背景的颜色。
CCboBoxExt的另一项功能是可以在列表和编辑框上显示工具提示文本。此工具提示可以配置为以多种方式显示。
显示项文本,当项不适合组合框时,或显示与项文本不同的文本。为了获得与项文本不同的工具提示文本,您有几种
设置此工具提示文本的方法。
virtual int AddStringWithInfo(LPCTSTR lpszString, LPCTSTR lpszInfo, BOOL bShowItemTooltip = TRUE);<br />virtual int InsertStringWithInfo(int nIndex, LPCTSTR lpszString, LPCTSTR lpszInfo, BOOL bShowItemTooltip = TRUE);<br />virtual void SetLBInfo(int nIndex, LPCTSTR lpszInfo, BOOL bShowItemTooltip = TRUE);<br />virtual void GetLBInfo(int nIndex, LPCTSTR lpszInfo) const;<br />virtual void GetLBInfo(int nIndex, CString& rInfo) const;<br />virtual void SetLBShowItemTooltip(int nIndex, const BOOL bShow = TRUE);<br />virtual BOOL GetLBShowItemTooltipState(int nIndex) const;<br />virtual int FindInfo(int nStartAfter, LPCTSTR lpszString) const; virtual int FindInfoExact(int nIndexStart, LPCTSTR lpszFind) const; virtual int SelectInfo(int nStartAfter, LPCTSTR lpszString);
您甚至可以通过工具提示信息文本查找或选择一个组合框项。另一项功能是,您可以设置工具提示项,使其在项级别显示,也就是说,您可以指定哪个项显示工具提示,哪个项不显示工具提示。此外,您可以设置工具提示的位置:在项上方或紧邻项旁边。
void SetEditTooltip(const BOOL bShowTooltip, BOOL bTooltipOnInfo = FALSE, BOOL bShowEditTooltipOverItem = FALSE)<br />void SetListTooltip(const BOOL bShowTooltip, BOOL bTooltipOnInfo = FALSE, BOOL bShowListTooltipOverItem = FALSE)
正如您所看到的,您可以分别设置编辑组合框的工具提示和/或列表组合框的工具提示。
这种工具提示配置组合可以在演示项目中看到:带列表框旁边工具提示的组合框。
以及带列表项上方列表信息工具提示的组合框。
当您将控件设置为在编辑框上方显示工具提示时,您还可以设置工具提示显示的位置:紧挨着编辑框上方,或在其上方。
这可以通过使用CComboBoxExt::SetEditTooltipOverItemPosition(const BOOL bAbove = TRUE)
来完成。
使用控件
为了使用此控件,您可以简单地将ComboBoxExt.h、ComboBoxExt.cpp、ComboBoxExtList.h和ComboBoxExtList.cpp文件添加到您的项目中,然后在您想使用此控件的地方,键入#include "ComboBoxExt.h"
。此控件可以作为动态(或非动态)创建的控件使用。
演示项目
演示项目包含一个使用CComboBoxExt
控件的SDI演示应用程序。CComboBoxExt
的工作模式可以通过测试应用程序窗体上的单选按钮更改(在那里您会看到一些解释工作模式的工具提示),并且可以通过窗体上的Alert text和Alert background按钮来切换编辑框的颜色。
已知问题
由于CBN_EDITCHANGE
的反射方式,当您将在CDialogBarr
中使用此控件时,为了使用MODE_AUTOCOMPLETE
,您必须在派生的CDialogBar
类中处理ON_CBN_EDITCHANGE
。示例:
// CYourDlgBar header
class CYourDlgBar : public CDialogBar
....
// Generated message map functions
//{{AFX_MSG(CYourDlgBar)
afx_msg void OnEditchangeCombo();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
and in your implementation file:
// CYourDlgBar .cpp file
BEGIN_MESSAGE_MAP(CYourDlgBar, CDialogBar)
//{{AFX_MSG_MAP(CYourDlgBar)
ON_CBN_EDITCHANGE(IDC_COMBO_FILE, OnEditchangeCombo)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
.....
.....
void CYourDlgBar::OnEditchangeCombo()
{
// TODO: Add your control notification handler code here
// Do nothing
}
最后...
当前的实现为自定义控件的下拉列表提供了新的可能性……我希望这些功能很快会到来……
尽情享受吧!
历史
- 2011年4月26日:初始版本。
- 2011年7月13日:文章更新。
- 2011年10月10日:更新了控件存档。
- 2013年5月10日:更新了控件存档。
- 2013年6月10日:已解决Bug:当列表展开后变短时,列表没有保持在编辑框上。
- 2013年8月29日:更新了下拉列表工作模式。
- 2013年11月11日:控件的下拉列表已子类化。
- 2014年1月28日:添加了信息工具提示,更新了控件存档。
- 2014年2月17日:已解决Bug:在Win7上,当控件有样式时,工具提示会闪烁。
- 2014年3月21日:更新并简化了代码。
- 2015年12月11日:使用VS2008编译时工具提示不出现;已修复Bug。
- 2022年12月12日:以UNICODE编译时工具提示不出现;已修复Bug。
- 2023年2月14日:控件动态创建时抛出错误;已修复Bug。