MFC仿QQ程序设计完整实例教程
仿QQ聊天软件MyQQ源代码教学(北大青鸟完整版)

需求分析——功能分析
主要功能:
注册与登录 好友管理 消息管理 个人设置
需求分析——界面分析
需要的界面:
注册界面 登录界面 登录后的主界面 查找/添加好友界面 聊天界面 系统消息界面 个人设置界面
头像列表界面
需求分析——辅助类分析
需要添加的辅助类:
DBHelper类 UserHelper 类
小组分工
4
4 4 4 4
软件开发流程
比尔盖子是一名建筑工人 起初只干一些比较简单的 建筑工作 凭个人技术和经验,不需要特 别设计,可以顺利完成
如同编写早期比较小的程序
软件开发流程
新任务:建造一间非常美 丽而完整的房间 工作变得复杂许多
像不断发展的软件,功能 越来越多,越来越复杂
软件开发流程
软件复杂性
图形用户界面 客户/服务器结构 分布式应用 数据通信 超大型关系型数据库
// 判断 ListView 中是否有选中的项 if (lvFaces.SelectedItems.Count == 0) { // … } // 获得选中的头像的索引 int faceId = lvFaces.SelectedItems[0].ImageIndex;
第四次集中编码:A任务
个人信息修改功能
第一次集中编码:难点分析
好友列表——第三方控件 SideBar
SbGroup 类型 Items 属性 Groups 属性 SbItem 类型
第一次集中编码:难点分析
SideBar
// 命名空间 using Aptech.UI; // 添加组 sbFriends.AddGroup("我的好友"); sbFriends.AddGroup("陌生人"); 显示的文字 // 添加项 SbItem item = new SbItem((string)dataReader["NickName"], (int)dataReader["FaceId"]); sbFriends.Groups[0].Items.Add(item); 显示的图像索引
QQ局域网根据多线程的聊天软件的编写

实战2012高技术的Hacker黄今天无私的教大家利用C++的MFC做局域网的QQ软件QQ很难吗?C++很难吗?MFC很难吗?做个软件很难吗?答案是不难,因为今天高技术的Hacker黄今天教大家利用C++的MFC做局域网的QQ软件。
废话少说,现在直接带领大家实战做个局域网的QQ软件用C++。
事件2012年11月14号夜晚,湖北大学实验室,实验结果做出一个如下截图的QQ 软件事件发起人hacker黄下面为了大家更好的理解实战类容,首先我将按逻辑的将本次试验叙述下来,不怕不懂,我将把每一步的截图和代码打出来,大家只需要看着截图,结合代码就行了哦哈哈施展正式开始:第一做局域网QQ界面打开vc6.0新建一个工程文件第二选择对话框,点击界面接好了第三删去对话框中的初始控件,第三添加一个组框控件截图如下第四设置组框组建的属性截图如下,并将其CAPTION属性设置为接收数据截图如下第五添加一个编辑框控件并设置其属性截图如下,并将其ID号吗改为IDC_EDIT_RECV截图如下用来显示用户接收到的数据第六再次添加一个组框并将其属性设置为发送数据第七在发送数据组框添加一个IP控件第八在选择一个一个编辑框控件,并设置其ID号,用来放松疏忽需要发送的数据截图如下第九添加一个发送的按钮,并将其ID号吗改为IDC_BTN_SEND第十展示最终的C++MFCQQ界面截图如下第十一加载套接字库截图如下,并添加代码如下补加的的代码如下if(!AfxSocketInit()){AfxMessageBox("加载套接字库失败");return FALSE;}第十二增加一头文件,截图及代码如下代码如下#include<Afxsock.h>第十三增加一个成员变量的函数及代码第十四增加一个成员变量并将其权限设为私有截图如下第十五在初始化套接字函数中输入初始化相关代码m_socket=socket(AF_INET,SOCK_DGRAM,0); if(INVALID_SOCKET==m_socket){MessageBox("套接字失败");return FALSE;SOCKADDR_IN addrSock;addrSock.sin_family=AF_INET;addrSock.sin_port=htons(6000);addrSock.sin_addr.S_un .S_addr =htonl(INADDR_ANY);int retval;retval=bind(m_socket,(SOCKADDR*)&addrSock,sizeof(SOCKADDR));if(SOCKET_ERROR==retval){closesocket(m_socket);MessageBox("绑定失败");return FALSE;}return TRUE;第十六调用初始化套接字函数在ONITDIALOGInitSocket();到此套接字的初始化工作全部完成了第十七开始编写接收端的程序创建线程函数及代码如下首先定义一个结构体struct RECVPARAM{SOCKET sock;HWND hwnd;};第十八在ONINITDIAG中创建一个指针RECVPARAM *pRecvParam=new RECVPARAM;pRecvParam->sock=m_socket;pRecvParam->hwnd=m_hWnd;HANDLEhThread=CreateThread(NULL,0,RecvProc,(LPVOID)pRecvParam,0,NULL);CloseHandle(hThread);第十九开始写线程函数,现增加一个成员函数以相关代码,如下第二十修还代码中的2个地方分别是如下第二十一再次运行又有一个错误在改正,这次是变函数为静态变量第二十二再创建的函数中输入相关代码,及服务端主要的代码SOCKET sock=((RECVPARAM*)IpParameter)->sock;HWND hwnd=((RECVPARAM*)IpParameter)->hwnd;SOCKADDR_IN addrFrom;int len =sizeof(SOCKADDR);char recvBuf[200];char tempBuf[300];int retval;while(TRUE){retval =recvfrom(sock,recvBuf,200,0,(SOCKADDR*)&addrFrom,&len);if(SOCKET_ERROR==retval)break;sprintf(tempBuf,"%s说:%s",inet_ntoa(addrFrom.sin_addr),recvBuf);::PostMessage(hwnd,WM_RECVDATA,0,(LPARAM)tempBuf);}第二十三定义消息得值#define WM_RECVDATA WM_USER+1第二十四做一个消息相应的函数afx_msg void OnRecvData(WPARAM wParam,LPARAM lParam);第二十五写一个消息映射的函数截图代码如下ON_MESSAGE(WM_RECVDATA,OnRecvData)第二十六消息响应函数的实现代码代码如下void CChatDlg :: OnRecvData(WPARAM wParam,LPARAM lParam) {CString str=(char*)lParam;CString strTemp;GetDlgItemText(IDC_EDIT_RECV,strTemp);str +="\r\n";str +=strTemp;SetDlgItemText(IDC_EDIT_RECV,str);}第二十七哈哈总结下至此服务端全部编写结束,程序调试正确第二十八开始编写发送端进入对话框页面单机发送按钮发送按钮函数第二十九编写发送端的函数代码// TODO: Add your control notification handler code hereDWORD dwIP;((CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS1))->GetAddress(dwIP);SOCKADDR_IN addrTo;addrTo.sin_family=AF_INET;addrTo.sin_port=htons(6000);addrTo.sin_addr.S_un .S_addr =htonl(dwIP);CString strSend;GetDlgItemText(IDC_EDIT_SEND,strSend);sendto(m_socket,strSend,strSend.GetLength()+1,0,(SOCKADDR*)&addrTo,sizeof(S OCKADDR));SetDlgItemText(IDC_EDIT_SEND,"");第三十至此发送端的让软件也编写完成第三十一我们运行我们编写好的软件如下* *。
mfc课程设计实例

mfc课程设计实例一、教学目标本课程旨在通过MFC(Microsoft Foundation Class)的教学,让学生掌握Windows应用程序开发的基本技能。
通过本课程的学习,学生将能够理解MFC的基本概念,掌握MFC应用程序的框架和生命周期,熟练使用MFC提供的各种控件和类,以及熟练使用MFC进行窗口设计、事件处理和资源管理等。
在知识目标上,学生需要掌握MFC的基本概念,包括MFC的类层次结构、应用程序框架、窗口类和控件类等。
学生还需要了解MFC应用程序的生命周期,包括初始化、创建窗口、处理消息和销毁等。
在技能目标上,学生需要能够使用MFC进行Windows应用程序的开发,包括窗口设计、事件处理、资源管理等。
学生还需要能够使用MFC进行调试和优化,以提高应用程序的性能和稳定性。
在情感态度价值观目标上,学生需要培养对编程的兴趣和热情,培养解决问题的能力和创新精神,以及培养良好的编程习惯和团队合作意识。
二、教学内容本课程的教学内容主要包括MFC的基本概念、MFC应用程序的框架和生命周期、MFC提供的各种控件和类、以及MFC进行窗口设计、事件处理和资源管理等。
具体的教学大纲如下:1.MFC的基本概念:介绍MFC的类层次结构、应用程序框架、窗口类和控件类等。
2.MFC应用程序的框架和生命周期:介绍MFC应用程序的创建、初始化、窗口创建、消息处理和销毁等过程。
3.MFC控件的使用:介绍MFC提供的各种控件的使用方法,包括按钮、编辑框、列表框等。
4.MFC窗口设计:介绍如何使用MFC进行窗口设计,包括窗口布局、控件摆放等。
5.MFC事件处理:介绍如何使用MFC进行事件处理,包括消息映射、事件处理函数等。
6.MFC资源管理:介绍如何使用MFC进行资源管理,包括图像、字体和颜色等。
三、教学方法为了激发学生的学习兴趣和主动性,本课程将采用多种教学方法,包括讲授法、讨论法、案例分析法和实验法等。
在讲授法方面,教师将系统地介绍MFC的基本概念、应用程序框架和生命周期等。
仿QQ聊天系统课程设计

仿QQ聊天系统课程设计D必须准确地,完整地体现出用户的要求。
1.1软件功能需求分析通过对用户需求的市场调查的分析,确定反应用户需求的系统逻辑模型,把整个设计划分成3个单元,分别是程序启动、用户界面、后台服务。
使用Android 和java编程语言及网络数据库相结合,编写一个基于android端的移动聊天系统软件。
这个系统提供多个用户及时并发通信的平台。
未注册用户可以注册成系统成员,已注册用户可以通过登录进入聊天系统。
在系统中用户可以选择与某一个用户聊天,用户可以查找好友或附近的人,可以添加好友或把好友加黑名单等。
➢用户注册:用户在注册界面填入相关正确信息后,后台对其进行处理。
➢用户登录:用户输入自己的QQ帐号及密码后,点击登录,后台对其进行验证,以及好友的查找,登录成功后返回该用户的会话界面。
➢聊天:用户选定聊天对象后,对其发送信息,信息将由后台转发给选定的聊天对象,进行,提示,显示。
➢后台运行用户可以退出主界面,将聊天软件在后台运行,当有消息传入时,消息会用广播的形势显示。
➢后台管理:对用户的管理。
1.2 安全需求分析由于Android系统自身具备的开放源码的特征,它的安全性能成为信息安全领域研究的一个重要课题。
Android的安全性能主要体现在两个方面:Android 的系统安全和数据安全。
Android系统安全是指智能终端本身的安全,是对操作系统的保护,防止未授权的访问及对授权用户服务的拒绝或对未授权用户服务的允许,包括行为检测、记录等措施。
Android的数据安全指确保存储数据完整性、合法性二个方面,要求做到系统正确地传输数据,授权程序顺利地读取数据。
Android安全中的一个重要的设计点是在默认的情况下应用没有权限执行对其他应用程序、操作系统或用户的有害操作,这些操作包括读取用户的隐私数据,访问网络,保持设备活动等等,应用程序的进程是一个安全的黑盒子,在没有给它权限的时候它不能干扰其他应用程序。
仿QQ即时通讯应用软件开发毕业设计

