自定义分组组合框






4.80/5 (16投票s)
2001年6月13日
3分钟阅读

213320

3718
一个类似组合框的控件,允许下拉列表中的元素进行分组。
引言
在开发一个较大的应用程序时,我发现自己需要一个可以内部进行分组的CCombobox
类型的控件。我希望该控件更像一个按钮装置,但带有一个用户可以选择的下拉列表...因此创建了 CDropButton
类。您可能之前在 Microsoft Money 中见过这种类型的控件。这是一种对下拉列表中的项目进行分组的绝佳方法。
该控件的功能非常强大,使用 CButton
类作为主类,以及 CWnd
和 CListbox
用于显示数据。它是完全可定制的,可以更改几乎所有内容的颜色,除了滚动条,这可能会在以后实现。
它的工作方式类似于普通的 CCombobox
,只是项目分组在标题下。 标题以粗体和区分线显示。 标题本身是不可选择的,并且其数据是按字母顺序排列的。 CDropButton
可以设置为用选择替换按钮上的文本,或者不替换。
以下是默认控件的样子
以下是自定义控件的样子(漂亮吗?)
该控件非常易于使用
使用以下创建方法创建一个默认的 CDropButton
m_pDropBtn = new CDropButton(); m_pDropBtn->Create("Options", CRect(100,100,280,120), this, ID_DROP_BUTTON);
您还可以在创建中发送大量选项,以便根据您的喜好进行自定义!
COLORREF crButtonBackgroundColor = RGB(150,0,0); COLORREF crButtonBackgroundOverColor = RGB(200,50,50); COLORREF crButtonTxtColor = RGB(255,255,255); COLORREF crButtonTxtOverColor = RGB(255,255,150); CFont* pTextFont = NULL; m_pDropBtn->Create("Options", CRect(300,100,450,120), this, ID_DROP_BUTTON, crButtonBackgroundColor, crButtonBackgroundOverColor, crButtonTxtColor, crButtonTxtOverColor, pTextFont); // Set OPTIONAL parameters m_pDropBtn->SetListHeight(200); // Set the Width Height m_pDropBtn->SetListWidth(170); // Set the List Width m_pDropBtn->ChangeTitleWithSelection( false); // When the users selects an item change the title in the top
在上面的例子中,我没有设置字体,但这是可以的,默认为 14 磅的 Arial。'crButtonBackgroundOverColor' 参数使按钮在鼠标经过控件时改变颜色。
创建 CDropButton 后,您可以获取列表框并设置可选属性。
// Get the CListBox CDropList* pList = m_pDropBtn->GetList(); // Set OPTIONAL paramters pList->SetBkColor(crBkListColor); // List background COlor pList->SetHighlightBkColor( RGB(255,255,100)); // List highlight background color
然后添加数据。 第一组中的项目没有标题。 您可以使用标准的 CListBox AddString
函数来添加它们。
// Add default Items pList->AddString("Split/Multiple Catagories..."); pList->AddString("Add New Category...");
您可以将特定项目添加到组。 您将组指定为第二个参数。 第三个和第四个参数是该特定项目的可选文本颜色。 每个项目都可以有特定的颜色!
// Add specific items with COLOR!! pList->AddString("EXPENSE", 2, RGB(128,0,0), RGB(255,0,0)); pList->AddString("Automobile", 2); pList->AddString("Health Care", 2); pList->AddString("Gifts", 2); pList->AddString("INCOME", 3, RGB(0,128,0), RGB(0,255,0)); pList->AddString("Wages/Salary", 3); pList->AddString("Retirement Income", 3); pList->AddString("Other Income", 3); pList->AddString("SPECIAL", 4, RGB(0,0,128), RGB(0,0,255)); pList->AddString("Transfer", 4); pList->AddString("Loan Payment", 4); pList->AddString("Clothing", 2); // Out of order but OK!
该控件仅发回一条消息。 它向您发送一个 CM_SELECTION_CHANGED
消息,以告知您何时选择已更改。 要实现它,请将以下语句放在您的消息映射中
ON_MESSAGE(CM_SELECTION_CHANGED, OnSelectionChanged)
将此行放在您的头文件中
afx_msg LONG OnSelectionChanged(UINT wParam, LONG lParam);
处理此问题的函数看起来类似于这样
LONG CTestView::OnSelectionChanged(UINT wParam, LONG lParam) { // What control sent the message CDropList* pList; switch(wParam) { case ID_DROP_BUTTON: pList = m_pDropBtn->GetList(); break; case ID_DROP_BUTTON2: pList = m_pDropBtn2->GetList(); break; } // Get the Current Selection and Display it CString csText; pList->GetText(pList->GetCurSel(), csText); AfxMessageBox(csText); return 1; }wParam 是发送消息的控件的 ID。
大多数标准的 CListBox
函数都可以工作,除了少数几个。 我没有测试过它是否适用于多重选择 CListBox
! 在我的例子中,我不需要这个,因此没有尝试考虑它。 此外,InsertString
将不起作用,该控件会处理数据项的位置。
RemoveString
确实有效,但在删除标题项目时略有不同。 当删除标题项目时,其所有子项也会被删除。
大多数其他标准函数应该可以工作(SelectString
、SetCurSel
等),但请注意我没有测试所有这些函数。 务必先尝试一下!
最后一件事,水平滚动不起作用! 我认为对于这个控件来说,这是不必要的。 但是,如果您确实需要它,只需将样式添加到 CDropList
。
CDropButton
背后的代码应该非常容易理解和修改。 如果您对代码进行更改(例如自定义滚动条),请发送给我一份副本! 我很乐意看到它!
这是在 Windows 2000 上使用 Visual C++ 6.0 创建的。