CComboBox 下拉时不选择 CurSel
CComboBox not selecting CurSel when dropped down
我在对话框中有一个按字母顺序排序的组合框。这个组合包含多个字符串,但有些字符串在不同情况下是重复的。即我们有一个 'On' 和一个 'ON',一个 'Off' 和一个 'OFF'。这似乎是多余的,但这是有原因的,尽管现在这并不重要。
重复项明显在列表中一个接一个出现,大写字符串在前。即:
OFF
Off
ON
On
当用户select输入'On'(小写)时,正确的索引设置为CurSel
并显示正确的字符串。但是,当我单击组合框的箭头下拉列表时,它不会突出显示 CurSel
,而是突出显示它前面的大写字符串。见下图。
这是 select在下拉列表中编辑的:
这就是展开下拉列表时在组合框中输入的内容。select
我已经捕获了 ON_CBN_DROPDOWN
消息,并检查了 cursel 值,它符合我的预期。
我也已经将这个组合框子类化,这样我就可以以区分大小写的方式在这个列表中搜索字符串,因为我知道它没有正常实现,所以它可能是导致我的问题的原因。
但我不明白为什么在这个阶段字符串会覆盖 cursel 值? CurSel
值不应该是用于 select 相关项目的值吗?
任何关于如何解决这个问题的想法都将不胜感激。
编辑:
我试图通过覆盖 OnWndMsg
来捕获 CBN_DROPDOWN
消息。出现此消息时,我会在下拉菜单之前获取当前 selected 项目(这是正确的项目)。然后我放下菜单,并调用 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 实现了区分大小写的组合框,并且效果很好。
进一步补充我的评论。我想你会发现当它是 dropdown 样式时,内部机制正在使用 SelectString 来设置索引。
副作用是它可能无法从列表中为您选择正确的条目。因此,鉴于您组合中内容的性质,请尝试以下操作:
int iIndex = m_cbData.FindStringExact(-1, "On");
m_cbData.SetCurSel(iIndex);
或
int iIndex = m_cbData.FindStringExact(-1, "OFF");
m_cbData.SetCurSel(iIndex);
但是,请注意,FindStringExact says the search is not case sensitive. But SelectString(默认行为)的文档更糟糕。
可以解决所有这些问题的替代方法是使用 SetWindowText 并按此方式进行。这样,列表框组件中的内容就无关紧要了。例如:
m_cbData.SetWindowText("On");
m_cbData.SetWindowText("ON");
并通过映射到字符串或直接使用 GetWindowText.
来获取变量的值
更新:有人已经完成了这项工作!这是一个区分大小写的组合框 class:
http://www.codeproject.com/Articles/1363/Case-sensitive-ComboBox
我在对话框中有一个按字母顺序排序的组合框。这个组合包含多个字符串,但有些字符串在不同情况下是重复的。即我们有一个 'On' 和一个 'ON',一个 'Off' 和一个 'OFF'。这似乎是多余的,但这是有原因的,尽管现在这并不重要。
重复项明显在列表中一个接一个出现,大写字符串在前。即:
OFF
Off
ON
On
当用户select输入'On'(小写)时,正确的索引设置为CurSel
并显示正确的字符串。但是,当我单击组合框的箭头下拉列表时,它不会突出显示 CurSel
,而是突出显示它前面的大写字符串。见下图。
这是 select在下拉列表中编辑的:
这就是展开下拉列表时在组合框中输入的内容。select
我已经捕获了 ON_CBN_DROPDOWN
消息,并检查了 cursel 值,它符合我的预期。
我也已经将这个组合框子类化,这样我就可以以区分大小写的方式在这个列表中搜索字符串,因为我知道它没有正常实现,所以它可能是导致我的问题的原因。
但我不明白为什么在这个阶段字符串会覆盖 cursel 值? CurSel
值不应该是用于 select 相关项目的值吗?
任何关于如何解决这个问题的想法都将不胜感激。
编辑:
我试图通过覆盖 OnWndMsg
来捕获 CBN_DROPDOWN
消息。出现此消息时,我会在下拉菜单之前获取当前 selected 项目(这是正确的项目)。然后我放下菜单,并调用 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 实现了区分大小写的组合框,并且效果很好。
进一步补充我的评论。我想你会发现当它是 dropdown 样式时,内部机制正在使用 SelectString 来设置索引。
副作用是它可能无法从列表中为您选择正确的条目。因此,鉴于您组合中内容的性质,请尝试以下操作:
int iIndex = m_cbData.FindStringExact(-1, "On");
m_cbData.SetCurSel(iIndex);
或
int iIndex = m_cbData.FindStringExact(-1, "OFF");
m_cbData.SetCurSel(iIndex);
但是,请注意,FindStringExact says the search is not case sensitive. But SelectString(默认行为)的文档更糟糕。
可以解决所有这些问题的替代方法是使用 SetWindowText 并按此方式进行。这样,列表框组件中的内容就无关紧要了。例如:
m_cbData.SetWindowText("On");
m_cbData.SetWindowText("ON");
并通过映射到字符串或直接使用 GetWindowText.
来获取变量的值更新:有人已经完成了这项工作!这是一个区分大小写的组合框 class:
http://www.codeproject.com/Articles/1363/Case-sensitive-ComboBox