标签:
<pre name="code" class="cpp">// ServerDlg.cpp : implementation file #include "stdafx.h" #include "Server.h" #include "ServerDlg.h" #include "ListenSocket.h" #include "CLientSocket.h" #include "../Content/UserType.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(); // Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: //{{AFX_MSG(CAboutDlg) //}}AFX_MSG DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) // No message handlers //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CServerDlg dialog CServerDlg::CServerDlg(CWnd* pParent /*=NULL*/) : CDialog(CServerDlg::IDD, pParent) { //读取配置文件 m_uPort = GetPrivateProfileInt(_T("NET"), _T("SERVERPORT"), 8811, _T("./Server.ini")); GetPrivateProfileString(_T("NET"), _T("SERVERIP"), _T("127.0.0.1"),m_strIP.GetBuffer(15), 15, _T("./Server.ini")); //{{AFX_DATA_INIT(CServerDlg) //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON_Logo); } void CServerDlg::DoDataExchange(CDataExchange* pDX) { //设置默认按钮 this->SetDefID(IDC_BUTTON_StartServer); CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CServerDlg) DDX_Control(pDX, IDC_LIST_ServerOnLineList, m_ServerOnLine); DDX_Text(pDX, IDC_EDIT_SerPort, m_uPort); DDX_Text(pDX, IDC_EDIT_IP, m_strIP); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CServerDlg, CDialog) //{{AFX_MSG_MAP(CServerDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_BUTTON_StartServer, OnBUTTONStartServer) ON_BN_CLICKED(IDC_BUTTON_PauseServer, OnBUTTONPauseServer) ON_WM_CLOSE() //}}AFX_MSG_MAP ON_MESSAGE(UD_NETPACK, OnNetRecv) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CServerDlg message handlers BOOL CServerDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here //服务器未启动时,暂停按钮不可用 GetDlgItem(IDC_BUTTON_PauseServer)->EnableWindow(FALSE); //设置服务器的IP地址 SetDlgItemText(IDC_IPADDRESS_IP, m_strIP); //显示ListControl网格 m_ServerOnLine.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_HEADERDRAGDROP ); //设置ListControl的属性 m_ServerOnLine.InsertColumn(0, _T("序号"), LVCFMT_LEFT, 50, -1); m_ServerOnLine.InsertColumn(1, _T("用户名"), LVCFMT_LEFT, 80, -1); m_ServerOnLine.InsertColumn(2, _T("时间"), LVCFMT_LEFT, 160, -1); m_ServerOnLine.InsertColumn(3, _T("事件"), LVCFMT_LEFT, 190, -1); return TRUE; // return TRUE unless you set the focus to a control } void CServerDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CServerDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle 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; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } // The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CServerDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } void CServerDlg::OnBUTTONStartServer() { UpdateData(TRUE); if (m_Socket.m_hSocket != 0xffffffff) { return; } // 创建流式Socket 及 绑定 int res = m_Socket.Create(m_uPort, SOCK_STREAM, m_strIP); if (!res) { MessageBox(_T("创建套接字失败"), _T("提示"), MB_ICONINFORMATION); return; } // 监听 if (!m_Socket.Listen()) { MessageBox(_T("监听失败"), _T("提示"), MB_ICONINFORMATION); m_Socket.Close(); //监听失败关闭Socket return; } //按下启动服务按钮后,将其设置为灰色不可用 GetDlgItem(IDC_BUTTON_StartServer)->EnableWindow(FALSE); //服务器列表插入日志 InsertLog(_T("服务器"), _T("启动服务器")); //按下启动服务按钮后,将暂停按钮设置可用 GetDlgItem(IDC_BUTTON_PauseServer)->EnableWindow(TRUE); UpdateData(FALSE); } void CServerDlg::OnBUTTONPauseServer() { //点击关闭服务器后将其按钮设置为不可用 GetDlgItem(IDC_BUTTON_PauseServer)->EnableWindow(FALSE); NET_PACK pPack; memset(&pPack, 0, sizeof(NET_PACK)); pPack.fun = SRVSTOP; lstrcpy(pPack.Content, _T("服务器维护中...")); list<CCLientSocket *>::iterator itr; for (itr=CCLientSocket::m_plClient.begin(); itr!=CCLientSocket::m_plClient.end(); itr++) { (*itr)->Send(&pPack, sizeof(NET_PACK)); delete (*itr); } //清空链表 CCLientSocket::m_plClient.clear(); if (m_Socket.m_hSocket != 0xffffffff) { m_Socket.Close(); //插入日志 InsertLog(_T("服务器"), _T("关闭服务器")); //按下暂停按钮后,将启动服务按钮设置可用 GetDlgItem(IDC_BUTTON_StartServer)->EnableWindow(TRUE); } } void CServerDlg::InsertLog(CString strName, CString strEvent) { //获取行数 int iCount = m_ServerOnLine.GetItemCount(); m_iNumber.Format("%d", iCount+1); m_ServerOnLine.InsertItem(iCount, m_iNumber); m_ServerOnLine.SetItemText(iCount, 1, strName); //获取服务器启动的时间 CTime StartTime = CTime::GetCurrentTime(); CString SerStartTime = StartTime.Format(_T("%Y/%m/%d %H:%M:%S")); m_ServerOnLine.SetItemText(iCount, 2, SerStartTime); m_ServerOnLine.SetItemText(iCount, 3, strEvent); } LRESULT CServerDlg::OnNetRecv(WPARAM wParam, LPARAM lParam) { NET_PACK *pPack = (NET_PACK *)wParam; CCLientSocket *pClient = (CCLientSocket *)lParam; switch(pPack->fun) { case LOGIN: DealLogin(pPack->SenderID, pClient); break; case LOGOUT: DealLogout(pPack->SenderID); break; case TRANSMIT: DealTransmit(pPack); break; case SENDUSERLIST: SendToClientOLUserList(pPack->ReceiveID); break; } delete pPack; pPack = NULL; return 0; } void CServerDlg::DealLogin(CString strName, CCLientSocket *pClient) { NET_PACK pack; //初始化网络包 memset(&pack, 0, sizeof(NET_PACK)); CCLientSocket *pSocket = FindClientSocket(strName); if (pSocket == NULL) { //未登录 pack.fun = LOGOK; /* CString UserList; UserList.Format(_T("%s 在线"), strName); lstrcpy(pack.Content, UserList); pClient->Send(&pack, sizeof(NET_PACK));*/ pClient->m_strName = strName; CCLientSocket::m_plClient.push_back(pClient); InsertLog(strName, strName+_T(" 登陆成功")); } else { //用户已登录 pack.fun = LOGERR; lstrcpy(pack.Content, _T("该用户已登录")); pClient->Send(&pack, sizeof(NET_PACK)); pClient->Close(); } SendToClientOLUserList(strName); } CCLientSocket * CServerDlg::FindClientSocket(CString strName, BOOL bRemove) { CCLientSocket* pClient = NULL; list<CCLientSocket*>::iterator itr; for (itr=CCLientSocket::m_plClient.begin(); itr!=CCLientSocket::m_plClient.end(); itr++) { if ((*itr)->m_strName == strName) { pClient = *itr; if (bRemove) { CCLientSocket::m_plClient.erase(itr); } break; } } return pClient; } void CServerDlg::DealLogout(CString strName) { CCLientSocket* pSocket = FindClientSocket(strName, TRUE); if (pSocket) { delete pSocket; pSocket = NULL; InsertLog(strName, strName+_T(" 注销成功")); } } void CServerDlg::DealTransmit(NET_PACK *pPack) { CCLientSocket *pSocket = FindClientSocket(pPack->ReceiveID); if (pSocket) { pSocket->Send(pPack, sizeof(NET_PACK)); } } void CServerDlg::OnClose() { OnBUTTONPauseServer(); CDialog::OnClose(); } BOOL CServerDlg::PreTranslateMessage(MSG* pMsg) { //屏蔽ESC if (pMsg->message == WM_KEYDOWN) { switch(pMsg->wParam) { case VK_ESCAPE: return TRUE; } } return CDialog::PreTranslateMessage(pMsg); } void CServerDlg::SendToClientOLUserList(CString strName) { NET_PACK pack; memset(&pack, 0, sizeof(NET_PACK)); pack.fun = SENDUSERLIST; CString UserList; UserList.Format(_T("%s (在线)"), strName); lstrcpy(pack.Content, UserList); list<CCLientSocket *>::iterator itr; for (itr=CCLientSocket::m_plClient.begin(); itr!=CCLientSocket::m_plClient.end(); itr++) { (*itr)->Send(&pack, sizeof(NET_PACK)); //delete (*itr); } } // ListenSocket.cpp : implementation file // /******************************************************************************************************************************************/ #include "stdafx.h" #include "Server.h" #include "ListenSocket.h" #include "CLientSocket.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CListenSocket CListenSocket::CListenSocket() { } CListenSocket::~CListenSocket() { } // Do not edit the following lines, which are needed by ClassWizard. #if 0 BEGIN_MESSAGE_MAP(CListenSocket, CSocket) //{{AFX_MSG_MAP(CListenSocket) //}}AFX_MSG_MAP END_MESSAGE_MAP() #endif // 0 ///////////////////////////////////////////////////////////////////////////// // CListenSocket member functions void CListenSocket::OnAccept(int nErrorCode) { CCLientSocket *pClient = new CCLientSocket; Accept(*pClient); CSocket::OnAccept(nErrorCode); } // CLientSocket.cpp : implementation file // /******************************************************************************************************************************************/ #include "stdafx.h" #include "Server.h" #include "CLientSocket.h" #include "../Content/UserType.h" #include "ServerDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CCLientSocket list<CCLientSocket *> CCLientSocket::m_plClient; CCLientSocket::CCLientSocket() { m_strName = _T(""); } CCLientSocket::~CCLientSocket() { } // Do not edit the following lines, which are needed by ClassWizard. #if 0 BEGIN_MESSAGE_MAP(CCLientSocket, CSocket) //{{AFX_MSG_MAP(CCLientSocket) //}}AFX_MSG_MAP END_MESSAGE_MAP() #endif // 0 ///////////////////////////////////////////////////////////////////////////// // CCLientSocket member functions void CCLientSocket::OnReceive(int nErrorCode) { NET_PACK *pPack = new NET_PACK; Receive(pPack, sizeof(NET_PACK)); ////////////////////////////////////////////////////////////////////////// //将接收到的数据包发送给主对话框处理 ////////////////////////////////////////////////////////////////////////// //获取主对话框的地址 CServerDlg *pDlg = (CServerDlg *)AfxGetApp()->m_pMainWnd; //给主对话框发送UD_NETPACK消息 pDlg->PostMessage(UD_NETPACK, (WPARAM)pPack, (LPARAM)this); CSocket::OnReceive(nErrorCode); } /******************************************************************************************************************************************/ //定义的用户数据包 #ifndef _USER_TYPE_ #define _USER_TYPE_ //功能号 typedef enum{LOGIN = 1, LOGOUT, LOGERR, LOGOK, TRANSMIT, SRVSTOP, SENDUSERLIST}FUN; //定义数据包 typedef struct { FUN fun; char SenderID[32]; char ReceiveID[32]; char Content[1024]; }NET_PACK; #endif
// ClientDlg.cpp : implementation file #include "stdafx.h" #include "Client.h" #include "ClientDlg.h" #include "../Content/UserType.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(); // Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: //{{AFX_MSG(CAboutDlg) //}}AFX_MSG DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) // No message handlers //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CClientDlg dialog CClientDlg::CClientDlg(CWnd* pParent /*=NULL*/) : CDialog(CClientDlg::IDD, pParent) { color = RGB(0, 0, 255); //{{AFX_DATA_INIT(CClientDlg) m_Name = _T(""); m_Input = _T(""); m_Receiver = _T(""); m_MsgList = _T(""); m_strAddUserName = _T(""); //}}AFX_DATA_INIT //读取配置文件 m_uPort = GetPrivateProfileInt(_T("NET"), _T("CLIENTPORT"), 8000, _T("./Client.ini")); GetPrivateProfileString(_T("NET"), _T("CLIENTIP"), _T("127.0.0.1"), m_strIP.GetBuffer(15), 15, _T("./Client.ini")); // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON_Client); } void CClientDlg::DoDataExchange(CDataExchange* pDX) { //设置默认按钮 this->SetDefID(IDC_BUTTON_Send); //设置默认焦点 GetDlgItem(IDC_EDIT_Input)->SetFocus(); CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CClientDlg) DDX_Control(pDX, IDC_LIST_UserList, m_UserList); DDX_Text(pDX, IDC_EDIT_Name, m_Name); DDX_Text(pDX, IDC_EDIT_Input, m_Input); DDX_Text(pDX, IDC_EDIT_Recver, m_Receiver); DDX_Text(pDX, IDC_EDIT_MsgList, m_MsgList); DDX_Text(pDX, IDC_EDIT_Addfri, m_strAddUserName); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CClientDlg, CDialog) //{{AFX_MSG_MAP(CClientDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_BUTTON_Login, OnBUTTONLogin) ON_BN_CLICKED(IDC_BUTTON_Logout, OnBUTTONLogout) ON_BN_CLICKED(IDC_BUTTON_Send, OnBUTTONSend) ON_WM_CLOSE() ON_BN_CLICKED(IDC_BUTTON_Exit, OnBUTTONExit) ON_BN_CLICKED(IDC_BUTTON_AddFriend, OnBUTTONAddFriend) ON_NOTIFY(NM_CLICK, IDC_LIST_UserList, OnClickLISTUserList) //}}AFX_MSG_MAP ON_MESSAGE(UD_NETPACK, OnNetRecv) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CClientDlg message handlers BOOL CClientDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here //初始化用户的ListBox m_UserList.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_HEADERDRAGDROP); m_UserList.InsertColumn(0, _T("序号"), LVCFMT_LEFT, 48, -1); m_UserList.InsertColumn(1, _T("用户名"), LVCFMT_LEFT, 150, -1); //将部分按钮初始化为不可用,登陆成功后方可使用 InitBtnStatus(); return TRUE; // return TRUE unless you set the focus to a control } void CClientDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CClientDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle 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; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } // The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CClientDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } void CClientDlg::OnBUTTONLogin() { UpdateData(TRUE); if (m_Socket.m_hSocket != 0xffffffff) { return; } if (m_Name.IsEmpty()) { MessageBox(_T("账号不能为空"), _T("提示"), MB_ICONINFORMATION); return; } // 创建Socket if (!m_Socket.Create()) { MessageBox(_T("创建套接字失败"), _T("提示"), MB_ICONINFORMATION); return; } // 连接服务器 if (!m_Socket.Connect(m_strIP, m_uPort)) { MessageBox(_T("连接服务器失败"), _T("提示"), MB_ICONINFORMATION); m_Socket.Close(); //关闭Socket return; } //登陆成功后设置各按钮的状态 LogOkBtnStatus(); //登陆成功后字体设置为蓝色 SetUsetListColor(RGB(0, 0, 255)); UpdateData(FALSE); //定义网络包 NET_PACK pack; memset(&pack, 0, sizeof(NET_PACK)); pack.fun = LOGIN; lstrcpy(pack.SenderID, m_Name); //发送数据 m_Socket.Send(&pack, sizeof(NET_PACK)); } LRESULT CClientDlg::OnNetRecv(WPARAM wParam, LPARAM lParam) { NET_PACK *pPack = (NET_PACK *)wParam; switch (pPack->fun) { case LOGERR://登录失败 DealLogErr(pPack->Content); break; case LOGOK://登陆成功 DealLogOk(pPack->Content); break; case TRANSMIT://转发消息 DealTransmit(pPack); break; case SRVSTOP://服务器停止 DealSrvStop(pPack->Content); break; case SENDUSERLIST: RecvUserList(pPack->Content); break; } delete pPack; pPack = NULL; return 0; } void CClientDlg::OnBUTTONLogout() { //定义网络包 NET_PACK pack; memset(&pack, 0, sizeof(NET_PACK)); pack.fun = LOGOUT; lstrcpy(pack.SenderID, m_Name); //发送数据 m_Socket.Send(&pack, sizeof(NET_PACK)); //0 表示不接受数据 m_Socket.ShutDown(0); m_Socket.Close(); //关闭Socket CString Status; Status.Format(_T("%s (离线)"), m_Name); //插入用户状态 InsertUser(Status); /* CString m_iNumber, str; int iCount = m_UserList.GetItemCount(); for (int i=-1; i<iCount; i++) { str = m_UserList.GetItemText(i++, 1); if (str.Right(7) == _T(" (在线)")) { m_UserList.DeleteItem(i); m_UserList // return; } } */ //用户离线,字体设置为灰色 SetUsetListColor(RGB(127, 127, 127)); //注销后各按钮的状态 LogOutBtnStatus(); } void CClientDlg::OnBUTTONSend() { UpdateData(TRUE); if (m_Receiver.IsEmpty()) { MessageBox(_T("请先选择接收对象"), _T("提示"), MB_ICONINFORMATION); return; } //定义网络包 NET_PACK pack; memset(&pack, 0, sizeof(NET_PACK)); pack.fun = TRANSMIT; lstrcpy(pack.SenderID, m_Name); lstrcpy(pack.ReceiveID, m_Receiver); lstrcpy(pack.Content, m_Input); //发送数据,若发送内容为空返回且不发送 if (m_Input.IsEmpty()) { MessageBox(_T("发送内容不能为空,请重新输入!"), _T("提示"), MB_ICONINFORMATION); return; } m_Socket.Send(&pack, sizeof(NET_PACK)); //获取系统时间 CString strTime, strInfo; CTime tm = CTime::GetCurrentTime(); strTime = tm.Format(_T("%Y-%m-%d %H:%M:%S")); strInfo.Format(_T(" %s\r\n【%s】:%s\r\n"), strTime, m_Name, m_Input); m_MsgList += strInfo; //发送成功后清空发送编辑框 m_Input = _T(""); UpdateData(FALSE); } void CClientDlg::DealLogOk(CString strContent) { // InsertUser(strContent); //MessageBox(strContent, _T("提示"), MB_ICONINFORMATION); } void CClientDlg::DealLogErr(CString strContent) { //若该用户已登录则设置登录按钮可用 LogOutBtnStatus(); m_Socket.Close(); //关闭Socket MessageBox(strContent, _T("提示"), MB_ICONINFORMATION); } void CClientDlg::DealTransmit(NET_PACK *pPack) { UpdateData(TRUE); CString strTime, strInfo; //获取系统时间 CTime tm = CTime::GetCurrentTime(); strTime = tm.Format("%Y-%m-%d %H:%M:%S"); strInfo.Format(_T(" %s\r\n【%s】:%s\r\n"), strTime, pPack->SenderID, pPack->Content); m_MsgList += strInfo; UpdateData(FALSE); } void CClientDlg::DealSrvStop(CString strContent) { m_Socket.Close(); //关闭Socket m_UserList.DeleteAllItems(); LogOutBtnStatus(); MessageBox(strContent, _T("提示")); } void CClientDlg::OnClose() { OnBUTTONLogout(); CDialog::OnClose(); } void CClientDlg::OnBUTTONExit() { if (IDOK == MessageBox(_T("确定关闭并退出吗?"), _T("温馨提示"), MB_OKCANCEL|MB_ICONQUESTION)) { OnBUTTONLogout(); ::PostMessage(AfxGetMainWnd()->GetSafeHwnd(), WM_CLOSE, 0, 0); } } void CClientDlg::InsertUser(CString strUserName) { int iCount = m_UserList.GetItemCount(); m_iItem.Format("%d", iCount+1); m_UserList.InsertItem(iCount, m_iItem); m_UserList.SetItemText(iCount, 1, strUserName); } BOOL CClientDlg::PreTranslateMessage(MSG* pMsg) { //屏蔽ESC if (pMsg->message == WM_KEYDOWN) { switch(pMsg->wParam) { case VK_ESCAPE: return TRUE; } } return CDialog::PreTranslateMessage(pMsg); } void CClientDlg::LogOkBtnStatus() { //登陆成功后,将注销按钮设置为可用 GetDlgItem(IDC_BUTTON_Logout)->EnableWindow(TRUE); //登陆成功后,将登陆按钮设置为不可用 GetDlgItem(IDC_BUTTON_Login)->EnableWindow(FALSE); //登陆成功后,将发送按钮设置为可用 GetDlgItem(IDC_BUTTON_Send)->EnableWindow(TRUE); //登陆成功后,将添加好友按钮设置为可用 GetDlgItem(IDC_BUTTON_AddFriend)->EnableWindow(TRUE); //登陆成功后,将添加好友编辑框设置为可用 GetDlgItem(IDC_EDIT_Addfri)->EnableWindow(TRUE); //登陆成功后,将发送消息编辑框设置为可用 GetDlgItem(IDC_EDIT_Input)->EnableWindow(TRUE); //登陆成功后,将接收者编辑框设置为可用 GetDlgItem(IDC_EDIT_Recver)->EnableWindow(TRUE); //登陆成功后,将用户列表设置为可用 GetDlgItem(IDC_LIST_UserList)->EnableWindow(TRUE); } void CClientDlg::LogOutBtnStatus() { //点击注销按钮后 将其设置为不可用 GetDlgItem(IDC_BUTTON_Logout)->EnableWindow(FALSE); //点击注销按钮后 将登陆按钮设置为可用 GetDlgItem(IDC_BUTTON_Login)->EnableWindow(TRUE); //点击注销按钮后 将发送按钮设置为不可用 GetDlgItem(IDC_BUTTON_Send)->EnableWindow(FALSE); //点击注销按钮后 将添加好友按钮设置为不可用 GetDlgItem(IDC_BUTTON_AddFriend)->EnableWindow(FALSE); //点击注销按钮后 将添加好友编辑框设置为不可用 GetDlgItem(IDC_EDIT_Addfri)->EnableWindow(FALSE); //点击注销按钮后 将发送消息编辑框设置为不可用 GetDlgItem(IDC_EDIT_Input)->EnableWindow(FALSE); //点击注销按钮后 将接收者编辑框设置为不可用 GetDlgItem(IDC_EDIT_Recver)->EnableWindow(FALSE); //点击注销按钮后 将用户列表设置为不可用 GetDlgItem(IDC_LIST_UserList)->EnableWindow(FALSE); } void CClientDlg::RecvUserList(CString strContent) { InsertUser(strContent); } void CClientDlg::SetUsetListColor(COLORREF color) { m_UserList.SetTextColor(color); } void CClientDlg::OnBUTTONAddFriend() { UpdateData(TRUE); if (m_strAddUserName.IsEmpty()) { MessageBox(_T("对方账号不能为空"), _T("温馨提示"), MB_ICONINFORMATION); return; } CString m_iNumber, str; int iCount = m_UserList.GetItemCount(); for (int i=0; i<iCount; i++) { str = m_UserList.GetItemText(i++, 1); if (m_strAddUserName == str.Left(str.GetLength()-7)) { MessageBox(_T("该用户已经是你的好友,不能重复添加。")); return; } } //m_UserList.InsertItem(iCount, m_iNumber); // m_UserList.SetItemText(iCount, 1, m_strAddUserName); InsertUser(m_strAddUserName); m_strAddUserName = _T(""); UpdateData(FALSE); } void CClientDlg::OnClickLISTUserList(NMHDR* pNMHDR, LRESULT* pResult) { UpdateData(TRUE); int nItem = -1; LPNMITEMACTIVATE lpNMItemActivate = (LPNMITEMACTIVATE)pNMHDR; if(lpNMItemActivate != NULL) { nItem = lpNMItemActivate->iItem; } CString strName, Extra; strName.Format("%d",nItem); strName = m_UserList.GetItemText(nItem,1); //在线用户,则提取其最左边的账号 if (strName.GetLength() > 7) { m_Receiver = strName.Left(strName.GetLength()-7); } else { //添加的好友则直接获取账号 m_Receiver = strName; } UpdateData(FALSE); *pResult = 0; } void CClientDlg::InitBtnStatus() { //未登陆之前,注销按钮不可用 GetDlgItem(IDC_BUTTON_Logout)->EnableWindow(FALSE); //未登陆之前,发送按钮不可用 GetDlgItem(IDC_BUTTON_Send)->EnableWindow(FALSE); //未登陆之前,添加好友按钮不可用 GetDlgItem(IDC_BUTTON_AddFriend)->EnableWindow(FALSE); //未登陆之前,添加好友编辑框不可用 GetDlgItem(IDC_EDIT_Addfri)->EnableWindow(FALSE); //未登陆之前, 发送消息编辑框不可用 GetDlgItem(IDC_EDIT_Input)->EnableWindow(FALSE); //未登陆之前, 接收者编辑框不可用 GetDlgItem(IDC_EDIT_Recver)->EnableWindow(FALSE); //未登陆之前, 用户列表不可用 GetDlgItem(IDC_LIST_UserList)->EnableWindow(FALSE); } /***************************************************************************************************************************************/ // ClientSocket.cpp : implementation file // #include "stdafx.h" #include "Client.h" #include "ClientSocket.h" #include "ClientDlg.h" #include "../Content/UserType.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CClientSocket CClientSocket::CClientSocket() { } CClientSocket::~CClientSocket() { } // Do not edit the following lines, which are needed by ClassWizard. #if 0 BEGIN_MESSAGE_MAP(CClientSocket, CSocket) //{{AFX_MSG_MAP(CClientSocket) //}}AFX_MSG_MAP END_MESSAGE_MAP() #endif // 0 ///////////////////////////////////////////////////////////////////////////// // CClientSocket member functions void CClientSocket::OnReceive(int nErrorCode) { NET_PACK *pPack = new NET_PACK; Receive(pPack, sizeof(NET_PACK)); //获取主对话框的地址 CClientDlg *pDlg = (CClientDlg *)AfxGetApp()->m_pMainWnd; pDlg->PostMessage(UD_NETPACK, (WPARAM)pPack, NULL); CSocket::OnReceive(nErrorCode); } /***********************************************************************************************************************************/ #ifndef _USER_TYPE_ #define _USER_TYPE_ //功能号 typedef enum{LOGIN = 1, LOGOUT, LOGERR, LOGOK, TRANSMIT, SRVSTOP, SENDUSERLIST}FUN; //定义数据包 typedef struct { FUN fun; char SenderID[32]; char ReceiveID[32]; char Content[1024]; }NET_PACK;
标签:
原文地址:http://blog.csdn.net/qq_20938879/article/details/51035888