CComboBox在下拉时不选择CurSel

时间:2016-04-08 14:51:58

标签: c++ winapi combobox mfc ccombobox

我在对话框中有一个按字母顺序排序的组合框。此组合包含多个字符串,但有些字符串与不同的情况重复。即我们有'开'和'开','关'和'关'。这可能看似多余,但有一个原因,尽管现在这并不重要。

副本显然在列表中一个接一个地出现,首先是大写字符串。即:

  

OFF

     

     

     

当用户选择“开”(小写)时,正确的索引设置为CurSel并显示正确的字符串。但是,当我单击组合框的箭头以下拉列表时,它不会突出显示CurSel,而是突出显示它之前的大写字符串。见下图。

这是在下拉列表中选择的:

Selected item before dropdown

这是在扩展下拉列表时在组合框中选择的内容。

Selected item after dropdown

我已经捕获了ON_CBN_DROPDOWN消息,并检查了cursel值,它就像我预期的那样。

我还已经将这个组合框子类化了,这样我就能以区分大小写的方式搜索这个列表中的字符串,因为我知道它没有正常实现,所以它可能是导致我的问题的原因。

但我不明白为什么字符串会在这个阶段覆盖cursel值? CurSel值是否应该是用于选择相关项目的值?

如何解决这个问题的任何想法将不胜感激。

修改 我试图通过覆盖OnWndMsg来捕获CBN_DROPDOWN消息。出现此消息时,我会在下拉菜单之前获取当前选定的项目(这是正确的项目)。然后我放下菜单,然后将SetCurSel调用到之前检索到的内容。

BOOL CMyComboBox::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam,    LRESULT *pResult)
{
    if(message == CBN_DROPDOWN)
    {
        int nCurSel = GetCurSel();
        if(nCurSel != CB_ERR)
        {
            ShowDropDown();
            SetCurSel(nCurSel);
            return TRUE;
        }

    }
    return CComboBox::OnWndMsg(message, wParam, lParam, pResult);
}

这种种类有效,但是当我杀死焦点或再次点击下拉箭头隐藏下拉列表时,文本框中会显示错误的项目。这是一种有效的方法,还是我完全不在这里? 下拉列表崩溃时会发送什么消息?

编辑2: 我已经从code project实现了区分大小写的组合框,它运行得很好。

1 个答案:

答案 0 :(得分:1)

继续我的评论。我认为你会发现内部机制使用 SelectString 来设置下拉样式时的索引。

副作用是它可能无法从列表中为您选择正确的条目。因此,考虑到组合中内容的性质,请尝试以下操作:

int iIndex = m_cbData.FindStringExact(-1, "On");
m_cbData.SetCurSel(iIndex);

或者

int iIndex = m_cbData.FindStringExact(-1, "OFF");
m_cbData.SetCurSel(iIndex);

但是,请注意,FindStringExact的文档说搜索不区分大小写。但是SelectString(默认行为)更糟糕。

可以解决所有这些问题的替代方案是使用 SetWindowText 并以这种方式执行。这样,列表框组件中的内容无关紧要。例如:

m_cbData.SetWindowText("On");
m_cbData.SetWindowText("ON");

通过映射到字符串或直接使用 GetWindowText 来获取变量的值。

更新:有人已经完成了这项工作!这是一个区分大小写的ComboBox类:

http://www.codeproject.com/Articles/1363/Case-sensitive-ComboBox