MFC 自绘CListBox

实现功能:

  每个一个ListItem都有两个图标,点击“X”图标可以删除该项。

  鼠标经过某一个项时,该项更换背景色。

代码:<仅作参考,有什么不好的地方,望大神指教!>

  1 // OwnerDrawListBox.cpp : implementation file
2 //
3
4 #include "stdafx.h"
5 #include "OwnerDrawListBox.h"
6 #include "resource.h"
7
8 #ifdef _DEBUG
9 #define new DEBUG_NEW
10 #undef THIS_FILE
11 static char THIS_FILE[] = __FILE__;
12 #endif
13
14 /////////////////////////////////////////////////////////////////////////////
15 // COwnerDrawListBox
16
17 COwnerDrawListBox::COwnerDrawListBox()
18 {
19 isDeleted = FALSE;
20 }
21
22 COwnerDrawListBox::~COwnerDrawListBox()
23 {
24 Destroy();
25 }
26
27
28 BEGIN_MESSAGE_MAP(COwnerDrawListBox, CListBox)
29 //{{AFX_MSG_MAP(COwnerDrawListBox)
30 ON_WM_DROPFILES()
31 //}}AFX_MSG_MAP
32 ON_WM_LBUTTONDOWN()
33 ON_WM_LBUTTONUP()
34 // ON_WM_CLOSE()
35 ON_WM_DESTROY()
36 ON_WM_MOUSEMOVE()
37 END_MESSAGE_MAP()
38
39 /////////////////////////////////////////////////////////////////////////////
40 // COwnerDrawListBox message handlers
41
42 // Delete the Pointer which holds the List Box Data Items
43 void COwnerDrawListBox::Destroy()
44 {
45
46 }
47
48 // This is where is handle the Drag and Drop Event
49 void COwnerDrawListBox::OnDropFiles(HDROP hDropInfo)
50 {
51 LPWSTR szFilePath = new TCHAR[MAX_PATH];
52 char* strFileName = new char[MAX_PATH],
53 *strDrive = new char[MAX_PATH],
54 *strDir = new char[MAX_PATH],
55 *strExt = new char[MAX_PATH];
56
57 ::DragQueryFile (hDropInfo, 0, szFilePath, sizeof ((LPWSTR)szFilePath));
58
59 HICON h = ::ExtractIcon(NULL,szFilePath,0);
60
61 // This function splits the whole path into Drive, Dir, File Name and Extension
62 ::_splitpath((char *)szFilePath, strDrive, strDir, strFileName, strExt);
63
64 if (h)
65 {
66 // After getting the the Icon handle and the Icon file name,
67 // Add them to the list box
68 Add((CString)strFileName,h);
69 }
70
71 SetCurSel(this->GetCount()-1);
72
73 ::DragFinish(hDropInfo);
74 }
75
76 void COwnerDrawListBox::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
77 {
78 // Changes the Width and the Height of item in the list box
79 lpMeasureItemStruct->itemHeight = 36;
80 lpMeasureItemStruct->itemWidth = 498;
81 isHightLight = FALSE;
82 }
83
84 void COwnerDrawListBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
85 {
86 CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
87 CPen pen;
88 CDC MemDC;
89 MemDC.CreateCompatibleDC(pDC);
90 CBrush brush;
91 pen.CreatePen(PS_SOLID, 1, RGB(230,230,230));
92 CRect *rectIcon, *rectText, *rectDel;
93 //字体
94 CFont hFont;
95 hFont.CreateFont(
96 17, // nHeight
97 0, // nWidth
98 0, // nEscapement
99 0, // nOrientation
100 FW_NORMAL, // nWeight
101 FALSE, // bItalic
102 FALSE, // bUnderline//FALSE
103 0, // cStrikeOut
104 ANSI_CHARSET, // nCharSet
105 OUT_DEFAULT_PRECIS, // nOutPrecision
106 CLIP_DEFAULT_PRECIS, // nClipPrecision
107 CLEARTYPE_QUALITY, // nQuality
108 DEFAULT_PITCH | FF_MODERN, // nPitchAndFamily
109 L"Arial"); // lpszFacename//Arial
110 CFont* hOldFont = pDC-> SelectObject(&hFont);
111
112 COLORREF crOldTextColor = pDC->GetTextColor();
113 COLORREF crOldBkColor = RGB(255,255,255);
114 COLORREF crOldBkColorEven = RGB(240,240,240);
115
116 m_rectListBoxItem = lpDrawItemStruct->rcItem;
117 CRect rect(CRect(m_rectListBoxItem.left,m_rectListBoxItem.top-1,m_rectListBoxItem.right,m_rectListBoxItem.bottom));
118 // Returns the required struct which holds the Data (Text ,Icon) to be drawn
119 DataItems *pListDataItem = (DataItems *)GetItemDataPtr(lpDrawItemStruct->itemID);
120
121 rectIcon = new CRect(m_rectListBoxItem.left+10,m_rectListBoxItem.top+6,m_rectListBoxItem.left+35,m_rectListBoxItem.top+30);
122 rectText = new CRect(rectIcon->right+20,m_rectListBoxItem.top,m_rectListBoxItem.left+466,m_rectListBoxItem.bottom);
123 rectDel = new CRect(m_rectListBoxItem.left+470,m_rectListBoxItem.top+6,m_rectListBoxItem.left+486,m_rectListBoxItem.top+29);
124 if(this->GetCount()>=1)
125 {
126 if((lpDrawItemStruct->itemAction | ODA_FOCUS) &&(lpDrawItemStruct->itemState & ODS_FOCUS))
127 {
128 // CRect rect(m_rectListBoxItem);
129 // pDC->DrawFocusRect(m_rectListBoxItem);
130 }
131
132 // If the user has selected an item from the list box, or the selection has been changed
133 // draw the item of the list box and fill it with the color of selected item
134 if ((lpDrawItemStruct->itemAction | ODA_SELECT) &&(lpDrawItemStruct->itemState & ODS_SELECTED))
135 {
136
137 // Fill the item rect with the blue color
138 COLORREF crNowBkColorChosen = RGB(190, 206,245);
139 brush.CreateSolidBrush(crNowBkColorChosen);
140 pDC->SelectObject(pen);
141 pDC->SelectObject(brush);
142 pDC->Rectangle(&rect);
143 // Set the color of the background of the text rect
144 pDC->SetBkColor(crNowBkColorChosen );
145 // Set the color of the text
146 pDC->SetTextColor(crOldTextColor);
147
148 DrawIconEx(pDC->GetSafeHdc(),rectIcon->left,rectIcon->top,pListDataItem->hIcon,26,21,0,NULL,DI_NORMAL);
149 pDC->DrawText(pListDataItem->strItemData,lstrlen(pListDataItem->strItemData),rectText, DT_LEFT|DT_SINGLELINE|DT_VCENTER);
150 DrawIconEx(pDC->GetSafeHdc(),rectDel->left,rectDel->top,AfxGetApp()->LoadIcon(IDI_DEL),23,23,0,NULL,DI_NORMAL);
151 pDC->SelectObject(hOldFont);
152 }
153 else
154 {
155 if(lpDrawItemStruct->itemID%2)
156 {
157 brush.CreateSolidBrush(crOldBkColorEven);
158 pDC->SelectObject(pen);
159 pDC->SelectObject(brush);
160 pDC->Rectangle(&rect);
161 pDC->SetBkColor(crOldBkColorEven );
162 }
163 else
164 {
165 brush.CreateSolidBrush(crOldBkColor);
166 pDC->SelectObject(pen);
167 pDC->SelectObject(brush);
168 pDC->Rectangle(&rect);
169 pDC->SetBkColor(crOldBkColor );
170 }
171 pDC->SetTextColor(crOldTextColor);
172
173 // HICON hicon = pListDataItem->hIcon;
174 // DrawIcon(MemDC.m_hDC,0,0,hicon);
175 // GetDC()-> BitBlt(rectIcon->left,rectIcon->top,rectIcon->Width(),rectIcon->Height(),&MemDC,0,0,SRCCOPY);
176 DrawIconEx(pDC->GetSafeHdc(),rectIcon->left,rectIcon->top,pListDataItem->hIcon,26,21,0,NULL,DI_NORMAL);
177 pDC->DrawText(pListDataItem->strItemData,lstrlen(pListDataItem->strItemData),rectText, DT_LEFT|DT_SINGLELINE|DT_VCENTER);
178 DrawIconEx(pDC->GetSafeHdc(),rectDel->left,rectDel->top,AfxGetApp()->LoadIcon(IDI_DEL),23,23,0,NULL,DI_NORMAL);
179 pDC->SelectObject(hOldFont);
180 }
181 }
182 //if(pDC!=NULL)
183 // pDC->Detach();
184 MemDC.DeleteDC();
185 delete rectText;
186 delete rectIcon;
187 delete rectDel;
188 }
189
190 void COwnerDrawListBox::Add(CString strItemName, HICON hDataIcon)
191 {
192 DataItems *m_pListBoxDataItems = new DataItems;
193
194 m_pListBoxDataItems->hIcon = hDataIcon;
195 m_pListBoxDataItems->strItemData = strItemName;
196
197 int index = AddString(L"");
198 SetItemDataPtr(index, m_pListBoxDataItems);
199 }
200
201 //Delete the Items of the ListBox
202 void COwnerDrawListBox::OnLButtonDown(UINT nFlags, CPoint point)
203 {
204 isDeleted =TRUE;
205 CRect rect;
206 GetClientRect(&rect);
207 rect = this->m_rectListBoxItem;
208 rectDelete= new CRect(rect.left+470,rect.top+12,498,rect.top+28);
209 if(rectDelete->PtInRect(point))
210 {
211 int index = this->GetCurSel();
212 DataItems * pdata = (DataItems *)GetItemDataPtr(index);
213
214 CoInitialize(NULL);
215 //读取XML
216 MSXML2::IXMLDOMDocumentPtr spXMLDoc;
217 spXMLDoc.CreateInstance(__uuidof(MSXML2::DOMDocument30));
218 spXMLDoc->load(L"config.xml");
219 MSXML2::IXMLDOMElementPtr spRoot = spXMLDoc->documentElement; //根节点
220
221 //写入XML
222 MSXML2::IXMLDOMNodePtr spShareNode = spRoot->selectSingleNode(L"/Win-DMS/SharedFolders");
223 MSXML2::IXMLDOMNodeListPtr FolderListPtr = NULL;
224 spShareNode->get_childNodes(&FolderListPtr);
225 MSXML2::IXMLDOMNodePtr FolderNodePtr = NULL;
226 long len = FolderListPtr->Getlength();
227 for (int i =0; i <len; i++)
228 {
229 FolderNodePtr = FolderListPtr->Getitem(i);
230 BSTR text = FolderNodePtr->Gettext();
231 if(index != -1)
232 {
233 if(!lstrcmp((LPCWSTR)text ,pdata->strItemData))
234 {
235 spShareNode->removeChild(FolderListPtr->Getitem(i));
236 break;
237 }
238 }
239
240 }
241 spXMLDoc->save(_variant_t(L"config.xml"));
242 if(spShareNode!=NULL)
243 spShareNode.Release();
244 if(FolderNodePtr!=NULL)
245 FolderNodePtr.Release();
246 if (FolderNodePtr!=NULL)
247 FolderListPtr.Release();
248 if (spRoot!=NULL)
249 spRoot.Release();
250 if (spXMLDoc!=NULL)
251 spXMLDoc.Release();
252 CoUninitialize();
253 //delete DataItems;
254 this->DeleteString(index);
255 }
256 isDeleted = FALSE;
257 delete rectDelete;
258 CListBox::OnLButtonDown(nFlags, point);
259 }
260
261 void COwnerDrawListBox::OnLButtonUp(UINT nFlags, CPoint point)
262 {
263 isHightLight = FALSE;
264 isDeleted = FALSE;
265 CListBox::OnLButtonUp(nFlags, point);
266 }
267
268
269 void COwnerDrawListBox::OnDestroy()
270 {
271 CListBox::OnDestroy();
272 int ItemCount;
273 ItemCount = GetCount();
274
275 if (ItemCount != 0 )
276 for (int i = 0; i < ItemCount; i++)
277 {
278 DataItems *m_pListBoxDataItems = (DataItems*) GetItemDataPtr(i);
279 delete m_pListBoxDataItems;
280 }
281 }
282
283
284 //待修改 实现鼠标放在delete上可以高亮。
285 void COwnerDrawListBox::OnMouseMove(UINT nFlags, CPoint point)
286 {
287 CClientDC dc(this);
288 COLORREF crFocusColor = RGB(190, 206,245);
289 int nCount = GetCount();
290 CRect rectItem;
291 CFont hFont;
292 hFont.CreateFont(
293 17, // nHeight
294 0, // nWidth
295 0, // nEscapement
296 0, // nOrientation
297 FW_NORMAL, // nWeight
298 FALSE, // bItalic
299 FALSE, // bUnderline//FALSE
300 0, // cStrikeOut
301 ANSI_CHARSET, // nCharSet
302 OUT_DEFAULT_PRECIS, // nOutPrecision
303 CLIP_DEFAULT_PRECIS, // nClipPrecision
304 CLEARTYPE_QUALITY, // nQuality
305 DEFAULT_PITCH | FF_MODERN, // nPitchAndFamily
306 L"Arial"); // lpszFacename//Arial
307 CFont* hOldFont = dc.SelectObject(&hFont);
308 for (int index = 0; index<nCount; index++)
309 {
310 GetItemRect(index,rectItem);
311 CRect rectDel (rectItem.left+470,rectItem.top+6,rectItem.left+486,rectItem.top+29);
312 if (rectItem.PtInRect(point))
313 {
314 if(this->GetCurSel() != index)
315 this->SetCurSel(index);
316 if(rectDel.PtInRect(point))
317 {
318 DrawIconEx(dc.GetSafeHdc(),rectDel.left,rectDel.top,AfxGetApp()->LoadIcon(IDI_DEL_HIGHLIGHT),23,23,0,NULL,DI_NORMAL);
319 }
320 else
321 DrawIconEx(dc.GetSafeHdc(),rectDel.left,rectDel.top,AfxGetApp()->LoadIcon(IDI_DEL),23,23,0,NULL,DI_NORMAL);
322 }
323 }
324
325 CListBox::OnMouseMove(nFlags, point);
326 }

 

posted @ 2011-11-13 23:30  lingyun1120  阅读(4699)  评论(0编辑  收藏  举报