ListCtrlBase.cpp
上传用户:lds876
上传日期:2013-05-25
资源大小:567k
文件大小:9k
源码类别:

P2P编程

开发平台:

Visual C++

  1. // ListCtrlBase.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "testbt.h"
  5. #include "ListCtrlBase.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. /////////////////////////////////////////////////////////////////////////////
  12. // CListCtrlBase
  13. CListCtrlBase::CListCtrlBase()
  14. {
  15. m_bFullRowSel=FALSE;
  16. m_bClientWidthSel=TRUE;
  17. m_cxClient=0;
  18. m_cxStateImageOffset=0;
  19. m_clrText=::GetSysColor(COLOR_WINDOWTEXT);
  20. m_clrTextBk=::GetSysColor(COLOR_WINDOW);
  21. m_clrBkgnd=::GetSysColor(COLOR_WINDOW);
  22. m_nTabFlag = DT_EXPANDTABS;
  23. }
  24. CListCtrlBase::~CListCtrlBase()
  25. {
  26. }
  27. BEGIN_MESSAGE_MAP(CListCtrlBase, CListCtrl)
  28. //{{AFX_MSG_MAP(CListCtrlBase)
  29. // NOTE - the ClassWizard will add and remove mapping macros here.
  30. //}}AFX_MSG_MAP
  31. ON_WM_SIZE()
  32. ON_WM_PAINT()
  33. ON_WM_SETFOCUS()
  34. ON_WM_KILLFOCUS()
  35. ON_WM_MEASUREITEM_REFLECT( )
  36. ON_MESSAGE(LVM_SETIMAGELIST, OnSetImageList)
  37. ON_MESSAGE(LVM_SETTEXTCOLOR, OnSetTextColor)
  38. ON_MESSAGE(LVM_SETTEXTBKCOLOR, OnSetTextBkColor)
  39. ON_MESSAGE(LVM_SETBKCOLOR, OnSetBkColor)
  40. END_MESSAGE_MAP()
  41. /////////////////////////////////////////////////////////////////////////////
  42. // CListCtrlBase message handlers
  43. void CListCtrlBase::MeasureItem ( LPMEASUREITEMSTRUCT lpMeasureItemStruct )
  44. {
  45. lpMeasureItemStruct->itemHeight = 18;
  46. }
  47. // offsets for first and other columns
  48. #define OFFSET_FIRST 2
  49. #define OFFSET_OTHER 6
  50. void CListCtrlBase::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
  51. {
  52. CDC* pDC=CDC::FromHandle(lpDrawItemStruct->hDC);
  53. CRect rcItem(lpDrawItemStruct->rcItem);
  54. UINT uiFlags=ILD_TRANSPARENT;
  55. CImageList* pImageList;
  56. int nItem=lpDrawItemStruct->itemID;
  57. BOOL bFocus=(GetFocus()==this);
  58. COLORREF clrTextSave, clrBkSave;
  59. COLORREF clrImage=m_clrBkgnd;
  60. static _TCHAR szBuff[MAX_PATH];
  61. LPCTSTR pszText;
  62. // get item data
  63. LV_ITEM lvi;
  64. lvi.mask=LVIF_TEXT | LVIF_IMAGE | LVIF_STATE;
  65. lvi.iItem=nItem;
  66. lvi.iSubItem=0;
  67. lvi.pszText=szBuff;
  68. lvi.cchTextMax=sizeof(szBuff);
  69. lvi.stateMask=0xFFFF; // get all state flags
  70. GetItem(&lvi);
  71. BOOL bSelected=(bFocus || (GetStyle() & LVS_SHOWSELALWAYS)) && lvi.state & LVIS_SELECTED;
  72. bSelected=bSelected || (lvi.state & LVIS_DROPHILITED);
  73. // set colors if item is selected
  74. CRect rcAllLabels;
  75. GetItemRect(nItem,rcAllLabels,LVIR_BOUNDS);
  76. CRect rcLabel;
  77. GetItemRect(nItem,rcLabel,LVIR_LABEL);
  78. rcAllLabels.left=rcLabel.left;
  79. // if(m_bClientWidthSel && rcAllLabels.right<m_cxClient)
  80. // rcAllLabels.right=m_cxClient;
  81. if(bSelected)
  82. {
  83. clrTextSave=pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
  84. clrBkSave=pDC->SetBkColor(::GetSysColor(COLOR_HIGHLIGHT));
  85. CBrush brush(::GetSysColor(COLOR_HIGHLIGHT));
  86. pDC->FillRect(rcAllLabels,&brush);
  87. }
  88. else
  89. {
  90. clrTextSave=pDC->SetTextColor(m_clrText);
  91. clrBkSave=pDC->SetBkColor(m_clrTextBk);
  92. CBrush brush(m_clrTextBk);
  93. pDC->FillRect(rcAllLabels,&brush);
  94. }
  95. // set color and mask for the icon
  96. if(lvi.state & LVIS_CUT)
  97. {
  98. clrImage=m_clrBkgnd;
  99. uiFlags|=ILD_BLEND50;
  100. }
  101. else if(bSelected)
  102. {
  103. clrImage=::GetSysColor(COLOR_HIGHLIGHT);
  104. uiFlags|=ILD_BLEND50;
  105. }
  106. // draw state icon
  107. UINT nStateImageMask=lvi.state & LVIS_STATEIMAGEMASK;
  108. if(nStateImageMask)
  109. {
  110. int nImage=(nStateImageMask>>12)-1;
  111. pImageList=GetImageList(LVSIL_STATE);
  112. if(pImageList)
  113. pImageList->Draw(pDC,nImage,CPoint(rcItem.left,rcItem.top),ILD_TRANSPARENT);
  114. }
  115. // draw normal and overlay icon
  116. CRect rcIcon;
  117. GetItemRect(nItem,rcIcon,LVIR_ICON);
  118. pImageList=GetImageList(LVSIL_SMALL);
  119. if(pImageList)
  120. {
  121. UINT nOvlImageMask=lvi.state & LVIS_OVERLAYMASK;
  122. if(rcItem.left<rcItem.right-1)
  123. ImageList_DrawEx(pImageList->m_hImageList,lvi.iImage,pDC->m_hDC,rcIcon.left,rcIcon.top,16,16,m_clrBkgnd,clrImage,uiFlags | nOvlImageMask);
  124. }
  125. // draw item label
  126. GetItemRect(nItem,rcItem,LVIR_LABEL);
  127. rcItem.right-=m_cxStateImageOffset;
  128. pszText=MakeShortString(pDC,szBuff,rcItem.right-rcItem.left,2*OFFSET_FIRST);
  129. rcLabel=rcItem;
  130. rcLabel.left+=OFFSET_FIRST;
  131. rcLabel.right-=OFFSET_FIRST;
  132. pDC->DrawText(pszText,-1,rcLabel, m_nTabFlag | DT_LEFT | DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER);
  133. // draw labels for extra columns
  134. LV_COLUMN lvc;
  135. lvc.mask=LVCF_FMT | LVCF_WIDTH;
  136. for(int nColumn=1; GetColumn(nColumn,&lvc); nColumn++)
  137. {
  138. rcItem.left=rcItem.right;
  139. rcItem.right+=lvc.cx;
  140. int nRetLen=GetItemText(nItem,nColumn,szBuff,sizeof(szBuff));
  141. if(nRetLen==0) continue;
  142. pszText=MakeShortString(pDC,szBuff,rcItem.right-rcItem.left,2*OFFSET_OTHER);
  143. UINT nJustify=DT_LEFT;
  144. if(pszText==szBuff)
  145. {
  146. switch(lvc.fmt & LVCFMT_JUSTIFYMASK)
  147. {
  148. case LVCFMT_RIGHT:
  149. nJustify=DT_RIGHT;
  150. break;
  151. case LVCFMT_CENTER:
  152. nJustify=DT_CENTER;
  153. break;
  154. default:
  155. break;
  156. }
  157. }
  158. rcLabel=rcItem;
  159. rcLabel.left+=OFFSET_OTHER;
  160. rcLabel.right-=OFFSET_OTHER;
  161. pDC->DrawText(pszText,-1,rcLabel,nJustify | DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER);
  162. }
  163. // draw focus rectangle if item has focus
  164. if(lvi.state & LVIS_FOCUSED && bFocus)
  165. pDC->DrawFocusRect(rcAllLabels);
  166. // set original colors
  167. pDC->SetTextColor(clrTextSave);
  168. pDC->SetBkColor(clrBkSave);
  169. }
  170. LPCTSTR CListCtrlBase::MakeShortString(CDC* pDC, LPCTSTR lpszLong, int nColumnLen, int nOffset)
  171. {
  172. static const _TCHAR szThreeDots[]=_T("...");
  173. int nStringLen=lstrlen(lpszLong);
  174. CSize ext;
  175. if (m_nTabFlag == DT_EXPANDTABS)
  176. ext = pDC->GetTabbedTextExtent(lpszLong,nStringLen, 0, NULL);
  177. else
  178. ext = pDC->GetTextExtent(lpszLong,nStringLen);
  179. if(nStringLen==0 || ext.cx+nOffset<=nColumnLen)
  180. return(lpszLong);
  181. static _TCHAR szShort[MAX_PATH];
  182. lstrcpy(szShort,lpszLong);
  183. int nAddLen=pDC->GetTextExtent(szThreeDots,sizeof(szThreeDots)).cx;
  184. for(int i=nStringLen-1; i>0; i--)
  185. {
  186. szShort[i]=0;
  187. if (m_nTabFlag == DT_EXPANDTABS)
  188. ext = pDC->GetTabbedTextExtent(szShort,i, 0, NULL);
  189. else
  190. ext = pDC->GetTextExtent(szShort,i);
  191. if(ext.cx+nOffset+nAddLen<=nColumnLen)
  192. break;
  193. }
  194. lstrcat(szShort,szThreeDots);
  195. return(szShort);
  196. }
  197. void CListCtrlBase::RepaintSelectedItems()
  198. {
  199. CRect rcItem, rcLabel;
  200. // invalidate focused item so it can repaint properly
  201. int nItem=GetNextItem(-1,LVNI_FOCUSED);
  202. if(nItem!=-1)
  203. {
  204. GetItemRect(nItem,rcItem,LVIR_BOUNDS);
  205. GetItemRect(nItem,rcLabel,LVIR_LABEL);
  206. rcItem.left=rcLabel.left;
  207. InvalidateRect(rcItem,FALSE);
  208. }
  209. // if selected items should not be preserved, invalidate them
  210. if(!(GetStyle() & LVS_SHOWSELALWAYS))
  211. {
  212. for(nItem=GetNextItem(-1,LVNI_SELECTED);
  213. nItem!=-1; nItem=GetNextItem(nItem,LVNI_SELECTED))
  214. {
  215. GetItemRect(nItem,rcItem,LVIR_BOUNDS);
  216. GetItemRect(nItem,rcLabel,LVIR_LABEL);
  217. rcItem.left=rcLabel.left;
  218. InvalidateRect(rcItem,FALSE);
  219. }
  220. }
  221. // update changes 
  222. UpdateWindow();
  223. }
  224. LRESULT CListCtrlBase::OnSetImageList(WPARAM wParam, LPARAM lParam)
  225. {
  226. if((int)wParam==LVSIL_STATE)
  227. {
  228. int cx, cy;
  229. if(::ImageList_GetIconSize((HIMAGELIST)lParam,&cx,&cy))
  230. m_cxStateImageOffset=cx;
  231. else
  232. m_cxStateImageOffset=0;
  233. }
  234. return(Default());
  235. }
  236. LRESULT CListCtrlBase::OnSetTextColor(WPARAM /*wParam*/, LPARAM lParam)
  237. {
  238. m_clrText=(COLORREF)lParam;
  239. return(Default());
  240. }
  241. LRESULT CListCtrlBase::OnSetTextBkColor(WPARAM /*wParam*/, LPARAM lParam)
  242. {
  243. m_clrTextBk=(COLORREF)lParam;
  244. return(Default());
  245. }
  246. LRESULT CListCtrlBase::OnSetBkColor(WPARAM /*wParam*/, LPARAM lParam)
  247. {
  248. m_clrBkgnd=(COLORREF)lParam;
  249. return(Default());
  250. }
  251. void CListCtrlBase::OnSize(UINT nType, int cx, int cy) 
  252. {
  253. m_cxClient=cx;
  254. CListCtrl::OnSize(nType, cx, cy);
  255. }
  256. void CListCtrlBase::OnPaint() 
  257. {
  258. // in full row select mode, we need to extend the clipping region
  259. // so we can paint a selection all the way to the right
  260. if(m_bClientWidthSel && (GetStyle() & LVS_TYPEMASK)==LVS_REPORT && GetFullRowSel())
  261. {
  262. CRect rcAllLabels;
  263. GetItemRect(0,rcAllLabels,LVIR_BOUNDS);
  264. if(rcAllLabels.right<m_cxClient)
  265. {
  266. // need to call BeginPaint (in CPaintDC c-tor)
  267. // to get correct clipping rect
  268. CPaintDC dc(this);
  269. CRect rcClip;
  270. dc.GetClipBox(rcClip);
  271. rcClip.left=min(rcAllLabels.right-1,rcClip.left);
  272. rcClip.right=m_cxClient;
  273. InvalidateRect(rcClip,FALSE);
  274. // EndPaint will be called in CPaintDC d-tor
  275. }
  276. }
  277. CListCtrl::OnPaint();
  278. }
  279. void CListCtrlBase::OnSetFocus(CWnd* pOldWnd) 
  280. {
  281. CListCtrl::OnSetFocus(pOldWnd);
  282. // check if we are getting focus from label edit box
  283. if(pOldWnd!=NULL && pOldWnd->GetParent()==this)
  284. return;
  285. // repaint items that should change appearance
  286. if(m_bFullRowSel && (GetStyle() & LVS_TYPEMASK)==LVS_REPORT)
  287. RepaintSelectedItems();
  288. }
  289. void CListCtrlBase::OnKillFocus(CWnd* pNewWnd) 
  290. {
  291. CListCtrl::OnKillFocus(pNewWnd);
  292. // check if we are losing focus to label edit box
  293. if(pNewWnd!=NULL && pNewWnd->GetParent()==this)
  294. return;
  295. // repaint items that should change appearance
  296. if(m_bFullRowSel && (GetStyle() & LVS_TYPEMASK)==LVS_REPORT)
  297. RepaintSelectedItems();
  298. }
  299. BOOL CListCtrlBase::GetFullRowSel()
  300. {
  301. return(m_bFullRowSel);
  302. }