#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();
}
此类具有自动匹配功能,最新的历史信息始终在下拉列表的最上面,只导入最新的规定的数目历史信息