QQClientDlg.cpp
上传用户:hysujiao87
上传日期:2007-12-02
资源大小:156k
文件大小:11k
源码类别:

ICQ/即时通讯

开发平台:

C/C++

  1. // QQClientDlg.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "QQClient.h"
  5. #include "QQClientDlg.h"
  6. #include "QQSocket.h"
  7. #include "SendDlg.h"
  8. #include "AddFriendDlg.h"
  9. #include "Communication.h"
  10. #include "XMLParser.h"
  11. #include <shlwapi.h>
  12. #ifdef _DEBUG
  13. #define new DEBUG_NEW
  14. #undef THIS_FILE
  15. static char THIS_FILE[] = __FILE__;
  16. #endif
  17. /////////////////////////////////////////////////////////////////////////////
  18. // CAboutDlg dialog used for App About
  19. class CAboutDlg : public CDialog
  20. {
  21. public:
  22. CAboutDlg();
  23. // Dialog Data
  24. //{{AFX_DATA(CAboutDlg)
  25. enum { IDD = IDD_ABOUTBOX };
  26. //}}AFX_DATA
  27. // ClassWizard generated virtual function overrides
  28. //{{AFX_VIRTUAL(CAboutDlg)
  29. protected:
  30. virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  31. //}}AFX_VIRTUAL
  32. // Implementation
  33. protected:
  34. //{{AFX_MSG(CAboutDlg)
  35. //}}AFX_MSG
  36. DECLARE_MESSAGE_MAP()
  37. };
  38. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  39. {
  40. //{{AFX_DATA_INIT(CAboutDlg)
  41. //}}AFX_DATA_INIT
  42. }
  43. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  44. {
  45. CDialog::DoDataExchange(pDX);
  46. //{{AFX_DATA_MAP(CAboutDlg)
  47. //}}AFX_DATA_MAP
  48. }
  49. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  50. //{{AFX_MSG_MAP(CAboutDlg)
  51. // No message handlers
  52. //}}AFX_MSG_MAP
  53. END_MESSAGE_MAP()
  54. /////////////////////////////////////////////////////////////////////////////
  55. // CQQClientDlg dialog
  56. CQQClientDlg::CQQClientDlg(LPCTSTR serverIP, CWnd* pParent /*=NULL*/)
  57. : CDialog(CQQClientDlg::IDD, pParent)
  58. {
  59. //{{AFX_DATA_INIT(CQQClientDlg)
  60. //}}AFX_DATA_INIT
  61. // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  62. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  63. _serverIP = serverIP;
  64. }
  65. void CQQClientDlg::DoDataExchange(CDataExchange* pDX)
  66. {
  67. CDialog::DoDataExchange(pDX);
  68. //{{AFX_DATA_MAP(CQQClientDlg)
  69. //}}AFX_DATA_MAP
  70. }
  71. BEGIN_MESSAGE_MAP(CQQClientDlg, CDialog)
  72. //{{AFX_MSG_MAP(CQQClientDlg)
  73. ON_WM_SYSCOMMAND()
  74. ON_WM_PAINT()
  75. ON_WM_QUERYDRAGICON()
  76. ON_BN_CLICKED(IDC_BTN_ADDFRD, OnBtnAddFriend)
  77. ON_WM_DESTROY()
  78. ON_MESSAGE(WM_PEER_NOTIFY, OnListenNotify)
  79. ON_MESSAGE(WM_SENDDLG_CLOSED, OnSenddlgClosed)
  80. ON_MESSAGE(WM_OUTBAR_NOTIFY, OnOutbarNotify)
  81. //}}AFX_MSG_MAP
  82. END_MESSAGE_MAP()
  83. /////////////////////////////////////////////////////////////////////////////
  84. // CQQClientDlg message handlers
  85. BOOL CQQClientDlg::OnInitDialog()
  86. {
  87. CDialog::OnInitDialog();
  88. // Add "About..." menu item to system menu.
  89. // IDM_ABOUTBOX must be in the system command range.
  90. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  91. ASSERT(IDM_ABOUTBOX < 0xF000);
  92. CMenu* pSysMenu = GetSystemMenu(FALSE);
  93. if (pSysMenu != NULL)
  94. {
  95. CString strAboutMenu;
  96. strAboutMenu.LoadString(IDS_ABOUTBOX);
  97. if (!strAboutMenu.IsEmpty())
  98. {
  99. pSysMenu->AppendMenu(MF_SEPARATOR);
  100. pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  101. }
  102. }
  103. // Set the icon for this dialog.  The framework does this automatically
  104. //  when the application's main window is not a dialog
  105. SetIcon(m_hIcon, TRUE); // Set big icon
  106. SetIcon(m_hIcon, FALSE); // Set small icon
  107. // TODO: Add extra initialization here
  108. SetWindowText(_userID);
  109. initFriendList();
  110. sockaddr_in serverAddr;
  111. CQQSocket::stringToIPAddr(_serverIP, serverAddr);
  112. serverAddr.sin_port = htons(6000);
  113. _comm.startListen(this, _userID, serverAddr);
  114. return TRUE;  // return TRUE  unless you set the focus to a control
  115. }
  116. void CQQClientDlg::OnSysCommand(UINT nID, LPARAM lParam)
  117. {
  118. if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  119. {
  120. CAboutDlg dlgAbout;
  121. dlgAbout.DoModal();
  122. }
  123. else
  124. {
  125. CDialog::OnSysCommand(nID, lParam);
  126. }
  127. }
  128. // If you add a minimize button to your dialog, you will need the code below
  129. //  to draw the icon.  For MFC applications using the document/view model,
  130. //  this is automatically done for you by the framework.
  131. void CQQClientDlg::OnPaint() 
  132. {
  133. if (IsIconic())
  134. {
  135. CPaintDC dc(this); // device context for painting
  136. SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  137. // Center icon in client rectangle
  138. int cxIcon = GetSystemMetrics(SM_CXICON);
  139. int cyIcon = GetSystemMetrics(SM_CYICON);
  140. CRect rect;
  141. GetClientRect(&rect);
  142. int x = (rect.Width() - cxIcon + 1) / 2;
  143. int y = (rect.Height() - cyIcon + 1) / 2;
  144. // Draw the icon
  145. dc.DrawIcon(x, y, m_hIcon);
  146. }
  147. else
  148. {
  149. CDialog::OnPaint();
  150. }
  151. }
  152. // The system calls this to obtain the cursor to display while the user drags
  153. //  the minimized window.
  154. HCURSOR CQQClientDlg::OnQueryDragIcon()
  155. {
  156. return (HCURSOR) m_hIcon;
  157. }
  158. void CQQClientDlg::OnBtnAddFriend() 
  159. {
  160. // TODO: Add your control notification handler code here
  161. CAddFriendDlg dlg;
  162. dlg._userID = _userID;
  163. dlg._serverIP = _serverIP;
  164. if (dlg.DoModal() != IDOK)
  165. return ;
  166. CFriendData friendData;
  167. if (queryUser(dlg._friendID, friendData) != S_OK)
  168. {
  169. friendData.userID = dlg._friendID;
  170. friendData.nickname = dlg._friendID;
  171. ::ZeroMemory(&friendData.addr, sizeof(sockaddr_in));
  172. }
  173. _friendList.addFriend(friendData);
  174. int itemCount = _obFriendList.GetItemCount();
  175. _obFriendList.InsertItem(0, itemCount, friendData.nickname, itemCount % 7);
  176. _obFriendList.Invalidate(TRUE);
  177. _obFriendList.UpdateWindow();
  178. }
  179. void CQQClientDlg::initFriendList(void)
  180. {
  181. DWORD flags = CGfxOutBarCtrl::fDragItems |
  182. CGfxOutBarCtrl::fEditGroups |
  183. CGfxOutBarCtrl::fEditItems |
  184. CGfxOutBarCtrl::fRemoveGroups |
  185. CGfxOutBarCtrl::fRemoveItems |
  186. CGfxOutBarCtrl::fAddGroups;
  187. CRect rcList;
  188. CWnd *outbar = GetDlgItem(IDC_STATIC_LIST);
  189. outbar->GetWindowRect(rcList);
  190. ScreenToClient(rcList);
  191. _obFriendList.Create(WS_CHILD | WS_VISIBLE, 
  192. rcList,
  193. this,
  194. IDC_STATIC_LIST,
  195. flags);
  196. _obFriendList.SetOwner(this);
  197. _headIconList.Create(IDB_HEADICON_LIST, 32, 0, RGB(0, 128, 128));
  198. _obFriendList.SetImageList(&_headIconList, CGfxOutBarCtrl::fLargeIcon);
  199. _obFriendList.SetAnimationTickCount(10);
  200. _obFriendList.AddFolder(_T("好友列表"), 0);
  201. _obFriendList.AddFolder(_T("黑名单"), 1);
  202. if (downloadFriends() != S_OK)
  203. return ;
  204. int friendCount = _friendList.getCount();
  205. for(int i = 0; i < friendCount; i++)
  206. {
  207. CFriendData *data = _friendList.getFriend(i);
  208. _ASSERTE(data != NULL);
  209. if (data == NULL)
  210. continue ;
  211. _obFriendList.InsertItem(0, i, data->nickname, i % 7);
  212. }
  213. _obFriendList.SetSelFolder(0);
  214. }
  215. void CQQClientDlg::clear()
  216. {
  217. _friendList.clear();
  218. _obFriendList.SetSelFolder(0);
  219. int itemCount = _obFriendList.GetItemCount();
  220. for(int i = 0; i < itemCount; i++)
  221. _obFriendList.RemoveItem(i);
  222. }
  223. HRESULT CQQClientDlg::queryUser(CString userID, CFriendData &friendData)
  224. {
  225. CCommunication comm;
  226. if (comm.create() != S_OK)
  227. return E_FAIL;
  228. if (comm.connect(_serverIP) != S_OK)
  229. return E_FAIL;
  230. if (comm.sendQueryUserRequest(userID) != S_OK)
  231. return E_FAIL;
  232. CXMLParser parser;
  233. if (comm.receiveResponse(parser, 5000, FALSE) != S_OK)
  234. return E_FAIL;
  235. CElement *root = parser.get_root();
  236. if (root->getChildContent(_T("userID")) != userID)
  237. return E_FAIL;
  238. friendData.userID = userID;
  239. friendData.nickname = root->getChildContent(_T("nickname"));
  240. if (root->getChildContent(_T("online")) == _T("true"))
  241. {
  242. CQQSocket::stringToIPAddr(root->getChildContent(_T("ipAddr")), friendData.addr);
  243. CString port = root->getChildContent(_T("port"));
  244. friendData.addr.sin_port = _ttoi(port);
  245. friendData.online = TRUE;
  246. }
  247. else
  248. friendData.online = FALSE;
  249. return S_OK;
  250. }
  251. HRESULT CQQClientDlg::downloadFriends()
  252. {
  253. clear();
  254. CCommunication comm;
  255. if (comm.create() != S_OK)
  256. return E_FAIL;
  257. if (comm.connect(_serverIP) != S_OK)
  258. return E_FAIL;
  259. comm.sendDownloadFriendsRequest(_userID);
  260. CXMLParser parser;
  261. if (comm.receiveResponse(parser) != S_OK)
  262. return E_FAIL;
  263. CElement *root = parser.get_root();
  264. CElementList friendList;
  265. root->GetChildrenByTag(_T("friend"), friendList);
  266. POSITION pos = friendList.GetHeadPosition();
  267. while(pos != NULL)
  268. {
  269. CElement *friendEle = friendList.GetNext(pos);
  270. _ASSERTE(friendEle != NULL);
  271. if (friendEle == NULL)
  272. continue ;
  273. CString friendID = friendEle->get_content();
  274. CFriendData friendData;
  275. if (queryUser(friendID, friendData) != S_OK)
  276. {
  277. friendData.userID = friendID;
  278. friendData.nickname = friendID;
  279. ::ZeroMemory(&friendData.addr, sizeof(sockaddr_in));
  280. }
  281. _friendList.addFriend(friendData);
  282. }
  283. return S_OK;
  284. }
  285. void CQQClientDlg::OnDestroy()
  286. {
  287. CCommunication comm;
  288. if (comm.create() != S_OK)
  289. return ;
  290. if (comm.connect(_serverIP) != S_OK)
  291. return ;
  292. comm.sendLogoffRequest(_userID);
  293. _comm.stopListen();
  294. CDialog::OnDestroy();
  295. // TODO: Add your message handler code here
  296. DialogIterator it = _dialogVector.begin();
  297. for (;it != _dialogVector.end(); it++)
  298. {
  299. (*it)->DestroyWindow();
  300. delete (*it);
  301. }
  302. }
  303. HRESULT CQQClientDlg::sendMessageToFriend(int index)
  304. {
  305. CFriendData *friendData = _friendList.getFriend(index);
  306. _ASSERTE(friendData != NULL);
  307. if (friendData == NULL)
  308. return E_FAIL;
  309. CSendDlg *dlg = NULL;
  310. DialogIterator it = _dialogVector.begin();
  311. for (;it != _dialogVector.end(); it++)
  312. {
  313. if ( ((CSendDlg*)(*it))->_friendID == friendData->userID )
  314. {
  315. dlg = (CSendDlg*)(*it);
  316. dlg->SetFocus();
  317. return S_OK;
  318. }
  319. }
  320. if (queryUser(friendData->userID, *friendData) != S_OK)
  321. {
  322. AfxMessageBox(_T("错误:连接服务器,查询用户数据失败"));
  323. return E_FAIL;
  324. }
  325. if (friendData->online == FALSE)
  326. {
  327. AfxMessageBox(_T("该用户不在线上."));
  328. return E_FAIL;
  329. }
  330. dlg = new CSendDlg(this);
  331. dlg->_friendName = friendData->nickname;
  332. dlg->_friendID = friendData->userID;
  333. dlg->_userID = _userID;
  334. dlg->_userName = _nickname;
  335. memcpy(&dlg->_friendAddr, &friendData->addr, sizeof(sockaddr_in));
  336. dlg->Create(IDD_SENDMSG);
  337. dlg->ShowWindow(SW_SHOW);
  338. _dialogVector.push_back(dlg);
  339. return S_OK;
  340. }
  341. LRESULT CQQClientDlg::OnSenddlgClosed(WPARAM wParam, LPARAM lParam)
  342. {
  343. TCHAR *friendID = (TCHAR*)wParam;
  344. CSendDlg *dlg = NULL;
  345. DialogIterator it = _dialogVector.begin();
  346. for (;it != _dialogVector.end(); it++)
  347. {
  348. if ( ((CSendDlg*)(*it))->_friendID == friendID )
  349. {
  350. dlg = (CSendDlg*)(*it);
  351. _dialogVector.erase(it);
  352. break ;
  353. }
  354. }
  355. delete[] friendID;
  356. if (dlg != NULL)
  357. delete dlg;
  358. return 0;
  359. }
  360. LRESULT CQQClientDlg::OnListenNotify(WPARAM wParam, LPARAM lParam)
  361. {
  362. TCHAR *message = (TCHAR*)wParam;
  363. TCHAR *friendID = (TCHAR*)lParam;
  364. CSendDlg *dlg = NULL;
  365. DialogIterator it = _dialogVector.begin();
  366. for (;it != _dialogVector.end(); it++)
  367. {
  368. if ( ((CSendDlg*)(*it))->_friendID == friendID )
  369. {
  370. dlg = (CSendDlg*)(*it);
  371. break ;
  372. }
  373. }
  374. CFriendData friendData;
  375. if (queryUser(friendID, friendData) != S_OK)
  376. {
  377. if (dlg != NULL)
  378. friendData.nickname = friendID;
  379. else
  380. return 0;
  381. }
  382. if (dlg == NULL)
  383. {
  384. dlg = new CSendDlg(this);
  385. dlg->_friendName = friendData.nickname;
  386. dlg->_friendID = friendData.userID;
  387. dlg->_userID = _userID;
  388. dlg->_userName = _nickname;
  389. memcpy(&dlg->_friendAddr, &friendData.addr, sizeof(sockaddr_in));
  390. dlg->Create(IDD_SENDMSG);
  391. dlg->ShowWindow(SW_SHOW);
  392. _dialogVector.push_back(dlg);
  393. }
  394. dlg->insertMessage(friendData.nickname, message);
  395. delete[] friendID;
  396. delete[] message;
  397. return 0;
  398. }
  399. LRESULT CQQClientDlg::OnOutbarNotify(WPARAM wParam, LPARAM lParam)
  400. {
  401. switch(wParam)
  402. {
  403. case NM_OB_ITEMCLICK:
  404. {
  405. int index = (int)lParam;
  406. sendMessageToFriend(index);
  407. break ;
  408. }
  409. }
  410. return 0;
  411. }