MFC登录界面实现类似QQ的功能(详细步骤)

首先添加一个combobox控件,添加“记住密码”复选框。

之后在CLoginDlg::OnInitDialog()函数里调用函数_OnSetComboBox(),此函数主要是进行下拉框用户名记录的显示,用户名及密码存储在UserInfo.ini文件里,存储格式为"用户名","密码","复选框状态",复选框状态为0或者1,代码如下:

void CLoginDlg::_OnSetComboBox()
{
	// TODO:  在此添加控件通知处理程序代码
	m_cbExample.ResetContent();//清理下拉框列表
	m_cbExample.SetItemHeight(0, 30);//设置下拉选项高度
	/*m_cbExample.SetFont(pFont, 1);*/

	if (!PathFileExists(_T(".\\UserInfo.ini")))//判断文件是否存在
	{
		return;
	}
	
	CString strFileName = _T(".\\UserInfo.ini");
	CString szLine = _T("");

	//打开文件
	CStdioFile  file;
	file.Open(strFileName, CFile::modeRead);

	//逐行读取字符串
	while (file.ReadString(szLine))
	{
		//查找逗号
		char a = ',';
		size_t pos = szLine.Find(a);
		CString username = szLine.Left(pos);//截取用户名

		if (username.GetLength()!=0)
		{
			m_cbExample.AddString(username);//显示到combobox控件上
		}
	}
	
	//关闭文件
	file.Close();
}

然后对combobox控件的CBN_SELCHANGE和CBN_EDITCHANGE消息添加处理函数,CBN_SELCHANGE消息是当combobox控件中的多个用户名被选中项切换的消息,处理函数为OnSelchangeEditUser(),而CBN_EDITCHANGE是当combobox控件里的内容被编辑时的消息,处理函数为OnEditchangeEditUser(),_SearchFromFile(CString username, CString& password ,CString& flag)函数根据用户名查询文件并获取相应密码。

void CLoginDlg::OnSelchangeEditUser()
{

	// TODO:  在此添加控件通知处理程序代码
	CString username;
	int nSel;


	// 获取组合框控件的列表框中选中项的索引   
	nSel = m_cbExample.GetCurSel();

	// 根据选中项索引获取该项字符串   
	m_cbExample.GetLBText(nSel, username);

	CString s;
	CString flag;

	_SearchFromFile(username,s,flag);//根据用户名查询是否存在对应密码

	if (s!=""&&flag=="1")
	{
		SetDlgItemText(IDC_EDIT_PASSWARD, s);//将密码显示到相应控件
		((CButton*)GetDlgItem(IDC_CHECK1))->SetCheck(1);//设置复选框为选中状态
	}
	else
	{
		SetDlgItemText(IDC_EDIT_PASSWARD, _T(""));
		((CButton*)GetDlgItem(IDC_CHECK1))->SetCheck(0);
	}
}

void CLoginDlg::OnEditchangeEditUser()
{
	// TODO:  在此添加控件通知处理程序代码
	CWnd* pWnd = GetDlgItem(IDC_EDIT_USER);
	CWnd* pWnd1 = GetDlgItem(IDC_EDIT_PASSWARD);

	CString username;
	pWnd->GetWindowTextW(username);
	
	CString s;
	CString flag;

	_SearchFromFile(username, s,flag);//根据用户名查询是否存在对应密码

	if (s != ""&&flag=="1")
	{
		SetDlgItemText(IDC_EDIT_PASSWARD, s);//将密码显示到相应控件
		((CButton*)GetDlgItem(IDC_CHECK1))->SetCheck(1);//设置复选框为选中状态
	}
	else
	{
		SetDlgItemText(IDC_EDIT_PASSWARD, _T(""));
		((CButton*)GetDlgItem(IDC_CHECK1))->SetCheck(0);
	}
}

void CLoginDlg::_SearchFromFile(CString username, CString& password ,CString& flag)
{
	if (!PathFileExists(_T(".\\UserInfo.ini")))
	{
		return;
	}

	CStdioFile file;
	file.Open(_T(".\\UserInfo.ini"), CFile::modeRead);

	CString szLine = _T("");

	while (file.ReadString(szLine))
	{
		//查找逗号
		char a = ',';
		size_t pos = szLine.Find(a);
		CString name = szLine.Left(pos);
		int size123 = szLine.GetLength();

		if (name == username)
		{
			password = szLine.Mid(pos+1, size123 - pos-3);
			flag = szLine.Right(1);
			file.Close();
			return;
		}
	}
	password = "";
	file.Close();
	return;
}

在登录按钮的点击事件的响应函数里,调用代码如下:

int status0 = ((CButton*)GetDlgItem(IDC_CHECK1))->GetCheck();//获取复选框状态

_WriteToFile(userName, passWard, status0);//存储用户名和密码到UserName.ini文件里

函数_WriteToFile(userName, passWard, status0)详细代码如下:

