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

📄 talkcdlg.cpp

📁 简单聊天室客户端
💻 CPP
字号:
// TalkCDlg.cpp : implementation file
//

#include "stdafx.h"
#include "TalkC.h"
#include "TalkCDlg.h"

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

CString strIP,strName;
int i=0,j,k;

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	CString	m_strIP;
	CString	m_strName;
	//}}AFX_DATA

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

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	virtual void OnOK();
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	m_strIP = _T("");
	m_strName = _T("");
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	DDX_Text(pDX, IDC_EDIT_IP, m_strIP);
	DDX_Text(pDX, IDC_EDIT_NAME, m_strName);
	DDV_MaxChars(pDX, m_strName, 20);
	//}}AFX_DATA_MAP
}

BOOL CAboutDlg::OnInitDialog()
{
	CDialog::OnInitDialog();
	m_strIP="192.168.2.5";
	UpdateData(FALSE);
	return TRUE;
}

void CAboutDlg::OnOK() 
{
	// TODO: Add extra validation here
	UpdateData();
	if(m_strName.IsEmpty()||m_strIP.IsEmpty()) return;
	strIP=m_strIP;
	strName=m_strName;
	
	CDialog::OnOK();
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTalkCDlg dialog

CTalkCDlg::CTalkCDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CTalkCDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CTalkCDlg)
	m_strMyName = _T("");
	m_strObjectName = _T("");
	m_strTopic = _T("");
	m_bPublic = FALSE;
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	pSock=NULL;

	m_nNoResponseCount = 0;

	HINSTANCE hInst = ::AfxGetInstanceHandle();
	m_hIconShow = (HICON)::LoadImage(hInst, MAKEINTRESOURCE(IDI_ICON_SHOW), IMAGE_ICON, 16, 16, LR_LOADTRANSPARENT);
	m_hIconHide = (HICON)::LoadImage(hInst, MAKEINTRESOURCE(IDI_ICON_HIDE), IMAGE_ICON, 16, 16, LR_LOADTRANSPARENT);
}

void CTalkCDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CTalkCDlg)
	DDX_Control(pDX, IDC_LIST_WORDS, m_listWords);
	DDX_Control(pDX, IDC_LIST_GUEST, m_listGuest);
	DDX_Text(pDX, IDC_STATIC_MYSELF, m_strMyName);
	DDX_Text(pDX, IDC_STATIC_OBJECT, m_strObjectName);
	DDX_Text(pDX, IDC_EDIT_TOPIC, m_strTopic);
	DDX_Check(pDX, IDC_CHECK_PUBLIC, m_bPublic);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CTalkCDlg, CDialog)
	//{{AFX_MSG_MAP(CTalkCDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(ID_SEND, OnTalk)
	ON_LBN_SELCHANGE(IDC_LIST_GUEST, OnGuestSel)
	ON_WM_CLOSE()
	ON_EN_SETFOCUS(IDC_EDIT_TOPIC, OnSetfocusTopic)
	ON_WM_MOVE()
	ON_WM_TIMER()
	ON_LBN_DBLCLK(IDC_LIST_WORDS, OnDblclkListWords)
	ON_BN_CLICKED(IDC_CHK_FLASH_ICON, OnChkFlashIcon)
	//}}AFX_MSG_MAP
	ON_MESSAGE(WM_NETDATA,OnNetReceiveData)
	ON_MESSAGE(WM_NETERROR,OnNetError)
	ON_MESSAGE(WM_NETDELETE,OnNetDelete)

	ON_MESSAGE(WM_CHAT_MSG, OnShellIconMsg)

END_MESSAGE_MAP()

#define g_bUseShell_Icon IsDlgButtonChecked(IDC_CHK_FLASH_ICON)

/////////////////////////////////////////////////////////////////////////////
// CTalkCDlg message handlers

