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



http://www.chinasem.cn/article/783283

相关文章

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

C++初始化数组的几种常见方法(简单易懂)

《C++初始化数组的几种常见方法(简单易懂)》本文介绍了C++中数组的初始化方法,包括一维数组和二维数组的初始化,以及用new动态初始化数组,在C++11及以上版本中,还提供了使用std::array... 目录1、初始化一维数组1.1、使用列表初始化(推荐方式)1.2、初始化部分列表1.3、使用std::

C++ Primer 多维数组的使用

《C++Primer多维数组的使用》本文主要介绍了多维数组在C++语言中的定义、初始化、下标引用以及使用范围for语句处理多维数组的方法,具有一定的参考价值,感兴趣的可以了解一下... 目录多维数组多维数组的初始化多维数组的下标引用使用范围for语句处理多维数组指针和多维数组多维数组严格来说,C++语言没

c++中std::placeholders的使用方法

《c++中std::placeholders的使用方法》std::placeholders是C++标准库中的一个工具,用于在函数对象绑定时创建占位符,本文就来详细的介绍一下,具有一定的参考价值,感兴... 目录1. 基本概念2. 使用场景3. 示例示例 1:部分参数绑定示例 2:参数重排序4. 注意事项5.

使用C++将处理后的信号保存为PNG和TIFF格式

《使用C++将处理后的信号保存为PNG和TIFF格式》在信号处理领域,我们常常需要将处理结果以图像的形式保存下来,方便后续分析和展示,C++提供了多种库来处理图像数据,本文将介绍如何使用stb_ima... 目录1. PNG格式保存使用stb_imagephp_write库1.1 安装和包含库1.2 代码解

C++实现封装的顺序表的操作与实践

《C++实现封装的顺序表的操作与实践》在程序设计中,顺序表是一种常见的线性数据结构,通常用于存储具有固定顺序的元素,与链表不同,顺序表中的元素是连续存储的,因此访问速度较快,但插入和删除操作的效率可能... 目录一、顺序表的基本概念二、顺序表类的设计1. 顺序表类的成员变量2. 构造函数和析构函数三、顺序表

使用C++实现单链表的操作与实践

《使用C++实现单链表的操作与实践》在程序设计中,链表是一种常见的数据结构,特别是在动态数据管理、频繁插入和删除元素的场景中,链表相比于数组,具有更高的灵活性和高效性,尤其是在需要频繁修改数据结构的应... 目录一、单链表的基本概念二、单链表类的设计1. 节点的定义2. 链表的类定义三、单链表的操作实现四、

使用C/C++调用libcurl调试消息的方式

《使用C/C++调用libcurl调试消息的方式》在使用C/C++调用libcurl进行HTTP请求时,有时我们需要查看请求的/应答消息的内容(包括请求头和请求体)以方便调试,libcurl提供了多种... 目录1. libcurl 调试工具简介2. 输出请求消息使用 CURLOPT_VERBOSE使用 C

C++实现获取本机MAC地址与IP地址

《C++实现获取本机MAC地址与IP地址》这篇文章主要为大家详细介绍了C++实现获取本机MAC地址与IP地址的两种方式,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 实际工作中,项目上常常需要获取本机的IP地址和MAC地址,在此使用两种方案获取1.MFC中获取IP和MAC地址获取