多人在线的网络聊天室(VC++)

 

 

 

 

 

 

 

              多人在线的网络聊天室
  服务器端程序:
  从CSocket派生CClientSocket类,用于实现对客户端消息的转发。
  CClientSocket类的头文件以及实现文件如下:
  CClientSocket类头文件:(.h文件)
class  CClientSocketList;
class CClientSocket : public CSocket
{
// Attributes
public:
    CClientSocketList*  List;
    CClientSocket*  Front;
 CClientSocket*  Next;
// Operations
public:
 CClientSocket(CClientSocketList*);
 virtual ~CClientSocket();

// Overrides
public:
 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CClientSocket)
 public:
 virtual void OnReceive(int nErrorCode);
 virtual void OnClose(int nErrorCode);
 //}}AFX_VIRTUAL

 // Generated message map functions
 //{{AFX_MSG(CClientSocket)
  // NOTE - the ClassWizard will add and remove member functions here.
 //}}AFX_MSG

// Implementation
protected:

};


CClientSocket类CPP文件:
#include  "ClientSocketList.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// CClientSocket

CClientSocket::CClientSocket(CClientSocketList*  tmp)
{
 Front=0;
 Next=0;
 List=tmp;
}

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)
{
 // TODO: Add your specialized code here and/or call the base class
    List->Sends(this);   //调用CClientSocketList类的Sends函数
 //向每一个客户端发送消息

 CSocket::OnReceive(nErrorCode);
}

void CClientSocket::OnClose(int nErrorCode)
{
 // TODO: Add your specialized code here and/or call the base class

 CSocket::OnClose(nErrorCode);
}


其中用到一个CClientSocketList类,为一个Generic  Class类,代表客户端Socket列表。它是一个自定义类。我们将在下面实现它。
  CClientSocketList类头文件如下:
  #include   "ClientSocket.h"
 
class CClientSocketList 
{
public:
 BOOL Add(CClientSocket*);
 BOOL Sends(CClientSocket*);
 CClientSocket*  Head;
 CClientSocketList();
 virtual ~CClientSocketList();

};

CClientSocketList类的CPP文件如下:
  #include "stdafx.h"
#include "ChatRoomServer.h"
#include "ClientSocketList.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//
// Construction/Destruction
//

CClientSocketList::CClientSocketList()
{
 Head=0;
}

CClientSocketList::~CClientSocketList()
{

}

BOOL CClientSocketList::Sends(CClientSocket *tmp)
{
 char   buff[1000];
 int  n;
 CClientSocket*  curr=Head;
 n=tmp->Receive(buff,1000);
 buff[n]=0;
 while(curr)
 {
  curr->Send(buff,n);
  curr=curr->Next;
 }
 return   true;
}

BOOL CClientSocketList::Add(CClientSocket *add)
{
 CClientSocket*   tmp=Head;
    if(!Head)
 {
  Head=add;
  return  true;
 }
 while(tmp->Next)    tmp=tmp->Next;
 tmp->Next=add;
 return   true;
}

这还只是完成了客户端的Socket类,我们还要创建一个服务器的侦听Socket类。我们称之为CListenSocket类。
  同样,我们将从CSocket派生它。
  CListenSocket类头文件:
  #include  "ClientSocketList.h"

/
// CListenSocket command target

class CListenSocket : public CSocket
{
// Attributes
public:

// Operations
public:
 CClientSocketList   CCSL;
 CListenSocket();
 virtual ~CListenSocket();

// Overrides
public:
 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CListenSocket)
 public:
 virtual void OnAccept(int nErrorCode);
 //}}AFX_VIRTUAL

 // Generated message map functions
 //{{AFX_MSG(CListenSocket)
  // NOTE - the ClassWizard will add and remove member functions here.
 //}}AFX_MSG

// Implementation
protected:
};


CListenSocket类CPP文件:
  #include "stdafx.h"
#include "ChatRoomServer.h"
#include "ListenSocket.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)
{
 // TODO: Add your specialized code here and/or call the base class
 CClientSocket*  tmp=new   CClientSocket(&CCSL);
    Accept(*tmp);
 CCSL.Add(tmp);
 CSocket::OnAccept(nErrorCode);
}


所有工程中需要的类都被完成以后。我们开始完成主窗体的代码。
  为启动服务,停止服务,退出窗口三个按钮添加消息响应函数。
  CChatRoomServerDlg类的头文件完成后如下:
  #include   "ListenSocket.h"
#include   "ClientSocketList.h"

class CChatRoomServerDlg : public CDialog
{
// Construction
public:
 CChatRoomServerDlg(CWnd* pParent = NULL); // standard constructor
    CListenSocket   ListenSocket;

// Dialog Data
 //{{AFX_DATA(CChatRoomServerDlg)
 enum { IDD = IDD_CHATROOMSERVER_DIALOG };
 CButton m_IDC_BTN_STOP;
 CButton m_IDC_BTN_START;
 //}}AFX_DATA

 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CChatRoomServerDlg)
 protected:
 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
 //}}AFX_VIRTUAL

