即时通讯编程(六)
作者:邵盛松 2009-06-03 QQ:346646173
目的:开发基于XMPP(Extensible Messaging and Presence Protocol)协议的即时通讯。
开发工具: Visual C++ 2005
本篇文章主要内容:程序在登录的时候处理接收的好友数据,将好友数据写入数据库,并在Tree Control上显示
注:数据库采用ADO操作,DBMS任选,SQLite,FireBird都可以。
创建一个数据库,表名为TB_JABBER,字段为JID,JABBERNAME,JABBERGROUP,SUBSCRIPTION,RESOURCE,在数据库设计时可以将组独
立成一个表。这里将用户的信息都存储在一个表当中。
在主界面对话框(ID为IDD_项目名称_DIALOG的窗口)添加一个Tree Control,命名为m_Tree_ctrlFriendList
基于MFC Unicode编码下将utf8编码转换为unicode
在这可以用成员函数,也可以在全局范围内定义函数,在这里定义成成员函数
CString CFriendList::UTF8ConvertUnicode(LPCSTR utf8)
{
int len;
len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL,0);
WCHAR * wszUtf8 = new WCHAR[len+1];
memset(wszUtf8, 0, len * 2 + 2);
MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wszUtf8, len);
CString strReturn=(const wchar_t*)wszUtf8;
return strReturn;
}
在handleRoster处理接收数据,将接受的数据先写入数据库,然后将接收的数据在界面
void CFriendList::handleRoster( const Roster& roster )
{
CString strSQL=_T("DELETE FROM TB_JABBER"); //先要将表的内容清空
m_pCon->Execute((_bstr_t)strSQL,NULL,adCmdText);
/**************************************************************************************************/
try
{
/**************************************************************************************************/
HRESULT hr4=m_pRs1->Open(_T("TB_JABBER"),m_pCon.GetInterfacePtr
(),adOpenStatic,adLockOptimistic,adCmdTable);
if(FAILED(hr4))
return;
if (!m_pRs1->Supports(adAddNew))
return;
Roster::const_iterator it = roster.begin();
for( ; it != roster.end(); ++it )
{
m_pRs1->AddNew();
CString strJID=UTF8ConvertUnicode((*it).second->jid().c_str());
CString strJName=UTF8ConvertUnicode((*it).second->name().c_str());
//strJID=_T("JID:")+strJID;
//strJName=_T("Name:")+strJName;
//AfxMessageBox(strJID);
m_pRs1->ADOFields->GetItem(_variant_t("JID"))->Value=_bstr_t(strJID);
//AfxMessageBox(strJName);
/******************************************************************/
m_pRs1->ADOFields->GetItem(_variant_t("JABBERNAME"))->Value=_bstr_t(strJName);
/******************************************************************/
/*CString strsubscription;
strsubscription.Format(_T("subscription: %d"),(*it).second->subscription());
AfxMessageBox(strsubscription);*/
m_pRs1->ADOFields->GetItem(_variant_t("SUBSCRIPTION"))->Value=_bstr_t((*it).second-
>subscription());
/******************************************************************/
StringList g = (*it).second->groups();
StringList::const_iterator it_g = g.begin();
if(it_g==g.end()) //因为服务器传递的组中不包括默认组,所有要自定义一个默认组
{
//AfxMessageBox(_T("没有传递组消息"));
CString strGroup=_T("我的好友");
m_pRs1->ADOFields->GetItem(_variant_t("JABBERGROUP"))->Value=_bstr_t(strGroup);
}
for( ; it_g != g.end(); ++it_g )
{
/******************************************************************/
CString group=UTF8ConvertUnicode((*it_g).c_str());
//group=_T("Group:")+group;
//AfxMessageBox(group);
if (!group.IsEmpty())
{
m_pRs1->ADOFields->GetItem(_variant_t("JABBERGROUP"))->Value=_bstr_t
(group);
}
else
{
m_pRs1->ADOFields->GetItem(_variant_t("JABBERGROUP"))->Value=_bstr_t(_T("未
上线"));
}
/******************************************************************/
}
RosterItem::ResourceMap::const_iterator rit = (*it).second->resources().begin();
for( ; rit != (*it).second->resources().end(); ++rit )
{
/******************************************************************/
CString resource=UTF8ConvertUnicode((*rit).first.c_str());
m_pRs1->ADOFields->GetItem(_variant_t("RESOURCE"))->Value=_bstr_t(resource);
//resource=_T("Resource:")+resource;
//AfxMessageBox(resource);
/******************************************************************/
}
}
/**************************************************************************************************/
m_pRs1->Update();//更新添加
m_pRs1->Close();//关闭记录集
}
catch(_com_error e)
{
AfxMessageBox(e.Description());
}
/**************************************************************************************************/
}
当数据库处理完毕就要显示在界面Tree Control上。
m_Tree_ctrlFriendList.DeleteAllItems();
std::vector<HTREEITEM> root;
try
{
_variant_t vFieldValue;
// int i;
//m_pRs->CursorLocation=adUseClient;
HRESULT hr100=m_pRs1->Open(_T("TB_JABBER"),m_pCon.GetInterfacePtr
(),adOpenStatic,adLockOptimistic,adCmdTable);
//HRESULT hr=m_pRs->Open(_T("TB_GROUP") ,"","", "", adModeUnknown);
if (SUCCEEDED(hr100))
{
//m_pRs->MoveFirst();
while (!m_pRs1->EndOfFile)
{
vFieldValue=m_pRs1->GetCollect(_T("JABBERGROUP"));
if(vFieldValue.vt!= VT_NULL)
{
bool bIsEqual=true;
CString strRoot=(_bstr_t)vFieldValue;
HTREEITEM hRoot = m_Tree_ctrlFriendList.GetRootItem();
while(hRoot)
{ CString strRootWillAdd =m_Tree_ctrlFriendList.GetItemText(hRoot);
if (!strRoot.Compare(strRootWillAdd))//相等
{
bIsEqual=false;
}
hRoot = m_Tree_ctrlFriendList.GetNextItem(hRoot, TVGN_NEXT);
}
if (bIsEqual==true)
{
m_Tree_ctrlFriendList.InsertItem((_bstr_t)vFieldValue);
}
//只添加不同名称的组
}
m_pRs1->MoveNext();
}
hr100=m_pRs1->Close();//关闭记录集
}
}
catch(_com_error e)
{
MessageBox(e.ErrorMessage());
}
UpdateData(true);
HTREEITEM hItem = m_Tree_ctrlFriendList.GetRootItem();
_variant_t vFieldValue1;
CString strGroupMember;
while(NULL != hItem)
{
CString str= m_Tree_ctrlFriendList.GetItemText(hItem);
CString strSQL=_T("SELECT * FROM TB_JABBER WHERE JABBERGROUP='")+str+_T("/'");
HRESULT hr3=m_pRs1->Open(_variant_t(strSQL),m_pCon.GetInterfacePtr
(),adOpenStatic,adLockOptimistic,adCmdText);
if (SUCCEEDED(hr3))
{
//m_pRs->MoveFirst();
while (!m_pRs1->EndOfFile)
{
vFieldValue1=m_pRs1->GetCollect(_T("JABBERNAME"));
/*************************************************************/
if (vFieldValue1.vt!=VT_NULL&&vFieldValue1.vt!=VT_EMPTY)
{
strGroupMember=vFieldValue1.bstrVal;
}
else
{
strGroupMember=_T("未名称");
}
m_Tree_ctrlFriendList.InsertItem(strGroupMember,hItem);
m_pRs1->MoveNext();
}
hr3=m_pRs1->Close();//关闭记录集
}
hItem = m_Tree_ctrlFriendList.GetNextVisibleItem(hItem);
}
以上在 Visual C++2005 下调试通过