仿QQ即时通讯应用软件开发摘要:本文按照软件工程的思想和开发步骤,采用C/S模式,利用SQL Server数据库,使用Visual C++开发工具设计并实现了一个仿QQ的即时通讯应用软件。
该软件实现了消息的即时传输、文本传输、语音聊天等功能,具体包括网络通信、协议包封装与解析、文件传输以及基于directsound框架的音频处理。
系统为保证语音传输的质量和效率,采用一定的声音编码格式对声音数据打包并传输到接收方。
该系统功能全面,界面美观,操作方便,具有一定的实用价值。
关键词:socket, 文字聊天,文件传输,实时语音传输,directsoundAbstract: In this paper, according to the software engineering and development steps, using C / S mode, the SQL Server database and Visual C++ language the system was designed and implement.The software has implemented the real-time transmission, transmission of text messages, voice chat and other functions, such as network communications, protocol packet encapsulation and analysis, file transfer and frame-based audio processing directsound.To ensure the quality and efficiency of the voice transmission the system adopt a certain voice encoding format for audio coding packaged and transmitted to the receiver side. The system is fully functional, beautiful interface, easy to operate, and has a certain practical value.Keywords: socket, text chat,file transfer, real-time voice transmission, directsound一、概述互联网的迅速发展不仅改变了人们的意识形态,更影响着人们的生活方式,网络元素在不知不觉中渗透到生活的每一个角落。
课程设计实训示例项目《蓝梦教育集团即时通讯系统》(仿腾讯QQ)——构建出客户端登录主窗口类(第1部分)

