admin 管理员组文章数量: 1184232
2023年12月22日发(作者:status英语)
课程设计任务书
学院 专业
课程名称 VC++课程设计
时间
学生姓名
题 目
指导老师
用VC++设计简单的聊天室程序
主要内容:
该系统要求完成聊天室的全过程,包括客户端和服务器两大部分的编程及其连接。服务器端聊天程序负责接收和发送来自客户端的聊天信息,客户端聊天程序负责建立和维护与服务器端的连接,想服务器发送本客户的聊天内容。系统采用VISUAL C++语言程序设计编程实现。
要求:
(1)通过实际软件项目的分析、设计、编码、测试等工作,掌握用软件工程的方法来开发和维护软件。
(2)按要求编写课程设计报告书,能正确编写分析、设计、编码、测试等技术文档和用户使用手册。
(3)进行系统的联合调试,编写系统使用说明。
(4)完成系统的文档、设计说明工作
应当提交的文件:
(1) 课程设计学年论文。
(2) 课程设计附件(主要是源程序)。
用VC++设计简单的聊天室程序
学生姓名: 指导老师:
摘 要 计算机网络技术发展至今已经大大超越了人们当初的预想,无论是人们日常的工作还是学习,我们都越来越多的依靠到互联网。各种实时性的聊天娱乐软件也同时诞生,而且为我们的即时通讯带来了众多的方便,比如说大家所熟知的腾讯QQ、微软的MSN、移动的Fetion等,都是做的比较成功的实时聊天工具。随着网络的日益普及,各种聊天工具也层出不穷,但当我们学习了《TCP/IP协议与网络编程》这门课程之后,我们便会觉得,其实要实现简单的网络通讯其实并不难。接下来的课程设计就是针对一个简单的网络聊天程序,利用MFC为开发工具,实现基本的通讯功能。在课程设计中,系统开发平台为Windows 2000,程序设计设计语言采用Visual C++,数据库采用MS SQL
2000,程序运行平台为Windows 98/2000/XP。
关键词 聊天软件;网络通讯;MFC;课程设计;Visual C++
1 引 言
1.1课题背景及意义
当今世界正处于信息时代,计算机和通信网络是这一时代所谓“信息基础设施”。在互联网相当普及的今天,在互联网上聊天对很多“网虫”来说已经是家常便饭了。聊天室程序可以说是网上最简单的多点通信程序。一个简单的聊天室, 从程序员的观点来看就是在多个I/O端点之间实现多对多的通信。基于SOCKET的局域网通信是一种灵活的、易于实现的、低成本的方法。它可以运行在各种使用TCP/IP协议作为通讯协议的网络上。而在SOCKET API的帮助下,开发基于SOCKET的局域网通信软件也是易于实现的。
1.2 实验平台介绍
Visual C++(简称VC)是Microsoft公司推出的目前使用极为广泛的基于Windows平台的C++可视化开发环境。VC基于C,C++语言,主要由是MFC组成,是与系统联系非常紧密的编程工具,它兼有高级,和低级语言的双重性,功能强大,灵活,执行效率高,几乎可说VC在 Windows平台无所不能。VC主要是针对Windows系统,适合一些系统级 的开发,可以方便实现一些底层 的调用。在VC里边嵌入汇编语言很简单。当对系统性能要求很高的时候,可用VC开发。VC在多线程、网络通信、分布应用方面,有着不可比拟的优势。
1.3 可行性分析
本课程设计主要解决在客户端于客户端的信息交换和客户端于服务器的信息交换及服务器的信息处理上的管理的课程设计。
此程序主要分为两部分:服务器端和客户端。服务器端用于提供一个网络端口,等待客户端发出请求,登录到此服务端,然后进行网络通讯和消息的转发;客户端可通过服务器端的IP地址发送连接请求,然后登陆聊天室。在服务器端的成员列表栏中会显示在线的所有人名单,有人退出聊天室,成员列表会自动除名。服务器端同时也提供了成员之间的私聊功能,此时服务器端作为一个转发站,进行消息的转发。整个程序的主体使用了CSocket类的方法,实现了网络通讯聊天。
先启动服务器端聊天程序,这是聊天服务器需要指定一个端口号,客户端则根据这
个端口号以及服务器的网络地址与服务器进行通信。在这里,把端口号成为“聊天频道” 。
在后面的程序代码分析中将看到,端口号并不等同于聊天频道,而是在聊天频道上增加一个固定的偏移值,使得这个聊天频道不会和系统保留的端口发生冲突。
服务器启动后将在这个指定的端口号中等待客户的连接。对于公共聊天室,服务器对客户的数目不做任何限制。而对于私人聊天室,每个聊天频道则只能允许两个客户互相连接,使得一方发送的信息只能到达对方的主机中。这里的服务器提供的是公共聊天服务。
通过分析发现,该程序完全可以通过Visual C++中MFC完成。
2需求分析
2.1 设计目的
综合运用本课程及计算机网络的相关知识设计并实现一个网络应用程序,以Visual
C++作为开发平台,通过实践复习巩固课堂所学的理论知识,提高对所学知识的综合应用能力。
2.2 设计要求
采用客户/服务器模式,分为客户端程序和服务器端程序。服务器采用WINSOCK I/O模型中的任一种,支持多个客户同时在线聊天。客户端程序和服务器程序通过网络交换聊天字符串内容,服务器窗口的列表框中显示当前在线用户,支持客户端之间的私聊(可以通过服务器中转,或考虑UDP打洞直接建立端端连接)。
课程设计要求设计并编程完成两个方面的内容:首先建立一个使用TCP协议的聊天室服务器,这个服务器可以同时支持多个用户的在线聊天;其次设计一个可以和服务器通信的聊天室客户端。
2.3 功能要求
支持多个客户端的连接,在服务器和多个客户端之间进行数据传输;
接收客户端发送的消息,并显示在一个列表框中;
在用户连接上后有提示,显示出连接的用户名字;
发送信息时可以显示聊天的所有记录;
2.4 系统主要功能和主要功能描述:
服务器端聊天程序必须能够做3件事情:
(1) 服务器聊天程序要在待定的端口上等待来自聊天客户的连接请求,并且需要维护一个客户连接表,以记录所有成功的连接。
(2) 服务器聊天程序要及时接受从各个聊天客户发送过来的信息,然后把这些信息转
发到一个或多个客户连接。对于公共聊天室,服务器将把接受到的信息向除源端外的所有客户发送过去。
(3) 服务器还要监控这些连接的状态,在客户主动离开或发生故障时从列表中删除相应的表项,并及时更新连接表。
这些要求可以通过CSocket类提供的功能实现。从CSocket派生出两个类CListenSocket和CClientSocket,它们分别用来侦听客户的连接请求和建立与客户的连接。服务器只需要一个侦听套接字CListenSocket,然后根据客户的连接请求动态创建客户套接字CClientSocket。客户套接字的数量是不可预知的,因此需要一个列表来记录。MFC的CPtrList类就能实现这种功能。
客户端聊天程序需要完成以下几个功能:
(1) 客户端聊天程序要负责建立和维护与服务器的连接,通过获取用户的设置尝试与服务器的连接,并且随时检测连接的状态。
(2) 客户端聊天程序要把用户输入的信息及时发送到聊天服务器。一般情况下,当用户输入一行信息并且按下回车键后聊天程序就要把这一行信息发送出去,才能及时地满足用户的交互需求。
(3) 要随时准备好接受来自服务器的信息,随时把接受到的信息显示出来,让用户及时看到对方的响应。
(4) 在用户退出聊天过程是要关闭与服务器的连接。比较好的做法是提前通知服务器或者直接给服务器发送一条退出通知,使得服务器能够及时掌握客户端的连接状态,把对方客户的退出信息及时发送到对等实体上。
客户端聊天程序需要使用一个通过CSocket类派生出来的CChatSocket类来实现。该套接字用来发送一个与服务器的连接请求和维持与服务器的连接,发送和接收聊天信息,完成上述各项功能。
3设计流程图
根据对用户的要求及功能设置可以得到以下的流程图3.1,用户首先启动客户端,登陆服务器并向服务器发送信息,启动服务器,服务器等待客户要求并向客户反馈在线用户信息,用户向服务器发送信息,服务器处理用户的数据,然后用户开始聊天。客户端的聊天分为对所有人的信息和私聊的信息,该信息应通过程序控制分别进行处理。
CListenSocket
启动
CClientSocket
登陆
等待客户端登陆
发送ID和IP
登陆成功
登陆失败
创建子套接字
连接上
客户端用户
发送message
显示Message
找到客户端并显示
Message
图3.1 设计流程图
4 调试分析过程描述
Login服务器:在启动聊天室服务端的时候,会出现图4.1的界面,该界面为服务器的登陆界面。
图4.1登陆服务器界面
启动服务器:在登陆页面的环境下,点击启动服务器按钮,即可创建一个新的服务器,服务器界面如图4.2所示。
图4.2 启动服务器界面
Login客户端:在启动客户端服务端的时候,会出现图4.3的界面,该界面为客户端的连接界面。
图4.3 登陆客户端界面
图4.4为创建张三客户端,输入用户名张三:
图4.4 输入名称张三
图4.5为用户张三连接服务器界面,在输入用户名张三并点击确定后,出现如下界面:
图4.5 张三登陆服务器
图4.6为用户李四的连接界面,在李四连接后,张三和李四用户同时出现在用户列表内:
图4.6 李四登陆服务器
图4.7为用户李四的连接界面,在王五连接后,张三,李四和王五用户同时出现在用户
列表内:
图4.7 王五登陆服务器
服务器显示:在张三,李四,王五进入聊天室后的界面为图4.8.:
图4.8 用户成功登陆后界面
开始聊天,群聊:客户端发送信息时的界面为图4.9
图4.9 聊天界面
图4.10为私聊界面。张三与李四私聊:点击私聊选项,并发送私聊内容。
图4.10 张三私聊界面
图4.11为张三私聊界面,李四和张三私聊,张三能看到李四发送的内容:
图4.11 李四私聊界面
图4.12为王五的界面显示,王五看不到张三和李四的私聊内容:
图4.12 非私聊对象界面
5 设计的总结和体会
该次课程设计的制作我主要是参照了图书馆内的相关书籍,找到一个类似的程序,然后按照书上的内容一步步的做出来了,虽然这个程序算不上是我自己写出来的,但通过这样的一个过程,还是让我学会了很多东西,也算能比较熟练地掌握MFC这一个软件了,这算是一个不小的收获吧,而且,在做这个程序的过程中,让我认识到了在做这样程序中,遇到解决不了的问题与同学的讨论时很重要的,譬如可以以运行,但是就是无法出现连接的显示和状态。最后与同学讨论后,才知道是服务器端有了错误,没有设置自己的IP地址,然后对于客户端进行了一番修改,才终于出现了上述的结果。虽然没有彻底做的出来,但是还是比较开心的,因为自己知道了哪里不足,哪里不可以,可以在以后多多的做练习来充实自己。
在课程设计过程中,收获知识,提高能力的同时,我也学到了很多人生的哲理,懂得怎么样去制定计划,怎么样去实现这个计划,并掌握了在执行过程中怎么样去克服心理上的不良情绪。因此在以后的生活和学习的过程中,我一定会把课程设计的精神带到生活中,不畏艰难,勇往直前!
我以后还是需要多多的练习,多多的勤奋,这样才有可能让自己有信心,有动力,让自己不至于懂的太少而怯场,因为不懂而不会做,相信自己以后会编写出让自己满意的程序和软件的。
6 参考文献
[1] 任泰明著. TCP/IP协议与网络编程. 西安电子科技大学出版社. 2004
[2] 唐克著. MFC程序设计:Using Visual C++ 6.0. 北京希望电子出版社. 2002
[3] 邓全良著. Winsock网络程序设计. 中国铁道出版社. 2002
[4]《Visual C++6.0使用与开发》 清华大学出版社,木林森、高峰霞、罗丽琼、奚红宇编著
[5]《Visual c++ 实用教程(第三版) 郑阿奇 , 电子工业出版社
附:源代码
I服务器:
// : implementation file
//
#include "stdafx.h"
#include "Server.h"
#include "ServerDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[ ] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
protected:
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
}
DECLARE_MESSAGE_MAP()
CDialog::DoDataExchange(pDX);
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CServerDlg dialog
CServerDlg::CServerDlg(CWnd* pParent /*=NULL*/)
{
}
void CServerDlg::DoDataExchange(CDataExchange* pDX)
{
}
BEGIN_MESSAGE_MAP(CServerDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BN_START, OnBnStart)
ON_BN_CLICKED(IDC_BN_CLOSE, OnBnClose)
ON_MESSAGE(WM_RECEIVE, OnReceive)
ON_MESSAGE(WM_CLIENTCLOSE, OnClientClose)
ON_MESSAGE(WM_ACCEPT, OnAccept)
ON_WM_DESTROY()
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST_USER, m_lbUser);
m_hIcon = AfxGetApp()->LoadIcon(IDI_ICONAPP);
: CDialog(CServerDlg::IDD, pParent)
DDX_Text(pDX, IDC_EDIT_DISPLAY, m_strDisplay);
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CServerDlg message handlers
BOOL CServerDlg::OnInitDialog()
{
CDialog::OnInitDialog();
}
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
}
SetIcon(m_hIcon, TRUE); // Set big icon
CString strAboutMenu;
ring(IDS_ABOUTBOX);
if (!y())
{
}
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
SetIcon(m_hIcon, FALSE);
m_iNetPort = 3127;
m_lize(this);
m_bServer = FALSE;
// Set small icon
GetDlgItem(IDC_BN_CLOSE)->EnableWindow(FALSE);
return TRUE; // return TRUE unless you set the focus to a control
void CServerDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
}
else
{
CAboutDlg dlgAbout;
l();
}
}
CDialog::OnSysCommand(nID, lParam);
void CServerDlg::OnPaint()
{
}
HCURSOR CServerDlg::OnQueryDragIcon()
{
}
void CServerDlg::OnBnStart()
{
if (IsIconic())
{
}
else
{
}
CDialog::OnPaint();
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) eHdc(), 0);
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (() - cxIcon + 1) / 2;
int y = (() - cyIcon + 1) / 2;
on(x, y, m_hIcon);
return (HCURSOR) m_hIcon;
// 创建套接字
m_(m_iNetPort);
// 开始监听
}
m_();
// 显示
CString strInfo;
ring(IDS_CREATE_SERVER);
ShowInDisplay(strInfo);
m_bServer = TRUE;
GetDlgItem(IDC_BN_START)->EnableWindow(FALSE);
GetDlgItem(IDC_BN_CLOSE)->EnableWindow(TRUE);
void CServerDlg::OnBnClose()
{
}
void CServerDlg::OnAccept()
{
}
void CServerDlg::OnClientClose(WPARAM wParam, LPARAM lParam)
{
CloseServer();
GetDlgItem(IDC_BN_START)->EnableWindow(TRUE);
GetDlgItem(IDC_BN_CLOSE)->EnableWindow(FALSE);
// 创建新客户
CMySocket *pNewClient = new CMySocket;
pNewClient->Initialize(this);
m_(*pNewClient);
// 放入链表中
m_l(pNewClient);
CMySocket *p_delClient = (CMySocket*)wParam;
// 关闭该用户
p_delClient->ShutDown();
char buffer[BUFFERSIZE];
while(p_delClient->Receive(buffer, BUFFERSIZE)>0);
p_delClient->Close();
// 在用户链表中删除该用户
POSITION psCur, psList = m_dPosition();
CMySocket *p_curClient;
while(psList!=NULL)
{
}
// 发送信息告诉其他用户该客户退出
CString strMsg;
ring(IDS_CLIENT_CLOSE);
NETMESSAGE netMessage(PTC_CLIENT_QUIT, p_delClient->GetName(), _T(""),
psCur = psList;
p_curClient = (CMySocket *)m_t(psList);
if(p_delClient==p_curClient)
{
}
m_At(psCur);
break;
p_delClient->GetName() + strMsg);
}
void CServerDlg::OnReceive(WPARAM wParam, LPARAM lParam)
{
SendToAllClient(netMessage);
// 界面上清理该用户信息
m_String(m_ring(-1, p_delClient->GetName()));
ShowInDisplay(p_delClient->GetName() + strMsg);
// 删除该用户
delete p_delClient;
CMySocket *p_curClient = (CMySocket*)wParam;
NETMESSAGE netMessage;
p_curClient->Receive((char *)&netMessage, sizeof(netMessage));
}
switch()
{
}
// 把加工过的信息发送给其他用户
SendToAllClient(netMessage);
case PTC_NEW:
// 新客户加入
NewClientAdd(p_curClient, &netMessage);
break;
// 普通聊天 case PTC_SAY:
ShowMessage(netMessage);
break;
void CServerDlg::CloseServer()
{
if(!m_bServer) return;
// 向所有客户发送服务端关闭的信息
CString strInfo;
ring(IDS_CLOSESERVER);
NETMESSAGE netMessage(PTC_SYSTEM, _T(""), _T(""), strInfo);
SendToAllClient(netMessage);
// 服务端界面显示关闭信息
ShowInDisplay(strInfo);
// 关闭服务端
m_();
// 关闭客户端
char buffer[BUFFERSIZE];
CMySocket *m_pClient;
POSITION psList = m_dPosition();
while(psList!=NULL)
{
}
}
m_pClient = (CMySocket *)m_t(psList);
m_pClient->ShutDown();
while(m_pClient->Receive(buffer, BUFFERSIZE)>0);
m_pClient->Close();
delete m_pClient;
m_All();
m_bServer = FALSE;
// 向所有户发出信息
void CServerDlg::SendToAllClient(const NETMESSAGE &netMessage)
{
}
void CServerDlg::ShowInDisplay(CString str)
{
}
void CServerDlg::OnDestroy()
{
}
// 新用户加入
CMySocket *m_pClient;
POSITION psList = m_dPosition();
while(psList!=NULL)
{
}
m_pClient = (CMySocket *)m_t(psList);
m_pClient->SendMsg(netMessage);
m_strDisplay += str + "rn";
UpdateData(false);
CDialog::OnDestroy();
// TODO: Add your message handler code here
void CServerDlg::NewClientAdd(CMySocket *p_client, NETMESSAGE *netMessage)
{
}
// 显示普通消息
void CServerDlg::ShowMessage(NETMESSAGE netMessage)
{
// 存入用户名字
p_client->SetName(netMessage->form);
// 在列表框中显示该用户
m_ing(p_client->GetName());
// 发送用户列表给该客户
NETMESSAGE netMsg(PTC_USER_LIST, _T(""), _T(""), _T(""));
int iListLen = m_nt();
CString strMsg;
for(int index=m_Index(); index { } // 加工信息 ring(IDS_NEW_CLIENT); strMsg = p_client->GetName() + strMsg; strcpy(netMessage->data, (LPCTSTR)strMsg); // 显示该用户进入 ShowInDisplay(strMsg); m_t(index, strMsg); strcpy(, (LPCTSTR)strMsg); p_client->SendMsg(netMsg); CString strTo = ; if(strTo==_T("")) { } strTo = "所有人"; CString strForm = ; CString strMsg = ; CString strOut = strForm + "对" + strTo + "说:" + strMsg; ShowInDisplay(strOut); } II客户端: // : implementation file // #include "stdafx.h" #include "Client.h" #include "ClientDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[ ] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App About class CAboutDlg : public CDialog { public: CAboutDlg(); enum { IDD = IDD_ABOUTBOX }; protected: virtual void DoDataExchange(CDataExchange* pDX); protected: DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { } // DDX/DDV support void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CClientDlg dialog CClientDlg::CClientDlg(CWnd* pParent /*=NULL*/) : CDialog(CClientDlg::IDD, pParent) { m_strDisplay = _T(""); m_strSend = _T(""); m_bWhispering = FALSE; m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CClientDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); DDX_Control(pDX, IDC_LIST_USER, m_lbUser); DDX_Text(pDX, IDC_EDIT_DIAPLAY, m_strDisplay); DDX_Text(pDX, IDC_EDIT_SEND, m_strSend); DDX_Check(pDX, IDC_CHECK_WHISPERING, m_bWhispering); } BEGIN_MESSAGE_MAP(CClientDlg, CDialog) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_BN_CONNECT, OnBnConnect) ON_BN_CLICKED(IDC_BN_CLOSE, OnBnClose) ON_BN_CLICKED(IDC_BN_SEND, OnBnSend) ON_MESSAGE(WM_RECEIVE, OnReceive) ON_MESSAGE(WM_SOCKETCLOSE, OnServerClose) ON_MESSAGE(WM_SEND, OnSend) ON_MESSAGE(WM_CONNCET, OnConnect) ON_LBN_DBLCLK(IDC_LIST_USER, OnDblclkListUser) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CClientDlg message handlers BOOL CClientDlg::OnInitDialog() { CDialog::OnInitDialog(); ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { } SetIcon(m_hIcon, TRUE); // Set big icon CString strAboutMenu; ring(IDS_ABOUTBOX); if (!y()) { } pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); SetIcon(m_hIcon, FALSE); // 参数初始化 m_lize(this); m_strNetIP = _T("127.0.0.1"); m_iNetPort = 3127; // Set small icon m_bConnect = FALSE; GetDlgItem(IDC_BN_CLOSE)->EnableWindow(FALSE); GetDlgItem(IDC_BN_SEND)->EnableWindow(FALSE); return TRUE; // return TRUE unless you set the focus to a control } void CClientDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { } else { } } void CClientDlg::OnPaint() { if (IsIconic()) { } CAboutDlg dlgAbout; l(); CDialog::OnSysCommand(nID, lParam); CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) eHdc(), 0); int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (() - cxIcon + 1) / 2; int y = (() - cyIcon + 1) / 2; on(x, y, m_hIcon); else { } } HCURSOR CClientDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } void CClientDlg::OnBnConnect() { CString strConnectError; // 获取用户名字 CInputDlg inputDlg; int iResult = l(); if(iResult==IDCANCEL){return;} m_strName = inputDlg.m_strName; // 创建套接字 if(!m_()) { } CString strInfo; ring(IDS_CONNECTING); ShowInDisplay(strInfo); // 连接服务器 if(!m_t(m_strNetIP, m_iNetPort)) { CDialog::OnPaint(); ring(IDS_FAIL_CREATE_SOCKET); ShowInDisplay(strConnectError); return; int n = m_tError(); } ring(IDS_FAIL_CONNECT); ShowInDisplay(strConnectError); return; ring(IDS_SUCCEED_CONNECT); ShowInDisplay(strInfo); m_bConnect = TRUE; // 发送自已的名字 NETMESSAGE netMessage(PTC_NEW, m_strName, _T(""), _T("")); m_g(netMessage); GetDlgItem(IDC_BN_CONNECT)->EnableWindow(FALSE); GetDlgItem(IDC_BN_CLOSE)->EnableWindow(TRUE); GetDlgItem(IDC_BN_SEND)->EnableWindow(TRUE); } void CClientDlg::OnBnClose() { if(m_bConnect) { } } void CClientDlg::OnBnSend() { m_(); m_bConnect = FALSE; GetDlgItem(IDC_BN_CONNECT)->EnableWindow(TRUE); GetDlgItem(IDC_BN_CLOSE)->EnableWindow(FALSE); GetDlgItem(IDC_BN_SEND)->EnableWindow(FALSE); m_ontent(); CString strMsg; ring(IDS_BREAK); ShowInDisplay(strMsg); OnSend(); m_strSend = _T(""); UpdateData(FALSE); } void CClientDlg::OnReceive() { NETMESSAGE netMessage; m_e((char *)&netMessage, sizeof(netMessage)); CString strForm = ; // 过滤自已发出的信息 if(strForm==m_strName) return; CString strTo = ; CString strMsg = ; switch() { case PTC_USER_LIST: // 用户列表 m_ing(strMsg); break; // 新用户进入 case PTC_NEW: m_ing(strForm); ShowInDisplay(strMsg); break; case PTC_SAY: ShowMessage(netMessage); // 密语 case PTC_WHISPERING: if(strTo!=m_strName) return; ShowMessage(netMessage); break; // 有用户退出 case PTC_CLIENT_QUIT: m_String(m_ring(-1, strForm)); ShowInDisplay(strMsg); } } break; void CClientDlg::OnServerClose() { if(!m_bConnect) return; CString strMsg; ring(IDS_SERVER_CLOSE); ShowInDisplay(strMsg); m_(); m_bConnect = FALSE; GetDlgItem(IDC_BN_CONNECT)->EnableWindow(TRUE); GetDlgItem(IDC_BN_CLOSE)->EnableWindow(FALSE); GetDlgItem(IDC_BN_SEND)->EnableWindow(FALSE); m_ontent(); } void CClientDlg::OnSend() { UpdateData(TRUE); // 主要是填充NETMESSAGE结构体 NETMESSAGE netMessage; strcpy(, m_strName); strcpy(, m_strSend); // 取得列表框中的用户 if(m_t(m_Sel(), )==LB_ERR) { } if(m_bWhispering) { strcpy(, _T("")); // 密语 } CString strTo = ; if(strTo==_T("")) { } = PTC_WHISPERING; MessageBox("请选择对方!", "错误"); return; else { } // 发送该信息 m_g(netMessage); // 显示发送信息 CString strTo = ; CString strMsg = ; ShowInDisplay("你对" + strTo + "说:" + strMsg); } void CClientDlg::ShowInDisplay(CString str) { m_strDisplay += str + "rn"; UpdateData(FALSE); } void CClientDlg::ShowMessage(const NETMESSAGE &netMessage) { CString strTo = ; if(strTo==_T("")) { strcpy(, _T("所有人")); = PTC_SAY; } strTo = "所有人"; else if(strTo==m_strName) { } CString strForm = ; CString strMsg = ; CString strOut = strForm + "对" + strTo + "说:" + strMsg; ShowInDisplay(strOut); } void CClientDlg::OnDblclkListUser() { // TODO: Add your control notification handler code here m_Sel(-1); } void CClientDlg::OnConnect() { m_bConnect = TRUE; } strTo = "你";
版权声明:本文标题:用VC++设计简单的聊天室程序完整课程设计 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/p/1703198482a441933.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论