📄 chatdlg.cpp
字号:
// ChatDlg.cpp : implementation file
//
#include "stdafx.h"
#include "wbQQClient.h"
#include "ChatDlg.h"
#include "CarryFile.h"
#include "AboutAuth.h"
#define NO_FLAGS_SET 0
#define MAXBUFLEN 5025
#define WM_SYSTEMTRAY WM_USER + 1
#define WM_RECVDATA WM_USER + 2
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
HWND recvWnd;
CWinThread *pSendFile;
//////////////////////////////全局函数获取SOCKET错误详细信息/////////////////
CString GetError(DWORD error)
{
CString strError;
switch(error)
{
case WSANOTINITIALISED:
strError="初始化错误";
break;
case WSAENOTCONN:
strError="对方没有启动";
break;
case WSAEWOULDBLOCK :
strError="对方已经关闭";
break;
case WSAECONNREFUSED:
strError="连接的尝试被拒绝";
break;
case WSAENOTSOCK:
strError="在一个非套接字上尝试了一个操作";
break;
case WSAEADDRINUSE:
strError="特定的地址已在使用中";
break;
case WSAECONNRESET:
strError="与主机的连接被关闭";
break;
default:
strError="一般错误";
}
return strError;
}
///////////////////////接收文件线程(客户端模式)////////////////////////////
UINT recvFile(void *data)
{
char nameIP[40];
strcpy(nameIP, (char*)data);
char name[20];
char IP[20];
for (int i=0; nameIP[i]!='~'; i++)
{
name[i] = nameIP[i];
}
name[i++] = '\0'; //获得发送者用户名
strcpy(IP, nameIP + i); //获得发送者IP地址
CString strCaption = name;
strCaption += " 传来文件";
CCarryFile dlg;
dlg.m_strCaption = strCaption;
strcpy(dlg.m_destIP, IP);
dlg.DoModal();
ExitThread(0);
return 0;
}
///////////////////////发送文件线程(服务器模式)/////////////////////////////
UINT sendFile(void *name)
{
char destName[20];
strcpy(destName, (char*)name);
CString strCaption = "传送文件给 ";
strCaption += destName;
CCarryFile dlg;
dlg.m_strCaption = strCaption;
dlg.m_bSendFile = true;
dlg.DoModal();
return 1;
}
/////////////////////////////////////////////////////////////////////////////
// CChatDlg dialog
UINT RecvThread(void* cs)
{
char buffer[MAXBUFLEN] = {0};
int numrcv;
SOCKET clientSocket = (SOCKET)cs;
while (1)
{
numrcv = recv(clientSocket, buffer, MAXBUFLEN, NO_FLAGS_SET);
if ((numrcv == 0) || (numrcv == SOCKET_ERROR))
{
AfxMessageBox("RecvThread:Connection terminated!\n"
+ GetError(GetLastError()), MB_OK);
break;
}
buffer[numrcv] = '\0';
char type[10]; //判断接收到的消息种类
for (int i=0; i<9; i++)
{
type[i] = buffer[i];
}
type[9] = '\0'; //"SendFile!"有9个字符
if (strcmp(type, "SendFile!") == 0) //对方要给我发送文件
{
char senderName[20];
for (i=0; buffer[i+9]!='~'; i++)
{
senderName[i] = buffer[i+9];
}
senderName[i] = '\0';
char str[80];
strcpy(str, senderName);
strcat(str, " 想给你发送文件!\n接收按“是”,拒绝按“否”");
if (AfxMessageBox(str, MB_YESNO) == IDYES)
{
AfxBeginThread(recvFile, (LPVOID*)(buffer+9)); //开始接收文件线程
}
else
{
CString strRefuse;
strRefuse = senderName;
strRefuse += ":";
strRefuse += "Refuse!";
send(clientSocket, strRefuse, strRefuse.GetLength(), 0);//发送拒收文件消息
}
continue;
}
type[7] = '\0'; //"Refuse!"有7个字符
if (strcmp(type, "Refuse!") == 0) //对方拒绝接收文件
{
AfxMessageBox("对方拒绝接收文件!\n按取消关闭对话框。", MB_OK);
TerminateThread(pSendFile, 0);
continue;
}
::PostMessage(recvWnd, WM_RECVDATA, DWORD((LPSTR)buffer), numrcv);//普通消息
}
closesocket(clientSocket);
return 1;
}
CChatDlg::CChatDlg(CWnd* pParent /*=NULL*/)
: CDialog(CChatDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CChatDlg)
m_strCity = _T("");
m_strRecv = _T("");
//}}AFX_DATA_INIT
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CChatDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CChatDlg)
DDX_Control(pDX, IDC_BTN_MORE, m_more);
DDX_Control(pDX, IDC_STATIC_PIC, m_pic);
DDX_Control(pDX, IDC_COMBO_PETNAME, m_petname);
DDX_Control(pDX, IDC_FRIEND, m_friend);
DDX_Control(pDX, IDC_EDIT_MESSAGE, m_message);
DDX_Text(pDX, IDC_EDIT_CITY, m_strCity);
DDX_Text(pDX, IDC_EDIT_RECEIVE, m_strRecv);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CChatDlg, CDialog)
//{{AFX_MSG_MAP(CChatDlg)
ON_WM_TIMER()
ON_BN_CLICKED(IDC_BTN_MORE, OnBtnMore)
ON_BN_CLICKED(IDC_BTN_SEND, OnBtnSend)
ON_BN_CLICKED(IDC_BTN_REPLY, OnBtnReply)
ON_CBN_SELCHANGE(IDC_COMBO_PETNAME, OnSelchangeComboPetname)
ON_COMMAND(ID_ABOUT, OnAbout)
ON_COMMAND(ID_CLOSE, OnClose)
ON_COMMAND(ID_SHOW, OnShow)
ON_BN_CLICKED(IDC_BTN_CARRY_FILE, OnBtnCarryFile)
//}}AFX_MSG_MAP
ON_MESSAGE(WM_RECVDATA, RecvData)
ON_MESSAGE(WM_SYSTEMTRAY, OnSystemTray)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CChatDlg message handlers
BOOL CChatDlg::InitNet()
{
char IP[20]; //用于从网络设置文件读取IP地址
char port[8]; //用于从网络设置文件读取字符串端口号
u_short nPort;
FILE *pFile;
CString cfgFileName;
cfgFileName.Format(".\\data\\netset.cfg");
pFile = fopen(cfgFileName, "r");
////////////////从网络设置文件读取聊天通信服务器IP地址////////////////
char ch = 's';
for (int i=0; ch != ','; i++)
{
ch = fgetc(pFile);
}
ch = 's';
for (i=0; ch != ','; i++)
{
ch = fgetc(pFile);
}
ch = 's';
for (i=0; ch != ','; i++) //ch已定位到聊天通信服务器IP地址
{
ch = fgetc(pFile);
IP[i] = ch;
}
IP[--i] = '\0';
////////////////从网络设置文件读取聊天通信服务器端口///////////////////
ch = 's';
for (i=0; !feof(pFile); i++)
{
ch=fgetc(pFile);
port[i] = ch;
}
port[--i] = '\0';
nPort = atoi(port);
fclose(pFile);
//////////////////初始化ws2_32.dll动态库,创建套接字///////////////////
status = WSAStartup(MAKEWORD(1, 1), &Data);
if (status != 0)
{
MessageBox("ERROR: WSAStartup unsuccessfull!" + GetError(GetLastError()),
"闻博QQ", MB_OK);
}
destAddr = inet_addr(IP);
memcpy(&destSockAddr.sin_addr, &destAddr, sizeof (destAddr));
destSockAddr.sin_port = htons(nPort);
destSockAddr.sin_family = AF_INET;
destSocket = socket(AF_INET, SOCK_STREAM, 0);
if (destSocket == INVALID_SOCKET)
{
MessageBox("ERROR:socket unsccessful!" + GetError(GetLastError()),
"闻博QQ", MB_OK);
status = WSACleanup();
if (status == SOCKET_ERROR)
{
MessageBox("ERROR:WSACleanup unsccessful!" + GetError(GetLastError()),
"闻博QQ", MB_OK);
}
return false;
}
status = connect(destSocket, (LPSOCKADDR)&destSockAddr, sizeof(destSockAddr));
if (status == SOCKET_ERROR)
{
MessageBox("ERROR:connect unsccessful!" + GetError(GetLastError()),
"闻博QQ", MB_OK);
status = closesocket(destSocket);
if (status == SOCKET_ERROR)
{
MessageBox("ERROR:closesocket unsccessful!" + GetError(GetLastError()),
"闻博QQ", MB_OK);
}
status = WSACleanup();
if (status == SOCKET_ERROR)
{
MessageBox("ERROR:WSACleanup unsccessful!" + GetError(GetLastError()),
"闻博QQ", MB_OK);
}
return false;
}
send(destSocket, m_strUserName, m_strUserName.GetLength(), 0);
AfxBeginThread(RecvThread, (LPVOID)destSocket);
return true;
}
void CChatDlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
char temp[30];
strcpy(temp, petname);
strcat(temp, "的消息");
if (!flag)
{
NOTIFYICONDATA nid;
nid.cbSize = sizeof (NOTIFYICONDATA);
nid.hWnd = m_hWnd;
nid.uID = ID_SYSTEMTRAY;
nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
nid.uCallbackMessage = WM_SYSTEMTRAY;
nid.hIcon = AfxGetApp()->LoadIcon(m_nNetSel);
strcpy(nid.szTip, temp);
::Shell_NotifyIcon(NIM_MODIFY, &nid);
m_pic.SetIcon(AfxGetApp()->LoadIcon(m_nNetSel));
}
else
{
NOTIFYICONDATA nid;
nid.cbSize = sizeof (NOTIFYICONDATA);
nid.hWnd = m_hWnd;
nid.uID = ID_SYSTEMTRAY;
nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
nid.uCallbackMessage = WM_SYSTEMTRAY;
nid.hIcon = AfxGetApp()->LoadIcon(IDI_NULL);
strcpy(nid.szTip, temp);
::Shell_NotifyIcon(NIM_MODIFY, &nid);
m_pic.SetIcon(AfxGetApp()->LoadIcon(IDI_NULL));
}
flag = !flag;
CDialog::OnTimer(nIDEvent);
}
LRESULT CChatDlg::OnSystemTray(WPARAM wParam, LPARAM lParam)
{
BringWindowToTop();
if (wParam == ID_SYSTEMTRAY)
{
switch (lParam)
{
case WM_LBUTTONDBLCLK:
{
KillTimer(0);
NOTIFYICONDATA nid;
nid.cbSize = sizeof(NOTIFYICONDATA);
nid.hWnd = m_hWnd;
nid.uID = ID_SYSTEMTRAY;
nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
nid.uCallbackMessage = WM_SYSTEMTRAY;
nid.hIcon = AfxGetApp()->LoadIcon(res);
strcpy(nid.szTip, ("闻博QQ:" + m_strUserName));
::Shell_NotifyIcon(NIM_MODIFY, &nid);
::ShowWindow(m_hWnd, SW_SHOWDEFAULT);
m_pic.SetIcon(AfxGetApp()->LoadIcon(res));
}
break;
case WM_RBUTTONDOWN:
{
CMenu menu;
menu.LoadMenu(IDR_MENU1);
CMenu *pMenu = menu.GetSubMenu(0);
ASSERT(pMenu != NULL);
CPoint point;
GetCursorPos(&point);
pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,
point.x, point.y, this);
PostMessage(WM_NULL);
}
break;
default:
break;
}
}
return 1;
}
BOOL CChatDlg::DestroyWindow()
{
// TODO: Add your specialized code here and/or call the base class
CString close = "Close!";
send(destSocket, close, close.GetLength(), 0);
////////////////////////////////////////////////////////////////////////
NOTIFYICONDATA nid;
nid.cbSize = sizeof (NOTIFYICONDATA);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -