简单的自绘CListBox(三)类似CTreeCtrl Expand效果 clistbox自绘

一个简单的扩展的CListBox类,点击某一个item的时候,自动展开该项来显示更多信息,类似CTreeCtrl控件的Expand样式风格。

view plaincopy to clipboardprint?

01.// H 文件

02.

03.#pragma once

04.

05.#include <vector>

06.using namespace std;

07.// CMultiLineListBox

08.

09.#define RGB_FOREGROUND RGB(0, 0, 0)

10.#define RGB_BACKGROUND RGB(255, 255, 255)

11.#define LISTBOX_BACKGROUND RGB(236, 255, 236)

12.

13.class CMultiLineListBox : public CListBox

14.{

15. DECLARE_DYNAMIC(CMultiLineListBox)

16.

17.public:

18. CMultiLineListBox();

19. virtual ~CMultiLineListBox();

20.

21.typedef struct _LISTBOX_INFO_

22.{

23.public:

24. typedef struct _SUBNODE_INFO_

25. {

26. public:

27. CString strText;

28. COLORREF fgColor;

29. COLORREF bgColor;

30.

31. _SUBNODE_INFO_()

32. {

33. clean();

34. }

35. ~_SUBNODE_INFO_()

36. {

37. clean();

38. }

39. protected:

40. inline void clean(void)

41. {

42. strText.Empty();

43. fgColor = RGB_FOREGROUND;

44. bgColor = RGB_BACKGROUND;

简单的自绘CListBox(三)(类似CTreeCtrl Expand效果) clistbox自绘
45. }

46. }SUBNODEINFO, *PSUBNODEINFO;

47.

48.public:

49. vector<SUBNODEINFO*> subArray;

50. CString strText;

51. COLORREF fgColor;

52. COLORREF bgColor;

53.

54. _LISTBOX_INFO_()

55. {

56. clean();

57. }

58. ~_LISTBOX_INFO_()

59. {

60. clean();

61. }

62.

63.protected:

64. inline void clean(void)

65. {

66. subArray.clear();

67. strText.Empty();

68. fgColor = RGB_FOREGROUND;

69. bgColor = RGB_BACKGROUND;

70. }

71.}LISTBOXINFO, * PLISTBOXINFO;

72.

73.protected:

74. static int m_nFocusIndex;

75. vector<LISTBOXINFO*> m_sArray;

76.

77.public:

78. int InsertString(int nIndex, LPCTSTR pszText, COLORREF fgColor = RGB_FOREGROUND, COLORREF bgColor = RGB_BACKGROUND);

79. int AddString(LPCTSTR pszText, COLORREF fgColor = RGB_FOREGROUND, COLORREF bgColor = RGB_BACKGROUND);

80. void AddSubString(int nIndex, LPCTSTR pszText, COLORREF fgColor = RGB_FOREGROUND, COLORREF bgColor = RGB_BACKGROUND);

81.

82.protected:

83. virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);

84. virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);

85. void UpdateItem(void);

86. void GetItemHeight(int nIndex);

87.

88.protected:

89. afx_msg BOOL OnEraseBkgnd(CDC* pDC);

90. afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);

91. afx_msg void OnLButtonDown(UINT nFlags, CPoint point);

92. afx_msg void OnMouseMove(UINT nFlags, CPoint point);

93. afx_msg LRESULT OnUpdateItem(WPARAM wParam, LPARAM lParam);

94.

95. DECLARE_MESSAGE_MAP()

96.};

// H 文件

#pragma once

#include <vector>

using namespace std;

// CMultiLineListBox

#define RGB_FOREGROUND RGB(0, 0, 0)

#define RGB_BACKGROUND RGB(255, 255, 255)

#define LISTBOX_BACKGROUND RGB(236, 255, 236)

class CMultiLineListBox : public CListBox

{

DECLARE_DYNAMIC(CMultiLineListBox)

public:

CMultiLineListBox();

virtual ~CMultiLineListBox();

typedef struct _LISTBOX_INFO_

{

public:

typedef struct _SUBNODE_INFO_

{

public:

CString strText;

COLORREF fgColor;

COLORREF bgColor;

_SUBNODE_INFO_()

{

clean();

}

~_SUBNODE_INFO_()

{

clean();

}

protected:

inline void clean(void)

{

strText.Empty();

fgColor = RGB_FOREGROUND;

bgColor = RGB_BACKGROUND;

}

}SUBNODEINFO, *PSUBNODEINFO;

public:

vector<SUBNODEINFO*> subArray;

CString strText;

COLORREF fgColor;

COLORREF bgColor;

_LISTBOX_INFO_()

{

clean();

}

~_LISTBOX_INFO_()

{

clean();

}

protected:

inline void clean(void)

{

subArray.clear();

strText.Empty();

fgColor = RGB_FOREGROUND;

bgColor = RGB_BACKGROUND;

}

}LISTBOXINFO, * PLISTBOXINFO;

protected:

static int m_nFocusIndex;

vector<LISTBOXINFO*> m_sArray;

public:

int InsertString(int nIndex, LPCTSTR pszText, COLORREF fgColor = RGB_FOREGROUND, COLORREF bgColor = RGB_BACKGROUND);

int AddString(LPCTSTR pszText, COLORREF fgColor = RGB_FOREGROUND, COLORREF bgColor = RGB_BACKGROUND);

void AddSubString(int nIndex, LPCTSTR pszText, COLORREF fgColor = RGB_FOREGROUND, COLORREF bgColor = RGB_BACKGROUND);

protected:

virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);

virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);

void UpdateItem(void);

void GetItemHeight(int nIndex);

protected:

afx_msg BOOL OnEraseBkgnd(CDC* pDC);

afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);

afx_msg void OnLButtonDown(UINT nFlags, CPoint point);

afx_msg void OnMouseMove(UINT nFlags, CPoint point);

afx_msg LRESULT OnUpdateItem(WPARAM wParam, LPARAM lParam);

DECLARE_MESSAGE_MAP()

};

view plaincopy to clipboardprint?

01.// CPP 文件

02.

03.// MultiLineListBox.cpp : implementation file

04.//

05.

06.#include "stdafx.h"

07.#include "MultiLineListBox.h"

08.

09.// CMultiLineListBox

10.#define MSG_UPDATEITEM WM_USER + 0x1001

11.#define ITEM_HEIGHT 20

12.

13.int CMultiLineListBox::m_nFocusIndex = -1;

14.

15.IMPLEMENT_DYNAMIC(CMultiLineListBox, CListBox)

16.

17.CMultiLineListBox::CMultiLineListBox()

18.{

19. m_sArray.clear();

20.}

21.

22.CMultiLineListBox::~CMultiLineListBox()

23.{

24. vector<LISTBOXINFO*>::const_iterator iter1 = m_sArray.begin();

25. for(; iter1 != m_sArray.end(); ++iter1)

26. {

27. LISTBOXINFO* pNode = *iter1;

28. vector<LISTBOXINFO::SUBNODEINFO*>::const_iterator iter2 = pNode->subArray.begin();

29. for(; iter2 != pNode->subArray.end(); ++iter2)

30. {

31. LISTBOXINFO::SUBNODEINFO* pSubNode = *iter2;

32. delete pSubNode;

33. pSubNode = NULL;

34. }

35. delete pNode;

36. pNode = NULL;

37. }

38. m_sArray.clear();

39.}

40.

41.BEGIN_MESSAGE_MAP(CMultiLineListBox, CListBox)

42. ON_WM_ERASEBKGND()

43. ON_WM_KEYDOWN()

44. ON_WM_LBUTTONDOWN()

45. ON_WM_MOUSEMOVE()

46. ON_MESSAGE(MSG_UPDATEITEM, &CMultiLineListBox::OnUpdateItem)

47.END_MESSAGE_MAP()

48.

49.int CMultiLineListBox::InsertString(int nIndex, LPCTSTR pszText, COLORREF fgColor, COLORREF bgColor)

50.{

51. LISTBOXINFO* pListBox = new LISTBOXINFO;

52. ASSERT(pListBox);

53.

54. ASSERT((nIndex >= 0) && (nIndex <= GetCount()));

55.

56. pListBox->strText = pszText;

57. pListBox->fgColor = fgColor;

58. pListBox->bgColor = bgColor;

59.

60. m_sArray.insert(m_sArray.begin() + nIndex, pListBox);

61.

62. return CListBox::InsertString(nIndex, pszText);

63.}

64.

65.int CMultiLineListBox::AddString(LPCTSTR pszText, COLORREF fgColor, COLORREF bgColor)

66.{

67. LISTBOXINFO* pListBox = new LISTBOXINFO;

68. ASSERT(pListBox);

69.

70. pListBox->strText = pszText;

71. pListBox->fgColor = fgColor;

72. pListBox->bgColor = bgColor;

73.

74. m_sArray.push_back(pListBox);

75.

76. return CListBox::AddString(pszText);

77.}

78.

79.void CMultiLineListBox::AddSubString(int nIndex, LPCTSTR pszText, COLORREF fgColor, COLORREF bgColor)

80.{

81. ASSERT((nIndex >=0) && (nIndex < GetCount()));

82.

83. ASSERT(!m_sArray.empty());

84.

85. LISTBOXINFO* pListBox = m_sArray.at(nIndex);

86. ASSERT(pListBox);

87.

88. LISTBOXINFO::SUBNODEINFO* pSubNode = new LISTBOXINFO::SUBNODEINFO;

89. ASSERT(pSubNode);

90.

91. pSubNode->strText = pszText;

92. pSubNode->fgColor = fgColor;

93. pSubNode->bgColor = bgColor;

94. pListBox->subArray.push_back(pSubNode);

95.}

96.

97.// CMultiLineListBox message handlers

98.

99.void CMultiLineListBox::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)

100.{

101. // TODO: Add your code to determine the size of specified item

102. ASSERT(lpMeasureItemStruct->CtlType == ODT_LISTBOX);

103.

104. lpMeasureItemStruct->itemHeight = ITEM_HEIGHT;

105.}

106.

107.void CMultiLineListBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)

108.{

109. // TODO: Add your code to draw the specified item

110. ASSERT(lpDrawItemStruct->CtlType == ODT_LISTBOX);

111.

112. int nIndex = lpDrawItemStruct->itemID;

113.

114. if((!m_sArray.empty()) && (nIndex < static_cast<int>(m_sArray.size())))

115. {

116. CDC dc;

117. dc.Attach(lpDrawItemStruct->hDC);

118.

119. // Save these value to restore them when done drawing.

120. COLORREF crOldTextColor = dc.GetTextColor();

121. COLORREF crOldBkColor = dc.GetBkColor();

122.

123. // If this item is selected, set the background color

124. // and the text color to appropriate values. Also, erase

125. // rect by filling it with the background color.

126. CRect rc(lpDrawItemStruct->rcItem);

127.

128. LISTBOXINFO* pListBox = m_sArray.at(nIndex);

129. ASSERT(pListBox);

130.

131. if ((lpDrawItemStruct->itemAction | ODA_SELECT) &&

132. (lpDrawItemStruct->itemState & ODS_SELECTED))

133. {

134. dc.SetTextColor(pListBox->bgColor);

135. dc.SetBkColor(pListBox->fgColor);

136. dc.FillSolidRect(&rc, pListBox->fgColor);

137.

138. // Draw item the text.

139. CRect rect(rc);

140. int nItemCount = 1;

141. nItemCount += static_cast<int>(pListBox->subArray.size());

142. int nItemHeight = rc.Height() / nItemCount;

143. rect.bottom = rect.top + nItemHeight;

144. dc.DrawText(pListBox->strText, pListBox->strText.GetLength(), CRect(rect.left + 5, rect.top, rect.right, rect.bottom), DT_SINGLELINE | DT_VCENTER);

145.

146. // Draw subitem the text.

147. CRect rcItem;

148. rcItem.SetRectEmpty();

149. rcItem.top = rect.bottom;

150. rcItem.left = rect.left;

151. rcItem.right = rect.right;

152. rcItem.bottom = rcItem.top + nItemHeight;

153.

154. vector<LISTBOXINFO::SUBNODEINFO*>::const_iterator iter = pListBox->subArray.begin();

155. for(; iter != pListBox->subArray.end(); ++iter)

156. {

157. LISTBOXINFO::SUBNODEINFO* pSubNode = *iter;

158. dc.SetTextColor(pSubNode->fgColor);

159. dc.SetBkColor(pSubNode->bgColor);

160. dc.FillSolidRect(&rcItem, pSubNode->bgColor);

161.

162. CRect rectItem(rcItem);

163. rectItem.left += 22;

164. dc.DrawText(pSubNode->strText, pSubNode->strText.GetLength(), &rectItem, DT_SINGLELINE | DT_VCENTER);

165.

166. rcItem.top = rcItem.bottom;

167. rcItem.bottom = rcItem.top + nItemHeight;

168. }

169.

170. dc.DrawFocusRect(rc); // Draw focus rect

171. }

172. else

173. {

174. dc.SetTextColor(pListBox->fgColor);

175. dc.SetBkColor(pListBox->bgColor);

176. dc.FillSolidRect(&rc, pListBox->bgColor);

177.

178. // Draw the text.

179. CRect rect(rc);

180. rect.left += 5;

181. dc.DrawText(pListBox->strText, pListBox->strText.GetLength(), &rect, DT_SINGLELINE | DT_VCENTER);

182. }

183.

184. // Reset the background color and the text color back to their

185. // original values.

186. dc.SetTextColor(crOldTextColor);

187. dc.SetBkColor(crOldBkColor);

188.

189. dc.Detach();

190. }

191.}

