实现局域网聊天,涉及到服务器端和用户端,使用MFC编程实现。
- 设计服务器端和用户端界面
- 分别建立两个项目,ChatRoomSever和ChatRoomClient
- ChatRoomSever用于创建Socket并监听和接受信息
- ChatRoomClient用于创建Socket并连接ChatRoomSever
具体流程如下所示:
(1)创建ChatRoomSever项目,MFC->基于对话框
涉及到的控件有:Group-box,StaticText,Button,List Control。List Control添加成员变量:类型为CListCtrl,变量名为m_list。
添加两个类:CClientSocket和CListenSocket,基类都是CSocket
(2)创建ChatRoomClient项目,MFC基于对话框,界面设计如下:
// ChatRoomServer.h : PROJECT_NAME 应用程序的主头文件
//#pragma once#ifndef __AFXWIN_H__#error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件"
#endif#include "resource.h" // 主符号// CChatRoomServerApp:
// 有关此类的实现,请参阅 ChatRoomServer.cpp
//class CChatRoomServerApp : public CWinApp
{
public:CChatRoomServerApp();// 重写
public:virtual BOOL InitInstance();// 实现DECLARE_MESSAGE_MAP()
};extern CChatRoomServerApp theApp;
// ChatRoomClient.cpp : 定义应用程序的类行为。
//#include "stdafx.h"
#include "ChatRoomClient.h"
#include "ChatRoomClientDlg.h"
#include "LoginDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif// CChatRoomClientAppBEGIN_MESSAGE_MAP(CChatRoomClientApp, CWinApp)ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()// CChatRoomClientApp 构造CChatRoomClientApp::CChatRoomClientApp()
{// 支持重新启动管理器m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;// TODO: 在此处添加构造代码,// 将所有重要的初始化放置在 InitInstance 中
}// 唯一的一个 CChatRoomClientApp 对象CChatRoomClientApp theApp;// CChatRoomClientApp 初始化BOOL CChatRoomClientApp::InitInstance()
{// 如果一个运行在 Windows XP 上的应用程序清单指定要// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,//则需要 InitCommonControlsEx()。 否则,将无法创建窗口。INITCOMMONCONTROLSEX InitCtrls;InitCtrls.dwSize = sizeof(InitCtrls);// 将它设置为包括所有要在应用程序中使用的// 公共控件类。InitCtrls.dwICC = ICC_WIN95_CLASSES;InitCommonControlsEx(&InitCtrls);CWinApp::InitInstance();if (!AfxSocketInit()){AfxMessageBox(IDP_SOCKETS_INIT_FAILED);return FALSE;}AfxEnableControlContainer();// 创建 shell 管理器,以防对话框包含// 任何 shell 树视图控件或 shell 列表视图控件。CShellManager *pShellManager = new CShellManager;// 激活“Windows Native”视觉管理器,以便在 MFC 控件中启用主题CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));// 标准初始化// 如果未使用这些功能并希望减小// 最终可执行文件的大小,则应移除下列// 不需要的特定初始化例程// 更改用于存储设置的注册表项// TODO: 应适当修改该字符串,// 例如修改为公司或组织名SetRegistryKey(_T("应用程序向导生成的本地应用程序"));CLoginDlg loginDlg;if (IDCANCEL == loginDlg.DoModal()){return FALSE;}CChatRoomClientDlg dlg;m_pMainWnd = &dlg;INT_PTR nResponse = dlg.DoModal();if (nResponse == IDOK){// TODO: 在此放置处理何时用// “确定”来关闭对话框的代码}else if (nResponse == IDCANCEL){// TODO: 在此放置处理何时用// “取消”来关闭对话框的代码}else if (nResponse == -1){TRACE(traceAppMsg, 0, "警告: 对话框创建失败,应用程序将意外终止。\n");TRACE(traceAppMsg, 0, "警告: 如果您在对话框上使用 MFC 控件,则无法 #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS。\n");}// 删除上面创建的 shell 管理器。if (pShellManager != NULL){delete pShellManager;}// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,// 而不是启动应用程序的消息泵。return FALSE;
}
// ChatRoomServerDlg.h : 头文件
//#pragma once
#include "afxcmn.h"
#include "resource.h"
//#include"ListenSocket.h"
class CListenSocket;
// CChatRoomServerDlg 对话框
class CChatRoomServerDlg : public CDialogEx
{
// 构造
public:CChatRoomServerDlg(CWnd* pParent = NULL); // 标准构造函数// 对话框数据
#ifdef AFX_DESIGN_TIMEenum { IDD = IDD_CHATROOMSERVER_DIALOG };
#endifprotected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持// 实现
protected:HICON m_hIcon;// 生成的消息映射函数virtual BOOL OnInitDialog();afx_msg void OnSysCommand(UINT nID, LPARAM lParam);afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();DECLARE_MESSAGE_MAP()
public:CListCtrl m_list;CListenSocket *m_pListenSocket;afx_msg void OnBnClickedBtnStart();afx_msg void OnBnClickedBtnClaose();
};// ChatRoomServerDlg.cpp : 实现文件
//#include "stdafx.h"
#include "ChatRoomServer.h"
#include "ChatRoomServerDlg.h"
#include "afxdialogex.h"
#include "ListenSocket.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif// 用于应用程序“关于”菜单项的 CAboutDlg 对话框class CAboutDlg : public CDialogEx
{
public:CAboutDlg();// 对话框数据
#ifdef AFX_DESIGN_TIMEenum { IDD = IDD_ABOUTBOX };
#endifprotected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持// 实现
protected:DECLARE_MESSAGE_MAP()
};CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{CDialogEx::DoDataExchange(pDX);
}BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()// CChatRoomServerDlg 对话框CChatRoomServerDlg::CChatRoomServerDlg(CWnd* pParent /*=NULL*/): CDialogEx(IDD_CHATROOMSERVER_DIALOG, pParent)
{m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);m_pListenSocket = NULL;
}void CChatRoomServerDlg::DoDataExchange(CDataExchange* pDX)
{CDialogEx::DoDataExchange(pDX);DDX_Control(pDX, IDC_LIST1, m_list);
}BEGIN_MESSAGE_MAP(CChatRoomServerDlg, CDialogEx)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDC_BTN_START, &CChatRoomServerDlg::OnBnClickedBtnStart)ON_BN_CLICKED(IDC_BTN_CLAOSE, &CChatRoomServerDlg::OnBnClickedBtnClaose)
END_MESSAGE_MAP()// CChatRoomServerDlg 消息处理程序BOOL CChatRoomServerDlg::OnInitDialog()
{CDialogEx::OnInitDialog();// 将“关于...”菜单项添加到系统菜单中。// IDM_ABOUTBOX 必须在系统命令范围内。ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX < 0xF000);CMenu* pSysMenu = GetSystemMenu(FALSE);if (pSysMenu != NULL){BOOL bNameValid;CString strAboutMenu;bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);ASSERT(bNameValid);if (!strAboutMenu.IsEmpty()){pSysMenu->AppendMenu(MF_SEPARATOR);pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);}}// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动// 执行此操作SetIcon(m_hIcon, TRUE); // 设置大图标SetIcon(m_hIcon, FALSE); // 设置小图标ShowWindow(SW_MINIMIZE);m_list.InsertColumn(0, _T("昵称"), LVCFMT_LEFT, 200);m_list.InsertColumn(1, _T("IP地址"), LVCFMT_LEFT, 150);m_list.InsertColumn(2, _T("端口"), LVCFMT_LEFT, 100);// TODO: 在此添加额外的初始化代码return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}void CChatRoomServerDlg::OnSysCommand(UINT nID, LPARAM lParam)
{if ((nID & 0xFFF0) == IDM_ABOUTBOX){CAboutDlg dlgAbout;dlgAbout.DoModal();}else{CDialogEx::OnSysCommand(nID, lParam);}
}// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。void CChatRoomServerDlg::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{CDialogEx::OnPaint();}
}//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CChatRoomServerDlg::OnQueryDragIcon()
{return static_cast<HCURSOR>(m_hIcon);
}//点击开启服务器
void CChatRoomServerDlg::OnBnClickedBtnStart()
{m_pListenSocket = new CListenSocket(this);CString strMsg;if (!m_pListenSocket->Create(9880, SOCK_STREAM)){strMsg.Format(_T("创建套接字失败:%d"), GetLastError());MessageBox(strMsg,_T("提示"));delete m_pListenSocket;m_pListenSocket = NULL;return;}if (!m_pListenSocket->Listen()){strMsg.Format(_T("监听失败:%d"), GetLastError());MessageBox(strMsg, _T("提示"));delete m_pListenSocket;m_pListenSocket = NULL;return;}GetDlgItem(IDC_BTN_START)->EnableWindow(FALSE);GetDlgItem(IDC_BTN_CLAOSE)->EnableWindow(TRUE);
}void CChatRoomServerDlg::OnBnClickedBtnClaose()
{if (m_pListenSocket == NULL)return;m_pListenSocket->Close();delete m_pListenSocket;m_pListenSocket = NULL;GetDlgItem(IDC_BTN_START)->EnableWindow(TRUE);GetDlgItem(IDC_BTN_CLAOSE)->EnableWindow(FALSE);
}
#pragma once
#include "afxsock.h"
class CClientSocket :public CSocket
{
public:CClientSocket();~CClientSocket();virtual void OnReceive(int nErrorCode);
};/
#include "stdafx.h"
#include "ClientSocket.h"extern list<CClientSocket*> g_ClientSocketList;
CClientSocket::CClientSocket()
{
}CClientSocket::~CClientSocket()
{
}void CClientSocket::OnReceive(int nErrorCode)
{// TODO: 在此添加专用代码和/或调用基类char *pRecvBuffer = new char[1024];ZeroMemory(pRecvBuffer, 1024);Receive(pRecvBuffer, 1024);list<CClientSocket*>::iterator it;for (it = g_ClientSocketList.begin(); it != g_ClientSocketList.end(); it++){CClientSocket *pSocket = *it;pSocket->Send(pRecvBuffer, strlen(pRecvBuffer));}delete []pRecvBuffer;CSocket::OnReceive(nErrorCode);
}
#pragma once
#include "afxsock.h"
class CChatRoomServerDlg;
class CClientSocket;
class CListenSocket :public CSocket
{
public:CChatRoomServerDlg* m_pDlg;CListenSocket();CListenSocket(CChatRoomServerDlg* pDlg);~CListenSocket();virtual void OnAccept(int nErrorCode);
};#include "stdafx.h"
#include "ListenSocket.h"
#include "ClientSocket.h"
#include "ChatRoomServerDlg.h"
list<CClientSocket*> g_ClientSocketList;
CListenSocket::CListenSocket()
{}CListenSocket::CListenSocket(CChatRoomServerDlg* pDlg)
{m_pDlg = pDlg;
}CListenSocket::~CListenSocket()
{
}void CListenSocket::OnAccept(int nErrorCode)
{CClientSocket *pSocket = new CClientSocket;Accept(*pSocket);//获取IP地址和端口号、用户名char szUsername[25];ZeroMemory(szUsername, 25);recv(pSocket->m_hSocket, szUsername, 25, 0);CString strIPAddress;UINT nPort;CString strPort;pSocket->GetPeerName(strIPAddress,nPort);strPort.Format(_T("%d"), nPort);//将套接字保存到链表g_ClientSocketList.push_back(pSocket);//将这些信息显示到界面m_pDlg->m_list.InsertItem(0, LPCTSTR(szUsername));m_pDlg->m_list.SetItemText(0, 1, LPCTSTR(strIPAddress));m_pDlg->m_list.SetItemText(0, 2, LPCTSTR(strPort));CSocket::OnAccept(nErrorCode);
}
(4)客户端程序
// ChatRoomClient.h : PROJECT_NAME 应用程序的主头文件
//#pragma once#ifndef __AFXWIN_H__#error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件"
#endif#include "resource.h" // 主符号// CChatRoomClientApp:
// 有关此类的实现,请参阅 ChatRoomClient.cpp
//class CChatRoomClientApp : public CWinApp
{
public:CChatRoomClientApp();CString m_strUsername;// 重写
public:virtual BOOL InitInstance();// 实现DECLARE_MESSAGE_MAP()
};extern CChatRoomClientApp theApp;// ChatRoomClient.cpp : 定义应用程序的类行为。
//#include "stdafx.h"
#include "ChatRoomClient.h"
#include "ChatRoomClientDlg.h"
#include "LoginDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif// CChatRoomClientAppBEGIN_MESSAGE_MAP(CChatRoomClientApp, CWinApp)ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()// CChatRoomClientApp 构造CChatRoomClientApp::CChatRoomClientApp()
{// 支持重新启动管理器m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;// TODO: 在此处添加构造代码,// 将所有重要的初始化放置在 InitInstance 中
}// 唯一的一个 CChatRoomClientApp 对象CChatRoomClientApp theApp;// CChatRoomClientApp 初始化BOOL CChatRoomClientApp::InitInstance()
{// 如果一个运行在 Windows XP 上的应用程序清单指定要// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,//则需要 InitCommonControlsEx()。 否则,将无法创建窗口。INITCOMMONCONTROLSEX InitCtrls;InitCtrls.dwSize = sizeof(InitCtrls);// 将它设置为包括所有要在应用程序中使用的// 公共控件类。InitCtrls.dwICC = ICC_WIN95_CLASSES;InitCommonControlsEx(&InitCtrls);CWinApp::InitInstance();if (!AfxSocketInit()){AfxMessageBox(IDP_SOCKETS_INIT_FAILED);return FALSE;}AfxEnableControlContainer();// 创建 shell 管理器,以防对话框包含// 任何 shell 树视图控件或 shell 列表视图控件。CShellManager *pShellManager = new CShellManager;// 激活“Windows Native”视觉管理器,以便在 MFC 控件中启用主题CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));// 标准初始化// 如果未使用这些功能并希望减小// 最终可执行文件的大小,则应移除下列// 不需要的特定初始化例程// 更改用于存储设置的注册表项// TODO: 应适当修改该字符串,// 例如修改为公司或组织名SetRegistryKey(_T("应用程序向导生成的本地应用程序"));CLoginDlg loginDlg;if (IDCANCEL == loginDlg.DoModal()){return FALSE;}CChatRoomClientDlg dlg;m_pMainWnd = &dlg;INT_PTR nResponse = dlg.DoModal();if (nResponse == IDOK){// TODO: 在此放置处理何时用// “确定”来关闭对话框的代码}else if (nResponse == IDCANCEL){// TODO: 在此放置处理何时用// “取消”来关闭对话框的代码}else if (nResponse == -1){TRACE(traceAppMsg, 0, "警告: 对话框创建失败,应用程序将意外终止。\n");TRACE(traceAppMsg, 0, "警告: 如果您在对话框上使用 MFC 控件,则无法 #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS。\n");}// 删除上面创建的 shell 管理器。if (pShellManager != NULL){delete pShellManager;}// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,// 而不是启动应用程序的消息泵。return FALSE;
}
// ChatRoomClientDlg.h : 头文件
//#pragma once
#include "afxwin.h"// CChatRoomClientDlg 对话框
class CChatRoomClientDlg : public CDialogEx
{
// 构造
public:CChatRoomClientDlg(CWnd* pParent = NULL); // 标准构造函数// 对话框数据
#ifdef AFX_DESIGN_TIMEenum { IDD = IDD_CHATROOMCLIENT_DIALOG };
#endifprotected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持// 实现
protected:HICON m_hIcon;// 生成的消息映射函数virtual BOOL OnInitDialog();afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();DECLARE_MESSAGE_MAP()
public:
// CEdit m_Histedit;
// CEdit m_strSendMsg;afx_msg void OnBnClickedOk();
// CString m_Histedit;CString m_strSendMsg;CEdit m_HistEdit;
};
//// ChatRoomClientDlg.cpp : 实现文件
//#include "stdafx.h"
#include "ChatRoomClient.h"
#include "ChatRoomClientDlg.h"
#include "afxdialogex.h"
#include "ClientSocket.h"#ifdef _DEBUG
#define new DEBUG_NEW
#endif// CChatRoomClientDlg 对话框extern CClientSocket *g_pClientSocket;
CChatRoomClientDlg::CChatRoomClientDlg(CWnd* pParent /*=NULL*/): CDialogEx(IDD_CHATROOMCLIENT_DIALOG, pParent), m_strSendMsg(_T(""))
{m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}void CChatRoomClientDlg::DoDataExchange(CDataExchange* pDX)
{CDialogEx::DoDataExchange(pDX);// DDX_Text(pDX, IDC_EDIT_HISTORY, m_Histedit);DDX_Text(pDX, IDC_EDIT_SEND, m_strSendMsg);DDX_Control(pDX, IDC_EDIT_HISTORY, m_HistEdit);
}BEGIN_MESSAGE_MAP(CChatRoomClientDlg, CDialogEx)ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDOK, &CChatRoomClientDlg::OnBnClickedOk)
END_MESSAGE_MAP()// CChatRoomClientDlg 消息处理程序BOOL CChatRoomClientDlg::OnInitDialog()
{CDialogEx::OnInitDialog();// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动// 执行此操作SetIcon(m_hIcon, TRUE); // 设置大图标SetIcon(m_hIcon, FALSE); // 设置小图标ShowWindow(SW_MINIMIZE);// TODO: 在此添加额外的初始化代码return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。void CChatRoomClientDlg::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{CDialogEx::OnPaint();}
}//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CChatRoomClientDlg::OnQueryDragIcon()
{return static_cast<HCURSOR>(m_hIcon);
}void CChatRoomClientDlg::OnBnClickedOk()
{UpdateData(TRUE);m_strSendMsg = m_strSendMsg.Trim();if (m_strSendMsg.IsEmpty()){MessageBox(_T("不能发送空消息"), _T("提示"));return;}if (m_strSendMsg.GetLength() > 1000){MessageBox(_T("发送消息过长"), _T("提示"));return;}CTime time = CTime::GetCurrentTime();CString strMsg;strMsg.Format(_T("%s\t%s: %s\r\n"), theApp.m_strUsername, time.Format(_T("%Y-%m-%d %H:%M:%S")), m_strSendMsg);g_pClientSocket->Send(strMsg,strMsg.GetLength());
// CDialogEx::OnOK();
}
#pragma once
#include "afxsock.h"
class CClientSocket :public CSocket
{
public:CClientSocket();~CClientSocket();virtual void OnReceive(int nErrorCode);
};//
#include "stdafx.h"
#include "ClientSocket.h"
#include "ChatRoomClientDlg.h"CClientSocket::CClientSocket()
{
}CClientSocket::~CClientSocket()
{
}void CClientSocket::OnReceive(int nErrorCode)
{char *pRecvBuffer = new char[1024];ZeroMemory(pRecvBuffer, 1024);Receive(pRecvBuffer, 1024);//将数据显示到界面CChatRoomClientDlg* pDlg = (CChatRoomClientDlg*) AfxGetMainWnd();int nLength=pDlg->m_HistEdit.GetWindowTextLength();pDlg->m_HistEdit.SetSel(nLength, -1);//设置光标到最后pDlg->m_HistEdit.ReplaceSel(LPCTSTR(pRecvBuffer));//delete[]pRecvBuffer;CSocket::OnReceive(nErrorCode);
}
#pragma once// CLoginDlg 对话框class CLoginDlg : public CDialogEx
{DECLARE_DYNAMIC(CLoginDlg)public:CLoginDlg(CWnd* pParent = NULL); // 标准构造函数virtual ~CLoginDlg();// 对话框数据
#ifdef AFX_DESIGN_TIMEenum { IDD = IDD_LOGIN_DLG };
#endifprotected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持DECLARE_MESSAGE_MAP()
public:afx_msg void OnBnClickedOk();CString m_strUsername;CString m_strPassword;
};// LoginDlg.cpp : 实现文件
//#include "stdafx.h"
#include "ChatRoomClient.h"
#include "LoginDlg.h"
#include "afxdialogex.h"
#include "ClientSocket.h"CClientSocket *g_pClientSocket = NULL;
// CLoginDlg 对话框IMPLEMENT_DYNAMIC(CLoginDlg, CDialogEx)CLoginDlg::CLoginDlg(CWnd* pParent /*=NULL*/): CDialogEx(IDD_LOGIN_DLG, pParent), m_strUsername(_T("zhangsan")), m_strPassword(_T("123456"))
{}CLoginDlg::~CLoginDlg()
{
}void CLoginDlg::DoDataExchange(CDataExchange* pDX)
{CDialogEx::DoDataExchange(pDX);DDX_Text(pDX, IDC_USERNAME, m_strUsername);DDX_Text(pDX, IDC_PASSWORD, m_strPassword);
}BEGIN_MESSAGE_MAP(CLoginDlg, CDialogEx)ON_BN_CLICKED(IDOK, &CLoginDlg::OnBnClickedOk)
END_MESSAGE_MAP()// CLoginDlg 消息处理程序void CLoginDlg::OnBnClickedOk()
{UpdateData(TRUE);if (m_strUsername.IsEmpty() || m_strPassword.IsEmpty()){MessageBox(_T("请输入用户名和密码"), _T("提示"));return;}if (m_strUsername.GetLength() > 10){MessageBox(_T("用户名不能超过10个字符"), _T("提示"));return;}if (m_strPassword != _T("123456")){MessageBox(_T("密码错误"), _T("提示"));return;}theApp.m_strUsername = m_strUsername;//连接服务器CString strMsg;g_pClientSocket = new CClientSocket;if (!g_pClientSocket->Create()){strMsg.Format(_T("创建套接字失败:%d"), GetLastError());MessageBox(strMsg, _T("提示"));delete g_pClientSocket;g_pClientSocket = NULL;return;}if (!g_pClientSocket->Connect(_T("XXXXX"), 9880)){strMsg.Format(_T("连接服务器失败:%d"), GetLastError());MessageBox(strMsg, _T("提示"));delete g_pClientSocket;g_pClientSocket = NULL;return;}//发送用户名信息g_pClientSocket->Send(m_strUsername, m_strUsername.GetLength());EndDialog(TRUE);}