⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chatroomdlg.cpp

📁 使用VC++编写的基于WinSock的聊天室程序
💻 CPP
字号:
// ChatRoomDlg.cpp : implementation file
//

#include "stdafx.h"
#include "ChatRoom.h"
#include "ChatRoomDlg.h"

#include "winsock.h"	//Winsock API函数必须包含的头文件

#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()

/////////////////////////////////////////////////////////////////////////////
// CChatRoomDlg dialog

CChatRoomDlg::CChatRoomDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CChatRoomDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CChatRoomDlg)
	m_uPort = 6000;
	m_sShowText = _T("");
	m_sInputText = _T("");
	m_Type = 0;
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CChatRoomDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CChatRoomDlg)
	DDX_Control(pDX, IDC_IPADDRESS1, m_ServerIp);
	DDX_Text(pDX, IDC_EDIT_PORT, m_uPort);
	DDX_LBString(pDX, IDC_LIST_SHOWTEXT, m_sShowText);
	DDX_Text(pDX, IDC_EDIT_INPUTDATA, m_sInputText);
	DDX_Radio(pDX, IDC_SERVER, m_Type);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CChatRoomDlg, CDialog)
	//{{AFX_MSG_MAP(CChatRoomDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDSEND, OnSend)
	ON_BN_CLICKED(IDCONNECTED, OnConnected)
	ON_BN_CLICKED(IDC_SERVER, OnServer)
	ON_BN_CLICKED(IDC_CLIENT, OnClient)
	ON_MESSAGE(SER_MESSAGE,OnServerMessage)
	ON_MESSAGE(CLI_MESSAGE,OnClientMessage)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CChatRoomDlg message handlers

BOOL CChatRoomDlg::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
	WSADATA wsaData;
	WORD version = MAKEWORD(2, 0);				//Winsock规范版本在2.0以上
	int ret = WSAStartup(version, &wsaData);
	if(ret != 0)
	{
		TRACE("Initilize Error!\n");  //初始化失败
		AfxMessageBox("Failed in initial socket");
	}
	
	m_ServerIp.EnableWindow(false);	
	(AfxGetMainWnd())->SetWindowText("服务器");

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

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

void CChatRoomDlg::OnSend() 
{
	// TODO: Add your control notification handler code here
	// TODO: Add your control notification handler code here
	if(!m_bInit)
	{
		AfxMessageBox("The session has not been set correctly");
		return;
	}
	CString in;
	GetDlgItem(IDC_EDIT_INPUTDATA)->GetWindowText(in);
	//输入框中只有回车键被按下,所以不发送回车键字符
	if(in.GetLength()<1)
	{
		return;
	}

//	if(in.GetAt(in.GetLength()-1)=='\n')
//	{
		//in.TrimRight(" ")用来消去无用的空格键字符
		in.TrimRight(" ");
		//将输入框中的字符清空,表示字符已经被发送
		GetDlgItem(IDC_EDIT_INPUTDATA)->SetWindowText("");
		if(in.GetLength()>2)
		{
			m_sShowText+=in;
			//将输入的话显示到显示窗口中
			GetDlgItem(IDC_LIST_SHOWTEXT)->SetWindowText(m_sShowText);		
			CEdit * output=(CEdit *)GetDlgItem(IDC_LIST_SHOWTEXT);
			//随时跟踪滚动条的位置
			output->LineScroll(output->GetLineCount());

			//服务器端
			if(!m_bClient)
			{
				int length=m_connectionList.GetCount();
				SOCKET  socket;
				for(int i=0;i<length;i++)
				{
					socket=m_connectionList.GetAt(m_connectionList.FindIndex(i));
					send(socket,in.GetBuffer(0),in.GetLength(),0);
				}
			}
			//客户端
			else
			{
				m_client.SendString(in);
			}
		}

	
}




void CChatRoomDlg::OnConnected() 
{
	// TODO: Add your control notification handler code here
	
	if (!m_Type)  //服务器:启动服务器
	{
		if(m_server.InitAndListen(this->m_hWnd,m_uPort)==FALSE)
		{
			return;
		}
		else
		{
			m_bInit=TRUE;
			m_bClient=FALSE;
			m_sShowText="Server has been set ok!\n";
			GetDlgItem(IDC_LIST_SHOWTEXT)->SetWindowText(m_sShowText);
		}
	}
	else          //客户机:连接服务器
	{
		BYTE  f0,f1,f2,f3;
		m_ServerIp.GetAddress(f0,f1,f2,f3);
		CString add;
		add.Format("%d.%d.%d.%d",f0,f1,f2,f3);
		//客户端连接初始化
		if(m_client.InitAndConnet(m_hWnd,m_uPort,add)==FALSE)
			return;	
	}

}

