myicqDlg.cpp
上传用户:zslianheng
上传日期:2013-04-03
资源大小:946k
文件大小:49k
源码类别:

Linux/Unix编程

开发平台:

Visual C++

  1. /***************************************************************************
  2.  *                                                                         *
  3.  *   This program is free software; you can redistribute it and/or modify  *
  4.  *   it under the terms of the GNU General Public License as published by  *
  5.  *   the Free Software Foundation; either version 2 of the License, or     *
  6.  *   (at your option) any later version.                                   *
  7.  *                                                                         *
  8.  *   copyright            : (C) 2002 by Zhang Yong                         *
  9.  *   email                : z-yong163@163.com                              *
  10.  ***************************************************************************/
  11. // myicqDlg.cpp : implementation file
  12. //
  13. #include "stdafx.h"
  14. #include "myicq.h"
  15. #include "myicqDlg.h"
  16. #include <mmsystem.h>
  17. #include "serversession.h"
  18. #include "tcpsession.h"
  19. #include "icqwindow.h"
  20. #include "icqdb.h"
  21. #include "icqconfig.h"
  22. #include "icqplugin.h"
  23. #include "GfxPopupMenu.h"
  24. #include "LoginDlg.h"
  25. #include "RegWizard.h"
  26. #include "ViewDetailDlg.h"
  27. #include "SendMsgDlg.h"
  28. #include "SearchWizard.h"
  29. #include "SysMsgDlg.h"
  30. #include "ViewMsgDlg.h"
  31. #include "SysHistoryDlg.h"
  32. #include "DelFriendDlg.h"
  33. #include "ModifyDetailDlg.h"
  34. #include "SysOptionDlg.h"
  35. #include "LoginAgainDlg.h"
  36. #include "NotifyWnd.h"
  37. #include "AboutDlg.h"
  38. #include "MsgMgrWnd.h"
  39. #include "SendRequestDlg.h"
  40. #include "BroadcastDlg.h"
  41. #ifdef _DEBUG
  42. #define new DEBUG_NEW
  43. #undef THIS_FILE
  44. static char THIS_FILE[] = __FILE__;
  45. #endif
  46. #define ID_GFX_SHOWONLINE 50001
  47. #define ID_GFX_RENAME 50002
  48. #define ID_GFX_REMOVE 50003
  49. #define ID_STATUS_AWAY 40000
  50. #define ID_PLUGIN 60000
  51. #define ID_SKIN_FIRST 70000
  52. #define IDC_OUTBAR 1001
  53. #define ID_HOTKEY 1002
  54. #define ID_TOOLTIP 1003
  55. #define ID_NOTIFYICON 1004
  56. #define IDT_RESEND 1001
  57. #define IDT_KEEPALIVE 1002
  58. #define IDT_STATUS 1003
  59. #define IDT_BLINK 1004
  60. #define IDT_DBLCLK 1005
  61. #define IDT_HOVER 1006
  62. #define IDT_AUTO_SWITCH_STATUS 1007
  63. #define WM_HOSTFOUND (WM_USER + 101)
  64. #define WM_NOTIFYICON (WM_USER + 102)
  65. #define HOTKEY_DEFAULT MAKELONG(0x5a, MOD_CONTROL | MOD_ALT)
  66. enum {
  67. ALIGN_NONE,
  68. ALIGN_TOP,
  69. ALIGN_LEFT,
  70. ALIGN_RIGHT
  71. };
  72. /////////////////////////////////////////////////////////////////////////////
  73. // CIcqDlg dialog
  74. CIcqDlg::CIcqDlg(CWnd* pParent /*=NULL*/)
  75. : CCaptionBtnDlg(2, CIcqDlg::IDD, pParent)
  76. {
  77. //{{AFX_DATA_INIT(CIcqDlg)
  78. //}}AFX_DATA_INIT
  79. // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  80. iconBlank = (HICON)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_BLANK),
  81. IMAGE_ICON, 0, 0, 0);
  82. iconSysMsg = (HICON)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_SYSMSG),
  83. IMAGE_ICON, 0, 0, 0);
  84. regMode = -1;
  85. alignType = ALIGN_NONE;
  86. isHide = FALSE;
  87. currentMenu = NULL;
  88. curContact = NULL;
  89. outbarCtrl.setListener(this);
  90. outbarCtrl.setImageList(&getApp()->largeImageList, &getApp()->smallImageList);
  91. }
  92. CIcqDlg::~CIcqDlg()
  93. {
  94. }
  95. void *CIcqDlg::getFaceIcon(int face, int status)
  96. {
  97. int i = getApp()->getImageIndex(face, status);
  98. return (void *) getApp()->largeImageList.ExtractIcon(i);
  99. }
  100. void CIcqDlg::popupMsg(void *icon, const char *text, uint32 t)
  101. {
  102. new CNotifyWnd((HICON) icon, text, t);
  103. }
  104. void CIcqDlg::drawCaptionBtn(CDC *pDC, CRect &rc, int button, BOOL pressed)
  105. {
  106. ASSERT(button < 2);
  107. if (!pressed) {
  108. pDC->Draw3dRect(rc, GetSysColor(COLOR_BTNHILIGHT), GetSysColor(COLOR_3DDKSHADOW));
  109. rc.InflateRect(-1, -1);
  110. pDC->Draw3dRect(rc, GetSysColor(COLOR_BTNFACE), GetSysColor(COLOR_3DSHADOW));
  111. } else {
  112. pDC->Draw3dRect(rc, GetSysColor(COLOR_3DDKSHADOW), GetSysColor(COLOR_BTNHILIGHT));
  113. rc.InflateRect(-1, -1);
  114. pDC->Draw3dRect(rc, GetSysColor(COLOR_3DSHADOW), GetSysColor(COLOR_BTNFACE));
  115. }
  116. rc.InflateRect(-1, -1);
  117. pDC->FillSolidRect(rc, GetSysColor(COLOR_BTNFACE));
  118. CPen pen(PS_SOLID, 1, GetSysColor(COLOR_BTNTEXT));
  119. CPen *penOld = pDC->SelectObject(&pen);
  120. int x, y;
  121. x = rc.left;
  122. y = (rc.top + rc.bottom) / 2;
  123. if (pressed) {
  124. x++;
  125. y++;
  126. }
  127. pDC->MoveTo(x, y);
  128. pDC->LineTo(x + rc.Width() - 2, y);
  129. if (button == 1) {
  130. x = (rc.left + rc.right) / 2 - 1;
  131. y = rc.top + 1;
  132. if (pressed) {
  133. x++;
  134. y++;
  135. }
  136. pDC->MoveTo(x, y);
  137. pDC->LineTo(x, y + rc.Height() - 2);
  138. }
  139. pDC->SelectObject(penOld);
  140. }
  141. void CIcqDlg::onCaptionBtnClicked(int button)
  142. {
  143. ASSERT(button < 2);
  144. if (button == 0) {
  145. ShowWindow(SW_MINIMIZE);
  146. ShowWindow(SW_HIDE);
  147. } else if (button == 1) {
  148. CGfxPopupMenu menu;
  149. menu.CreatePopupMenu();
  150. int id = 1000;
  151. menu.appendMenu(id, options.skin.empty() ? IDB_CHECK : IDB_FOLDER, IDS_SKIN_RESTORE);
  152. CFileFind finder;
  153. BOOL cont = finder.FindFile(getApp()->rootDir + "skins\*");
  154. while (cont) {
  155. cont = finder.FindNextFile();
  156. if (!finder.IsDots() && finder.IsDirectory()) {
  157. int bmpID = (finder.GetFileTitle() == options.skin.c_str() ? IDB_CHECK : IDB_FOLDER);
  158. menu.appendMenu(++id, bmpID, finder.GetFileTitle());
  159. }
  160. }
  161. CPoint pt;
  162. GetCursorPos(&pt);
  163. id = menu.TrackPopupMenu(TPM_RETURNCMD, pt.x, pt.y, this);
  164. if (id == 0)
  165. return;
  166. ShowWindow(SW_MINIMIZE);
  167. if (id == 1000) {
  168. outbarCtrl.setSkin(NULL);
  169. options.skin = "";
  170. } else {
  171. CString str;
  172. menu.GetMenuString(id, str, 0);
  173. if (skin.load(getApp()->rootDir + "skins\" + str))
  174. outbarCtrl.setSkin(&skin);
  175. options.skin = str;
  176. }
  177. IcqDB::saveOptions(options);
  178. ShowWindow(SW_NORMAL);
  179. }
  180. }
  181. void CIcqDlg::onSendError(uint32 seq)
  182. {
  183. if (!seq) {
  184. // Destination port is unreachable.
  185. IcqWindow *win = findWindow(WIN_REG_WIZARD);
  186. if (win) {
  187. ((CRegWizard *) win)->onSendError(seq);
  188. return;
  189. }
  190. } else if (lastSeq != seq) {
  191. IcqLink::onSendError(seq);
  192. return;
  193. }
  194. lastSeq = 0;
  195. onError();
  196. }
  197. void CIcqDlg::onConnect(bool success)
  198. {
  199. IcqWindow *win = findWindow(WIN_REG_WIZARD);
  200. if (win) {
  201. ((CRegWizard *) win)->onConnect(success);
  202. return;
  203. }
  204. if (success)
  205. lastSeq = serverSession()->login(myInfo.passwd.c_str(), pendingStatus);
  206. else {
  207. myInfo.status = STATUS_OFFLINE;
  208. updateStatusIcon();
  209. logout();
  210. }
  211. }
  212. IcqContact *CIcqDlg::addContact(uint32 uin, int folder)
  213. {
  214. outbarCtrl.removeContact(uin);
  215. IcqContact *c = findContact(uin);
  216. if (!c) {
  217. c = new IcqContact;
  218. c->uin = uin;
  219. CString nick;
  220. nick.Format("%lu", uin);
  221. c->nick = nick;
  222. contactList.push_back(c);
  223. }
  224. int n = outbarCtrl.getFolderCount();
  225. if (folder == n - 1)
  226. c->type = CONTACT_IGNORE;
  227. else if (folder == n - 2)
  228. c->type = CONTACT_STRANGER;
  229. else
  230. c->type = CONTACT_FRIEND;
  231. outbarCtrl.addContact(folder, c);
  232. outbarCtrl.repaintInsideRect();
  233. saveGroupInfo();
  234. return c;
  235. }
  236. void CIcqDlg::login(uint32 status)
  237. {
  238. pendingStatus = status;
  239. SetTimer(IDT_STATUS, 250, NULL);
  240. m_btnStatus.setText(IDS_STATUS_LOGGING_IN);
  241. resolveHost();
  242. }
  243. void CIcqDlg::logout()
  244. {
  245. IcqLink::logout();
  246. KillTimer(IDT_RESEND);
  247. KillTimer(IDT_KEEPALIVE);
  248. KillTimer(IDT_AUTO_SWITCH_STATUS);
  249. PtrList::iterator it;
  250. for (it = contactList.begin(); it != contactList.end(); ++it) {
  251. IcqContact *c = (IcqContact *) *it;
  252. outbarCtrl.update(c->uin, TRUE);
  253. }
  254. }
  255. void CIcqDlg::addFriend(IcqContact *c, int folder)
  256. {
  257. if (folder < 0)
  258. folder = outbarCtrl.getSelFolder();
  259. c->type = CONTACT_FRIEND;
  260. CSysMsgDlg *win = new CSysMsgDlg(c->uin);
  261. win->Create(IDD_SYS_MESSAGE);
  262. }
  263. BOOL CIcqDlg::delFriend(IcqContact *c, int folder)
  264. {
  265. CString str;
  266. str.Format(IDS_PROMPT_DEL_FRIEND, c->uin);
  267. if (AfxMessageBox(str, MB_YESNO) != IDYES)
  268. return FALSE;
  269. {
  270. CDelFriendDlg dlg(c->uin);
  271. if (dlg.DoModal() != IDOK)
  272. return FALSE;
  273. }
  274. int n = outbarCtrl.getFolderCount();
  275. if (folder == n - 1 || folder < 0)
  276. destroyContact(c->uin);
  277. if (folder == n - 2 || folder < 0)
  278. IcqDB::delContact(c->uin);
  279. outbarCtrl.removeContact(c->uin);
  280. if (folder >= 0) {
  281. outbarCtrl.addContact(folder, c);
  282. saveGroupInfo();
  283. c->type = (folder == n - 1 ? CONTACT_IGNORE : CONTACT_STRANGER);
  284. } else {
  285. contactList.remove(c);
  286. delete c;
  287. }
  288. return TRUE;
  289. }
  290. void CIcqDlg::onHostFound(in_addr &addr)
  291. {
  292. if (addr.s_addr != INADDR_NONE)
  293. serverSession()->connect(inet_ntoa(addr), options.port);
  294. else
  295. onError();
  296. }
  297. void CIcqDlg::onlineNotify(IcqContact *c)
  298. {
  299. if (options.flags.test(UF_ONLINE_NOTIFY)) {
  300. options.playSound(SOUND_ONLINE, c);
  301. outbarCtrl.blinkText(c->uin);
  302. if (c->flags.test(CF_OPTION_POPUP_ONLINE)) {
  303. CString str;
  304. str.Format(IDS_NOTIFY_ONLINE, c->nick.c_str(), c->uin);
  305. new CNotifyWnd(getApp()->largeImageList.ExtractIcon(c->face), str);
  306. }
  307. }
  308. }
  309. void CIcqDlg::addNotifyIcon()
  310. {
  311. NOTIFYICONDATA tnid;
  312. tnid.cbSize = sizeof(NOTIFYICONDATA);
  313. tnid.hWnd = m_hWnd;
  314. tnid.uID = ID_NOTIFYICON;
  315. tnid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
  316. tnid.uCallbackMessage = WM_NOTIFYICON;
  317. tnid.hIcon = getApp()->m_hIcon;
  318. lstrcpy(tnid.szTip, AfxGetAppName());
  319. Shell_NotifyIcon(NIM_ADD, &tnid);
  320. }
  321. void CIcqDlg::removeNotifyIcon()
  322. {
  323. NOTIFYICONDATA tnid;
  324. tnid.cbSize = sizeof(NOTIFYICONDATA);
  325. tnid.hWnd = m_hWnd;
  326. tnid.uID = ID_NOTIFYICON;
  327. Shell_NotifyIcon(NIM_DELETE, &tnid);
  328. }
  329. void CIcqDlg::modifyNotifyIcon(HICON hIcon)
  330. {
  331. NOTIFYICONDATA tnid;
  332. tnid.cbSize = sizeof(NOTIFYICONDATA);
  333. tnid.hWnd = m_hWnd;
  334. tnid.uID = ID_NOTIFYICON;
  335. tnid.uFlags = NIF_ICON;
  336. tnid.hIcon = hIcon;
  337. Shell_NotifyIcon(NIM_MODIFY, &tnid);
  338. }
  339. void CIcqDlg::popupMainMenu(UINT nFlags, CPoint &pt)
  340. {
  341. CGfxPopupMenu menu;
  342. CMenu tmp;
  343. tmp.LoadMenu(IDR_MAIN);
  344. menu.Attach(*tmp.GetSubMenu(0));
  345. CGfxPopupMenu fileMenu;
  346. fileMenu.Attach(*menu.GetSubMenu(0));
  347. fileMenu.modifyMenu(ID_MESSAGE_MGR, IDB_MSG_HISTORY);
  348. fileMenu.modifyMenu(ID_CONTACT_MGR, IDB_CONTACT_MGR);
  349. menu.modifyMenu(0, IDB_FILEMGR, FALSE);
  350. menu.modifyMenu(ID_CHANGE_USER, IDB_CHANGE_USER);
  351. menu.modifyMenu(ID_REG_WIZARD, IDB_REG_WIZARD);
  352. menu.modifyMenu(ID_MODIFY_INFO, IDB_VIEW_DETAIL);
  353. menu.modifyMenu(ID_SYS_OPTION, IDB_SYS_OPTION);
  354. menu.modifyMenu(ID_HELP, IDB_HELP);
  355. menu.modifyMenu(ID_APP_EXIT, IDB_EXIT);
  356. if (myInfo.uin >= 1000)
  357. menu.DeleteMenu(ID_BROADCAST_MSG, 0);
  358. else
  359. menu.modifyMenu(ID_BROADCAST_MSG, iconSysMsg);
  360. menu.setVertBitmap(IDB_VERT);
  361. currentMenu = &menu;
  362. menu.TrackPopupMenu(nFlags, pt.x, pt.y, this);
  363. currentMenu = NULL;
  364. }
  365. void CIcqDlg::popupStatusMenu(UINT nFlags, CPoint &pt)
  366. {
  367. CMenu tmp;
  368. tmp.LoadMenu(IDR_STATUS);
  369. CGfxPopupMenu statusMenu;
  370. statusMenu.Attach(*tmp.GetSubMenu(0));
  371. CGfxPopupMenu awayMenu;
  372. awayMenu.Attach(*statusMenu.GetSubMenu(2));
  373. statusMenu.modifyMenu(ID_STATUS_ONLINE, IDB_STATUS_ONLINE);
  374. statusMenu.modifyMenu(2, IDB_STATUS_AWAY, FALSE);
  375. statusMenu.modifyMenu(ID_STATUS_INVIS, IDB_STATUS_INVIS);
  376. statusMenu.modifyMenu(ID_STATUS_OFFLINE, IDB_STATUS_OFFLINE);
  377. bool autoReply = options.flags.test(UF_AUTO_REPLY);
  378. UINT bitmap;
  379. StrList l;
  380. IcqDB::loadAutoReply(l);
  381. int pos = 0;
  382. UINT id = ID_STATUS_AWAY;
  383. StrList::iterator it;
  384. for (it = l.begin(); it != l.end(); ++it) {
  385. bitmap = (autoReply && *it == options.autoReplyText) ?
  386. IDB_STATUS_AWAY : IDB_STATUS_OFFLINE;
  387. CString str = (*it).c_str();
  388. if (str.GetLength() > 20)
  389. str = str.Left(20) + "...";
  390. awayMenu.InsertMenu(pos, MF_BYPOSITION, id++, str);
  391. awayMenu.modifyMenu(pos++, bitmap, FALSE);
  392. awayMenu.InsertMenu(pos++, MF_SEPARATOR | MF_BYPOSITION);
  393. }
  394. bitmap = autoReply ? IDB_STATUS_OFFLINE : IDB_STATUS_AWAY;
  395. awayMenu.modifyMenu(ID_STATUS_AWAY_NOREPLY, bitmap);
  396. awayMenu.modifyMenu(ID_STATUS_AWAY_CUSTOM, IDB_SYS_OPTION);
  397. currentMenu = &statusMenu;
  398. statusMenu.TrackPopupMenu(nFlags, pt.x, pt.y, this);
  399. currentMenu = NULL;
  400. }
  401. void CIcqDlg::updateStatusIcon()
  402. {
  403. KillTimer(IDT_STATUS);
  404. switch (myInfo.status) {
  405. case STATUS_ONLINE:
  406. m_btnStatus.setText(IDS_STATUS_ONLINE);
  407. break;
  408. case STATUS_OFFLINE:
  409. m_btnStatus.setText(IDS_STATUS_OFFLINE);
  410. break;
  411. case STATUS_AWAY:
  412. m_btnStatus.setText(IDS_STATUS_AWAY);
  413. break;
  414. case STATUS_INVIS:
  415. m_btnStatus.setText(IDS_STATUS_INVIS);
  416. break;
  417. }
  418. HICON hIcon = statusImgList.ExtractIcon(myInfo.status);
  419. m_btnStatus.SetIcon(hIcon);
  420. modifyNotifyIcon(hIcon);
  421. }
  422. void CIcqDlg::animateStatus()
  423. {
  424. SetTimer(IDT_STATUS, 250, NULL);
  425. OnTimer(IDT_STATUS);
  426. }
  427. void CIcqDlg::hideWindow(BOOL hide)
  428. {
  429. CRect rc;
  430. GetWindowRect(rc);
  431. int moves = 20;
  432. int xStep, yStep;
  433. int xEnd, yEnd;
  434. int cxScreen;
  435. switch (alignType) {
  436. case ALIGN_TOP:
  437. xStep = 0;
  438. xEnd = rc.left;
  439. if (hide) {
  440. yStep = -rc.bottom / moves;
  441. yEnd = -rc.Height() + 2;
  442. } else {
  443. yStep = -rc.top / moves;
  444. yEnd = 0;
  445. }
  446. break;
  447. case ALIGN_LEFT:
  448. yStep = 0;
  449. yEnd = rc.top;
  450. if (hide) {
  451. xStep = -rc.right / moves;
  452. xEnd = -rc.Width() + 2;
  453. } else {
  454. xStep = -rc.left / moves;
  455. xEnd = 0;
  456. }
  457. break;
  458. case ALIGN_RIGHT:
  459. yStep = 0;
  460. yEnd = rc.top;
  461. cxScreen = GetSystemMetrics(SM_CXSCREEN);
  462. if (hide) {
  463. xStep = (cxScreen - rc.left) / moves;
  464. xEnd = cxScreen - 2;
  465. } else {
  466. xStep = (cxScreen - rc.right) / moves;
  467. xEnd = cxScreen - rc.Width();
  468. }
  469. break;
  470. }
  471. for (int i = 0; i < moves; i++) {
  472. rc.left += xStep;
  473. rc.top += yStep;
  474. SetWindowPos(NULL, rc.left, rc.top, 0, 0, SWP_NOSIZE | SWP_NOSENDCHANGING);
  475. RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE | RDW_ALLCHILDREN);
  476. Sleep(20);
  477. }
  478. SetWindowPos(NULL, xEnd, yEnd, 0, 0, SWP_NOSIZE);
  479. isHide = hide;
  480. if (!isHide)
  481. SetTimer(IDT_HOVER, 50, NULL);
  482. }
  483. void CIcqDlg::addPendingMsg(IcqMsg *msg)
  484. {
  485. if (msgList.empty())
  486. SetTimer(IDT_BLINK, 400, NULL);
  487. if (!msg->isSysMsg() && !findPendingMsg(msg->uin))
  488. outbarCtrl.blinkImage(msg->uin);
  489. IcqLink::addPendingMsg(msg);
  490. }
  491. void CIcqDlg::onNewUINReply(uint32 uin)
  492. {
  493. myInfo.uin = uin;
  494. IcqWindow *win = findWindow(WIN_REG_WIZARD);
  495. if (win)
  496. ((CRegWizard *) win)->onNewUINReply(uin);
  497. }
  498. void CIcqDlg::onContactListReply(UinList &l)
  499. {
  500. IcqWindow *win = findWindow(WIN_REG_WIZARD);
  501. if (win) {
  502. uinList = l;
  503. ((CRegWizard *) win)->onContactListReply();
  504. }
  505. }
  506. void CIcqDlg::onLoginReply(uint16 error)
  507. {
  508. IcqWindow *win = findWindow(WIN_REG_WIZARD);
  509. if (win) {
  510. ((CRegWizard *) win)->onLoginReply(error);
  511. return;
  512. }
  513. lastSeq = 0;
  514. if (error != LOGIN_SUCCESS) {
  515. KillTimer(IDT_RESEND);
  516. AfxMessageBox(IDS_WRONG_PASSWD);
  517. return;
  518. }
  519. SetTimer(IDT_KEEPALIVE, KEEPALIVE_TIMEOUT * 1000, NULL);
  520. myInfo.status = pendingStatus;
  521. updateStatusIcon();
  522. if (regMode == 0)
  523. serverSession()->modifyUser(&myInfo);
  524. else if (regMode == 1) {
  525. serverSession()->updateUser();
  526. while (!uinList.empty()) {
  527. uint32 uin = uinList.front();
  528. uinList.pop_front();
  529. serverSession()->updateContact(uin);
  530. }
  531. }
  532. regMode = -1;
  533. }
  534. void CIcqDlg::onUpdateContactReply(IcqContact *info)
  535. {
  536. IcqLink::onUpdateContactReply(info);
  537. IcqContact *c = findContact(info->uin);
  538. if (c) {
  539. IcqDB::saveContact(*c);
  540. outbarCtrl.update(c->uin);
  541. }
  542. IcqWindow *win = findWindow(WIN_VIEW_DETAIL, info->uin, serverSession()->ackseq);
  543. if (win)
  544. ((CViewDetailDlg *) win)->onUpdateContactReply(info);
  545. }
  546. void CIcqDlg::onUpdateUserReply()
  547. {
  548. IcqDB::saveUser(myInfo);
  549. }
  550. void CIcqDlg::onUserOnline(uint32 uin, uint32 status, uint32 ip, uint16 port, uint32 realIP, bool multi)
  551. {
  552. if (status != STATUS_ONLINE && status != STATUS_AWAY)
  553. return;
  554. IcqContact *c = findContact(uin, CONTACT_FRIEND);
  555. if (!c)
  556. c = addContact(uin);
  557. c->ip = ip;
  558. c->port = port;
  559. c->realIP = realIP;
  560. c->status = status;
  561. outbarCtrl.update(uin, TRUE);
  562. if (c->flags.test(CF_OPTION_INVISIBLE))
  563. OnStatusInvis();
  564. if (c->flags.test(CF_OPTION_GREETING) && !c->greeting.empty())
  565. sendMessage(MSG_TEXT, uin, c->greeting.c_str());
  566. if (!multi)
  567. onlineNotify(c);
  568. }
  569. void CIcqDlg::onUserOffline(uint32 uin)
  570. {
  571. IcqLink::onUserOffline(uin);
  572. outbarCtrl.update(uin, TRUE);
  573. IcqContact *c = findContact(uin);
  574. if (c && c->flags.test(CF_OPTION_POPUP_OFFLINE)) {
  575. CString str;
  576. str.Format(IDS_NOTIFY_OFFLINE, c->nick.c_str(), c->uin);
  577. new CNotifyWnd(getApp()->largeImageList.ExtractIcon(c->face), str);
  578. }
  579. }
  580. void CIcqDlg::onStatusChanged(uint32 uin, uint32 status)
  581. {
  582. if (status != STATUS_ONLINE && status != STATUS_AWAY)
  583. return;
  584. IcqContact *c = findContact(uin);
  585. if (c) {
  586. if (c->status != STATUS_ONLINE && status == STATUS_ONLINE)
  587. onlineNotify(c);
  588. c->status = status;
  589. outbarCtrl.update(uin);
  590. }
  591. }
  592. void CIcqDlg::onRecvMessage(IcqMsg *msg)
  593. {
  594. uint8 type = msg->type;
  595. uint32 from = msg->uin;
  596. BOOL relay = (msg->flags & MF_RELAY);
  597. if (type == MSG_AUTH_ACCEPTED) {
  598. serverSession()->updateContact(from);
  599. addContact(from);
  600. }
  601. IcqContact *c = findContact(from);
  602. if (!c && !msg->isSysMsg()) {
  603. int n = outbarCtrl.getFolderCount();
  604. c = addContact(from, n - 2);
  605. }
  606. if (msg->isSysMsg()) {
  607. options.playSound(SOUND_SYSMSG);
  608. addPendingMsg(msg);
  609. IcqDB::saveMsg(*msg);
  610. return;
  611. }
  612. if (!c)
  613. return;
  614. if (c->status == STATUS_OFFLINE && !relay) {
  615. c->status = STATUS_ONLINE;
  616. outbarCtrl.update(c->uin, TRUE);
  617. }
  618. options.playSound(SOUND_MSG, c);
  619. if (type == MSG_TCP_REQUEST) {
  620. addPendingMsg(msg);
  621. return;
  622. }
  623. IcqDB::saveMsg(*msg);
  624. // auto reply
  625. if ((myInfo.status == STATUS_AWAY) &&
  626. options.flags.test(UF_AUTO_REPLY) &&
  627. !options.autoReplyText.empty() &&
  628. type != MSG_AUTO_REPLY)
  629. sendMessage(MSG_AUTO_REPLY, from, options.autoReplyText.c_str());
  630. IcqWindow *win;
  631. if (c->flags.test(CF_DIALOGMODE)) {
  632. win = findWindow(WIN_SEND_MESSAGE, from);
  633. if (!win) {
  634. CSendMsgDlg *pDlg = new CSendMsgDlg(c);
  635. pDlg->Create(IDD_SEND_MESSAGE);
  636. win = pDlg;
  637. }
  638. ((CSendMsgDlg *) win)->onRecvMessage(*msg);
  639. delete msg;
  640. } else {
  641. addPendingMsg(msg);
  642. win = findWindow(WIN_VIEW_MESSAGE, from);
  643. if (win)
  644. ((CViewMsgDlg *) win)->onRecvMessage();
  645. else if (options.flags.test(UF_AUTO_POPUP_MSG)) {
  646. CViewMsgDlg *dlg = new CViewMsgDlg(c);
  647. dlg->Create(IDD_VIEW_MESSAGE);
  648. win = dlg;
  649. }
  650. }
  651. }
  652. void CIcqDlg::onUserFound(PtrList *l)
  653. {
  654. IcqWindow *win = findWindow(WIN_SEARCH_WIZARD, 0, serverSession()->ackseq);
  655. if (win)
  656. ((CSearchWizard *) win)->onUserFound(l);
  657. }
  658. void CIcqDlg::onAddFriendReply(uint32 uin, uint8 result)
  659. {
  660. uint16 seq = serverSession()->ackseq;
  661. IcqWindow *win;
  662. if (win = findWindow(WIN_SEARCH_WIZARD, uin, seq))
  663. ((CSearchWizard *) win)->onAddFriendReply(result);
  664. else if ((win = findWindow(WIN_SYS_MESSAGE, 0, seq)) ||
  665. (win = findWindow(WIN_ADD_FRIEND, uin, seq)))
  666. ((CSysMsgDlg *) win)->onAddFriendReply(result);
  667. else
  668. return;
  669. if (result == ADD_FRIEND_ACCEPTED) {
  670. serverSession()->updateContact(uin);
  671. addContact(uin);
  672. }
  673. }
  674. void CIcqDlg::setDefaultOptions()
  675. {
  676. static const char *files[NR_SOUNDS] = {
  677. "global.wav",
  678. "msg.wav",
  679. "system.wav",
  680. "folder.wav",
  681. };
  682. for (int i = 0; i < NR_SOUNDS; i++)
  683. options.soundFiles[i] = getApp()->rootDir + "sound\" + files[i];
  684. bitset<NR_USER_FLAGS> &flags = options.flags;
  685. flags.set(UF_ALWAYS_ON_TOP);
  686. flags.set(UF_TASKBAR_STYLE);
  687. flags.set(UF_ONLINE_NOTIFY);
  688. flags.set(UF_MONITOR_NETWORK);
  689. flags.set(UF_TASKBAR_ICON);
  690. flags.set(UF_USE_HOTKEY);
  691. flags.set(UF_DEFAULT_HOTKEY);
  692. flags.set(UF_SOUND_ON);
  693. CString str;
  694. int id;
  695. StrList l;
  696. for (id = IDS_QUICKREPLY_1; id <= IDS_QUICKREPLY_4; id++) {
  697. str.LoadString(id);
  698. l.push_back((LPCTSTR) str);
  699. }
  700. IcqDB::saveQuickReply(l);
  701. l.clear();
  702. for (id = IDS_AUTOREPLY_1; id <= IDS_AUTOREPLY_3; id++) {
  703. str.LoadString(id);
  704. l.push_back((LPCTSTR) str);
  705. }
  706. IcqDB::saveAutoReply(l);
  707. options.autoStatus = STATUS_AWAY;
  708. options.autoStatusTime = 10;
  709. outbarCtrl.removeAllFolders();
  710. str.LoadString(IDS_GROUP_FRIEND);
  711. outbarCtrl.addFolder(str);
  712. str.LoadString(IDS_GROUP_STRANGER);
  713. outbarCtrl.addFolder(str);
  714. str.LoadString(IDS_GROUP_BLACKLIST);
  715. outbarCtrl.addFolder(str);
  716. outbarCtrl.setSelFolder(0);
  717. }
  718. void CIcqDlg::onError()
  719. {
  720. updateStatusIcon();
  721. logout();
  722. }
  723. void CIcqDlg::resolveHost()
  724. {
  725. const char *host = options.host.c_str();
  726. if (options.flags.test(UF_USE_PROXY) && !options.proxy[options.proxyType].resolve)
  727. serverSession()->connect(host, options.port);
  728. else {
  729. struct in_addr addr;
  730. if ((addr.s_addr = inet_addr(host)) != INADDR_NONE)
  731. onHostFound(addr);
  732. else
  733. getHostByName(host);
  734. }
  735. }
  736. void CIcqDlg::initGUI()
  737. {
  738. CString str;
  739. str.Format("%lu", myInfo.uin);
  740. SetWindowText(str);
  741. #ifndef _DEBUG
  742. SetWindowPos(options.flags.test(UF_ALWAYS_ON_TOP) ? &wndTopMost : &wndNoTopMost,
  743. 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
  744. #endif
  745. removeNotifyIcon();
  746. if (options.flags.test(UF_TASKBAR_ICON))
  747. addNotifyIcon();
  748. UnregisterHotKey(m_hWnd, ID_HOTKEY);
  749. if (options.flags.test(UF_USE_HOTKEY)) {
  750. uint32 hotKey = (options.flags.test(UF_DEFAULT_HOTKEY) ?
  751. HOTKEY_DEFAULT : options.hotKey);
  752. if (!RegisterHotKey(m_hWnd, ID_HOTKEY, HIWORD(hotKey), LOWORD(hotKey)))
  753. AfxMessageBox(IDS_FAILED_HOTKEY);
  754. }
  755. outbarCtrl.setShowOnlineOnly(options.flags.test(UF_SHOW_ONLINE));
  756. PtrList &l = PluginFactory::getPluginList();
  757. PtrList::iterator it;
  758. for (it = l.begin(); it != l.end(); ++it) {
  759. IcqPlugin *p = (IcqPlugin *) *it;
  760. if (p->type == ICQ_PLUGIN_TOY)
  761. ((ToyPlugin *) p)->init(icqLink, getApp()->getProfile(p->name.c_str()));
  762. }
  763. if (options.skin.empty())
  764. outbarCtrl.setSkin(NULL);
  765. else if (skin.load(getApp()->rootDir + "skins\" + options.skin.c_str()))
  766. outbarCtrl.setSkin(&skin);
  767. }
  768. BOOL CIcqDlg::doRegWizard()
  769. {
  770. destroyUser();
  771. SetTimer(IDT_RESEND, SEND_TIMEOUT * 1000, NULL);
  772. {
  773. CRegWizard wiz;
  774. wiz.DoModal();
  775. if (!wiz.isFinished)
  776. return FALSE;
  777. wiz.getData(&myInfo, &options);
  778. regMode = wiz.modeDlg.m_mode;
  779. }
  780. serverSession()->uin = myInfo.uin;
  781. IcqConfig::addUser(myInfo.uin);
  782. getApp()->setDBDir(myInfo.uin);
  783. setDefaultOptions();
  784. IcqDB::saveOptions(options);
  785. IcqDB::saveUser(myInfo);
  786. saveGroupInfo();
  787. if (regMode == 1) {
  788. UinList::iterator it, next;
  789. for (it = uinList.begin(); it != uinList.end(); it = next) {
  790. next = it;
  791. ++next;
  792. uint32 uin = *it;
  793. IcqContact *c = findContact(uin);
  794. if (c)
  795. uinList.erase(it);
  796. else
  797. addContact(uin);
  798. }
  799. }
  800. saveGroupInfo();
  801. outbarCtrl.Invalidate();
  802. initGUI();
  803. login();
  804. return TRUE;
  805. }
  806. BOOL CIcqDlg::doLogin()
  807. {
  808. CLoginDlg loginDlg;
  809. int result = loginDlg.DoModal();
  810. if (result == IDCANCEL)
  811. return FALSE;
  812. if (result == IDC_REGWIZARD)
  813. return doRegWizard();
  814. destroyUser();
  815. myInfo.uin = loginDlg.m_uin;
  816. serverSession()->uin = myInfo.uin;
  817. getApp()->setDBDir(myInfo.uin);
  818. if (!IcqDB::loadOptions(options) ||
  819. !IcqDB::loadUser(myInfo) ||
  820. !loadGroupInfo()) {
  821. if (AfxMessageBox(IDS_PROMPT_DB_CORRUPTED, MB_YESNO) == IDYES)
  822. return doRegWizard();
  823. return FALSE;
  824. }
  825. SetTimer(IDT_RESEND, SEND_TIMEOUT * 1000, NULL);
  826. CString passwd = loginDlg.m_passwd;
  827. while (passwd != myInfo.passwd.c_str()) {
  828. CLoginAgainDlg againDlg(loginDlg.m_uin);
  829. if (againDlg.DoModal() != IDOK)
  830. return FALSE;
  831. passwd = againDlg.m_passwd;
  832. }
  833. initGUI();
  834. login(options.flags.test(UF_LOGIN_INVIS) ? STATUS_INVIS : STATUS_ONLINE);
  835. return TRUE;
  836. }
  837. void CIcqDlg::destroyUser()
  838. {
  839. IcqLink::destroyUser();
  840. UnregisterHotKey(m_hWnd, ID_HOTKEY);
  841. regMode = -1;
  842. }
  843. IcqMsg *CIcqDlg::fetchMsg(uint32 uin)
  844. {
  845. IcqMsg *msg = findPendingMsg(uin);
  846. if (msg)
  847. msgList.remove(msg);
  848. if (!findPendingMsg(uin)) {
  849. if (uin)
  850. outbarCtrl.blinkImage(uin, FALSE);
  851. else
  852. m_btnSysMsg.SetIcon(iconSysMsg);
  853. }
  854. if (msgList.empty()) {
  855. KillTimer(IDT_BLINK);
  856. updateStatusIcon();
  857. }
  858. return msg;
  859. }
  860. void CIcqDlg::showOptions(UINT iSelectPage)
  861. {
  862. CSysOptionDlg win(this, iSelectPage);
  863. if (win.DoModal() == IDOK) {
  864. IcqDB::saveOptions(options);
  865. initGUI();
  866. }
  867. }
  868. void CIcqDlg::onStatusAway()
  869. {
  870. if (myInfo.status == STATUS_OFFLINE)
  871. login(STATUS_AWAY);
  872. else {
  873. if (myInfo.status != STATUS_AWAY) {
  874. myInfo.status = STATUS_AWAY;
  875. serverSession()->changeStatus(myInfo.status);
  876. }
  877. updateStatusIcon();
  878. }
  879. }
  880. void CIcqDlg::onNotifyDblClk()
  881. {
  882. if (msgList.empty()) {
  883. if (isHide) {
  884. hideWindow(FALSE);
  885. SetTimer(IDT_HOVER, 5000, NULL);
  886. } else {
  887. ShowWindow(SW_NORMAL);
  888. SetForegroundWindow();
  889. }
  890. } else {
  891. IcqMsg *msg = (IcqMsg *) msgList.front();
  892. if (msg->isSysMsg())
  893. OnSysMessage();
  894. else {
  895. IcqContact *c = findContact(msg->uin);
  896. if (c)
  897. onItemDoubleClicked(c);
  898. }
  899. }
  900. }
  901. void CIcqDlg::saveGroupInfo()
  902. {
  903. IcqDB::saveGroupInfo(outbarCtrl);
  904. }
  905. BOOL CIcqDlg::loadGroupInfo()
  906. {
  907. if (!IcqDB::loadContact(contactList))
  908. return FALSE;
  909. if (!IcqDB::loadGroupInfo(outbarCtrl) || outbarCtrl.getFolderCount() < 3)
  910. return FALSE;
  911. return TRUE;
  912. }
  913. BOOL CIcqDlg::loadPlugins()
  914. {
  915. CString dir = getApp()->rootDir + "plugins\*.dll";
  916. CFileFind finder;
  917. BOOL cont = finder.FindFile(dir);
  918. while (cont) {
  919. cont = finder.FindNextFile();
  920. HINSTANCE module = AfxLoadLibrary(finder.GetFilePath());
  921. if (!module)
  922. continue;
  923. GETTYPE getType = (GETTYPE) GetProcAddress(module, "getType");
  924. if (getType) {
  925. int type = getType();
  926. IcqPlugin *plugin = NULL;
  927. if (type == ICQ_PLUGIN_NET) {
  928. NetPlugin *p = new NetPlugin;
  929. p->getNameIcon = (GETNAMEICON) GetProcAddress(module, "getNameIcon");
  930. p->createSession = (CREATESESSION) GetProcAddress(module, "createSession");
  931. plugin = p;
  932. } else if (type == ICQ_PLUGIN_TOY) {
  933. ToyPlugin *p = new ToyPlugin;
  934. p->getNameIcon = (GETNAMEICON) GetProcAddress(module, "getNameIcon");
  935. p->init = (INIT) GetProcAddress(module, "init");
  936. p->configure = (CONFIGURE) GetProcAddress(module, "configure");
  937. p->about = (ABOUT) GetProcAddress(module, "about");
  938. plugin = p;
  939. }
  940. plugin->type = type;
  941. plugin->name = finder.GetFileTitle();
  942. PluginFactory::registerPlugin(plugin);
  943. }
  944. }
  945. HICON icon = AfxGetApp()->LoadIcon(IDI_PLUGIN);
  946. dir = getApp()->rootDir + "plugins\*.ini";
  947. cont = finder.FindFile(dir);
  948. while (cont) {
  949. cont = finder.FindNextFile();
  950. ExePlugin *p = new ExePlugin;
  951. p->type = ICQ_PLUGIN_EXE;
  952. p->name = finder.GetFileTitle();
  953. p->icon = icon;
  954. const char *name = p->name.c_str();
  955. CString file = finder.GetFilePath();
  956. char buf[1024];
  957. GetPrivateProfileString(name, "name", name, buf, sizeof(buf), file);
  958. p->locName = buf;
  959. GetPrivateProfileString(name, "client", NULL, buf, sizeof(buf), file);
  960. p->clientCmd = buf;
  961. GetPrivateProfileString(name, "server", NULL, buf, sizeof(buf), file);
  962. p->serverCmd = buf;
  963. PluginFactory::registerPlugin(p);
  964. }
  965. return TRUE;
  966. }
  967. void CIcqDlg::renamed(int obj, int index, const char *text) 
  968. {
  969. if (obj == OutBarCtrl::HT_FOLDER)
  970. saveGroupInfo();
  971. else if (obj == OutBarCtrl::HT_ITEM) {
  972. IcqContact *c = outbarCtrl.contact(index);
  973. if (c) {
  974. c->nick = text;
  975. IcqDB::saveContact(*c);
  976. }
  977. }
  978. }
  979. void CIcqDlg::itemDragged(int item, int toFolder)
  980. {
  981. IcqContact *c = outbarCtrl.contact(item);
  982. int fromFolder = outbarCtrl.getSelFolder();
  983. int n = outbarCtrl.getFolderCount();
  984. if (fromFolder >= n - 2 && toFolder < n - 2)
  985. addFriend(c, toFolder);
  986. else if (fromFolder < n - 2 && toFolder >= n - 2)
  987. delFriend(c, toFolder);
  988. else {
  989. c->type = (toFolder == n - 1 ? CONTACT_IGNORE : CONTACT_STRANGER);
  990. outbarCtrl.removeContact(c->uin);
  991. outbarCtrl.addContact(toFolder, c);
  992. saveGroupInfo();
  993. }
  994. }
  995. void CIcqDlg::selFolderChanged(int folder)
  996. {
  997. options.playSound(SOUND_FOLDER);
  998. }
  999. void CIcqDlg::itemClicked(int item)
  1000. {
  1001. curContact = outbarCtrl.contact(item);
  1002. CGfxPopupMenu menu;
  1003. CMenu tmp;
  1004. int sel = outbarCtrl.getSelFolder();
  1005. int n = outbarCtrl.getFolderCount();
  1006. if (sel < n - 2)
  1007. tmp.LoadMenu(IDR_CONTACT);
  1008. else if (sel < n - 1)
  1009. tmp.LoadMenu(IDR_STRANGER);
  1010. else
  1011. tmp.LoadMenu(IDR_IGNORE);
  1012. menu.Attach(*tmp.GetSubMenu(0));
  1013. if (sel < n - 2) {
  1014. UINT id = ID_PLUGIN;
  1015. PtrList &l = PluginFactory::getPluginList();
  1016. PtrList::iterator it;
  1017. for (it = l.begin(); it != l.end(); ++it) {
  1018. IcqPlugin *plugin = (IcqPlugin *) *it;
  1019. string name;
  1020. HICON icon = NULL;
  1021. int type = plugin->type;
  1022. if (type == ICQ_PLUGIN_NET) {
  1023. NetPlugin *p = (NetPlugin *) plugin;
  1024. if (p->getNameIcon)
  1025. icon = (HICON) p->getNameIcon(name);
  1026. else
  1027. name = p->name;
  1028. } else if (type == ICQ_PLUGIN_EXE) {
  1029. ExePlugin *p = (ExePlugin *) plugin;
  1030. name = p->locName;
  1031. icon = (HICON) p->icon;
  1032. } else
  1033. continue;
  1034. menu.AppendMenu(0, id, name.c_str());
  1035. menu.modifyMenu(id++, icon);
  1036. }
  1037. }
  1038. menu.modifyMenu(ID_SEND_MSG, IDB_SEND_MSG);
  1039. menu.modifyMenu(ID_SEND_EMAIL, IDB_SEND_EMAIL);
  1040. menu.modifyMenu(ID_HOMEPAGE, IDB_HOMEPAGE);
  1041. menu.modifyMenu(ID_MSG_HISTORY, IDB_MSG_HISTORY);
  1042. menu.modifyMenu(ID_VIEW_DETAIL, IDB_VIEW_DETAIL);
  1043. menu.modifyMenu(ID_ADD_AS_FRIEND, IDB_ADD);
  1044. menu.EnableMenuItems(&menu, this);
  1045. CPoint pt;
  1046. ::GetCursorPos(&pt);
  1047. currentMenu = &menu;
  1048. menu.TrackPopupMenu(TPM_LEFTALIGN, pt.x, pt.y, this);
  1049. currentMenu = NULL;
  1050. }
  1051. void CIcqDlg::rightButtonDown(int obj, int index)
  1052. {
  1053. CGfxPopupMenu menu;
  1054. CMenu tmp;
  1055. tmp.LoadMenu(IDR_OUTBAR);
  1056. menu.Attach(*tmp.GetSubMenu(0));
  1057. menu.modifyMenu(ID_GFX_SMALLICON, IDB_SMALLICON);
  1058. menu.modifyMenu(ID_GFX_LARGEICON, IDB_LARGEICON);
  1059. menu.modifyMenu(ID_GFX_ADDGROUP, IDB_ADDGROUP);
  1060. menu.modifyMenu(ID_GFX_FONTCOLOR, IDB_FONTCOLOR);
  1061. menu.modifyMenu(ID_GFX_BACKGROUND, IDB_BACKGROUND);
  1062. menu.appendMenu(ID_GFX_SHOWONLINE, IDB_SHOWONLINE, outbarCtrl.showOnlineOnly() ? IDS_SHOWALL : IDS_SHOWONLINE);
  1063. if (obj == OutBarCtrl::HT_ITEM) {
  1064. menu.AppendMenu(MF_SEPARATOR);
  1065. menu.appendMenu(ID_GFX_REMOVE, IDB_REMOVEITEM, IDS_REMOVEITEM);
  1066. menu.appendMenu(ID_GFX_RENAME, IDB_RENAME, IDS_RENAMEITEM);
  1067. } else if (obj == OutBarCtrl::HT_FOLDER) {
  1068. int n = outbarCtrl.getFolderCount();
  1069. if (index > 0 && index < n - 2) {
  1070. menu.AppendMenu(MF_SEPARATOR);
  1071. menu.appendMenu(ID_GFX_REMOVE, IDB_REMOVEGROUP, IDS_REMOVEGROUP);
  1072. menu.appendMenu(ID_GFX_RENAME, IDB_RENAME, IDS_RENAMEGROUP);
  1073. }
  1074. }
  1075. menu.EnableMenuItems(&menu, this);
  1076. CPoint pt;
  1077. ::GetCursorPos(&pt);
  1078. currentMenu = &menu;
  1079. menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, this);
  1080. currentMenu = NULL;
  1081. }
  1082. void CIcqDlg::itemDoubleClicked(int item)
  1083. {
  1084. onItemDoubleClicked(outbarCtrl.contact(item));
  1085. }
  1086. void CIcqDlg::onItemDoubleClicked(IcqContact *c)
  1087. {
  1088. int sel = outbarCtrl.getSelFolder();
  1089. int n = outbarCtrl.getFolderCount();
  1090. IcqMsg *msg = fetchMsg(c->uin);
  1091. if (msg && msg->type == MSG_TCP_REQUEST) {
  1092. if (sel < n - 2) {
  1093. CSendRequestDlg *dlg = new CSendRequestDlg(msg);
  1094. dlg->Create(IDD_SEND_REQUEST);
  1095. delete msg;
  1096. }
  1097. } else {
  1098. curContact = c;
  1099. if (sel < n - 1) {
  1100. if (msg)
  1101. msgList.push_front(msg);
  1102. OnSendMessage();
  1103. } else
  1104. OnViewDetail();
  1105. }
  1106. }
  1107. HANDLE CIcqDlg::getHostByName(const char *name)
  1108. {
  1109. return WSAAsyncGetHostByName(m_hWnd, WM_HOSTFOUND, name, hostBuf, sizeof(hostBuf));
  1110. }
  1111. void CIcqDlg::DoDataExchange(CDataExchange* pDX)
  1112. {
  1113. CCaptionBtnDlg::DoDataExchange(pDX);
  1114. //{{AFX_DATA_MAP(CIcqDlg)
  1115. DDX_Control(pDX, ID_STATISTICS, m_btnStat);
  1116. DDX_Control(pDX, ID_ABOUT, m_btnAbout);
  1117. DDX_Control(pDX, IDC_MAIN_MENU, m_btnMain);
  1118. DDX_Control(pDX, IDC_STATUS, m_btnStatus);
  1119. DDX_Control(pDX, IDC_SYS_MESSAGE, m_btnSysMsg);
  1120. DDX_Control(pDX, IDC_FIND_CONTACT, m_btnSearch);
  1121. //}}AFX_DATA_MAP
  1122. }
  1123. BEGIN_MESSAGE_MAP(CIcqDlg, CCaptionBtnDlg)
  1124. //{{AFX_MSG_MAP(CIcqDlg)
  1125. ON_WM_SIZE()
  1126. ON_WM_GETMINMAXINFO()
  1127. ON_COMMAND(ID_SEND_MSG, OnSendMessage)
  1128. ON_COMMAND(ID_VIEW_DETAIL, OnViewDetail)
  1129. ON_BN_CLICKED(IDC_FIND_CONTACT, OnFindContact)
  1130. ON_WM_TIMER()
  1131. ON_BN_CLICKED(IDC_SYS_MESSAGE, OnSysMessage)
  1132. ON_WM_NCHITTEST()
  1133. ON_BN_CLICKED(IDC_MAIN_MENU, OnMainMenu)
  1134. ON_COMMAND(ID_GFX_SMALLICON, OnGfxSmallIcon)
  1135. ON_UPDATE_COMMAND_UI(ID_GFX_SMALLICON, OnUpdateGfxSmallIcon)
  1136. ON_COMMAND(ID_GFX_LARGEICON, OnGfxLargeIcon)
  1137. ON_UPDATE_COMMAND_UI(ID_GFX_LARGEICON, OnUpdateGfxLargeIcon)
  1138. ON_COMMAND(ID_GFX_FONTCOLOR, OnGfxFontColor)
  1139. ON_COMMAND(ID_GFX_BACKGROUND, OnGfxBackground)
  1140. ON_COMMAND(ID_GFX_ADDGROUP, OnGfxAddGroup)
  1141. ON_UPDATE_COMMAND_UI(ID_GFX_ADDGROUP, OnUpdateGfxAddGroup)
  1142. ON_COMMAND(ID_GFX_REMOVE, OnGfxRemove)
  1143. ON_COMMAND(ID_GFX_RENAME, OnGfxRename)
  1144. ON_COMMAND(ID_MODIFY_INFO, OnModifyInfo)
  1145. ON_COMMAND(ID_GFX_SHOWONLINE, OnGfxShowOnline)
  1146. ON_BN_CLICKED(IDC_STATUS, OnStatus)
  1147. ON_COMMAND(ID_STATUS_ONLINE, OnStatusOnline)
  1148. ON_COMMAND(ID_STATUS_OFFLINE, OnStatusOffline)
  1149. ON_COMMAND(ID_STATUS_INVIS, OnStatusInvis)
  1150. ON_COMMAND(ID_SYS_OPTION, OnSysOption)
  1151. ON_COMMAND(ID_STATUS_AWAY_CUSTOM, OnStatusAwayCustom)
  1152. ON_COMMAND(ID_STATUS_AWAY_NOREPLY, OnStatusAwayNoReply)
  1153. ON_WM_MEASUREITEM()
  1154. ON_COMMAND(ID_REG_WIZARD, OnRegWizard)
  1155. ON_COMMAND(ID_CHANGE_USER, OnChangeUser)
  1156. ON_BN_CLICKED(ID_ABOUT, OnAbout)
  1157. ON_WM_DESTROY()
  1158. ON_WM_MOVING()
  1159. ON_COMMAND(ID_SEND_EMAIL, OnSendEmail)
  1160. ON_COMMAND(ID_HOMEPAGE, OnHomePage)
  1161. ON_COMMAND(ID_ADD_AS_FRIEND, OnAddAsFriend)
  1162. ON_COMMAND(ID_MSG_HISTORY, OnMsgHistory)
  1163. ON_COMMAND(ID_MESSAGE_MGR, OnMessageMgr)
  1164. ON_COMMAND(ID_BROADCAST_MSG, OnBroadcastMsg)
  1165. //}}AFX_MSG_MAP
  1166. ON_MESSAGE(WM_HOSTFOUND, OnHostFound)
  1167. ON_MESSAGE(WM_HOTKEY, OnHotKey)
  1168. ON_MESSAGE(WM_NOTIFYICON, OnNotifyIcon)
  1169. ON_NOTIFY_EX(TTN_NEEDTEXT, 0, OnToolTipText)
  1170. ON_COMMAND_RANGE(ID_STATUS_AWAY, ID_STATUS_AWAY + 9, OnStatusAway)
  1171. ON_COMMAND_RANGE(ID_PLUGIN, ID_PLUGIN + 1000, OnPlugin)
  1172. END_MESSAGE_MAP()
  1173. /////////////////////////////////////////////////////////////////////////////
  1174. // CIcqDlg message handlers
  1175. BOOL CIcqDlg::OnInitDialog()
  1176. {
  1177. CCaptionBtnDlg::OnInitDialog();
  1178. toolTip.Create(this);
  1179. CRect rc;
  1180. GetWindowRect(rc);
  1181. ScreenToClient(rc);
  1182. toolTip.AddTool(this, LPSTR_TEXTCALLBACK, rc, ID_TOOLTIP);
  1183. m_btnSearch.SetIcon(IDI_FIND);
  1184. m_btnSysMsg.SetIcon(iconSysMsg);
  1185. m_btnAbout.SetIcon(IDI_ABOUT);
  1186. m_btnStat.SetIcon(IDI_STAT);
  1187. m_btnMain.SetFlat(FALSE, FALSE);
  1188. statusImgList.Create(16, 16, ILC_MASK | ILC_COLOR8, 4, 0);
  1189. UINT id[] = {
  1190. IDB_STATUS_ONLINE,
  1191. IDB_STATUS_OFFLINE,
  1192. IDB_STATUS_AWAY,
  1193. IDB_STATUS_INVIS
  1194. };
  1195. CBitmap bm;
  1196. for (int i = 0; i < 4; i++) {
  1197. bm.LoadBitmap(id[i]);
  1198. statusImgList.Add(&bm, RGB(192, 192, 192));
  1199. bm.DeleteObject();
  1200. }
  1201. m_btnStatus.SetTooltipText(IDS_CHANGE_STATUS);
  1202. m_btnMain.SetTooltipText(IDS_MAINMENU);
  1203. m_btnSearch.SetTooltipText(IDS_SEARCH);
  1204. m_btnSysMsg.SetTooltipText(IDS_SYSMSG);
  1205. m_btnAbout.SetTooltipText(IDS_ABOUT);
  1206. m_btnStat.SetTooltipText(IDS_STATISTICS);
  1207. outbarCtrl.CreateEx(WS_EX_CLIENTEDGE, NULL, NULL, WS_VISIBLE | WS_CHILD,
  1208. CRect(0, 0, 0, 0), this, IDC_OUTBAR);
  1209. loadPlugins();
  1210. if (!doLogin()) {
  1211. EndDialog(IDCANCEL);
  1212. return TRUE;
  1213. }
  1214. outbarCtrl.SetFocus();
  1215. return FALSE;
  1216. }
  1217. void CIcqDlg::OnSize(UINT nType, int cx, int cy) 
  1218. {
  1219. CCaptionBtnDlg::OnSize(nType, cx, cy);
  1220. int y = cy;
  1221. CRect rc;
  1222. m_btnMain.GetWindowRect(rc);
  1223. ScreenToClient(rc);
  1224. y -= rc.Height();
  1225. m_btnMain.MoveWindow(rc.left, y, rc.Width(), rc.Height(), FALSE);
  1226. m_btnStatus.GetWindowRect(rc);
  1227. ScreenToClient(rc);
  1228. m_btnStatus.MoveWindow(rc.left, y, cx - rc.left, rc.Height(), FALSE);
  1229. m_btnStat.GetWindowRect(rc);
  1230. ScreenToClient(rc);
  1231. y -= rc.Height() + 2;
  1232. m_btnStat.MoveWindow(rc.left, y, rc.Width(), rc.Height(), FALSE);
  1233. m_btnSysMsg.GetWindowRect(rc);
  1234. ScreenToClient(rc);
  1235. m_btnSysMsg.MoveWindow(rc.left, y, cx - rc.left, rc.Height(), FALSE);
  1236. m_btnAbout.GetWindowRect(rc);
  1237. ScreenToClient(rc);
  1238. y -= rc.Height() + 2;
  1239. m_btnAbout.MoveWindow(rc.left, y, rc.Width(), rc.Height(), FALSE);
  1240. m_btnSearch.GetWindowRect(rc);
  1241. ScreenToClient(rc);
  1242. m_btnSearch.MoveWindow(rc.left, y, cx - rc.left, rc.Height(), FALSE);
  1243. y -= 2;
  1244. outbarCtrl.MoveWindow(0, 0, cx, y, FALSE);
  1245. RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE | RDW_ALLCHILDREN);
  1246. }
  1247. void CIcqDlg::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI) 
  1248. {
  1249. lpMMI->ptMinTrackSize.x = 95;
  1250. lpMMI->ptMinTrackSize.y = 245;
  1251. lpMMI->ptMaxTrackSize.x = 340;
  1252. CCaptionBtnDlg::OnGetMinMaxInfo(lpMMI);
  1253. }
  1254. UINT CIcqDlg::OnNcHitTest(CPoint point) 
  1255. {
  1256. UINT res = CCaptionBtnDlg::OnNcHitTest(point);
  1257. if (res == HTCLIENT)
  1258. return HTCAPTION;
  1259. switch (alignType) {
  1260. case ALIGN_TOP:
  1261. if (res == HTLEFT || res == HTRIGHT || res == HTTOP ||
  1262. res == HTTOPLEFT || res == HTTOPRIGHT)
  1263. res = HTERROR;
  1264. else if (res == HTBOTTOMLEFT || res == HTBOTTOMRIGHT)
  1265. res = HTBOTTOM;
  1266. if (isHide && res == HTBOTTOM)
  1267. hideWindow(FALSE);
  1268. break;
  1269. case ALIGN_LEFT:
  1270. if (res == HTTOP || res == HTBOTTOM || res == HTLEFT ||
  1271. res == HTTOPLEFT || res == HTBOTTOMLEFT)
  1272. res = HTERROR;
  1273. else if (res == HTTOPRIGHT || res == HTBOTTOMRIGHT)
  1274. res = HTRIGHT;
  1275. if (isHide && res == HTRIGHT)
  1276. hideWindow(FALSE);
  1277. break;
  1278. case ALIGN_RIGHT:
  1279. if (res == HTTOP || res == HTBOTTOM || res == HTRIGHT ||
  1280. res == HTTOPRIGHT || res == HTBOTTOMRIGHT)
  1281. res = HTERROR;
  1282. else if (res == HTTOPLEFT || res == HTBOTTOMLEFT)
  1283. res = HTLEFT;
  1284. if (isHide && res == HTLEFT)
  1285. hideWindow(FALSE);
  1286. break;
  1287. }
  1288. return res;
  1289. }
  1290. BOOL CIcqDlg::PreTranslateMessage(MSG* pMsg) 
  1291. {
  1292. if ((myInfo.status != STATUS_OFFLINE) &&
  1293. (pMsg->message >= WM_MOUSEFIRST && pMsg->message <= WM_MOUSELAST) ||
  1294. (pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST) &&
  1295. options.flags.test(UF_AUTO_SWITCH_STATUS)) {
  1296. if (myInfo.status == STATUS_AWAY && options.flags.test(UF_AUTO_CANCEL_AWAY))
  1297. OnStatusOnline();
  1298. if (options.autoStatusTime > 0)
  1299. SetTimer(IDT_AUTO_SWITCH_STATUS, options.autoStatusTime * 60000, NULL);
  1300. }
  1301. if (pMsg->hwnd == m_hWnd)
  1302. toolTip.RelayEvent(pMsg);
  1303. return CCaptionBtnDlg::PreTranslateMessage(pMsg);
  1304. }
  1305. void CIcqDlg::OnSendMessage() 
  1306. {
  1307. IcqContact *c = curContact;
  1308. IcqMsg *msg = fetchMsg(c->uin);
  1309. IcqWindow *win;
  1310. if (c->flags.test(CF_DIALOGMODE) || !msg) {
  1311. outbarCtrl.blinkImage(c->uin, FALSE);
  1312. CSendMsgDlg *pDlg;
  1313. win = findWindow(WIN_SEND_MESSAGE, c->uin);
  1314. if (!win) {
  1315. pDlg = new CSendMsgDlg(c);
  1316. pDlg->Create(IDD_SEND_MESSAGE);
  1317. } else {
  1318. pDlg = (CSendMsgDlg *) win;
  1319. pDlg->ShowWindow(SW_NORMAL);
  1320. pDlg->BringWindowToTop();
  1321. }
  1322. if (c->flags.test(CF_DIALOGMODE)) {
  1323. while (msg) {
  1324. pDlg->onRecvMessage(*msg);
  1325. delete msg;
  1326. msg = fetchMsg(c->uin);
  1327. }
  1328. }
  1329. } else {
  1330. // fake that we have not fetched it.
  1331. msgList.push_front(msg);
  1332. CViewMsgDlg *pDlg;
  1333. win = findWindow(WIN_VIEW_MESSAGE, c->uin);
  1334. if (!win) {
  1335. pDlg = new CViewMsgDlg(c);
  1336. pDlg->Create(IDD_VIEW_MESSAGE);
  1337. } else {
  1338. pDlg = (CViewMsgDlg *) win;
  1339. pDlg->ShowWindow(SW_NORMAL);
  1340. pDlg->BringWindowToTop();
  1341. }
  1342. }
  1343. }
  1344. void CIcqDlg::OnViewDetail() 
  1345. {
  1346. CViewDetailDlg *win = new CViewDetailDlg(curContact->uin);
  1347. win->Create();
  1348. }
  1349. void CIcqDlg::OnFindContact() 
  1350. {
  1351. IcqWindow *win = findWindow(WIN_SEARCH_WIZARD);
  1352. if (!win) {
  1353. CSearchWizard *dlg = new CSearchWizard;
  1354. dlg->Create();
  1355. }
  1356. }
  1357. void CIcqDlg::OnTimer(UINT nIDEvent) 
  1358. {
  1359. if (nIDEvent == IDT_RESEND)
  1360. checkSendQueue();
  1361. else if (nIDEvent == IDT_KEEPALIVE)
  1362. serverSession()->sendKeepAlive();
  1363. else if (nIDEvent == IDT_STATUS) {
  1364. static int frame = 0;
  1365. HICON hIcon = statusImgList.ExtractIcon(frame);
  1366. m_btnStatus.SetIcon(hIcon);
  1367. modifyNotifyIcon(hIcon);
  1368. if (++frame >= 3)
  1369. frame = 0;
  1370. } else if (nIDEvent == IDT_BLINK) {
  1371. static int frame = 0;
  1372. frame ^= 1;
  1373. IcqMsg *msg = (IcqMsg *) msgList.front();
  1374. HICON icon = NULL;
  1375. if (msg->isSysMsg()) {
  1376. icon = (frame ? iconSysMsg : iconBlank);
  1377. m_btnSysMsg.SetIcon(icon);
  1378. } else {
  1379. IcqContact *c = findContact(msg->uin);
  1380. if (c)
  1381. icon = (frame ? getApp()->smallImageList.ExtractIcon(c->face) : iconBlank);
  1382. }
  1383. modifyNotifyIcon(icon);
  1384. } else if (nIDEvent == IDT_DBLCLK) {
  1385. KillTimer(nIDEvent);
  1386. CPoint pt;
  1387. GetCursorPos(&pt);
  1388. SetForegroundWindow();
  1389. popupStatusMenu(TPM_BOTTOMALIGN | TPM_RIGHTALIGN, pt);
  1390. } else if (nIDEvent == IDT_HOVER) {
  1391. CPoint pt;
  1392. GetCursorPos(&pt);
  1393. CRect rc;
  1394. GetWindowRect(rc);
  1395. rc.InflateRect(10, 10);
  1396. if (!rc.PtInRect(pt)) {
  1397. KillTimer(nIDEvent);
  1398. hideWindow();
  1399. }
  1400. } else if (nIDEvent == IDT_AUTO_SWITCH_STATUS) {
  1401. KillTimer(nIDEvent);
  1402. if (options.flags.test(UF_AUTO_SWITCH_STATUS)) {
  1403. switch (options.autoStatus) {
  1404. case STATUS_AWAY:
  1405. onStatusAway();
  1406. break;
  1407. case STATUS_INVIS:
  1408. OnStatusInvis();
  1409. break;
  1410. case STATUS_OFFLINE:
  1411. OnStatusOffline();
  1412. break;
  1413. }
  1414. }
  1415. } else
  1416. CCaptionBtnDlg::OnTimer(nIDEvent);
  1417. }
  1418. void CIcqDlg::OnSysMessage() 
  1419. {
  1420. IcqMsg *msg = fetchMsg(0);
  1421. IcqWindow *win;
  1422. if (!msg) {
  1423. CSysHistoryDlg *pDlg;
  1424. win = findWindow(WIN_SYS_HISTORY);
  1425. if (!win) {
  1426. pDlg = new CSysHistoryDlg;
  1427. pDlg->Create(IDD_SYS_HISTORY);
  1428. } else {
  1429. pDlg = (CSysHistoryDlg *) win;
  1430. pDlg->ShowWindow(SW_NORMAL);
  1431. pDlg->BringWindowToTop();
  1432. }
  1433. } else {
  1434. CSysMsgDlg *win = new CSysMsgDlg(msg);
  1435. win->Create(IDD_SYS_MESSAGE);
  1436. }
  1437. }
  1438. void CIcqDlg::OnMainMenu() 
  1439. {
  1440. CGfxPopupMenu menu;
  1441. CMenu tmp;
  1442. tmp.LoadMenu(IDR_MAIN);
  1443. menu.Attach(*tmp.GetSubMenu(0));
  1444. menu.modifyMenu(ID_CHANGE_USER, IDB_CHANGE_USER);
  1445. menu.modifyMenu(ID_REG_WIZARD, IDB_REG_WIZARD);
  1446. menu.modifyMenu(ID_MODIFY_INFO, IDB_VIEW_DETAIL);
  1447. menu.modifyMenu(ID_SYS_OPTION, IDB_SYS_OPTION);
  1448. menu.modifyMenu(ID_APP_EXIT, IDB_EXIT);
  1449. CRect rc;
  1450. m_btnMain.GetWindowRect(rc);
  1451. popupMainMenu(TPM_BOTTOMALIGN, rc.TopLeft());
  1452. }
  1453. void CIcqDlg::OnGfxSmallIcon() 
  1454. {
  1455. outbarCtrl.setIconView(FALSE);
  1456. saveGroupInfo();
  1457. }
  1458. void CIcqDlg::OnUpdateGfxSmallIcon(CCmdUI* pCmdUI) 
  1459. {
  1460. pCmdUI->Enable(outbarCtrl.isLargeIconView());
  1461. }
  1462. void CIcqDlg::OnGfxLargeIcon() 
  1463. {
  1464. outbarCtrl.setIconView(TRUE);
  1465. saveGroupInfo();
  1466. }
  1467. void CIcqDlg::OnUpdateGfxLargeIcon(CCmdUI* pCmdUI) 
  1468. {
  1469. pCmdUI->Enable(!outbarCtrl.isLargeIconView());
  1470. }
  1471. void CIcqDlg::OnGfxFontColor() 
  1472. {
  1473. CColorDialog dlg;
  1474. if (dlg.DoModal() == IDOK) {
  1475. outbarCtrl.setFontColor(dlg.GetColor());
  1476. saveGroupInfo();
  1477. }
  1478. }
  1479. void CIcqDlg::OnGfxBackground() 
  1480. {
  1481. CColorDialog dlg;
  1482. if (dlg.DoModal() == IDOK) {
  1483. outbarCtrl.setBgColor(dlg.GetColor());
  1484. saveGroupInfo();
  1485. }
  1486. }
  1487. void CIcqDlg::OnGfxAddGroup() 
  1488. {
  1489. outbarCtrl.addFolderUI();
  1490. saveGroupInfo();
  1491. }
  1492. void CIcqDlg::OnGfxRename()
  1493. {
  1494. outbarCtrl.renameUI();
  1495. }
  1496. void CIcqDlg::OnUpdateGfxAddGroup(CCmdUI* pCmdUI) 
  1497. {
  1498. pCmdUI->Enable(outbarCtrl.getSelFolder() < outbarCtrl.getFolderCount() - 2);
  1499. }
  1500. void CIcqDlg::OnGfxRemove() 
  1501. {
  1502. int obj = outbarCtrl.hitObj();
  1503. int index = outbarCtrl.hitIndex();
  1504. if (obj == OutBarCtrl::HT_FOLDER) {
  1505. if (outbarCtrl.getItemCount(index) > 0)
  1506. AfxMessageBox(IDS_GROUP_NOT_EMPTY);
  1507. else {
  1508. outbarCtrl.removeFolder(index);
  1509. saveGroupInfo();
  1510. }
  1511. } else if (obj == OutBarCtrl::HT_ITEM) {
  1512. IcqContact *c = outbarCtrl.contact(index);
  1513. int n = outbarCtrl.getFolderCount();
  1514. if (outbarCtrl.getSelFolder() < n - 2)
  1515. delFriend(c);
  1516. else {
  1517. outbarCtrl.removeItem(index);
  1518. contactList.remove(c);
  1519. IcqDB::delContact(c->uin);
  1520. saveGroupInfo();
  1521. delete c;
  1522. }
  1523. }
  1524. }
  1525. void CIcqDlg::OnModifyInfo() 
  1526. {
  1527. CModifyDetailDlg *win = new CModifyDetailDlg;
  1528. win->Create();
  1529. }
  1530. void CIcqDlg::OnGfxShowOnline() 
  1531. {
  1532. bool b = !outbarCtrl.showOnlineOnly();
  1533. outbarCtrl.setShowOnlineOnly(b);
  1534. options.flags.set(UF_SHOW_ONLINE, b);
  1535. IcqDB::saveOptions(options);
  1536. }
  1537. void CIcqDlg::OnStatus() 
  1538. {
  1539. CRect rc;
  1540. m_btnStatus.GetWindowRect(rc);
  1541. popupStatusMenu(TPM_BOTTOMALIGN, rc.TopLeft());
  1542. }
  1543. void CIcqDlg::OnStatusOnline() 
  1544. {
  1545. if (myInfo.status == STATUS_OFFLINE)
  1546. login();
  1547. else {
  1548. if (myInfo.status != STATUS_ONLINE) {
  1549. myInfo.status = STATUS_ONLINE;
  1550. serverSession()->changeStatus(myInfo.status);
  1551. }
  1552. updateStatusIcon();
  1553. }
  1554. }
  1555. void CIcqDlg::OnStatusOffline() 
  1556. {
  1557. if (myInfo.status != STATUS_OFFLINE)
  1558. logout();
  1559. updateStatusIcon();
  1560. }
  1561. void CIcqDlg::OnStatusInvis() 
  1562. {
  1563. if (myInfo.status == STATUS_OFFLINE)
  1564. login(STATUS_INVIS);
  1565. else {
  1566. if (myInfo.status != STATUS_INVIS) {
  1567. myInfo.status = STATUS_INVIS;
  1568. serverSession()->changeStatus(myInfo.status);
  1569. }
  1570. destroySession();
  1571. updateStatusIcon();
  1572. }
  1573. }
  1574. void CIcqDlg::OnStatusAwayNoReply() 
  1575. {
  1576. options.flags.set(UF_AUTO_REPLY, false);
  1577. IcqDB::saveOptions(options);
  1578. onStatusAway();
  1579. }
  1580. void CIcqDlg::OnSysOption() 
  1581. {
  1582. showOptions();
  1583. }
  1584. void CIcqDlg::OnStatusAwayCustom() 
  1585. {
  1586. showOptions(1);
  1587. }
  1588. void CIcqDlg::OnStatusAway(UINT nID)
  1589. {
  1590. int pos = nID - ID_STATUS_AWAY;
  1591. StrList l;
  1592. IcqDB::loadAutoReply(l);
  1593. StrList::iterator it;
  1594. for (it = l.begin(); it != l.end(); ++it) {
  1595. if (pos-- <= 0)
  1596. break;
  1597. }
  1598. if (pos < 0) {
  1599. options.flags.set(UF_AUTO_REPLY);
  1600. options.autoReplyText = *it;
  1601. IcqDB::saveOptions(options);
  1602. onStatusAway();
  1603. }
  1604. }
  1605. void CIcqDlg::OnPlugin(UINT nID)
  1606. {
  1607. int pos = nID - ID_PLUGIN;
  1608. PtrList &l = PluginFactory::getPluginList();
  1609. PtrList::iterator it;
  1610. IcqPlugin *p = NULL;
  1611. int i = 0;
  1612. for (it = l.begin(); it != l.end(); ++it) {
  1613. p = (IcqPlugin *) *it;
  1614. if (p->type == ICQ_PLUGIN_NET || p->type == ICQ_PLUGIN_EXE) {
  1615. if (++i > pos)
  1616. break;
  1617. }
  1618. }
  1619. if (it != l.end()) {
  1620. p = (IcqPlugin *) *it;
  1621. CSendRequestDlg *dlg = new CSendRequestDlg(p->name.c_str(), curContact);
  1622. dlg->Create(IDD_SEND_REQUEST);
  1623. }
  1624. }
  1625. LRESULT CIcqDlg::OnHostFound(WPARAM wParam, LPARAM lParam)
  1626. {
  1627. WORD error = WSAGETASYNCERROR(lParam);
  1628. struct in_addr addr;
  1629. addr.s_addr = INADDR_NONE;
  1630. if (error == 0) {
  1631. struct hostent *hent = (struct hostent *) hostBuf;
  1632. addr = *(struct in_addr *) hent->h_addr;
  1633. }
  1634. IcqWindow *win = findWindow(WIN_REG_WIZARD);
  1635. if (win)
  1636. ((CRegWizard *) win)->onHostFound(addr);
  1637. else
  1638. onHostFound(addr);
  1639. return TRUE;
  1640. }
  1641. LRESULT CIcqDlg::OnHotKey(WPARAM wParam, LPARAM lParam)
  1642. {
  1643. if (wParam == ID_HOTKEY)
  1644. onNotifyDblClk();
  1645. return 1;
  1646. }
  1647. LRESULT CIcqDlg::OnNotifyIcon(WPARAM wParam, LPARAM lParam)
  1648. {
  1649. if (wParam != ID_NOTIFYICON || !myInfo.uin)
  1650. return 0;
  1651. if (lParam == WM_LBUTTONDOWN)
  1652. SetTimer(IDT_DBLCLK, GetDoubleClickTime(), NULL);
  1653. else if (lParam == WM_RBUTTONUP) {
  1654. CPoint pt;
  1655. GetCursorPos(&pt);
  1656. SetForegroundWindow();
  1657. popupMainMenu(TPM_BOTTOMALIGN | TPM_RIGHTALIGN, pt);
  1658. } else if (lParam == WM_LBUTTONDBLCLK) {
  1659. KillTimer(IDT_DBLCLK);
  1660. onNotifyDblClk();
  1661. }
  1662. return 1;
  1663. }
  1664. BOOL CIcqDlg::OnToolTipText(UINT id, NMHDR *pNMHDR, LRESULT *pResult)
  1665. {
  1666. TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *) pNMHDR;
  1667. if (pNMHDR->idFrom == ID_TOOLTIP) {
  1668. if (serverSession()->sessionCount) {
  1669. CString str;
  1670. str.Format(IDS_NR_ONLINES, serverSession()->sessionCount);
  1671. strcpy(pTTT->szText, str);
  1672. } else {
  1673. pTTT->lpszText = (LPSTR) (LPCTSTR) AfxGetAppName();
  1674. pTTT->hinst = NULL;
  1675. }
  1676. }
  1677. return TRUE;
  1678. }
  1679. void CIcqDlg::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct) 
  1680. {
  1681. if (lpMeasureItemStruct->CtlType == ODT_MENU && currentMenu)
  1682. currentMenu->MeasureItem(lpMeasureItemStruct);
  1683. else
  1684. CCaptionBtnDlg::OnMeasureItem(nIDCtl, lpMeasureItemStruct);
  1685. }
  1686. void CIcqDlg::OnRegWizard() 
  1687. {
  1688. if (!doRegWizard())
  1689. EndDialog(IDCANCEL);
  1690. }
  1691. void CIcqDlg::OnChangeUser() 
  1692. {
  1693. doLogin();
  1694. outbarCtrl.Invalidate();
  1695. }
  1696. void CIcqDlg::OnAbout() 
  1697. {
  1698. CAboutDlg dlg;
  1699. dlg.DoModal();
  1700. }
  1701. void CIcqDlg::OnDestroy() 
  1702. {
  1703. destroyUser();
  1704. removeNotifyIcon();
  1705. CCaptionBtnDlg::OnDestroy();
  1706. }
  1707. void CIcqDlg::OnMoving(UINT fwSide, LPRECT pRect) 
  1708. {
  1709. if (!options.flags.test(UF_TASKBAR_STYLE)) {
  1710. CCaptionBtnDlg::OnMoving(fwSide, pRect);
  1711. return;
  1712. }
  1713. CRect rcOld, rcWorkArea;
  1714. CPoint pt;
  1715. GetWindowRect(rcOld);
  1716. SystemParametersInfo(SPI_GETWORKAREA, 0, rcWorkArea, 0);
  1717. GetCursorPos(&pt);
  1718. int cxScreen = GetSystemMetrics(SM_CXSCREEN);
  1719. if (alignType == ALIGN_NONE) {
  1720. if (pt.y - rcWorkArea.top < 20) {
  1721. alignType = ALIGN_TOP;
  1722. pRect->top = 0;
  1723. } else if (pt.x - rcWorkArea.left < 20) {
  1724. alignType = ALIGN_LEFT;
  1725. pRect->left = 0;
  1726. winNormalSize = rcOld.Size();
  1727. } else if (rcWorkArea.right - pt.x < 20) {
  1728. alignType = ALIGN_RIGHT;
  1729. pRect->right = cxScreen;
  1730. winNormalSize = rcOld.Size();
  1731. }
  1732. if (alignType != ALIGN_NONE)
  1733. SetTimer(IDT_HOVER, 50, NULL);
  1734. }
  1735. if (alignType == ALIGN_TOP) {
  1736. if (pRect->top > 0)
  1737. alignType = ALIGN_NONE;
  1738. else {
  1739. pRect->top = 0;
  1740. pRect->bottom = rcOld.Height();
  1741. }
  1742. } else if (alignType == ALIGN_LEFT) {
  1743. if (pRect->left > 0) {
  1744. pRect->right = pRect->left + winNormalSize.cx;
  1745. pRect->bottom = pRect->top + winNormalSize.cy;
  1746. alignType = ALIGN_NONE;
  1747. } else {
  1748. pRect->left = 0;
  1749. pRect->right = rcOld.Width();
  1750. pRect->top = 0;
  1751. pRect->bottom = rcWorkArea.bottom;
  1752. }
  1753. } else if (alignType == ALIGN_RIGHT) {
  1754. if (pRect->right < cxScreen) {
  1755. pRect->left = pRect->right - winNormalSize.cx;
  1756. pRect->bottom = pRect->top + winNormalSize.cy;
  1757. alignType = ALIGN_NONE;
  1758. } else {
  1759. pRect->right = cxScreen;
  1760. pRect->left = pRect->right - rcOld.Width();
  1761. pRect->top = 0;
  1762. pRect->bottom = rcWorkArea.bottom;
  1763. }
  1764. }
  1765. if (alignType == ALIGN_NONE)
  1766. KillTimer(IDT_HOVER);
  1767. CCaptionBtnDlg::OnMoving(fwSide, pRect);
  1768. }
  1769. void CIcqDlg::OnSendEmail() 
  1770. {
  1771. CString url = "mailto:";
  1772. url += curContact->email.c_str();
  1773. ShellExecute(NULL, _T("open"), url, NULL, NULL, SW_SHOW);
  1774. }
  1775. void CIcqDlg::OnHomePage() 
  1776. {
  1777. ShellExecute(NULL, _T("open"), curContact->homepage.c_str(), NULL, NULL, SW_SHOW);
  1778. }
  1779. void CIcqDlg::OnAddAsFriend() 
  1780. {
  1781. addFriend(curContact, 0);
  1782. }
  1783. void CIcqDlg::OnMsgHistory() 
  1784. {
  1785. CMsgMgrWnd *pWnd = new CMsgMgrWnd;
  1786. if (pWnd->LoadFrame(IDR_MSGMGR))
  1787. pWnd->ActivateFrame(curContact->uin);
  1788. }
  1789. void CIcqDlg::OnMessageMgr() 
  1790. {
  1791. CMsgMgrWnd *pWnd = new CMsgMgrWnd;
  1792. if (pWnd->LoadFrame(IDR_MSGMGR))
  1793. pWnd->ActivateFrame();
  1794. }
  1795. void CIcqDlg::OnBroadcastMsg() 
  1796. {
  1797. CBroadcastDlg *win = new CBroadcastDlg;
  1798. win->Create(IDD_BROADCAST);
  1799. }
  1800. void CIcqDlg::OnOK()
  1801. {
  1802. }