// Implementation
protected:
 HICON m_hIcon;

 // Generated message map functions
 //{{AFX_MSG(CChatRoomServerDlg)
 virtual BOOL OnInitDialog();
 afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
 afx_msg void OnPaint();
 afx_msg HCURSOR OnQueryDragIcon();
 afx_msg void OnButtonStart();
 afx_msg void OnButtonStop();
 //}}AFX_MSG
 DECLARE_MESSAGE_MAP()
};


我们将要实现它。
CChatRoomServerDlg类的CPP文件如下:
  #include "stdafx.h"
#include "ChatRoomServer.h"
#include "ChatRoomServerDlg.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()

/
// CChatRoomServerDlg dialog

CChatRoomServerDlg::CChatRoomServerDlg(CWnd* pParent )
 : CDialog(CChatRoomServerDlg::IDD, pParent)
{
 //{{AFX_DATA_INIT(CChatRoomServerDlg)
  // NOTE: the ClassWizard will add member initialization here
 //}}AFX_DATA_INIT
 // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CChatRoomServerDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
 //{{AFX_DATA_MAP(CChatRoomServerDlg)
 DDX_Control(pDX, IDC_BUTTON_STOP, m_IDC_BTN_STOP);
 DDX_Control(pDX, IDC_BUTTON_START, m_IDC_BTN_START);
 //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CChatRoomServerDlg, CDialog)
 //{{AFX_MSG_MAP(CChatRoomServerDlg)
 ON_WM_SYSCOMMAND()
 ON_WM_PAINT()
 ON_WM_QUERYDRAGICON()
 ON_BN_CLICKED(IDC_BUTTON_START, OnButtonStart)
 ON_BN_CLICKED(IDC_BUTTON_STOP, OnButtonStop)
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CChatRoomServerDlg message handlers

BOOL CChatRoomServerDlg::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
 m_IDC_BTN_STOP.EnableWindow(FALSE);

 return TRUE;  // return TRUE  unless you set the focus to a control
}

void CChatRoomServerDlg::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 CChatRoomServerDlg::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 CChatRoomServerDlg::OnQueryDragIcon()
{
 return (HCURSOR) m_hIcon;
}

void CChatRoomServerDlg::OnButtonStart()
{
 // TODO: Add your control notification handler code here
 m_IDC_BTN_START.EnableWindow(FALSE);
 ListenSocket.Create(4848);
 ListenSocket.Listen();
 m_IDC_BTN_STOP.EnableWindow(TRUE);
}

void CChatRoomServerDlg::OnButtonStop()
{
 // TODO: Add your control notification handler code here
 m_IDC_BTN_STOP.EnableWindow(FALSE);
 ListenSocket.Close();
 m_IDC_BTN_START.EnableWindow(TRUE);
}


至此服务器端代码全部完成,我们将接下来再接再厉,完成客户端代码。
  客户端代码:
  从CSocket派生一个CServerSocket类,用以接收和转发服务器的消息。
  CServerSocket类的头文件和CPP文件如下:
  CServerSocket.h文件:
  class   CChatRoomClientDlg;
class CServerSocket : public CSocket
{
// Attributes
public:
    CChatRoomClientDlg*  myDlg;
    CString   NikeName;
// Operations
public:
 CServerSocket();
 virtual ~CServerSocket();

// Overrides
public:
 BOOL SetDlg(CChatRoomClientDlg*  tmp);
 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CServerSocket)
 public:
 virtual void OnReceive(int nErrorCode);
 //}}AFX_VIRTUAL

 // Generated message map functions
 //{{AFX_MSG(CServerSocket)
  // NOTE - the ClassWizard will add and remove member functions here.
 //}}AFX_MSG

// Implementation
protected:
};


CServerSocket类的CPP文件如下:
  #include "stdafx.h"
#include "ChatRoomClient.h"
#include "ServerSocket.h"
#include  "ChatRoomClientDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// CServerSocket

CServerSocket::CServerSocket()
{
 NikeName="";
    myDlg=0;
}


CServerSocket::~CServerSocket()
{
}


// Do not edit the following lines, which are needed by ClassWizard.
#if 0
BEGIN_MESSAGE_MAP(CServerSocket, CSocket)
 //{{AFX_MSG_MAP(CServerSocket)
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif // 0

/
// CServerSocket member functions

BOOL CServerSocket::SetDlg(CChatRoomClientDlg *tmp)
{
     myDlg=tmp;
  return  TRUE;
}


void CServerSocket::OnReceive(int nErrorCode)
{
 // TODO: Add your specialized code here and/or call the base class
 myDlg->GetMessage();
 CSocket::OnReceive(nErrorCode);
}


在启动客户端的程序时,我们将会预先弹出一个连接窗口以获取服务器的IP和用户的昵称。
  于是我们想到工程中添加一个对话框资源,为该对话框资源关联一个类。
  CConnectedDlg类:
  CConnectedDlg类的头文件如下:
  #include   "ServerSocket.h"
 
/
// CConnectedDlg dialog

class CConnectedDlg : public CDialog
{
// Construction
public:
 CConnectedDlg(CServerSocket*  tmp,CWnd* pParent = NULL);   // standard constructor
    CServerSocket*   myServerSocket;
   
// Dialog Data
 //{{AFX_DATA(CConnectedDlg)
 enum { IDD = IDD_DIALOG_CONNECTDLG };
 CString m_IDC_EDIT_ADDRESS;
 CString m_IDC_EDIT_NIKNAME;
 //}}AFX_DATA


// Overrides
 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CConnectedDlg)
 protected:
 virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
 //}}AFX_VIRTUAL

// Implementation
protected:

 // Generated message map functions
 //{{AFX_MSG(CConnectedDlg)
  // NOTE: the ClassWizard will add member functions here
 virtual   void   OnOK();
 //}}AFX_MSG
 DECLARE_MESSAGE_MAP()
};


CConnectedDlg类的CPP文件如下所示:
  #include "stdafx.h"
#include "ChatRoomClient.h"
#include "ConnectedDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/
// CConnectedDlg dialog


CConnectedDlg::CConnectedDlg(CServerSocket*  tmp,CWnd* pParent )
 : CDialog(CConnectedDlg::IDD, pParent)
{
 //{{AFX_DATA_INIT(CConnectedDlg)
 m_IDC_EDIT_ADDRESS = _T("");
 m_IDC_EDIT_NIKNAME = _T("");
 //}}AFX_DATA_INIT
 myServerSocket=tmp;
}


void CConnectedDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
 //{{AFX_DATA_MAP(CConnectedDlg)
 DDX_Text(pDX, IDC_EDIT_ADDRESS, m_IDC_EDIT_ADDRESS);
 DDX_Text(pDX, IDC_EDIT_NIKNAME, m_IDC_EDIT_NIKNAME);
 //}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CConnectedDlg, CDialog)
 //{{AFX_MSG_MAP(CConnectedDlg)
  // NOTE: the ClassWizard will add message map macros here
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CConnectedDlg message handlers


void   CConnectedDlg::OnOK()
{
 UpdateData(TRUE);
 char * address;
 int  n;
    if(!myServerSocket->Create())
 {
  myServerSocket->Close();
  AfxMessageBox("Socket创建错误!!");
  return;
 }
 n=m_IDC_EDIT_ADDRESS.GetLength();
 address=new  char[n+1];
 sprintf(address,"%s",m_IDC_EDIT_ADDRESS.GetBuffer(n));
 address[n]=0;
 if(!myServerSocket->Connect(address,4848))
 {
  myServerSocket->Close();
  AfxMessageBox("网络连接错误,请重新检查服务器地址填写是否正确!");
  return;
 }

 myServerSocket->NikeName=m_IDC_EDIT_NIKNAME;
 CDialog::OnOK();
}

 

然后我们重写对话框中按钮的消息响应函数:
  代码如下:
  CChatRoomClient类的头文件:
  #include  "ServerSocket.h"

class CChatRoomClientDlg : public CDialog
{
// Construction
public:
 BOOL GetMessage();
 CChatRoomClientDlg(CServerSocket*,CWnd* pParent = NULL); // standard constructor
    CServerSocket*   myServerSocket;

// Dialog Data
 //{{AFX_DATA(CChatRoomClientDlg)
 enum { IDD = IDD_CHATROOMCLIENT_DIALOG };
 CListBox m_IDC_LIST_CHAT;
 CString m_IDC_EDIT_MESSAGE;
 //}}AFX_DATA

 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CChatRoomClientDlg)
 protected:
 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
 //}}AFX_VIRTUAL

// Implementation
protected:
 HICON m_hIcon;

 // Generated message map functions
 //{{AFX_MSG(CChatRoomClientDlg)
 virtual BOOL OnInitDialog();
 afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
 afx_msg void OnPaint();
 afx_msg HCURSOR OnQueryDragIcon();
 afx_msg void OnButtonSend();
 //}}AFX_MSG
 DECLARE_MESSAGE_MAP()
};


CChatRoomClient类的CPP文件:
  #include "stdafx.h"
#include "ChatRoomClient.h"
#include "ChatRoomClientDlg.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()

/
// CChatRoomClientDlg dialog

