开发语言:C++
使用工具:Visual Studio2019,MySQL,navicat
开发者:xxlzdf等
csdn源码及项目所用库下载:xxlzdf-学习公社源码及表结构
1.基本注册登录,用户注册后登陆,忘记密码修改密码等;
2.聊天室功能:使用udp协议广播发送接收信息;
3.搜索资源功能:搜索服务器相应类别的所有资源;
4.上传/下载功能:上传资源到服务器、从服务器下载资源到本地;
5.查看用户信息功能:查看个人信息,并签到获得积分。
在之前的博客C++基于MFC——课程管理系统中有详细介绍传送门
连接MySQL所需成员变量在头文件中定义初始化
MYSQL* conn;
MYSQL_RES* res;
MYSQL_ROW row;
const char* server = "localhost";
const char* user = "root";
const char* password = "123";
const char* database = "system";
本项目资源共享部分服务器端基于FTP服务器,链接为本地搭建FTP服务器的教程Windows下搭建FTP服务器
功能:用户的注册、登录和修改密码主页面
分析:获取控件Edit中输入的字符串,并对空白输入进行处理。
登录用到用户表,通过输入的用户名搜索用户名和密码是否匹配,匹配则登陆成功。
另外设置了匿名登录功能,供游客直接登录使用,方便可以下载项目直接进行程序的测试。
void CsystemDlg::OnBnClickedOk()
{
// TODO: 在此添加控件通知处理程序代码
CString name, pass;
GetDlgItemText(IDC_EDIT_NAME, name);
GetDlgItemText(IDC_EDIT_PASS, pass);
if (!name.GetLength())
{
MessageBox(L"用户名不能为空!", L"提示");
return;
}
else if(!pass.GetLength())
{
MessageBox(L"密码不能为空!", L"提示");
return;
}
conn = mysql_init(NULL);
if (0 == mysql_options(conn, MYSQL_SET_CHARSET_NAME, "gbk"))//设置字符集
{
cout << "设置字符集成功\n\n" << endl;
}
// connect to database
if (!mysql_real_connect(conn, server, user, password, database, 3306, NULL, 0))
{
std::cout << stderr << "%s\n" << mysql_error(conn);
return ;
}
CString sql;
sql.Format(_T("select * from user where User_Name='%s'"), name);
USES_CONVERSION;
char* mysql = T2A(sql);
if (mysql_query(conn, mysql))
{
MessageBox(_T("查询数据出错"), _T("警告"), MB_OK);
return;
}
res = mysql_use_result(conn);
if ((row = mysql_fetch_row(res)) != NULL)
{
if ((CString)row[2] != pass)
{
MessageBox(_T("用户名或密码错误!"), _T("警告"), MB_OK);
Password.SetWindowText(L"");
return;
}
else
{
MessageBox(_T("登录成功"), _T("提示"), MB_OK);
Meun m(name);
m.DoModal();
return;
}
}
else
{
MessageBox(_T("用户名或密码错误!"), _T("警告"), MB_OK);
Password.SetWindowText(L"");
}
mysql_close(conn);
}
void CsystemDlg::OnBnClickedButtonNoname()//匿名登录
{
// TODO: 在此添加控件通知处理程序代码
CString cr = L"匿名用户";
Login.SetWindowText(cr);
Password.SetWindowText(L"******");
Meun m(cr);
m.DoModal();
}
void CsystemDlg::OnBnClickedButtonReg()//注册
{
// TODO: 在此添加控件通知处理程序代码
Register reg;
reg.DoModal();
}
void CsystemDlg::OnBnClickedButtonFog()//忘记密码
{
// TODO: 在此添加控件通知处理程序代码
AlterPass alt;
alt.DoModal();
}
功能:用户的注册
分析:注册需要用户输入详细的个人信息,我们需要对输入进行非空判断,并检查输入密码和确认密码是否一致。都满足条件则向用户表中添加注册的一条记录。
为了用户表记录保持唯一性,我们在获取输入的用户名和邮箱后先查询表中的记录,如果有重复则提示用户名/邮箱已被注册,我们要求注册用户重新填写用户名和邮箱进行注册。
注册成功后,即赠送5个积分用于资源共享。这里只需要在注册插入时默认插入字段User_Score = 5
.
void Register::OnBnClickedOk()
{
// TODO: 在此添加控件通知处理程序代码
CString name, mail, age, pass, pass2;
GetDlgItemText(IDC_EDIT_NAME, name);
GetDlgItemText(IDC_EDIT_MAIL, mail);
GetDlgItemText(IDC_EDIT_AGE, age);
GetDlgItemText(IDC_EDIT_PASS, pass);
GetDlgItemText(IDC_EDIT_PASS2, pass2);
conn = mysql_init(NULL);//conn分配初始化MySQL对象
if (0 == mysql_options(conn, MYSQL_SET_CHARSET_NAME, "gbk"))//设置字符集
{
}
// connect to database
if (!mysql_real_connect(conn, server, user, password, database, 3306, NULL, 0))
{
MessageBox(_T("没有获得数据库连接"), _T("警告"), MB_OK);
return;
}
if (!name.GetLength()) MessageBox(L"用户名不能为空!", L"提示");
else if (!mail.GetLength()) MessageBox(L"邮箱不能为空!", L"提示");
else if (!age.GetLength()) MessageBox(L"年龄不能为空!", L"提示");
else if (!pass.GetLength()) MessageBox(L"密码不能为空!", L"提示");
else if (!pass2.GetLength()) MessageBox(L"确认密码不能为空!", L"提示");
else
{
CString s, e;
s.Format(L"Select * from user where User_Name='%s'", name);
e.Format(L"Select * from user where User_Mail='%s'", mail);
USES_CONVERSION;
char* mysql = T2A(s);
char* mysql2 = T2A(e);
if (mysql_query(conn, mysql))//mysql_query(mysql连接,想要进行的查询语句)
{
MessageBox(_T("查询数据出错"), _T("警告"), MB_OK);
mysql_close(conn);
return;
}
res = mysql_use_result(conn);
if ((row = mysql_fetch_row(res))!=NULL)
{
MessageBox(L"该用户名已存在!", L"警告");
}
else
{
if (mysql_query(conn, mysql2))//mysql_query(mysql连接,想要进行的查询语句)
{
MessageBox(_T("查询数据出错"), _T("警告"), MB_OK);
mysql_close(conn);
return;
}
res = mysql_use_result(conn);
if ((row = mysql_fetch_row(res)) != NULL)
{
MessageBox(L"该邮箱已被注册!", L"警告");
}
else if (pass != pass2)
{
MessageBox(L"两次输入密码不一致!", L"提示");
}
else
{
CString sql;
int age1 = _ttoi(age);
sql.Format(L"Insert into user(User_Name,User_Pass,User_Score,User_Age,User_Mail,User_Last_Login) VALUES('%s', '%s', '%d', '%d', '%s','00:00:00')", name, pass, 5, age1, mail);
//USES_CONVERSION;
mysql = T2A(sql);
if (mysql_query(conn, mysql))
{
MessageBox(_T("注册失败!"), _T("警告"), MB_OK);
mysql_close(conn);
return;
}
MessageBox(L"注册成功,赠送您5积分!", L"提示", MB_OK);
mysql_close(conn);
CDialog::OnOK();
}
}
}
}
功能:用户修改密码
分析:找回密码首先对输入进行非空判断
我们需要用户填写正确的用户名及邮箱,且要求用户名邮箱匹配同一条记录(同一个用户),并检查两次输入密码是否一致,一致则修改表中记录的内容。
void AlterPass::OnBnClickedOk()
{
// TODO: 在此添加控件通知处理程序代码
CString name, mail, pass, pass2;
GetDlgItemText(IDC_EDIT_NAME, name);
GetDlgItemText(IDC_EDIT_MAIL, mail);
GetDlgItemText(IDC_EDIT_PASS, pass);
GetDlgItemText(IDC_EDIT_PASS2, pass2);
conn = mysql_init(NULL);//conn分配初始化MySQL对象
if (0 == mysql_options(conn, MYSQL_SET_CHARSET_NAME, "gbk"))//设置字符集
{
}
// connect to database
if (!mysql_real_connect(conn, server, user, password, database, 3306, NULL, 0))
{
MessageBox(_T("没有获得数据库连接"), _T("警告"), MB_OK);
return;
}
if (!name.GetLength()) MessageBox(L"用户名不能为空!", L"提示");
else if (!mail.GetLength()) MessageBox(L"邮箱不能为空!", L"提示");
else if (!pass.GetLength()) MessageBox(L"新密码不能为空!", L"提示");
else if (!pass2.GetLength()) MessageBox(L"确认密码不能为空!", L"提示");
else
{
CString s;
s.Format(L"Select * from user where User_Name='%s'", name);
USES_CONVERSION;
char* mysql = T2A(s);
if (mysql_query(conn, mysql))//mysql_query(mysql连接,想要进行的查询语句)
{
MessageBox(_T("查询数据出错"), _T("警告"), MB_OK);
mysql_close(conn);
return;
}
res = mysql_use_result(conn);
if ((row = mysql_fetch_row(res)) != NULL)
{
mysql_close(conn);
if(mail==(CString)row[5])
{
if (pass != pass2)
{
MessageBox(L"两次输入密码不一致!", L"提示");
}
else
{
RevisePass(name, pass);
CDialog::OnOK();
}
}
else
{
MessageBox(L"请填写正确的邮箱!", L"警告");
Edit_Mail.SetWindowText(_T(""));//添加清空操作
}
}
else
{
MessageBox(L"该用户不存在!", L"警告");
Edit_Name.SetWindowText(_T(""));//添加清空操作
}
}
}
void AlterPass::RevisePass(CString name,CString pass)
{
CString sql;
sql.Format(L"update user set User_Pass='%s' where User_Name='%s'", pass, name);
USES_CONVERSION;
char* mysql = T2A(sql);
conn = mysql_init(NULL);//conn分配初始化MySQL对象
if (0 == mysql_options(conn, MYSQL_SET_CHARSET_NAME, "gbk"))//设置字符集
{
}
// connect to database
if (!mysql_real_connect(conn, server, user, password, database, 3306, NULL, 0))
{
MessageBox(_T("没有获得数据库连接"), _T("警告"), MB_OK);
return ;
}
if (mysql_query(conn, mysql))
{
MessageBox(_T("更新失败!"), _T("警告"), MB_OK);
mysql_close(conn);
return;
}
MessageBox(L"密码修改成功!", L"提示", MB_OK);
mysql_close(conn);
}
功能:菜单功能
分析:添加其他类的头文件,每个按钮的点击事件下定义相应的对象,访问对象的对话框,并向其传入登录用户的用户名。
void Meun::OnBnClickedButtonChat()//聊天室
{
Chat_Room ch(str);
ch.DoModal();
// TODO: 在此添加控件通知处理程序代码
}
void Meun::OnBnClickedCancel()//退出按钮
{
// TODO: 在此添加控件通知处理程序代码
int m=MessageBox(_T("退出程序?") ,_T("提示"), MB_OKCANCEL);
if(m==1) CDialog::OnCancel();
}
void Meun::OnBnClickedButtonUp()//资源分享
{
// TODO: 在此添加控件通知处理程序代码
FtpClient Ftp(str);
Ftp.DoModal();
}
void Meun::OnBnClickedButtonView()//查看个人信息
{
// TODO: 在此添加控件通知处理程序代码
Self_Infor sif(str);
sif.DoModal();
}
void Meun::OnBnClickedButtonSch()//资源搜索
{
// TODO: 在此添加控件通知处理程序代码
Book_Search book;
book.DoModal();
}
功能:在局域网中实现聊天功能
分析:用户在局域网上发送广播消息,同时也接受其他用户发送的广播消息,收到的信息显示在上面的列表框中,下面的文本框用于编辑用户要广播发送的信息。
需要在OnInitDialog()中创建套接字并绑定本地地址,并调用WSAAsyncSelect()函数用于接收信息的数据报套接字注册FD_READ网络事件
在利用sendto发送数据时,需要将提取的字符串在Unicode下由CString类型转换为const char*类型。
BOOL Chat_Room::OnInitDialog()
{
CDialog::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != nullptr)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
udpsock = socket(AF_INET, SOCK_DGRAM, 0);
int vsize = sizeof(BOOL);
BOOL yes = TRUE;
setsockopt(udpsock, SOL_SOCKET, SO_BROADCAST, (char*)&yes, vsize);
struct sockaddr_in localaddr;
int len = sizeof(struct sockaddr_in);
localaddr.sin_family = AF_INET;
localaddr.sin_port = htons(PORT);
localaddr.sin_addr.s_addr = INADDR_ANY;
if (bind(udpsock, (sockaddr*)&localaddr, len) == SOCKET_ERROR)
{
MessageBox(_T("bind local address error!"));
closesocket(udpsock);
WSACleanup();
return 0;
}
if (WSAAsyncSelect(udpsock, m_hWnd, RECVMSG, FD_READ) != 0)
MessageBox(_T("套接字消息注册失败!"));
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
afx_msg LRESULT Chat_Room::OnRecvmsg(WPARAM wParam, LPARAM lParam)
{
char buf[1000];
CString str;
int a;
a = recvfrom(udpsock, buf, sizeof(buf), 0, NULL, NULL);
if (a > 0)
{
//MessageBox((LPCTSTR)(buf));
str.Format(_T("%s:%s"), tr, buf);//tr为登录用户的用户名
m_List.AddString(str);
}
return 0;
}
void Chat_Room::OnBnClickedOk()
{
// TODO: 在此添加控件通知处理程序代码
CString str;
GetDlgItemText(IDC_EDIT1, str);
if (!str.GetLength())
{
MessageBox(L"输入消息不能为空!", L"提示");
return;
}
struct sockaddr_in broadcastaddr;//广播地址
int len = sizeof(broadcastaddr);
broadcastaddr.sin_family = AF_INET;
broadcastaddr.sin_port = htons(PORT);
broadcastaddr.sin_addr.s_addr = INADDR_BROADCAST;
UpdateData();
//Unicode下CString转换到const char*
sendto(udpsock, (LPCSTR)(LPCTSTR)str, 1000, 0, (struct sockaddr*)&broadcastaddr, len);
GetDlgItem(IDC_EDIT1)->SetWindowText(_T(""));//点击发送后将Edit中的字清空
}
void Chat_Room::OnBnClickedCancel()
{
// TODO: 在此添加控件通知处理程序代码
closesocket(udpsock);
CDialog::OnCancel();
}
本对话框改编于FTP基于MFC对话框实现与服务器文件传输,感谢大佬的思路以及源代码。
本项目的服务器端基于windowsFTP服务器,上传时需要用户至少选择一个类别上传。
这里我们利用CString filename = strname.Left(n);
取出文件名,CString category = strdir.Right(strdir.GetLength()-1);
取出文件夹名。
文件夹名就是上传资源的类别,我们可以利用文件名和文件夹名作为Book_Name和Book_cate在数据库中添加记录。
还少了一个出版社名,这需要用户手动输入。
void FtpClient::OnUpLoad()
{
// TODO: 在此添加控件通知处理程序代码
if (!bconnect)
{
MessageBox(L"请先连接FTP服务器!");
return;
}
CString str;
CString strname;
//弹出“打开”对话框
CFileDialog file(true, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("所有文件(*.*)|*.*|"), this);
if (file.DoModal() == IDOK)
{
str = file.GetPathName();
strname = file.GetFileName();
}
CString strdir;
pFtpConnection->GetCurrentDirectory(strdir);
//将文件名和类别取出来入库
int n = strname.ReverseFind('.');
CString filename = strname.Left(n);//去掉后缀
CString category = strdir.Right(strdir.GetLength()-1); //去掉前缀
//上传文件这里利用数据库查询限制不能上传库中已有的资源
if (!filename.GetLength()) return;
if (category.GetLength()-1==0)
{
MessageBox(L"请至少选择一个类别再上传", L"提示");
return;
}
if (!Search(filename))
{
//上传文件
BOOL bput = pFtpConnection->PutFile((LPCTSTR)str, (LPCTSTR)strname);
//获取出版社
Book_Pub book;
book.DoModal();
CString publisher=book.Get_Publish();//成员函数获取用户输入的出版社名
//添加到数据库
Add_Book(filename,category, publisher);
if (bput)
{
pInternetSession->Close();//关闭会话
this->ConnectFtp();//重新连接保持持续会话
pFtpConnection->SetCurrentDirectory(strdir);
this->UpdateDir();//更新目录列表
if (tr != "匿名用户") Update_Score(tr);
MessageBox(_T("上传成功!获得5积分!"), L"提示");
}
}
else
{
MessageBox(L"上传失败,库中已有您的资源!", L"提示");
}
}
void FtpClient::Add_Book(CString file,CString cate,CString publisher)
{
conn = mysql_init(NULL);//conn分配初始化MySQL对象
if (0 == mysql_options(conn, MYSQL_SET_CHARSET_NAME, "gbk"))//设置字符集
{
}
// connect to database
if (!mysql_real_connect(conn, server, user, password, database, 3306, NULL, 0))
{
MessageBox(_T("没有获得数据库连接"), _T("警告"), MB_OK);
return;
}
CString sql;
sql.Format(L"insert into book(Book_Name,Book_Update_Times,Book_Cate,Book_Publish) values('%s', '0', '%s', '%s')", file,cate, publisher);
USES_CONVERSION;
char* mysql = T2A(sql);
if (mysql_query(conn, mysql))
{
MessageBox(_T("插入数据出错"), _T("警告"), MB_OK);
return;
}
}
bool FtpClient::Search(CString name)
{
conn = mysql_init(NULL);//conn分配初始化MySQL对象
if (0 == mysql_options(conn, MYSQL_SET_CHARSET_NAME, "gbk"))//设置字符集
{
}
// connect to database
if (!mysql_real_connect(conn, server, user, password, database, 3306, NULL, 0))
{
MessageBox(_T("没有获得数据库连接"), _T("警告"), MB_OK);
return false;
}
CString sql;
sql.Format(L"select * from book where Book_Name='%s'", name);
USES_CONVERSION;
char* mysql = T2A(sql);
if (mysql_query(conn, mysql))
{
MessageBox(_T("查找数据出错"), _T("警告"), MB_OK);
return false;
}
res = mysql_use_result(conn);
if ((row = mysql_fetch_row(res)) != NULL) return true;
else return false;
}
void FtpClient::Update_Score(CString str)
{
conn = mysql_init(NULL);//conn分配初始化MySQL对象
if (0 == mysql_options(conn, MYSQL_SET_CHARSET_NAME, "gbk"))//设置字符集
{
}
// connect to database
if (!mysql_real_connect(conn, server, user, password, database, 3306, NULL, 0))
{
MessageBox(_T("没有获得数据库连接"), _T("警告"), MB_OK);
return;
}
CString sql;
sql.Format(L"update user set User_Score = User_Score +5 where User_Name='%s'", str);
USES_CONVERSION;
char* mysql = T2A(sql);
if (mysql_query(conn, mysql))
{
MessageBox(_T("更新数据出错"), _T("警告"), MB_OK);
return;
}
mysql_free_result(res);
mysql_close(conn);
}
下载时首先点击进入相应文件夹选择资源,再对用户记录进行查询,积分大于等于5可以下载,下载后扣除五个积分。
积分不足时则弹窗提示。
void FtpClient::OnDownload()
{
// TODO: 在此添加控件通知处理程序代码
CString selfile;
if (!bconnect)
{
MessageBox(L"请先连接FTP服务器!");
return;
}
if (FileName.GetCurSel() == LB_ERR)
{
MessageBox(L"请至少选择一个资源下载!");
return;
}
FileName.GetText(FileName.GetCurSel(), selfile);//获得想要下载资源名
//MessageBox(selfile);
if (!selfile.IsEmpty())
{
if (tr != "匿名用户")
{
if (Judge_Score(tr))
{
Update_Formal(selfile);
}
else
{
MessageBox(L"积分不足,无法下载!", L"警告");
}
}
else
{
Update_Formal(selfile);
}
}
}
void FtpClient::Update_Formal(CString selfile)
{
//弹出另存为对话框
CFileDialog file(true, NULL, selfile, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("所有文件(*.*)|*.*|"), this);
if (file.DoModal() == IDOK)
{
CString strPath;
CString strdir;
strPath = file.GetPathName();
pFtpConnection->GetCurrentDirectory(strdir);
pFtpConnection->GetFile(selfile, strPath);//下载文件到的本地位置
pInternetSession->Close();
this->ConnectFtp();
pFtpConnection->SetCurrentDirectory(strdir);
this->UpdateDir();
if(tr!="匿名用户") Revise_Score(tr);
MessageBox(_T("下载成功,扣除您5积分!"), L"提示");
}
}
bool FtpClient::Judge_Score(CString str)
{
conn = mysql_init(NULL);//conn分配初始化MySQL对象
if (0 == mysql_options(conn, MYSQL_SET_CHARSET_NAME, "gbk"))//设置字符集
{
}
// connect to database
if (!mysql_real_connect(conn, server, user, password, database, 3306, NULL, 0))
{
MessageBox(_T("没有获得数据库连接"), _T("警告"), MB_OK);
return false;
}
CString sql;
sql.Format(L"select User_Score from user where User_Name='%s'", str);
USES_CONVERSION;
char* mysql = T2A(sql);
if (mysql_query(conn, mysql))
{
MessageBox(_T("查询数据出错"), _T("警告"), MB_OK);
return false;
}
res = mysql_use_result(conn);
if ((row = mysql_fetch_row(res)) != NULL)
{
//MessageBox(_T("查询成功!"), _T("提示"), MB_OK);
int score =_ttoi((CString)row[0]);
//MessageBox((CString)row[0]);
if (score < 5) return false;
else return true;
}
}
void FtpClient::Revise_Score(CString str)
{
conn = mysql_init(NULL);//conn分配初始化MySQL对象
if (0 == mysql_options(conn, MYSQL_SET_CHARSET_NAME, "gbk"))//设置字符集
{
}
// connect to database
if (!mysql_real_connect(conn, server, user, password, database, 3306, NULL, 0))
{
MessageBox(_T("没有获得数据库连接"), _T("警告"), MB_OK);
return;
}
CString sql;
sql.Format(L"update user set User_Score = User_Score -5 where User_Name='%s'", str);
USES_CONVERSION;
char* mysql = T2A(sql);
if (mysql_query(conn, mysql))
{
MessageBox(_T("更新数据出错"), _T("警告"), MB_OK);
return;
}
mysql_free_result(res);
mysql_close(conn);
}
功能:用户输入类别搜索资源
分析:用户输入资源类别进行查询,对输入进行非空判断,非空则在book表中进行查询,返回消息弹窗并将类别名传入show()展示该类别所有资源。
void Book_Search::OnBnClickedSearch()
{
// TODO: 在此添加控件通知处理程序代码
CString cate;
GetDlgItemText(IDC_EDIT_SCH, cate);
if (!cate.GetLength())
{
MessageBox(L"输入不能为空!", L"警告");
return;
}
conn = mysql_init(NULL);//conn分配初始化MySQL对象
if (0 == mysql_options(conn, MYSQL_SET_CHARSET_NAME, "gbk"))//设置字符集
{
}
// connect to database
if (!mysql_real_connect(conn, server, user, password, database, 3306, NULL, 0))
{
MessageBox(_T("没有获得数据库连接"), _T("警告"), MB_OK);
return;
}
CString sql;
sql.Format(L"select *from book where Book_Cate='%s'", cate);
USES_CONVERSION;
char* mysql = T2A(sql);
if (mysql_query(conn, mysql))
{
MessageBox(_T("查询数据出错"), _T("警告"), MB_OK);
return;
}
res = mysql_use_result(conn);
if ((row = mysql_fetch_row(res)) != NULL)
{
MessageBox(_T("查询成功!"), _T("提示"), MB_OK);
Show_Resource show(cate);
show.DoModal();
}
else
{
MessageBox(_T("抱歉,库中暂无此类资源!"), _T("通知"), MB_OK);
return;
}
mysql_free_result(res);
mysql_close(conn);
}
功能:显示输入类别的所有资源
分析:
选定List Control控件,选择其视图为报表模式。
对标题及表头在DoDataExchange()中进行初始化。
void Show_Resource::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST2, Res_List);
CString title;
title.Format(L"%s资源",cate);
SetDlgItemText(IDC_STATIC_TITLE, title);
Res_List.InsertColumn(0, _T("资源名称"));
Res_List.SetColumnWidth(0, 200);
Res_List.InsertColumn(1, L"资源分类");
Res_List.SetColumnWidth(1, 100);
Res_List.InsertColumn(2, _T("资源出版社"));
Res_List.SetColumnWidth(2, 140);
Res_List.InsertColumn(3, _T("累计下载次数"));
Res_List.SetColumnWidth(3, 110);
Show();
}
然后利用类别在book表中查询,将查询结果显示在相应列中。
void Show_Resource::Show()
{
conn = mysql_init(NULL);//conn分配初始化MySQL对象
if (0 == mysql_options(conn, MYSQL_SET_CHARSET_NAME, "gbk"))//设置字符集
{
}
// connect to database
if (!mysql_real_connect(conn, server, user, password, database, 3306, NULL, 0))
{
MessageBox(_T("没有获得数据库连接"), _T("警告"), MB_OK);
return;
}
CString sql;
sql.Format(L"select *from book where Book_Cate='%s'", cate);
USES_CONVERSION;
char* mysql = T2A(sql);
if (mysql_query(conn, mysql))
{
MessageBox(_T("查询数据出错"), _T("警告"), MB_OK);
return;
}
res = mysql_use_result(conn);
Res_List.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);//调整选框
Res_List.DeleteAllItems();
int i = 0;
// output table name
while ((row = mysql_fetch_row(res)) != NULL)
{
Res_List.InsertItem(i, (CString)(row[1]));
Res_List.SetItemText(i, 1, (CString)(row[3]));
Res_List.SetItemText(i, 2, (CString)(row[4]));
Res_List.SetItemText(i, 3, (CString)(row[2]));
i++;
}
mysql_free_result(res);
mysql_close(conn);
}
功能:查看详细的个人信息
分析:通过登陆的用户名在表中查询,将查询结果显示在statictext上。
void Self_Infor::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//添加一些代码
SetDlgItemText(IDC_STATIC_NAME, str);//text显示选中行的id
if (str == "匿名用户")
{
SetDlgItemText(IDC_STATIC_MAIL, (CString)("无"));
SetDlgItemText(IDC_STATIC_AGE, (CString)("无"));
SetDlgItemText(IDC_STATIC_SCORE, (CString)("无限"));
return;
}
conn = mysql_init(NULL);//conn分配初始化MySQL对象
if (0 == mysql_options(conn, MYSQL_SET_CHARSET_NAME, "gbk"))//设置字符集
{
}
// connect to database
if (!mysql_real_connect(conn, server, user, password, database, 3306, NULL, 0))
{
MessageBox(_T("没有获得数据库连接"), _T("警告"), MB_OK);
return;
}
CString sql;
sql.Format(L"select * from user where User_Name='%s'", str);
USES_CONVERSION;
char* mysql = T2A(sql);
if (mysql_query(conn, mysql))
{
MessageBox(_T("查询数据出错"), _T("警告"), MB_OK);
return;
}
res = mysql_use_result(conn);
if ((row = mysql_fetch_row(res)) != NULL)
{
SetDlgItemText(IDC_STATIC_NAME, (CString)row[1]);
SetDlgItemText(IDC_STATIC_MAIL, (CString)row[5]);
SetDlgItemText(IDC_STATIC_AGE, (CString)row[4]);
SetDlgItemText(IDC_STATIC_SCORE, (CString)row[3]);
}
else
{
MessageBox(_T("查询本行出错"), _T("警告"), MB_OK);
return;
}
mysql_free_result(res);
mysql_close(conn);
}
通过CTime类获取签到当天的年月日,并与表中
User_Last_Login
的数据比对,如果不相同则更新数据并显示签到成功,如果相同则说明当日已经签到,弹窗提醒。
void Self_Infor::OnBnClickedButtonSign()
{
// TODO: 在此添加控件通知处理程序代码
if (str == "匿名用户") MessageBox(L"欲签到,请您先注册登录!",L"提示");
CTime t = CTime::GetCurrentTime();
int nYear = t.GetYear();
int nMonth = t.GetMonth();
int nDay = t.GetDay();
CString today;
today.Format(L"%d:%d:%d", nYear, nMonth, nDay);
//MessageBox(today);
conn = mysql_init(NULL);//conn分配初始化MySQL对象
if (0 == mysql_options(conn, MYSQL_SET_CHARSET_NAME, "gbk"))//设置字符集
{
}
// connect to database
if (!mysql_real_connect(conn, server, user, password, database, 3306, NULL, 0))
{
MessageBox(_T("没有获得数据库连接"), _T("警告"), MB_OK);
return;
}
CString sql;
sql.Format(L"select * from user where User_Name='%s'", str);
USES_CONVERSION;
char* mysql = T2A(sql);
if (mysql_query(conn, mysql))
{
MessageBox(_T("查询数据出错"), _T("警告"), MB_OK);
return;
}
res = mysql_use_result(conn);
if ((row = mysql_fetch_row(res)) != NULL)
{
if ((CString)row[6]!= today)
{
Update_Score(today);
MessageBox(L"签到成功,获得5积分!", L"提示");
int score = _ttoi((CString)row[3])+5;
CString ans;
ans.Format(L"%d",score);
SetDlgItemText(IDC_STATIC_SCORE, ans);
}
else
{
MessageBox(L"您今天已经签到过了!", L"提示");
}
}
mysql_free_result(res);
}
void Self_Infor::Update_Score(CString today)
{
conn = mysql_init(NULL);//conn分配初始化MySQL对象
if (0 == mysql_options(conn, MYSQL_SET_CHARSET_NAME, "gbk"))//设置字符集
{
}
// connect to database
if (!mysql_real_connect(conn, server, user, password, database, 3306, NULL, 0))
{
MessageBox(_T("没有获得数据库连接"), _T("警告"), MB_OK);
return;
}
CString sql;
sql.Format(L"update user set User_Last_Login = '%s' , User_Score = User_Score +5 where User_Name='%s'", today,str);
USES_CONVERSION;
char* mysql = T2A(sql);
if (mysql_query(conn, mysql))
{
MessageBox(_T("更新数据出错"), _T("警告"), MB_OK);
return;
}
res = mysql_use_result(conn);
mysql_close(conn);
}
这次课题的目的首先是为了练习socket套接字编程,将聊天和文件传输运用到课题中去。但是文件传输这里一直没找到合适且可行的方法,直到看到了利用FTP服务器的文件传输的博客,因为之前没有了解过相关的知识,所以进行改编并运用到项目中来。
从一筹莫展到完成项目花费了大概将近两周的时间,完成项目还是需要搜索大量的知识、关注细节并不断调试错误,还是很能提高编程能力的。
附项目源代码及数据库表结构和数据:C++基于MFC课程设计——学习公社