在MFC对话框中,我将CComboBox
与CBS_DROPDOWNLIST
一起使用。它是所有者绘制的CComboBox
。
我要在列表框中列出组名称和组项目。使用链接https://www.codeproject.com/Articles/450/CComboBox-with-disabled-items中给出的源代码。
当我选择或单击组名称时,CComboBox
的编辑控件不应更新组项目文本。在该链接中,他们正在执行以下操作来摆脱选择组项目。
WM_LBUTTONUP
处理程序,我们实际上可以禁止单击组项目。 CharToItem
处理程序,我们可以禁用通过键盘选择组项目。CBN_SELENDOK
做出反应,我们可以确保未选择组项目。const UINT nMessage=::RegisterWindowMessage("ComboSelEndOK");
BEGIN_MESSAGE_MAP(CODrawCombo, CComboBox)
ON_CONTROL_REFLECT(CBN_SELENDOK, OnSelendok)
ON_REGISTERED_MESSAGE(nMessage, OnRealSelEndOK)
ON_CONTROL_REFLECT(CBN_EDITUPDATE, OnComboEdited)
ON_MESSAGE(WM_CTLCOLORLISTBOX, OnCtlColor)
END_MESSAGE_MAP()
void CODrawCombo::OnSelendok()
{
// TODO: Add your control notification handler code here
GetWindowText(m_strSavedText);
PostMessage(nMessage);
}
LRESULT CODrawCombo::OnRealSelEndOK(WPARAM,LPARAM)
{
CString currentText;
GetWindowText(currentText);
int index=FindStringExact(-1,currentText);
if (index>=0 && !IsItemEnabled)
{
SetWindowText(m_strSavedText);
GetParent()->SendMessage(WM_COMMAND,MAKELONG(GetWindowLong(m_hWnd,GWL_ID),CBN_SELCHANGE),(LPARAM)m_hWnd);
}
return 0;
}
void CListBoxInsideComboBox::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CRect rect; GetClientRect(rect);
if (rect.PtInRect(point))
{
BOOL outside=FALSE;
int index=((CListBox *)this)->ItemFromPoint(point,outside);
if (!outside && !m_Parent->IsItemEnabled(index))
return; // don't click there
}
CWnd::OnLButtonUp(nFlags, point);
}
单击组项目后,如果我单击CListBox
之外的地方,CComboBox
的编辑控件仅更新为组名?该如何解决?
答案 0 :(得分:0)
您的代码已准备好响应CBN_SELENDOK
,但在用户进行列表选择然后取消选择时未准备好。
您也可以回复CBN_SELENDCANCEL
通知。进行操作时,您可能需要响应CBN_SELCHANGE
,以使用户无法使用键盘更改为无效选择。
ON_CONTROL_REFLECT(CBN_SELENDCANCEL, CheckIfEnabled)
ON_CONTROL_REFLECT(CBN_SELCHANGE, CheckIfEnabled)
...
int m_save_index;
...
CExtendedComboBox::CExtendedComboBox()
{
m_save_index = 0;
m_ListBox.SetParent(this);
}
void CExtendedComboBox::OnSelendok()
{
GetWindowText(m_strSavedText);
PostMessage(nMessage);
int index = GetCurSel();
if(index >= 0 && IsItemEnabled(index))
m_save_index = index;
}
void CExtendedComboBox::CheckIfEnabled()
{
int index = GetCurSel();
if(index >= 0 && !IsItemEnabled(index))
SetCurSel(m_save_index);
}
顺便说一句,来自codeproject链接的代码有些陈旧。要正确地子类别化组合框的列表框,请使用GetComboBoxInfo
并将子类CListBox
进行子类别化。我不确定PostMessage
和OnRealSelEndOK
以及那里列出的其他一些功能的用途。