BOOL CTalkCDlg::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_bPublic=TRUE;
	UpdateData(FALSE);

	RECT rcEdit;
	CWnd *pEdit = GetDlgItem(IDC_EDIT_TOPIC);
	pEdit->GetWindowRect(&rcEdit);
	ScreenToClient(&rcEdit);
	pEdit->DestroyWindow();

//	m_hEditTopic = CreateWindowW(L"EDIT", L"", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL,
//		rcEdit.left, rcEdit.top, rcEdit.right - rcEdit.left, rcEdit.bottom - rcEdit.top,
//		m_hWnd, NULL, ::AfxGetInstanceHandle(), NULL);
	m_hEditTopic = CreateWindowExW(WS_EX_CLIENTEDGE, L"EDIT", L"", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL,
		rcEdit.left, rcEdit.top, rcEdit.right - rcEdit.left, rcEdit.bottom - rcEdit.top,
		m_hWnd, NULL, ::AfxGetInstanceHandle(), NULL);

	::SendMessage(m_hEditTopic, WM_SETFONT, (WPARAM)GetFont()->m_hObject, LPARAM(TRUE));

	SetWindowLong(m_hEditTopic, GWL_ID, IDC_EDIT_TOPIC);

	CAboutDlg dlgAbout;
	if(dlgAbout.DoModal()==IDOK)
	{
		pSock=new CTalkCSock(this,strIP);
		GetDlgItem(ID_SEND)->EnableWindow();
		m_strMyName=strName;
		UpdateData(FALSE);
	}
	else OnCancel();

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

void CTalkCDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		if(!pSock)
		{
			CAboutDlg dlgAbout;
			if(dlgAbout.DoModal()==IDOK)
			{
				pSock=new CTalkCSock(this,strIP);
				GetDlgItem(ID_SEND)->EnableWindow();
				m_strMyName=strName;
				UpdateData(FALSE);
			}
		}
		if(m_nNoResponseCount > 0)
		{
			m_nNoResponseCount = 0;
			KillTimer(1001);
		}
	}
	else if(g_bUseShell_Icon && nID == SC_MINIMIZE)
	{
		CDialog::OnSysCommand(nID, lParam);
		ShowWindow(SW_HIDE);
	}
	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 CTalkCDlg::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 CTalkCDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CTalkCDlg::OnTalk() 
{
	// TODO: Add your control notification handler code here
	UpdateData();
	if(m_strTopic.IsEmpty())return;
	if(!m_strObjectName.Compare(_T("所有人")))m_bPublic=TRUE;
	m_strTemp=m_strObjectName+"\n";
	m_strTemp+=m_strMyName;
	m_strTemp+=_T("\n");
	m_strTemp+=m_strTopic;
	pSock->Talk(m_strTemp,m_bPublic);
	UpdateData(FALSE);
	GetDlgItem(IDC_EDIT_TOPIC)->PostMessage(EM_SETSEL,0,-1);
}

