#pragma once #include <list> #define MAXSTRSIZE 1500 //"值"字符串的最大长度 #define MAXVALUE 10 //注册表保留最大的历史记录数目, 最好设置为1-25之间 class CHisInfoComboBox : public CComboBox { DECLARE_DYNAMIC(CHisInfoComboBox) public: CHisInfoComboBox(); virtual ~CHisInfoComboBox(); public: bool SetHistoryInfoToReg(); bool GetHistoryInfoFromReg(); bool SetHistoryInfoToBuffer(); //把历史信息放进内存 bool GetHistoryInfoFromBuffer(); //从内存取出历史信息 protected: void InitHisInfo(); public: afx_msg void OnCbnKillfocus(); afx_msg void OnDestroy(); afx_msg void OnCbnEditchange(); afx_msg void OnCbnDropdown(); afx_msg void OnCbnSetfocus(); protected: DECLARE_MESSAGE_MAP() private: CRegKey m_regKey; CString m_strKey; std::list<CString> m_lContentOfList; bool m_bFlag; };
// CHisInfoComboBox IMPLEMENT_DYNAMIC(CHisInfoComboBox, CComboBox) CHisInfoComboBox::CHisInfoComboBox():m_bFlag(false) { } CHisInfoComboBox::~CHisInfoComboBox() { } BEGIN_MESSAGE_MAP(CHisInfoComboBox, CComboBox) ON_CONTROL_REFLECT(CBN_KILLFOCUS, &CHisInfoComboBox::OnCbnKillfocus) ON_WM_CREATE() ON_WM_CREATE() ON_WM_CLOSE() ON_WM_DESTROY() ON_CONTROL_REFLECT(CBN_EDITCHANGE, &CHisInfoComboBox::OnCbnEditchange) ON_CONTROL_REFLECT(CBN_DROPDOWN, &CHisInfoComboBox::OnCbnDropdown) ON_CONTROL_REFLECT(CBN_SETFOCUS, &CHisInfoComboBox::OnCbnSetfocus) END_MESSAGE_MAP() void CHisInfoComboBox::InitHisInfo() { if (!m_bFlag) { int ID; CString strID; CString strTmp; ID = GetDlgCtrlID(); strID.Format(_T("%d"), ID); strTmp = _T("Test\\ComboBox "); strTmp += strID; m_strKey = strTmp; m_regKey.Create(HKEY_CURRENT_USER, strTmp); m_regKey.Close(); m_bFlag = true; } } bool CHisInfoComboBox::SetHistoryInfoToReg() { if (!m_bFlag) return false; std::list<CString>::iterator itBeg; std::list<CString>::iterator itEnd; CRegKey regKey; regKey.Open(HKEY_CURRENT_USER, m_strKey); while (m_lContentOfList.size() > MAXVALUE) //注册表只保留最近的MAXVALUE条历史记录 { itBeg = m_lContentOfList.begin(); itEnd = m_lContentOfList.end(); m_lContentOfList.erase(--itEnd); //去掉最久的历史记录 } itBeg = m_lContentOfList.begin(); itEnd = m_lContentOfList.end(); char ch = 'A'; for (; itBeg != itEnd; ++itBeg) { if (*itBeg == _T("")) continue; CString strTmp(ch); ch += 1; regKey.SetStringValue(strTmp, *itBeg); } regKey.Close(); return true; } bool CHisInfoComboBox::GetHistoryInfoFromReg() { InitHisInfo(); DWORD dwCountOfSubKey; DWORD dwCountOfValue; DWORD dwType; DWORD wValNameSize; DWORD dwValSize; LONG lResult; TCHAR *strValName; TCHAR *strVal; wValNameSize = MAXSTRSIZE; dwValSize = MAXSTRSIZE; strValName = new TCHAR[wValNameSize]; if (!strValName) return false; strVal = new TCHAR[dwValSize]; if (!strVal) return false; CRegKey regKey; regKey.Open(HKEY_CURRENT_USER, m_strKey); lResult = ::RegQueryInfoKey(regKey.m_hKey, NULL, NULL, NULL, &dwCountOfSubKey, NULL, NULL, &dwCountOfValue, NULL, NULL, NULL, NULL); if (lResult != ERROR_SUCCESS) return false; for (int i = 0; i < (int)dwCountOfValue; ++i) { wValNameSize = MAXSTRSIZE; lResult = RegEnumValue(regKey.m_hKey, i, strValName, &wValNameSize, NULL, &dwType,NULL, NULL); if (lResult != ERROR_SUCCESS) return false; if (wcscmp(strValName, _T("")) == 0) continue; dwValSize = MAXSTRSIZE; dwType = REG_SZ; regKey.QueryStringValue(strValName, strVal, &dwValSize); m_lContentOfList.push_front(strVal); } delete []strValName; delete []strVal; strValName = NULL; strVal = NULL; regKey.Close(); return true; } void CHisInfoComboBox::OnCbnKillfocus() { SetHistoryInfoToBuffer(); } void CHisInfoComboBox::OnDestroy() { CComboBox::OnDestroy(); // TODO: 在此处添加消息处理程序代码 SetHistoryInfoToReg(); } bool CHisInfoComboBox::SetHistoryInfoToBuffer() { CString strText; GetWindowText(strText); strText.TrimLeft(_T(' ')); if (strText == _T("")) return true; if (FindString(0, strText) == CB_ERR) m_lContentOfList.push_front(strText); return true; } //示例:假设历史记录为word, hello, one, three //若编辑框为空 , 则下拉列表显示word, hello,one, three //若编辑框内容为e, 则下拉列表显示hello, one, three bool CHisInfoComboBox::GetHistoryInfoFromBuffer() { CString strText; GetWindowText(strText); strText.TrimLeft(_T(" ")); std::list<CString>::iterator itBeg; std::list<CString>::iterator itEnd; for (itBeg = m_lContentOfList.begin(), itEnd = m_lContentOfList.end(); itBeg != itEnd; ++itBeg) { if (strText == _T("")) { if (FindString(0, *itBeg) == CB_ERR) AddString(*itBeg); } else { if (itBeg->FindOneOf(strText) != -1) { if (FindString(0, *itBeg) == CB_ERR) AddString(*itBeg); } else { int i = FindString(0, *itBeg); DeleteString(i); } } } return true; } void CHisInfoComboBox::OnCbnEditchange() { // TODO: 在此添加控件通知处理程序代码 GetHistoryInfoFromBuffer(); int nCount = GetCount(); if (nCount) { PostMessage(CB_SHOWDROPDOWN, TRUE); } else PostMessage(CB_SHOWDROPDOWN, FALSE); } void CHisInfoComboBox::OnCbnDropdown() { // TODO: 在此添加控件通知处理程序代码 GetHistoryInfoFromBuffer(); } void CHisInfoComboBox::OnCbnSetfocus() //编辑框获得焦点时从注册表读入历史信息 { // TODO: 在此添加控件通知处理程序代码 if (!m_bFlag) GetHistoryInfoFromReg(); }此类具有自动匹配功能,最新的历史信息始终在下拉列表的最上面,只导入最新的规定的数目历史信息