MyTreeView.cpp
上传用户:power_led
上传日期:2013-04-11
资源大小:373k
文件大小:14k
源码类别:

ICQ/即时通讯

开发平台:

Visual C++

  1. // MyTreeView.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "ChatClient.h"
  5. #include "MyTreeView.h"
  6. #include "ClientLog.h"
  7. #include "SendMessageDlg.h"
  8. #include "ClientFormView.h"
  9. #include "MainFrm.h"
  10. #include "ShowMessage.h"
  11. #ifdef _DEBUG
  12. #define new DEBUG_NEW
  13. #undef THIS_FILE
  14. static char THIS_FILE[] = __FILE__;
  15. #endif
  16. /////////////////////////////////////////////////////////////////////////////
  17. // CMyTreeView
  18. IMPLEMENT_DYNCREATE(CMyTreeView, CTreeView)
  19. CMyTreeView::CMyTreeView():m_Tree(GetTreeCtrl())
  20. {
  21. }
  22. CMyTreeView::~CMyTreeView()
  23. {
  24. POSITION pos;
  25. pos = m_ClientNameList.GetHeadPosition();
  26. POSITION tempos = pos;
  27. if(pos)
  28. {
  29. int iCount = m_ClientNameList.GetCount();
  30. for(int i = 0;i < iCount; i ++)
  31. {
  32. tempos = pos;
  33. Client * pTempClient = (Client *)m_ClientNameList.GetNext(pos);
  34. delete pTempClient;
  35. m_ClientNameList.RemoveAt(tempos);
  36. }
  37. }
  38. }
  39. BEGIN_MESSAGE_MAP(CMyTreeView, CTreeView)
  40. //{{AFX_MSG_MAP(CMyTreeView)
  41. ON_WM_CREATE()
  42. ON_NOTIFY_REFLECT(NM_RCLICK, OnRclick)
  43. ON_COMMAND(ID_JOININROOM, OnJoininroom)
  44. ON_COMMAND(ID_MENU_SEND, OnMenuSend)
  45. ON_WM_LBUTTONDBLCLK()
  46. ON_NOTIFY_REFLECT(NM_RDBLCLK, OnRclick)
  47. ON_NOTIFY_REFLECT(NM_DBLCLK, OnRclick)
  48. ON_WM_TIMER()
  49. //}}AFX_MSG_MAP
  50. ON_MESSAGE(WM_ADDNEWROOM,AddNewRoom)
  51. ON_MESSAGE(WM_NEWCLIENTCOMEIN,OnNewClientIn)
  52. ON_MESSAGE(WM_USERLOGOUT,OnClientOut)
  53. ON_MESSAGE(WM_SAYINPRIVATE,OnSayInPrivate)
  54. END_MESSAGE_MAP()
  55. /////////////////////////////////////////////////////////////////////////////
  56. // CMyTreeView drawing
  57. void CMyTreeView::OnDraw(CDC* pDC)
  58. {
  59. CDocument* pDoc = GetDocument();
  60. // TODO: add draw code here
  61. }
  62. /////////////////////////////////////////////////////////////////////////////
  63. // CMyTreeView diagnostics
  64. #ifdef _DEBUG
  65. void CMyTreeView::AssertValid() const
  66. {
  67. CTreeView::AssertValid();
  68. }
  69. void CMyTreeView::Dump(CDumpContext& dc) const
  70. {
  71. CTreeView::Dump(dc);
  72. }
  73. #endif //_DEBUG
  74. extern CChatClientApp theApp;
  75. void CMyTreeView::AddNewRoom(Message wParam,LPARAM lParam)
  76. {
  77. //CString
  78. CMainFrame * m_pMainFrame = (CMainFrame *)AfxGetMainWnd();
  79. ASSERT_VALID(m_pMainFrame);
  80. ASSERT(m_pMainFrame != NULL);
  81. static int iTimes = 1;
  82. if(iTimes == 1)
  83. {
  84. AfxGetMainWnd()->ShowWindow(SW_SHOWNORMAL);
  85. m_pMainFrame ->GetFormView()->SetDlgItemText(IDC_SELFNAME,theApp.m_skMainSocket.GetUserName());
  86. iTimes ++;
  87. }
  88. Message msObj = wParam;
  89. CString strRoom = msObj.strRoom;
  90. m_Tree.InsertItem(strRoom,2,3,m_ParentItem);
  91. // m_Tree.InsertItem("strRoom",2,3,m_ParentItem);
  92. m_Tree.Expand(m_ParentItem,TVE_EXPAND);
  93. }
  94. /////////////////////////////////////////////////////////////////////////////
  95. // CMyTreeView message handlers
  96. int CMyTreeView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  97. {
  98. if (CTreeView::OnCreate(lpCreateStruct) == -1)
  99. return -1;
  100. // TODO: Add your specialized creation code here
  101. m_ImageList.Create(IDB_IMAGELIST,16,5,RGB(255,0,255));
  102. m_Tree.SetImageList(&m_ImageList,TVSIL_NORMAL);
  103. m_ParentItem = m_Tree.InsertItem("聊天室列表",2,3);
  104. return 0;
  105. }
  106. extern CChatClientApp theApp;
  107. void CMyTreeView::OnRclick(NMHDR* pNMHDR, LRESULT* pResult) 
  108. {
  109. CMenu menu;
  110. CMenu * pContextMenu; 
  111. POINT point;
  112. GetCursorPos(&point);
  113. // CTreeView::OnLButtonDown(0,point);
  114. ScreenToClient(&point);
  115. HTREEITEM hItem = m_Tree.GetSelectedItem();
  116. CRect rect;
  117. m_Tree.GetItemRect(hItem,&rect,TRUE);
  118. if(rect.PtInRect(point))
  119. {
  120. if(m_Tree.GetParentItem(hItem) == m_ParentItem)
  121. {
  122. menu.LoadMenu(IDR_JOINROOM);
  123. pContextMenu = menu.GetSubMenu(0);
  124. ClientToScreen(&point);
  125. pContextMenu->TrackPopupMenu(TPM_LEFTBUTTON   ,point.x,point.y ,this);
  126. }
  127. else
  128. {
  129. if(hItem != m_ParentItem && m_Tree.GetItemText(hItem) != theApp.m_skMainSocket.GetUserName() && theApp.m_skMainSocket.GetState() == HAVELOGIN)
  130. {
  131. HTREEITEM hParent = m_Tree.GetParentItem(hItem);
  132. CString strRoom = m_Tree.GetItemText(hParent);
  133. if(strRoom == theApp.m_skMainSocket.GetRoomName())
  134. {
  135. menu.LoadMenu(IDR_CLIENT);
  136. pContextMenu = menu.GetSubMenu(0);
  137. ClientToScreen(&point);
  138. pContextMenu->TrackPopupMenu(TPM_LEFTBUTTON   ,point.x,point.y ,this);
  139. }
  140. else
  141. AfxMessageBox("处于不同的房间内,不能执行此项操作");
  142. }
  143. }
  144. }
  145. *pResult = 0;
  146. }
  147. extern CChatClientApp theApp;
  148. void CMyTreeView::OnJoininroom() 
  149. {
  150. // TODO: Add your command handler code here
  151. Message msObj;
  152. HTREEITEM hItem;
  153. if(theApp.m_skMainSocket.GetState() == NOTLOGIN)
  154. {
  155. //构造msobj
  156. hItem = m_Tree.GetSelectedItem();
  157. CString strRoomName = m_Tree.GetItemText(hItem);
  158. CString strUsrName = theApp.m_skMainSocket.GetUserName();
  159. // theApp.m_skMainSocket.SetUserName(strUsrName);
  160. theApp.m_skMainSocket.SetRoomName(strRoomName);
  161. theApp.m_skMainSocket.SetState(HAVELOGIN);
  162. msObj.iType = USERLOG;
  163. msObj.iSubType = USERLOGIN;
  164. int iLen = strRoomName.GetLength();
  165. iLen > 20 ? 20: iLen;
  166. lstrcpy(msObj.strRoom,_T(strRoomName.GetBuffer(iLen)));
  167. strRoomName.ReleaseBuffer();
  168. iLen = strUsrName.GetLength();
  169. iLen > 20 ? 20 : iLen;
  170. lstrcpy(msObj.strName,_T(strUsrName.GetBuffer(iLen)));
  171. strUsrName.ReleaseBuffer();
  172. iLen = theApp.m_skMainSocket.Send(&msObj,sizeof(msObj));
  173. if(iLen < sizeof(msObj))
  174. {
  175. AfxMessageBox("发送失败");
  176. return;
  177. }
  178. }
  179. else
  180. if(theApp.m_skMainSocket.GetState() == HAVELOGIN)
  181. {
  182. HTREEITEM hItem = m_Tree.GetSelectedItem();
  183. CString strRoomName = m_Tree.GetItemText(hItem);
  184. if(strRoomName != theApp.m_skMainSocket.GetRoomName())
  185. {
  186. HTREEITEM hItem = m_Tree.GetChildItem(m_ParentItem);
  187. msObj.iType = USERSESSION;
  188. msObj.iSubType = CHANGEROOM;
  189. //用户名
  190. CString strTemp;
  191. strTemp =  theApp.m_skMainSocket.GetUserName();
  192. int iLen = strTemp.GetLength();
  193. iLen > 20 ? 20:iLen;
  194. lstrcpy(msObj.strName,_T(strTemp.GetBuffer(iLen)));
  195. strTemp.ReleaseBuffer();
  196. //旧房件名
  197. strTemp = theApp.m_skMainSocket.GetRoomName();
  198. iLen = strTemp.GetLength();
  199. iLen > 20 ? 20 : iLen;
  200. lstrcpy(msObj.strRoom,_T(strTemp.GetBuffer(iLen)));
  201. strTemp.ReleaseBuffer();
  202. //新房间名
  203. hItem = m_Tree.GetSelectedItem();
  204. strTemp = m_Tree.GetItemText(hItem);
  205. iLen = strTemp.GetLength();
  206. iLen > 20 ? 20 :iLen;
  207. lstrcpy(msObj.strContent,_T(strTemp.GetBuffer(iLen)));
  208. strTemp.ReleaseBuffer();
  209. if(theApp.m_skMainSocket.Send(&msObj,sizeof(msObj)) != sizeof(msObj))
  210. {
  211. AfxMessageBox("发送错误");
  212. }
  213. theApp.m_skMainSocket.SetRoomName(m_Tree.GetItemText(hItem));
  214. }
  215. }
  216. return;
  217. }
  218. void CMyTreeView::OnClientOut(Message wParam, LPARAM lParam)
  219. {
  220. Message msObj = wParam;
  221. CString strRoom = msObj.strRoom;
  222. CString strUsrName = msObj.strName;
  223. HTREEITEM hItem = m_Tree.GetChildItem(m_ParentItem);
  224. BOOL bFind = FALSE;
  225. while(hItem && !bFind)
  226. {
  227. CString strNodeName = m_Tree.GetItemText(hItem);
  228. if(strNodeName == strRoom)
  229. {
  230. //查找用户名的那一项
  231. HTREEITEM hChildItem = m_Tree.GetChildItem(hItem);
  232. while(hChildItem)
  233. {
  234. CString strUserNode = m_Tree.GetItemText(hChildItem);
  235. if(strUserNode == strUsrName)
  236. {
  237. m_Tree.DeleteItem(hChildItem);
  238. m_Tree.Expand(hItem,TVE_EXPAND);
  239. bFind = TRUE;
  240. break;
  241. }
  242. hChildItem = m_Tree.GetNextItem(hChildItem,1);
  243. }
  244. }
  245. hItem = m_Tree.GetNextItem(hItem,1);
  246. }
  247. }
  248. void CMyTreeView::OnNewClientIn(Message wParam, LPARAM lParam)
  249. {
  250. Message msObj = wParam;
  251. CString strRoom = msObj.strRoom;
  252. CString strUsrName = msObj.strName;
  253. //自己加入的消息传入进来
  254. if(strRoom == theApp.m_skMainSocket.GetRoomName() && strUsrName == theApp.m_skMainSocket.GetUserName())
  255. {
  256. //改变FormView中的数据
  257. CClientFormView * m_pFormView =(CClientFormView *) ((CMainFrame * )AfxGetMainWnd())->GetFormView();
  258. ASSERT(m_pFormView != NULL);
  259. ASSERT_VALID(m_pFormView);
  260. m_pFormView ->SetDlgItemText(IDC_SELFNAME,strUsrName);
  261. m_pFormView ->SetDlgItemText(IDC_ROOMNAME,strRoom);
  262. //改变任务栏图标的提醒信息
  263. lstrcpy(theApp.TaskIcon.szTip,_T(strUsrName.GetBuffer(strUsrName.GetLength())));
  264. Shell_NotifyIcon(NIM_MODIFY,&theApp.TaskIcon);
  265. //显示正常的窗口
  266. return;
  267. }
  268. HTREEITEM hItem = m_Tree.GetChildItem(m_ParentItem);
  269. while(hItem)
  270. {
  271. CString strNodeName = m_Tree.GetItemText(hItem);
  272. CString strTemp = theApp.m_skMainSocket.GetUserName();
  273. if(strNodeName == strRoom)
  274. {
  275. if(strUsrName != strTemp)
  276. {
  277. m_Tree.InsertItem(strUsrName,0,1,hItem);
  278. m_Tree.Expand(hItem,TVE_EXPAND);
  279. break;
  280. }
  281. }
  282. hItem = m_Tree.GetNextItem(hItem,1);
  283. }
  284. }
  285. void CMyTreeView::OnMenuSend() 
  286. {
  287. // TODO: Add your command handler code here
  288. CSendMessageDlg Dlg;
  289. if(Dlg.DoModal() == IDOK)
  290. {
  291. if(Dlg.m_strSentence.GetLength())
  292. {
  293. if(Dlg.m_strSentence.GetLength == 0)
  294. return;
  295. Message msObj;
  296. memset(&msObj,0,sizeof(Message));
  297. msObj.iType = USERSESSION;
  298. msObj.iSubType = SAYINPRIVATE;
  299. CString strTemp  = theApp.m_skMainSocket.GetRoomName();
  300. int iLen = strTemp.GetLength();
  301. lstrcpy(msObj.strRoom,_T(strTemp.GetBuffer(iLen)));
  302. strTemp.ReleaseBuffer();
  303. strTemp = Dlg.m_strSentence;
  304. iLen = strTemp.GetLength();
  305. iLen > 1024 ? 1024 : iLen;
  306. lstrcpy(msObj.strContent,_T(strTemp.GetBuffer(iLen)));
  307. strTemp.ReleaseBuffer();
  308. //自己的名字
  309. strTemp = theApp.m_skMainSocket.GetUserName();
  310. iLen = strTemp.GetLength();
  311. iLen > 20 ? 20:iLen;
  312. lstrcpy(msObj.strName,_T(strTemp.GetBuffer(iLen)));
  313. strTemp.ReleaseBuffer();
  314. //说话对象的名字
  315. HTREEITEM hItem = m_Tree.GetSelectedItem();
  316. strTemp = m_Tree.GetItemText(hItem);
  317. iLen = strTemp.GetLength();
  318. iLen > 20 ? 20 : iLen;
  319. lstrcpy(msObj.strClientName,_T(strTemp.GetBuffer(iLen)));
  320. strTemp.ReleaseBuffer();
  321.  iLen = theApp.m_skMainSocket.Send(&msObj,sizeof(Message));
  322. }
  323. }
  324. return;
  325. }
  326. //接收到信息
  327. //整个的处理过程是这样:
  328. //首先,接收到信息以后,在m_ClientNameList中添加一项,这样,在ontimer中,可以检查链表中都是有谁在发送信息,而且
  329. //你还没有回复.这样OnTimer中就可以实现多个人的头像一起晃动。
  330. //当你回复或者取消以后,相应的应该在m_ClientNameList中删除已经恢复或者取消的那一项。
  331. void CMyTreeView::OnSayInPrivate(Message wParam,LPARAM lParam)
  332. {
  333. Message msObj = wParam;
  334. CString strClientName = msObj.strName;
  335. Client * pNewClient;
  336. //设置每一个Client对应的ontimer中IDEVENT
  337. pNewClient = new Client();
  338. int iCount = m_ClientNameList.GetCount();
  339. pNewClient ->SetUserName(strClientName);
  340. int iMaxId = 1;
  341. if(iCount == 0)
  342. {
  343. pNewClient ->SetTimerId(iMaxId);
  344. }
  345. else
  346. {
  347. //查找出最大的iTimerId;
  348. POSITION pos;
  349. pos = m_ClientNameList.GetHeadPosition();
  350. if(pos)
  351. {
  352. for(int i = 0; i< iCount; i ++)
  353. {
  354. Client * pTempClient = (Client *)m_ClientNameList.GetNext(pos);
  355. if(iMaxId > pTempClient ->GetTimerId())
  356. iMaxId = pTempClient ->GetTimerId();
  357. }
  358. iMaxId ++;
  359. }
  360. pNewClient ->SetTimerId(iMaxId);
  361. }
  362. m_ClientNameList.AddTail(pNewClient);
  363. //启动Ontimer
  364. SetTimer(iMaxId,800,NULL);
  365. //显示对话框
  366. CString strContent  = msObj.strContent;
  367. CShowMessage Dlg(strContent,strClientName,iMaxId);
  368. Dlg.DoModal();
  369. SetIcon(strClientName,0,1);
  370. ////
  371. return;
  372. }
  373. BOOL CMyTreeView::PreCreateWindow(CREATESTRUCT& cs) 
  374. {
  375. // TODO: Add your specialized code here and/or call the base class
  376. cs.style |= TVS_HASLINES;
  377. cs.style |= TVS_LINESATROOT;
  378. cs.style |= TVS_HASBUTTONS;
  379. return CTreeView::PreCreateWindow(cs);
  380. }
  381. //启动ONtimer。主要是让用户的图标晃动,并且发出报警的声音
  382. void CMyTreeView::OnTimer(UINT nIDEvent) 
  383. {
  384. // TODO: Add your message handler code here and/or call default
  385. POSITION pos;
  386. pos = m_ClientNameList.GetHeadPosition();
  387. int iCount = m_ClientNameList.GetCount();
  388. if(pos)
  389. {
  390. for(int i = 0 ;i < iCount; i++)
  391. {
  392. Client * pTempClient =(Client *) m_ClientNameList.GetNext(pos);
  393. if(nIDEvent ==(UINT) pTempClient->GetTimerId())
  394. {
  395. int i = pTempClient ->GetTimes();
  396. pTempClient->AddTimes();
  397. i %= 2;
  398. if(i == 1)
  399. {
  400. theApp.TaskIcon.hIcon = theApp.LoadIcon(IDI_EMPTY);
  401. Shell_NotifyIcon(NIM_MODIFY,&theApp.TaskIcon);
  402. PlaySound("msg.wav",NULL,SND_ASYNC);
  403. SetIcon(pTempClient ->GetUserName(),0,0);
  404. }
  405. else
  406. {
  407. theApp.TaskIcon.hIcon = theApp.LoadIcon(IDI_TASKICON);
  408. Shell_NotifyIcon(NIM_MODIFY,&theApp.TaskIcon);
  409. SetIcon(pTempClient ->GetUserName(),5,5);
  410. }
  411. }//end if IDEvent == 
  412. }//endfor
  413. }//end if pos
  414. CTreeView::OnTimer(nIDEvent);
  415. }
  416. //在创建的链表中删除一项
  417. void CMyTreeView::DeleteOneClient(const CString & strName,const int iID)
  418. {
  419. POSITION pos;
  420. pos = m_ClientNameList.GetHeadPosition();
  421. int iCount = m_ClientNameList.GetCount();
  422. POSITION tempos = pos;
  423. if(pos && iCount)
  424. {
  425. for(int i = 0;i < iCount; i ++)
  426. {
  427. tempos = pos;
  428. Client * pTempClient = (Client *)m_ClientNameList.GetNext(pos);
  429. if(pTempClient->GetUserName() == strName && pTempClient->GetTimerId() == iID)
  430. {
  431. delete pTempClient;
  432. m_ClientNameList.RemoveAt(tempos);
  433. break;
  434. }
  435. }
  436. }
  437. return;
  438. }
  439. //设置树型控件中某一项的图标
  440. void CMyTreeView::SetIcon(const CString &strClientName,const int iNormalIcon,const int iSelectedIcon)
  441. {
  442. CString strRoom;
  443. strRoom = theApp.m_skMainSocket.GetRoomName();
  444. HTREEITEM hItem = m_Tree.GetChildItem(m_ParentItem);
  445. BOOL bFind = FALSE;
  446. while(hItem && !bFind)
  447. {
  448. CString strNodeName = m_Tree.GetItemText(hItem);
  449. if(strNodeName == strRoom)
  450. {
  451. //查找用户名的那一项
  452. HTREEITEM hChildItem = m_Tree.GetChildItem(hItem);
  453. while(hChildItem)
  454. {
  455. CString strUserNode = m_Tree.GetItemText(hChildItem);
  456. if(strUserNode == strClientName)
  457. {
  458. m_Tree.SetItemImage(hChildItem,iNormalIcon,iSelectedIcon);
  459. }
  460. hChildItem = m_Tree.GetNextItem(hChildItem,1);
  461. }
  462. }
  463. hItem = m_Tree.GetNextItem(hItem,1);
  464. }
  465. }