1 // TreeCtrlEx.cpp: 实现文件
2 //
3
4 #include "stdafx.h"
5 #include "TreeCtrlEx.h"
6 #include "MusicPlayer2.h"
7
8
9 // CTreeCtrlEx
10
11 std::map<CString, bool> CTreeCtrlEx::m_expand_state;
12
IMPLEMENT_DYNAMIC(CTreeCtrlEx,CTreeCtrl)13 IMPLEMENT_DYNAMIC(CTreeCtrlEx, CTreeCtrl)
14
15 CTreeCtrlEx::CTreeCtrlEx()
16 : m_theme_color(theApp.m_app_setting_data.theme_color)
17 {
18 }
19
~CTreeCtrlEx()20 CTreeCtrlEx::~CTreeCtrlEx()
21 {
22 }
23
InsertPath(CString path,HTREEITEM hRoot)24 void CTreeCtrlEx::InsertPath(CString path, HTREEITEM hRoot)
25 {
26 HTREEITEM hRootItem = InsertItem(path, hRoot);
27 _InsertPath(path, hRootItem);
28 }
29
InsertPath(CString path,HTREEITEM hRoot,std::function<bool (const CString &)> is_path_show)30 void CTreeCtrlEx::InsertPath(CString path, HTREEITEM hRoot, std::function<bool(const CString&)> is_path_show)
31 {
32 HTREEITEM hRootItem = InsertItem(path, hRoot);
33 _InsertPath(path, hRootItem, is_path_show);
34 }
35
GetItemPath(HTREEITEM hItem)36 CString CTreeCtrlEx::GetItemPath(HTREEITEM hItem)
37 {
38 CString strPath;
39 strPath = GetItemText(hItem);
40 while (hItem != NULL)
41 {
42 hItem = GetNextItem(hItem, TVGN_PARENT);
43 CString strParent = GetItemText(hItem);
44 if(!strParent.IsEmpty())
45 {
46 if (strParent[strParent.GetLength() - 1] == L'\\')
47 strParent.Delete(strParent.GetLength() - 1, 1);
48 strPath = strParent + _T("\\") + strPath;
49 }
50 }
51 strPath += _T('\\');
52 return strPath;
53 }
54
IsItemExpand(HTREEITEM hItem)55 bool CTreeCtrlEx::IsItemExpand(HTREEITEM hItem)
56 {
57 return (GetItemState(hItem, TVIS_EXPANDED)&TVIS_EXPANDED) == TVIS_EXPANDED;
58 }
59
ExpandAll(HTREEITEM hItem)60 void CTreeCtrlEx::ExpandAll(HTREEITEM hItem)
61 {
62 IterateItems(hItem, [&](HTREEITEM hChild)
63 {
64 Expand(hChild, TVE_EXPAND);
65 });
66 }
67
ExpandAll()68 void CTreeCtrlEx::ExpandAll()
69 {
70 ExpandAll(NULL);
71 }
72
IterateItems(HTREEITEM hRoot,std::function<void (HTREEITEM)> func)73 void CTreeCtrlEx::IterateItems(HTREEITEM hRoot, std::function<void(HTREEITEM)> func)
74 {
75 HTREEITEM hChild, hNext;
76 if(hRoot!=NULL)
77 func(hRoot);
78
79 hChild = GetNextItem(hRoot, TVGN_CHILD);
80 if (hChild)
81 {
82 //遍历子节点
83 IterateItems(hChild, func);
84 hNext = hChild;
85 do
86 {
87 hNext = GetNextItem(hNext, TVGN_NEXT);
88 if (hNext != NULL)
89 IterateItems(hNext, func);
90 } while (hNext != NULL);
91 }
92 }
93
SaveExpandState()94 void CTreeCtrlEx::SaveExpandState()
95 {
96 IterateItems(NULL, [&](HTREEITEM hItem)
97 {
98 bool expand = IsItemExpand(hItem);
99 m_expand_state[GetItemPath(hItem)] = expand;
100 });
101 }
102
SaveItemExpandState(HTREEITEM hItem,bool expand)103 void CTreeCtrlEx::SaveItemExpandState(HTREEITEM hItem, bool expand)
104 {
105 CString item_path = GetItemPath(hItem);
106 m_expand_state[item_path] = expand;
107 }
108
RestoreExpandState()109 void CTreeCtrlEx::RestoreExpandState()
110 {
111 IterateItems(NULL, [&](HTREEITEM hItem)
112 {
113 CString item_path = GetItemPath(hItem);
114 auto iter = m_expand_state.find(item_path);
115 if(iter != m_expand_state.end())
116 {
117 bool expand = iter->second;
118 Expand(hItem, expand ? TVE_EXPAND : TVE_COLLAPSE);
119 }
120 });
121
122 }
123
_InsertPath(CString path,HTREEITEM hRoot,std::function<bool (const CString &)> is_path_show)124 void CTreeCtrlEx::_InsertPath(CString path, HTREEITEM hRoot, std::function<bool(const CString&)> is_path_show)
125 {
126 if (!path.IsEmpty() && path.Right(1) == _T("\\"))
127 path = path.Left(path.GetLength() - 1);
128 CFileFind nFindFile;
129 CString str = L"";
130 CString nPicFileName = L"";
131 BOOL IsExist = FALSE;
132 HTREEITEM hSubItem;
133 nPicFileName.Format(L"%s\\*.*", path);
134 IsExist = nFindFile.FindFile(nPicFileName);
135 while (IsExist)
136 {
137 IsExist = nFindFile.FindNextFile();
138 if (nFindFile.IsDots())
139 continue;
140 nPicFileName = nFindFile.GetFileName();
141 //路径
142 if (nFindFile.IsDirectory() && is_path_show(nFindFile.GetFilePath()))
143 {
144 hSubItem = InsertItem(nPicFileName, hRoot);
145 _InsertPath(nFindFile.GetFilePath(), hSubItem, is_path_show);
146 }
147 }
148 nFindFile.Close();
149 }
150
151
BEGIN_MESSAGE_MAP(CTreeCtrlEx,CTreeCtrl)152 BEGIN_MESSAGE_MAP(CTreeCtrlEx, CTreeCtrl)
153 ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, &CTreeCtrlEx::OnNMCustomdraw)
154 END_MESSAGE_MAP()
155
156
157
158
159 void CTreeCtrlEx::PreSubclassWindow()
160 {
161 // TODO: 在此添加专用代码和/或调用基类
162
163 CTreeCtrl::PreSubclassWindow();
164 }
165
166
OnNMCustomdraw(NMHDR * pNMHDR,LRESULT * pResult)167 void CTreeCtrlEx::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult)
168 {
169 //设置树控件的颜色,参考自(https://blog.csdn.net/daoming1112/article/details/77891525)
170
171 LPNMTVCUSTOMDRAW pNMCD = reinterpret_cast<LPNMTVCUSTOMDRAW>(pNMHDR);
172 NMCUSTOMDRAW nmCustomDraw = pNMCD->nmcd;
173 switch (nmCustomDraw.dwDrawStage)
174 {
175 case CDDS_ITEMPREPAINT:
176 {
177 if (nmCustomDraw.uItemState & CDIS_FOCUS) //设置选中行的颜色
178 {
179 pNMCD->clrText = m_theme_color.dark3;
180 pNMCD->clrTextBk = m_theme_color.light2;
181 }
182 else
183 {
184 pNMCD->clrText = CColorConvert::m_gray_color.dark3;
185 pNMCD->clrTextBk = GetBkColor();
186 }
187 }
188 default:
189 break;
190 }
191 *pResult = 0;
192 *pResult |= CDRF_NOTIFYPOSTPAINT;
193 *pResult |= CDRF_NOTIFYITEMDRAW;
194 }
195