void CChatRoomDlg::OnServer() 
{
	// TODO: Add your control notification handler code here
	m_Type=0;
	m_ServerIp.EnableWindow(false);
	GetDlgItem(IDCONNECTED)->SetWindowText("启动服务器");
	(AfxGetMainWnd())->SetWindowText("服务器");		
}

void CChatRoomDlg::OnClient() 
{
	// TODO: Add your control notification handler code here
	m_Type=1;
	m_ServerIp.EnableWindow(true);
	GetDlgItem(IDCONNECTED)->SetWindowText("连接服务器");
	(AfxGetMainWnd())->SetWindowText("客户机");		
}


/////////////////////////////////////////////////////////////////
//Server消息相应函数
LRESULT CChatRoomDlg::OnServerMessage(WPARAM wParam, LPARAM lParam)
{

	SOCKET socket,ts;
	int length,i,j;
	CString str="";
	CEdit * output=NULL;
	char s[1024];
	int len;
	switch(lParam)
	{
		case FD_ACCEPT:
			socket= accept(m_server.m_hSocket,NULL,NULL);
			length=m_connectionList.GetCount();
			for(i=0;i<length;i++)
			{
				ts=m_connectionList.GetAt(m_connectionList.FindIndex(i));
				s[0]=NULL;
				strcat(s,"一个游客进入了聊天室");
				send(ts,s,strlen(s),0);
			}
			m_sShowText+="\n";
			m_sShowText+="一个游客进入了聊天室了";
			GetDlgItem(IDC_LIST_SHOWTEXT)->SetWindowText(m_sShowText);
			output=(CEdit *)GetDlgItem(IDC_LIST_SHOWTEXT);
			//随时跟踪滚动条的位置
			output->LineScroll(output->GetLineCount());
			m_connectionList.AddHead(socket);
			return 0;

		case FD_READ:
			length=m_connectionList.GetCount();
			for(i=0;i<length;i++)
			{
				socket=m_connectionList.GetAt(m_connectionList.FindIndex(i));
				if(socket==wParam)
				{
					len=recv(socket,s,1024,0);
					s[len]=NULL;
					//将一个客户端发送的消息传递到其他客户端去
					for(j=0;j<length;j++)
					{
						socket=m_connectionList.GetAt(m_connectionList.FindIndex(j));
						if(socket!=wParam)
						{
							send(socket,s,strlen(s),0);
						}
					}
					m_sShowText=m_sShowText+s;
					GetDlgItem(IDC_LIST_SHOWTEXT)->SetWindowText(m_sShowText);
					CEdit * output=(CEdit *)GetDlgItem(IDC_LIST_SHOWTEXT);
					//随时跟踪滚动条的位置
					output->LineScroll(output->GetLineCount());
					return 0;
				}
			}
			return 0;

		case FD_WRITE:
			return 0;

		case FD_CLOSE:
			return 0;

		default:
			m_sShowText=m_sShowText+"An networking error has occured with a client";
			GetDlgItem(IDC_LIST_SHOWTEXT)->SetWindowText(m_sShowText);
			CEdit * output=(CEdit *)GetDlgItem(IDC_LIST_SHOWTEXT);
			//随时跟踪滚动条的位置
			output->LineScroll(output->GetLineCount());
			return 0;
	}
}

LRESULT CChatRoomDlg::OnClientMessage(WPARAM wParam, LPARAM lParam)
{
	CEdit * output=NULL;
	char s[1024];
	int len;
	switch(lParam)
	{
		case FD_CONNECT:
			len=GetLastError();
			if(len!=0)
			{
				AfxMessageBox("Error in Connecting");
			}
			else
			{
				m_bInit=TRUE;
				m_bClient=TRUE;
				m_sShowText="Having connected to server!\n";
				GetDlgItem(IDC_LIST_SHOWTEXT)->SetWindowText(m_sShowText);
			}
			return 0;
		case FD_READ:
			len=recv(m_client.m_hSocket,s,1024,0);
			s[len]=NULL;
			m_sShowText+=s;
			//随时跟踪滚动条的位置 
			output=(CEdit *)GetDlgItem(IDC_LIST_SHOWTEXT);
			output->SetWindowText(m_sShowText);
			output->LineScroll(output->GetLineCount());
			return 0;
		case FD_WRITE:
			return 0;
		case FD_CLOSE:
			return 0;
		default:
			output=(CEdit *)GetDlgItem(IDC_LIST_SHOWTEXT);
			output->SetWindowText("An network error has occured,the connection is dropped");
			closesocket(m_client.m_hSocket);
			m_bInit=false;
			return 0;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -