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

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. // SendMsgDlg.cpp : implementation file
  12. //
  13. #include "stdafx.h"
  14. #include "myicq.h"
  15. #include "SendMsgDlg.h"
  16. #include "myicqDlg.h"
  17. #include "ViewDetailDlg.h"
  18. #include "serversession.h"
  19. #include "icqlink.h"
  20. #include "icqdb.h"
  21. #ifdef _DEBUG
  22. #define new DEBUG_NEW
  23. #undef THIS_FILE
  24. static char THIS_FILE[] = __FILE__;
  25. #endif
  26. #define IDT_SENDMSG 1001
  27. #define IDT_ANIMATE 1002
  28. /////////////////////////////////////////////////////////////////////////////
  29. // CSendMsgDlg dialog
  30. CSendMsgDlg::CSendMsgDlg(IcqContact *c, CWnd* pParent /*=NULL*/)
  31. :CMyDlg(CSendMsgDlg::IDD, pParent), IcqWindow(WIN_SEND_MESSAGE, c->uin)
  32. {
  33. //{{AFX_DATA_INIT(CSendMsgDlg)
  34. m_msgText = _T("");
  35. m_ipport = _T("");
  36. //}}AFX_DATA_INIT
  37. m_hIcon = AfxGetApp()->LoadIcon(IDI_SENDMSG);
  38. contact = c;
  39. viewHistory = FALSE;
  40. groupSend = FALSE;
  41. frame = 0;
  42. m_uin.Format("%lu", c->uin);
  43. m_nick = c->nick.c_str();
  44. m_email = c->email.c_str();
  45. in_addr addr;
  46. addr.s_addr = htonl(c->ip);
  47. m_ipport.Format("%s:%d", inet_ntoa(addr), c->port);
  48. }
  49. bool CSendMsgDlg::isSeq(uint32 seq)
  50. {
  51. if (!groupSend)
  52. return IcqWindow::isSeq(seq);
  53. list<SEQ>::iterator it;
  54. for (it = seqList.begin(); it != seqList.end(); ++it) {
  55. if ((*it).seq == seq)
  56. return true;
  57. }
  58. return false;
  59. }
  60. void CSendMsgDlg::enableControls(BOOL enable)
  61. {
  62. m_edtMsg.EnableWindow(enable);
  63. GetDlgItem(IDC_SEND)->EnableWindow(enable);
  64. GetDlgItem(IDC_GROUPSEND)->EnableWindow(enable);
  65. if (!enable)
  66. SetTimer(IDT_ANIMATE, 300, NULL);
  67. else {
  68. KillTimer(IDT_ANIMATE);
  69. m_btnPic.SetIcon(getApp()->largeImageList.ExtractIcon(contact->face));
  70. }
  71. }
  72. void CSendMsgDlg::resize()
  73. {
  74. int w = wholeSize.cx;
  75. int h = wholeSize.cy;
  76. if (!viewHistory)
  77. h -= lowerHeight;
  78. if (!contact->flags.test(CF_DIALOGMODE))
  79. h -= upperHeight;
  80. if (!groupSend) {
  81. CRect rc;
  82. GetDlgItem(IDC_RECIPIENTS_STATIC)->GetWindowRect(rc);
  83. w -= rc.Width() + 2;
  84. }
  85. SetWindowPos(NULL, 0, 0, w, h, SWP_NOMOVE | SWP_NOZORDER);
  86. }
  87. void CSendMsgDlg::setChatMode(BOOL moveControls)
  88. {
  89. int offset = upperHeight;
  90. CString str;
  91. if (contact->flags.test(CF_DIALOGMODE))
  92. str.LoadString(IDS_CHATMODE_NORMAL);
  93. else {
  94. str.LoadString(IDS_CHATMODE_DIALOG);
  95. offset = -offset;
  96. }
  97. SetDlgItemText(IDC_CHATMODE, str);
  98. m_edtMsg.SetFocus();
  99. if (moveControls) {
  100. for (CWnd *p = GetWindow(GW_CHILD); p; p = p->GetNextWindow()) {
  101. CRect rc;
  102. p->GetWindowRect(rc);
  103. ScreenToClient(rc);
  104. rc.OffsetRect(0, offset);
  105. p->MoveWindow(rc, FALSE);
  106. }
  107. }
  108. resize();
  109. RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE | RDW_ALLCHILDREN);
  110. }
  111. void CSendMsgDlg::initTree()
  112. {
  113. m_recipients.ModifyStyle(TVS_CHECKBOXES, 0);
  114. m_recipients.ModifyStyle(0, TVS_CHECKBOXES);
  115. m_recipients.SetImageList(&getApp()->smallImageList, TVSIL_NORMAL);
  116. MyICQCtrl &outbar = ((CIcqDlg *) AfxGetMainWnd())->outbarCtrl;
  117. int nrFolders = outbar.getFolderCount();
  118. CString name;
  119. for (int i = 0; i < nrFolders - 1; ++i) {
  120. outbar.getFolderName(i, name);
  121. int image = getApp()->iconIndex(ICON_FOLDER);
  122. HTREEITEM parent = m_recipients.InsertItem(name, image, image);
  123. m_recipients.SetItemState(parent, 0, LVIS_STATEIMAGEMASK);
  124. int nrItems = outbar.getItemCount(i);
  125. for (int j = 0; j < nrItems; ++j) {
  126. IcqContact *c = outbar.contact(i, j);
  127. if (c->status == STATUS_ONLINE) {
  128. name.Format("%s (%lu)", c->nick.c_str(), c->uin);
  129. HTREEITEM item = m_recipients.InsertItem(name, getApp()->getImageIndex(c->face),
  130. getApp()->getImageIndex(c->face, STATUS_AWAY), parent);
  131. m_recipients.SetItemData(item, c->uin);
  132. if (c->uin == uin)
  133. m_recipients.SetCheck(item);
  134. }
  135. }
  136. m_recipients.Expand(parent, TVE_EXPAND);
  137. }
  138. }
  139. void CSendMsgDlg::appendMsg(IcqMsg &msg, COLORREF color)
  140. {
  141. CString str;
  142. CTime t(msg.when);
  143. CString strTime = t.Format("%H:%M:%S");
  144. str.Format("%s (%s): %srn",
  145. (msg.flags & MF_RECEIVED) ? contact->nick.c_str() : icqLink->myInfo.nick.c_str(),
  146. (LPCTSTR) strTime, msg.text.c_str());
  147. if (msg.flags & MF_RELAY) {
  148. CString tmp;
  149. tmp.LoadString(IDS_SERVER_RELAY);
  150. str += tmp + "rn";
  151. }
  152. long start, end;
  153. m_ctlMsgView.SetSel(-1, -1);
  154. m_ctlMsgView.GetSel(start, end);
  155. m_ctlMsgView.ReplaceSel(str);
  156. m_ctlMsgView.SetSel(start, -1);
  157. CHARFORMAT cf;
  158. cf.dwMask = CFM_COLOR;
  159. cf.dwEffects = 0;
  160. cf.crTextColor = color;
  161. m_ctlMsgView.SetSelectionCharFormat(cf);
  162. m_ctlMsgView.SetSel(-1, -1);
  163. }
  164. void CSendMsgDlg::saveWindowPos()
  165. {
  166. if (!IsIconic()) {
  167. CRect rc;
  168. GetWindowRect(rc);
  169. contact->winX = rc.left;
  170. contact->winY = rc.top;
  171. }
  172. }
  173. void CSendMsgDlg::onAck(uint32 seq)
  174. {
  175. if (!groupSend) {
  176. if (seq > 0xffff)
  177. KillTimer(IDT_SENDMSG);
  178. enableControls();
  179. IcqDB::saveMsg(msgSent);
  180. } else {
  181. uint32 to = 0;
  182. list<SEQ>::iterator it;
  183. for (it = seqList.begin(); it != seqList.end(); ++it) {
  184. if ((*it).seq == seq) {
  185. to = (*it).uin;
  186. seqList.erase(it);
  187. break;
  188. }
  189. }
  190. msgSent.uin = to;
  191. IcqDB::saveMsg(msgSent);
  192. if (seqList.empty()) {
  193. KillTimer(IDT_SENDMSG);
  194. enableControls();
  195. }
  196. }
  197. appendMsg(msgSent, RGB(0, 128, 0));
  198. m_msgText.Empty();
  199. UpdateData(FALSE);
  200. if (contact->flags.test(CF_DIALOGMODE))
  201. GetDlgItem(IDC_MSG_EDIT)->SetFocus();
  202. else
  203. OnCancel();
  204. }
  205. void CSendMsgDlg::onSendError(uint32 seq)
  206. {
  207. if (!groupSend) {
  208. if (myMessageBox(IDS_SEND_RETRY, IDS_SORRY, this, MB_YESNO | MB_ICONERROR) == IDYES)
  209. seq = serverSession()->sendMessage(MSG_TEXT, uin, m_msgText);
  210. else
  211. enableControls();
  212. } else {
  213. list<SEQ>::iterator it;
  214. for (it = seqList.begin(); it != seqList.end(); ++it) {
  215. if ((*it).seq == seq) {
  216. seqList.erase(it);
  217. break;
  218. }
  219. }
  220. if (seqList.empty())
  221. myMessageBox(IDS_GROUPSEND_FAILED, IDS_SORRY, this, MB_ICONERROR);
  222. }
  223. }
  224. void CSendMsgDlg::onRecvMessage(IcqMsg &msg)
  225. {
  226. appendMsg(msg, RGB(0, 0, 255));
  227. ShowWindow(SW_NORMAL);
  228. BringWindowToTop();
  229. }
  230. void CSendMsgDlg::sendMessage(const char *text)
  231. {
  232. m_msgText = text;
  233. UpdateData(FALSE);
  234. OnSend();
  235. }
  236. void CSendMsgDlg::loadHistory()
  237. {
  238. m_lstHistory.loadHistory(uin);
  239. }
  240. BOOL CSendMsgDlg::onGroupSend()
  241. {
  242. seqList.clear();
  243. HTREEITEM item = m_recipients.GetFirstVisibleItem();
  244. while (item) {
  245. uint32 to = m_recipients.GetItemData(item);
  246. if (to && m_recipients.GetCheck(item)) {
  247. uint32 seq = icqLink->sendMessage(MSG_TEXT, to, m_msgText);
  248. SEQ node;
  249. node.uin = to;
  250. node.seq = seq;
  251. seqList.push_back(node);
  252. }
  253. item = m_recipients.GetNextVisibleItem(item);
  254. }
  255. if (seqList.empty()) {
  256. myMessageBox(IDS_UIN_EMPTY, IDS_ERROR, this, MB_ICONERROR);
  257. return FALSE;
  258. }
  259. return TRUE;
  260. }
  261. void CSendMsgDlg::DoDataExchange(CDataExchange* pDX)
  262. {
  263. CMyDlg::DoDataExchange(pDX);
  264. //{{AFX_DATA_MAP(CSendMsgDlg)
  265. DDX_Control(pDX, IDC_RECIPIENTS, m_recipients);
  266. DDX_Control(pDX, IDC_MSG_EDIT, m_edtMsg);
  267. DDX_Control(pDX, IDC_MSG_HISTORY, m_lstHistory);
  268. DDX_Control(pDX, IDC_MSG_VIEW, m_ctlMsgView);
  269. DDX_Control(pDX, IDC_PIC, m_btnPic);
  270. DDX_Text(pDX, IDC_MSG_EDIT, m_msgText);
  271. DDV_MaxChars(pDX, m_msgText, 512);
  272. DDX_Text(pDX, IDC_UIN, m_uin);
  273. DDX_Text(pDX, IDC_IPPORT, m_ipport);
  274. DDX_Text(pDX, IDC_NICK, m_nick);
  275. DDX_Text(pDX, IDC_EMAIL, m_email);
  276. //}}AFX_DATA_MAP
  277. }
  278. BEGIN_MESSAGE_MAP(CSendMsgDlg, CMyDlg)
  279. //{{AFX_MSG_MAP(CSendMsgDlg)
  280. ON_BN_CLICKED(IDC_PIC, OnPic)
  281. ON_BN_CLICKED(IDC_HISTORY, OnHistory)
  282. ON_BN_CLICKED(IDC_CHATMODE, OnChatMode)
  283. ON_BN_CLICKED(IDC_ENTER, OnEnter)
  284. ON_BN_CLICKED(IDC_CTRLENTER, OnCtrlEnter)
  285. ON_BN_CLICKED(IDC_SEND, OnSend)
  286. ON_LBN_DBLCLK(IDC_MSG_HISTORY, OnDblclkHistory)
  287. ON_WM_TIMER()
  288. ON_BN_CLICKED(IDC_GROUPSEND, OnGroupSend)
  289. //}}AFX_MSG_MAP
  290. END_MESSAGE_MAP()
  291. /////////////////////////////////////////////////////////////////////////////
  292. // CSendMsgDlg message handlers
  293. BOOL CSendMsgDlg::OnInitDialog() 
  294. {
  295. CMyDlg::OnInitDialog();
  296. initTree();
  297. int x = contact->winX;
  298. int y = contact->winY;
  299. if (x != -1 || y != -1)
  300. SetWindowPos(NULL, x, y, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
  301. m_btnPic.SetIcon(getApp()->largeImageList.ExtractIcon(contact->face));
  302. in_addr addr;
  303. addr.s_addr = htonl(contact->ip);
  304. SetDlgItemText(IDC_ADDR, inet_ntoa(addr));
  305. SetDlgItemInt(IDC_PORT, contact->port, FALSE);
  306. CheckRadioButton(IDC_ENTER, IDC_CTRLENTER,
  307. (contact->flags.test(CF_SENDENTER) ? IDC_ENTER : IDC_CTRLENTER));
  308. CRect rc;
  309. GetWindowRect(rc);
  310. wholeSize = rc.Size();
  311. GetDlgItem(IDC_UPPER)->GetWindowRect(rc);
  312. upperHeight = rc.Height();
  313. GetDlgItem(IDC_LOWER)->GetWindowRect(rc);
  314. lowerHeight = rc.Height();
  315. setChatMode(!contact->flags.test(CF_DIALOGMODE));
  316. return TRUE;  // return TRUE unless you set the focus to a control
  317.               // EXCEPTION: OCX Property Pages should return FALSE
  318. }
  319. void CSendMsgDlg::PostNcDestroy() 
  320. {
  321. delete this;
  322. }
  323. void CSendMsgDlg::OnCancel() 
  324. {
  325. saveWindowPos();
  326. DestroyWindow();
  327. }
  328. void CSendMsgDlg::OnSend() 
  329. {
  330. UpdateData();
  331. if (m_msgText.IsEmpty()) {
  332. myMessageBox(IDS_MESSAGE_EMPTY, IDS_ERROR, this);
  333. return;
  334. }
  335. msgSent.flags = 0;
  336. msgSent.when = time(NULL);
  337. msgSent.type = MSG_TEXT;
  338. msgSent.text = m_msgText;
  339. if (groupSend) {
  340. if (!onGroupSend())
  341. return;
  342. } else {
  343. msgSent.uin = uin;
  344. seq = icqLink->sendMessage(MSG_TEXT, uin, m_msgText);
  345. if (seq > 0xffff)
  346. SetTimer(IDT_SENDMSG, 30000, NULL);
  347. else
  348. msgSent.flags |= MF_RELAY;
  349. }
  350. enableControls(FALSE);
  351. if (!contact->flags.test(CF_DIALOGMODE)) {
  352. saveWindowPos();
  353. ShowWindow(SW_SHOWMINIMIZED);
  354. }
  355. }
  356. void CSendMsgDlg::OnPic() 
  357. {
  358. CViewDetailDlg *win = new CViewDetailDlg(uin);
  359. win->Create(this);
  360. }
  361. void CSendMsgDlg::OnHistory() 
  362. {
  363. viewHistory = !viewHistory;
  364. resize();
  365. if (viewHistory)
  366. loadHistory();
  367. else
  368. m_lstHistory.ResetContent();
  369. }
  370. void CSendMsgDlg::OnChatMode() 
  371. {
  372. contact->flags.flip(CF_DIALOGMODE);
  373. IcqDB::saveContact(*contact);
  374. setChatMode();
  375. if (contact->flags.test(CF_DIALOGMODE)) {
  376. // FIXME: only need to load the last 3 messages
  377. PtrList l;
  378. IcqDB::loadMsg(uin, l);
  379. for (int i = 0; !l.empty(); ++i) {
  380. IcqMsg *msg = (IcqMsg *) l.back();
  381. l.pop_back();
  382. if (i < 3)
  383. appendMsg(*msg, RGB(128, 128, 128));
  384. delete msg;
  385. }
  386. } else
  387. m_ctlMsgView.SetWindowText("");
  388. }
  389. void CSendMsgDlg::OnEnter() 
  390. {
  391. contact->flags.set(CF_SENDENTER);
  392. }
  393. void CSendMsgDlg::OnCtrlEnter() 
  394. {
  395. contact->flags.set(CF_SENDENTER, false);
  396. }
  397. BOOL CSendMsgDlg::PreTranslateMessage(MSG* pMsg) 
  398. {
  399. if (pMsg->message == WM_KEYDOWN &&
  400. pMsg->wParam == VK_RETURN &&
  401. pMsg->hwnd == m_edtMsg &&
  402. (contact->flags.test(CF_SENDENTER) || (GetKeyState(VK_CONTROL) & 0x80)))
  403. {
  404. OnSend();
  405. return TRUE;
  406. }
  407. return CMyDlg::PreTranslateMessage(pMsg);
  408. }
  409. void CSendMsgDlg::OnDblclkHistory() 
  410. {
  411. int index = m_lstHistory.GetCurSel();
  412. if (index >= 0) {
  413. CString str;
  414. m_lstHistory.GetText(index, str);
  415. str += "rn";
  416. m_edtMsg.ReplaceSel(str, TRUE);
  417. }
  418. }
  419. void CSendMsgDlg::OnTimer(UINT nIDEvent) 
  420. {
  421. if (nIDEvent == IDT_SENDMSG) {
  422. KillTimer(nIDEvent);
  423. msgSent.flags |= MF_RELAY;
  424. seq = serverSession()->sendMessage(MSG_TEXT, uin, m_msgText);
  425. } else if (nIDEvent == IDT_ANIMATE) {
  426. frame ^= 1;
  427. int i = contact->face;
  428. if (frame == 1)
  429. i += getApp()->nrFaces * 2;
  430. m_btnPic.SetIcon(getApp()->largeImageList.ExtractIcon(i));
  431. } else
  432. CMyDlg::OnTimer(nIDEvent);
  433. }
  434. void CSendMsgDlg::OnGroupSend() 
  435. {
  436. groupSend = !groupSend;
  437. CString str;
  438. if (groupSend) {
  439. str.LoadString(IDS_SINGLE_RECIPIENTS);
  440. viewHistory = FALSE;
  441. if (contact->flags.test(CF_DIALOGMODE))
  442. OnChatMode();
  443. } else
  444. str.LoadString(IDS_MULTIPLE_RECIPIENTS);
  445. SetDlgItemText(IDC_GROUPSEND, str);
  446. BOOL b = !groupSend;
  447. GetDlgItem(IDC_HISTORY)->EnableWindow(b);
  448. GetDlgItem(IDC_CHATMODE)->EnableWindow(b);
  449. resize();
  450. }