自动完成Combobox小结
来源:互联网 发布:淘宝返利最高的软件 编辑:程序博客网 时间:2024/05/12 10:43
工作需要做一个自动完成combobox,就是用户在编辑框输入的时候,下拉框能自动选择用户输入最相近的一项,同时编辑框给出自动完成功能。
途中遇到很多小麻烦,网上下了一大堆源码,总结了不少经验,不敢独享,以飨读者。
首先继承一个CCombobox的类,响应以下消息处理:
- BEGIN_MESSAGE_MAP(CComboCompletion, CComboBox)
- //{{AFX_MSG_MAP(CComboCompletion)
- //ON_CONTROL_REFLECT(CBN_SELCHANGE, OnSelChange)
- ON_CONTROL_REFLECT(CBN_DROPDOWN, OnDropdown)
- ON_CONTROL_REFLECT(CBN_EDITUPDATE, OnEditUpdate)
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
注意,不宜响应CBN_SELCHANGE,而是应该响应CBN_EDITUPDATE,前者让组合框的爸爸去解决就好了。。。
在处理消息之前,我们应该对消息进行一下判断,并不是用户的每次按键都是有意义的。
同时,有些消息如果不想传给父亲,就要中断消息链。在我的例子里,回车键会发给父窗口的编辑器导致换行,所以我这里阻止了回车消息的传递。
- // 重写PreTranslateMessage函数以预处理消息
- BOOL CComboCompletion::PreTranslateMessage(MSG* pMsg)
- {
- if (pMsg->message == WM_CHAR)
- {
- m_bAutoComplete = TRUE;
- int nVirtKey = (int) pMsg->wParam;
- switch(nVirtKey)
- {
- case VK_RETURN:
- {
- // 回车按下,收起下拉列表
- ShowDropDown(FALSE);
- // 设置当前选择列
- CString str;
- GetWindowText(str);
- SelectString(-1, str);
- // 这里直接返回,于是组合框的爸爸也无法响应回车了
- return TRUE;
- }
- // 如果是删除操作,则不进行自动完成
- case VK_DELETE:
- case VK_BACK:
- m_bAutoComplete = FALSE;
- default:
- break;
- }
- }
- return CComboBox::PreTranslateMessage(pMsg);
- }
接下来处理编辑事件响应。
注意PostMessage是自动选择的关键!否则下拉框虽然能滚动,但是不会高亮选择项!
原因不是很明确,不过肯定是消息同步和异步处理之间的原因。
- void CComboCompletion::OnEditUpdate()
- {
- CString line; // partial line entered by user
- CString sMatchedText; // holds full line from list
- // get the text from the user input
- GetWindowText(line);
- int iHiLightStart = line.GetLength();
- // if the line is empty
- if(line.GetLength() == 0)
- {
- // 关闭下拉框
- ShowDropDown(FALSE);
- // empty the selection
- SetWindowText(_T(""));
- m_bAutoComplete = true;
- return;
- }
- // 这里处理删除操作的逻辑
- if(!m_bAutoComplete)
- {
- m_bAutoComplete = true;
- return;
- }
- // 开始匹配用户输入
- int m_iSelectedRow = FindString(-1, line);
- if(m_iSelectedRow >= 0)
- {
- // 打开下拉框
- ShowDropDown(TRUE);
- // 注意这里一定要使用postmessage以保证下拉框的选项被选中!
- PostMessage(CB_SETCURSEL, m_iSelectedRow, 0);
- }
- // 接下来处理匹配失败
- else
- {
- ShowDropDown(FALSE);
- SetWindowText(line);
- }
- // 最后我们要高亮自动匹配的部分,以方便用户继续编辑,同样的要用异步消息发送
- PostMessage(CB_SETEDITSEL, 0, MAKELPARAM(iHiLightStart, -1));
- }
基本就差不多了,你会发现一个bug,就是自动提示的时候打开下拉框鼠标不见了!
嘿嘿。。。这就是我最开始之所以响应CBN_DROPDOWN消息的原因,这里得做个补救措施:
- void CComboCompletion::OnDropdown()
- {
- SetCursor(LoadCursor(NULL, IDC_ARROW));
- }
现在效果出来了,貌似比较专业...下图:
如果是CComboBoxEx则麻烦一点,你需要自己实现排序,插入,搜索字符串的操作。
然而原理则是一样的。
0 0
- 自动完成Combobox小结
- 自动完成Combobox小结
- comboBox 自动完成搜索功能
- 具有自动完成功能的ComboBox
- ComboBox自动完成功能(Source)
- C# ComboBox自动完成功能的例子
- 另一个具有自动完成功能的ComboBox
- 自定义具有自动完成功能的ComboBox
- ComboBox自动完成功能的例子
- ComboBox自动完成功能的例子
- C# ComboBox自动完成功能的示例
- C# ComboBox自动完成功能的示例
- wxpython comboBox 自动完成提示功能
- 具有自动完成功能的ComboBox(源码、原创)
- 输入框输入的自动完成(Edit .ComboBox)
- 利用ComboBox自带属性完成自动补全功能
- 继承 System.Windows.Forms.ComboBox 实现支持自动完成功能的 ComboBox!个人感觉还可以!!!
- MFC COMBOBOX 短代码 实现的自动匹配输入 自动完成 但有小缺陷
- 花生壳内网版和公网版的区别
- alienvault OTX情报交换系统
- hdu4995 (不错的小模拟)
- Leetcode dp Distinct Subsequences
- 显示定义拷贝构造函数和赋值函数的意义及深浅拷贝区别
- 自动完成Combobox小结
- 数据结构(c++版)
- 数据库操作 Zend\Db\ResultSet
- C++ 的一个问题的理解(私有变量成员)
- Block详解
- Amazon.com Stored XSS via Book Metadata
- 设计模式大集锦 (程序员面试全攻略)
- 常见排序算法(冒泡、选择、插入、快速、归并C++实现)
- select, poll, epoll详解(一)