本文主要是介绍C++基于MFC课程设计——在线聊天室与图书资源共享,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
学习公社课程设计
- 学习公社
- 一、系统使用展示
- 二、系统主要结构
- 1.系统功能介绍
- 2.数据库表的设计
- 用户表
- 资源表
- 3.MySQL数据库与vs连接
- 三、主要源代码及分析:
- ==VS和MySQL的连接==
- ==本地搭建FTP服务器==
- ==1.用户登录界面==
- 用户登录
- 用户注册
- 忘记密码
- ==2.菜单==
- 菜单展示
- ==3.聊天室==
- 利用UDP协议实现
- ==4.资源共享==
- 利用FTP服务器实现
- 上传资源
- 资源下载
- ==5.资源搜索==
- 资源显示
- ==6.查看个人信息==
- 签到功能
- 四、总结
学习公社
开发语言:C++
使用工具:Visual Studio2019,MySQL,navicat
开发者:xxlzdf等
csdn源码及项目所用库下载:xxlzdf-学习公社源码及表结构
一、系统使用展示
二、系统主要结构
1.系统功能介绍
1.基本注册登录,用户注册后登陆,忘记密码修改密码等;
2.聊天室功能:使用udp协议广播发送接收信息;
3.搜索资源功能:搜索服务器相应类别的所有资源;
4.上传/下载功能:上传资源到服务器、从服务器下载资源到本地;
5.查看用户信息功能:查看个人信息,并签到获得积分。
2.数据库表的设计
用户表
资源表
3.MySQL数据库与vs连接
在之前的博客C++基于MFC——课程管理系统中有详细介绍传送门
三、主要源代码及分析:
头文件
源文件
对话框文件
VS和MySQL的连接
连接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服务器,链接为本地搭建FTP服务器的教程Windows下搭建FTP服务器
1.用户登录界面
用户登录
功能:用户的注册、登录和修改密码主页面
分析:获取控件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 databaseif (!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 databaseif (!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 databaseif (!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 databaseif (!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);
}
2.菜单
菜单展示
功能:菜单功能
分析:添加其他类的头文件,每个按钮的点击事件下定义相应的对象,访问对象的对话框,并向其传入登录用户的用户名。
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();
}
3.聊天室
利用UDP协议实现
功能:在局域网中实现聊天功能
分析:用户在局域网上发送广播消息,同时也接受其他用户发送的广播消息,收到的信息显示在上面的列表框中,下面的文本框用于编辑用户要广播发送的信息。
需要在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();
}
4.资源共享
利用FTP服务器实现
本对话框改编于FTP基于MFC对话框实现与服务器文件传输,感谢大佬的思路以及源代码。
上传资源
本项目的服务器端基于windowsFTP服务器,上传时需要用户至少选择一个类别上传。
这里我们利用CString filename = strname.Left(n);
取出文件名,CString category = strdir.Right(strdir.GetLength()-1);
取出文件夹名。
文件夹名就是上传资源的类别,我们可以利用文件名和文件夹名作为Book_Name和Book_cate在数据库中添加记录。
还少了一个出版社名,这需要用户手动输入。
上传成功后,获得5个积分。
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 databaseif (!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 databaseif (!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 databaseif (!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 databaseif (!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 databaseif (!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.资源搜索
功能:用户输入类别搜索资源
分析:用户输入资源类别进行查询,对输入进行非空判断,非空则在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 databaseif (!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 databaseif (!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 namewhile ((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);
}
6.查看个人信息
功能:查看详细的个人信息
分析:通过登陆的用户名在表中查询,将查询结果显示在statictext上。
void Self_Infor::DoDataExchange(CDataExchange* pDX)
{CDialog::DoDataExchange(pDX);//添加一些代码SetDlgItemText(IDC_STATIC_NAME, str);//text显示选中行的idif (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 databaseif (!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 databaseif (!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 databaseif (!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课程设计——学习公社
这篇关于C++基于MFC课程设计——在线聊天室与图书资源共享的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!