VC++ combobox模糊匹配,自动匹配
来源:互联网 发布:家庭矛盾 知乎 编辑:程序博客网 时间:2024/05/22 06:10
借鉴文章
http://blog.csdn.net/lsldd/article/details/4595386
http://blog.csdn.net/dyzhen/article/details/6185863
谢谢以上两位大神
(1) 使在输入了一个完整的匹配项,或者回车选中某项时,触发CBN_SELCHANGE消息.
(2) ShowDropDown(TRUE)采用消息迂回调用.原因如下,当输入中文词组时,OnEditUpdate会逐字依次调用,也就是说一次性输入几个汉字它就调用几次,而在此当中直接调用ShowDropDown(TRUE)会导致组合框Edit框的内容瞬间变成了匹配选项的内容,且为高亮选中状态,OnEditUpdate接下去处理接下来的汉字的时候,就仅把这一个汉字当成了输入内容,前面的内容就丢失了,所以导致匹配失效. (哎...说的自己都不明白...调试跟踪就知道是咋回事了).
本文首先派生了一个CComboBox类CComboCompletion,然后增加虚函数PreTranslateMessage,处理键盘输入,然后增加CBN_DROPDOWN和CBN_EDITUPDATE消息的处理.
头文件ComboCompletion.h:
#if !defined(AFX_COMBOCOMPLETION_H__9255E6D2_71F7_48CD_B6F5_5B249E0BE307__INCLUDED_)#define AFX_COMBOCOMPLETION_H__9255E6D2_71F7_48CD_B6F5_5B249E0BE307__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000// ComboCompletion.h : header file///////////////////////////////////////////////////////////////////////////////// CComboCompletion window#define WM_SHOWDROP WM_USER + 101class CComboCompletion : public CComboBox{// Constructionpublic:CComboCompletion();// Attributespublic:// Operationspublic:// Overrides// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CComboCompletion)public:virtual BOOL PreTranslateMessage(MSG* pMsg);//}}AFX_VIRTUAL// Implementationpublic:virtual ~CComboCompletion();// Generated message map functionsprotected://{{AFX_MSG(CComboCompletion)afx_msg void OnDropdown();afx_msg void OnEditupdate();afx_msg HRESULT OnShowDropDown(WPARAM wParam, LPARAM lParam);//}}AFX_MSGDECLARE_MESSAGE_MAP()private:BOOL m_bAutoComplete;};///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_COMBOCOMPLETION_H__9255E6D2_71F7_48CD_B6F5_5B249E0BE307__INCLUDED_)
ComboCompletion.cpp
// ComboCompletion.cpp : implementation file//#include "stdafx.h"#include "hrinetnsm_con.h"#include "ComboCompletion.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// CComboCompletionCComboCompletion::CComboCompletion(){}CComboCompletion::~CComboCompletion(){}BEGIN_MESSAGE_MAP(CComboCompletion, CComboBox)//{{AFX_MSG_MAP(CComboCompletion)ON_CONTROL_REFLECT(CBN_DROPDOWN, OnDropdown)ON_CONTROL_REFLECT(CBN_EDITUPDATE, OnEditupdate)//}}AFX_MSG_MAPON_MESSAGE(WM_SHOWDROP, OnShowDropDown)END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CComboCompletion message handlersBOOL CComboCompletion::PreTranslateMessage(MSG* pMsg) {// TODO: Add your specialized code here and/or call the base classif (pMsg->message == WM_CHAR){m_bAutoComplete = TRUE;int nVirKey = pMsg->wParam;switch (nVirKey){case VK_RETURN:{// 关闭下拉框ShowDropDown(FALSE);CString strLine;GetWindowText(strLine);// 回车即选中高亮项SelectString(-1, strLine);// 给父窗口发送选项改变的消息WPARAM wParam = MAKELPARAM(GetDlgCtrlID(), CBN_SELCHANGE);GetParent()->PostMessage(WM_COMMAND, wParam, (LPARAM)m_hWnd);break;}case VK_DELETE:case VK_BACK:m_bAutoComplete = FALSE;break;default:break;}}return CComboBox::PreTranslateMessage(pMsg);}void CComboCompletion::OnDropdown() {// TODO: Add your control notification handler code hereSetCursor(LoadCursor(NULL, IDC_ARROW)); }void CComboCompletion::OnEditupdate() {// TODO: Add your control notification handler code hereCString strLine; GetWindowText(strLine); int iHiLightStart = strLine.GetLength(); if(strLine.GetLength() == 0) { ShowDropDown(FALSE); SetWindowText(_T("")); m_bAutoComplete = TRUE; return; } // 处理删除操作 if(!m_bAutoComplete) { m_bAutoComplete = TRUE; return; } // 开始匹配用户输入 int iSelectedRow = FindString(-1, strLine); if(iSelectedRow >= 0) {// ShowDropDown(TRUE); PostMessage(WM_SHOWDROP, 0, 0);// 匹配的选项被选中 PostMessage(CB_SETCURSEL, iSelectedRow, 0); // 给父窗口发送选项改变的消息,这样可以保证当输入完整的匹配的部门时,不用回车也触发部门改变消息WPARAM wParam = MAKELPARAM(GetDlgCtrlID(), CBN_SELCHANGE);GetParent()->PostMessage(WM_COMMAND, wParam, (LPARAM)m_hWnd);} else { // ShowDropDown(FALSE); // SetWindowText(strLine); } // 高亮自动完成的部分PostMessage(CB_SETEDITSEL, 0, MAKELPARAM(iHiLightStart, -1)); }HRESULT CComboCompletion::OnShowDropDown(WPARAM wParam, LPARAM lParam){ShowDropDown(TRUE);return 0;}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
后来发现这个类还是不能满足条件,领导希望输入首字母,自动补全的同时还要删除无关信息,终于在pudn找到一个
AutoCombox1.h
#pragma once// CAutoCombox1class CAutoCombox1 : public CComboBox{DECLARE_DYNAMIC(CAutoCombox1)public:CAutoCombox1();virtual ~CAutoCombox1();// manipulating listbox itemsint AddString(LPCTSTR lpszString);int DeleteString(UINT nIndex);int InsertString(int nIndex, LPCTSTR lpszString);void ResetContent();//set statevoid SetFlag(UINT nFlag){m_nFlag = nFlag;}private:int Dir(UINT attr, LPCTSTR lpszWildCard){ASSERT(FALSE);}//forbiddenprotected:virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);void AutoSelect();void AutoMatchAndSel();DECLARE_MESSAGE_MAP()private:CEdit* m_pEdit;//edit controlUINT m_nFlag;//some flag//bit 0: 0 is show all, 1 is remove not matching, if no maching, show all.CStringArray m_strArr;};
AutoCombox1.cpp
// AutoCombox1.cpp : implementation file//#include "stdafx.h"// #include "MyCombox.h"#include "AutoCombox1.h"// CAutoCombox1IMPLEMENT_DYNAMIC(CAutoCombox1, CComboBox)CAutoCombox1::CAutoCombox1(){m_pEdit = NULL;m_nFlag = 0;}CAutoCombox1::~CAutoCombox1(){if (m_pEdit){if (::IsWindow(m_hWnd)){m_pEdit->UnsubclassWindow();}delete m_pEdit;m_pEdit = NULL;}}BEGIN_MESSAGE_MAP(CAutoCombox1, CComboBox)END_MESSAGE_MAP()// CAutoCombox1 message handlers//自动选择最匹配的,如果没有,则不选择。////////////////////////////////void CAutoCombox1::AutoSelect(){// Make sure we can 'talk' to the edit controlif ( m_pEdit == NULL ) {m_pEdit = new CEdit();m_pEdit->SubclassWindow(GetDlgItem(1001)->GetSafeHwnd());}// Save the state of the edit controlCString strText;//取得输入字符串int nStart = 0, nEnd = 0;//取得光标位置m_pEdit->GetWindowText(strText);m_pEdit->GetSel(nStart, nEnd);// Perform actual completionint nBestIndex = -1;//是否能找到匹配的字符int nBestFrom = INT_MAX;//匹配开始的字符if (!strText.IsEmpty()){for ( int nIndex=0; nIndex<GetCount(); ++nIndex ){CString str;GetLBText(nIndex,str);int nFrom = str.Find(strText);if ( nFrom != -1 && nFrom < nBestFrom )//能匹配,而且是更好的匹配,才记录{nBestIndex = nIndex;nBestFrom = nFrom;}}//for}//Set select indexif (!GetDroppedState()){ShowDropDown(TRUE);m_pEdit->SetWindowText(strText);m_pEdit->SetSel(nStart, nEnd);}if ( GetCurSel() != nBestIndex ){// Select the matching entry in the listSetCurSel(nBestIndex);// Restore the edit controlm_pEdit->SetWindowText(strText);m_pEdit->SetSel(nStart, nEnd);}}//删除不匹配的,自动选择剩余中最匹配的,如果没有,则显示全部。//////////////void CAutoCombox1::AutoMatchAndSel(){// Make sure we can 'talk' to the edit controlif ( m_pEdit == NULL ) {m_pEdit = new CEdit();m_pEdit->SubclassWindow(GetDlgItem(1001)->GetSafeHwnd());}// 保存edit控件的状态CString strText;//取得输入字符串int nStart = 0, nEnd = 0;//取得光标位置m_pEdit->GetWindowText(strText);m_pEdit->GetSel(nStart, nEnd);//清空CComboBox里面的数据CComboBox::ResetContent();// 重新填充列表,并选择最合适的int nBestIndex = -1;//是否能找到匹配的字符int nBestFrom = INT_MAX;//匹配开始的字符if (!strText.IsEmpty()){for ( int nIndex=0; nIndex<m_strArr.GetSize(); ++nIndex ){int nFrom = m_strArr[nIndex].Find(strText);char kk = m_strArr[nIndex].GetAt(0);char jj = strText.GetAt(0);BOOL flag = FALSE;if (kk==jj){flag = TRUE;}if ( nFrom != -1&&flag==TRUE)//能匹配{int n = CComboBox::AddString(m_strArr[nIndex]);if (nFrom < nBestFrom)//更好的匹配,则记录{nBestIndex = n;nBestFrom = nFrom;}}}//for}if (GetCount() == 0)//没有的显示所有{for (int nIndex=0; nIndex<m_strArr.GetSize(); ++nIndex){CComboBox::AddString(m_strArr[nIndex]);}}//显示下拉列表if (!GetDroppedState()){ShowDropDown(TRUE);}//设置选择项// Select and Restore the edit controlSetCurSel(nBestIndex);m_pEdit->SetWindowText(strText);m_pEdit->SetSel(nStart, nEnd);}// manipulating listbox itemsint CAutoCombox1::AddString(LPCTSTR lpszString){m_strArr.Add(lpszString);return CComboBox::AddString(lpszString);}int CAutoCombox1::DeleteString(UINT nIndex){m_strArr.RemoveAt(nIndex);return CComboBox::DeleteString(nIndex);}int CAutoCombox1::InsertString(int nIndex, LPCTSTR lpszString){m_strArr.InsertAt(nIndex, lpszString);return CComboBox::InsertString(nIndex, lpszString);}void CAutoCombox1::ResetContent(){m_strArr.RemoveAll();CComboBox::ResetContent();}//All Message Handle DispatchBOOL CAutoCombox1::OnCommand(WPARAM wParam, LPARAM lParam){if ( HIWORD(wParam) == EN_CHANGE ){if (m_nFlag & 0x01){AutoMatchAndSel();}else{AutoSelect();}return true;}else{return CComboBox::OnCommand(wParam, lParam);}}
=================================================================================================================
程序猿和程序媛必备的咖啡-OneDay咖啡生活-https://shop110384469.taobao.com/
- VC++ combobox模糊匹配,自动匹配
- c# 实现ComboBox自动模糊匹配
- c# 实现ComboBox自动模糊匹配
- c# 实现ComboBox自动模糊匹配
- easyui combobox模糊匹配
- Ext combobox 动态模糊匹配
- ExtJs combobox支持模糊匹配
- Ext combobox 动态模糊匹配
- 自动匹配ComboBox控件
- EXT Ext combobox 动态模糊匹配
- Ext.net ComboBox模糊匹配store数据
- EasyUi模糊匹配搜索框combobox
- ComboBox 智能过滤,模糊匹配,拼音首字母匹配
- ComboBox自动匹配下拉列表中的值
- 带有输入自动匹配功能的Combobox
- C#实现ComboBox自动匹配字符
- 模糊匹配
- 模糊匹配
- Ubuntu修改Mysql字符编码
- C++的构造函数
- Android网络(3):HttpClient作客户端,Tomcat Servlet作服务器的交互示例
- 欢迎使用CSDN-markdown编辑器
- CSS实现输入框的周围高亮效果让边框发亮
- VC++ combobox模糊匹配,自动匹配
- android usb adb流程,Android系统关机或重启的几种实现方式
- ubuntu下设置开机自动挂载硬盘
- 对程序员最具影响力的书籍清单
- Android网络(4):HttpClient必经之路----使用线程安全的单例模式HttpClient,及HttpClient和Application的融合
- 最大字段和
- 买不到的数目
- Eclipse添加源代码的注释模板
- mysqlbinlog: unknown variable 'default-character-set=utf8'