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

📄 clientdlg.cpp

📁 信使小精灵,是一个简易的聊天工具。主要是演示了网络编程的主要步骤。本程序使用封装好的函数库
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// ClientDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Client.h"
#include "ClientDlg.h"

#include <transport.h>
#include <protocolhdr.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
#define DISCONNECT_TIMER	(WM_USER + 101)
#define LOGINFAILED_TIMER	(WM_USER + 102)
/////////////////////////////////////////////////////////////////////////////
static void HandleClientNetEvent(IN SOCKET hSocket, IN ETransportEvent eEvent, 
							  IN void *pDataBuf, IN unsigned long nDataLen, 
							  IN int nError, IN void *pContext)
{
	if( nError != TRANSPORT_OK ) return;

	CClientDlg *pDlg = (CClientDlg *)pContext;
	if( NULL == pDlg ) return;

	pDlg->ProcessNetEvent(eEvent, pDataBuf, nDataLen);
}
/////////////////////////////////////////////////////////////////////////////
// CClientDlg dialog

CClientDlg::CClientDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CClientDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CClientDlg)
	m_strServerAddress = _T("");
	m_strChatMessage = _T("");
	m_strUserName = _T("");
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CClientDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CClientDlg)
	DDX_Control(pDX, IDC_CMB_USERNAME, m_cmbUserName);
	DDX_Control(pDX, IDC_CHAT_MESSAGE, m_editChatMessage);
	DDX_Control(pDX, IDC_CMB_CHATMESSAGE, m_cmbChatMessage);
	DDX_Control(pDX, IDC_MESSGAE_LIST, m_ctrlUserList);
	DDX_Control(pDX, IDC_CMB_SERVERADDRESS, m_cmbServerAddress);
	DDX_CBString(pDX, IDC_CMB_SERVERADDRESS, m_strServerAddress);
	DDV_MaxChars(pDX, m_strServerAddress, 16);
	DDX_CBString(pDX, IDC_CMB_CHATMESSAGE, m_strChatMessage);
	DDV_MaxChars(pDX, m_strChatMessage, 256);
	DDX_CBString(pDX, IDC_CMB_USERNAME, m_strUserName);
	DDV_MaxChars(pDX, m_strUserName, 30);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CClientDlg, CDialog)
	//{{AFX_MSG_MAP(CClientDlg)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_CONNECT, OnConnect)
	ON_BN_CLICKED(IDC_DISCONNECT, OnDisconnect)
	ON_WM_TIMER()
	ON_BN_CLICKED(IDC_SEND, OnSend)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CClientDlg message handlers

BOOL CClientDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// 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
	int nResult = Transport_Init();
	if( TRANSPORT_OK != nResult)
	{
		PostMessage(WM_CLOSE);
	}

	///////////////////////////////////////////////
	SetConnectionID(INVALID_SOCKET);
	///////////////////////////////////////////////
	
	/*Get Local Address*/
	const int nIpAddressLen = MAX_IPADDRESS_LEN;
	const int nHostNameLen = MAX_HOSTNAME_LEN;
	char pIpAddress[nIpAddressLen] = {0};
	char pHostName[nHostNameLen] = {0};
	unsigned long ulIpAddress = m_tClientTunnel.net_GetLocalHostIp(pIpAddress, nIpAddressLen, pHostName, nHostNameLen);
	if( ulIpAddress != SOCKET_ERROR )
	{
		CString strIpAddress = (CString)pIpAddress;
		m_cmbServerAddress.InsertString(0, strIpAddress);
		m_cmbServerAddress.SetCurSel(0);

		CString strUserName = (CString)pHostName;
		m_cmbUserName.InsertString(0, strUserName);
		m_cmbUserName.SetCurSel(0);
	}
	
	GetDlgItem(IDC_CONNECT)->EnableWindow(TRUE);
	GetDlgItem(IDC_DISCONNECT)->EnableWindow(FALSE);
	m_ctrlUserList.EnableWindow(FALSE);

	if(::IsWindow(m_editChatMessage.GetSafeHwnd()))
	{
		COLORREF clrBk = RGB(160, 180, 220);
		m_editChatMessage.SetBackgroundColor(FALSE, clrBk);
	}
	
	CString strWindowText = (CString)WINDOW_TITLE;
	SetWindowText(strWindowText);
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

