xref: /MusicPlayer2/MusicPlayer2/TreeCtrlEx.cpp (revision b93a36737ca3a6b7f3947aefa5df4d5de64e07e4)
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