简单的自绘CListBox(三)类似CTreeCtrl Expand效果 clistbox自绘
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;
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. }
更多阅读
手机截屏怎么弄?最简单的方法教给大家 步步高家教机截屏工具
手机截屏怎么弄?最简单的方法教给大家——简介手机怎么截屏?各种手机方法大有不同,安卓4.0以上系统的有自带的截图功能,这些手机直接按住关机键几秒,即可出现截图选项; 有些是音量键和电源键同时摁,按住几秒即可出现截图选项;但是对于安卓2.
教你用最简单的方法刻录高音质车载CD 如何刻录高音质cd
教你用最简单的方法刻录高音质车载CD——简介你还在买正版车载CD么?你还在为不喜欢里面的某些歌曲而烦恼么?网上教程看不懂?让我来告诉你,其实windows 7 系统内置有刻录软件Media Player,不需要另外下载刻录软件(不是说那些软件不好,只是
三层交换机S3600 最简单的vlan划分和配置举例 三层交换机划分vlan
三层交换机(S3600)最简单的vlan划分和配置举例三层交换机(S3600)最简单的vlan划分和配置举例一:配置基于端口的VLAN创建vlan2并进入视图system-view[H3C]vlan2#指定VLAN2的描述字符串为ho
复数对六种基本运算的自洽性和超级完美公式1+expi*PI)=0 matlab exp 复数
在高等数学研究中,一切有关数的计算都可以归结为六种基本运算。这六种基本数的运算恰好构成三对互逆运算,而且存在三个彼此递进的关系层级,即加减—>乘除—>乘方与开方。复数恰好是对这六种运算闭合自洽的数系。这可能与阴阳(正负或虚实
一个简单的方法——防止电脑感染病毒图 防止手术感染的方法
这篇文章是我自己经验的总结,放在这里,也许可以帮助对电脑不熟悉的网友,减少甚至避免今后在网络上受到病毒袭击。如果文中有错误或者值得改进之处,欢迎各位提出——xyh一个简单的方法——防止电脑感染病毒我们常常遇到这样的问题,就是新