65.9K
CodeProject 正在变化。 阅读更多。
Home

一种禁用可编辑 CComboBox 在下拉时基于部分字符串匹配自动选择项目的方法

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.50/5 (7投票s)

2010年2月28日

CPOL

3分钟阅读

viewsIcon

25323

Windows 下的组合框有一个“不错”的功能,即当用户下拉组合框的列表时,会自动为用户选择一个项目。此选择基于组合框的部分字符串匹配,即,它将选择列表中第一个 - 如果有的话 - 以...

Windows 下的组合框有一个“不错”的功能,即当用户下拉组合框的列表时,会自动为用户选择一个项目。此选择基于组合框的部分字符串匹配,即,它将选择列表中第一个 - 如果有的话 - 以组合框编辑字段中相同的字符开头的项目。 例如,如果组合框包含以下几个项目:apple pear pineaple,并且用户在编辑字段中输入“ap”,然后单击按钮以显示下拉列表,则组合框将从其列表中选择“apple”,并将用户的“ap”替换为“apple”。 大多数情况下,这可能是一件好事,但有时它可能只是令人讨厌,例如,如果用户只想查看列表中有哪些项目,而不想丢失他已经输入到组合框编辑字段中的内容。 我试图找到一个简单的解决方案,但谷歌只向我保证,我不是世界上唯一一个希望不时关闭此功能的人。 (当然,我可能只是在寻找错误的术语......)所以这里有一个可能的解决方案:与其让组合框进行部分字符串匹配,不如让它进行精确的字符串匹配,这样,只有当列表中的项目与用户的条目完全匹配时,它才会选择该项目。 为什么这对我们有好处? 嗯,因为如果用户的条目在列表中,它将被整齐地突出显示,但是,由于此字符串与用户的字符串完全相同,因此它不会删除它(实际上,它会将该字符串替换为列表中的字符串,但由于这是完全相同的字符串,因此用户看不到任何内容)。 该方法非常简单。 当用户下拉列表时,组合框似乎正在使用列表自己的字符串搜索方法,组合框将 LB_FINDSTRING[^] 消息发送到列表,该列表搜索以指定子字符串开头的项目。 如果我们将此消息替换为 LB_FINDSTRINGEXACT[^],则列表将 - 正如消息的名称所暗示的那样 - 搜索完全匹配。 因此,我们可以做的是子类化列表,当我们收到 LB_FINDSTRING 时,使用 LB_FINDSTRINGEXACT 调用原始 windows proc。 首先,我们使用 GetComboBoxInfo[^] 和组合框来获取列表的句柄,然后我们可以使用例如 SetWindowLongPtr[^] 和 GWL_WNDPROC 来使列表使用我们自己的程序,我们在其中“翻译”查找字符串消息。 这是一个半伪实现:1. - 获取列表的句柄
COMBOBOXINFO info;
GetComboBoxInfo(handle_to_the_combo, &info);
HWND handleOfList = info.hwndList;
2. - 子类化列表
WNDPROC originalListProc;
originalListProc = (WNDPROC)SetWindowLongPtr(handleOfList, GWL_WNDPROC, MyListProc);
3. - 实现 MyListProc
LRESULT MyListProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
  if (msg == LB_FINDSTRING) msg = LB_FINDSTRINGEXACT;
  return CallWindowProc(originalListProc, hWnd, msg, wParam, lParam);
}
这当然只是一个简单的实现,您可以采用它并将其塑造成您需要的形式,使其易于重用,或者例如编写您自己的字符串搜索方法以根据需要更改区分大小写等等...
© . All rights reserved.