// ClientDlg.cpp : implementation file // #include "stdafx.h" #include "Client.h" #include "ClientDlg.h" #include "LogDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CClientDlg dialog CClientDlg::CClientDlg(CWnd* pParent /*=NULL*/) : CDialog(CClientDlg::IDD, pParent) { //{{AFX_DATA_INIT(CClientDlg) m_Say = _T(""); m_Ctx = _T(""); m_personal = FALSE; //}}AFX_DATA_INIT curNum = 0; m_personal = false; m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CClientDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CClientDlg) DDX_Control(pDX, IDC_LIST1, m_List); DDX_Text(pDX, IDC_SAY, m_Say); DDX_Text(pDX, IDC_CTX, m_Ctx); DDX_Check(pDX, IDC_CHECK1, m_personal); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CClientDlg, CDialog) //{{AFX_MSG_MAP(CClientDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_EXIT, OnExit) ON_BN_CLICKED(IDC_SEND, OnSend) ON_MESSAGE(SOCKET_EVENT,OnSocket) //SOCKET有消息,启动Socket程序 ON_NOTIFY(NM_DBLCLK, IDC_LIST1, OnDblclkList1) ON_WM_CTLCOLOR() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CClientDlg message handlers BOOL CClientDlg::OnInitDialog() { CString msg; DWORD err; CDialog::OnInitDialog(); SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon tryagain: CLogDlg ld; if(ld.DoModal() != IDOK) //没有按确认键 { PostQuitMessage(0); //退出程序 return TRUE; } if(strlen(ld.m_ipAddr) == 0) { MessageBox("请输入服务器地址!"); goto tryagain; } if(ld.m_Name.IsEmpty()) { MessageBox("请输入你的称谓!"); goto tryagain; } m_Name = ld.m_Name; char im = ld.m_imgNum + 1; m_socket.AttachCWnd(this); //把SOCKET与对话框联系起来,SOCKET有消息就通知本对话框 if(m_socket.Create() == FALSE) //自动完成SOCKET的初始化、设置 { err = GetLastError(); msg.Format("创建Socket失败!\r\n错误代码:%d",err);//sprintf相同 goto msgbox; } SetWindowText("正在连接到服务器..."); //设置对话框的标题 //连接到服务器计算机,端口为0x8123的程序 if(m_socket.Connect(ld.m_ipAddr,0x8123) == FALSE) { //如果连接成功,对方创建新的SOCKET,新的端口号,就与新的SOCKET,新的端口号通信。 err = GetLastError(); msg.Format("连接服务器失败! \r\n错误代码:%d",err); msgbox: MessageBox(msg); PostQuitMessage(0); //退出 return TRUE; } char pkt[200]; sprintf(pkt,"%s 已连接到服务器!",m_Name); SetWindowText(pkt); //设置对话框的标题 Sleep(1000); pkt[0] = 0x11; //功能码,登入聊天室,自己定义 pkt[1] = im; strncpy(pkt+2,m_Name,64); //将称谓拷到功能码后面 int l = strlen(pkt)+1; if(m_socket.Send(pkt,l) == FALSE)//发送到服务器,参数:起始地址、长度 MessageBox("发送数据错误!"); HICON myIcon[10]; myIcon[0]=AfxGetApp()->LoadIcon(IDI_ICON1);//注意这里是通过LoadIcon获得HICON myIcon[1]=AfxGetApp()->LoadIcon(IDI_ICON2); myIcon[2]=AfxGetApp()->LoadIcon(IDI_ICON3); myIcon[3]=AfxGetApp()->LoadIcon(IDI_ICON4); myIcon[4]=AfxGetApp()->LoadIcon(IDI_ICON5); myIcon[5]=AfxGetApp()->LoadIcon(IDI_ICON6); myIcon[6]=AfxGetApp()->LoadIcon(IDI_ICON7); myIcon[7]=AfxGetApp()->LoadIcon(IDI_ICON8); myIcon[8]=AfxGetApp()->LoadIcon(IDI_ICON9); myIcon[9]=AfxGetApp()->LoadIcon(IDI_ICON10); m_ImageList.Create(32, 32, ILC_COLOR32, 8, 8); for(int i=0; i < 10; i++) { m_ImageList.Add(myIcon[i]); } m_List.SetImageList(&m_ImageList, LVSIL_SMALL); m_bExit.AutoLoad(IDC_EXIT,this); m_bSend.AutoLoad(IDC_SEND,this); m_bmBack.DeleteObject(); m_brBack.DeleteObject(); m_bmBack.LoadBitmap(IDB_TALKBK); m_brBack.CreatePatternBrush(&m_bmBack); return TRUE; } void CClientDlg::OnSysCommand(UINT nID, LPARAM lParam) { CDialog::OnSysCommand(nID, lParam); } void CClientDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); SendMessage(WM_ICONERASEBKGND, (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 { CDialog::OnPaint(); } } HCURSOR CClientDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } void CClientDlg::OnOK() { CDialog::OnOK(); } void CClientDlg::OnCancel() { CDialog::OnCancel(); } void CClientDlg::OnExit() { m_socket.Close(); //TCP/IP会告诉服务器我已退出 CDialog::OnOK(); } void CClientDlg::OnSend() { char pkt[4096]; int len; UpdateData(); memset(pkt,0,sizeof(pkt)); //数组清零 if(m_personal) { pkt[0] = 0x51; strcpy(pkt + 1,pName[m_curIndex]); len = sprintf(pkt + 100 ,"%s 悄悄的对你说:%s\r\n",m_Name,m_Say); m_socket.Send(pkt,len + 100); sprintf(pkt + 100 ," 你悄悄的对%s说:%s\r\n",pName[m_curIndex],m_Say); m_Ctx += pkt +100; m_Say.Empty(); // m_personal = false; } else { pkt[0] = 0x21; //填入功能码0x21 len = sprintf(pkt+1,"%s说: %s\r\n",m_Name,m_Say); //len是长度 m_socket.Send(pkt,len + 3); //字符串以零结尾。多发两个零 m_Say.Empty(); } UpdateData(FALSE); // GetDlgItem(IDC_SAY)->SetFocus(); } void CClientDlg::OnSocket(WPARAM wParam, LPARAM lParam) { char pkt[4096]; memset(pkt,0,4096); CEdit *pEd = (CEdit*)GetDlgItem(IDC_CTX); //得到编辑框对象的控制指针 LVFINDINFO info; LVITEM lvitem; switch(lParam) { case RETR: m_socket.Receive(pkt,4096); if(m_Ctx.GetLength() > 8196) m_Ctx.Empty(); //忽略功能码 switch(pkt[0]) { case 0x11: pName[curNum] = pkt +2; curNum++; m_Ctx += pkt + 2; m_Ctx += " 进入聊室。\r\n"; lvitem.mask = LVIF_IMAGE|LVIF_TEXT; lvitem.iItem = curNum; lvitem.pszText = pkt + 2; lvitem.iImage = pkt[1] - 1; lvitem.iSubItem = 0; m_List.InsertItem(&lvitem); break; case 0x31: pName[curNum] = pkt +2; curNum++; lvitem.mask = LVIF_IMAGE|LVIF_TEXT; lvitem.iItem = curNum; lvitem.pszText = pkt + 2; lvitem.iImage = pkt[1] - 0x31; lvitem.iSubItem = 0; m_List.InsertItem(&lvitem); break; case 0x41: m_Ctx += pkt + 1; m_Ctx += " 退出聊室。\r\n"; info.flags = LVFI_PARTIAL|LVFI_STRING; info.psz = pkt + 1; int item; item = m_List.FindItem(&info); if(item != -1) { m_List.DeleteItem(item); } break; default: m_Ctx += pkt + 1; } pEd->LineScroll(1000); UpdateData(false); break; case CLOSE: MessageBox("服务器已关闭!"); break; } } void CClientDlg::OnDblclkList1(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: Add your control notification handler code here m_curIndex =m_List.GetNextItem(-1, LVNI_SELECTED); if(m_curIndex == -1) { return; } CString s; s.Format("%d",m_curIndex); // MessageBox(s + pName[m_curIndex]); *pResult = 0; m_personal =true; UpdateData(false); } HBRUSH CClientDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); if(nCtlColor == CTLCOLOR_DLG) return m_brBack; else return hbr; }