CChatRoomClientDlg::CChatRoomClientDlg(CServerSocket  *tmp,CWnd* pParent )
 : CDialog(CChatRoomClientDlg::IDD, pParent)
{
 //{{AFX_DATA_INIT(CChatRoomClientDlg)
 m_IDC_EDIT_MESSAGE = _T("");
 //}}AFX_DATA_INIT
 // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
 myServerSocket=tmp;
}

void CChatRoomClientDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
 //{{AFX_DATA_MAP(CChatRoomClientDlg)
 DDX_Control(pDX, IDC_LIST1, m_IDC_LIST_CHAT);
 DDX_Text(pDX, IDC_EDIT_MESSAGE, m_IDC_EDIT_MESSAGE);
 //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CChatRoomClientDlg, CDialog)
 //{{AFX_MSG_MAP(CChatRoomClientDlg)
 ON_WM_SYSCOMMAND()
 ON_WM_PAINT()
 ON_WM_QUERYDRAGICON()
 ON_BN_CLICKED(IDC_BUTTON_SEND, OnButtonSend)
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CChatRoomClientDlg message handlers

BOOL CChatRoomClientDlg::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
 
 return TRUE;  // return TRUE  unless you set the focus to a control
}

void CChatRoomClientDlg::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 CChatRoomClientDlg::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 CChatRoomClientDlg::OnQueryDragIcon()
{
 return (HCURSOR) m_hIcon;
}

BOOL CChatRoomClientDlg::GetMessage()
{
 char   buffer[1000];
    int    count;
    count=myServerSocket->Receive(buffer,1000);
 buffer[count]=0;
 m_IDC_LIST_CHAT.AddString(buffer);
 return  TRUE;
}

void CChatRoomClientDlg::OnButtonSend()
{
 // TODO: Add your control notification handler code here
 int   n;
 char  message[1000];
 UpdateData(TRUE);
 m_IDC_EDIT_MESSAGE=myServerSocket->NikeName+":"+m_IDC_EDIT_MESSAGE;
 n=m_IDC_EDIT_MESSAGE.GetLength();
 sprintf(message,"%s",m_IDC_EDIT_MESSAGE.GetBuffer(n));
 message[n]=0;
    if(!myServerSocket->Send(message,n+1))
 {
  AfxMessageBox("网络传输错误!");
 }
}


此刻问题还没有完。由于主程序的启动窗体是CChatRoomClientDlg,而我们所需要的启动窗体是CConnectedDlg。所以我们必须在应用程序类CChatRoomClientApp类的InitInstance()函数中进行一些修改,也就是所谓初始化工作。
  代码如下:
  ChatRoomClient类的实现文件,其中包含CChatRoomClientApp::InitInstance();函数。
  其代码如下:
  #include "stdafx.h"
#include "ChatRoomClient.h"
#include "ChatRoomClientDlg.h"
#include "ServerSocket.h"
#include  "ConnectedDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CServerSocket   curSocket;

/
// CChatRoomClientApp

BEGIN_MESSAGE_MAP(CChatRoomClientApp, CWinApp)
 //{{AFX_MSG_MAP(CChatRoomClientApp)
  // NOTE - the ClassWizard will add and remove mapping macros here.
  //    DO NOT EDIT what you see in these blocks of generated code!
 //}}AFX_MSG
 ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()

/
// CChatRoomClientApp construction

CChatRoomClientApp::CChatRoomClientApp()
{
 // TODO: add construction code here,
 // Place all significant initialization in InitInstance
}

/
// The one and only CChatRoomClientApp object

CChatRoomClientApp theApp;

/
// CChatRoomClientApp initialization

BOOL CChatRoomClientApp::InitInstance()
{
 if(!AfxSocketInit())
 {
  AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
  return   FALSE;
 }
 AfxEnableControlContainer();

 // Standard initialization
 // If you are not using these features and wish to reduce the size
 //  of your final executable, you should remove from the following
 //  the specific initialization routines you do not need.

#ifdef _AFXDLL
 Enable3dControls();   // Call this when using MFC in a shared DLL
#else
 Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
    CConnectedDlg  cdlg(&curSocket);
    if(cdlg.DoModal()==IDCANCEL)
  return  FALSE;
 CChatRoomClientDlg dlg(&curSocket);

 m_pMainWnd = &dlg;
 curSocket.SetDlg(&dlg);

 int nResponse = dlg.DoModal();
 if (nResponse == IDOK)
 {
  // TODO: Place code here to handle when the dialog is
  //  dismissed with OK
 }
 else if (nResponse == IDCANCEL)
 {
  // TODO: Place code here to handle when the dialog is
  //  dismissed with Cancel
 }

 // Since the dialog has been closed, return FALSE so that we exit the
 //  application, rather than start the application's message pump.
 return FALSE;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值