void CTalkCDlg::OnNetReceiveData(WPARAM wParam,LPARAM lParam)
{
	switch(wParam)
	{
	case NET_GUEST:
		m_listGuest.AddString(pSock->GetNewGuestName());
		break;
	case NET_DELETE:
		m_listGuest.DeleteString(
			m_listGuest.FindString(-1,pSock->GetBuf()));
		m_strTemp=_T("服务器 : 所有人");
		m_listWords.AddString(m_strTemp);
		m_strTemp.LoadString(IDS_GUESTDELETE);
		m_strTemp=pSock->GetBuf()+m_strTemp;

		m_listWords.AddString(_T("    ")+m_strTemp);

		SetDlgItemText(IDC_STATIC_OBJECT, _T("所有人"));

		break;
	case NET_DATA:
		m_strTemp=pSock->GetSourceName();
		if(!pSock->IsPublic()) m_strTemp+=_T("悄悄地 : ");
		else m_strTemp+=_T(" : ");
		m_strTemp+=pSock->GetObjectName();

		m_listWords.AddString(m_strTemp);

		m_strTemp=_T("    ")+pSock->GetTopic();
		m_listWords.AddString(m_strTemp);

		if(m_listWords.GetCount() > 512)
		{
			m_listWords.DeleteString(0);
		}
		m_listWords.PostMessage(WM_VSCROLL,SB_BOTTOM);
		break;
	case NET_REDAY:
		m_strTemp=pSock->GetBuf();
		k=m_strTemp.GetLength();
		do{
			j=m_strTemp.Find('\n',i);
			if(j==-1)j=k;
			if(!m_strMyName.Compare(m_strTemp.Mid(i,j-i)))
			{
				CString str;
				str.LoadString(IDS_REPEAT_NAME);
				AfxMessageBox(str);
				OnNetDelete(0,0);
				return;
			}
			m_listGuest.AddString(m_strTemp.Mid(i,j-i));

			i=j+1;
		}while(j!=k);
		pSock->Logon(strName);
		m_listGuest.SetCurSel(m_listGuest.FindString(-1,_T("所有人")));
		m_strObjectName=_T("所有人");
		UpdateData(FALSE);
		break;
	}
	NoticeUser(wParam, m_strTemp);

}

void CTalkCDlg::NoticeUser(DWORD dwType, LPCTSTR lpszString)
{
	if(::IsIconic(m_hWnd) || !IsWindowVisible())
	{
		if(IsDlgButtonChecked(IDC_CHECK_POPUP))
		{
			ShowWindow(SW_RESTORE);
			SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
		}
		else
		{
			if(m_nNoResponseCount == 0)
			{
				if(IsDlgButtonChecked(IDC_CHECK_FLASHWND))
				{
					SetTimer(1001, 800, NULL);
				}
			}
			if(IsDlgButtonChecked(IDC_CHECK_AUDIO) && dwType == NET_DATA)
			{
				Beep(80, 100);
			}

			LPCTSTR p = lpszString;
			while(p && *p == ' ') ++p;
			SetWindowText(p);

			++m_nNoResponseCount;
		}
	}
}

void CTalkCDlg::OnGuestSel() 
{
	// TODO: Add your control notification handler code here
	UpdateData();
	TCHAR szString[128] = _T("所有人");
	int nCurSel = m_listGuest.GetCurSel();
	if(nCurSel >= 0)
	{
		m_listGuest.GetText(nCurSel, szString);
	}

	m_strObjectName = szString;
	if(!m_strObjectName.Compare(_T("所有人")))m_bPublic=TRUE;

	SetDlgItemText(IDC_STATIC_OBJECT, szString);
//	UpdateData(FALSE);
}

void CTalkCDlg::OnNetDelete(WPARAM wParam,LPARAM lParam)
{
	delete pSock;
	pSock=NULL;
	GetDlgItem(ID_SEND)->EnableWindow(FALSE);
	m_listGuest.ResetContent( );
}

void CTalkCDlg::OnClose() 
{
	// TODO: Add your message handler code here and/or call default
	if(pSock)
		if(AfxMessageBox(_T("确定要离开?"),MB_OKCANCEL)==IDCANCEL) 
			return;
	if(pSock) delete pSock;
	pSock=NULL;

	CDialog::OnClose();
	SetupShell_Icon(FALSE);
}

void CTalkCDlg::OnNetError(WPARAM wParam,LPARAM lParam)
{

	m_strTemp.LoadString(IDS_CONNECTERROR);
	AfxMessageBox(m_strTemp);
	delete pSock;
	pSock=NULL;
	GetDlgItem(ID_SEND)->EnableWindow(FALSE);
}

void CTalkCDlg::OnSetfocusTopic() 
{
	// TODO: Add your control notification handler code here
	GetDlgItem(IDC_EDIT_TOPIC)->PostMessage(EM_SETSEL,0,-1);
}

