用MFC做QQ程序设计完整实例教程.docx
- 文档编号:5426716
- 上传时间:2023-05-08
- 格式:DOCX
- 页数:46
- 大小:298.45KB
用MFC做QQ程序设计完整实例教程.docx
《用MFC做QQ程序设计完整实例教程.docx》由会员分享,可在线阅读,更多相关《用MFC做QQ程序设计完整实例教程.docx(46页珍藏版)》请在冰点文库上搜索。
用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)读取、更新字体颜色。
让我们先看下运行结果:
Windows7
Windows2003
Windows7Windows2003
Windows7Windows2003
Windows7
Windows2003
心动了么?
让我们开始对第一个模块,也就是MainBord的设计吧。
一、MainBord模块
新建一个MainBord工程
选择Dialogbased,然后Finsh
二、界面设计如下:
(一)、MainBord界面设计如下:
将各ID值设置如下图,通过类向导添加listbox成员变量
(二)、添加好友对话框界面设计如下:
双击,添加类
将各ID值设置如下图,通过类向导添加成员变量
(三)、弹出菜单界面设计如下:
(四)添加图标
三、代码部分:
(一)准备部分
首先,在StdAfx.h中添加如下代码:
afxsock.h头文件;在MainBordDlg.cpp添加Message.h、AddFreind.h;
其次,MainBordDlg.h添加如下代码:
#defineWM_CLIENT_ACCEPTWM_USER+101
#defineWM_CLIENT_READCLOSEWM_USER+102
/////////////////////////////////////////////////////////////////////////////
//CMainBordDlgdialog
//Construction
public:
intTrayAddIcon();
charlpszTipBefore[100];//修改前的图标提示信息
LRESULTOnAccept(WPARAMwParam,LPARAMlParam);
LRESULTOnRead(WPARAMwParam,LPARAMlParam);
CMainBordDlg(CWnd*pParent=NULL);//standardconstructor
SOCKETClient;//客户的连接请求
SOCKETServerSocket;//SOCKET
SOCKETtempSocket;
SOCKADDR_INtempSocketAddr;
SOCKADDR_INm_sockServerAddr;//SOCKET结构
BOOLIsTrue;
CStringip;
CStringSystemMessage;
voidSendMsg();
CStringIPName;
CStringHostName;
voidGetIP_Name();
voidSelectWay();
//好友列表
structFriendList
{
charname[100];
charIP[18];
structFriendList*next;
public:
CStringip;
}*start,*last;
第三,添加Message.h文件
代码如下:
structMessage
{
intsign;
charmsg[1000];
}msg;
第四,添加消息响应
LRESULTCMainBordDlg:
:
OnRead(WPARAMwParam,LPARAMlParam)
{
if(!
IsTrue)
{
//m_List.InsertString(0,"有数据到达,但是没有工作站连接。
");
}
CStringstr;
switch(WSAGETSELECTEVENT(lParam))
{
caseFD_READ:
if(recv(Client,(char*)&msg,sizeof(msg),0)==SOCKET_ERROR)
{
//m_List.InsertString(0,"接收数据发生错误。
");
return0;
}
SelectWay();
//m_History_List.InsertString(0,str);
//MessageBox(str);
break;
caseFD_CLOSE:
str=_T("工作站退出。
");
//m_List.InsertString(0,str);
closesocket(Client);
//IsTrue=FALSE;
break;
}
return0L;
}
LRESULTCMainBordDlg:
:
OnAccept(WPARAMwParam,LPARAMlParam)
{
if(WSAGETSELECTERROR(lParam))
{
//m_List.InsertString(0,"ErrordetectedonentryintoOnServerAccept.");
return0L;
}
if(WSAGETSELECTEVENT(lParam)==FD_ACCEPT)//如果
{
Client=accept(ServerSocket,(LPSOCKADDR)&m_sockServerAddr,0);
if(Client==INVALID_SOCKET)
{
//m_List.InsertString(0,"Serversocketfailedtoacceptconnection.");
return0L;
}
//Clinet
WSAAsyncSelect(Client,m_hWnd,WM_CLIENT_READCLOSE,FD_READ|FD_CLOSE);
IsTrue=TRUE;
}
//m_List.InsertString(0,"有客户机连接上了服务器。
");
return0L;
}
(一)、登录模块
登陆模块的实现过程有下面几个步骤:
(1)初始化列表,获取用户名,服务器的IP地址,使按键失效。
在MainBordDlg.cpp的初始化函数OnInitDialog添加如下代码:
m_FriendList.SetItemHeight(0,18);
start=NULL;
last=NULL;
//TODO:
Addextrainitializationhere
GetIP_Name();
strcpy(lpszTipBefore,"QQ"+IPName);
(CEdit*)GetDlgItem(IDC_AddBTN)->EnableWindow(FALSE);
(CEdit*)GetDlgItem(IDC_HIDEBTN)->EnableWindow(FALSE);
(2)在MainBordDlg.cpp添加获取主机获得IP和主机名的函数
voidCMainBordDlg:
:
GetIP_Name()//获得IP和主机名
{
WORDwVersionRequested;
WSADATAwsaData;
charhostname[128];
CStringstrip;
PHOSTENThostinfo;
wVersionRequested=MAKEWORD(2,0);
if(WSAStartup(wVersionRequested,&wsaData)==0)
{
if(gethostname(hostname,sizeof(hostname))==0)
{
if((hostinfo=gethostbyname(hostname))!
=NULL)
{
strip=inet_ntoa(*(structin_addr*)*hostinfo->h_addr_list);
}
}
WSACleanup();
}
IPName=strip;
HostName.Format("%s",hostname);
}
(3)确定登陆后创建套接字,绑定,监听,初始化成功后,激活添加好友和隐藏功能
在MainBordDlg.cpp添加登陆按钮的方法
voidCMainBordDlg:
:
OnStartBTN()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
WSADATAwsaData;
intiErrorCode;
if(WSAStartup(MAKEWORD(2,1),&wsaData))//调用WindowsSocketsDLL
{
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添加一个成员
//Construction
public:
CStringipstr;
2好友请求对话框添加代码,在AddFreind.cpp增加发送请求(确定)按钮代码:
voidAddFreind:
:
OnOK()
{
//TODO:
Addextravalidationhere
UpdateData(TRUE);
m_IPAddress.GetWindowText(ipstr);
CDialog:
:
OnOK();
}
3在MainBordDlg.cpp添加好友按钮的方法
voidCMainBordDlg:
:
OnAddBTN()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
AddFreindmydlg;
if(mydlg.DoModal()==IDOK)
{
if(mydlg.ipstr.GetLength()==0)
{
MessageBox("您没有输入IP地址!
!
!
","错误信息",NULL);
return;
}
ip=mydlg.ipstr;
}
elsereturn;
WSADATAwsaData;
if(WSAStartup(MAKEWORD(2,1),&wsaData))//调用WindowsSocketsDLL
{
WSACleanup();
return;
}
tempSocket=socket(PF_INET,SOCK_STREAM,0);//创建服务器端Socket,类型为SOCK_STREAM,面向连接的通信
if(tempSocket==INVALID_SOCKET)
{
return;
}
DWORDdwip;
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)服务端得到客户端信息,加入列表;
voidCMainBordDlg:
:
SelectWay()
{
FriendList*newlist=newstructFriendList;
CStringstrIP,strName,temp;//添加新成员
CStringmessage;
inti,j=0;
i=msg.sign;
message.Format("%d#%s",msg.sign,msg.msg);
//MessageBox("here!
!
!
");
//MessageBox(message);
CFilemyfile;
switch(i)
{
case1:
//别人跟你聊天
myfile.Open("msg.txt",CFile:
:
modeCreate|CFile:
:
modeWrite);
myfile.Write(message,message.GetLength());
myfile.Close();
//(HWNDFindWindow(LPCTSTRlpClassName,LPCTSTRlpWindowName)
WinExec("Talk.exe",SW_SHOW);break;
case2:
message.Format("%s",msg.msg);
//MessageBox(message);
strIP="";
strName="";
j=0;
while(msg.msg[j]!
='#')
{
strIP+=msg.msg[j];
j++;
}
j++;
while(msg.msg[j]!
='#')
{
strName+=msg.msg[j];
j++;
}
if((MessageBox(strName+"请求你通过身份验证","请求信息",IDOK))!
=1)
{
//MessageBox("here!
!
!
");
return;
}
for(j=0;j { m_FriendList.GetText(j,temp); if(strcmp(strName,temp)==0) {MessageBox("你已经添加了这个成员","错误信息",NULL); return;} } strcpy(newlist->IP,strIP); strcpy(newlist->name,strName); newlist->next=NULL; if(start==NULL){start=newlist;last=newlist;} else{ last->next=newlist; last=newlist; } m_FriendList.AddString(strName); ip=strIP;//同意加为好友 SystemMessage=IPName+"#"+HostName+"#"; msg.sign=3; SendMsg(); break; case3: //MessageBox(message); message.Format("%s",msg.msg); //MessageBox(message); strIP=""; strName=""; j=0; while(msg.msg[j]! ='#') { strIP+=msg.msg[j]; j++; } j++; while(msg.msg[j]! ='#') { strName+=msg.msg[j]; j++; } for(j=0;j { m_FriendList.GetText(j,temp); if(strcmp(strName,temp)==0) {MessageBox("你已经添加了这个成员","错误信息",NULL); return;} } strcpy(newlist->IP,strIP); strcpy(newlist->name,strName); newlist->next=NULL; if(start==NULL){start=newlist;last=newlist;} else{ last->next=newlist; last=newlist; } m_FriendList.AddString(strName); MessageBox(strName+"通过你的身份验证! ! ! ","验证信息",NULL); UpdateData(TRUE);break; default: break; } } (2)消息响应: voidCMainBordDlg: : SendMsg()//接受或发送系统请求信息 { WSADATAwsaData; if(WSAStartup(MAKEWORD(2,1),&wsaData))//调用WindowsSocketsDLL { WSACleanup(); return; } tempSocket=socket(PF_INET,SOCK_STREAM,0);//创建服务器端Socket,类型为SOCK_STREAM,面向连接的通信 if(tempSocket==INVALID_SOCKET) { return; } DWORDdwip; if((dwi
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- MFC QQ 程序设计 完整 实例教程