65.9K
CodeProject 正在变化。 阅读更多。
Home

扩展的 CComboBox

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.82/5 (40投票s)

2011 年 4 月 27 日

MIT

4分钟阅读

viewsIcon

171893

downloadIcon

6141

一个组合框控件,显示一个下拉窗口以帮助用户。

Mode: Standard

引言

我经常需要一个组合框,它可以根据我的意图提供建议,但我没有找到符合我需求的东西,所以我决定自己实现一个并分享它。我试图让它保持简单、标准且易于使用。

描述

我的类,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

    这种工作模式MODE_DROPDOWN可以通过CComboBoxExt::SetMode(CComboBoxExt::MODE_DROPDOWN);方法激活。

  • MODE_AUTOCOMPLETE,在这种模式下,组合框会显示一个下拉列表,该列表与编辑框中键入的字母匹配,并自动完成与编辑框中键入的字母匹配的单词。

    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.hComboBoxExt.cppComboBoxExtList.hComboBoxExtList.cpp文件添加到您的项目中,然后在您想使用此控件的地方,键入#include "ComboBoxExt.h"。此控件可以作为动态(或非动态)创建的控件使用。

演示项目

演示项目包含一个使用CComboBoxExt控件的SDI演示应用程序。CComboBoxExt的工作模式可以通过测试应用程序窗体上的单选按钮更改(在那里您会看到一些解释工作模式的工具提示),并且可以通过窗体上的Alert textAlert 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。
© . All rights reserved.