CComboBox中如何限制某些项目不被选中?

How to restrict some items to be not selected in CComboBox?

在 MFC 对话框中,我使用 CComboBoxCBS_DROPDOWNLIST。这是自画像 CComboBox

我正在列表框中列出群组名称和群组项目。使用linkhttps://www.codeproject.com/Articles/450/CComboBox-with-disabled-items.

中给出的源代码

当我select或点击组名时,CComboBox的编辑控件应该不会更新组项文本。在那个 link 中,他们正在做以下事情来摆脱 selection 组项目。

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 的编辑控件是否只更新了组名?如何解决?

您的代码已准备好响应 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 link 中的代码有点旧。要正确地继承组合框的列表框,请使用 GetComboBoxInfo 并继承 a CListBox。我不确定 PostMessageOnRealSelEndOK 以及那里列出的其他一些功能的目的是什么。