192.

193.BOOL CMultiLineListBox::OnEraseBkgnd(CDC* pDC)

194.{

195. // Set listbox background color

196. CRect rc;

197. GetClientRect(&rc);

198.

199. CDC memDC;

200. memDC.CreateCompatibleDC(pDC);

201. ASSERT(memDC.GetSafeHdc());

202.

203. CBitmap bmp;

204. bmp.CreateCompatibleBitmap(pDC, rc.Width(), rc.Height());

205. ASSERT(bmp.GetSafeHandle());

206.

207. CBitmap* pOldbmp = (CBitmap*)memDC.SelectObject(&bmp);

208.

209. memDC.FillSolidRect(rc, LISTBOX_BACKGROUND); // Set background color which you want

210. pDC->BitBlt(0, 0, rc.Width(), rc.Height(), &memDC, 0, 0, SRCCOPY);

211.

212. memDC.SelectObject(pOldbmp);

213. bmp.DeleteObject();

214. memDC.DeleteDC();

215.

216. return TRUE;

217.}

218.

219.void CMultiLineListBox::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)

220.{

221. // TODO: Add your message handler code here and/or call default

222. CListBox::OnKeyDown(nChar, nRepCnt, nFlags);

223.

224. UpdateItem();

225.}

226.

227.void CMultiLineListBox::OnLButtonDown(UINT nFlags, CPoint point)

228.{

229. // TODO: Add your message handler code here and/or call default

230. CListBox::OnLButtonDown(nFlags, point);

231.

232. UpdateItem();

233.}

234.

235.void CMultiLineListBox::OnMouseMove(UINT nFlags, CPoint point)

236.{

237. // TODO: Add your message handler code here and/or call default

238. CListBox::OnMouseMove(nFlags, point);

239.

240. UpdateItem();

241.}

242.

243.void CMultiLineListBox::UpdateItem()

244.{

245. // If per item height not equal, you must calculate area between the current focus item with last one,

246. // otherwise you must calculate area between the current focus item with previously focus item.

247. int nIndex = GetCurSel();

248. if((CB_ERR != nIndex) && (m_nFocusIndex != nIndex))

249. {

250. PostMessage(MSG_UPDATEITEM, (WPARAM)m_nFocusIndex, (LPARAM)nIndex);

251. m_nFocusIndex = nIndex; // Set current select focus index

252. }

253.}

254.

255.LRESULT CMultiLineListBox::OnUpdateItem(WPARAM wParam, LPARAM lParam)

256.{

257. int nPreIndex = static_cast<int>(wParam);

258. int nCurIndex = static_cast<int>(lParam);

259.

260. if(-1 != nPreIndex)

261. {

262. SetItemHeight(nPreIndex, ITEM_HEIGHT);

263. }

264.

265. if(-1 != nCurIndex)

266. {

267. int nItemCount = 1;

268. LISTBOXINFO* pListBox = m_sArray.at(nCurIndex);

269. ASSERT(pListBox);

270. nItemCount += static_cast<int>(pListBox->subArray.size());

271. SetItemHeight(nCurIndex, ITEM_HEIGHT * nItemCount);

272. }

273.

274. Invalidate(); // Update item

275. return 0;

276.}

// CPP 文件

// MultiLineListBox.cpp : implementation file

//

#include "stdafx.h"

#include "MultiLineListBox.h"

// CMultiLineListBox

#define MSG_UPDATEITEM WM_USER + 0x1001

#define ITEM_HEIGHT 20

int CMultiLineListBox::m_nFocusIndex = -1;

IMPLEMENT_DYNAMIC(CMultiLineListBox, CListBox)

CMultiLineListBox::CMultiLineListBox()

{

m_sArray.clear();

}

CMultiLineListBox::~CMultiLineListBox()

{

vector<LISTBOXINFO*>::const_iterator iter1 = m_sArray.begin();

for(; iter1 != m_sArray.end(); ++iter1)

{

LISTBOXINFO* pNode = *iter1;

vector<LISTBOXINFO::SUBNODEINFO*>::const_iterator iter2 = pNode->subArray.begin();

for(; iter2 != pNode->subArray.end(); ++iter2)

{

LISTBOXINFO::SUBNODEINFO* pSubNode = *iter2;

delete pSubNode;

pSubNode = NULL;

}

delete pNode;

pNode = NULL;

}

m_sArray.clear();

}

BEGIN_MESSAGE_MAP(CMultiLineListBox, CListBox)

ON_WM_ERASEBKGND()

ON_WM_KEYDOWN()

ON_WM_LBUTTONDOWN()

ON_WM_MOUSEMOVE()

ON_MESSAGE(MSG_UPDATEITEM, &CMultiLineListBox::OnUpdateItem)

END_MESSAGE_MAP()

int CMultiLineListBox::InsertString(int nIndex, LPCTSTR pszText, COLORREF fgColor, COLORREF bgColor)

{

LISTBOXINFO* pListBox = new LISTBOXINFO;

ASSERT(pListBox);

ASSERT((nIndex >= 0) && (nIndex <= GetCount()));

pListBox->strText = pszText;

pListBox->fgColor = fgColor;

pListBox->bgColor = bgColor;

m_sArray.insert(m_sArray.begin() + nIndex, pListBox);

return CListBox::InsertString(nIndex, pszText);

}

int CMultiLineListBox::AddString(LPCTSTR pszText, COLORREF fgColor, COLORREF bgColor)

{

LISTBOXINFO* pListBox = new LISTBOXINFO;

ASSERT(pListBox);

pListBox->strText = pszText;

pListBox->fgColor = fgColor;

pListBox->bgColor = bgColor;

m_sArray.push_back(pListBox);

return CListBox::AddString(pszText);

}

void CMultiLineListBox::AddSubString(int nIndex, LPCTSTR pszText, COLORREF fgColor, COLORREF bgColor)

{

ASSERT((nIndex >=0) && (nIndex < GetCount()));

ASSERT(!m_sArray.empty());

LISTBOXINFO* pListBox = m_sArray.at(nIndex);

ASSERT(pListBox);

LISTBOXINFO::SUBNODEINFO* pSubNode = new LISTBOXINFO::SUBNODEINFO;

ASSERT(pSubNode);

pSubNode->strText = pszText;

pSubNode->fgColor = fgColor;

pSubNode->bgColor = bgColor;

pListBox->subArray.push_back(pSubNode);

}

// CMultiLineListBox message handlers

void CMultiLineListBox::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)

{

// TODO: Add your code to determine the size of specified item

ASSERT(lpMeasureItemStruct->CtlType == ODT_LISTBOX);

lpMeasureItemStruct->itemHeight = ITEM_HEIGHT;

}

void CMultiLineListBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)

