// NetChatDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "NetChat.h"
#include "NetChatDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CNetChatDlg 对话框
CNetChatDlg::CNetChatDlg(CWnd* pParent /*=NULL*/)
: CDialog(CNetChatDlg::IDD, pParent)
, m_strChatInfo(_T(""))
, m_bAllUser(FALSE)
, m_strChatMsg(_T(""))
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CNetChatDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Text(pDX, IDC_CHAT_INFO, m_strChatInfo);
DDX_Control(pDX, IDC_RECV_USER, m_ctrlRecvUser);
DDX_Check(pDX, IDC_ALL_USER, m_bAllUser);
DDX_Text(pDX, IDC_CHAT_MSG, m_strChatMsg);
DDX_Control(pDX, IDC_USER_LIST, m_ctrlUserList);
}
BEGIN_MESSAGE_MAP(CNetChatDlg, CDialog)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_MESSAGE(WM_TCPACCEPT, OnTCPAccept)
ON_MESSAGE(WM_UDPRECEIVE, OnUDPReceive)
ON_WM_DESTROY()
ON_BN_CLICKED(IDC_USER_FRESH, &CNetChatDlg::OnBnClickedUserFresh)
ON_NOTIFY(NM_CLICK, IDC_USER_LIST, &CNetChatDlg::OnNMClickUserList)
ON_BN_CLICKED(IDC_SEND_MSG, &CNetChatDlg::OnBnClickedSendMsg)
ON_BN_CLICKED(IDC_SEND_FILE, &CNetChatDlg::OnBnClickedSendFile)
END_MESSAGE_MAP()
// CNetChatDlg 消息处理程序
BOOL CNetChatDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
m_ctrlUserList.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_REPORT);
m_ctrlUserList.InsertColumn(0, "状态", LVCFMT_LEFT, 60);
m_ctrlUserList.InsertColumn(1, "用户名", LVCFMT_LEFT, 100);
m_ctrlUserList.InsertColumn(2, "主机名", LVCFMT_LEFT, 120);
m_ctrlUserList.InsertColumn(3, "IP地址", LVCFMT_LEFT, 120);
memset(&m_tLocalUsr, 0, sizeof(USERINFO)); // 清空m_tLocalUsr
unsigned long nSize = 0;
m_tLocalUsr.nState = USER_ONLINE; // 用户在线状态
nSize = sizeof(m_tLocalUsr.szName);
::GetUserName(m_tLocalUsr.szName, &nSize); // 取得系统用户名
nSize = sizeof(m_tLocalUsr.szHost);
::GetComputerName(m_tLocalUsr.szHost, &nSize); // 取得系统主机名
hostent* phost = ::gethostbyname(m_tLocalUsr.szHost); // 取得主机IP地址
lstrcpy(m_tLocalUsr.szAddr, inet_ntoa(*(struct in_addr*)phost->h_addr_list[0]));
m_pUDPClient = new CUDPSocket(this);
m_pUDPClient->CreateClient(m_tLocalUsr.szAddr, UDP_PORTNR); // 创建UDP客户端
m_pTCPServer = new CTCPSocket(this);
m_pTCPServer->CreateServer(m_tLocalUsr.szAddr, TCP_PORTNR); // 创建TCP服务端
OnBnClickedUserFresh(); // 刷新用户信息
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CNetChatDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CNetChatDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
LRESULT CNetChatDlg::OnTCPAccept(WPARAM wParam, LPARAM lParam)
{
ASSERT_VALID(m_pTCPServer);
CSocket *pServer = new CSocket();
m_pTCPServer->Accept((*pServer)); // 接受客户端连接请求
FILEINFO *pf = new FILEINFO;
memset(pf, 0, sizeof(FILEINFO));
pServer->Receive(pf, sizeof(FILEINFO)); // 接收文件信息
pf->sock = pServer->Detach(); // 文件接收套接字
AfxBeginThread(RecvFileProc, (LPVOID)pf,
THREAD_PRIORITY_NORMAL, 0, 0, NULL); // 创建文件接收线程
delete pServer;
return 0;
}
LRESULT CNetChatDlg::OnUDPReceive(WPARAM wParam, LPARAM lParam)
{
ASSERT_VALID(m_pUDPClient);
SENDDATA sd;
memset(&sd, 0, sizeof(SENDDATA));
m_pUDPClient->Receive(&sd, sizeof(SENDDATA)); // 接收数据
USERINFO *pInfo = FindUser(sd.szSend); // 是否已经含有该用户信息
// 接收用户信息
if (sd.nType==TYPE_USERINFO && !pInfo)
{
USERINFO *pi = new USERINFO;
memcpy(pi, sd.szData, sizeof(USERINFO)); // 拷贝用户信息
m_lsUsrInfo.AddTail(pi); // 将用户信息指针添加到链表中
sd.nType = TYPE_USERINFO;
lstrcpy(sd.szRecv, pi->szAddr);
lstrcpy(sd.szSend, m_tLocalUsr.szAddr);
memcpy(sd.szData, &m_tLocalUsr, sizeof(USERINFO));
m_pUDPClient->SendTo(&sd, sizeof(SENDDATA), UDP_PORTNR, sd.szRecv); // 回发
UpdateUserList(); // 刷新用户信息列表
return 0;
}
// 接收聊天消息
if (sd.nType == TYPE_CHATDATA)
{
m_strChatInfo += pInfo->szName, m_strChatInfo += ": ";
m_strChatInfo += sd.szData, m_strChatInfo += "\r\n";
SetDlgItemText(IDC_CHAT_INFO, m_strChatInfo); // 添加聊天信息
CEdit *pEdit = (CEdit*)GetDlgItem(IDC_CHAT_INFO);
pEdit->LineScroll(pEdit->GetLineCount()); // 滚动消息内容
return 0;
}
// 接收文件信息
if (sd.nType == TYPE_FILEINFO)
{
FILEINFO fi;
memcpy(&fi, sd.szData, sizeof(FILEINFO)); // 取得文件信息
if (MessageBox(fi.szFile, "提示", MB_YESNO|MB_ICONINFORMATION) != IDYES)
return 0;
// 请求信息
sd.nType = TYPE_REQUFILE;
lstrcpy(fi.szRecv, m_tLocalUsr.szAddr); // 文件接收方
lstrcpy(sd.szSend, m_tLocalUsr.szAddr); // 信息发送方
lstrcpy(sd.szRecv, fi.szSend); // 信息接收方
memcpy(sd.szData, &fi, sizeof(FILEINFO));
m_pUDPClient->SendTo(&sd, sizeof(SENDDATA), UDP_PORTNR, sd.szRecv);
return 0;
}
// 接收文件请求信息
if (sd.nType == TYPE_REQUFILE)
{
FILEINFO *pf = new FILEINFO;
memcpy(pf, sd.szData, sizeof(FILEINFO)); // 取得文件信息
CTCPSocket *pClient = new CTCPSocket(this);
pClient->Create(0, SOCK_STREAM, NULL); // 创建TCP客户端
pClient->Connect(pf->szSend, TCP_PORTNR); // 连接到服务端
pClient->Send(pf, sizeof(FILEINFO)); // 发送文件信息
pf->sock = pClient->Detach(); // 文件发送套接字
AfxBeginThread(SendFileProc, (LPVOID)pf,
THREAD_PRIORITY_NORMAL, 0, 0, NULL); // 创建文件发送线程
delete pClient;
return 0;
}
return 0;
}
void CNetChatDlg::OnDestroy()
{
CDialog::OnDestroy();
m_pUDPClient->Close(); // 关闭UDP客户端
delete m_pUDPClient;
m_pTCPServer->Close(); // 关闭TCP客户端
delete m_pTCPServer;
POSITION pos = m_lsUsrInfo.GetHeadPosition();
for(; pos != NULL; m_lsUsrInfo.GetNext(pos)) // 分别取得链表中所有项
delete (USERINFO*)m_lsUsrInfo.GetAt(pos); // 释放用户信息
}
void CNetChatDlg::OnBnClickedUserFresh()
{
SENDDATA sd;
sd.nType = TYPE_USERINFO;
lstrcpy(sd.szSend, m_tLocalUsr.szAddr); // 发送方IP地址
memcpy(sd.szData, &m_tLocalUsr, sizeof(USERINFO)); // 本地信息
m_pUDPClient->SendTo(&sd, sizeof(SENDDATA), UDP_PORTNR); // 广播本地信息
}
void CNetChatDlg::UpdateUserList(void)
{
m_ctrlRecvUser.ResetContent(); // 清空接收人组合框中的内容
m_ctrlUserList.DeleteAllItems(); // 清空用户信息列表中的�
MFC实现网络聊天功能
4星 · 超过85%的资源 需积分: 12 162 浏览量
2011-07-27
11:06:16
上传
评论
收藏 71KB RAR 举报
lchx05200821
- 粉丝: 0
- 资源: 6
最新资源
- 中医临床诊疗术语-证候同义词典
- NovAtelConvert-Setup
- MySql主备数据库配置
- BGP路由基本配置(可以互通)
- 《软件方法2024版》公开内容202405更新-epub版
- 适用于tensorflow-2.11.0 CUDA版本11.2的cuDNN8.1版本
- 5Y study学习平台2016计算机基础-综合测试(8)_哔哩哔哩_bilibili_2580252704.mp4
- (大赛作品)STM32实现的F072RB NUCLEO智能家居控制.zip
- STM32实现的数字示波器源码+数字信号处理教程、配套实例.zip
- 【cookie续续】【cookie续续】【cookie续续】
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