PlayerListCtrl.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:21k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /* 
  2.  * Copyright (C) 2003-2005 Gabest
  3.  * http://www.gabest.org
  4.  *
  5.  *  This Program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2, or (at your option)
  8.  *  any later version.
  9.  *   
  10.  *  This Program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13.  *  GNU General Public License for more details.
  14.  *   
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with GNU Make; see the file COPYING.  If not, write to
  17.  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  18.  *  http://www.gnu.org/copyleft/gpl.html
  19.  *
  20.  */
  21. // PlayerListCtrl.cpp : implementation file
  22. //
  23. #include "stdafx.h"
  24. #include "mplayerc.h"
  25. #include "PlayerListCtrl.h"
  26. #include ".playerlistctrl.h"
  27. // CInPlaceEdit
  28. CInPlaceEdit::CInPlaceEdit(int iItem, int iSubItem, CString sInitText)
  29. : m_sInitText( sInitText )
  30. {
  31. m_iItem = iItem;
  32. m_iSubItem = iSubItem;
  33. m_bESC = FALSE;
  34. }
  35. CInPlaceEdit::~CInPlaceEdit()
  36. {
  37. }
  38. BEGIN_MESSAGE_MAP(CInPlaceEdit, CEdit)
  39. //{{AFX_MSG_MAP(CInPlaceEdit)
  40. ON_WM_KILLFOCUS()
  41. ON_WM_NCDESTROY()
  42. ON_WM_CHAR()
  43. ON_WM_CREATE()
  44. //}}AFX_MSG_MAP
  45. END_MESSAGE_MAP()
  46. /////////////////////////////////////////////////////////////////////////////
  47. // CInPlaceEdit message handlers
  48. BOOL CInPlaceEdit::PreTranslateMessage(MSG* pMsg)
  49. {
  50. if(pMsg->message == WM_KEYDOWN)
  51. {
  52. if(pMsg->wParam == VK_RETURN
  53. || pMsg->wParam == VK_DELETE
  54. || pMsg->wParam == VK_ESCAPE
  55. || GetKeyState(VK_CONTROL))
  56. {
  57. ::TranslateMessage(pMsg);
  58. ::DispatchMessage(pMsg);
  59. return TRUE;      // DO NOT process further
  60. }
  61. }
  62. return CEdit::PreTranslateMessage(pMsg);
  63. }
  64. void CInPlaceEdit::OnKillFocus(CWnd* pNewWnd)
  65. {
  66. CEdit::OnKillFocus(pNewWnd);
  67. CString str;
  68. GetWindowText(str);
  69. LV_DISPINFO dispinfo;
  70. dispinfo.hdr.hwndFrom = GetParent()->m_hWnd;
  71. dispinfo.hdr.idFrom = GetDlgCtrlID();
  72. dispinfo.hdr.code = LVN_ENDLABELEDIT;
  73. dispinfo.item.mask = LVIF_TEXT;
  74. dispinfo.item.iItem = m_iItem;
  75. dispinfo.item.iSubItem = m_iSubItem;
  76. dispinfo.item.pszText = m_bESC ? NULL : LPTSTR((LPCTSTR)str);
  77. dispinfo.item.cchTextMax = str.GetLength();
  78. GetParent()->GetParent()->SendMessage(WM_NOTIFY, GetParent()->GetDlgCtrlID(), (LPARAM)&dispinfo);
  79. DestroyWindow();
  80. }
  81. void CInPlaceEdit::OnNcDestroy()
  82. {
  83. CEdit::OnNcDestroy();
  84. delete this;
  85. }
  86. void CInPlaceEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
  87. {
  88. if(nChar == VK_ESCAPE || nChar == VK_RETURN)
  89. {
  90. if(nChar == VK_ESCAPE) m_bESC = TRUE;
  91. GetParent()->SetFocus();
  92. return;
  93. }
  94. CEdit::OnChar(nChar, nRepCnt, nFlags);
  95. }
  96. int CInPlaceEdit::OnCreate(LPCREATESTRUCT lpCreateStruct)
  97. {
  98. if(CEdit::OnCreate(lpCreateStruct) == -1)
  99. return -1;
  100. // Set the proper font
  101. CFont* font = GetParent()->GetFont();
  102. SetFont(font);
  103. SetWindowText(m_sInitText);
  104. SetFocus();
  105. SetSel(0, -1);
  106. return 0;
  107. }
  108. // CInPlaceComboBox
  109. CInPlaceComboBox::CInPlaceComboBox(int iItem, int iSubItem, CList<CString>& lstItems, int nSel)
  110. {
  111. m_iItem = iItem;
  112. m_iSubItem = iSubItem;
  113. m_lstItems.AddTail(&lstItems);
  114. m_nSel = nSel;
  115. m_bESC = FALSE;
  116. }
  117. CInPlaceComboBox::~CInPlaceComboBox()
  118. {
  119. }
  120. BEGIN_MESSAGE_MAP(CInPlaceComboBox, CComboBox)
  121. //{{AFX_MSG_MAP(CInPlaceComboBox)
  122. ON_WM_CREATE()
  123. ON_WM_KILLFOCUS()
  124. ON_WM_CHAR()
  125. ON_WM_NCDESTROY()
  126. ON_CONTROL_REFLECT(CBN_CLOSEUP, OnCloseup)
  127. //}}AFX_MSG_MAP
  128. END_MESSAGE_MAP()
  129. /////////////////////////////////////////////////////////////////////////////
  130. // CInPlaceComboBox message handlers
  131. int CInPlaceComboBox::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  132. {
  133. if (CComboBox::OnCreate(lpCreateStruct) == -1)
  134. return -1;
  135. // Set the proper font
  136. CFont* font = GetParent()->GetFont();
  137. SetFont(font);
  138. for(POSITION pos = m_lstItems.GetHeadPosition(); pos != NULL;)
  139. AddString((LPCTSTR)(m_lstItems.GetNext(pos)));
  140. SetFocus();
  141. SetCurSel(m_nSel);
  142. return 0;
  143. }
  144. BOOL CInPlaceComboBox::PreTranslateMessage(MSG* pMsg) 
  145. {
  146. if(pMsg->message == WM_KEYDOWN)
  147. {
  148. if(pMsg->wParam == VK_RETURN 
  149. || pMsg->wParam == VK_ESCAPE)
  150. {
  151. ::TranslateMessage(pMsg);
  152. ::DispatchMessage(pMsg);
  153. return TRUE; // DO NOT process further
  154. }
  155. }
  156. return CComboBox::PreTranslateMessage(pMsg);
  157. }
  158. void CInPlaceComboBox::OnKillFocus(CWnd* pNewWnd) 
  159. {
  160. CComboBox::OnKillFocus(pNewWnd);
  161. CString str;
  162. GetWindowText(str);
  163. LV_DISPINFO dispinfo;
  164. dispinfo.hdr.hwndFrom = GetParent()->m_hWnd;
  165. dispinfo.hdr.idFrom = GetDlgCtrlID();
  166. dispinfo.hdr.code = LVN_ENDLABELEDIT;
  167. dispinfo.item.mask = LVIF_TEXT|LVIF_PARAM;
  168. dispinfo.item.iItem = m_iItem;
  169. dispinfo.item.iSubItem = m_iSubItem;
  170. dispinfo.item.pszText = m_bESC ? NULL : LPTSTR((LPCTSTR)str);
  171. dispinfo.item.cchTextMax = str.GetLength();
  172. dispinfo.item.lParam = GetCurSel();
  173. GetParent()->GetParent()->SendMessage(WM_NOTIFY, GetParent()->GetDlgCtrlID(), (LPARAM)&dispinfo);
  174. PostMessage(WM_CLOSE);
  175. }
  176. void CInPlaceComboBox::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
  177. {
  178. if(nChar == VK_ESCAPE || nChar == VK_RETURN)
  179. {
  180. if(nChar == VK_ESCAPE) m_bESC = TRUE;
  181. GetParent()->SetFocus();
  182. return;
  183. }
  184. CComboBox::OnChar(nChar, nRepCnt, nFlags);
  185. }
  186. void CInPlaceComboBox::OnNcDestroy() 
  187. {
  188. CComboBox::OnNcDestroy();
  189. delete this;
  190. }
  191. void CInPlaceComboBox::OnCloseup() 
  192. {
  193. GetParent()->SetFocus();
  194. }
  195. // CInPlaceListBox
  196. CInPlaceListBox::CInPlaceListBox(int iItem, int iSubItem, CList<CString>& lstItems, int nSel)
  197. {
  198. m_iItem = iItem;
  199. m_iSubItem = iSubItem;
  200. m_lstItems.AddTail(&lstItems);
  201. m_nSel = nSel;
  202. m_bESC = FALSE;
  203. }
  204. CInPlaceListBox::~CInPlaceListBox()
  205. {
  206. }
  207. BEGIN_MESSAGE_MAP(CInPlaceListBox, CListBox)
  208. //{{AFX_MSG_MAP(CInPlaceListBox)
  209. ON_WM_CREATE()
  210. ON_WM_KILLFOCUS()
  211. ON_WM_CHAR()
  212. ON_WM_NCDESTROY()
  213. //}}AFX_MSG_MAP
  214. END_MESSAGE_MAP()
  215. /////////////////////////////////////////////////////////////////////////////
  216. // CInPlaceListBox message handlers
  217. int CInPlaceListBox::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  218. {
  219. if(CListBox::OnCreate(lpCreateStruct) == -1)
  220. return -1;
  221. // Set the proper font
  222. CFont* font = GetParent()->GetFont();
  223. SetFont(font);
  224. for(POSITION pos = m_lstItems.GetHeadPosition(); pos != NULL;)
  225. {
  226. AddString( (LPCTSTR) (m_lstItems.GetNext( pos )) );
  227. }
  228. SetCurSel( m_nSel );
  229. SetFocus();
  230. return 0;
  231. }
  232. BOOL CInPlaceListBox::PreTranslateMessage(MSG* pMsg) 
  233. {
  234. if(pMsg->message == WM_KEYDOWN)
  235. {
  236. if(pMsg->wParam == VK_RETURN 
  237. || pMsg->wParam == VK_ESCAPE)
  238. {
  239. ::TranslateMessage(pMsg);
  240. ::DispatchMessage(pMsg);
  241. return TRUE; // DO NOT process further
  242. }
  243. }
  244. return CListBox::PreTranslateMessage(pMsg);
  245. }
  246. void CInPlaceListBox::OnKillFocus(CWnd* pNewWnd) 
  247. {
  248. CListBox::OnKillFocus(pNewWnd);
  249. CString str;
  250. GetWindowText(str);
  251. LV_DISPINFO dispinfo;
  252. dispinfo.hdr.hwndFrom = GetParent()->m_hWnd;
  253. dispinfo.hdr.idFrom = GetDlgCtrlID();
  254. dispinfo.hdr.code = LVN_ENDLABELEDIT;
  255. dispinfo.item.mask = LVIF_TEXT|LVIF_PARAM;
  256. dispinfo.item.iItem = m_iItem;
  257. dispinfo.item.iSubItem = m_iSubItem;
  258. dispinfo.item.pszText = m_bESC ? NULL : LPTSTR((LPCTSTR)str);
  259. dispinfo.item.cchTextMax = str.GetLength();
  260. dispinfo.item.lParam = GetCurSel();
  261. GetParent()->GetParent()->SendMessage(WM_NOTIFY, GetParent()->GetDlgCtrlID(), (LPARAM)&dispinfo);
  262. PostMessage(WM_CLOSE);
  263. }
  264. void CInPlaceListBox::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
  265. {
  266. if(nChar == VK_ESCAPE || nChar == VK_RETURN)
  267. {
  268. if(nChar == VK_ESCAPE) m_bESC = TRUE;
  269. GetParent()->SetFocus();
  270. return;
  271. }
  272. CListBox::OnChar(nChar, nRepCnt, nFlags);
  273. }
  274. void CInPlaceListBox::OnNcDestroy() 
  275. {
  276. CListBox::OnNcDestroy();
  277. delete this;
  278. }
  279. // CPlayerListCtrl
  280. IMPLEMENT_DYNAMIC(CPlayerListCtrl, CListCtrl)
  281. CPlayerListCtrl::CPlayerListCtrl(int tStartEditingDelay)
  282. : m_tStartEditingDelay(tStartEditingDelay)
  283. , m_nItemClicked(-1)
  284. {
  285. }
  286. CPlayerListCtrl::~CPlayerListCtrl()
  287. {
  288. }
  289. void CPlayerListCtrl::PreSubclassWindow()
  290. {
  291. EnableToolTips(TRUE);
  292. CListCtrl::PreSubclassWindow();
  293. }
  294. int CPlayerListCtrl::HitTestEx(CPoint& point, int* col) const
  295. {
  296. if(col) *col = 0;
  297. int row = HitTest(CPoint(0, point.y), NULL);
  298. if((GetWindowLong(m_hWnd, GWL_STYLE) & LVS_TYPEMASK) != LVS_REPORT)
  299. return row;
  300. int nColumnCount = ((CHeaderCtrl*)GetDlgItem(0))->GetItemCount();
  301. for(int top = GetTopIndex(), bottom = GetBottomIndex(); top <= bottom; top++)
  302. {
  303. CRect r;
  304. GetItemRect(top, &r, LVIR_BOUNDS);
  305. if(r.top <= point.y && point.y < r.bottom)
  306. {
  307. for(int colnum = 0; colnum < nColumnCount; colnum++)
  308. {
  309. int colwidth = GetColumnWidth(colnum);
  310. if(point.x >= r.left && point.x <= (r.left + colwidth))
  311. {
  312. if(col) *col = colnum;
  313. return top;
  314. }
  315. r.left += colwidth;
  316. }
  317. }
  318. }
  319. return -1;
  320. }
  321. int CPlayerListCtrl::GetBottomIndex() const
  322. {
  323. CRect r;
  324. GetClientRect(r);
  325. int nBottomIndex = GetTopIndex() + GetCountPerPage() - 1;
  326. if(nBottomIndex >= GetItemCount()) 
  327. {
  328. nBottomIndex = GetItemCount() - 1;
  329. }
  330. else if(nBottomIndex < GetItemCount())
  331. {
  332. CRect br;
  333. GetItemRect(nBottomIndex, br, LVIR_BOUNDS);
  334. if(br.bottom < r.bottom)
  335. nBottomIndex++;
  336. }
  337. return(nBottomIndex);
  338. }
  339. CImageList* CPlayerListCtrl::CreateDragImageEx(LPPOINT lpPoint)
  340. {
  341.   if(GetSelectedCount() <= 0)
  342. return NULL;
  343. CRect cSingleRect, cCompleteRect(0, 0, 0, 0);
  344. GetClientRect(cSingleRect);
  345. int nWidth = cSingleRect.Width();
  346. // Start and Stop index in view area
  347. int nIndex = GetTopIndex() - 1;
  348. int nBottomIndex = GetBottomIndex();
  349. // Determine the size of the drag image (limite for 
  350. // rows visibled and Client width)
  351. while((nIndex = GetNextItem(nIndex, LVNI_SELECTED)) != -1 && nIndex <= nBottomIndex)
  352. {
  353. GetItemRect(nIndex, cSingleRect, LVIR_BOUNDS);
  354. /*
  355. CRect r;
  356. GetItemRect(nIndex, r, LVIR_LABEL);
  357. cSingleRect.left = r.left;
  358. */
  359. if(cSingleRect.left < 0) cSingleRect.left = 0;
  360. if(cSingleRect.right > nWidth) cSingleRect.right = nWidth;
  361. cCompleteRect |= cSingleRect;
  362. }
  363. //
  364. // Create bitmap in memory DC
  365. //
  366. CClientDC cDc(this);
  367. CDC cMemDC;
  368. CBitmap cBitmap;
  369. if(!cMemDC.CreateCompatibleDC(&cDc))
  370. return NULL;
  371. if(!cBitmap.CreateCompatibleBitmap(&cDc, cCompleteRect.Width(), cCompleteRect.Height()))
  372. return NULL;
  373. CBitmap* pOldMemDCBitmap = cMemDC.SelectObject(&cBitmap);
  374. // Here green is used as mask color
  375. cMemDC.FillSolidRect(0, 0, cCompleteRect.Width(), cCompleteRect.Height(), RGB(0, 255, 0));
  376. // Paint each DragImage in the DC
  377. nIndex = GetTopIndex() - 1;
  378. while((nIndex = GetNextItem(nIndex, LVNI_SELECTED)) != -1 && nIndex <= nBottomIndex)
  379. {   
  380. CPoint pt;
  381. CImageList* pSingleImageList = CreateDragImage(nIndex, &pt);
  382. if(pSingleImageList)
  383. {
  384. GetItemRect(nIndex, cSingleRect, LVIR_BOUNDS);
  385. pSingleImageList->Draw(&cMemDC,
  386. 0, 
  387. CPoint(cSingleRect.left - cCompleteRect.left, cSingleRect.top - cCompleteRect.top), 
  388. ILD_MASK);
  389. pSingleImageList->DeleteImageList();
  390. delete pSingleImageList;
  391. }
  392. }
  393. cMemDC.SelectObject(pOldMemDCBitmap);
  394. //
  395. // Create the imagelist with the merged drag images
  396. //
  397. CImageList* pCompleteImageList = new CImageList;
  398. pCompleteImageList->Create(cCompleteRect.Width(), 
  399. cCompleteRect.Height(),
  400. ILC_COLOR | ILC_MASK, 0, 1);
  401. // Here green is used as mask color
  402. pCompleteImageList->Add(&cBitmap, RGB(0, 255, 0)); 
  403. //
  404. // as an optional service:
  405. // Find the offset of the current mouse cursor to the imagelist
  406. // this we can use in BeginDrag()
  407. //
  408. if(lpPoint)
  409. {
  410. lpPoint->x = cCompleteRect.left;
  411. lpPoint->y = cCompleteRect.top;
  412. }
  413. return(pCompleteImageList);
  414. }
  415. bool CPlayerListCtrl::PrepareInPlaceControl(int nRow, int nCol, CRect& rect)
  416. {
  417. if(!EnsureVisible(nRow, TRUE)) return(false);
  418. int nColumnCount = ((CHeaderCtrl*)GetDlgItem(0))->GetItemCount();
  419. if(nCol >= nColumnCount || GetColumnWidth(nCol) < 5) return(false);
  420. int offset = 0;
  421. for(int i = 0; i < nCol; i++) offset += GetColumnWidth(i);
  422. GetItemRect(nRow, &rect, LVIR_BOUNDS);
  423. CRect rcClient;
  424. GetClientRect(&rcClient);
  425. if(offset + rect.left < 0 || offset + rect.left > rcClient.right)
  426. {
  427. CSize size(offset + rect.left, 0);
  428. Scroll(size);
  429. rect.left -= size.cx;
  430. }
  431. rect.left += offset;
  432. rect.right = rect.left + GetColumnWidth(nCol);
  433. if(rect.right > rcClient.right) rect.right = rcClient.right;
  434. rect.DeflateRect(1, 0, 0, 1);
  435. if(nCol == 0)
  436. {
  437. CRect r;
  438. GetItemRect(nRow, r, LVIR_LABEL);
  439. rect.left = r.left-1;
  440. }
  441. return(true);
  442. }
  443. CEdit* CPlayerListCtrl::ShowInPlaceEdit(int nItem, int nCol)
  444. {
  445. CRect rect;
  446. if(!PrepareInPlaceControl(nItem, nCol, rect))
  447. return(NULL);
  448. DWORD dwStyle = /*WS_BORDER|*/WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL;
  449. LV_COLUMN lvcol;
  450. lvcol.mask = LVCF_FMT;
  451. GetColumn(nCol, &lvcol);
  452. dwStyle |= (lvcol.fmt&LVCFMT_JUSTIFYMASK) == LVCFMT_LEFT ? ES_LEFT
  453. : (lvcol.fmt&LVCFMT_JUSTIFYMASK) == LVCFMT_RIGHT ? ES_RIGHT
  454. : ES_CENTER;
  455. CEdit* pEdit = new CInPlaceEdit(nItem, nCol, GetItemText(nItem, nCol));
  456. pEdit->Create(dwStyle, rect, this, IDC_EDIT1);
  457. m_fInPlaceDirty = false;
  458. return pEdit;
  459. }
  460. CComboBox* CPlayerListCtrl::ShowInPlaceComboBox(int nItem, int nCol, CList<CString>& lstItems, int nSel)
  461. {
  462. CRect rect;
  463. if(!PrepareInPlaceControl(nItem, nCol, rect))
  464. return(NULL);
  465. DWORD dwStyle = /*WS_BORDER|*/WS_CHILD|WS_VISIBLE|WS_VSCROLL/*|WS_HSCROLL*/
  466. |CBS_DROPDOWNLIST|CBS_DISABLENOSCROLL/*|CBS_NOINTEGRALHEIGHT*/;
  467. CComboBox* pComboBox = new CInPlaceComboBox(nItem, nCol, lstItems, nSel);
  468. pComboBox->Create(dwStyle, rect, this, IDC_COMBO1);
  469. CorrectComboListWidth(*pComboBox, GetFont());
  470. int width = GetColumnWidth(nCol);
  471. if(pComboBox->GetDroppedWidth() < width)
  472. pComboBox->SetDroppedWidth(width);
  473. m_fInPlaceDirty = false;
  474. return pComboBox;
  475. }
  476. CListBox* CPlayerListCtrl::ShowInPlaceListBox(int nItem, int nCol, CList<CString>& lstItems, int nSel)
  477. {
  478. CRect rect;
  479. if(!PrepareInPlaceControl(nItem, nCol, rect))
  480. return(NULL);
  481. DWORD dwStyle = WS_BORDER|WS_CHILD|WS_VISIBLE|WS_VSCROLL/*|WS_HSCROLL*/|LBS_NOTIFY;
  482. CListBox* pListBox = new CInPlaceListBox(nItem, nCol, lstItems, nSel);
  483. pListBox->Create(dwStyle, rect, this, IDC_LIST1);
  484. CRect ir;
  485. GetItemRect(m_nItemClicked, &ir, LVIR_BOUNDS);
  486. pListBox->SetItemHeight(-1, ir.Height());
  487. CDC* pDC = pListBox->GetDC();
  488. CFont* pWndFont = GetFont();
  489. pDC->SelectObject(pWndFont);
  490. int width = GetColumnWidth(nCol);
  491. POSITION pos = lstItems.GetHeadPosition();
  492. while(pos)
  493. {
  494. int w = pDC->GetTextExtent(lstItems.GetNext(pos)).cx + 16;
  495. if(width < w) width = w;
  496. }
  497. ReleaseDC(pDC);
  498. CRect r;
  499. pListBox->GetWindowRect(r);
  500. ScreenToClient(r);
  501. r.top = ir.bottom;
  502. r.bottom = r.top + pListBox->GetItemHeight(0) * (pListBox->GetCount() + 1);
  503. r.right = r.left + width;
  504. pListBox->MoveWindow(r);
  505. m_fInPlaceDirty = false;
  506. return pListBox;
  507. }
  508. BEGIN_MESSAGE_MAP(CPlayerListCtrl, CListCtrl)
  509. ON_WM_VSCROLL()
  510. ON_WM_HSCROLL()
  511. ON_WM_MOUSEWHEEL()
  512. ON_WM_LBUTTONDOWN()
  513. ON_WM_TIMER()
  514. ON_WM_LBUTTONDBLCLK()
  515. ON_NOTIFY_REFLECT(LVN_MARQUEEBEGIN, OnLvnMarqueeBegin)
  516. ON_NOTIFY_REFLECT(LVN_INSERTITEM, OnLvnInsertitem)
  517. ON_NOTIFY_REFLECT(LVN_DELETEITEM, OnLvnDeleteitem)
  518. ON_EN_CHANGE(IDC_EDIT1, OnEnChangeEdit1)
  519. ON_CBN_DROPDOWN(IDC_COMBO1, OnCbnDropdownCombo1)
  520. ON_CBN_SELENDOK(IDC_COMBO1, OnCbnSelendokCombo1)
  521. ON_LBN_SELCHANGE(IDC_LIST1, OnLbnSelChangeList1)
  522. ON_NOTIFY_EX(HDN_ITEMCHANGINGA, 0, OnHdnItemchanging)
  523. ON_NOTIFY_EX(HDN_ITEMCHANGINGW, 0, OnHdnItemchanging)
  524. ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipNotify)
  525. ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipNotify)
  526. END_MESSAGE_MAP()
  527. // CPlayerListCtrl message handlers
  528. void CPlayerListCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
  529. {
  530. if(GetFocus() != this) SetFocus();
  531. CListCtrl::OnVScroll(nSBCode, nPos, pScrollBar);
  532. }
  533. void CPlayerListCtrl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
  534. {
  535. if(GetFocus() != this) SetFocus();
  536. CListCtrl::OnHScroll(nSBCode, nPos, pScrollBar);
  537. }
  538. BOOL CPlayerListCtrl::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
  539. {
  540. if(GetFocus() != this) SetFocus();
  541. return CListCtrl::OnMouseWheel(nFlags, zDelta, pt);
  542. }
  543. void CPlayerListCtrl::OnLButtonDown(UINT nFlags, CPoint point)
  544. {
  545. CListCtrl::OnLButtonDown(nFlags, point);
  546. if(GetFocus() != this) SetFocus();
  547. KillTimer(1);
  548. int m_nItemClickedNow, m_nSubItemClickedNow;
  549. if((m_nItemClickedNow = HitTestEx(point, &m_nSubItemClickedNow)) < 0)
  550. {
  551. m_nItemClicked = -1;
  552. }
  553. else if(m_nItemClicked == m_nItemClickedNow /*&& m_nSubItemClicked == m_nSubItemClickedNow*/)
  554. {
  555. m_nSubItemClicked = m_nSubItemClickedNow;
  556. LV_DISPINFO dispinfo;
  557. dispinfo.hdr.hwndFrom = m_hWnd;
  558. dispinfo.hdr.idFrom = GetDlgCtrlID();
  559. dispinfo.hdr.code = LVN_BEGINLABELEDIT;
  560. dispinfo.item.mask = 0;
  561. dispinfo.item.iItem = m_nItemClicked;
  562. dispinfo.item.iSubItem = m_nSubItemClicked;
  563. if(GetParent()->SendMessage(WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&dispinfo))
  564. {
  565. if(m_tStartEditingDelay > 0)
  566. {
  567. SetTimer(1, m_tStartEditingDelay, NULL);
  568. }
  569. else
  570. {
  571. dispinfo.hdr.code = LVN_DOLABELEDIT;
  572. GetParent()->SendMessage(WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&dispinfo);
  573. }
  574. }
  575. }
  576. else
  577. {
  578. m_nItemClicked = m_nItemClickedNow;
  579. m_nSubItemClicked = m_nSubItemClickedNow;
  580. SetItemState(m_nItemClicked, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED); 
  581. }
  582. }
  583. void CPlayerListCtrl::OnTimer(UINT nIDEvent)
  584. {
  585. if(nIDEvent == 1)
  586. {
  587. KillTimer(1);
  588. UINT flag = LVIS_FOCUSED;
  589. if((GetItemState(m_nItemClicked, flag) & flag) == flag && m_nSubItemClicked >= 0)
  590. {
  591. LV_DISPINFO dispinfo;
  592. dispinfo.hdr.hwndFrom = m_hWnd;
  593. dispinfo.hdr.idFrom = GetDlgCtrlID();
  594. dispinfo.hdr.code = LVN_DOLABELEDIT;
  595. dispinfo.item.mask = 0;
  596. dispinfo.item.iItem = m_nItemClicked;
  597. dispinfo.item.iSubItem = m_nSubItemClicked;
  598. GetParent()->SendMessage(WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&dispinfo);
  599. }
  600. }
  601. CListCtrl::OnTimer(nIDEvent);
  602. }
  603. void CPlayerListCtrl::OnLButtonDblClk(UINT nFlags, CPoint point)
  604. {
  605. KillTimer(1);
  606. CListCtrl::OnLButtonDblClk(nFlags, point);
  607. }
  608. void CPlayerListCtrl::OnLvnMarqueeBegin(NMHDR* pNMHDR, LRESULT* pResult)
  609. {
  610. LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
  611. *pResult = 1;
  612. }
  613. void CPlayerListCtrl::OnLvnInsertitem(NMHDR* pNMHDR, LRESULT* pResult)
  614. {
  615. LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
  616. m_nItemClicked = -1;
  617. *pResult = 0;
  618. }
  619. void CPlayerListCtrl::OnLvnDeleteitem(NMHDR* pNMHDR, LRESULT* pResult)
  620. {
  621. LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
  622. m_nItemClicked = -1;
  623. *pResult = 0;
  624. }
  625. void CPlayerListCtrl::OnEnChangeEdit1()
  626. {
  627. m_fInPlaceDirty = true;
  628. }
  629. void CPlayerListCtrl::OnCbnDropdownCombo1()
  630. {
  631. CComboBox* pCombo = (CComboBox*)GetDlgItem(IDC_COMBO1);
  632. CRect ir;
  633. GetItemRect(m_nItemClicked, &ir, LVIR_BOUNDS);
  634. CRect r;
  635. pCombo->GetWindowRect(r);
  636. ScreenToClient(r);
  637. r.bottom = r.top + ir.Height() + pCombo->GetItemHeight(0)*10;
  638. pCombo->MoveWindow(r);
  639. }
  640. void CPlayerListCtrl::OnCbnSelendokCombo1()
  641. {
  642. m_fInPlaceDirty = true;
  643. }
  644. void CPlayerListCtrl::OnLbnSelChangeList1()
  645. {
  646. m_fInPlaceDirty = true;
  647. SetFocus();
  648. }
  649. BOOL CPlayerListCtrl::OnHdnItemchanging(UINT id, NMHDR* pNMHDR, LRESULT* pResult)
  650. {
  651. LPNMHEADER phdr = reinterpret_cast<LPNMHEADER>(pNMHDR);
  652. // SetFocus();
  653. *pResult = 0;
  654. return FALSE;
  655. }
  656. int CPlayerListCtrl::OnToolHitTest(CPoint point, TOOLINFO* pTI) const
  657. {
  658. int col;
  659. int row = HitTestEx(point, &col);
  660. if(row == -1)
  661. return -1;
  662. CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
  663. int nColumnCount = pHeader->GetItemCount();
  664. CRect rect;
  665. GetItemRect(row, &rect, LVIR_BOUNDS);
  666. for(int colnum = 0; colnum < nColumnCount; colnum++)
  667. {
  668. int colwidth = GetColumnWidth(colnum);
  669. if(colnum == col)
  670. {
  671. rect.right = rect.left + colwidth; break;
  672. }
  673. rect.left += colwidth;
  674. }
  675. pTI->hwnd = m_hWnd;
  676. pTI->uId = (UINT)((row<<10)+(col&0x3ff)+1);
  677. pTI->lpszText = LPSTR_TEXTCALLBACK;
  678. pTI->rect = rect;
  679. return pTI->uId;
  680. }
  681. BOOL CPlayerListCtrl::OnToolTipNotify(UINT id, NMHDR* pNMHDR, LRESULT* pResult)
  682. {
  683. TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
  684. TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
  685. UINT nID = pNMHDR->idFrom;
  686. if(pNMHDR->code == TTN_NEEDTEXTA && (pTTTA->uFlags & TTF_IDISHWND)
  687. || pNMHDR->code == TTN_NEEDTEXTW && (pTTTW->uFlags & TTF_IDISHWND))
  688. {
  689. // idFrom is actually the HWND of the tool
  690. nID = ::GetDlgCtrlID((HWND)nID);
  691. }
  692. if(nID == 0)    // Notification in NT from automatically
  693. return FALSE;    // created tooltip
  694. if(pNMHDR->code == TTN_NEEDTEXTA) pTTTA->lParam = (LPARAM)m_hWnd;
  695. else if(pNMHDR->code == TTN_NEEDTEXTW) pTTTW->lParam = (LPARAM)m_hWnd;
  696. *pResult = 0;
  697. return GetParent()->SendMessage(WM_NOTIFY, id, (LPARAM)pNMHDR);
  698. }