{

// TODO: Add your code to draw the specified item

ASSERT(lpDrawItemStruct->CtlType == ODT_LISTBOX);

int nIndex = lpDrawItemStruct->itemID;

if((!m_sArray.empty()) && (nIndex < static_cast<int>(m_sArray.size())))

{

CDC dc;

dc.Attach(lpDrawItemStruct->hDC);

// Save these value to restore them when done drawing.

COLORREF crOldTextColor = dc.GetTextColor();

COLORREF crOldBkColor = dc.GetBkColor();

// If this item is selected, set the background color

// and the text color to appropriate values. Also, erase

// rect by filling it with the background color.

CRect rc(lpDrawItemStruct->rcItem);

LISTBOXINFO* pListBox = m_sArray.at(nIndex);

ASSERT(pListBox);

if ((lpDrawItemStruct->itemAction | ODA_SELECT) &&

(lpDrawItemStruct->itemState & ODS_SELECTED))

{

dc.SetTextColor(pListBox->bgColor);

dc.SetBkColor(pListBox->fgColor);

dc.FillSolidRect(&rc, pListBox->fgColor);

// Draw item the text.

CRect rect(rc);

int nItemCount = 1;

nItemCount += static_cast<int>(pListBox->subArray.size());

int nItemHeight = rc.Height() / nItemCount;

rect.bottom = rect.top + nItemHeight;

dc.DrawText(pListBox->strText, pListBox->strText.GetLength(), CRect(rect.left + 5, rect.top, rect.right, rect.bottom), DT_SINGLELINE | DT_VCENTER);

// Draw subitem the text.

CRect rcItem;

rcItem.SetRectEmpty();

rcItem.top = rect.bottom;

rcItem.left = rect.left;

rcItem.right = rect.right;

rcItem.bottom = rcItem.top + nItemHeight;

vector<LISTBOXINFO::SUBNODEINFO*>::const_iterator iter = pListBox->subArray.begin();

for(; iter != pListBox->subArray.end(); ++iter)

{

LISTBOXINFO::SUBNODEINFO* pSubNode = *iter;

dc.SetTextColor(pSubNode->fgColor);

dc.SetBkColor(pSubNode->bgColor);

dc.FillSolidRect(&rcItem, pSubNode->bgColor);

CRect rectItem(rcItem);

rectItem.left += 22;

dc.DrawText(pSubNode->strText, pSubNode->strText.GetLength(), &rectItem, DT_SINGLELINE | DT_VCENTER);

rcItem.top = rcItem.bottom;

rcItem.bottom = rcItem.top + nItemHeight;

}

dc.DrawFocusRect(rc);// Draw focus rect

}

else

{

dc.SetTextColor(pListBox->fgColor);

dc.SetBkColor(pListBox->bgColor);

dc.FillSolidRect(&rc, pListBox->bgColor);

// Draw the text.

CRect rect(rc);

rect.left += 5;

dc.DrawText(pListBox->strText, pListBox->strText.GetLength(), &rect, DT_SINGLELINE | DT_VCENTER);

}

// Reset the background color and the text color back to their

// original values.

dc.SetTextColor(crOldTextColor);

dc.SetBkColor(crOldBkColor);

dc.Detach();

}

}

BOOL CMultiLineListBox::OnEraseBkgnd(CDC* pDC)

{

// Set listbox background color

CRect rc;

GetClientRect(&rc);

CDC memDC;

memDC.CreateCompatibleDC(pDC);

ASSERT(memDC.GetSafeHdc());

CBitmap bmp;

bmp.CreateCompatibleBitmap(pDC, rc.Width(), rc.Height());

ASSERT(bmp.GetSafeHandle());

CBitmap* pOldbmp = (CBitmap*)memDC.SelectObject(&bmp);

memDC.FillSolidRect(rc, LISTBOX_BACKGROUND); // Set background color which you want

pDC->BitBlt(0, 0, rc.Width(), rc.Height(), &memDC, 0, 0, SRCCOPY);

memDC.SelectObject(pOldbmp);

bmp.DeleteObject();

memDC.DeleteDC();

return TRUE;

}

void CMultiLineListBox::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)

{

// TODO: Add your message handler code here and/or call default

CListBox::OnKeyDown(nChar, nRepCnt, nFlags);

UpdateItem();

}

void CMultiLineListBox::OnLButtonDown(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

CListBox::OnLButtonDown(nFlags, point);

UpdateItem();

}

void CMultiLineListBox::OnMouseMove(UINT nFlags, CPoint point)

{

// TODO: Add your message handler code here and/or call default

CListBox::OnMouseMove(nFlags, point);

UpdateItem();

}

void CMultiLineListBox::UpdateItem()

{

// If per item height not equal, you must calculate area between the current focus item with last one,

// otherwise you must calculate area between the current focus item with previously focus item.

int nIndex = GetCurSel();

if((CB_ERR != nIndex) && (m_nFocusIndex != nIndex))

{

PostMessage(MSG_UPDATEITEM, (WPARAM)m_nFocusIndex, (LPARAM)nIndex);

m_nFocusIndex = nIndex; // Set current select focus index

}

}

LRESULT CMultiLineListBox::OnUpdateItem(WPARAM wParam, LPARAM lParam)

{

int nPreIndex = static_cast<int>(wParam);

int nCurIndex = static_cast<int>(lParam);

if(-1 != nPreIndex)

{

SetItemHeight(nPreIndex, ITEM_HEIGHT);

}

if(-1 != nCurIndex)

{

int nItemCount = 1;

LISTBOXINFO* pListBox = m_sArray.at(nCurIndex);

ASSERT(pListBox);

nItemCount += static_cast<int>(pListBox->subArray.size());

SetItemHeight(nCurIndex, ITEM_HEIGHT * nItemCount);

}

Invalidate(); // Update item

return 0;

}