void CTalkCDlg::OnMove(int x, int y) 
{
	CDialog::OnMove(x, y);
	
	// TODO: Add your message handler code here
	if(m_nNoResponseCount > 0)
	{
		m_nNoResponseCount = 0;
		KillTimer(1001);
		SetWindowText(_T("Talk Client"));
		ModifyShell_Icon(NULL, m_hIconShow);

	}
}

void CTalkCDlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	if(nIDEvent == 1001)
	{
		static BOOL bInvert = FALSE;
		bInvert = !bInvert;
		if(g_bUseShell_Icon)
		{
			static HICON s_hIcon = m_hIconShow;

			if(s_hIcon == m_hIconShow) s_hIcon = m_hIconHide;
			else s_hIcon = m_hIconShow;

			ModifyShell_Icon(NULL, s_hIcon);
			TRACE("CTalkCDlg::OnTimer() s_hIcon = 0x%X\n", s_hIcon);
		}
		else
		{
			FlashWindow(bInvert);
		}
	}
	
	CDialog::OnTimer(nIDEvent);
}

void CTalkCDlg::OnDblclkListWords() 
{
	// TODO: Add your control notification handler code here
	int nCurSel = m_listWords.GetCurSel();
	if(nCurSel >= 0)
	{
		TCHAR szString[MAX_PATH + MAX_PATH] = _T("");
		m_listWords.GetText(nCurSel, szString);
		LPTSTR p = szString;
		while(p && *p == ' ') ++p;
		SetDlgItemText(IDC_EDIT_TOPIC, p);
	}
}

void CTalkCDlg::SetupShell_Icon(BOOL bInstall)
{
	NOTIFYICONDATA tnd = { sizeof(NOTIFYICONDATA) };
	tnd.hWnd			= m_hWnd;
	tnd.uID				= IDR_MAINFRAME;
	tnd.uFlags			= NIF_MESSAGE | NIF_ICON | NIF_TIP;
	tnd.uCallbackMessage= WM_CHAT_MSG;
	tnd.hIcon			= m_hIconShow;

	strcpy(tnd.szTip, _T("SmallChat Client"));

	DWORD dwMessage = NIM_DELETE;
	if(bInstall) dwMessage = NIM_ADD;
	Shell_NotifyIcon(dwMessage, &tnd);
}

void CTalkCDlg::ModifyShell_Icon(LPCTSTR lpszTips, HICON hIcon)
{
	if(lpszTips || hIcon)
	{
		NOTIFYICONDATA tnd	 = { sizeof(NOTIFYICONDATA) };
		tnd.hWnd			 = m_hWnd;
		tnd.uID				 = IDR_MAINFRAME;
		tnd.hIcon			 = hIcon;

		if(lpszTips) tnd.uFlags |= NIF_TIP;
		if(hIcon)    tnd.uFlags |= NIF_ICON;

		if(lpszTips) strcpy(tnd.szTip, lpszTips);
		BOOL bSucceeded = Shell_NotifyIcon(NIM_MODIFY , &tnd);
		TRACE("Shell_NotifyIcon(NIM_MODIFY) return %d\n", bSucceeded);
	}
}

void CTalkCDlg::OnChkFlashIcon() 
{
	// TODO: Add your control notification handler code here
	BOOL bCheckShellIcon = IsDlgButtonChecked(IDC_CHK_FLASH_ICON);

	SetupShell_Icon(bCheckShellIcon);
}

LRESULT CTalkCDlg::OnShellIconMsg(WPARAM wParam, LPARAM lParam)
{
	if(lParam == WM_LBUTTONUP || lParam == WM_RBUTTONUP)
	{
		int nShowCmd = SW_SHOW;
		if(IsWindowVisible()) nShowCmd = SW_HIDE;
		ShowWindow(nShowCmd);

		if(nShowCmd == SW_SHOW)
		{
			ShowWindow(SW_RESTORE);
		}
	}

	return 0;
}

⌨️ 快捷键说明

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