// 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::ShowMessageText(const char *szMessageText)
{
	CString strLogInfo = (CString)szMessageText;
	if( strLogInfo.IsEmpty() ) return;

	HWND hWnd = m_editChatMessage.GetSafeHwnd();
	if( (NULL == hWnd) || (!::IsWindow(hWnd)) ) return;

	COLORREF clrText = RGB(0, 0, 0);
	int nType = -1;
	
	switch(nType)
	{
	case MB_OK:		//操作记录
		{
			clrText = RGB(128, 0, 255);			
			
			break;
		}
	case MB_ICONINFORMATION:	//提示信息
		{
			clrText = RGB(0, 0, 128);
			
			break;
		}	
	case MB_ICONEXCLAMATION:	//警告信息
		{
			clrText = RGB(255, 0, 0);
			
			break;
		}
	default:
		{
			clrText = RGB(0, 0, 0);
			
			break;
		}
	}

	m_editChatMessage.AppendText(strLogInfo, clrText);
}
////////////////////////////////////////////////////////////////////
void CClientDlg::ProcessNetEvent(int nEventType, void *pRecvMsg, DWORD dwDataLen)
{
	if( Transport_ReadEv == nEventType )
	{
		if( NULL == pRecvMsg ) return;

		TMessageHeader* pHeader = (TMessageHeader *)pRecvMsg;
		char *pDataBuf = (char *)pRecvMsg + MESSAGE_HEADER_LEN;

		WORD dwMessageID = pHeader->wMessageId;
		switch(dwMessageID)
		{
		case MSG_LOGIN_RESP:
			{
				LOGIN_RESULT_STRU tLoginResult = {0};
				memcpy(&tLoginResult, pDataBuf, sizeof(LOGIN_RESULT_STRU));
				
				ProcessLoginResponse(&tLoginResult);	

				break;
			}

		case MSG_USERINFO_RESP:
			{
				TUSERLIST_INFO_STRU tUserListInfo = {0};
				memcpy(&tUserListInfo, pDataBuf, sizeof(TUSERLIST_INFO_STRU));

				ProcessUserListInfoResponse(&tUserListInfo);

				break;
			}

		case MSG_LOGOUT_RESP:
			{
				TUSERLIST_INFO_STRU tUserListInfo = {0};
				memcpy(&tUserListInfo, pDataBuf, sizeof(TUSERLIST_INFO_STRU));

				ProcessLogoutResponse(&tUserListInfo);

				break;
			}

		case MSG_CHATMESSAGE_RESP:
			{
				TCHAT_MESSAGE_STRU *pChatMessage = (TCHAT_MESSAGE_STRU *)pDataBuf;
				
				ProcessChatMessageResponse((void *)pChatMessage);				

				break;
			}

		default:
			{
				break;
			}
		}
	}
	else if( Transport_CloseEv == nEventType )
	{
		SetTimer(DISCONNECT_TIMER, 0, NULL);
	}
	///////
}

void CClientDlg::OnOK() 
{
	// TODO: Add extra validation here
	CWnd *pFocusWnd = GetFocus();
	if( NULL == pFocusWnd ) return;

	CEdit *pEditWnd = (CEdit *)m_cmbChatMessage.GetWindow(GW_CHILD);
	if( NULL != pEditWnd )
	{
		if( pFocusWnd->m_hWnd == pEditWnd->m_hWnd )
		{			
			OnSend();

			return;
		}
	}

	return;
	pEditWnd = (CEdit *)m_cmbServerAddress.GetWindow(GW_CHILD);
	if( NULL != pEditWnd )
	{
		if( pFocusWnd->m_hWnd == pEditWnd->m_hWnd )
		{
			OnConnect();

			return;
		}
	}

	pEditWnd = (CEdit *)m_cmbUserName.GetWindow(GW_CHILD);
	if( NULL != pEditWnd )
	{
		if( pFocusWnd->m_hWnd == pEditWnd->m_hWnd )
		{
			OnConnect();

			return;
		}
	}

	return;

	CDialog::OnOK();
}

void CClientDlg::OnCancel() 
{
	// TODO: Add extra cleanup here
	if( INVALID_SOCKET != GetConnectionID() ) 
	{
		int nResult = MessageBox("你真的要退出吗?", "请确认退出", MB_YESNO|MB_ICONQUESTION);
		if( IDYES != nResult ) return;
	}

	OnDisconnect();

	Transport_UnInit();
	
	CDialog::OnCancel();
}

void CClientDlg::OnConnect() 
{
	// TODO: Add your control notification handler code here
	CWaitCursor wait;

	if( !UpdateData() ) return;

	CString strServerAddress = m_strServerAddress;
	strServerAddress.TrimLeft();
	strServerAddress.TrimRight();
	if( strServerAddress.IsEmpty() )
	{
		ShowMessageText("请填写服务器地址!");

		return;
	}

	CString strUserName = m_strUserName;
	strUserName.TrimLeft();
	strUserName.TrimRight();
	if( strUserName.IsEmpty() )
	{

⌨️ 快捷键说明

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