MFC仿QQ程序设计完整实例.doc_第1页
MFC仿QQ程序设计完整实例.doc_第2页
MFC仿QQ程序设计完整实例.doc_第3页
MFC仿QQ程序设计完整实例.doc_第4页
MFC仿QQ程序设计完整实例.doc_第5页
免费预览已结束,剩余12页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

本系统基于客户端/服务器基本原理,程序即是服务端,也是客户端,通过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)读取、更新字体颜色。让我们先看下运行结果:Windows7 Windows2003 Windows7 Windows2003 Windows7 Windows2003Windows7Windows 2003心动了么?让我们开始对第一个模块,也就是MainBord的设计吧。一、MainBord模块新建一个MainBord工程 选择Dialog based,然后Finsh二、界面设计如下:(一)、MainBord界面设计如下:将各ID值设置如下图,通过类向导添加listbox成员变量(二)、添加好友对话框界面设计如下:双击,添加类将各ID值设置如下图,通过类向导添加成员变量(三)、弹出菜单界面设计如下: (四)添加图标三、代码部分:(一)准备部分首先,在StdAfx.h中添加如下代码:afxsock.h 头文件;在MainBordDlg.cpp添加Message.h 、AddFreind.h;其次,MainBordDlg.h添加如下代码: #define WM_CLIENT_ACCEPT WM_USER+101#define WM_CLIENT_READCLOSE WM_USER+102/ CMainBordDlg dialog/ Constructionpublic:int TrayAddIcon();char lpszTipBefore100; /修改前的图标提示信息LRESULT OnAccept(WPARAM wParam,LPARAM lParam);LRESULT OnRead(WPARAM wParam,LPARAM lParam);CMainBordDlg(CWnd* pParent = NULL);/ standard constructor SOCKET Client; /客户的连接请求SOCKET ServerSocket; /SOCKET SOCKET tempSocket;SOCKADDR_IN tempSocketAddr;SOCKADDR_IN m_sockServerAddr; /SOCKET 结构BOOL IsTrue;CString ip;CString SystemMessage;void SendMsg();CString IPName;CString HostName;void GetIP_Name();void SelectWay(); /好友列表struct FriendListchar name100;char IP18;struct FriendList *next;public:CString ip; *start,*last;第三,添加Message.h文件代码如下:struct Messageint sign;char msg1000;msg;第四,添加消息响应LRESULT CMainBordDlg:OnRead(WPARAM wParam, LPARAM lParam)if(!IsTrue)/m_List.InsertString(0,有数据到达,但是没有工作站连接。);CString str;switch (WSAGETSELECTEVENT(lParam)case FD_READ:if(recv(Client,(char *)&msg,sizeof(msg),0) = SOCKET_ERROR)/m_List.InsertString(0,接收数据发生错误。);return 0;SelectWay();/m_History_List.InsertString(0,str);/MessageBox(str);break;case FD_CLOSE:str = _T(工作站退出。);/m_List.InsertString(0,str);closesocket(Client);/IsTrue = FALSE;break;return 0L;LRESULT CMainBordDlg:OnAccept(WPARAM wParam, LPARAM lParam)if (WSAGETSELECTERROR(lParam)/m_List.InsertString(0,Error detected on entry into OnServerAccept.);return 0L;if(WSAGETSELECTEVENT(lParam) = FD_ACCEPT)/如果 Client = accept(ServerSocket,(LPSOCKADDR)&m_sockServerAddr,0); if (Client = INVALID_SOCKET)/m_List.InsertString(0,Server socket failed to accept connection.);return 0L;/ClinetWSAAsyncSelect(Client,m_hWnd,WM_CLIENT_READCLOSE,FD_READ|FD_CLOSE);IsTrue = TRUE;/m_List.InsertString(0,有客户机连接上了服务器。);return 0L;(一)、登录模块登陆模块的实现过程有下面几个步骤:(1)初始化列表,获取用户名,服务器的IP地址,使按键失效。在MainBordDlg.cpp的初始化函数OnInitDialog添加如下代码:m_FriendList.SetItemHeight( 0, 18 );start=NULL;last=NULL;/ TODO: Add extra initialization here GetIP_Name();strcpy(lpszTipBefore,QQ +IPName);(CEdit *)GetDlgItem(IDC_AddBTN)-EnableWindow(FALSE);(CEdit *)GetDlgItem(IDC_HIDEBTN)-EnableWindow(FALSE);(2)在MainBordDlg.cpp添加获取主机获得IP和主机名的函数void CMainBordDlg:GetIP_Name()/获得IP和主机名WORD wVersionRequested;WSADATA wsaData;char hostname128;CString strip;PHOSTENT hostinfo;wVersionRequested=MAKEWORD(2,0);if(WSAStartup(wVersionRequested,&wsaData)=0)if(gethostname(hostname,sizeof(hostname)=0)if(hostinfo=gethostbyname(hostname)!=NULL)strip=inet_ntoa(*(struct in_addr *)*hostinfo-h_addr_list);WSACleanup();IPName=strip;HostName.Format(%s,hostname);(3) 确定登陆后创建套接字,绑定,监听, 初始化成功后,激活添加好友和隐藏功能在MainBordDlg.cpp添加登陆按钮的方法void CMainBordDlg:OnStartBTN() / TODO: Add your control notification handler code hereWSADATA wsaData; int iErrorCode; if (WSAStartup(MAKEWORD(2,1),&wsaData) /调用Windows Sockets DLL WSACleanup(); return;/m_List.InsertString(0,服务器开始创建SOCKET。);ServerSocket=socket(PF_INET,SOCK_STREAM,0); /创建服务器端Socket,类型为SOCK_STREAM,面向连接的通信 if(ServerSocket = INVALID_SOCKET) /m_List.InsertString(0,无法创建服务器socket!); return; m_sockServerAddr.sin_family = AF_INET; m_sockServerAddr.sin_addr.s_addr = INADDR_ANY; /向所有的IP地址发送消息 m_sockServerAddr.sin_port = htons(8001); if (bind(ServerSocket,(LPSOCKADDR)&m_sockServerAddr,sizeof(m_sockServerAddr) = SOCKET_ERROR) /与选定的端口绑定 /m_List.InsertString(0,无法绑定服务器。); return; iErrorCode=WSAAsyncSelect(ServerSocket,m_hWnd,WM_CLIENT_ACCEPT,FD_ACCEPT); / 产生相应传递给窗口的消息为WM_SERVER_ACCEPT ,这是自定义消息 if (iErrorCode = SOCKET_ERROR) return; if (listen(ServerSocket,1) = SOCKET_ERROR) /开始监听客户连接请求/m_List.InsertString(0,服务器监听失败!); return;IsTrue = TRUE; /m_List.AddString(服务器绑定监听成功。);(CEdit *)GetDlgItem(IDC_AddBTN)-EnableWindow(TRUE);(CEdit *)GetDlgItem(IDC_HIDEBTN)-EnableWindow(TRUE); return; (二)好友模块添加好友的实现过程有下面几个步骤:(1)弹出对话框 (2)获取对话框中的IP(3)检查对方是否在线,建立连接(4)发送请求验证1在AddFreind.h添加一个成员 / Constructionpublic:CString ipstr;2好友请求对话框添加代码,在AddFreind.cpp增加发送请求(确定)按钮代码:void AddFreind:OnOK() / TODO: Add extra validation hereUpdateData(TRUE);m_IPAddress.GetWindowText(ipstr);CDialog:OnOK();3在MainBordDlg.cpp添加好友按钮的方法 void CMainBordDlg:OnAddBTN() / TODO: Add your control notification handler code hereAddFreind mydlg;if(mydlg.DoModal() = IDOK)if(mydlg.ipstr.GetLength()=0)MessageBox(您没有输入IP地址!,错误信息,NULL);return;ip=mydlg.ipstr;else return;WSADATA wsaData; if (WSAStartup(MAKEWORD(2,1),&wsaData) /调用Windows Sockets DLL WSACleanup(); return;tempSocket=socket(PF_INET,SOCK_STREAM,0); /创建服务器端Socket,类型为SOCK_STREAM,面向连接的通信 if(tempSocket = INVALID_SOCKET) return;DWORD dwip;if(dwip=inet_addr(ip)=INADDR_NONE)MessageBox(IP赋值错误,错误信息);return; tempSocketAddr.sin_family=AF_INET; /使用TCP/IP协议 tempSocketAddr.sin_port = htons(8001);tempSocketAddr.sin_addr.S_un.S_addr = dwip;if(connect(tempSocket,(LPSOCKADDR)&tempSocketAddr,sizeof(tempSocketAddr) = SOCKET_ERROR) MessageBox(对方不在线,添加失败,NULL); return;else msg.sign=2;SystemMessage=IPName+#+HostName+#;strcpy(msg.msg,SystemMessage); if(send(tempSocket,(char *)&msg,sizeof(msg),0)=SOCKET_ERROR)MessageBox(发送消息失败,错误信息,MB_OK);return;3好友列表模块与消息响应(1)客户接收请求,将服务端加入列表,发送客户端信息 ;(2)服务端得到客户端信息,加入列表; void CMainBordDlg:SelectWay()FriendList *newlist=new struct FriendList;CString strIP,strName,temp;/添加新成员CString message;int i,j=0;i=msg.sign;message.Format(%d#%s,msg.sign,msg.msg);/MessageBox(here!);/MessageBox(message);CFile myfile;switch(i)case 1:/别人跟你聊天myfile.Open(msg.txt,CFile:modeCreate | CFile:modeWrite ); myfile.Write(message, message.GetLength(); myfile.Close(); /(HWND FindWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName)WinExec(Talk.exe,SW_SHOW);break;case 2:message.Format(%s,msg.msg);/MessageBox(message); strIP=;strName=;j=0;while(msg.msgj!=#)strIP+=msg.msgj;j+;j+;while(msg.msgj!=#)strName+=msg.msgj;j+; if(MessageBox(strName+请求你通过身份验证,请求信息,IDOK)!=1) /MessageBox(here!); return; for(j=0;jIP,strIP);strcpy(newlist-name,strName);newlist-next=NULL;if(start=NULL)start=newlist;last=newlist;elselast-next=newlist;last=newlist;m_FriendList.AddString(strName); ip=strIP;/同意加为好友 SystemMessage=IPName+#+HostName+#;msg.sign=3;SendMsg(); break;case 3:/MessageBox(message);message.Format(%s,msg.msg);/MessageBox(message);strIP=;strName=;j=0;while(msg.msgj!=#)strIP+=msg.msgj;j+;j+;while(msg.msgj!=#)strName+=msg.msgj;j+;for(j=0;jIP,strIP);strcpy(newlist-name,strName);newlist-next=NULL;if(start=NULL)start=newlist;last=newlist;elselast-next=newlist;last=newlist;m_FriendList.AddString(strName);MessageBox(strName+通过你的身份验证!,验证信息,NULL);UpdateData(TRUE);break;default:break;(2) 消息响应:void CMainBordDlg:SendMsg()/接受或发送系统请求信息WSADATA wsaData; if (WSAStartup(MAKEWORD(2,1),&wsaData) /调用Windows Sockets DLL WSACleanup(); return;tempSocket=socket(PF_INET,SOCK_STREAM,0); /创建服务器端Socket,类型为SOCK_STREAM,面向连接的通信 if(tempSocket = INVALID_SOCKET) return;DWORD dwip;if(dwip=inet_addr(ip)=INADDR_NONE)MessageBox(IP赋值错误,错误信息);return; tempSocketAddr.sin_family=AF_INET; /使用TCP/IP协议 tempSocketAddr.sin_port = htons(8001);tempSocketAddr.sin_addr.S_un.S_addr = dwip;if(connect(tempSocket,(LPSOCKADDR)&tempSocketAddr,sizeof(tempSocketAddr) = SOCKET_ERROR) MessageBox(对方不在线,失败信息,NULL); return;strcpy(msg.msg,SystemMessage);if(send(tempSocket,(char *)&msg,sizeof(msg),0)=SOCKET_ERROR)MessageBox(发送消息失败,错误信息,MB_OK);return; (3)双击好友列表,弹出发送信息对话框。void CMainBordDlg:OnDblclkFriendLIST() / TODO: Add your control notification handler code hereif(IsTrue!=TRUE)return;/未登录int index=m_FriendList.GetCurSel();if(index!=LB_ERR)CString strname;m_FriendList.GetText(index,strname);FriendList *s;s=start;while(s!=NULL&strcmp(s-name,strname)!=0)s=s-next;if(s=NULL)MessageBox(没找到!);return;CString ipstr;ipstr.Format(%s,s-IP);CString a;a=0#+ipstr+#+strname+#;CFile myfile;myfile.Open(msg.txt,CFile:modeCreate | CFile:modeWrite );myfile.Write( a, a.GetLength(); myfile.Close();/MessageBox(a);WinExec(Talk.exe,SW_SHOW);3隐藏模块(1) 隐藏为隐藏按钮添加代码如下:void CMainBordDlg:OnHidebtn() TrayAddIcon();ShowWindow(SW_HIDE);添加TrayAddIcon()方法int CMainBordDlg:TrayAddIcon() BOOL res;NOTIFYICONDATA tnid;HICON hicon;hicon=LoadIcon(AfxGetApp()-m_hInstance,MAKEINTRESOURCE(IDI_ICONBEFORE);tnid.cbSize=sizeof(NOTIFYICONDATA);tnid.hWnd=GetSafeHwnd();tnid.cbSize=sizeof(NOTIFYICONDATA);tnid.hWnd=GetSafeHwnd();tnid.uID=DEMOICON;tnid.uFlags=NIF_ICON|NIF_TIP|NIF_MESSAGE;tnid.uCallbackMessage=TESTWM_NOTIFYICON;tnid.hIcon=hicon;if(lpszTipBefore)lstrcpyn(tnid.szTip,lpszTipBefore,sizeof(tnid.szTip);elsetnid.szTip0=0;res=Shell_NotifyIcon(NIM_ADD,&tnid);if(hicon)DestroyIcon(hicon);return res;(2)在MainBordDlg.cpp添加下面代码:BEGIN_MESSAGE_MAP(CMainBordDlg, CDialog)ON_BN_CLICKED(IDC_HIDEBTN, OnHidebtn)ON_COMMAND(ID_SUBMENU1,OnSubmenu1)ON_COMMAND(ID_SUBMENU2,OnSubmenu2)在MainBordDlg.h 添加如下代码:protected:/ Generated message map functions/AFX_MSG(CMainBordDlg)afx_msg LRESULT OnTestNotifyIcon(WPARAM wParam,LPARAM lParam);afx_msg void OnSubmenu1();afx_msg void OnSubmenu2();在resouce.h添加#define IDR_MENU1 139#define ID_SUBMENU1 32771#define ID_SUBMENU2 32772(3)响应鼠标LRESULT CMainBordDlg:OnTestNotifyIcon(WPARAM wParam, LPARAM lParam) switch(lParam)case WM_LBUTTONDBLCLK:if(wParam=DEMOICON)ShowWindow(SW_SHOW);break;case WM_RBUTTONDOWN:if(wParam=DEMOICON)CMenu *pm1,m2;CPoint pp(LOWORD(lParam),HIWORD(lParam);m2.LoadMenu(IDR_MENU1);pm1=m2.GetSubMenu(0);ClientToScreen(&pp);pm1-TrackPopupMenu(TPM_RIGHTALIGN|TPM_LEFTBUTTON,pp.x,GetSystemMetrics(SM_CYSCREEN)-50,this);break; default:break;return 0L;(4)添加菜单方法的鼠标双击左键显示主界面鼠标右键,弹出控制菜单void CMainBordDlg:OnSubmenu1() / TODO: Add your command handler code hereShowWindow(SW_SHOW);void CMainBordDlg:OnSubmenu2() / TODO: Add your command handler code hereEndDialog(TRUE);二、聊天Talk模块一 、新建一个Talk工程 选择Dialog based,然后Finsh二 界面设计如下:(一)、Talk界面设计如下:将各ID值设置如下图,通过类向导添加成员变量准备工作:在stdafx.h中添加fxsock.h头文件。1建一个Message.h文件,代码如MaindBord一致。2在TalkDlg.cpp添加头文件 fstream.h、Message.h添加宏定义,用来控制颜色#define GetRValue(rgb) (BYTE)(rgb)#define GetGValue(rgb) (BYTE)(WORD)(rgb) 8)#define GetBValue(rgb) (BYTE)(rgb)16)3在TalkDlg.h 添加成员变量如下:/ Constructionpublic:void GetIP_Name();SOCKADDR_IN sockStruct;SOCKET ServerSocket;CString IPstr;CTalkDlg(CWnd* pParent = NULL);/ standard constructorCString IPName;CString HostName;CFont *Font; LOGFONT m_logft;COLORREF m_color;private:BOOL sign;一、发送信息模块聊天模块中,发送信息模块的实现过程有下面几个步骤:1用户按下发送按钮后,检测对方是否在线,将聊天内容发送出去,在本地即时聊天内容显示的编辑框中添加发送的内容并写入聊天记录。void CTalkDlg:OnOK() / TODO: Add extra validation hereif(sign)CEdit* myedit;myedit=(CEdit*) GetDlgItem(IDC_TALK);myedit-SetReadOnly(FALSE);m_SendMSG.SetWindowText(发送);sign=FALSE;m_Talk.Empty();UpdateData(FALSE);(CEdit *)GetDlgItem(IDC_TALK)-SetFocus();return;LPCTSTR ip;ip=IPstr;WSADATA wsaData;if(WSAStartup(MAKEWORD(2,1),&wsaData)/调用Windows Sockets DLLMessageBox(WinSock 无法初始化!,错误信息,NULL);return;DWORD dwip;if(dwip=inet_addr(ip)=INADDR_NONE)MessageBox(IP有误,错误信息,NULL);return;ServerSocket=socket(PF_INET,SOCK_STREAM,0);/创建服务器Socketif(ServerSocket=INVALID_SOCKET)MessageBox(无法创建服务器Socket,错误信息,NULL);return;sockStruct.sin_family=AF_INET;/TCP/IP 协议sockStruct.sin_port=htons(8001);/端口sockStruct.sin_addr.S_un.S_addr=dwip;if(connect(ServerSocket,(LPSOCKADDR)&sockStruct,sizeof(sockStruct)=SOCKET_ERROR)MessageBox(对方已经下线!,错误信息,NULL);return;/MessageBox(登录成功!,成功信息,NULL);/WSAAsyncSelect(ServerSocket,m_hWnd,WM_CLIENT_READCLOSE,FD_READ|FD_CLOSE);/ 产生相应传递给窗口的消息为WM_SERVER_ACCEPT ,这是自定义消息UpdateData(TRUE);if(m_Talk.IsEmpty()MessageBox(不允许发送空消息,错误信息,NULL);return;CString strtime;CTime time = CTime:GetCurrentTime();strtime = time.Format(%H:%M:%S);CString rec;rec=HostName+ +strtime+rn+m_Talk+rn+rn;CFile recordfile;recordfile.Open(record.txt,CFile:modeCreate |CFile:modeNoTruncate| CFile:modeWrite );recordfile.SeekToEnd();recordfile.Write( rec, rec.GetLength(); recordfile.Close();msg.sign=1;m_Talk=IPName+#+HostName+#+m_Talk+#;strcpy(msg.msg,(LPCTSTR)m_Talk);if(send(ServerSocket,(char *)&msg,sizeof(msg),0)=SOCKET_ERROR)MessageBox(发送消息失败,错误信息,MB_OK);return;/m_TalkList.InsertString(0,m_Talk);m_Talk.Empty();UpdateData(FALSE);CDialog:OnOK();添加:GetIP_Name()函数。void CTalkDlg:GetIP_Name()WORD wVersionRequested;WSADATA wsaData;char hostname128;CString strip;PHOSTENT hostinfo;wVersionRequested=MAKEWORD(2,0);if(WSAStartup(wVersionRequested,&wsaData)=0)if(gethostname(hostname,sizeof(hostname)=0)if(hostinfo=gethostbyname(hostname)!=NULL)strip=inet_ntoa(*(struct in_addr *)*hosti

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论