注意:
ComboBoxEx虽然继承与CComboBox,但不可以使用CComboBox的如下函数:(使用时产生ASSERT断言失败)
_AFXCMN_INLINE int CComboBoxEx::Dir(UINT attr, LPCTSTR lpszWildCard)
{ UNUSED_ALWAYS(attr); UNUSED_ALWAYS(lpszWildCard);
ASSERT(FALSE); return CB_ERR; }
_AFXCMN_INLINE int CComboBoxEx::FindString(int nIndexStart, LPCTSTR lpszFind) const
{ UNUSED_ALWAYS(nIndexStart); UNUSED_ALWAYS(lpszFind);
ASSERT(FALSE); return CB_ERR; }
_AFXCMN_INLINE int CComboBoxEx::AddString(LPCTSTR lpszString)
{ UNUSED_ALWAYS(lpszString); ASSERT(FALSE); return CB_ERR;}
_AFXCMN_INLINE BOOL CComboBoxEx::SetEditSel(int nStartChar, int nEndChar)
{ UNUSED_ALWAYS(nStartChar); UNUSED_ALWAYS(nEndChar);
ASSERT(FALSE); return FALSE; }
_AFXCMN_INLINE int CComboBoxEx::InsertString(int nIndex, LPCTSTR lpszString)
{ UNUSED_ALWAYS(nIndex); UNUSED_ALWAYS(lpszString);
ASSERT(FALSE); return CB_ERR; }
创建扩展组合框 (Extended Combo Box) 控件的方式取决于是在对话框中使用该控件还是在非对话框窗口中创建此控件。
直接在对话框中使用 CComboBoxEx
- 在对话框编辑器中,将“Extended Combo Box”控件添加到对话框模板资源。指定其控件 ID。(实践证明不可以使用Combo Box控件资源)
- 使用扩展组合框 (Extended Combo Box) 控件的“属性”对话框指定任何所需样式。
- 使用添加成员变量向导添加带 Control 属性的 CComboBoxEx 类型的成员变量。可以使用此成员调用 CComboBoxEx 成员函数。
- 对于任何需要处理的扩展组合框 (Extended Combo Box) 控件通知消息,使用“属性”窗口在对话框类中映射处理函数(请参见将消息映射到函数)。
- 在 OnInitDialog 中为 CComboBoxEx 对象设置任何附加样式。
在非对话框窗口中使用 CComboBoxEx
- 在视图或窗口类中定义此控件。
- 调用控件的 Create 成员函数,可能在 OnInitialUpdate 中,也可能与父窗口的 OnCreate 处理函数一样早。设置此控件的样式。
扩展组合框 (Extended Combo Box) 控件的主要功能是可以将图像列表中的图像与组合框 (ComboBox) 控件中的各项相关联。每项都可以显示三个不同的图像:一个是选定状态的图像,一个是未选定状态的图像,第三个是覆盖图像的图像。
下面的过程将图像列表与扩展组合框 (Extended Combo Box) 控件相关联:
将图像列表与扩展组合框 (Extended Combo Box) 控件相关联
- 通过使用 CImageList 构造函数并存储所得到的指针来构造新的图像列表(或者使用现有图像列表对象)。
- 通过调用 CImageList::Create 初始化新的图像列表对象。以下代码是此调用的一个示例。
m_pImageList->Create(16, 16, ILC_COLOR, 2, 2);
- 为每个可能的状态添加可选图像:选定、未选定或覆盖。下面的代码添加三个预定义图像。
m_pImageList->Add(pApp->m_hIconSelected); m_pImageList->Add(pApp->m_hIconNotSelected); m_pImageList->Add(pApp->m_hIconOverlay);
- 通过调用 CComboBoxEx::SetImageList 将图像列表与控件相关联。
扩展组合框项所使用的不同类型的图像由 COMBOBOXEXITEM 结构的 iImage、iSelectedImage 和 iOverlay 成员中的值确定。每个值是关联控件图像列表中的图像索引。默认情况下,这些成员设置为 0,使控件不显示项的图像。如果要将图像用于特定项,可以在插入组合框项时相应地修改结构,或通过修改现有组合框项相应地修改结构。
设置新项的图像
如果正在插入新项,请使用正确的值初始化 iImage、iSelectedImage 和 iOverlay 结构成员,然后通过调用 CComboBoxEx::InsertItem 插入项。
下面的示例将新扩展组合框项 (cbi
) 插入扩展组合框 (Extended Combo Box) 控件 (m_comboEx
),并为所有三个图像状态提供索引:
COMBOBOXEXITEM cbi; CString str; int nItem; cbi.mask = CBEIF_IMAGE | CBEIF_INDENT | CBEIF_OVERLAY | CBEIF_SELECTEDIMAGE | CBEIF_TEXT; cbi.iItem = i; str.Format(_T("Item %02d"), i); cbi.pszText = (LPTSTR)(LPCTSTR)str; cbi.cchTextMax = str.GetLength(); cbi.iImage = 0; cbi.iSelectedImage = 1; cbi.iOverlay = 2; cbi.iIndent = (i & 0x03); //Set indentation according //to item position nItem = m_comboEx.InsertItem(&cbi); ASSERT(nItem == i);
设置现有项的图像
如果正在修改现有项,需要使用 COMBOBOXEXITEM 结构的 mask 成员。
修改现有项以使用图像
- 声明 COMBOBOXEXITEM 结构并将 mask 数据成员设置为要修改的值。
- 使用此结构调用 CComboBoxEx::GetItem。
- 使用适当的值修改刚返回的结构的 mask、iImage 和 iSelectedImage 成员。
- 传入已修改的结构来调用 CComboBoxEx::SetItem。
下面的示例通过交换第三个扩展组合框项的选定和未选定图像说明此过程:
COMBOBOXEXITEM cbi; CString str; int nItem; cbi.mask = CBEIF_IMAGE | CBEIF_SELECTEDIMAGE; cbi.iItem = 2; m_comboEx.GetItem(&cbi); cbi.iImage = 1; cbi.iSelectedImage = 0; nItem = m_comboEx.SetItem(&cbi); ASSERT(nItem != 0);
第二部分:
获取CComboBoxEX控件中项目的文字部分:
1.若样式为Drop Down
CEdit* pedit=m_comboEx.GetEditCtrl();
CString str;
pedit->GetWindowText(str);
2.若样式为Drop List
CString str;
int i=m_comboEx.GetCurSel(); int n=m_comboEx.GetLBTextLen(i); m_comboEx.GetLBText(i,str);
补充CImageList知识:
ILC_COLOR 缺省模式,默认=ILC_COLOR4。老版本的系统是ILC_COLORDDB使用设备依赖位图。 ILC_COLOR4 4位DIB位图,表示生成的位图每个像素是由4位组成,也就是16色位图。 ILC_COLOR8 同上,8位位图,256色。 ——上面2个都要用到调色板。 ILC_COLOR16 16 位DIB(32/64k 色) 位图。 ILC_COLOR24 24 位真彩色位图。 ILC_COLOR32 32位真彩,显示效果跟ILC_COLOR24位一样,多了一个Alpha通道,记录透明度,方便操作。 ILC_COLORDDB 设备依赖位图,表示颜色位跟设备(操作系统记录着)相关。 ILC_MASK 使用掩膜,当前ImageList使用2个位图,如果指定了一个单色位图,就将其做为掩膜,掩膜是用来透明的,就是显示时候不绘制背景——这样看起来效果很真实,xp操作系统桌面的图标就是这个效果。 参数写0,就==ILC_COLOR。默认例子:int nServerInfo = m_serverMap.size(); m_Combo_SeverName.ResetContent(); BOOL bImage = TRUE; CImageList imageList;CBitmap bitMap; if(!imageList.Create(16,16,ILC_COLOR32|ILC_MASK,1,0) ||!bitMap.LoadBitmap(IDB_BITMAP_COMBOBOX_SERVER)) { TRACE("列表框Image List加载失败!"); bImage = FALSE; } else { bImage = TRUE; imageList.Add(&bitMap,RGB(0,0,0)); m_Combo_SeverName.SetImageList(&imageList); bitMap.Detach(); imageList.Detach(); } for (int i = 0; i < nServerInfo ; i++) { ServerMap_ConstItor itor = m_serverMap.find(i); ASSERT(itor != m_serverMap.end()); CString text; text = itor->second.RemoteARName; COMBOBOXEXITEM insItem; insItem.mask=(bImage == TRUE? (CBEIF_TEXT|CBEIF_SELECTEDIMAGE|CBEIF_IMAGE) :CBEIF_TEXT); insItem.iItem=itor->first; insItem.iImage=0; insItem.iSelectedImage = 0; insItem.pszText = (LPTSTR)(LPCTSTR)text; int index = m_Combo_SeverName.InsertItem(&insItem); ASSERT(index == itor->first); }消息响应要点:1.ON_CBN_SELCHANGE用户在列表中单击或者利用箭头键选择了另一个项,从而引起了选中项的改变。在处理此消息时,编辑控件中的文本只能通过GetLBText或者类似的某个函数存取。不能使用GetWindowText函数。实践表明:这时调用GetWindowText函数可以拿到正确的文本。2.ON_CBN_EDITCHANGE用户发出了一个可能改变编辑控件中文本的动作。与消息CBN_EDITUPDATE不同,本消息是在Windows刷新屏幕之后发出的。风格为CBS_DROPDOWNLIST的组合框没有该通知。实践表明,ON_CBN_EDITCHANGE在ON_CBN_SELECTCHANGE之前进行响应。实践表明:这时调用GetWindowText函数可以拿到正确的文本。3.ON_CBN_SELENDOK用户在选择了一项以后,要么按了ENTER键,要么按了向下箭头键,从而隐藏了组合框的列表。此通知消息在CBN_CLOSEUP之前发送,表明用户的选择将不被认为是有效的。即使没有发送CBN_CLOSEUP通知消息,也会发送CBN_SELENDCANCEL或CBN_SEL-ENDOK消息(例如风格为CBS_SIMPLE的组合框)。实践表明:ON_CBN_SELENDOK在ON_CBN_EDITCHANGE之前进行响应。实践表明:这时调用GetCurSel拿到正确的索引,再用GetLBText拿到选择的文本,而用GetWindowText拿到之前的文本,不是选择后显示的文本,因为这时控件中的Edit部分还没有更新显示。
3.在调用CComboBox::SetCurSel()更新选择时不会立即发送CBN_SELCHANGE消息,因此调用SetCurSel()来触发CBN_SELCHANGE消息响应是错误的。调用SetCurSel()时只是更新了CComboBox内部的索引值,该索引值就是通过GetCurSel()获得的值。即使调用UpdateData也不行。
4.对于DropDownList风格的组合框不会触发CBN_EDITCHANGE消息发送(即使是选择触发编辑框内容被改变也不会发送),对于其他风格的组合框才会在内容改变时触发CBN_EDITCHANGE消息(用ON_CBN_EDITCHANGE响应)。