【框架-MFC】CComboBox - 重写 输入时实现自动补全

本文介绍了一种在Windows应用程序中实现组合框自动补全功能的方法。通过重写控件响应函数ON_CONTROL_REFLECT(CBN_EDITUPDATE),文章详细展示了如何在用户输入时实时更新下拉列表,提供匹配项建议,并保持光标位置不变。示例代码中包含了如何构建和初始化数据源,以及如何处理文本输入变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

源码下载

重写函数

ON_CONTROL_REFLECT(CBN_EDITUPDATE, OnCbnEditUpdate)

实现代码

void CComboBoxIS::OnCbnEditUpdate()
{
	UpdateData(FALSE);
	WORD nStartChar = 0;
	WORD nEndChar = 0;
	{//获取光标位置
		DWORD dwSel = GetEditSel();
		nStartChar = LOWORD(dwSel);//低字记录了编辑控件中选中的字符串中起始位置
		nEndChar= HIWORD(dwSel);		//高字记录了紧接着选中的字符串的第一个字符的位置
	}

	{//清空下列列表
		int countnum = GetCount();
		if (countnum>0)
		{
			for (int i =0;i<countnum;i++)
			{
				DeleteString(0);
			}
		}
	}

	CString searchName;
	{//判断当前字符是否为NULL
		GetWindowText(searchName);
		if (searchName.IsEmpty() == TRUE)
		{
			m_editState = Mouse_Normal;
			TRACE(_T("On Combo-box Edit Update\n"));
			ShowDropDown(FALSE);
			Invalidate(FALSE);
			return;
		}
	}
	
	{//搜索并显示匹配的字符串
		CStringArray addString ;
		addString.SetSize(100);
		addString.RemoveAll();
		AddString(searchName);
		addString.Add(searchName);
		//添加字符串
		for (int i = 0; i <m_arrData.GetCount();i++)
		{
			CString str = m_arrData[i];
			int n = str.Find(searchName);
			CString tmp;
			tmp.Format(_T("%d"),n);
			OutputDebugString(tmp);
			OutputDebugString(_T("\n"));
			if(n>=0)
			{
				BOOL bAdd = TRUE;
				for(int j =0;j<addString.GetCount();j++)
				{
					if (str == addString[j])
					{
						bAdd = FALSE;
						break;
					}
				}
				if(bAdd == TRUE)
				{
					AddString(m_arrData[i]);
					addString.Add(m_arrData[i]);
					OutputDebugString(m_arrData[i]);
					OutputDebugString(_T("\n"));
				}
			}
		}
		if(addString.GetCount()<=1)
		{
			addString.RemoveAll();;
			int countnum = GetCount();
			if (countnum>0)
			{
				for (int i =0;i<countnum;i++)
				{
					DeleteString(0);
				}
			}
			m_editState = Mouse_Normal;
			ShowDropDown(false);
			Invalidate(FALSE);
			
			//SetEditSel(searchName.GetLength(),searchName.GetLength());
			SetEditSel(nStartChar,nEndChar); //光标跳到相应位置
			return;
		}
		addString.RemoveAll();;
	}

	{
		::SetCursor(LoadCursor(NULL,MAKEINTRESOURCE(IDC_ARROW))); //防止鼠标消失
		m_editState = Mouse_Down;
		ShowDropDown(TRUE);//显示下拉框
		//SetEditSel(searchName.GetLength(),searchName.GetLength()); //光标跳到末尾,//置光标于文本最后,防止全部选中
		SetEditSel(nStartChar,nEndChar); //恢复光标位置 光标跳到相应位置
	}
}

测试例子

void CComboBoxIS::Example1()
{
	m_arrData.Add(_T("少莫千华"));
	m_arrData.Add(_T("天行健,君子以自强不息;地势坤,君子以厚德载物"));
	m_arrData.Add(_T("天山暮雪"));
	m_arrData.Add(_T("我们"));
	m_arrData.Add(_T("我是歌手"));
	m_arrData.Add(_T("四大名助"));
	m_arrData.Add(_T("四大发明"));
	m_arrData.Add(_T("四大发明家"));
	m_arrData.Add(_T("四大名著"));
	m_arrData.Add(_T("快乐大本营"));
	m_arrData.Add(_T("天天向上"));
	m_arrData.Add(_T("极限挑战"));
	m_arrData.Add(_T("奔跑吧兄弟"));
	m_arrData.Add(_T("爱情保卫战"));
	m_arrData.Add(_T("锦绣未央"));
	m_arrData.Add(_T("真正男子汉"));
	m_arrData.Add(_T("爸爸去哪了"));
	m_arrData.Add(_T("天地玄黄 宇宙洪荒 日月盈昃"));
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值