view plaincopy to clipboardprint?

01.// 调用方法

02.// 成员变量,关联了CListBox窗口对象

03.CMultiLineListBox m_listBox;

04.// 资源编辑CListBox属性设置Owner Draw: Variable, Selection: Single, Has Strings: TRUE

05.

06.// 主对话框的OnInitDialog函数中设置

07.COLORREF clr[][2] =

08. {

09. {RGB(53, 0, 27), RGB(236, 255, 236)},

10. {RGB(66, 0, 33), RGB(233, 255, 233)},

11. {RGB(85, 0, 43), RGB(204, 255, 204)},

12. {RGB(106, 0, 53), RGB(191, 255, 191)},

13. {RGB(119, 0, 60), RGB(9, 255, 9)},

14. {RGB(136, 0, 68), RGB(0, 236, 0)},

15. {RGB(155, 0, 78), RGB(0, 225, 0)},

16. {RGB(168, 0, 84), RGB(0, 204, 0)},

17. {RGB(170, 0, 85), RGB(0, 185, 0)},

18. {RGB(187, 0, 94), RGB(0, 170, 0)},

19. {RGB(206, 0, 103), RGB(0, 151, 0)},

20. {RGB(211, 0, 111), RGB(0, 136, 0)},

21. {RGB(236, 0, 118), RGB(0, 117, 0)},

22. {RGB(255, 108, 182), RGB(0, 98, 0)},

23. {RGB(255, 121, 188), RGB(0, 89, 0)},

24. {RGB(255, 138, 197), RGB(0, 70, 0)},

25. {RGB(255, 157, 206), RGB(0, 53, 0)},

26. {RGB(255, 170, 212), RGB(0, 36, 0)},

27. {RGB(255, 193, 224), RGB(0, 21, 0)}

28. };

29.

30. CString strText(_T(""));

31. int nIndex = -1;

32. for(int i=0; i<sizeof(clr)/sizeof(clr[0]); i++)

33. {

34. strText.Format(_T("%02d - Hello, World!"), i+1);

35.

36. nIndex = m_listBox.AddString(strText, clr[i][0], clr[i][1]);

37. if(i % 2)

38. {

39. for(int j=0; j<3; j++)

40. {

41. strText.Format(_T("%02d.%02d - Hello, World!"), i+1, j+1);

42. m_listBox.AddSubString(nIndex, strText, clr[i][1], clr[i][0]);

43. }

44. }

45. else

46. {

47. for(int j=0; j<2; j++)

48. {

49. strText.Format(_T("%02d.%02d - Hello, World!"), i+1, j+1);

50. m_listBox.AddSubString(nIndex, strText, clr[i][1], clr[i][0]);

51. }

52. }

53. }

  

爱华网本文地址 » http://www.aihuau.com/a/25101011/56662.html

更多阅读

手机截屏怎么弄?最简单的方法教给大家 步步高家教机截屏工具

手机截屏怎么弄?最简单的方法教给大家——简介手机怎么截屏?各种手机方法大有不同,安卓4.0以上系统的有自带的截图功能,这些手机直接按住关机键几秒,即可出现截图选项; 有些是音量键和电源键同时摁,按住几秒即可出现截图选项;但是对于安卓2.

教你用最简单的方法刻录高音质车载CD 如何刻录高音质cd

教你用最简单的方法刻录高音质车载CD——简介你还在买正版车载CD么?你还在为不喜欢里面的某些歌曲而烦恼么?网上教程看不懂?让我来告诉你,其实windows 7 系统内置有刻录软件Media Player,不需要另外下载刻录软件(不是说那些软件不好,只是

一个简单的方法——防止电脑感染病毒图 防止手术感染的方法

这篇文章是我自己经验的总结,放在这里,也许可以帮助对电脑不熟悉的网友,减少甚至避免今后在网络上受到病毒袭击。如果文中有错误或者值得改进之处,欢迎各位提出——xyh一个简单的方法——防止电脑感染病毒我们常常遇到这样的问题,就是新

声明:《简单的自绘CListBox(三)类似CTreeCtrl Expand效果 clistbox自绘》为网友伤已成曲分享!如侵犯到您的合法权益请联系我们删除