C++基于MFC课程设计——在线聊天室与图书资源共享

2024-03-07 10:59

本文主要是介绍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课程设计——在线聊天室与图书资源共享的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:https://blog.csdn.net/qq_45929428/article/details/118212161
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/783283

相关文章

Windows下C++使用SQLitede的操作过程

《Windows下C++使用SQLitede的操作过程》本文介绍了Windows下C++使用SQLite的安装配置、CppSQLite库封装优势、核心功能(如数据库连接、事务管理)、跨平台支持及性能优... 目录Windows下C++使用SQLite1、安装2、代码示例CppSQLite:C++轻松操作SQ

C++中RAII资源获取即初始化

《C++中RAII资源获取即初始化》RAII通过构造/析构自动管理资源生命周期,确保安全释放,本文就来介绍一下C++中的RAII技术及其应用,具有一定的参考价值,感兴趣的可以了解一下... 目录一、核心原理与机制二、标准库中的RAII实现三、自定义RAII类设计原则四、常见应用场景1. 内存管理2. 文件操

C++中零拷贝的多种实现方式

《C++中零拷贝的多种实现方式》本文主要介绍了C++中零拷贝的实现示例,旨在在减少数据在内存中的不必要复制,从而提高程序性能、降低内存使用并减少CPU消耗,零拷贝技术通过多种方式实现,下面就来了解一下... 目录一、C++中零拷贝技术的核心概念二、std::string_view 简介三、std::stri

C++高效内存池实现减少动态分配开销的解决方案

《C++高效内存池实现减少动态分配开销的解决方案》C++动态内存分配存在系统调用开销、碎片化和锁竞争等性能问题,内存池通过预分配、分块管理和缓存复用解决这些问题,下面就来了解一下... 目录一、C++内存分配的性能挑战二、内存池技术的核心原理三、主流内存池实现:TCMalloc与Jemalloc1. TCM

C++ 函数 strftime 和时间格式示例详解

《C++函数strftime和时间格式示例详解》strftime是C/C++标准库中用于格式化日期和时间的函数,定义在ctime头文件中,它将tm结构体中的时间信息转换为指定格式的字符串,是处理... 目录C++ 函数 strftipythonme 详解一、函数原型二、功能描述三、格式字符串说明四、返回值五

C++作用域和标识符查找规则详解

《C++作用域和标识符查找规则详解》在C++中,作用域(Scope)和标识符查找(IdentifierLookup)是理解代码行为的重要概念,本文将详细介绍这些规则,并通过实例来说明它们的工作原理,需... 目录作用域标识符查找规则1. 普通查找(Ordinary Lookup)2. 限定查找(Qualif

基于Python实现一个简单的题库与在线考试系统

《基于Python实现一个简单的题库与在线考试系统》在当今信息化教育时代,在线学习与考试系统已成为教育技术领域的重要组成部分,本文就来介绍一下如何使用Python和PyQt5框架开发一个名为白泽题库系... 目录概述功能特点界面展示系统架构设计类结构图Excel题库填写格式模板题库题目填写格式表核心数据结构

C/C++ chrono简单使用场景示例详解

《C/C++chrono简单使用场景示例详解》:本文主要介绍C/C++chrono简单使用场景示例详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友... 目录chrono使用场景举例1 输出格式化字符串chrono使用场景China编程举例1 输出格式化字符串示

C++/类与对象/默认成员函数@构造函数的用法

《C++/类与对象/默认成员函数@构造函数的用法》:本文主要介绍C++/类与对象/默认成员函数@构造函数的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录名词概念默认成员函数构造函数概念函数特征显示构造函数隐式构造函数总结名词概念默认构造函数:不用传参就可以

C++类和对象之默认成员函数的使用解读

《C++类和对象之默认成员函数的使用解读》:本文主要介绍C++类和对象之默认成员函数的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、默认成员函数有哪些二、各默认成员函数详解默认构造函数析构函数拷贝构造函数拷贝赋值运算符三、默认成员函数的注意事项总结一