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

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. // OutBarCtrl.cpp : implementation file
  12. //
  13. #include "stdafx.h"
  14. #include "myicq.h"
  15. #include "OutBarCtrl.h"
  16. #include "OutBarEdit.h"
  17. #ifdef _DEBUG
  18. #define new DEBUG_NEW
  19. #undef THIS_FILE
  20. static char THIS_FILE[] = __FILE__;
  21. #endif
  22. OutBarFolder::~OutBarFolder()
  23. {
  24. for (int i = items.size() - 1; i >= 0; i--)
  25. delete items[i];
  26. }
  27. void OutBarFolder::addItem(const char *t, int img)
  28. {
  29. OutBarItem *item = new OutBarItem(t, img);
  30. items.push_back(item);
  31. }
  32. #define IDT_SCROLL 1001
  33. #define IDT_DBLCLK 1002
  34. /////////////////////////////////////////////////////////////////////////////
  35. // OutBarCtrl
  36. OutBarCtrl::OutBarCtrl()
  37. {
  38. listener = NULL;
  39. largeIcons = smallIcons = NULL;
  40. selFolder = 0;
  41. bgColor = RGB(128, 128, 192);
  42. fontColor = RGB(0, 0, 0);
  43. lastHit =
  44. pressedHit =
  45. clickedItem = -1;
  46. dragItem = -1;
  47. largeIconView = TRUE;
  48. editCtrl = NULL;
  49. currentCursor = NULL;
  50. handCursor = AfxGetApp()->LoadCursor(IDC_HAND);
  51. forbiddenCursor = AfxGetApp()->LoadCursor(IDC_FORBIDDEN);
  52. dragCursor = AfxGetApp()->LoadCursor(IDC_DRAG);
  53. }
  54. OutBarCtrl::~OutBarCtrl()
  55. {
  56. if (editCtrl)
  57. delete editCtrl;
  58. removeAllFolders();
  59. }
  60. int OutBarCtrl::addFolder(const char *text)
  61. {
  62. OutBarFolder *f = new OutBarFolder(text);
  63. folders.push_back(f);
  64. return folders.size() - 1;
  65. }
  66. void OutBarCtrl::addItem(int folder, const char *text, int image)
  67. {
  68. if (folder >= 0 && folder < getFolderCount())
  69. folders[folder]->addItem(text, image);
  70. }
  71. void OutBarCtrl::insertItem(int folder, int pos, OutBarItem *item)
  72. {
  73. if (folder >= 0 && folder < getFolderCount()) {
  74. vector<OutBarItem *> &items = folders[folder]->items;
  75. items.insert(items.begin() + pos, item);
  76. }
  77. }
  78. void OutBarCtrl::getFolderName(int i, CString &name)
  79. {
  80. if (i >= 0 && i < getFolderCount())
  81. name = folders[i]->text;
  82. }
  83. int OutBarCtrl::getItemCount(int folder)
  84. {
  85. return folders[folder]->items.size();
  86. }
  87. int &OutBarCtrl::scrollPos()
  88. {
  89. return folders[selFolder]->scrollPos;
  90. }
  91. int OutBarCtrl::getCountPerPage()
  92. {
  93. CRect rc;
  94. getInsideRect(rc);
  95. int h = (largeIconView ? LARGE_ITEM_H : SMALL_ITEM_H);
  96. return ((rc.Height() / h) + 1);
  97. }
  98. void OutBarCtrl::setSelFolder(int i)
  99. {
  100. if (i != selFolder && i < getFolderCount())
  101. selFolder = i;
  102. }
  103. void OutBarCtrl::getFolderRect(CRect &rc, int i)
  104. {
  105. GetClientRect(rc);
  106. if (i <= selFolder)
  107. rc.top += i * FOLDER_HEIGHT;
  108. else
  109. rc.top = rc.bottom - (folders.size() - i) * FOLDER_HEIGHT;
  110. rc.bottom = rc.top + FOLDER_HEIGHT;
  111. }
  112. void OutBarCtrl::getInsideRect(CRect &rc)
  113. {
  114. GetClientRect(rc);
  115. rc.top += (selFolder + 1) * FOLDER_HEIGHT;
  116. rc.bottom -= (folders.size() - selFolder - 1) * FOLDER_HEIGHT;
  117. }
  118. void OutBarCtrl::getItemRect(CRect &rc, int i)
  119. {
  120. getInsideRect(rc);
  121. int h = (largeIconView ? LARGE_ITEM_H : SMALL_ITEM_H);
  122. rc.top += h * (i - scrollPos()) + ICON_OFFSET;
  123. rc.bottom = rc.top + h;
  124. }
  125. void OutBarCtrl::getIconRect(CRect &rc, int i)
  126. {
  127. getItemRect(rc, i);
  128. if (largeIconView) {
  129. rc.left += (rc.Width() - LARGE_ICON_W) / 2;
  130. rc.right = rc.left + LARGE_ICON_W;
  131. rc.bottom = rc.top + LARGE_ICON_H;
  132. } else {
  133. rc.top += (rc.Height() - SMALL_ICON_H) / 2;
  134. rc.bottom = rc.top + SMALL_ICON_H;
  135. rc.left += 2;
  136. rc.right = rc.left + SMALL_ICON_W;
  137. }
  138. }
  139. void OutBarCtrl::getLabelRect(CRect &rc, int i)
  140. {
  141. getItemRect(rc, i);
  142. if (largeIconView)
  143. rc.top += LARGE_ICON_H;
  144. else
  145. rc.left += SMALL_ICON_W + 2 + 5;
  146. }
  147. void OutBarCtrl::getScrollRect(CRect &rc, int i)
  148. {
  149. getInsideRect(rc);
  150. int size = GetSystemMetrics(SM_CXVSCROLL);
  151. rc.right -= 5;
  152. rc.left = rc.right - size;
  153. if (i == SCROLL_DIR_UP) {
  154. rc.top += 5;
  155. rc.bottom = rc.top + size;
  156. } else {
  157. rc.bottom -= 5;
  158. rc.top = rc.bottom - size;
  159. }
  160. }
  161. void OutBarCtrl::repaintInsideRect()
  162. {
  163. CRect rc;
  164. getInsideRect(rc);
  165. InvalidateRect(rc);
  166. }
  167. HIT OutBarCtrl::hitTest(const CPoint &pt)
  168. {
  169. int obj = HT_NONE;
  170. int index = -1;
  171. CRect rcClient, rc;
  172. GetClientRect(rcClient);
  173. getInsideRect(rc);
  174. if (!rc.PtInRect(pt)) {
  175. if (pt.y >= 0 && pt.y < rc.top) {
  176. obj = HT_FOLDER;
  177. index = (pt.y - 1) / FOLDER_HEIGHT;
  178. } else if (pt.y > rc.bottom && pt.y < rcClient.bottom - 1) {
  179. obj = HT_FOLDER;
  180. index = (pt.y - rc.bottom) / FOLDER_HEIGHT + selFolder + 1;
  181. }
  182. } else {
  183. for (int i = 0; i < 2; i++) {
  184. if (canScroll(i)) {
  185. CRect rcScroll;
  186. getScrollRect(rcScroll, i);
  187. if (rcScroll.PtInRect(pt))
  188. return MAKEHIT(HT_SCROLL, i);
  189. }
  190. }
  191. if (largeIconView) {
  192. int offset = (rc.Width() - LARGE_ICON_W) / 2;
  193. if (pt.x >= rc.left + offset &&
  194. pt.x <= rc.right - offset) {
  195. int y = pt.y - rc.top;
  196. offset = y % LARGE_ITEM_H - ICON_OFFSET;
  197. if (offset >= 0 && offset <= LARGE_ICON_H) {
  198. int i = y / LARGE_ITEM_H + scrollPos();
  199. if (i <= getMaxVisibleItem()) {
  200. obj = HT_ITEM;
  201. index = i;
  202. }
  203. }
  204. }
  205. } else if (pt.x < SMALL_ICON_W + 32) {
  206. int i = (pt.y - rc.top) / SMALL_ITEM_H + scrollPos();
  207. if (i <= getMaxVisibleItem()) {
  208. obj = HT_ITEM;
  209. index = i;
  210. }
  211. }
  212. }
  213. return MAKEHIT(obj, index);
  214. }
  215. BOOL OutBarCtrl::canScroll(int dir)
  216. {
  217. if (dir == SCROLL_DIR_UP)
  218. return (scrollPos() > 0);
  219. int n = getCountPerPage();
  220. return (n + scrollPos() <= getItemCount());
  221. }
  222. void OutBarCtrl::scroll(int dir, int delta)
  223. {
  224. if (dir == SCROLL_DIR_UP)
  225. scrollPos() -= delta;
  226. else
  227. scrollPos() += delta;
  228. if (!canScroll(dir)) {
  229. KillTimer(IDT_SCROLL);
  230. CClientDC dc(this);
  231. drawScroll(&dc, dir);
  232. pressedHit = lastHit = HITNONE;
  233. }
  234. repaintInsideRect();
  235. }
  236. void OutBarCtrl::drawFolder(CDC *pDC, int i, BOOL pressed, BOOL hilight)
  237. {
  238. CRect rc;
  239. getFolderRect(rc, i);
  240. if (pressed) {
  241. pDC->Draw3dRect(rc, GetSysColor(COLOR_3DDKSHADOW), GetSysColor(COLOR_BTNHILIGHT));
  242. rc.InflateRect(-1, -1);
  243. pDC->Draw3dRect(rc, GetSysColor(COLOR_BTNSHADOW), GetSysColor(COLOR_BTNFACE));
  244. } else if (hilight) {
  245. pDC->Draw3dRect(rc, GetSysColor(COLOR_BTNHILIGHT), GetSysColor(COLOR_3DDKSHADOW));
  246. rc.InflateRect(-1, -1);
  247. pDC->Draw3dRect(rc, GetSysColor(COLOR_BTNFACE), GetSysColor(COLOR_3DDKSHADOW));
  248. } else
  249. pDC->Draw3dRect(rc, GetSysColor(COLOR_BTNHILIGHT), GetSysColor(COLOR_3DDKSHADOW));
  250. rc.InflateRect(-1, -1);
  251. pDC->FillSolidRect(rc, GetSysColor(COLOR_BTNFACE));
  252. if (pressed)
  253. rc.OffsetRect(1, 1);
  254. drawFolderText(pDC, i, rc);
  255. }
  256. void OutBarCtrl::drawFolderText(CDC *pDC, int i, CRect &rc)
  257. {
  258. CFont *oldFont = pDC->SelectObject(CFont::FromHandle((HFONT) GetStockObject(DEFAULT_GUI_FONT)));
  259. int oldBkMode = pDC->SetBkMode(TRANSPARENT);
  260. pDC->DrawText(folders[i]->text, rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
  261. pDC->SetBkMode(oldBkMode);
  262. pDC->SelectObject(oldFont);
  263. }
  264. void OutBarCtrl::drawItem(CDC *pDC, int i, BOOL redraw)
  265. {
  266. CRect rc;
  267. getIconRect(rc, i);
  268. if (redraw) {
  269. CRect clip;
  270. getInsideRect(clip);
  271. CRgn rgn;
  272. rgn.CreateRectRgnIndirect(clip);
  273. pDC->SelectClipRgn(&rgn);
  274. drawBackground(pDC, rc);
  275. }
  276. drawItemImage(pDC, i, rc);
  277. if (!redraw)
  278. drawItemText(pDC, i, fontColor);
  279. }
  280. int OutBarCtrl::getMaxVisibleItem()
  281. {
  282. int max = getCountPerPage() + scrollPos();
  283. if (max > getItemCount())
  284. max = getItemCount();
  285. return (--max);
  286. }
  287. void OutBarCtrl::drawBackground(CDC *pDC, CRect &rc)
  288. {
  289. pDC->FillSolidRect(rc, bgColor);
  290. }
  291. void OutBarCtrl::drawItemImage(CDC *pDC, int i, CRect &rc)
  292. {
  293. int img = folders[selFolder]->items[i]->image;
  294. CImageList *imageList = (largeIconView ? largeIcons : smallIcons);
  295. imageList->Draw(pDC, img, rc.TopLeft(), ILD_TRANSPARENT);
  296. }
  297. void OutBarCtrl::drawItemText(CDC *pDC, int i, COLORREF color)
  298. {
  299. CRect rc;
  300. getLabelRect(rc, i);
  301. OutBarItem *item = folders[selFolder]->items[i];
  302. int style = DT_SINGLELINE | DT_VCENTER;
  303. if (largeIconView)
  304. style |= DT_CENTER;
  305. CFont *oldFont = pDC->SelectObject(CFont::FromHandle((HFONT) GetStockObject(DEFAULT_GUI_FONT)));
  306. COLORREF oldColor = pDC->SetTextColor(color);
  307. int oldBkMode = pDC->SetBkMode(TRANSPARENT);
  308. pDC->DrawText(item->text, rc, style);
  309. pDC->SetBkMode(oldBkMode);
  310. pDC->SetTextColor(oldColor);
  311. pDC->SelectObject(oldFont);
  312. }
  313. void OutBarCtrl::hilightItem(CDC *pDC, int i, BOOL pressed)
  314. {
  315. CRect rc;
  316. getInsideRect(rc);
  317. CRgn rgn;
  318. rgn.CreateRectRgnIndirect(rc);
  319. pDC->SelectClipRgn(&rgn);
  320. getIconRect(rc, i);
  321. if (pressed)
  322. pDC->Draw3dRect(rc, GetSysColor(COLOR_3DDKSHADOW), GetSysColor(COLOR_BTNHILIGHT));
  323. else
  324. pDC->Draw3dRect(rc, GetSysColor(COLOR_BTNHILIGHT), GetSysColor(COLOR_3DDKSHADOW));
  325. }
  326. void OutBarCtrl::drawScroll(CDC *pDC, int i, BOOL pressed)
  327. {
  328. CRect rc;
  329. getScrollRect(rc, i);
  330. int state = (i == SCROLL_DIR_UP ? DFCS_SCROLLUP : DFCS_SCROLLDOWN);
  331. if (pressed)
  332. state |= DFCS_PUSHED;
  333. pDC->DrawFrameControl(rc, DFC_SCROLL, state);
  334. }
  335. void OutBarCtrl::removeFolder(int i)
  336. {
  337. delete folders[i];
  338. folders.erase(folders.begin() + i);
  339. Invalidate();
  340. }
  341. void OutBarCtrl::removeAllFolders()
  342. {
  343. for (int i = folders.size() - 1; i >= 0; i--)
  344. delete folders[i];
  345. folders.clear();
  346. }
  347. void OutBarCtrl::removeItem(int i)
  348. {
  349. vector<OutBarItem *> &items = folders[selFolder]->items;
  350. delete items[i];
  351. items.erase(items.begin() + i);
  352. repaintInsideRect();
  353. }
  354. void OutBarCtrl::renameUI()
  355. {
  356. onEditCanceled();
  357. int obj = HITOBJ(lastHit);
  358. int i = HITINDEX(lastHit);
  359. DWORD flags = WS_VISIBLE | WS_CHILD | ES_CENTER;
  360. const char *text = "";
  361. editCtrl = new OutBarEdit(this, obj, i);
  362. if (obj == HT_FOLDER) {
  363. text = folders[i]->text;
  364. editCtrl->Create(flags, CRect(0, 0, 0, 0), this, 1);
  365. editCtrl->ModifyStyleEx(0, WS_EX_CLIENTEDGE, SWP_FRAMECHANGED);
  366. } else if (obj == HT_ITEM) {
  367. CClientDC dc(this);
  368. drawItem(&dc, i, TRUE);
  369. text = folders[selFolder]->items[i]->text;
  370. editCtrl->Create(flags | WS_BORDER, CRect(0, 0, 0, 0), this, 1);
  371. }
  372. editCtrl->SetFont(CFont::FromHandle((HFONT) GetStockObject(DEFAULT_GUI_FONT)));
  373. editCtrl->SetWindowText(text);
  374. editCtrl->SetFocus();
  375. editCtrl->SetSel(0, -1);
  376. resizeEditCtrl();
  377. }
  378. void OutBarCtrl::addFolderUI()
  379. {
  380. OutBarFolder *f = new OutBarFolder("");
  381. folders.insert(folders.begin() + selFolder + 1, f);
  382. Invalidate();
  383. lastHit = MAKEHIT(HT_FOLDER, selFolder + 1);
  384. renameUI();
  385. }
  386. void OutBarCtrl::resizeEditCtrl()
  387. {
  388. if (!editCtrl)
  389. return;
  390. int obj = editCtrl->obj;
  391. int i = editCtrl->index;
  392. CRect rc;
  393. if (obj == HT_FOLDER) {
  394. getFolderRect(rc, i);
  395. rc.InflateRect(-2, -2);
  396. } else if (obj == HT_ITEM) {
  397. getLabelRect(rc, i);
  398. if (largeIconView) {
  399. rc.left += 5;
  400. rc.right -= 5;
  401. }
  402. }
  403. editCtrl->MoveWindow(rc);
  404. }
  405. void OutBarCtrl::onEditFinished()
  406. {
  407. if (!editCtrl)
  408. return;
  409. CString text;
  410. editCtrl->GetWindowText(text);
  411. int index = editCtrl->index;
  412. if (editCtrl->obj == HT_FOLDER)
  413. folders[index]->text = text;
  414. else if (editCtrl->obj == HT_ITEM)
  415. folders[selFolder]->items[index]->text = text;
  416. if (listener)
  417. listener->renamed(editCtrl->obj, index, text);
  418. delete editCtrl;
  419. editCtrl = NULL;
  420. }
  421. void OutBarCtrl::onEditCanceled()
  422. {
  423. if (editCtrl) {
  424. delete editCtrl;
  425. editCtrl = NULL;
  426. }
  427. }
  428. BEGIN_MESSAGE_MAP(OutBarCtrl, CWnd)
  429. //{{AFX_MSG_MAP(OutBarCtrl)
  430. ON_WM_PAINT()
  431. ON_WM_MOUSEMOVE()
  432. ON_WM_LBUTTONDOWN()
  433. ON_WM_LBUTTONUP()
  434. ON_WM_LBUTTONDBLCLK()
  435. ON_WM_TIMER()
  436. ON_WM_SIZE()
  437. ON_WM_MOUSEWHEEL()
  438. ON_WM_RBUTTONDOWN()
  439. ON_WM_ERASEBKGND()
  440. ON_WM_SETCURSOR()
  441. ON_WM_KEYDOWN()
  442. //}}AFX_MSG_MAP
  443. ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
  444. END_MESSAGE_MAP()
  445. /////////////////////////////////////////////////////////////////////////////
  446. // OutBarCtrl message handlers
  447. void OutBarCtrl::OnPaint() 
  448. {
  449. CPaintDC dc(this); // device context for painting
  450. CDC memDC;
  451. memDC.CreateCompatibleDC(&dc);
  452. CRect rcClient;
  453. GetClientRect(rcClient);
  454. CBitmap bm;
  455. bm.CreateCompatibleBitmap(&dc, rcClient.Width(), rcClient.Height());
  456. CBitmap *oldBitmap = memDC.SelectObject(&bm);
  457. int obj = HITOBJ(lastHit);
  458. int index = HITINDEX(lastHit);
  459. int i;
  460. for (i = folders.size() - 1; i >= 0; i--)
  461. drawFolder(&memDC, i, FALSE, (obj == HT_FOLDER && index == i));
  462. CRect rc;
  463. getInsideRect(rc);
  464. drawBackground(&memDC, rc);
  465. CRgn rgn;
  466. rgn.CreateRectRgnIndirect(rc);
  467. memDC.SelectClipRgn(&rgn);
  468. int max = getMaxVisibleItem();
  469. for (i = scrollPos(); i <= max; i++)
  470. drawItem(&memDC, i);
  471. if (obj == HT_ITEM)
  472. hilightItem(&memDC, index, FALSE);
  473. for (i = 1; i >= 0; i--) {
  474. if (canScroll(i))
  475. drawScroll(&memDC, i, pressedHit == MAKEHIT(HT_SCROLL, i));
  476. }
  477. dc.BitBlt(0, 0, rcClient.Width(), rcClient.Height(), &memDC, 0, 0, SRCCOPY);
  478. memDC.SelectObject(oldBitmap);
  479. }
  480. void OutBarCtrl::OnMouseMove(UINT nFlags, CPoint point) 
  481. {
  482. HIT hit = hitTest(point);
  483. if (hit != lastHit) {
  484. int newObj = HITOBJ(hit);
  485. int newIndex = HITINDEX(hit);
  486. if (!editCtrl) {
  487. CClientDC dc(this);
  488. int obj = HITOBJ(lastHit);
  489. int index = HITINDEX(lastHit);
  490. if (obj == HT_FOLDER)
  491. drawFolder(&dc, index, FALSE, FALSE);
  492. else if (obj == HT_ITEM)
  493. drawItem(&dc, index, TRUE);
  494. else if (obj == HT_SCROLL && HITOBJ(pressedHit) == HT_SCROLL) {
  495. drawScroll(&dc, index);
  496. KillTimer(IDT_SCROLL);
  497. }
  498. if (newObj == HT_FOLDER) {
  499. TRACKMOUSEEVENT tme;
  500. tme.cbSize = sizeof(tme);
  501. tme.dwFlags = TME_LEAVE;
  502. tme.hwndTrack = m_hWnd;
  503. tme.dwHoverTime = 0;
  504. // _TrackMouseEvent(&tme);
  505. drawFolder(&dc, newIndex, hit == pressedHit, TRUE);
  506. } else {
  507. if (newObj == HT_ITEM)
  508. hilightItem(&dc, newIndex, hit == pressedHit);
  509. else if (newObj == HT_SCROLL && hit == pressedHit) {
  510. SetTimer(IDT_SCROLL, 100, NULL);
  511. scroll(newIndex);
  512. }
  513. }
  514. }
  515. lastHit = hit;
  516. if (dragItem >= 0) {
  517. if (newObj == HT_FOLDER && selFolder != newIndex)
  518. currentCursor = dragCursor;
  519. else
  520. currentCursor = forbiddenCursor;
  521. } else if (newObj == HT_FOLDER)
  522. currentCursor = handCursor;
  523. else
  524. currentCursor = NULL;
  525. }
  526. CWnd::OnMouseMove(nFlags, point);
  527. }
  528. void OutBarCtrl::OnLButtonDown(UINT nFlags, CPoint point) 
  529. {
  530. if (GetFocus() != this) SetFocus();
  531. OnMouseMove(nFlags, point);
  532. int obj = HITOBJ(lastHit);
  533. int index = HITINDEX(lastHit);
  534. CClientDC dc(this);
  535. pressedHit = lastHit;
  536. if (obj == HT_FOLDER)
  537. drawFolder(&dc, index, TRUE);
  538. else if (obj == HT_ITEM) {
  539. dragItem = index;
  540. hilightItem(&dc, index, TRUE);
  541. } else if (obj == HT_SCROLL) {
  542. SetTimer(IDT_SCROLL, 100, NULL);
  543. scroll(index);
  544. }
  545. CWnd::OnLButtonDown(nFlags, point);
  546. }
  547. void OutBarCtrl::OnLButtonUp(UINT nFlags, CPoint point) 
  548. {
  549. OnMouseMove(nFlags, point);
  550. int obj = HITOBJ(lastHit);
  551. int index = HITINDEX(lastHit);
  552. if (dragItem >= 0) {
  553. if (obj == HT_FOLDER) {
  554. currentCursor = handCursor;
  555. if (listener && selFolder != index)
  556. listener->itemDragged(dragItem, index);
  557. } else
  558. currentCursor = NULL;
  559. dragItem = -1;
  560. }
  561. CClientDC dc(this);
  562. if (pressedHit == lastHit) {
  563. if (obj == HT_FOLDER) {
  564. if (index == selFolder)
  565. drawFolder(&dc, index);
  566. else {
  567. selFolder = index;
  568. Invalidate();
  569. if (listener)
  570. listener->selFolderChanged(selFolder);
  571. }
  572. } else if (obj == HT_ITEM) {
  573. hilightItem(&dc, index, FALSE);
  574. clickedItem = index;
  575. SetTimer(IDT_DBLCLK, 300, NULL);
  576. } else if (obj == HT_SCROLL) {
  577. drawScroll(&dc, index);
  578. KillTimer(IDT_SCROLL);
  579. }
  580. }
  581. pressedHit = HITNONE;
  582. CWnd::OnLButtonUp(nFlags, point);
  583. }
  584. void OutBarCtrl::OnLButtonDblClk(UINT nFlags, CPoint point) 
  585. {
  586. if (HITOBJ(lastHit) == HT_ITEM) {
  587. KillTimer(IDT_DBLCLK);
  588. if (listener)
  589. listener->itemDoubleClicked(clickedItem);
  590. clickedItem = -1;
  591. }
  592. CWnd::OnLButtonDblClk(nFlags, point);
  593. }
  594. void OutBarCtrl::OnTimer(UINT nIDEvent) 
  595. {
  596. if (nIDEvent == IDT_SCROLL) {
  597. if (HITOBJ(pressedHit) == HT_SCROLL)
  598. scroll(HITINDEX(pressedHit));
  599. } else if (nIDEvent == IDT_DBLCLK) {
  600. KillTimer(IDT_DBLCLK);
  601. if (listener && lastHit == MAKEHIT(HT_ITEM, clickedItem))
  602. listener->itemClicked(clickedItem);
  603. clickedItem = -1;
  604. }
  605. CWnd::OnTimer(nIDEvent);
  606. }
  607. void OutBarCtrl::OnSize(UINT nType, int cx, int cy) 
  608. {
  609. CWnd::OnSize(nType, cx, cy);
  610. resizeEditCtrl();
  611. }
  612. BOOL OutBarCtrl::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) 
  613. {
  614. int dir;
  615. int delta = zDelta / WHEEL_DELTA;
  616. if (delta > 0)
  617. dir = SCROLL_DIR_UP;
  618. else {
  619. dir = SCROLL_DIR_DOWN;
  620. delta = -delta;
  621. }
  622. if (canScroll(dir))
  623. scroll(dir, delta);
  624. return CWnd::OnMouseWheel(nFlags, zDelta, pt);
  625. }
  626. void OutBarCtrl::OnRButtonDown(UINT nFlags, CPoint point) 
  627. {
  628. OnMouseMove(nFlags, point);
  629. if (listener)
  630. listener->rightButtonDown(HITOBJ(lastHit), HITINDEX(lastHit));
  631. CWnd::OnRButtonDown(nFlags, point);
  632. }
  633. BOOL OutBarCtrl::OnEraseBkgnd(CDC* pDC) 
  634. {
  635. return TRUE;
  636. }
  637. BOOL OutBarCtrl::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
  638. {
  639. if (currentCursor) {
  640. SetCursor(currentCursor);
  641. return TRUE;
  642. }
  643. return CWnd::OnSetCursor(pWnd, nHitTest, message);
  644. }
  645. void OutBarCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
  646. {
  647. int start = -1;
  648. if (HITOBJ(lastHit) == HT_ITEM)
  649. start = HITINDEX(lastHit);
  650. vector<OutBarItem *> &items = folders[selFolder]->items;
  651. int n = items.size();
  652. int c = toupper(nChar);
  653. int k = start;
  654. for (int i = 0; i < n; ++i) {
  655. if (toupper(items[++k % n]->text[0]) == c)
  656. break;
  657. }
  658. if (i < n) {
  659. k %= n;
  660. lastHit = MAKEHIT(HT_ITEM, k);
  661. scrollToPos(k);
  662. }
  663. CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
  664. }
  665. LRESULT OutBarCtrl::OnMouseLeave(WPARAM wParam, LPARAM lParam)
  666. {
  667. int obj = HITOBJ(lastHit);
  668. int index = HITINDEX(lastHit);
  669. if (obj == HT_FOLDER) {
  670. CClientDC dc(this);
  671. drawFolder(&dc, index, FALSE, FALSE);
  672. }
  673. lastHit = pressedHit = HT_NONE;
  674. return 0;
  675. }