J2EE课程设计实训教学示例项目《蓝梦教育集团即时通讯系统》(仿腾讯QQ)——构建出客户端登录主窗口类(第1部分)1.1.1构建出客户端登录主窗口类IMLoginMainFrame1、客户端的实用工具类(1)类名称为IMSystemClientUtils,包名称为com.px1987.imsystem.client.util(2)编程该类package com.px1987.imsystem.client.util;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import .URISyntaxException;import .URL;import java.util.HashMap;import java.util.List;import java.util.Map;import javax.swing.JOptionPane;import mons.httpclient.HttpClient;import mons.httpclient.HttpStatus;import ValuePair;import mons.httpclient.methods.PostMethod;import com.px1987.imsystem.client.constant.IMSystemClientAppConstant; import com.px1987.imsystem.client.exception.IMSystemException;import com.px1987.imsystem.client.frame.IMLoginMainFrame;import SystemInfoVO;import com.px1987.imsystem.client.vobject.NoSerializableVO;import erLoginOnLineInfoVO;import erInfoBaseVO;public class IMSystemClientUtils {private static HttpClient oneCommonsHttpClientInstance=null;private static NetSystemInfoVO oneNetSystemInfoVOInstance=null;private static NoSerializableVO oneNoSerializableVOInstance=null;private static UserLoginOnLineInfoVO oneUserLoginInfoVOInstance=null;private static Map<String,List<UserInfoBaseVO>> returnAllFriendsInfoVO=null;public static Map<String,List<UserInfoBaseVO>> getReturnAllFriendsInfoVO() { return IMSystemClientUtils.returnAllFriendsInfoVO;}public static void setReturnAllFriendsInfoVO(Map<String,List<UserInfoBaseVO>> returnAllFriendsInfoVO) {IMSystemClientUtils.returnAllFriendsInfoVO = returnAllFriendsInfoVO;}private IMSystemClientUtils() {}public static synchronized HttpClient getCommonsHttpClientInstance(){ if(oneCommonsHttpClientInstance==null){oneCommonsHttpClientInstance=new HttpClient();}return oneCommonsHttpClientInstance;}public static synchronized NetSystemInfoVO getNetSystemInfoVOInstance(){ if(oneNetSystemInfoVOInstance==null){oneNetSystemInfoVOInstance=new NetSystemInfoVO();}return oneNetSystemInfoVOInstance;}public static synchronized void setNetSystemInfoVOInstance(NetSystemInfoVO oneNetSystemInfoVO){oneNetSystemInfoVOInstance=oneNetSystemInfoVO;}public static synchronized NoSerializableVO getNoSerializableVOInstance(){ if(oneNoSerializableVOInstance==null){oneNoSerializableVOInstance=new NoSerializableVO();}return oneNoSerializableVOInstance;}public static synchronized UserLoginOnLineInfoVO getUserLoginOnLineInfoVOInstance(){if(oneUserLoginInfoVOInstance==null){oneUserLoginInfoVOInstance=new UserLoginOnLineInfoVO();}return oneUserLoginInfoVOInstance;}public static synchronized void setUserLoginOnLineInfoVOInstance(UserLoginOnLineInfoVO oneUserLoginInfoVO){ oneUserLoginInfoVOInstance=oneUserLoginInfoVO;}//************************************************************************** public static void exitIMLoginMainFrame(IMLoginMainFrame oneIMLoginMainFrame){try {IMSystemClientUtils.sendCloseFrameMessageToServer(); //向服务器发送在线注销的消息} catch (IMSystemException exception) {exception.printStackTrace();System.out.println("在IMSystemClientUtils类中的出现了IMSystemException异常错误,错误信息为:" +exception.getMessage());}oneIMLoginMainFrame.dispose(); //不仅要关闭主窗口、而且也还要退出系统程序System.exit(0);}public static void sendCloseFrameMessageToServer() throws IMSystemException{HttpClient oneHttpClient = null;oneHttpClient = IMSystemClientUtils.getCommonsHttpClientInstance();String targetURL = NetSystemUtil.getWebAppContextURL() + "/userInfoManageServlet.action";PostMethod onePostMethod = new PostMethod(targetURL);onePostMethod.addRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=gb2312"); //设置传输字符集,如果需要传输中文这需要设置为中文字符集NameValuePair request_Action = new NameValuePair("action",newInteger(IMSystemClientAppConstant.HttpClientUserInfoRequest_logOutOnLineStatus ).toString());onePostMethod.setRequestBody(new NameValuePair[] {request_Action});try {oneHttpClient.executeMethod(onePostMethod);} catch (IOException ex) {throw new IMSystemException("在IMSystemClientUtils类中的sendCloseFrameMessageToServer方法出现了IOException异常");}onePostMethod.releaseConnection();return;}public static boolean testNetConnectionSetupStatus(String webAppContextURL) throwsIMSystemException {Boolean returnTestResult = null;HttpClient oneHttpClient = null;oneHttpClient = IMSystemClientUtils.getCommonsHttpClientInstance();String targetURL = webAppContextURL +"/imWebServiceUtileServlet.action";PostMethod onePostMethod = new PostMethod(targetURL);onePostMethod.addRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=gb2312"); //设置传输字符集,如果需要传输中文这需要设置为中文字符集NameValuePair request_Action = new NameValuePair("action",new Integer(IMSystemClientAppConstant.HttpClientUserInfoRequest_testNetConnectionSetupStatus).toString());onePostMethod.setRequestBody(new NameValuePair[] {request_Action});try {oneHttpClient.executeMethod(onePostMethod);} catch (IOException ex) {returnTestResult=new Boolean(false);throw new IMSystemException("在IMSystemClientUtils类中的testNetConnectionSetupStatus方法出现了IOException异常");}if (onePostMethod.getStatusCode() != HttpStatus.SC_OK) { //出现响应异常时,直接关闭http连接onePostMethod.releaseConnection();return false;}InputStream oneInputStream = null;try {oneInputStream = onePostMethod.getResponseBodyAsStream();ObjectInputStream oneObjectInputStream = new ObjectInputStream(oneInputStream);returnTestResult = (Boolean) oneObjectInputStream.readObject(); //获得服务器端返回的在线用户总数的对象} catch (IOException ex1) {returnTestResult=new Boolean(false);throw new IMSystemException("在IMSystemClientUtils类中的testNetConnectionSetupStatus方法出现了IOException异常");} catch (ClassNotFoundException ex) {returnTestResult=new Boolean(false);throw new IMSystemException("在IMSystemClientUtils类中的testNetConnectionSetupStatus方法出现了ClassNotFoundException异常");}onePostMethod.releaseConnection();return returnTestResult.booleanValue();}public static String getSerializableFileName(){return "/systemConfig.dat"; // 直接放在classes目录下}public static void setAllVOInSerializableFile(URL TargetFileURL) { // 该方法为对用户所做的各种配置进行序列化操作——利用序列化技术保存两个VO Map<String,Object> oneMap = new HashMap<String,Object>();oneMap.put("oneUserLoginInfoVOKey",IMSystemClientUtils.getUserLoginOnLineInfoVOInstance());oneMap.put("oneNetSystemInfoVOKey",IMSystemClientUtils.getNetSystemInfoVOInstance());/*file.separator : 文件分隔符, Windows环境下为“\",Unix环境下为“/”;user.home :用户主目录;java.home :Java实时运行环境的安装目录;java.ext.dirs :JDK的安装目录; :操作系统名称; :用户登录名称;os.version :操作系统版本;path.separator :当前操作系统的路径分隔符;user.dir :当前用户程序所在目录。
仿QQ聊天软件MyQQ源代码教学北大青鸟完整版

// 小头像 sbFriends.View = SbView.SmallIcon;
总结及项目答辩
教员对项目完成情况作总结 学员以小组形式按要求答辩
Thank you
注册、登录功能
第二次集中编码 (4学时)
查找/添加好友、部分聊天功能
第三次集中编码 (4学时)
个人信息显示、完整聊天功能
第四次集中编码 (4学时)
个人信息修改、完善整个功能
项目答辩、总结(4学时)
搭建项目框架 提交小组计划
项目准备阶段:A任务
建库 建表
Users Friends FriendShipPolicy
建关系
项目准备阶段:B任务
建表
Star BloodType Messages MessageType
项目准备阶段:C任务
第一次集中编码:A任务
设计注册窗体界面 实现用户注册功能
第一次集中编码:B任务
设计登录后主窗体 显示好友列表
第一次集中编码:C任务
设计登录窗体 实现登录功能
第一次集中编码:难点分析
注册与登录 好友管理 消息管理 个人设置
需求分析——界面分析
需要的界面:
注册界面 登录界面 登录后的主界面 查找/添加好友界面 聊天界面 系统消息界面 个人设置界面 头像列表界面
需求分析——辅助类分析
需要添加的辅助类:
DBHelper类 UserHelper 类
MyQQ 聊天工具
小组分工
组员 B
// 判断选中行的第一个单元格是否有值 if (dgvBasicResult.SelectedRows[0].Cells[0] != null) { // … }
c++MFC CSocket仿QQ聊天软件,实现1对1聊天,群聊

c++/MFC CSocket仿QQ聊天软件,实现1对1聊天,群聊分类:c++ 2012-11-25 16:45 1582人阅读评论(13) 收藏举报c++C++mfcMFCqqQQsocket聊天学习,c++有2个星期了。
本来,本人是做php出身的。
做php快2年了,最近身边多了很多高手。
让自己对c开始感兴趣了,就开始学习c++了。
首先接触的就是mfc。
前几天,看到了一个博文,是有关,mfc网络编程的。
可对方,的实例只能是多对多,出于兴趣,自己改写了下它的程序,实现了点对点的聊天。
所以,本实例并非纯原创的。
这个还请大家见谅,尤其是作者。
我在他程序基础上,增加了1对1的聊天,同时还保留了群聊。
而且,最关键的是,我增加了很多备注。
很适合新手学习。
本人也是新手,还请各位高手提出宝贵建议。
先谢谢大家了。
如果要转载请注明原地址:/open520yin/article/details/8222279实例下载地址:/detail/open520yin/4808903(为了自己能有点下载积分,客户端和服务端一起打包5个积分不算贵吧。
呵呵。
)大家要是想看懂这个可能还需要先了解一下mfc的socket的一些基本使用规则我也有一篇博文写了c++/MFC 极为简单的socket实例:/open520yin/article/details/8202465MFC的CSocket编程,利用CSocket实现一个基于TCP实现一个QQ聊天程序。
///////////////////////////////////////////////////////////////////////// 服务端start ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////先讲讲服务端,一切先从服务端开始:首先就是要使用AfxSocketInit初始化winsocket,[cpp]view plaincopyprint?1. //初始化winSock库,成功则返回非0否则返回02. WSAData wsData;3. if(!AfxSocketInit(&wsData))4. {5. AfxMessageBox(_T("Socket 库初始化出错!"));6. return false;7. }m_iSocket 是一个CServerSocket*的指针 ,CServerSocket类是一个我们自己的类我会在后面给出相应代码,他继承于CSocket类。
mfc程序设计实例的步骤

mfc程序设计实例的步骤MFC程序设计是Windows平台下的一种经典的程序开发框架,它提供了一系列的软件工具和技术,可以帮助我们快速地开发高效、稳定、易于维护的Windows应用程序。
如果你想学习MFC程序设计,那么下面是一些基本的步骤,可以帮助你入门。
1. 准备工作:安装Visual Studio和MFC库首先,你需要安装Visual Studio开发环境,因为MFC是由微软开发的,所以它的最佳开发环境就是Visual Studio。
然后,你需要安装MFC库,这个库包含了许多用来开发Windows桌面应用程序的类、函数和工具。
2. 创建MFC应用程序项目在Visual Studio中创建一个新的MFC应用程序项目,你需要选择一个MFC应用程序的模板,然后配置一些基本信息,如项目名称、位置等。
一旦创建好了项目,你就可以开始编写代码了。
3. 设计用户界面设计好用户界面是一个重要的步骤,因为它是用户与你的应用程序交互的主要方式。
在MFC中,你可以使用类似于Visual Basic的可视化设计工具来创建Windows窗体、对话框和控件,然后使用代码来处理它们的事件和行为。
4. 编写程序代码在MFC中,你可以使用C++编程语言来编写程序代码。
你需要了解MFC库中提供的类、函数和工具,这些都是你开发应用程序的基础。
你可以使用MFC中的类来创建窗口、菜单和工具栏等控件,处理消息、事件和命令等操作。
5. 调试和测试调试和测试是开发过程中不可或缺的步骤。
你可以使用Visual Studio的调试工具来发现和解决程序中的错误和问题,确保你的程序能够正确地运行和达到预期的功能。
6. 发布和部署最后,你需要将你的应用程序发布和部署到用户的计算机上。
你可以使用Visual Studio的部署工具来创建安装程序或者自己手动进行部署。
确保你的应用程序能够在用户的计算机上正常运行和使用。
以上就是MFC程序设计的基本步骤。
当然,这只是一个大概的概述,如果你想成为一个MFC程序员,你需要不断学习和实践,才能掌握更多的技能和经验。
模仿QQ MFC 源码

登陆框.h#pragma once#include"afxcmn.h"#include"afxwin.h"// CLoginDlg 对话框class CLoginDlg : public CDialog{DECLARE_DYNAMIC(CLoginDlg)public:CLoginDlg(CWnd* pParent = NULL); // 标准构造函数virtual ~CLoginDlg();// 对话框数据enum { IDD = IDD_DIALOG_LOGIN };protected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持DECLARE_MESSAGE_MAP()public:afx_msg void OnBnClickedOk();CString m_strUsername;CString m_strPassord;afx_msg void OnBnClickedButtonClose();afx_msg void OnLButtonDown(UINT nFlags, CPoint point);afx_msg void OnLButtonUp(UINT nFlags, CPoint point);afx_msg void OnMouseMove(UINT nFlags, CPoint point);private:BOOL m_bMoving;CPoint m_ptPreMove;public:CLinkCtrl m_cLinkRegister;CLinkCtrl m_cLinkFindpwd;static DWORD m_nIconID;//用于存放登录后托盘显示的图标afx_msg void OnNMClickSyslinkRegister(NMHDR *pNMHDR, LRESULT *pResult);afx_msg void OnNMClickSyslinkFindpwd(NMHDR *pNMHDR, LRESULT *pResult);virtual BOOL OnInitDialog();afx_msg void OnBnClickedButtonList();CButton m_btnList;afx_msg void OnPaint();afx_msg void OnOnlin();afx_msg void OnQme();afx_msg void OnLeave();afx_msg void OnBusy();afx_msg void OnDarao();afx_msg void OnYinshen();afx_msg LRESULT OnShowTask(WPARAM wParam, LPARAM lParam);void ToTray(BOOL Show);CButton m_btnJianPan;CButton m_btnConfig;CToolTipCtrl toolTipCtrl[3];NOTIFYICONDATA m_nid;virtual BOOL PreTranslateMessage(MSG* pMsg);afx_msg void Onshowwindow();afx_msg void OnOpenmainpanel();afx_msg void OnHideWindows();afx_msg void OnButtonClose();afx_msg void OnBnClickedButtonMin();afx_msg void OnBnClickedButtonJianpan();afx_msg void OnCbnSelchangeComboUsername();BOOL m_isRemPassword;afx_msg void OnBnClickedCheckSavepwd();BOOL m_isAutoLogin;afx_msg void OnBnClickedCheckAutologin();afx_msg void OnTimer(UINT_PTR nIDEvent);BOOL m_isFirstLoginAccount;//hj};登陆框.cpp// LoginDlg.cpp : 实现文件//#include"stdafx.h"#include"QQDemo.h"#include"LoginDlg.h"#include"RegisterDlg.h"#include"SeekDlg.h"#define WM_SHOWTASK WM_USER+1// CLoginDlg 对话框IMPLEMENT_DYNAMIC(CLoginDlg, CDialog)DWORD CLoginDlg::m_nIconID = IDI_IMONLINE;CLoginDlg::CLoginDlg(CWnd* pParent/*=NULL*/): CDialog(CLoginDlg::IDD, pParent), m_strUsername(_T("")), m_strPassord(_T("")), m_bMoving(FALSE), m_isRemPassword(TRUE), m_isAutoLogin(FALSE), m_isFirstLoginAccount(TRUE){}CLoginDlg::~CLoginDlg(){Shell_NotifyIcon(NIM_DELETE,&m_nid);//从托盘中删除}void CLoginDlg::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);DDX_CBString(pDX, IDC_COMBO_USERNAME, m_strUsername);DDX_Text(pDX, IDC_EDIT_PASSWORD, m_strPassord);DDX_Control(pDX, IDC_SYSLINK_REGISTER, m_cLinkRegister);DDX_Control(pDX, IDC_SYSLINK_FINDPWD, m_cLinkFindpwd);DDX_Control(pDX, IDC_BUTTON_LIST, m_btnList);DDX_Control(pDX, IDC_BUTTON_JIANPAN, m_btnJianPan);DDX_Control(pDX, IDC_BUTTON_CONFIG, m_btnConfig);DDX_Check(pDX, IDC_CHECK_SA VEPWD, m_isRemPassword);DDX_Check(pDX, IDC_CHECK_AUTOLOGIN, m_isAutoLogin);}BEGIN_MESSAGE_MAP(CLoginDlg, CDialog)ON_BN_CLICKED(IDOK, &CLoginDlg::OnBnClickedOk)ON_BN_CLICKED(IDC_BUTTON_CLOSE, &CLoginDlg::OnBnClickedButtonClose)ON_WM_LBUTTONDOWN()ON_WM_LBUTTONUP()ON_WM_MOUSEMOVE()ON_MESSAGE(WM_SHOWTASK, &CLoginDlg::OnShowTask)ON_NOTIFY(NM_CLICK, IDC_SYSLINK_REGISTER, &CLoginDlg::OnNMClickSyslinkRegister) ON_NOTIFY(NM_CLICK, IDC_SYSLINK_FINDPWD, &CLoginDlg::OnNMClickSyslinkFindpwd) ON_BN_CLICKED(IDC_BUTTON_LIST, &CLoginDlg::OnBnClickedButtonList)ON_WM_PAINT()ON_COMMAND(IDM_ONLIN, &CLoginDlg::OnOnlin)ON_COMMAND(IDM_QME, &CLoginDlg::OnQme)ON_COMMAND(IDM_LEA VE, &CLoginDlg::OnLeave)ON_COMMAND(IDM_BUSY, &CLoginDlg::OnBusy)ON_COMMAND(IDM_DARAO, &CLoginDlg::OnDarao)ON_COMMAND(IDM_YINSHEN, &CLoginDlg::OnYinshen)ON_COMMAND(ID_showWindow, &CLoginDlg::Onshowwindow)ON_COMMAND(IDC_BUTTON_CLOSE, &CLoginDlg::OnButtonClose)ON_COMMAND(1200,OnOpenmainpanel)ON_COMMAND(1201,OnHideWindows)ON_BN_CLICKED(IDC_BUTTON_MIN, &CLoginDlg::OnBnClickedButtonMin)ON_BN_CLICKED(IDC_BUTTON_JIANPAN, &CLoginDlg::OnBnClickedButtonJianpan)ON_CBN_SELCHANGE(IDC_COMBO_USERNAME, &CLoginDlg::OnCbnSelchangeComboUsername) ON_BN_CLICKED(IDC_CHECK_SA VEPWD, &CLoginDlg::OnBnClickedCheckSavepwd)ON_BN_CLICKED(IDC_CHECK_AUTOLOGIN, &CLoginDlg::OnBnClickedCheckAutologin)ON_WM_TIMER()END_MESSAGE_MAP()// CLoginDlg 消息处理程序void CLoginDlg::ToTray(BOOL Show){if(Show){UpdateData(TRUE);Shell_NotifyIcon(NIM_ADD,&m_nid); //放入托盘中ShowWindow(SW_HIDE); //隐藏主窗口}else{Shell_NotifyIcon(NIM_DELETE,&m_nid);//从托盘中删除}}//处理托盘的回调函数(也就是对托盘的一些消息响应如单击,右击,双击)LRESULT CLoginDlg::OnShowTask(WPARAM wParam, LPARAM lParam){switch(lParam){case WM_RBUTTONDOWN:{CRect rect;CPoint p;GetCursorPos(&p);CMenu menu;if(this->IsWindowVisible()){menu.CreatePopupMenu();menu.AppendMenu(MF_STRING,1201,_T("隐藏主面板"));menu.AppendMenu(MF_STRING,WM_DESTROY,_T("关闭"));menu.TrackPopupMenu(TPM_LEFTALIGN,p.x,p.y,this);}else{menu.CreatePopupMenu();menu.AppendMenu(MF_STRING,1200,_T("打开主面板"));menu.AppendMenu(MF_STRING,WM_DESTROY,_T("关闭"));menu.TrackPopupMenu(TPM_LEFTALIGN,p.x,p.y,this);}}break;case WM_LBUTTONDOWN:ShowWindow(SW_SHOW);break;}return 0;}void CLoginDlg::OnBnClickedOk(){UpdateData();BOOL isFind = FALSE;//判断是否已经找到密码CString temp;//存储格式化字符串if(m_strUsername == _T("")){MessageBox(_T("帐号不能为空!请重新输入!"));return;}if(m_strPassord == _T("")){MessageBox(_T("密码不能为空!请输入密码!"));return;}//判断该帐号是否已经注册(在qqData.ini文件中)//int nInqqdata;CString strAccountInqqData;CString strPasswordInqqData;int nCount=::GetPrivateProfileInt(_T("FileCount"),_T("Count"),0,_T(".\\qqData.ini"));for(int i = 0;i < nCount;i++){temp.Format(_T("%d"),i + 1);::GetPrivateProfileString(_T("admin") + temp,_T("Account") + temp,m_strUsername, strAccountInqqData.GetBuffer(MAX_PA TH),MAX_PA TH,_T(".\\qqData.ini"));::GetPrivateProfileString(_T("admin") + temp,_T("Password") + temp,_T(""), strPasswordInqqData.GetBuffer(MAX_PA TH),MAX_PA TH,_T(".\\qqData.ini"));//如果账号,密码与配置文件中的数据一致则登录成功if (strAccountInqqData == m_strUsername){if(m_strPassord == strPasswordInqqData){isFind = TRUE;break;}}}if(!isFind){MessageBox(_T("账号或密码有错误,请确认后重新登录!"));return;}int bCount = ::GetPrivateProfileInt(_T("FileCount"),_T("Count"),0,_T(".\\qq.ini"));CString strAccount;//存储本地读取文件中的账号CString strPassword;//存储本地文件中的密码CString strRemPassword;//存储配置文件中的记住密码状态CString strAutoLogin;//存储配置文件自动登录状态CString strLastLogin;//存储配置文件是否为上次登录状态BOOL isExistInqq=FALSE;//是否存在于本地的配置文件int nIndex;//帐号在配置文件中下标if (m_isRemPassword){strRemPassword = _T("1");}strRemPassword = _T("0");if (m_isAutoLogin){strAutoLogin = _T("1");}elsestrAutoLogin = _T("0");bCount++;//判断是否本地配置文件中已经存在该帐号的信息for (int i= 0;i < bCount;i++){nIndex=i + 1;temp.Format(_T("%d"),nIndex);::GetPrivateProfileString(_T("admin") + temp,_T("Account") + temp,_T(""), strAccount.GetBuffer(MAX_PA TH),MAX_PATH,_T(".\\qq.ini"));if(strAccount==m_strUsername){isExistInqq=TRUE;break;}}if (!isExistInqq){temp.Format(_T("%d"),bCount);::WritePrivateProfileString(_T("admin") +temp,_T("Account") + temp,m_strUsername,_T(".\\qq.ini"));//写入密码,当记住密码时为账户密码,否则密码为空if(m_isRemPassword){::WritePrivateProfileString(_T("admin") + temp,_T("Password") + temp,m_strPassord,_T(".\\qq.ini"));}else::WritePrivateProfileString(_T("admin") + temp,_T("Password") + temp,_T(""),_T(".\\qq.ini"));::WritePrivateProfileString(_T("admin") +temp,_T("isRemPassword") + temp,strRemPassword,_T(".\\qq.ini"));::WritePrivateProfileString(_T("admin") +temp,_T("isAutoLogin") + temp,strAutoLogin,_T(".\\qq.ini"));::WritePrivateProfileString(_T("FileCount"),_T("Count"),temp,_T(".\\qq.ini"));else{temp.Format(_T("%d"),nIndex);if(m_isRemPassword){::WritePrivateProfileString(_T("admin") + temp,_T("Password") + temp,m_strPassord,_T(".\\qq.ini"));}else::WritePrivateProfileString(_T("admin") + temp,_T("Password") + temp,_T(""),_T(".\\qq.ini"));::WritePrivateProfileString(_T("admin") + temp,_T("isRemPassword") + temp,strRemPassword,_T(".\\qq.ini"));::WritePrivateProfileString(_T("admin") + temp,_T("isAutoLogin") + temp,strAutoLogin,_T(".\\qq.ini"));}Shell_NotifyIcon(NIM_DELETE,&m_nid);//获得此时本地文件存在的帐号数目bCount = ::GetPrivateProfileInt(_T("FileCount"),_T("Count"),0,_T(".\\qq.ini"));for(int i = 0;i < bCount;i++){temp.Format(_T("%d"),i + 1);::WritePrivateProfileString(_T("admin") + temp,_T("isLastLogin") + temp,_T("0"),_T(".\\qq.ini"));}//为现在这个帐号设置isLastLogin的值if (isExistInqq){temp.Format(_T("%d"),nIndex);::WritePrivateProfileString(_T("admin") + temp,_T("isLastLogin") + temp,_T("1"),_T(".\\qq.ini"));}else{temp.Format(_T("%d"),bCount);::WritePrivateProfileString(_T("admin") + temp,_T("isLastLogin") + temp,_T("1"),_T(".\\qq.ini"));}//对当前帐号的排名计数器设为,并写入本地配置文件中::WritePrivateProfileString(_T("admin") + temp,_T("Rank") + temp,_T("0"),_T(".\\qq.ini"));//遍历本地配置文件,除了本次登录的帐号外,其他帐号的排名计数都加for (int i = 0;i < bCount;i++){temp.Format(_T("%d"),i + 1);::GetPrivateProfileString(_T("admin") + temp,_T("isLastLogin") + temp,_T(""),strLastLogin.GetBuffer(MAX_PA TH),MAX_PA TH,_T(".\\qq.ini"));if (strLastLogin != _T("1")){int rank = GetPrivateProfileInt(_T("admin") + temp,_T("Rank") + temp,0,_T(".\\qq.ini"));rank++;CString strRank;strRank.Format(_T("%d"),rank);::WritePrivateProfileString(_T("admin") + temp,_T("Rank") + temp,strRank,_T(".\\qq.ini"));}}OnOK();}void CLoginDlg::OnLButtonDown(UINT nFlags, CPoint point){if (point.y <= 50){m_bMoving = TRUE;m_ptPreMove = point;ClientToScreen(&m_ptPreMove);//GetCapture();}CDialog::OnLButtonDown(nFlags, point);}void CLoginDlg::OnLButtonUp(UINT nFlags, CPoint point){m_bMoving = FALSE;CDialog::OnLButtonUp(nFlags, point);}void CLoginDlg::OnMouseMove(UINT nFlags, CPoint point){if (m_bMoving){CPoint ptTemp = point;ClientToScreen(&ptTemp);CPoint ptOffset = ptTemp - m_ptPreMove;m_ptPreMove = ptTemp;CRect rectWindow;GetWindowRect(&rectWindow);rectWindow += ptOffset;MoveWindow(&rectWindow);}CDialog::OnMouseMove(nFlags, point);}void CLoginDlg::OnNMClickSyslinkRegister(NMHDR *pNMHDR, LRESULT *pResult){// TODO: 在此添加控件通知处理程序代码//PNMLINK pNMLink = (PNMLINK)pNMHDR;//::ShellExecute(m_hWnd, _T("open"), pNMLink->item.szUrl, NULL, NULL, SW_SHOWNORMAL);CRegisterDlg dlg;if(IDOK != dlg.DoModal())return;//把注册信息存入qqData注册表UpdateData();int nCount = ::GetPrivateProfileInt(_T("FileCount"),_T("Count"),0,_T(".\\qqData.ini"));nCount++;CString temp;temp.Format(_T("%d"),nCount);::WritePrivateProfileString(_T("admin") + temp,_T("Account") + temp,dlg.m_Reg_strAccount,_T(".\\qqData.ini"));::WritePrivateProfileString(_T("admin") + temp,_T("Password") + temp,dlg.m_Reg_strPassword,_T(".\\qqData.ini"));::WritePrivateProfileString(_T("FileCount"),_T("Count"),temp,_T(".\\qqData.ini"));*pResult = 0;}void CLoginDlg::OnNMClickSyslinkFindpwd(NMHDR *pNMHDR, LRESULT *pResult){// TODO: 在此添加控件通知处理程序代码//PNMLINK pNMLink = (PNMLINK)pNMHDR;//::ShellExecute(m_hWnd, _T("open"), pNMLink->item.szUrl, NULL, NULL, SW_SHOWNORMAL);CSeekDlg dlg;dlg.DoModal();*pResult = 0;}BOOL CLoginDlg::OnInitDialog(){CDialog::OnInitDialog();// TODO: 在此添加额外的初始化ModifyStyleEx(WS_EX_APPWINDOW,WS_EX_TOOLWINDOW);CBitmap map1, map2, map3;map1.LoadBitmap(IDB_BITMAP1);m_btnList.SetBitmap(map1);map2.LoadBitmap(IDB_BITMAP9);m_btnJianPan.SetBitmap(map2);map3.LoadBitmap(IDB_BITMAP10);m_btnConfig.SetBitmap(map3);for (int i=0; i<3; ++i){toolTipCtrl[i].Create(this);}toolTipCtrl[0].AddTool(GetDlgItem(IDC_BUTTON_CONFIG), _T("设置"));toolTipCtrl[1].AddTool(GetDlgItem(IDC_BUTTON_MIN), _T("最小化"));toolTipCtrl[2].AddTool(GetDlgItem(IDC_BUTTON_CLOSE), _T("关闭"));m_nid.cbSize = (DWORD) sizeof(NOTIFYICONDATA);m_nid.hWnd = m_hWnd;m_nid.uID = IDI_OFFLINE;//IDR_MAINFRAME;m_nid.hIcon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_OFFLINE));m_nid.uFlags = NIF_ICON | NIF_MESSAGE|NIF_TIP;m_nid.uCallbackMessage = WM_SHOWTASK;wcscpy_s(m_nid.szTip,_T("QQ"));//实现任务栏无图标ModifyStyleEx(WS_EX_APPWINDOW,WS_EX_TOOLWINDOW,SWP_FRAMECHANGED);Shell_NotifyIcon(NIM_ADD, &m_nid);m_cLinkRegister.SetWindowText(_T("<ahref=\"/chs/index.html?from=client&ptlang=2052®key=&ADUIN=0&ADSESSION=0&ADT AG=CLIENT.QQ.4855_NewAccount_Btn.0&ADPUBNO=26095\">注册账号</a>"));m_cLinkFindpwd.SetWindowText(_T("<ahref=\"https:///cn2/findpsw/pc/pc_find_pwd_input_account?source_id=1003&ptlang=2052&aquin=105 8072426\">忘记密码</a>"));//获得本地配置文件中已经保存的账号数目int nCount = ::GetPrivateProfileInt(_T("FileCount"),_T("Count"),0,_T(".\\qq.ini"));CString strAccount;//保存读取配置文件后的账号CString strPassword;//保存读取配置文件后的账号的密码CString temp;//保存格式化字符串int nShow;//显示帐号的个数//如果本地文件帐号数目小于四个,则把显示的数目设为帐号数目,否则显示四个if (nCount <= 4){nShow = nCount;}elsenShow = 4;//动态构造一个数组,存储每个帐号的登录排名计数(当前登录排名为,其他排名在之前基础上加)int *a = new int [nCount + 1];memset(a,0,nCount + 1);//把每个帐号的排名计数赋值给对应的数组元素for (int i = 0;i < nCount;i++){temp.Format(_T("%d"),i + 1);a[i] = ::GetPrivateProfileInt(_T("admin") + temp,_T("Rank") + temp,0,_T(".\\qq.ini"));}//对排名计数进行排序int i;int j;int k;for(i = 0;i < nCount;i++)for(j = i + 1;j < nCount;j++)if(a[i] > a[j]){k = a[i];a[i] = a[j];a[j] = k;}//把排名计数前指定位数增加到组合框for(int n= 0;n < nShow;n++){for (j = 0;j < nCount;j++){temp.Format(_T("%d"),j+1);if (a[n] == ::GetPrivateProfileInt(_T("admin") + temp,_T("Rank") + temp,0,_T(".\\qq.ini"))){::GetPrivateProfileString(_T("admin") + temp,_T("Account") + temp,_T(""), strAccount.GetBuffer(MAX_PA TH),MAX_PA TH,_T(".\\qq.ini"));((CComboBox*)GetDlgItem(IDC_COMBO_USERNAME))->InsertString(n,strAccount);break;}}}//把上次登录的帐号显示到组合框中CString isLastLogin;////保存配置文件中的是否为上次登录的账号int nIndex = 0;//存储上次登录账号的下标CString strRemPassword;//保存配置文件中的记住密码选择状态CString strAutoLogin;//保存配置文件中的自动登录选择状态for(int i = 0;i < nCount;i++){temp.Format(_T("%d"),i + 1);::GetPrivateProfileString(_T("admin") + temp,_T("isLastLogin") + temp,_T(""),isLastLogin.GetBuffer(MAX_PA TH),MAX_PA TH,_T(".\\qq.ini"));if (isLastLogin == _T("1")){nIndex = i + 1;break;}}//获得上一次登录的帐号,密码,记住密码状态,自动登陆状态temp.Format(_T("%d"),nIndex);::GetPrivateProfileString(_T("admin") + temp,_T("Account") + temp,_T(""), strAccount.GetBuffer(MAX_PA TH),MAX_PA TH,_T(".\\qq.ini"));::GetPrivateProfileString(_T("admin") + temp,_T("Password") + temp,_T(""), strPassword.GetBuffer(MAX_PA TH),MAX_PA TH,_T(".\\qq.ini"));::GetPrivateProfileString(_T("admin") + temp,_T("isRemPassword") + temp,_T(""), strRemPassword.GetBuffer(MAX_PA TH),MAX_PA TH,_T(".\\qq.ini"));::GetPrivateProfileString(_T("admin") + temp,_T("isAutoLogin") + temp,_T(""), strAutoLogin.GetBuffer(MAX_PATH),MAX_PA TH,_T(".\\qq.ini"));if (strRemPassword == _T("1")){m_isRemPassword = TRUE;}elsem_isRemPassword = FALSE;if (strAutoLogin == _T("1")){m_isAutoLogin = TRUE;m_isRemPassword = TRUE;}elsem_isAutoLogin = FALSE;m_strPassord = strPassword;UpdateData(FALSE);SetDlgItemText(IDC_COMBO_USERNAME,strAccount);SetTimer(1,5000,NULL);//设置定时器,用于自动登录//释放内存delete []a;return TRUE; // return TRUE unless you set the focus to a control// 异常: OCX 属性页应返回FALSE}void CLoginDlg::OnBnClickedButtonList(){// TODO: 在此添加控件通知处理程序代码CMenu menu, *pMenu;menu.LoadMenu(IDR_MENU1);pMenu = menu.GetSubMenu(0);CBitmap bitmap0,bitmap1,bitmap2,bitmap3,bitmap4,bitmap5,bitmap6,bitmap7;bitmap0.LoadBitmap(IDB_BITMAP1);bitmap1.LoadBitmap(IDB_BITMAP2);bitmap2.LoadBitmap(IDB_BITMAP3);bitmap3.LoadBitmap(IDB_BITMAP4);bitmap4.LoadBitmap(IDB_BITMAP5);bitmap5.LoadBitmap(IDB_BITMAP6);/*bitmap6.LoadBitmap(IDB_BITMAP7);bitmap7.LoadBitmap(IDB_BITMAP8);*/pMenu->SetMenuItemBitmaps(0, MF_BYPOSITION, &bitmap0, &bitmap0);pMenu->SetMenuItemBitmaps(1, MF_BYPOSITION, &bitmap1, &bitmap1);pMenu->SetMenuItemBitmaps(3, MF_BYPOSITION, &bitmap2, &bitmap2);pMenu->SetMenuItemBitmaps(4, MF_BYPOSITION, &bitmap3, &bitmap3);pMenu->SetMenuItemBitmaps(5, MF_BYPOSITION, &bitmap4, &bitmap4);pMenu->SetMenuItemBitmaps(7, MF_BYPOSITION, &bitmap5, &bitmap5);/*pMenu->SetMenuItemBitmaps(6, MF_BYPOSITION, &bitmap0, &bitmap0);pMenu->SetMenuItemBitmaps(7, MF_BYPOSITION, &bitmap0, &bitmap0);*/CRect rect;GetDlgItem(IDC_BUTTON_LIST)->GetWindowRect(&rect);pMenu->TrackPopupMenu(TPM_LEFTBUTTON,rect.right-rect.Width(), rect.bottom, this, 0);}void CLoginDlg::OnPaint(){CPaintDC dc(this); // device context for paintingCBitmap bitmap;bitmap.LoadBitmap(IDB_BITMAP12);CRect rect;GetClientRect(&rect);CDC demo;demo.CreateCompatibleDC(&dc);demo.SelectObject(&bitmap);//dc.StretchBlt(0, 0, rect.Width(), rect.Height(), &demo, 0, 0, bitMap.bmWidth, bitMap.bmHeight, SRCCOPY);dc.BitBlt(0, 0, rect.Width(), rect.Height(), &demo, 0, 0, SRCCOPY);// 不为绘图消息调用CDialog::OnPaint()}void CLoginDlg::OnOnlin(){// TODO: 在此添加命令处理程序代码CBitmap bitmap;bitmap.LoadBitmap(IDB_BITMAP1);m_btnList.SetBitmap(bitmap);m_nIconID = IDI_IMONLINE;}void CLoginDlg::OnQme(){CBitmap bitmap;bitmap.LoadBitmap(IDB_BITMAP2);m_btnList.SetBitmap(bitmap);m_nIconID = IDI_QME;// TODO: 在此添加命令处理程序代码}void CLoginDlg::OnLeave(){// TODO: 在此添加命令处理程序代码CBitmap bitmap;bitmap.LoadBitmap(IDB_BITMAP3);m_btnList.SetBitmap(bitmap);m_nIconID = IDI_AWAY;}void CLoginDlg::OnBusy(){// TODO: 在此添加命令处理程序代码CBitmap bitmap;bitmap.LoadBitmap(IDB_BITMAP4);m_btnList.SetBitmap(bitmap);m_nIconID = IDI_BUSY;}void CLoginDlg::OnDarao(){// TODO: 在此添加命令处理程序代码CBitmap bitmap;bitmap.LoadBitmap(IDB_BITMAP5);m_btnList.SetBitmap(bitmap);m_nIconID = IDI_MUTE;}void CLoginDlg::OnYinshen(){// TODO: 在此添加命令处理程序代码CBitmap bitmap;bitmap.LoadBitmap(IDB_BITMAP6);m_btnList.SetBitmap(bitmap);m_nIconID = IDI_INVISIBLE;}BOOL CLoginDlg::PreTranslateMessage(MSG* pMsg){// TODO: 在此添加专用代码和/或调用基类if (pMsg->message== WM_LBUTTONDOWN ||pMsg->message== WM_LBUTTONUP ||pMsg->message== WM_MOUSEMOVE)for (int i=0; i<3; ++i){toolTipCtrl[i].RelayEvent(pMsg);}return CDialog::PreTranslateMessage(pMsg);}void CLoginDlg::Onshowwindow(){// TODO: 在此添加命令处理程序代码ShowWindow(SW_SHOW);}void CLoginDlg::OnButtonClose(){// TODO: 在此添加命令处理程序代码PostMessage(WM_QUIT);ToTray(TRUE);}void CLoginDlg::OnBnClickedButtonClose(){static CRect rectLarge;static CRect rectSmall;if (rectLarge.IsRectNull()){CRect rectSeparator;GetWindowRect(&rectLarge);//获得变小前的对话框面积GetDlgItem(IDC_STATIC)->GetWindowRect(&rectSeparator);rectSmall.left = rectLarge.left;rectSmall.top = rectLarge.top;rectSmall.right = rectLarge.right;rectSmall.bottom = rectSeparator.bottom;}for (int i = rectSmall.Height(); i>=0; i--){SetWindowPos(NULL, 0, 0, rectSmall.Width(), i, SWP_NOMOVE | SWP_NOZORDER);Sleep(5);}//OnOK();PostMessage(WM_QUIT);ToTray(TRUE);}void CLoginDlg::OnBnClickedButtonMin(){// TODO: 在此添加控件通知处理程序代码ShowWindow(SW_HIDE);ToTray(TRUE);}void CLoginDlg::OnBnClickedButtonJianpan(){// TODO: 在此添加控件通知处理程序代码}void CLoginDlg::OnCbnSelchangeComboUsername(){m_isFirstLoginAccount=FALSE;//表示不是第一次登录的账号//获取当前选择的行,并显示到列表框中int nIndex = ((CComboBox*)GetDlgItem(IDC_COMBO_USERNAME))->GetCurSel();int nCount = ::GetPrivateProfileInt(_T("FileCount"),_T("Count"),0,_T(".\\qq.ini"));((CComboBox*)GetDlgItem(IDC_COMBO_USERNAME))->GetLBText(nIndex,m_strUsername);int n=0;//保存账号在配置文件中的下标CString temp;//保存格式化的字符串CString strAccount;//保存在配置文件中的读取到的账号CString strPassword;//保存在配置文件中的读取到的账号的密码CString strRemPassword;//保存最近一次账号登录的记住密码状态CString strAutoLogin;//保存最近一次账号登录的自动登录状态//遍历配置文件,判断上次保存的密码记住状态!for(int i = 0;i < nCount;i++){temp.Format(_T("%d"),i + 1);::GetPrivateProfileString(_T("admin")+temp,_T("Account")+temp,_T(""),strAccount.GetBuffer(MAX_PA TH),MAX_PA TH,_T(".\\qq.ini"));if (m_strUsername == strAccount){n=i+1;::GetPrivateProfileString(_T("admin")+temp,_T("isRemPassword")+temp,_T(""),strRemPassword.GetBuffe r(MAX_PA TH),MAX_PA TH,_T(".\\qq.ini"));if (strRemPassword==_T("1")){m_isRemPassword=TRUE;}elsem_isRemPassword=FALSE;break;}}//再考虑自动登录框的选择状态::GetPrivateProfileString(_T("admin")+temp,_T("isAutoLogin")+temp,_T(""),strAutoLogin.GetBuffer(MAX_PATH),MAX_PA TH,_T(".\\qq.ini"));//如果是自动登录,那要记住密码if(strAutoLogin == _T("1")){m_isRemPassword = TRUE;m_isAutoLogin = TRUE;}elsem_isAutoLogin = FALSE;temp.Format(_T("%d"),n);::GetPrivateProfileString(_T("admin") + temp,_T("Password") + temp,_T(""), strPassword.GetBuffer(MAX_PA TH),MAX_PA TH,_T(".\\qq.ini"));m_strPassord = strPassword;SetDlgItemText(IDC_EDIT_PASSWORD,m_strPassord);CButton *ptn = (CButton*)GetDlgItem(IDC_CHECK_SA VEPWD); //获得CheckBox的指针ptn->SetCheck(m_isRemPassword);//设置记住密码框选择状态CButton *qtn = (CButton*)GetDlgItem(IDC_CHECK_AUTOLOGIN); //获得CheckBox的指针qtn->SetCheck(m_isAutoLogin);//设置自动登录框选择状态}void CLoginDlg::OnBnClickedCheckSavepwd(){//如果记住密码状态没有选,则自动登录也不能选CButton *pRemPassWord = (CButton*)GetDlgItem(IDC_CHECK_SA VEPWD);CButton *pBtnAutoLogin = (CButton*)GetDlgItem(IDC_CHECK_AUTOLOGIN);if (pRemPassWord->GetCheck() == 0){pBtnAutoLogin->SetCheck(0);}}void CLoginDlg::OnBnClickedCheckAutologin(){// TODO: 在此添加控件通知处理程序代码//如果当前不是自动登录状态,则单击后,为自动登录状态,否则取消自动登录状态if (!m_isAutoLogin){m_isAutoLogin = TRUE;m_isRemPassword = TRUE; //如果为自动登录状态,则应该记住密码CButton *q = (CButton*)GetDlgItem(IDC_CHECK_SA VEPWD);q->SetCheck(m_isRemPassword);}else{m_isAutoLogin = FALSE;}CButton *p = (CButton*)GetDlgItem(IDC_CHECK_AUTOLOGIN); //获得CheckBox的指针p->SetCheck(m_isAutoLogin);//设置选择状态}void CLoginDlg::OnTimer(UINT_PTR nIDEvent){// 如果是不是上一次登录的账号,则返回if(!m_isFirstLoginAccount)return;UpdateData();int nCount=::GetPrivateProfileInt(_T("FileCount"),_T("Count"),0,_T(".\\qq.ini"));CString temp;//存储格式化字符串CString strAccount;//存储读取文件中的账号CString strPassword;//存储读取文件中的密码CString strAutoLogin;//存储读取文件中的自动登录状态//遍历配置文件,找到当前输入的账号密码,取得该账号的自动登录的选择状态for(int i = 0;i < nCount;i++){temp.Format(_T("%d"),i + 1);::GetPrivateProfileString(_T("admin")+temp,_T("Account")+temp,m_strUsername, strAccount.GetBuffer(MAX_PA TH),MAX_PA TH,_T(".\\qq.ini"));::GetPrivateProfileString(_T("admin")+temp,_T("Password")+temp,_T(""), strPassword.GetBuffer(MAX_PA TH),MAX_PA TH,_T(".\\qq.ini"));if ((m_strUsername == strAccount)&&(m_strPassord == strPassword)){::GetPrivateProfileString(_T("admin")+temp,_T("isAutoLogin")+temp,_T(""), strAutoLogin.GetBuffer(MAX_PATH),MAX_PA TH,_T(".\\qq.ini"));//如果为自动登录状态,则调用OnOk,关闭定时器if (strAutoLogin == _T("1")){OnOK();KillTimer(1);break;}}}CDialog::OnTimer(nIDEvent);}void CLoginDlg::OnOpenmainpanel(){//托盘右键菜单实现,隐藏主面板ShowWindow(SW_SHOW);}void CLoginDlg::OnHideWindows(){//托盘右键菜单实现,打开主面板ShowWindow(SW_HIDE);}主界面.h// QQDemoDlg.h : 头文件//#pragma once#include"Linkname.h"#include"RoomDlg.h"#include"GroupDlg.h"#include"SessionDlg.h"#include"Twitter.h"#include"afxwin.h"#include"EditDlg.h"// CQQDemoDlg 对话框class CQQDemoDlg : public CDialog{// 构造public:CQQDemoDlg(CWnd* pParent = NULL); // 标准构造函数~CQQDemoDlg();// 对话框数据enum { IDD = IDD_QQDEMO_DIALOG };protected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持// 实现public:void ToTray(DWORD dwMessage,HICON hIcon);//用于托盘的增加,修改,删除操作protected://修正移动时窗口的大小void FixMoving(UINT fwSide, LPRECT pRect);//修正改改变窗口大小时窗口的大小void FixSizing(UINT fwSide, LPRECT pRect);//从收缩状态显示窗口void DoShow();//从显示状态收缩窗口void DoHide();//重载函数,只是为了方便调用BOOL SetWindowPos(const CWnd* pWndInsertAfter,LPCRECT pCRect, UINT nFlags = SWP_SHOWWINDOW);afx_msg void OnTimer(UINT nIDEvent);afx_msg void OnSizing(UINT fwSide, LPRECT pRect);afx_msg int OnCreate(LPCREA TESTRUCT lpCreateStruct);afx_msg void OnMoving(UINT fwSide, LPRECT pRect);。
课程设计项目《蓝梦教育集团即时通讯系统》(仿腾讯QQ)——构建出客户端系统中的各个自定义的组件类程序

(完整word版)山寨QQ(韩顺平版)(word文档良心出品)

这是一个简单的javaProject项目,没有涉及到数据库界面对这个项目中完成的功能进行阐述:1、qq用户登录:用户账号为1、2、3一直到50,密码都为123456,由于没有涉及到数据库,所以只是简单的在服务器进行验证。
2、实现1对1之间的聊天,实现1对多之间的聊天。
3、实现用户上线显示功能具体的演示为:1、启动服务器QqServer下com.qq.view.MyServerFrame,在该类下面启动服务器2、启动客户端QqClient下com.qq.view.QqClientLogin,在该类下面输入账号和密码登入ps:聊天时要把要把需要聊天的窗口都打开,才能看到。
比如1和2聊天,必须打开1对2聊天的窗口和2对1聊天的窗口QQ客户端:QQ服务器下面的是关于各个包的源代码,小伙伴们可以新建一个class,然后把这些拷贝上去就可以用了,当然前提是按照上面的工程创建好包Image文件夹下用到的图片:命名为:beibu.gif命名为:xiangdao.png命名为:quxiao.png命名为:qq.png命名为:mm.png命名为:clear.png命名为:dengru.pngQqClientConService类:package com.qq.client.model;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import .Socket;import com.qq.client.tools.ClientConServerThread;import com.qq.client.tools.ManageClientConServerThread; import mon.Message;import er;/*** 客户端连接服务器后台* */public class QqClientConService {public Socket client;//判断是否成功登录,成功返回true,否则返回falsepublic boolean sendLoginInfoToServer(Object o) {boolean isLogin = false;try {//创建连接client = new Socket("localhost", 9999);ObjectOutputStream oos = newObjectOutputStream(client.getOutputStream());oos.writeObject(o);ObjectInputStream ois = newObjectInputStream(client.getInputStream());Message message = (Message)ois.readObject();//登录成功的判断if(message.getMesType()==1) {isLogin = true;//登录成功,创建一个改客户端和服务器的线程ClientConServerThread ccst = new ClientConServerThread(client);//把改线程添加到管理线程的map中ManageClientConServerThread.addClientConServerThread(((User )o).getName(), ccst);//启动该线程new Thread(ccst).start();}} catch (Exception e) {e.printStackTrace();}return isLogin;}}QqClientUser类:package com.qq.client.model;import er;/*** 这是QQ客户端,发送用户名和密码** */public class QqClientUser {//调用客户端连接服务器后台的方法,返回true为成功登录,false为登入失败public boolean checkUser(User user) {return newQqClientConService().sendLoginInfoToServer(user);}}ClientConServerThread类:package com.qq.client.tools;import java.io.ObjectInputStream;import .Socket;import com.qq.client.view.QqChar;import com.qq.client.view.QqFriendList;import mon.Message;import mon.MessageType;/*** 这是客户端和服务器保持通讯的线程* */public class ClientConServerThread implements Runnable{ public Socket client;public ClientConServerThread(Socket client) {this.client = client;}@Overridepublic void run() {//不停的读取从服务器发来的消息while(true) {try {ObjectInputStream ois = newObjectInputStream(client.getInputStream());Message message = (Message) ois.readObject();//判断发来的消息包是否为普通消息包,或者是返回在线好友的包if(message.getMesType() ==MessageType.message_common_mes) {//把从服务器发来的消息显示在聊天界面:1.从管理聊天窗口的类中取得该窗口 2.调用显示方法.QqChar qqChar =ManageQqChar.getQqChar(message.getGetter()+""+message.getSender());qqChar.showMessage(message);} else if(message.getMesType() == MessageType.message_ret_onLineFriend) {String getter = message.getGetter();//修改响应的好友列表QqFriendList qqFriendList = ManageQqFriendList.getQqFriendList(getter);//更新在线好友if(qqFriendList != null) {qqFriendList.updateFriend(message);}}} catch (Exception e) {e.printStackTrace();}}}}ManageClientConServerThread类:package com.qq.client.tools;import java.util.HashMap;import java.util.Map;/*** 这是一个管理客户端和服务器保持通讯的线程类* */public class ManageClientConServerThread {public static Map map = new HashMap<String, ClientConServerThread>();//把线程添加到map中public static void addClientConServerThread(String userName, ClientConServerThread ccst) {map.put(userName, ccst);}//根据用户名取得该线程public static ClientConServerThread getClientConServerThread(String userName) {return (ClientConServerThread)map.get(userName);}}ManageQqChar类:package com.qq.client.tools;import java.util.HashMap;import java.util.Map;import com.qq.client.view.QqChar;/*** 这是一个管理用户聊天界面的类* */public class ManageQqChar {public static Map map = new HashMap<String, QqChar>();//把用户聊天界面Qqchar添加到map中public static void addQqChar(String loginAndFriend, QqChar qqchar) {map.put(loginAndFriend, qqchar);}//根据登入用户和发送用户取得该聊天界面public static QqChar getQqChar(String loginAndFriend) { return (QqChar)map.get(loginAndFriend);}}ManageQqFriendList类:package com.qq.client.tools;import java.util.HashMap;import java.util.Map;import com.qq.client.view.QqFriendList;/*** 管理好友、黑名单..界面类* */public class ManageQqFriendList {public static Map map = new HashMap<String, QqFriendList>();//把用用户列表类添加到map中public static void addQqFriendList(String userName, QqFriendList list) {map.put(userName, list);}//根据登录用户取得该用户列表类public static QqFriendList getQqFriendList(String userName) { return (QqFriendList)map.get(userName);}}QqChar类:package com.qq.client.view;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.io.ObjectOutputStream;import java.util.Date;import javax.swing.ImageIcon;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JPanel;import javax.swing.JTextArea;import javax.swing.JTextField;import com.qq.client.tools.ManageClientConServerThread;import mon.Message;import mon.MessageType;/*** QQ聊天窗口** */public class QqChar extends JFrame implements ActionListener { JTextField jtf;//输入的文本框JTextArea jta;//文本区域JButton jb;//发送按钮JPanel jp;//装文本框和发送按钮的panelString friend;String userName;public static void main(String[] args) {QqChar qqChar = new QqChar("1","2");}public QqChar(String userName,String friend) {erName = userName;this.friend = friend;jtf = new JTextField(15);jta = new JTextArea();jb = new JButton("发送");jb.addActionListener(this);jp = new JPanel();jp.add(jtf);jp.add(jb);this.add(jta, "Center");this.add(jp, "South");this.setTitle(userName+" 正在和 " + friend + " 聊天");this.setIconImage(newImageIcon("image/qq.png").getImage());this.setSize(300, 200);this.setVisible(true);}public void showMessage(Message message) {String info=message.getSender()+" 对"+message.getGetter()+" 说:"+message.getContext()+"\r\n";this.jta.append(info);}@Overridepublic void actionPerformed(ActionEvent e) {//当点击发送按钮时,把消息发送到服务器端if(e.getSource() == jb) {Message message = new Message();message.setMesType(MessageType.message_common_mes);message.setSender(userName);message.setGetter(friend);message.setContext(jtf.getText());jtf.setText("");message.setTime(new Date().toString());try {ObjectOutputStream oos = newObjectOutputStream(ManageClientConServerThread.getClientConSer verThread(userName).client.getOutputStream());oos.writeObject(message);} catch (Exception e1) {e1.printStackTrace();}}}}QqClientLogin类:import javax.swing.JLabel;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.JPasswordField;import javax.swing.JTabbedPane;import javax.swing.JTextField;import com.qq.client.model.QqClientUser;import com.qq.client.tools.ManageClientConServerThread; import com.qq.client.tools.ManageQqFriendList;import mon.Message;import mon.MessageType;import er;/*** QQ客户端登入窗口** */public class QqClientLogin extends JFrame implements ActionListener{//定义北部组件JLabel jbl1;//定义中部组件:其中中部组件有一个选项卡的窗口管理,有三个JPanel,一个文本框,一个密码框,4个JLabel,一个清除号码按钮,两个多选框JTabbedPane jtp;//选项卡窗口JPanel jp2;//QQ号码JPanel jp3;//手机号码JPanel jp4;//电子邮件JLabel jp2_jpl1;//QQ号码JLabel jp2_jpl2;//QQ密码JLabel jp2_jpl3;//忘记密码JLabel jp2_jpl4;//申请密码保护JButton jp2_jb1;//清除号码JTextField jp2_jtf;//文本框JPasswordField jp2_jpf;//密码框JCheckBox jp2_jcb1;//隐身登入JCheckBox jp2_jcb2;//记住密码//定义南部组件JPanel jp1;JButton jp1_jb1;//登入按钮JButton jp1_jb2;//取消按钮JButton jp1_jb3;//注册向导按钮public static void main(String[] args) {QqClientLogin qqClientLogin=new QqClientLogin();}public QqClientLogin() {//处理北部的组件jbl1 = new JLabel(new ImageIcon("image/beibu.gif"));//处理中部的组件jp2=new JPanel(new GridLayout(3,3));//把中部分成三行三列jp2_jpl1 = new JLabel("QQ号码", JLabel.CENTER);jp2_jpl2 = new JLabel("QQ密码", JLabel.CENTER);jp2_jpl3 = new JLabel("忘记密码", JLabel.CENTER);jp2_jpl3.setForeground(Color.blue);//把忘记密码设为蓝色jp2_jpl4 = new JLabel("申请密码保护", JLabel.CENTER);jp2_jb1 = new JButton(new ImageIcon("image/clear.png"));jp2_jtf = new JTextField();jp2_jpf = new JPasswordField();jp2_jcb1 = new JCheckBox("隐身登入");jp2_jcb2 = new JCheckBox("记住密码");//把控件按照顺序加入到jp2jp2.add(jp2_jpl1);jp2.add(jp2_jtf);jp2.add(jp2_jb1);jp2.add(jp2_jpl2);jp2.add(jp2_jpf);jp2.add(jp2_jpl3);jp2.add(jp2_jcb1);jp2.add(jp2_jcb2);jp2.add(jp2_jpl4);//创建选项卡窗口,把三个JPanel放进去,最后把选项卡放进JFrame 中jtp=new JTabbedPane();jtp.add("QQ号码",jp2);jp3= new JPanel();jtp.add("手机号码",jp3);jp4=new JPanel();jtp.add("电子邮件",jp4);//处理南部的组件jp1 = new JPanel();jp1_jb1 = new JButton(new ImageIcon("image/dengru.png"));jp1_jb1.addActionListener(this);jp1_jb2 = new JButton(new ImageIcon("image/quxiao.png"));jp1_jb3=new JButton(new ImageIcon("image/xiangdao.png"));//把三个按钮放进jp1中jp1.add(jp1_jb1);jp1.add(jp1_jb2);jp1.add(jp1_jb3);//把定义好的组件放入到JFrame中this.add(jbl1,"North");//放入北部组件this.add(jp1, "South");//放入南部组件this.add(jtp, "Center");//放入中部组件//定义JFrame的一些属性this.setSize(350, 240);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.setIconImage(newImageIcon("image/qq.png").getImage());this.setResizable(false);//不允许放大,改变窗口大小等this.setVisible(true);}@Overridepublic void actionPerformed(ActionEvent e) {//用户点击登录按钮if(e.getSource()==jp1_jb1) {User user =new User();user.setName(jp2_jtf.getText().trim());user.setPassWord(newString(jp2_jpf.getPassword()).trim());QqClientUser qqClientUser = new QqClientUser();//判断是否登录成功if(qqClientUser.checkUser(user)) {try {//把创建好友列表提前QqFriendList qqList = newQqFriendList(jp2_jtf.getText());ManageQqFriendList.addQqFriendList(user.getName(), qqList);//发送一个要求返回在线好友的请求包ObjectOutputStream oos = new ObjectOutputStream(ManageClientConServerThread.getClientConServerThread(user.getName()).client.getOutputSt ream());Message message = new Message();message.setSender(user.getName());message.setMesType(MessageType.message_get_onLineFriend);//发送oos.writeObject(message);} catch (Exception e1) {e1.printStackTrace();}this.dispose();} else {JOptionPane.showMessageDialog(this,"QQ号码或者密码错误");}}}}QqFriendList类:package com.qq.client.view;import javax.swing.*;import com.qq.client.tools.ManageQqChar;import mon.Message;import java.awt.*;import java.awt.event.*;/*** 我的好友列表(包括陌生人和黑名单)* */public class QqFriendList extends JFrame implements ActionListener,MouseListener{//第一张卡片信息(我的好友列表)JPanel jphy1;//总panelJPanel jphy2;//中部的panelJPanel jphy3;//南部的panel,放两个buttonJButton jphy_jb1;//我的好友按钮,防在总panel的北部JButton jphy_jb2;//陌生人按钮,放在jphy3中JButton jphy_jb3;//黑名单按钮,放在jphy3中JScrollPane jsp1;//中部的滚动的paneJLabel jbls[];//中部在线好友的列表//第二张卡片信息(陌生人列表)JPanel jpmsr1;//总panelJPanel jpmsr2;//中部的panelJPanel jpmsr3;//南部的panel,放两个buttonJButton jpmsr_jb1;//我的好友按钮,放在jpmsr3中JButton jpmsr_jb2;//陌生人按钮,放在jpmsr3中JButton jpmsr_jb3;//黑名单按钮,放在总的panel的南部JScrollPane jsp2;//中部的滚动的paneString userName;//把整个JFrame变成卡片布局CardLayout c1;public static void main(String[] args) {QqFriendList qqFriendList = new QqFriendList("1");}public QqFriendList(String userName) {erName = userName;//处理第一张卡片jphy_jb1 = new JButton("我的好友");jphy_jb2 = new JButton("陌生人");jphy_jb2.addActionListener(this);jphy_jb3 = new JButton("黑名单");jphy1 = new JPanel(new BorderLayout());//总的JPaneljphy2= new JPanel(new GridLayout(50,1,4,4));//中部的JPanel,假定有五十个好友//给jphy2这个panel中初始化50个好友jbls = new JLabel[50];for(int i=0; i<jbls.length; i++) {jbls[i] = new JLabel(i+1+"", newImageIcon("image/mm.png"), JLabel.LEFT);jbls[i].setEnabled(false);if(jbls[i].getText().equals(userName)) {jbls[i].setEnabled(true);}jbls[i].addMouseListener(this);jphy2.add(jbls[i]);}jphy3 = new JPanel(new GridLayout(2, 1));//把黑名单按钮和陌生人按钮加入到jpyh3中jphy3.add(jphy_jb2);jphy3.add(jphy_jb3);//把jphy2放入滚动的pane中jsp1 = new JScrollPane(jphy2);//把jphy_jb1,jsp1,jphy3分别放入jphy1中北,中,南三个位置jphy1.add(jphy_jb1,"North");jphy1.add(jsp1,"Center");jphy1.add(jphy3,"South");//处理第二张卡片jpmsr_jb1 = new JButton("我的好友");jpmsr_jb1.addActionListener(this);jpmsr_jb2 = new JButton("陌生人");jpmsr_jb3 = new JButton("黑名单");jpmsr1 = new JPanel(new BorderLayout());//总的JPaneljpmsr2 = new JPanel(new GridLayout(20,1,4,4));//中部的JPanel,假定有二十个陌生人//给jpmsr2这个panel中初始化20个陌生人JLabel jbls2[] = new JLabel[20];for(int i=0; i<jbls2.length; i++) {jbls2[i] = new JLabel(i+1+"", newImageIcon("image/mm.png"), JLabel.LEFT);jpmsr2.add(jbls2[i]);}jpmsr3 = new JPanel(new GridLayout(2, 1));//把我的好友按钮和陌生人按钮加入到jpmsr3中jpmsr3.add(jpmsr_jb1);jpmsr3.add(jpmsr_jb2);//把jpmsr1放入滚动的pane中jsp2 = new JScrollPane(jpmsr2);//把jpmsr3,jsp2,jpmsr_jb3分别放入jpmsr1中北,中,南三个位置jpmsr1.add(jpmsr3,"North");jpmsr1.add(jsp2,"Center");jpmsr1.add(jpmsr_jb3,"South");//把卡片放入JFrame中c1 = new CardLayout();this.setLayout(c1);this.add(jphy1, "1");this.add(jpmsr1, "2");//在窗口显示自己的namethis.setTitle(userName);this.setSize(170, 450);this.setVisible(true);}//更新在线好友情况public void updateFriend(Message message) {String onLineFriend[] = message.getContext().split(" ");for(int i=0; i<onLineFriend.length; i++) {jbls[Integer.parseInt(onLineFriend[i])-1].setEnabled(true);}}@Overridepublic void mouseClicked(MouseEvent e) {//响应用户双击事件,并得到好友编号if(e.getClickCount() ==2) {String friendNo = ((JLabel)e.getSource()).getText();QqChar qqChar = new QqChar(userName,friendNo);//把新开的聊天窗口加入到管理聊天窗口的map中ManageQqChar.addQqChar(erName+" "+friendNo, qqChar);}}@Overridepublic void mousePressed(MouseEvent e) {}@Overridepublic void mouseReleased(MouseEvent e) {}@Overridepublic void mouseEntered(MouseEvent e) {//当鼠标移上去时,使好友头像变为红色JLabel j1 = (JLabel)e.getSource();j1.setForeground(Color.red);}@Overridepublic void mouseExited(MouseEvent e) { //当把鼠标移走时,恢复成黑色JLabel j1 = (JLabel)e.getSource();j1.setForeground(Color.black);}@Overridepublic void actionPerformed(ActionEvent e) { //如果点击了陌生人按钮,就显示第二张卡片if(e.getSource()==jphy_jb2) {c1.show(this.getContentPane(), "2");} else if(e.getSource()==jpmsr_jb1) {c1.show(this.getContentPane(), "1");}}}Message类:(由于客户端和服务器端的common包里面的东西是一样的,所以这里只发一遍)package mon;import java.io.Serializable;/*** 发送的消息的类* */public class Message implements Serializable{private int mesType;//服务器返回的信息包:1代表用户验证成功,2代表用户验证失败,3代表其他信息包;private String sender;//发送消息的人private String getter;//接收消息的人private String context;//发送的消息private String time;//发送的时间public int getMesType() {return mesType;}public void setMesType(int mesType) {this.mesType = mesType;}public String getSender() {return sender;}public void setSender(String sender) {this.sender = sender;}public String getGetter() {return getter;}public void setGetter(String getter) {this.getter = getter;}public String getContext() {return context;}public void setContext(String context) { this.context = context;}public String getTime() {return time;}public void setTime(String time) {this.time = time;}}MessageType类:package mon;/*** 定义包的总类* */public interface MessageType {//表明登入成功的包int message_succeed = 1;//表明登入失败的包int message_login_fail = 2;//表明普通的包int message_common_mes = 3;//要求返回在线好友的包int message_get_onLineFriend = 4;//返回在线好友的包int message_ret_onLineFriend = 5; }User类:package mon;import java.io.Serializable;/*** 用户类* */public class User implements Serializable{ private String name;//用户名private String passWord;//密码public String getName() {return name;}public void setName(String name) { = name;}public String getPassWord() {return passWord;}public void setPassWord(String passWord) { this.passWord = passWord;}}ManageClientThread类:package com.qq.server.model;import java.util.HashMap;import java.util.Iterator;import java.util.Map;/*** 这是一个管理服务器和客户端保持通讯的线程类* */public class ManageClientThread {public static Map map = new HashMap<String, SerConClientThread>();//向map中添加一个线程public static void addCilentThread(String userName, SerConClientThread sc) {map.put(userName, sc);}//根据userName取得一个线程public static SerConClientThread getCilentThread(String userName) {return (SerConClientThread) map.get(userName);}//返回当前在线的人的情况public static String getAllOnLineUser() {//使用迭代器完成Iterator it = map.keySet().iterator();String res = "";while(it.hasNext()) {res += it.next().toString() + " ";}return res;}}MyQqServer类:package com.qq.server.model;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import .ServerSocket;import .Socket;import mon.Message;import er;/*** 这是QQ服务器** */public class MyQqServer {public ServerSocket server;public static void main(String[] args) {new MyQqServer();}public MyQqServer() {try {System.out.println("在9999服务器监听.....");server = new ServerSocket(9999);//阻塞,等待某个客户端来连接while(true){Socket client = server.accept();//读取从客户端发来的消息ObjectInputStream ois = newObjectInputStream(client.getInputStream());User user = (User)ois.readObject();System.out.println("姓名是==="+user.getName()+"===密码是---"+user.getPassWord()+"---");ObjectOutputStream oos = newObjectOutputStream(client.getOutputStream());Message message = new Message();//只要密码是123456都让它登录成功if(user.getPassWord().equals("123456")) {message.setMesType(1);oos.writeObject(message);//登入成功,开启一个线程SerConClientThread sc = new SerConClientThread(client);//把该线程加入到map中ManageClientThread.addCilentThread(user.getName(), sc);//启动线程sc.start();//通知其他在线用户sc.notifyOther(user.getName());} else {//登录不成功时message.setMesType(2);oos.writeObject(message);client.close();}}} catch (Exception e) {e.printStackTrace();}}}QqServerUser类由于没写东西,所以不用创建也可以。
仿qq软件课课程设计

仿qq软件课课程设计一、教学目标本课程的学习目标包括知识目标、技能目标和情感态度价值观目标。
知识目标要求学生掌握QQ软件的基本功能,如即时通讯、文件传输、语音视频通话等。
技能目标要求学生能够熟练操作QQ软件,进行信息的发送和接收、文件的传输和共享、语音视频通话的建立和结束等。
情感态度价值观目标要求学生树立正确的网络交往观念,认识到网络交流的工具性,注重个人信息的保护,遵守网络道德规范,促进良好的网络环境的建设。
二、教学内容本课程的教学内容主要包括QQ软件的基本功能和使用方法。
首先,介绍QQ软件的下载和安装方法,以及账号的注册和登录过程。
然后,详细讲解QQ软件的界面结构和功能模块,如消息、联系人、群聊、文件传输等。
接着,通过实际操作演示,引导学生掌握QQ软件的使用方法,如发送和接收消息、发起语音视频通话、传输文件等。
最后,结合实例,介绍QQ软件的高级功能和技巧,如自定义QQ界面、设置消息提醒、使用QQ群功能等。
三、教学方法为了激发学生的学习兴趣和主动性,本课程将采用多种教学方法。
首先,通过讲授法,向学生传授QQ软件的基本知识和使用方法。
其次,利用讨论法,学生进行小组讨论,分享彼此的操作经验和技巧。
然后,采用案例分析法,分析实际案例,让学生了解QQ软件在实际生活中的应用和价值。
最后,运用实验法,让学生亲自动手操作QQ软件,进行实践操作和练习。
四、教学资源为了支持教学内容和教学方法的实施,丰富学生的学习体验,我们将选择和准备适当的教学资源。
教材方面,我们将使用《计算机应用基础》教材,该书详细介绍了QQ软件的使用方法和技巧。
参考书方面,我们将推荐《QQ使用技巧手册》等书籍,供学生课后阅读和参考。
多媒体资料方面,我们将制作PPT演示文稿,以图文并茂的形式展示QQ软件的操作过程和功能特点。
实验设备方面,我们将准备计算机实验室,确保每个学生都能有机会亲自操作QQ软件。
五、教学评估本课程的教学评估方式包括平时表现、作业和考试三个部分,以保证评估的客观性和公正性。
(完整)基于MFC仿QQ聊天程序设计完整实例教程

本系统基于客户端/服务器基本原理,程序即是服务端,也是客户端,通过IP就可以相互添加好友,并且实现点到点通信,有聊天记录(未实现根据用户发送的消息而改变字体颜色,只能在客户端改),字体颜色设置(一改全改~),包含主界面MaindBord和聊天Talk两大功能模块。
(1) MaindBord模块A、登录模块登陆模块的实现过程有下面几个步骤:(1)初始化列表信息,获取用户名,服务器的IP地址,使按键失效(2)确认登陆后创建套接字,绑定,监听(3)初始化成功后,激活添加好友和隐藏功能B、好友模块添加好友的实现过程有下面几个步骤:(1)弹出对话框(2)获取对话框中的IP(3)检查对方是否在线,建立连接(4)发送请求验证C、好友列表模块(1)客户接收请求,将服务端加入列表,发送客户端信息(2)服务端得到客户端信息,加入列表(3)双击好友列表,弹出发送信息对话框D、隐藏模块(1)隐藏与显示(2)响应鼠标,弹出控制菜单(2)聊天Talk模块A、发送信息模块聊天模块中,发送信息模块的实现过程有下面几个步骤:(1)通过列表双击一个好友为聊天对象,弹出聊天窗口;(2)用户按下发送按钮后,检测对方是否在线,检测对方是否在线(3)将聊天内容发送出去(4)在本地即时聊天内容显示的编辑框中添加发送的内容并写入聊天记录。
B、接收信息模块聊天模块中,接收信息模块的实现过程有下面几个步骤:(1)由主界面判断接收到信息的类型,是否为好友发来信息,如果是,则打开聊天窗口(2)读取消息,并写入聊天记录,(3)载入字体颜色信息。
(4) 显示聊天记录C、聊天记录管理模块聊天记录管理模块的实现过程有下面几个步骤:(1)将发送内容和接收内容写入文本文件;(2)显示聊天记录;(3)删除聊天记录。
D、字体颜色模块实现字体颜色模块的过程有下面几个步骤:(1)调用系统字体,获取字体,写入存档(2) 调用系统字体颜色,获取颜色,写入存档(3)读取、更新字体颜色。
C语言《仿QQ登录》项目设计教案

班级:组别:姓名:组内评价:教师评价:实训项目使用分支程序仿QQ登录(2课时)【实训目标】1.了解分支程序结构2.掌握分支程序设计【实训重难点】重点:使用分支程序进行设计难点:1.分支程序流程图设计2.字符串的输入及字符串的比较【实训准备】1.掌握分支程序结构的执行过程2.了解编程的基本步骤【实训过程】实训项目: 使用分支程序仿QQ登录模块一(引入)观察:实际QQ登录过程,画出其流程图流程图:模块二(项目分解)任务一:使用分支程序仿QQ登录要求:1.只要求输入密码,并进行密码验证2.密码必须全是数字(假设密码为111111)3.密码不正确输出”密码验证错误!”,密码正确不提示。
4.拓展:如果密码正确输出”登录成功!”,程序该如何修改。
拓展:流程图:程序代码:运行情况:实训中出现的问题及解决方法:任务二: 使用分支程序仿QQ登录(使用双分支结构)要求:1.输入账号和密码,并进行验证2.账号必须为数字,密码包含是数字和字母(假设账号为33633749,密码为logo111)3.密码正确输出”登录成功!”,密码不正确输出”密码验证错误!”4.拓展:这道程序能不能用多分支结构来设计,该如何修改。
拓展:流程图:程序代码:运行情况:实训中出现的问题及解决方法:任务三:使用分支程序仿QQ登录要求:在任务二的基础上,要求密码输入3次不正确以后,不充许再输入实训中出现的问题及解决方法:模块三(总体设计)使用分支程序仿QQ登录要求:输入的密码用*来代替。
实训中出现的问题及解决方法:【项目小结】【考核评价】。
仿qq课程设计

仿qq 课程设计一、课程目标知识目标:1. 让学生理解仿QQ软件的基本功能与界面设计,掌握相关的信息技术知识。
2. 学习并掌握网络通信的基本原理,了解信息安全的重要性。
3. 了解软件开发的基本流程,认识到团队协作在软件开发中的作用。
技能目标:1. 培养学生运用所学知识设计并实现简易的即时通讯软件的能力。
2. 提高学生分析问题、解决问题的能力,培养创新思维和动手实践能力。
3. 培养学生的团队协作能力,提高沟通表达和协作解决问题的效率。
情感态度价值观目标:1. 培养学生热爱科学、积极探索的学习态度,激发对信息技术的兴趣和热情。
2. 增强学生的信息安全意识,树立正确的网络道德观念。
3. 培养学生的责任感和团队精神,提高面对挑战的勇气和自信心。
分析课程性质、学生特点和教学要求,本课程将目标分解为以下具体学习成果:1. 学生能够独立完成仿QQ软件的基本功能设计与实现。
2. 学生能够运用所学知识,针对实际需求进行创新性设计和改进。
3. 学生能够在团队协作中发挥自己的作用,共同解决软件开发过程中遇到的问题。
4. 学生能够树立正确的网络道德观念,自觉维护网络环境的安全与和谐。
二、教学内容1. 网络通信原理:讲解网络通信的基本概念、原理和模型,以教材第三章为基础,包括TCP/IP协议、客户端与服务器通信过程等。
2. 软件界面设计:分析QQ软件的界面设计,结合教材第五章,教授界面布局、色彩搭配、图标设计等基本知识。
3. 数据存储与传输:以教材第四章为参考,讲解数据在即时通讯软件中的存储和传输方式,强调数据安全和隐私保护。
4. 功能模块实现:根据教材第六章,教授如何实现仿QQ软件的登录、消息发送与接收、好友管理等功能模块。
5. 信息安全:结合教材第二章,讲解信息安全的基本概念,强调密码学在即时通讯软件中的应用。
6. 团队协作与项目管理:以教材第七章为依据,培养学生团队协作精神,教授项目管理和沟通技巧。
教学安排与进度:第一周:网络通信原理学习,了解TCP/IP协议和客户端/服务器通信过程。