void CLoginDlg::_WriteToFile(std::string username, std::string password, int flag)
{
	const void * username1 = username.c_str();
	const void * password1 = password.c_str();
	std::string flag0 = std::to_string(flag);
	const void * flag1 = flag0.c_str();

	CStdioFile file0;

	if (!PathFileExists(_T(".\\UserInfo.ini")))//判断文件是否存在
	{
		return;
	}
	
	file0.Open(_T(".\\UserInfo.ini"), CFile::modeRead);
	CString szLine = _T("");

	while (file0.ReadString(szLine))
	{
		//查找逗号
		char a = ',';
		size_t   pos = szLine.Find(a);

		CString name = szLine.Left(pos);
		CString name1(username.c_str());
		CString pass(password.c_str());
		CString status1 = szLine.Right(1);

		if (name == name1)//本地文件里有对应用户名
		{
			file0.Close();
			_SortUserInfo(name);//根据用户名对用户信息进行重新排序
			if (status1 == "0" && flag == 1)//曾经登录过,但是未选择记住密码
			{
				_EditUserInfo(name,pass,flag);//存储密码及复选框状态
			}
			if (status1 == "1" && flag == 0)//曾经登录过且选择了记住密码,现在是未选择
			{
				_EditUserInfo(name, _T(""), flag);//删除密码,存储复选框状态
			}
			return;
		}
	}
	file0.Close();

	//若执行完上述代码本地没有相应用户名的记录则执行下面代码

	CStdioFile file00;
	file00.Open(_T(".\\UserInfo.ini"), CFile::modeRead);

	//将文件里的用户信息全部获取到,并且存储到infoo里面
	std::vector<CString> infoo;
	CString szLine00;
	while (file00.ReadString(szLine00))
	{
		if (szLine00.GetLength() != 0)
		{
			infoo.push_back(szLine00);
		}
	}
	file00.Close();

	CStdioFile file;
	file.Open(_T(".\\UserInfo.ini"), CFile::modeCreate | CFile::modeWrite /*| CFile::modeNoTruncate, NULL*/);//打开文件,文件不存在则创建,存在则清空文件内容

	if (file.GetLength()!=0)
	{
		file.Write("\n", 1);
	}

	//将用户名、密码及复选框状态按对应格式写入到文件中
	file.Write(username1, username.length());
	file.Write(",", 1);

	if (flag == 1)
	{
		file.Write(password1, password.length());
	}
	else
	{
		file.Write("", 0);
	}
	
	file.Write(",", 1);
	file.Write(flag1, 1);
	file.Write("\n", 1);
	
	file.SeekToEnd();
	for (int j = 0; j < infoo.size(); j++)
	{
		file.WriteString(infoo[j]);
		file.Write("\n", 1);
	}
	file.Close();
	return;
}


void CLoginDlg::_SortUserInfo(CString username)
{
	if (!PathFileExists(_T(".\\UserInfo.ini")))
	{
		return;
	}
	CStdioFile file;
	file.Open(_T(".\\UserInfo.ini"), CFile::modeReadWrite);

	std::vector<CString> infoo;
	CString szLine;
	while (file.ReadString(szLine))
	{
		if (szLine.GetLength() != 0)
		{
			infoo.push_back(szLine);
		}
	}
	file.Close();

	CString user1;
	for (int i = 0; i < infoo.size(); i++)
	{
		CString infor = infoo[i];
		CString user = infor.Left(username.GetLength());
		if (user == username)
		{
			user1 = infoo[i];
			infoo.erase(infoo.begin() + i);
		}
	}
	std::vector<CString> infoo1;
	infoo1.push_back(user1);
	for (int i = 0; i < infoo.size();i++)
	{
		infoo1.push_back(infoo[i]);
	}

	CStdioFile file1;
	file1.Open(_T(".\\UserInfo.ini"), CFile::modeCreate | CFile::modeWrite);

	for (int j = 0; j < infoo1.size(); j++)
	{
		file1.WriteString(infoo1[j]);
		file1.Write("\n", 1);
	}

	file1.Close();
}


函数_EditUserInfo(CString username, CString password, int flag)可以实现密码的修改,以及当“记住密码”复选框被选中和没有被选中时对于文件的操作。

void CLoginDlg::_EditUserInfo(CString username, CString password, int flag)
{
	if (!PathFileExists(_T(".\\UserInfo.ini")))
	{
		return;
	}

	CStdioFile file;
	file.Open(_T(".\\UserInfo.ini"), CFile::modeReadWrite);

	std::vector<CString> infoo;
	CString szLine;

	while (file.ReadString(szLine))
	{
		if (szLine.GetLength()!=0)
		{
			infoo.push_back(szLine);
		}
	}

	file.Close();
	CString a;
	a.Format(_T("%d"), flag);

	for (int i = 0; i < infoo.size(); i++)
	{
		CString infor = infoo[i];
		CString user = infor.Left(username.GetLength());

		if (user == username)
		{
			infoo[i] = username + "," + password + "," + a;
		}
	}

	CStdioFile file1;
	file1.Open(_T(".\\UserInfo.ini"), CFile::modeCreate | CFile::modeWrite);

	for (int j = 0; j < infoo.size(); j++)
	{
		file1.WriteString(infoo[j]);
		file1.Write("\n", 1);
	}
	file1.Close();
}

函数_SetInitialUserInfo()设置登录界面初始状态,自动填充上次登录成功且记住密码的用户名及密码,在OnInitDialog函数里被调用。

void CLoginDlg::_SetInitialUserInfo()
{
	CStdioFile file;
	file.Open(_T(".\\UserInfo.ini"), CFile::modeRead);

	CString szLine = _T("");
	while (file.ReadString(szLine))
	{
		//查找逗号
		char a = ',';
		size_t   pos = szLine.Find(a);
		int size123 = szLine.GetLength();
		
		CString name = szLine.Left(pos);
		CString status1 = szLine.Right(1);
		CString password = szLine.Mid(pos + 1, size123 - pos - 3);

		if (!name.GetLength() == 0)
		{
			SetDlgItemText(IDC_EDIT_USER, name);
			SetDlgItemText(IDC_EDIT_PASSWARD, password);
			if (status1 == "1")
			{
				((CButton*)GetDlgItem(IDC_CHECK1))->SetCheck(1);
			}
			else
			{
				((CButton*)GetDlgItem(IDC_CHECK1))->SetCheck(0);
			}
			break;
		}
	}

	file.Close();
}

猜你喜欢

转载自blog.csdn.net/kai69/article/details/80853997