按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
if(iMins 《 10)
sMins。Insert(0; ’0’);
sSecs。Format(〃%d〃; iSecs);
if(iSecs 《 10)
·293 ·
…………………………………………………………Page 305……………………………………………………………
Visual C++ 6。0 程序设计从入门到精通
sSecs。Insert(0; ’0’);
CString sDisplayTime;
sDisplayTime = sHours+sMins+sSecs;
lvi。mask = LVIF_TEXT;
lvi。iItem = iActualItem;
lvi。iSubItem = 1;
lvi。pszText = sDisplayTime。GetBuffer(sDisplayTime。GetLength());
BOOL test = GetListCtrl()。SetItem(&lvi);
//插入客户端地址
CString sIPPort;
sIPPort。Format(〃%s:%d〃; IPAddress; Port);
lvi。mask = LVIF_TEXT;
lvi。iSubItem = 2;
lvi。pszText = sIPPort。GetBuffer(sIPPort。GetLength());
GetListCtrl()。SetItem(&lvi);
}
添加一个在列表中删除某用户的操作,函数名为 void DeleteChatter(CString Name) ,其中
Name 就是用户名。代码如下:
void CChattersListView::DeleteChatter(CString Name)
{
LVFINDINFO lvfi;
lvfi。flags = LVFI_STRING;
lvfi。psz = Name。GetBuffer(Name。GetLength());
//在列表中查找用户名,得到其索引值
int nFoundAt = GetListCtrl()。FindItem(&lvfi);
//如果找到则将其删除
if(nFoundAt != …1)
GetListCtrl()。DeleteItem(nFoundAt);
}
(4 )编写聊天信息界面
新建一个类,取名为 CChatView,其父类为 CView,该类用于显示聊天信息。为其添加
一个成员变量:CEdit m_EditBox,负责聊天信息的显示。
为 WM_CREATE 消息添加响应函数,在此函数中,对 m_EditBox 进行初始化,代码如
下:
int CChatView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == …1)
return …1;
·294 ·
…………………………………………………………Page 306……………………………………………………………
第 11 章 网络编程
// TODO: Add your specialized creation code here
CRect rect;
GetClientRect(&rect);
m_EditBox。Create(WS_VISIBLE |
WS_BORDER |
WS_CHILD |
ES_MULTILINE |
WS_VSCROLL;
rect; this ; 0);
return 0;
}
当窗口大小变化时,会激发 WM_SIZE 消息。为此消息编写响应函数,代码如下:
void CChatView::OnSize(UINT nType; int cx; int cy)
{
CView::OnSize(nType; cx; cy);
// TODO: Add your message handler code here
m_EditBox。MoveWindow(0 ; 0 ; cx ; cy ; FALSE);
}
最后,为该类添加一函数 void ShowMessage(LPCTSTR lpszMessage) ,此函数用于消息的
显示,其参数为消息内容。代码如下:
void CChatView::ShowMessage(LPCTSTR lpszMessage)
{
CString strTemp = lpszMessage;
strTemp += _T(〃rn〃);
int len = m_EditBox。GetWindowTextLength();
m_EditBox。SetSel(len;len);
m_EditBox。ReplaceSel(strTemp);
}
至此,负责显示客户端信息以及聊天信息的两个窗口都已编写完毕,接下来要在主框架
中进行分割,也就是将主框架分割成显示客户端信息的窗口和显示聊天信息的窗口两部分。
(5 )分割框架
为类 CMainFrame 添加成员变量 CSplitterWnd m_wndSplitter,用于分割主框架。重载函
数 virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs; CCreateContext* pContext) ,该函数
在主框架生成期间被调用,在此函数中添加分割窗口的操作,代码如下:
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/;
CCreateContext* pContext)
{
·295 ·
…………………………………………………………Page 307……………………………………………………………
Visual C++ 6。0 程序设计从入门到精通
//将窗口分为两行一列
if (!m_wndSplitter。CreateStatic(this; 2; 1))
return FALSE;
//指定每个窗口的位置及初始大小
if (!m_wndSplitter。CreateView(0; 0; RUNTIME_CLASS(CChattersListView); CSize(150; 100);
pContext) ||
!m_wndSplitter。CreateView(1; 0; RUNTIME_CLASS(CChatView); CSize(300; 300); pContext))
{
m_wndSplitter。DestroyWindow();
return FALSE;
}
return TRUE;
}
在此函数中用到了类 CChatView 和 CChattersListView,因此在文件“MainFrm。cpp ”的
开头要加入下面两个语句:
#include 〃ChatView。h〃
#include 〃ChattersListView。h〃
现在编译、运行程序,可以看到主框架已经被分割成两个窗口,如图 11…8 所示。
图 11…8 主框架被分割为两部分
至此,界面部分已经完成。
(6 )创建 CListeningSocket 类
该类用户监听客户端的连接,创建方式与 CChattersListView 类的创建方式相同,只是基
类选择 CSocket 。
在类的定义中声明宏 DECLARE_DYNAMIC(CListeningSocket) ,该宏的作用是可以在运
·296 ·
…………………………………………………………Page 308……………………………………………………………
第 11 章 网络编程
行时获得类的信息。相应的,如果在类定义中声明了此宏,则在类实现时需要声明宏
IMPLEMENT_DYNAMIC(CListeningSocket; CSocket) 。
为该类增加成员变量 CChatServerDoc* m_pDoc,这是因为本程序采用文档…视图结构,
所有关于数据的操作都可以通过文档类进行,m_pDoc 就是文档类的一个指针。这里用到了
CChatServerDoc 类 , 因 此 在 CListeningSocket 类 定 义 的 外 部 , 要 加 上 语 句 class
CChatServerDoc,在文件“ListeningSocket。cpp ”中,要加入语句#include 〃ChatServerDoc。h〃 。
为 CListeningSocket 类新增加一个构造函数 CListeningSocket(CChatServerDoc* pDoc),
代码如下:
CListeningSocket::CListeningSocket(CChatServerDoc* pDoc)
{
m_pDoc = pDoc;
}
最后要重载 CSocket 类的 OnAccept()函数,代码如下:
void CListeningSocket::OnAccept(int nErrorCode)
{
//调用 CScoekt 的 OnAccept 函数
CSocket::OnAccept(nErrorCode);
//其余工作交给文档类处理
m_pDoc…》ProcessAccept();
}
可以看出,CListeningSocket 类的工作就是接收客户端连接,然后具体的数据传输工作交
给 CChatServerDoc 类来处理。这里的 ProcessAccept()函数是 CChatServerDoc 类的一个成员函
数。在后面的 CChatServerDoc 类成员函数的实现中,读者可以看到此函数的具体实现过程。
(7 )创建 CClientSocket 类
当服务器监听到一个连接并接收后,会生成一个新的 CSocket 对象来处理服务器和客户
端的数据传输 。在本程序中,将这新生成的 CSocket 封装成 CClientSocket 类。创建该类的过
程和创建 CListeningSocket 类完全一样。
同样的,在类的定义中声明宏 DECLARE_DYNAMIC(CClientSocket) ,在类的实现中声
明宏 IMPLEMENT_DYNAMIC(CClientSocket; CSocket) 。
为该类加入成员变量,如表 11…7 所示。