QListCtrl.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691
  1. // QListCtrl.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "CP_Main.h"
  5. #include "QListCtrl.h"
  6. #include "ProcessPaste.h"
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #undef THIS_FILE
  10. static char THIS_FILE[] = __FILE__;
  11. #endif
  12. #define ROW_BOTTOM_BORDER 2
  13. #define ROW_LEFT_BORDER 3
  14. #define COLOR_SHADOW RGB(245, 245, 245)
  15. #define DUMMY_COL_WIDTH 1
  16. /////////////////////////////////////////////////////////////////////////////
  17. // CQListCtrl
  18. CQListCtrl::CQListCtrl()
  19. {
  20. m_pchTip = NULL;
  21. m_pwchTip = NULL;
  22. LOGFONT lf;
  23. lf.lfHeight = -9;
  24. lf.lfWidth = 0;
  25. lf.lfEscapement = 0;
  26. lf.lfOrientation = 0;
  27. lf.lfWeight = FW_LIGHT;
  28. lf.lfItalic = FALSE;
  29. lf.lfUnderline = FALSE;
  30. lf.lfStrikeOut = FALSE;
  31. lf.lfCharSet = ANSI_CHARSET;
  32. lf.lfOutPrecision = OUT_STRING_PRECIS;
  33. lf.lfClipPrecision = CLIP_STROKE_PRECIS;
  34. lf.lfQuality = DEFAULT_QUALITY;
  35. lf.lfPitchAndFamily = VARIABLE_PITCH | FF_DONTCARE;
  36. lstrcpy(lf.lfFaceName, "Small Font");
  37. m_SmallFont = CreateFontIndirect(&lf);
  38. m_bShowTextForFirstTenHotKeys = true;
  39. m_Accelerator = NULL;
  40. m_acFirstTen = NULL;
  41. }
  42. CQListCtrl::~CQListCtrl()
  43. {
  44. if(m_pchTip != NULL)
  45. delete m_pchTip;
  46. if(m_pwchTip != NULL)
  47. delete m_pwchTip;
  48. DestroyAndCreateAccelerator(FALSE);
  49. if(m_acFirstTen)
  50. {
  51. DestroyAcceleratorTable(m_acFirstTen);
  52. m_acFirstTen = NULL;
  53. }
  54. }
  55. BEGIN_MESSAGE_MAP(CQListCtrl, CListCtrl)
  56. //{{AFX_MSG_MAP(CQListCtrl)
  57. ON_NOTIFY_REFLECT(LVN_KEYDOWN, OnKeydown)
  58. ON_NOTIFY_REFLECT(NM_DBLCLK, OnDblclk)
  59. ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomdrawList)
  60. ON_WM_SYSKEYDOWN()
  61. ON_WM_ERASEBKGND()
  62. ON_WM_CREATE()
  63. ON_WM_VSCROLL()
  64. ON_WM_HSCROLL()
  65. //}}AFX_MSG_MAP
  66. ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText)
  67. ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipText)
  68. END_MESSAGE_MAP()
  69. /////////////////////////////////////////////////////////////////////////////
  70. // CQListCtrl message handlers
  71. void CQListCtrl::OnKeydown(NMHDR* pNMHDR, LRESULT* pResult)
  72. {
  73. LV_KEYDOWN* pLVKeyDow = (LV_KEYDOWN*)pNMHDR;
  74. switch (pLVKeyDow->wVKey)
  75. {
  76. case VK_RETURN:
  77. {
  78. ARRAY arr;
  79. GetSelectionIndexes(arr);
  80. SendSelection(arr);
  81. }
  82. break;
  83. case VK_ESCAPE:
  84. GetParent()->SendMessage(NM_END, 0, 0);
  85. break;
  86. case VK_RIGHT:
  87. {
  88. int nItem = GetNextItem(-1, LVNI_SELECTED);
  89. if (nItem != -1)
  90. GetParent()->SendMessage(NM_RIGHT, nItem, 0);
  91. }
  92. break;
  93. case VK_LEFT:
  94. GetParent()->SendMessage(NM_LEFT, 0, 0);
  95. break;
  96. case VK_DELETE:
  97. GetParent()->SendMessage(NM_DELETE, 0, 0);
  98. break;
  99. }
  100. *pResult = 0;
  101. }
  102. void CQListCtrl::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult)
  103. {
  104. LPNMITEMACTIVATE lpnmItem = (LPNMITEMACTIVATE) pNMHDR;
  105. UINT Flags;
  106. int nItem = -1;
  107. if ((nItem = HitTest(lpnmItem->ptAction, &Flags)) != -1)
  108. {
  109. if (Flags | LVHT_ONITEM)
  110. SendSelection(nItem);
  111. }
  112. *pResult = 0;
  113. }
  114. void CQListCtrl::SendSelection(int nItem)
  115. {
  116. GetParent()->SendMessage(NM_SELECT, 1, (LPARAM) &nItem);
  117. }
  118. void CQListCtrl::SendSelection(ARRAY &arrItems)
  119. {
  120. GetParent()->SendMessage(NM_SELECT, arrItems.GetSize(), (LPARAM) arrItems.GetData());
  121. }
  122. void CQListCtrl::GetSelectionIndexes(ARRAY &arr)
  123. {
  124. arr.RemoveAll();
  125. POSITION pos = GetFirstSelectedItemPosition();
  126. while (pos)
  127. arr.Add(GetNextSelectedItem(pos));
  128. /*
  129. int nItem = GetNextItem(-1, LVNI_SELECTED);
  130. while (nItem != -1)
  131. {
  132. arr.Add(nItem);
  133. nItem = GetNextItem(nItem, LVNI_SELECTED);
  134. }
  135. */
  136. }
  137. void CQListCtrl::GetSelectionItemData(ARRAY &arr)
  138. {
  139. arr.RemoveAll();
  140. POSITION pos = GetFirstSelectedItemPosition();
  141. while (pos)
  142. arr.Add(GetItemData(GetNextSelectedItem(pos)));
  143. /*
  144. int nItem = GetNextItem(-1, LVNI_SELECTED);
  145. while (nItem != -1)
  146. {
  147. arr.Add((int)GetItemData(nItem));
  148. nItem = GetNextItem(nItem, LVNI_SELECTED);
  149. }
  150. */
  151. }
  152. void CQListCtrl::RemoveAllSelection()
  153. {
  154. POSITION pos = GetFirstSelectedItemPosition();
  155. while (pos)
  156. {
  157. SetSelection(GetNextSelectedItem(pos), FALSE);
  158. }
  159. }
  160. BOOL CQListCtrl::SetSelection(int nRow, BOOL bSelect)
  161. {
  162. if(bSelect)
  163. return SetItemState(nRow, LVIS_SELECTED, LVIS_SELECTED);
  164. else
  165. return SetItemState(nRow, ~LVIS_SELECTED, LVIS_SELECTED);
  166. }
  167. BOOL CQListCtrl::SetText(int nRow, int nCol, CString cs)
  168. {
  169. return SetItemText(nRow, nCol, cs);
  170. }
  171. BOOL CQListCtrl::SetCaret(int nRow, BOOL bFocus)
  172. {
  173. if(bFocus)
  174. return SetItemState(nRow, LVIS_FOCUSED, LVIS_FOCUSED);
  175. else
  176. return SetItemState(nRow, ~LVIS_FOCUSED, LVIS_FOCUSED);
  177. }
  178. long CQListCtrl::GetCaret()
  179. {
  180. return GetNextItem(0, LVNI_FOCUSED);
  181. }
  182. BOOL CQListCtrl::SetFormattedText(int nRow, int nCol, LPCTSTR lpszFormat,...)
  183. {
  184. CString csText;
  185. va_list vlist;
  186. ASSERT(AfxIsValidString(lpszFormat));
  187. va_start(vlist,lpszFormat);
  188. csText.FormatV(lpszFormat,vlist);
  189. va_end(vlist);
  190. return SetText(nRow,nCol,csText);
  191. }
  192. void CQListCtrl::SetNumberOfLinesPerRow(int nLines)
  193. {
  194. CDC *pDC = GetDC();
  195. CRect crRect(0, 0, 0, 0);
  196. CFont *pOldFont = pDC->SelectObject(GetFont());
  197. //Get the height to draw one character
  198. pDC->DrawText("W", crRect, DT_VCENTER | DT_EXPANDTABS | DT_CALCRECT);
  199. pDC->SelectObject(pOldFont);
  200. //Get the total height of each row
  201. int nHeight = (crRect.Height() * nLines) + ROW_BOTTOM_BORDER;
  202. //Create a image list of that height and set it to the list box
  203. CImageList imglist;
  204. imglist.Create(DUMMY_COL_WIDTH, nHeight, ILC_COLOR16 | ILC_MASK, 1, 1);
  205. SetImageList(&imglist, LVSIL_SMALL );
  206. }
  207. void CQListCtrl::OnCustomdrawList(NMHDR* pNMHDR, LRESULT* pResult)
  208. {
  209. NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>( pNMHDR );
  210. *pResult = 0;
  211. // Request item-specific notifications if this is the
  212. // beginning of the paint cycle.
  213. if ( CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage )
  214. {
  215. *pResult = CDRF_NOTIFYITEMDRAW;
  216. }
  217. else if ( CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage )
  218. {
  219. LVITEM rItem;
  220. int nItem = static_cast<int>( pLVCD->nmcd.dwItemSpec );
  221. CDC* pDC = CDC::FromHandle ( pLVCD->nmcd.hdc );
  222. COLORREF crBkgnd;
  223. BOOL bListHasFocus;
  224. CRect rcItem;
  225. bListHasFocus = ( GetSafeHwnd() == ::GetFocus() );
  226. // Get the image index and selected/focused state of the
  227. // item being drawn.
  228. ZeroMemory ( &rItem, sizeof(LVITEM) );
  229. rItem.mask = LVIF_STATE;
  230. rItem.iItem = nItem;
  231. rItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
  232. GetItem(&rItem);
  233. // Get the rect that bounds the text label.
  234. GetItemRect(nItem, rcItem, LVIR_LABEL);
  235. rcItem.left -= DUMMY_COL_WIDTH;
  236. CPen cpWhite;
  237. cpWhite.CreatePen(PS_SOLID, 1, RGB(255, 255, 255));
  238. CPen *pOldPen = NULL;
  239. COLORREF OldColor = -1;
  240. int nOldBKMode = -1;
  241. // Draw the background of the list item. Colors are selected
  242. // according to the item's state.
  243. if(rItem.state & LVIS_SELECTED)
  244. {
  245. if(bListHasFocus)
  246. {
  247. crBkgnd = GetSysColor(COLOR_HIGHLIGHT);
  248. OldColor = pDC->SetTextColor(GetSysColor(COLOR_HIGHLIGHTTEXT));
  249. pOldPen = pDC->SelectObject((CPen*)&cpWhite);
  250. }
  251. else
  252. {
  253. crBkgnd = GetSysColor(COLOR_BTNFACE);
  254. OldColor = pDC->SetTextColor(GetSysColor(COLOR_BTNTEXT));
  255. }
  256. }
  257. else
  258. {
  259. //Shade alternating Rows
  260. if((nItem % 2) == 0)
  261. crBkgnd = COLOR_SHADOW;
  262. else
  263. crBkgnd = GetSysColor(COLOR_WINDOW);
  264. OldColor = pDC->SetTextColor(GetSysColor(COLOR_BTNTEXT));
  265. }
  266. pDC->FillSolidRect(rcItem, crBkgnd);
  267. nOldBKMode = pDC->SetBkMode(TRANSPARENT);
  268. CRect rcText = rcItem;
  269. rcText.left += ROW_LEFT_BORDER;
  270. rcText.top++;
  271. // Draw the text.
  272. CString csText = GetItemText(nItem, 0);
  273. if(m_bShowTextForFirstTenHotKeys)
  274. {
  275. if(nItem < 10)
  276. rcText.left += 12;
  277. }
  278. pDC->DrawText(csText, rcText, DT_VCENTER | DT_EXPANDTABS);
  279. // Draw a focus rect around the item if necessary.
  280. if(bListHasFocus && (rItem.state & LVIS_FOCUSED))
  281. pDC->DrawFocusRect(rcItem);
  282. if((nItem < 10) && (m_bShowTextForFirstTenHotKeys))
  283. {
  284. CString cs;
  285. if(nItem == 9)
  286. cs.Format("%d", 0);
  287. else
  288. cs.Format("%d", nItem+1);
  289. CRect crClient;
  290. GetWindowRect(crClient);
  291. ScreenToClient(crClient);
  292. CRect crHotKey = rcItem;
  293. crHotKey.right = crHotKey.left + 11;
  294. crHotKey.left += 2;
  295. crHotKey.top += 2;
  296. HFONT hOldFont = (HFONT)pDC->SelectObject(m_SmallFont);
  297. pDC->DrawText(cs, crHotKey, DT_BOTTOM);
  298. pDC->MoveTo(CPoint(rcItem.left + 11, rcItem.top));
  299. pDC->LineTo(CPoint(rcItem.left + 11, rcItem.bottom));
  300. pDC->SelectObject(hOldFont);
  301. }
  302. if(pOldPen)
  303. pDC->SelectObject(pOldPen);
  304. if(OldColor > -1)
  305. pDC->SetTextColor(OldColor);
  306. if(nOldBKMode > -1)
  307. pDC->SetBkMode(nOldBKMode);
  308. *pResult = CDRF_SKIPDEFAULT; // We've painted everything.
  309. }
  310. }
  311. void CQListCtrl::RefreshVisibleRows()
  312. {
  313. int nTopIndex = GetTopIndex();
  314. int nLastIndex = nTopIndex + GetCountPerPage();
  315. RedrawItems(nTopIndex, nLastIndex);
  316. ::UpdateWindow(m_hWnd);
  317. }
  318. void CQListCtrl::OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
  319. {
  320. if(GetKeyState(VK_RETURN) & 0x800)
  321. GetParent()->SendMessage(NM_PROPERTIES, 0, 0);
  322. else
  323. CListCtrl::OnSysKeyDown(nChar, nRepCnt, nFlags);
  324. }
  325. BOOL CQListCtrl::OnEraseBkgnd(CDC* pDC)
  326. {
  327. // return TRUE;
  328. return CListCtrl::OnEraseBkgnd(pDC);
  329. }
  330. BOOL CQListCtrl::OnToolTipText( UINT id, NMHDR * pNMHDR, LRESULT * pResult )
  331. {
  332. // need to handle both ANSI and UNICODE versions of the message
  333. TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
  334. TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
  335. CString strTipText;
  336. UINT nID = pNMHDR->idFrom;
  337. if(nID == 0) // Notification in NT from automatically
  338. return FALSE; // created tooltip
  339. ::SendMessage(pNMHDR->hwndFrom, TTM_SETMAXTIPWIDTH, 0, 500);
  340. // Use Item's name as the tool tip. Change this for something different.
  341. // Like use its file size, etc.
  342. strTipText = GetToolTipText(nID-1);
  343. //Replace the tabs with 5 spaces, the tooltip didn't like the \t s
  344. strTipText.Replace("\t", " ");
  345. #ifndef _UNICODE
  346. if (pNMHDR->code == TTN_NEEDTEXTA)
  347. {
  348. if(m_pchTip != NULL)
  349. delete m_pchTip;
  350. m_pchTip = new TCHAR[strTipText.GetLength()+1];
  351. lstrcpyn(m_pchTip, strTipText, strTipText.GetLength());
  352. m_pchTip[strTipText.GetLength()] = 0;
  353. pTTTW->lpszText = (WCHAR*)m_pchTip;
  354. }
  355. else
  356. {
  357. if(m_pwchTip != NULL)
  358. delete m_pwchTip;
  359. m_pwchTip = new WCHAR[strTipText.GetLength()+1];
  360. _mbstowcsz(m_pwchTip, strTipText, strTipText.GetLength());
  361. m_pwchTip[strTipText.GetLength()] = 0; // end of text
  362. pTTTW->lpszText = (WCHAR*)m_pwchTip;
  363. }
  364. #else
  365. if(pNMHDR->code == TTN_NEEDTEXTA)
  366. {
  367. if(m_pchTip != NULL)
  368. delete m_pchTip;
  369. m_pchTip = new TCHAR[strTipText.GetLength()+1];
  370. _wcstombsz(m_pchTip, strTipText, strTipText.GetLength());
  371. m_pchTip[strTipText.GetLength()] = 0; // end of text
  372. pTTTA->lpszText = (LPTSTR)m_pchTip;
  373. }
  374. else
  375. {
  376. if(m_pwchTip != NULL)
  377. delete m_pwchTip;
  378. m_pwchTip = new WCHAR[strTipText.GetLength()+1];
  379. lstrcpyn(m_pwchTip, strTipText, strTipText.GetLength());
  380. m_pwchTip[strTipText.GetLength()] = 0;
  381. pTTTA->lpszText = (LPTSTR) m_pwchTip;
  382. }
  383. #endif
  384. *pResult = 0;
  385. return TRUE; // message was handled
  386. }
  387. int CQListCtrl::OnToolHitTest(CPoint point, TOOLINFO * pTI) const
  388. {
  389. CRect rect;
  390. GetClientRect(&rect);
  391. if(rect.PtInRect(point))
  392. {
  393. if(GetItemCount())
  394. {
  395. int nTopIndex = GetTopIndex();
  396. int nBottomIndex = nTopIndex + GetCountPerPage();
  397. if(nBottomIndex > GetItemCount()) nBottomIndex = GetItemCount();
  398. for(int nIndex = nTopIndex; nIndex <= nBottomIndex; nIndex++)
  399. {
  400. GetItemRect(nIndex, rect, LVIR_BOUNDS);
  401. if(rect.PtInRect(point))
  402. {
  403. pTI->hwnd = m_hWnd;
  404. pTI->uId = (UINT)(nIndex+1);
  405. pTI->lpszText = LPSTR_TEXTCALLBACK;
  406. pTI->rect = rect;
  407. return pTI->uId;
  408. }
  409. }
  410. }
  411. }
  412. return -1;
  413. }
  414. int CQListCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
  415. {
  416. if (CListCtrl::OnCreate(lpCreateStruct) == -1)
  417. return -1;
  418. EnableToolTips();
  419. return 0;
  420. }
  421. BOOL CQListCtrl::PreTranslateMessage(MSG* pMsg)
  422. {
  423. if(m_Accelerator)
  424. {
  425. m_CheckingAccelerator = true;
  426. if(TranslateAccelerator(m_hWnd, m_Accelerator, pMsg) != 0)
  427. {
  428. m_CheckingAccelerator = false;
  429. return TRUE;
  430. }
  431. m_CheckingAccelerator = false;
  432. }
  433. if(m_acFirstTen)
  434. {
  435. m_CheckingAccelerator = true;
  436. if(TranslateAccelerator(m_hWnd, m_acFirstTen, pMsg) != 0)
  437. {
  438. m_CheckingAccelerator = false;
  439. return TRUE;
  440. }
  441. m_CheckingAccelerator = false;
  442. }
  443. switch(pMsg->message)
  444. {
  445. case WM_KEYDOWN:
  446. if(pMsg->wParam == 'A')
  447. {
  448. if(GetKeyState(VK_CONTROL) & 0x8000)
  449. {
  450. int nCount = GetItemCount();
  451. for(int i = 0; i < nCount; i++)
  452. {
  453. SetSelection(i);
  454. }
  455. return TRUE;
  456. }
  457. }
  458. break;
  459. }
  460. return CListCtrl::PreTranslateMessage(pMsg);
  461. }
  462. CString CQListCtrl::GetToolTipText(int nItem)
  463. {
  464. CString cs;
  465. if((GetStyle() & LVS_OWNERDATA))
  466. {
  467. CWnd* pParent=GetParent();
  468. if(pParent && (pParent->GetSafeHwnd() != NULL))
  469. {
  470. CQListToolTipText info;
  471. memset(&info, 0, sizeof(info));
  472. info.hdr.code = NM_GETTOOLTIPTEXT;
  473. info.hdr.hwndFrom = GetSafeHwnd();
  474. info.hdr.idFrom = GetDlgCtrlID();
  475. info.lItem = nItem;
  476. pParent->SendMessage(WM_NOTIFY,(WPARAM)info.hdr.idFrom,(LPARAM)&info);
  477. cs = info.cText;
  478. }
  479. }
  480. return cs;
  481. }
  482. DWORD CQListCtrl::GetItemData(int nItem)
  483. {
  484. if((GetStyle() & LVS_OWNERDATA))
  485. {
  486. CWnd* pParent=GetParent();
  487. if(pParent && (pParent->GetSafeHwnd() != NULL))
  488. {
  489. LV_DISPINFO info;
  490. memset(&info, 0, sizeof(info));
  491. info.hdr.code = LVN_GETDISPINFO;
  492. info.hdr.hwndFrom = GetSafeHwnd();
  493. info.hdr.idFrom = GetDlgCtrlID();
  494. info.item.iItem = nItem;
  495. info.item.lParam = -1;
  496. info.item.mask = LVIF_PARAM;
  497. pParent->SendMessage(WM_NOTIFY,(WPARAM)info.hdr.idFrom,(LPARAM)&info);
  498. return info.item.lParam;
  499. }
  500. }
  501. return CListCtrl::GetItemData(nItem);
  502. }
  503. void CQListCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
  504. {
  505. CListCtrl::OnVScroll(nSBCode, nPos, pScrollBar);
  506. }
  507. void CQListCtrl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
  508. {
  509. CListCtrl::OnHScroll(nSBCode, nPos, pScrollBar);
  510. }
  511. void CQListCtrl::DestroyAndCreateAccelerator(BOOL bCreate)
  512. {
  513. if(m_Accelerator)
  514. {
  515. DestroyAcceleratorTable(m_Accelerator);
  516. m_Accelerator = NULL;
  517. }
  518. if(bCreate)
  519. m_Accelerator = CMainTable::LoadAcceleratorKeys();
  520. }
  521. void CQListCtrl::LoadFirstTenHotKeys(CMainTable &recset)
  522. {
  523. if(m_acFirstTen)
  524. {
  525. DestroyAcceleratorTable(m_acFirstTen);
  526. m_acFirstTen = NULL;
  527. }
  528. int nMax = min(10, recset.GetRecordCount());
  529. CArray<ACCEL, ACCEL> keys;
  530. recset.MoveFirst();
  531. BOOL bAddControl = CGetSetOptions::GetUseCtrlNumForFirstTenHotKeys();
  532. for(int i = 0; i < nMax; i++)
  533. {
  534. ACCEL me;
  535. me.cmd = (USHORT)recset.m_lID;
  536. me.fVirt = 0;
  537. if(bAddControl)
  538. {
  539. me.fVirt |= FCONTROL;
  540. }
  541. me.fVirt |= FVIRTKEY;
  542. if(i == 9)
  543. me.key = 48;
  544. else
  545. me.key = 49+i;
  546. keys.Add(me);
  547. recset.MoveNext();
  548. }
  549. if(keys.GetSize() > 0)
  550. m_acFirstTen = CreateAcceleratorTable(keys.GetData(), keys.GetSize());
  551. }
  552. BOOL CQListCtrl::OnCommand(WPARAM wParam, LPARAM lParam)
  553. {
  554. //return 1 if from accelerator
  555. if((HIWORD(wParam) == 1) && (m_CheckingAccelerator))
  556. {
  557. USHORT usPasteID = LOWORD(wParam);
  558. GetParent()->SendMessage(NM_SELECT_DB_ID, usPasteID, 0);
  559. return TRUE;
  560. }
  561. return CListCtrl::OnCommand(wParam, lParam);
  562. }