- 下载source files - 32 Kb
- 下载demo project - 71 Kb
新闻!
本文的源代码和相关bug现在可以在谷歌code中找到:http://code.google.com/p/advcombobox/。
我把它移到了那里,这样每个人都可以报告bug并参与到控件的开发中来。我没有时间自己解决所有问题,如果你想帮忙,请发邮件到[email protected],我会把你加入到项目中。对于每一个新版本,我将继续在CodeProject.com更新这个页面。这个控件在这里已经有很长时间了,它仍然在使用,所以我想是时候更新一下了。
AdvComboBox文章索引
,, 介绍,, 安装
,, 功能
,, 通知
,, 风格
,, 未来的升级
,, 提示,提示
,, 改进和Bug修复
2.1版本有什么新特性
我已经厌倦了在InitDialog函数中添加所有项目,这在一个页面中有几个CAdvComboBox的情况下是很烦人的。这个类现在将在stringtable中查找与CAdvComboBox控件在资源编辑器中的ID相同的条目。演示项目已经升级,以显示此特性。有关这方面的更多信息已在安装中添加。如果您想添加另一个stringtable条目,只需调用新函数LoadString(UINT nID),其中nID引用stringtable条目。
在这个版本中,我添加了代码,以便CAdvComboBox可以与宏RUNTIME_CLASS一起使用。克里希纳请求的。
我还添加了缺少的通过Alt-Down或Alt-Up键打开下拉窗口的功能。这是托马斯·弗罗伊登伯格提出的要求。
介绍
我开始在另一个CListBox中有组合框的程序中使用一个控件。我想要的第一个标准是组合框应该是平的(没有阴影)。我看了一段时间,没有找到合适的,所以我必须创造自己的。当我开始在平面组合盒上工作时,我想到了另一个很酷的功能。有多少次你想要和IE地址栏一样的功能。当你输入一个地址,IAutoComplete COM-object开始工作。好极了!…与否。我希望在我的组合框中有同样的功能,尤其是可调整大小的下拉窗口。所以,回到起点。经过许多个漫长的夜晚和几种不同的方法,我终于成功了。
这个ComboBox不是MFC的CComboBox的子类,主要是因为我想能够调整下拉窗口的大小。相反,我创建了一个CWnd对象,它看起来几乎与MFC的CComboBox相同。棘手的部分是让下拉窗口以与CComboBox相同的方式做出反应。首先,下拉窗口必须是桌面的子窗口,然后还有一个讨厌的鼠标和键盘捕获问题。解决这个问题的方法是在一个窗口中包含一个列表框和一个滚动条。由于捕获问题,CListBox类使用的滚动条无法使用。
在开发过程中增加了更多的特性;下拉窗口中的选中项和禁用项。
下面是一个类结构的图片。
Picture 1
AdvComboBox的下拉窗口是autosize样式,也就是说,它计算显示列表中所有项目所需的大小。因此,结果是一个行为几乎与MFC的CComboBox相同的组合框。您不应该更改任何已经在使用中的代码,除此之外,您必须将资源从标准的组合框更改为自定义控件。我已经测试了W2K和XP。现在我求助于CodeProject的成员和其他人来帮助我测试和查找bug,也许还需要添加一些新特性。
安装
在MFC DLL中使用CAdvComboBox创建一个新的项目来升级你的当前项目
本文包含在项目中实现CAdvComboBox类的三种不同方法。一个描述了新项目的工作顺序,第二个描述了如何升级当前项目,最后一个描述了如何在MFC DLL中实现CAdvComboBox。
创建一个新项目
-
使用App向导创建一个对话框应用程序。下面的解释建立在调用应用程序AdvCBDemoInsert到工作空间的基础上 AdvComboBox.hAdvComboBox.cppDropWnd.hDropWnd.cppDropListBox.hDropListBox.cppDropScrollBar.hDropScrollBar.cppVisualStylesXP.hVisualStylesXP.h 在您的对话框资源编辑器中添加一个自定义控件,使用工具栏中的自定义控件工具在对话框中放置一个新的自定义控件。输入控件的属性,如下图所示。CAdvComboBox自定义控件类名是AdvComboBoxCtrl,它是在AdvComboBox.h中定义的。
-
Picture 2 描述不同的风格设置: ,组合style 价值财产window CBS_DROPDOWN 0 x_____002 CBS_DROPDOWNLIST 0 x_____103 CBS_AUTOHSCROLL 0 x_____043 x_____103 CBS_SORT 0 因此,这意味着如果您希望您的combobox具有CBS_DROPDOWN、CBS_AUTOHSCROLL和CBS_SORT样式,那么样式值应该以142结束(如图2所示)。然后资源编辑器将您选择的样式转换为此值。 以下风格尚未实现的:,,,CBS_DISABLENOSCROLL ,, CBS_HASSTRINGS ,, CBS_LOWERCASE ,, CBS_NOINTEGRALHEIGHT ,, CBS_OEMCONVERT ,, CBS_OWNERDRAWFIXED ,, CBS_OWNERDRAWVARIABLE ,, CBS_SIMPLE , CBS_UPPERCASE 在AdvCBDemoDlg.h头文件中,将以下公共成员变量添加到CAdvCBDemoDlg类中: 隐藏,复制codecadvcombobox m_ctladvcombo; 在AdvCBDemoDlg.cpp文件中添加以下DXX_调用 隐藏,复制CodeDDX_Control(pDX, IDC_ADV_COMBO, m_ctlAdvCombo); 将它添加到AFX_DATA_MAP之外,以避免将来发生任何事故。现在,函数DoDataExchange(…)应该如下所示: 隐藏,复制co全无CAdvCBDemoDlg::DoDataExchange(CDataExchange* pDX) { CDialog: DoDataExchange (pDX); / / {{AFX_DATA_MAP (CAdvCBDemoDlg) //注意:ClassWizard会在这里添加DDX和DDV调用 / /}} AFX_DATA_MAP DDX_Control (pDX IDC_ADV_COMBO m_ctlAdvCombo); } 现在你应该可以用AdvComboBox来测试你的对话框了。 另一个需要实现的特性是如何从控件中获取和设置数据。下面对此进行了描述。 你可以使用相同的方法来获取和设置数据,就像你会与一个普通的CComboBox,除了一个小的区别。DDX_CBIndex和DDX_CBString应该更改为DDX_ACBIndex和DDX_ACBString才能工作。这些函数可以在AdvComboBox.cpp文件中找到。 要添加获取和设置数据的功能,请在AdvCBDemoDlg.h文件中添加以下一个或两个变量 隐藏,复制codeint m_nadvcombo; 装运箱m_stradvcombo; 您还必须在CAdvCBDemoDlg的构造函数中初始化这些变量的值。在AFX_DATA_INIT外部添加以下代码。 隐藏,复制Codem_nAdvCombo = -1; m_strAdvCombo = " "; 还要在步骤6中添加的DDX_Control下面的AdvCBDemoDlg.cpp文件中的函数DoDataExchange(…)中添加DDX_调用。 隐藏,复制CodeDDX_ACBIndex(pDX, IDC_ADV_COMBO, m_nAdvCombo); DDX_ACBString(pDX, IDC_ADV_COMBO, m_strAdvCombo); 你现在应该能够使用AdvComboBox控件,就像MFC的CComboBox一样。 版本2.1中添加了以下内容 使用stringtable条目填充CAdvComboBox列表。为了能够在这个组合框中使用stringtable,必须使用与在资源编辑器中创建的控件相同的标识符创建一个stringtable条目。在本例中,stringtable条目ID应该是IDC_ADV_COMBO。下面是这个示例的图片(图3),您可以将其添加到您的项目中。在stringtable条目中,一个换行符('\n')表示组合框列表中一个项的结束。请查看演示项目以获得关于如何实现此功能的进一步信息。
-
Picture 3
升级当前项目
这个描述不像上面的描述那么详细。希望您有足够的知识来管理以下内容。-
将以下文件插入您的工作区 AdvComboBox.hAdvComboBox.cppDropWnd.hDropWnd.cppDropListBox.hDropListBox.cppDropScrollBar.hDropScrollBar.cppVisualStylesXP.hVisualStylesXP.h 在头文件中包含AdvComboBox.h文件 在头文件中将所有的CComboBox变量定义重命名为CAdvComboBox。替换资源组合框替换资源编辑器中的当前组合框以自定义控件并设置如图2所示的属性。当然,您可以更改自定义控件的样式。 提示!对自定义控件使用与组合框相同的ID。这使它更加容易,因此您不必更改所有事件(ON_CBN_SELCHANGE等)的ID。 改变所有的DDX_CBIndex和DDX_CBString到DDX_ACBIndex和DDX_ACBString在你的。cpp文件。如果你没有在你的新自定义控件上设置相同的ID,就改变这些调用中的ID。编译和测试您的项目现在应该可以工作,除了CAdvComboBox的限制。
在MFC DLL中使用CAdvComboBox
这只是一个关于如何在DLL中有windows(对话框)的DLL中使用这个类的简短描述CAdvComboBox
。为了能够注册类,您必须对代码进行一些更改。的
实例句柄
结构
WNDCLASS
必须有DLL的
实例句柄
,而不是调用应用程序
实例句柄
。
-
像这样声明一个CAdvComboBox变量: 隐藏,复制CodeCAdvComboBox m_ctlAdvCombo(TRUE) 你还必须在DLL项目中添加一个全局HINSTANCE变量。添加以下文件,例如,StdAfx.cpp在你的DLL项目: 隐藏,复制CodeHINSTANCE g_hDLLInstance = NULL; 然后,在StdAfx.h文件中添加extern定义,如下所示: 隐藏,复制Codeextern HINSTANCE g_hDLLInstance; 初始化DllMain函数中的全局HINSTANCESet hDllInstance。 隐藏,复制Codeg_hDLLInstance = hInstance; 接下来要做的是在AdvComboBox.cpp文件中找到RegisterWindowClass()函数。改变函数,使它看起来像这样: 隐藏,复制CodeBOOL CAdvComboBox: RegisterWindowClass () { WNDCLASS wndcls; 实例句柄hInst; 如果(m_bInst) { hInst = g_hDLLInstance; } 其他的 { hInst =()句柄; } 断言(hInst != 0); … 返回TRUE; } 最后导出CAdvComboBox类,但同样重要的是,如果你想在DLL之外使用它,你必须导出这个类。记住还要导出两个DDX_函数。类定义: 隐藏,复制Codeclass摔交declspec(dllexport) CAdvComboBox: public CWnd DDX_定义: 隐藏,复制Code_declspec(dllexport) void AFXAPI DDX_ACBIndex(CDataExchange* pDX, int nIDC int&指数); (ddataexchange * pDX) int nIDC CString&值);
AdvComboBox功能
中的函数CAdvComboBox
类与MFC中的相同
CComboBox
。如果需要更多的帮助,请访问MSDN。
还有一些额外的功能可以使用。这些内容如下所述
- GetComboRect 描述:使用此函数检索组合框的pos和大小。GetComboRect()返回AdvComboBox的Rect ,
- 在ver 2.0中有新的版本 描述:返回下拉窗口可见项的默认数量。使用SetDefaultVisibleItems(int)定义:int GetDefaultVisibleItems()返回:条目的数量。 ,
- GetItemChecked 定义:BOOL GetItemChecked(int nIndex)参数:列表中的nindex&item index返回:TRUE if Item nIndex被检查,或者CB_ERR如果发生错误。 ,
- GetItemDisabled 定义:BOOL GetItemDisabled(int nIndex)参数:列表中的nindex&item index返回:TRUE如果nIndex被禁用,或者CB_ERR如果发生错误。 ,
- 在ver 1.2中是新的 描述:在dropwindow将被放置在combobox之上之前,获取最小可见列表框项目。定义:int GetMinVisibleItems()返回:最小可见列表框项目的数量。 ,
- 在ver 2.1中,LoadString nbsp 描述:从stringtable加载一个条目,并在dropwindow列表中添加条目。定义:void LoadString(UINT nStringID)参数:nStringIDID加载的字符串返回:void ,
- ModifyACBStyle 描述:修改CAdvComboBox的样式。可以在这里找到可用的样式。这个函数只处理ACBS_样式。它的工作作为MFC的ModifyStyle. 定义:void ModifyACBStyle(UINT nRemoveStyle, UINT nAddStyle) 参数:nRemoveStyle ACBS样式添加。 ,
- PointInWindow 定义:BOOL PointInWindow(CPoint ptScreenPoint)参数:ptScreenPoint是否在combobox中。如果该点在combobox窗口中,返回:TRUE。 ,
- 在ver 2.0中新增了SetDefaultVisibleItems 描述:设置下拉窗口中默认可见的项目数。定义:void SetDefaultVisibleItems(int nItems = -1);参数:nItems 显示下拉窗口时可见的项目数。如果样式应该是autosize. return:void,则设置为-1 ,
- SetItemChecked 中,描述:设置一个项目组合又是检查或如故;定义:空白SetItemChecked (int nIndex BOOL bChecked),参数:nIndex 从零开始的项索引项设置只参数:bChecked 新状态的项目设置只回报:空白 ,
- SetItemDisabled 中,描述:设置一个项目组合禁用或启用只定义:空白SetItemDisabled (int nIndex BOOL bDisabled),参数:nIndex 从零开始的项索引项设置只参数:bDisabled 新状态的项目设置只回报:空白 ,
- setminvisibleitem nbsp;在ver 1.2中是新的 描述:在dropwindow被放置在组合框上方之前,设置最小可见列表框项目。默认是五个项目。定义:void SetMinVisibleItems(int nMinItems)参数:nminitems&minimum listbox项目的数量 ,
- DDX_ACBIndex 描述:使用这个函数来获取和设置数据与MFC的UpdateData(…)的定义:void AFXAPI DDX_ACBIndex(CDataExchange* pDX, int nIDC, int&指数) ,
- DDX_ACBString 描述:使用这个函数来获取和设置MFC的UpdateData(…)数据定义:void AFXAPI DDX_ACBString(CDataExchange* pDX, int nIDC, CString&)值)
下面是CAdvComboBox中实现的CComboBox函数列表。
- AddString
- DeleteString
- 中
- FindStringExact
- GetCount
- GetCurSel
- GetDroppedControlRect
- GetDroppedState
- GetEditSel
- GetItemData
- GetItemDataPtr
- GetLBText
- GetLBTextLen
- GetTopIndex
- InsertString
- LimitText nbsp;在第1.2条新
- ResetContent
- SelectString
- SetCurSel
- SetEditSel
- SetItemData
- SetItemDataPtr
- SetTopIndex
- ShowDropDown
下面的CComboBox函数在CAdvComboBox中没有实现
- 清晰的
- CompareItem
- 复制
- 减少
- Dir
- DrawItem
- DeleteItem
- GetDroppedWidth
- GetExtendedUI
- GetHorizontalExtent
- GetItemHeight
- GetLocale
- MeasureItem
- 粘贴
- SetDroppedWidth
- SetExtendedUI
- SetHorizontalExtent
- SetItemHeight
- SetLocale
AdvComboBox通知
的CAdvComboBox
发送以下通知给父的,作为MFC的
CComboBox
所做的事。
- CBN_CLOSEUP
- CBN_DROPDOWN
- CBN_EDITCHANGE
- CBN_EDITUPDATE
- CBN_KILLFOCUS
- CBN_SELCHANGE
- CBN_SELENDCANCEL
- CBN_SELENDOK
- CBN_SETFOCUS
没有发送以下通知。
- CBN_DBLCLKThis消息仅在combobox样式为CBS_SIMPLE且CAdvComboBox不支持此样式时发送。
- 这个控件还没有内置内存管理,我不确定是否会这样做。无聊!
AdvComboBox风格
的CAdvComboBox
有自己的风格。这里对它们进行了描述。
- acbs_flatmake the combobox flat。使用这种样式,combobox将一直绘制到资源中自定义控件矩形的边界。
- 使用这种样式,组合框将被绘制成一个普通的组合框,即3D外观。
- 要使下拉窗口包含可检查列表,请使用这种样式。
- AdvComboBox将自动搜索dropwindow项目,在与已在AdvComboBox的编辑框中输入的文本最接近的匹配之后。如果找到,则将其余文本追加到编辑框。
- 当在编辑框中输入文本时,AdvComboBox将在下拉窗口中显示与输入文本匹配的列表。
CAdvComboBox支持以下CComboBox样式
- CBS_AUTOHSCROLL
- CBS_DROPDOWN
- CBS_DROPDOWNLIST
- CBS_SORT
不支持以下CComboBox样式
- CBS_DISABLENOSCROLL
- CBS_HASSTRINGS
- CBS_LOWERCASE
- CBS_NOINTEGRALHEIGHT
- CBS_OEMCONVERT
- CBS_OWNERDRAWFIXED
- CBS_OWNERDRAWVARIABLE
- CBS_SIMPLE
- CBS_UPPERCASE
未来的升级
- net兼容
提示,提示
- 使用ClassWizardCreate您的项目与MFC的CComboBox,这样ClassWizard可以帮助您实现通知,如ON_CBN_SELCHANGE。当你为combobox创建了所有的事件后,更改为CAdvComboBox。这是实现这个类最简单、最快的方法。
- 在OnInitDialog()中添加一个对ModifyACBStyle(…)的调用,如下: 隐藏,Codem_ctlAdvCombo副本。ModifyACBStyle(0, ACBS_FLAT);
- 在我测试过的范围内,AdvComboBox是兼容主题的。如果颜色或其他方面有问题,请告诉我。在告诉我之前,请再和CComboBox做一次比较。
改进和Bug修复
版本2.1
- 具有相同ID的Stringtable条目将填充列表。
- 添加函数LoadString(单位)
- 现在可以使用宏RUNTIME_CLASS了。在这个版本中,我在代码中添加了CAdvComboBox,这样CAdvComboBox就可以与宏RUNTIME_CLASS一起使用。克里希纳请求的。
- 按Alt+上/下键打开下拉窗口。增加了通过Alt-Down或Alt-Up键打开下拉窗口的功能。这是Thomas Freudenberg的请求。
版本2.0
- 添加函数GetDefaultVisibleItems ()
- 添加函数SetDefaultVisibleItems (int)
- 添加CAdvComboBox样式的ACBS_AUTOAPPEND
- 添加了CAdvComboBox风格的ACBS_AUTOSUGGEST
- CAdvComboBox现在也与CommCtrl 6.0清单兼容。我使用David Yuheng Zhao的类CVisualStylesXP作为工作基础,但我已经添加了一些功能,如从DLL获取的函数现在是静态函数,和一个函数检查CommCtrl DLL版本,看看我们是否能够使用视觉风格。如果一个清单没有被使用,这个函数会告诉我们即使我们在WinXP上运行。
- 添加了两个新文件:VisualStylesXP.h和VisualStylesXP.cpp
版本1.21
- 修正了使用Create(…)时的错误当试图用函数create(…)创建CAdvCombBox类,样式为CBS_DROPDOWN时,出现了这个错误。感谢找到这个bug。
版本1.2
- 实现了鼠标滚轮滚动下拉窗口。
- CComboBox函数LimitText现在已经实现。
- 不再需要Windows定义_WIN32_WINNT。
- 如果到屏幕底部的距离不够,下拉窗口将显示在组合框的上方。默认的listbox项目的最小数目设置为5,但是这个值可以通过调用CAdvComboBox类中的SetMinVisibleItems(int)函数来更改。
版本1.1
- 现在可以禁用该控件。
- 切换到另一个程序时,dropwindow关闭。
- 修正了Win2K下的一个小绘图错误。
本文转载于:http://www.diyabc.com/frontweb/news13688.html