Commit before breaking everything
[matches/honours.git] / research / transmission_spectroscopy / TOF / Win32++ / samples / Explorer / src / MyTreeView.cpp
1 //////////////////////////////////////////////////////////\r
2 // MyTreeView.cpp\r
3 //  Definitions for the CMyTreeView and TreeItemData classes\r
4 \r
5 #include "stdafx.h"\r
6 #include "ExplorerApp.h"\r
7 #include "Mainfrm.h"\r
8 #include "MyTreeView.h"\r
9 #include "MyListView.h"\r
10 #include "resource.h"\r
11 \r
12 ////////////////////////////////\r
13 //CMyTreeView function definitions\r
14 CMyTreeView::CMyTreeView()\r
15 {\r
16         SetImageLists();\r
17 }\r
18 \r
19 CMyTreeView::~CMyTreeView()\r
20 {\r
21         DeleteItems();\r
22 }\r
23 \r
24 int CALLBACK CMyTreeView::CompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)\r
25 {\r
26         UNREFERENCED_PARAMETER(lParamSort);\r
27         TreeItemData* pItem1 = (TreeItemData*)lParam1;\r
28         TreeItemData* pItem2 = (TreeItemData*)lParam2;\r
29         HRESULT hr;\r
30 \r
31         hr = pItem1->GetParentFolder().CompareIDs(0, pItem1->GetRelCpidl(), pItem2->GetRelCpidl());\r
32         if(FAILED(hr))\r
33                 return 0;\r
34 \r
35         return (short)SCODE_CODE(GetScode(hr));\r
36 }\r
37 \r
38 void CMyTreeView::DeleteItems()\r
39 {\r
40         m_pItems.clear();\r
41 }\r
42 \r
43 void CMyTreeView::DoContextMenu(CPoint& ptScreen)\r
44 {\r
45         TVHITTESTINFO  tvhti;\r
46         tvhti.pt = ptScreen;\r
47         ScreenToClient(tvhti.pt);\r
48         tvhti.flags = LVHT_NOWHERE;\r
49         HitTest(tvhti);\r
50 \r
51         if(TVHT_ONITEM & tvhti.flags)\r
52                 DoItemMenu(tvhti.hItem , ptScreen);\r
53 }\r
54 \r
55 void CMyTreeView::DoItemMenu(HTREEITEM hItem, CPoint& ptScreen)\r
56 {\r
57         TVITEM tvItem = {0};\r
58         tvItem.mask = TVIF_PARAM;\r
59         tvItem.hItem = hItem;\r
60 \r
61         if(GetItem(tvItem))\r
62         {\r
63                 HRESULT        hr;\r
64                 TreeItemData*  pInfo = (TreeItemData*)tvItem.lParam;\r
65                 CContextMenu cm;\r
66                 CShellFolder sf;\r
67 \r
68                 if (pInfo->GetParentFolder().GetIShellFolder() != NULL)\r
69                         sf = pInfo->GetParentFolder();\r
70                 else\r
71                         sf.SHGetDesktopFolder();\r
72 \r
73                 if(sf.GetIShellFolder())\r
74                 {\r
75                         hr = sf.GetUIObjectOf(m_hWnd, 1, &(pInfo->GetRelCpidl()), IID_IContextMenu, 0, cm);\r
76 \r
77                         if(SUCCEEDED(hr))\r
78                         {\r
79                                 CMenu Popup;\r
80                                 Popup.CreatePopupMenu();\r
81                                 if(Popup.GetHandle())\r
82                                 {\r
83                                         hr = cm.QueryContextMenu(Popup, 0, 1, 0x7fff, CMF_NORMAL | CMF_EXPLORE);\r
84 \r
85                                         if(SUCCEEDED(hr))\r
86                                         {\r
87                                                 cm.QueryInterface(IID_IContextMenu2, m_ccm2);\r
88 \r
89                                                 UINT idCmd = Popup.TrackPopupMenu(TPM_LEFTALIGN | TPM_RETURNCMD | TPM_RIGHTBUTTON ,\r
90                                                         ptScreen.x, ptScreen.y, this, NULL);\r
91 \r
92                                                 //A Treeview control sometimes requires this to end the\r
93                                                 // TrackPopupMenu properly\r
94                                                 GetParent()->PostMessage(WM_CANCELMODE, 0, 0);\r
95 \r
96                                                 if(idCmd)\r
97                                                 {\r
98                                                         CMINVOKECOMMANDINFO  cmi = {0};\r
99                                                         cmi.cbSize = sizeof(CMINVOKECOMMANDINFO);\r
100                                                         cmi.hwnd = m_hWnd;\r
101                                                         cmi.lpVerb = (LPCSTR)(INT_PTR)(idCmd - 1);\r
102                                                         cmi.nShow = SW_SHOWNORMAL;\r
103                                                         cm.InvokeCommand(cmi);\r
104                                                 }\r
105 \r
106                                                 m_ccm2.Release();\r
107                                         }\r
108                                 }\r
109                         }\r
110                 }\r
111         }\r
112 }\r
113 \r
114 LRESULT CMyTreeView::OnNotifyReflect(WPARAM, LPARAM lParam)\r
115 {\r
116         LPNMHDR  lpnmh = (LPNMHDR) lParam;\r
117 \r
118         switch(lpnmh->code)\r
119         {\r
120         case NM_RCLICK:\r
121                 {\r
122                         CPoint ptScreen;\r
123                         ::GetCursorPos(&ptScreen);\r
124                         DoContextMenu(ptScreen);\r
125                 }\r
126                 break;\r
127         case TVN_GETDISPINFO:\r
128                 {\r
129                         LPNMTVDISPINFO lpdi = (LPNMTVDISPINFO)lParam;\r
130                         TreeItemData* pItem = (TreeItemData*)lpdi->item.lParam;\r
131 \r
132                         //do we need to supply the text?\r
133                         if(lpdi->item.mask & TVIF_TEXT)\r
134                         {\r
135                                 SHFILEINFO sfi = {0};\r
136 \r
137                                 //get the display name of the item\r
138                                 if(pItem->GetFullCpidl().SHGetFileInfo(0, sfi, SHGFI_PIDL | SHGFI_DISPLAYNAME))\r
139                                         ::lstrcpyn(lpdi->item.pszText, sfi.szDisplayName, lpdi->item.cchTextMax -1);\r
140                         }\r
141 \r
142                         //do we need to supply the unselected image?\r
143                         if(lpdi->item.mask & TVIF_IMAGE)\r
144                         {\r
145                                 SHFILEINFO sfi = {0};\r
146 \r
147                                 //get the unselected image for this item\r
148                                 if(pItem->GetFullCpidl().SHGetFileInfo(0, sfi, SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_LINKOVERLAY))\r
149                                         lpdi->item.iImage = sfi.iIcon;\r
150                         }\r
151 \r
152                         //do we need to supply the selected image?\r
153                         if(lpdi->item.mask & TVIF_SELECTEDIMAGE)\r
154                         {\r
155                                 SHFILEINFO sfi = {0};\r
156 \r
157                                 //get the selected image for this item\r
158                                 if(pItem->GetFullCpidl().SHGetFileInfo(0, sfi, SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_OPENICON))\r
159                                         lpdi->item.iSelectedImage = sfi.iIcon;\r
160                         }\r
161                 }\r
162                 break;\r
163 \r
164         case TVN_ITEMEXPANDING:\r
165                 {\r
166                         LPNMTREEVIEW pnmtv = (LPNMTREEVIEW)lParam;\r
167 \r
168                         switch(pnmtv->action)\r
169                         {\r
170                         case TVE_EXPAND:\r
171                                 {\r
172                                         UINT ExpandedOnce = pnmtv->itemNew.state & TVIS_EXPANDEDONCE;\r
173                                         if (!ExpandedOnce)\r
174                                                 GetChildItems(pnmtv->itemNew.hItem);\r
175                                 }\r
176                                 break;\r
177                         }\r
178                 }\r
179                 break;\r
180 \r
181         case TVN_SELCHANGED:\r
182                 {\r
183                         LPNMTREEVIEW pnmtv = (LPNMTREEVIEW)lParam;\r
184                         TreeItemData* pItem = (TreeItemData*)pnmtv->itemNew.lParam;\r
185 \r
186                         CMyListView* LeftView = GetExplorerApp().GetMainFrame().GetListView();\r
187                         LeftView->DisplayFolder(pItem->GetParentFolder(), pItem->GetFullCpidl(), pItem->GetRelCpidl());\r
188                 }\r
189                 break;\r
190         } // switch(lpnmh->code)\r
191 \r
192         return 0;\r
193 }\r
194 \r
195 void CMyTreeView::EnumObjects(HTREEITEM hParentItem, CShellFolder& cParentFolder, Cpidl& cpidlParent)\r
196 {\r
197         CEnumIDList cEnum;\r
198         if(SUCCEEDED(cParentFolder.EnumObjects(NULL, SHCONTF_FOLDERS | SHCONTF_INCLUDEHIDDEN, cEnum)))\r
199         {\r
200                 ULONG ulFetched = 1;\r
201                 Cpidl cpidlRel;\r
202 \r
203                 //enumerate the item's PIDLs\r
204                 while(S_OK == (cEnum.Next(1, cpidlRel, ulFetched)) && ulFetched)\r
205                 {\r
206                         TVITEM         tvItem = {0};\r
207                         TVINSERTSTRUCT tvInsert = {0};\r
208                         ULONG          ulAttribs;\r
209 \r
210                         //fill in the TV_ITEM structure for this item\r
211                         tvItem.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN;\r
212 \r
213                         //Store a pointer to the TreeItemData in the lParam and m_pItems\r
214                         TreeItemData* pItem = new TreeItemData(cpidlParent, cpidlRel, cParentFolder);\r
215                         tvItem.lParam = (LPARAM)pItem;\r
216                         m_pItems.push_back(pItem);\r
217 \r
218                         //text and images are done on a callback basis\r
219                         tvItem.pszText = LPSTR_TEXTCALLBACK;\r
220                         tvItem.iImage = tvItem.iSelectedImage = I_IMAGECALLBACK;\r
221 \r
222                         //determine if the item has children or shared\r
223                         ulAttribs = SFGAO_HASSUBFOLDER | SFGAO_FOLDER | SFGAO_SHARE;\r
224                         cParentFolder.GetAttributesOf(1, cpidlRel, ulAttribs);\r
225                         tvItem.cChildren = (ulAttribs & SFGAO_HASSUBFOLDER);\r
226 \r
227                         //determine if the item is shared\r
228                         if(ulAttribs & SFGAO_SHARE)\r
229                         {\r
230                                 tvItem.mask |= TVIF_STATE;\r
231                                 tvItem.stateMask |= TVIS_OVERLAYMASK;\r
232                                 tvItem.state |= INDEXTOOVERLAYMASK(1); //1 is the index for the shared overlay image\r
233                         }\r
234 \r
235                         //fill in the TV_INSERTSTRUCT structure for this item\r
236                         tvInsert.item = tvItem;\r
237                         tvInsert.hInsertAfter = TVI_LAST;\r
238                         tvInsert.hParent = hParentItem;\r
239 \r
240                         InsertItem(tvInsert);\r
241                         ulFetched = 0;\r
242                 }\r
243         }\r
244 }\r
245 \r
246 BOOL CMyTreeView::GetChildItems(HTREEITEM hParentItem)\r
247 {\r
248         TVITEM tvItem = {0};\r
249         tvItem.mask = TVIF_PARAM;\r
250         tvItem.hItem = hParentItem;\r
251         if (!GetItem(tvItem))\r
252                 return FALSE;\r
253 \r
254         //change the cursor\r
255         HCURSOR hCursor = ::SetCursor(LoadCursor(NULL, IDC_WAIT));\r
256 \r
257         //turn redawing off in the TreeView. This will speed things up as we add items\r
258         SendMessage(WM_SETREDRAW, FALSE, 0);\r
259 \r
260         TreeItemData* pItem = (TreeItemData*)tvItem.lParam;\r
261         CShellFolder cParentFolder;\r
262         HRESULT        hr;\r
263 \r
264         //if the parent folder is NULL, then we are at the root of the namespace, so the parent of this item is the desktop folder\r
265         if(!pItem->GetParentFolder().GetIShellFolder())\r
266                 hr = cParentFolder.SHGetDesktopFolder();\r
267 \r
268         //otherwise we need to get the IShellFolder for this item\r
269         else\r
270                 hr = pItem->GetParentFolder().BindToObject(pItem->GetRelCpidl(), NULL, IID_IShellFolder, cParentFolder);\r
271 \r
272         if(FAILED(hr))\r
273                 return FALSE;\r
274 \r
275         EnumObjects(hParentItem, cParentFolder, pItem->GetFullCpidl());\r
276 \r
277         //sort the new items\r
278         TV_SORTCB tvSort;\r
279         tvSort.hParent = hParentItem;\r
280         tvSort.lpfnCompare = CompareProc;\r
281         tvSort.lParam = 0;\r
282         SortChildrenCB(tvSort, 0);\r
283 \r
284         //turn redawing back on in the TreeView\r
285         SendMessage(WM_SETREDRAW, TRUE, 0);\r
286 \r
287         UpdateWindow();\r
288         ::SetCursor(hCursor);\r
289 \r
290         return TRUE;\r
291 }\r
292 \r
293 HIMAGELIST CMyTreeView::GetImageList(BOOL bLarge)\r
294 {\r
295         if (bLarge)\r
296                 return m_hLargeImageList;\r
297         else\r
298                 return m_hSmallImageList;\r
299 }\r
300 \r
301 BOOL CMyTreeView::GetRootItems()\r
302 {\r
303         DeleteAllItems();\r
304 \r
305         Cpidl cpidlDesk;\r
306         cpidlDesk.SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOP);\r
307         if (cpidlDesk.GetPidl())\r
308         {\r
309                 TV_ITEM           tvItem = {0};\r
310                 TV_INSERTSTRUCT   tvInsert = {0};\r
311                 HTREEITEM         hParentItem;\r
312 \r
313                 //fill in the TVITEM structure for this item\r
314                 tvItem.mask = TVIF_PARAM | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN;\r
315 \r
316                 //Store a pointer to the TreeItemData in the lParam and m_pItems\r
317                 TreeItemData* pItem = new TreeItemData(cpidlDesk);\r
318                 tvItem.lParam = (LPARAM)pItem;\r
319                 m_pItems.push_back(pItem);\r
320 \r
321                 //text and images are done on a callback basis\r
322                 tvItem.pszText = LPSTR_TEXTCALLBACK;\r
323                 tvItem.iImage = tvItem.iSelectedImage = I_IMAGECALLBACK;\r
324 \r
325                 //assume the desktop has children\r
326                 tvItem.cChildren = TRUE;\r
327 \r
328                 //fill in the TV_INSERTSTRUCT structure for this item\r
329                 tvInsert.item = tvItem;\r
330                 tvInsert.hInsertAfter = TVI_LAST;\r
331                 tvInsert.hParent = TVI_ROOT;\r
332 \r
333                 SetFocus();\r
334 \r
335                 //add the item\r
336                 hParentItem = InsertItem(tvInsert);\r
337 \r
338                 //go ahead and expand this item\r
339                 Expand(hParentItem, TVE_EXPAND);\r
340 \r
341                 //Select the next item\r
342                 HTREEITEM hNext = GetNextItem(hParentItem, TVGN_CHILD);\r
343 \r
344                 //Expand this item\r
345                 Expand(hNext, TVE_EXPAND);\r
346 \r
347                 //Select this item\r
348                 SelectItem(hNext);\r
349 \r
350                 //Scroll this item into view\r
351                 SelectSetFirstVisible(hNext);\r
352 \r
353                 return TRUE;\r
354         }\r
355 \r
356         return FALSE;\r
357 }\r
358 \r
359 void CMyTreeView::OnInitialUpdate()\r
360 {\r
361         //Set the image list\r
362         SendMessage(TVM_SETIMAGELIST, TVSIL_NORMAL, (LPARAM) GetImageList(FALSE));\r
363 }\r
364 \r
365 void CMyTreeView::PreCreate(CREATESTRUCT &cs)\r
366 {\r
367         cs.dwExStyle = WS_EX_CLIENTEDGE;\r
368         cs.style = WS_TABSTOP | WS_CHILD | WS_VISIBLE | TVS_HASLINES |\r
369                                         TVS_HASBUTTONS | TVS_NOTOOLTIPS | TVS_SHOWSELALWAYS ;\r
370 }\r
371 \r
372 BOOL CMyTreeView::SelectFromListView(Cpidl& cpidlFull)\r
373 {\r
374         HTREEITEM hItem = GetSelection();\r
375 \r
376         //Set parent item's has Children flag\r
377         TVITEM tvItem = {0};\r
378         tvItem.mask = TVIF_CHILDREN;\r
379         tvItem.cChildren = 1;\r
380         tvItem.hItem = hItem;\r
381         SetItem(tvItem);\r
382 \r
383         //Expand the tree item\r
384         Expand(hItem, TVE_EXPAND);\r
385 \r
386         //First Child\r
387         HTREEITEM hChild = GetChild(hItem);\r
388 \r
389         while (hChild != NULL)\r
390         {\r
391                 //Get the TVITEM structure for this item\r
392                 TVITEM tvItem = {0};\r
393                 tvItem.mask = TVIF_PARAM;\r
394                 tvItem.hItem = hChild;\r
395                 if(!GetItem(tvItem))\r
396                         return FALSE;\r
397 \r
398                 //Get the TreeItemData pointer from the item's lParam\r
399                 TreeItemData* pTD = (TreeItemData*)tvItem.lParam;\r
400 \r
401                 //Compare the pidls\r
402                 if (pTD->GetFullCpidl() == cpidlFull)\r
403                 {\r
404                         SelectItem(hChild);\r
405                         return TRUE;\r
406                 }\r
407 \r
408                 //Next Sibling\r
409                 hChild = GetNextSibling(hChild);\r
410         }\r
411         TRACE(_T("Item NOT found\n"));\r
412 \r
413         return FALSE;\r
414 }\r
415 \r
416 void CMyTreeView::SetImageLists()\r
417 {\r
418         SHFILEINFO  sfi;\r
419 \r
420         // Get the system image list\r
421         m_hLargeImageList = (HIMAGELIST)::SHGetFileInfo(_T("C:\\"), 0, &sfi,\r
422                 sizeof(SHFILEINFO), SHGFI_SYSICONINDEX);\r
423 \r
424         m_hSmallImageList = (HIMAGELIST)::SHGetFileInfo(_T("C:\\"), 0, &sfi,\r
425                 sizeof(SHFILEINFO), SHGFI_SYSICONINDEX | SHGFI_SMALLICON);\r
426 }\r
427 \r
428 LRESULT CMyTreeView::WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam)\r
429 {\r
430         switch (uMsg)\r
431         {\r
432                 case WM_DRAWITEM:\r
433                 case WM_MENUCHAR:\r
434                 case WM_MEASUREITEM:\r
435                 case WM_INITMENUPOPUP:\r
436                 {\r
437                         if(m_ccm2.GetIContextMenu2())\r
438                                 m_ccm2.HandleMenuMsg(uMsg, wParam, lParam);\r
439                 }\r
440                 break;\r
441                 case WM_DESTROY:\r
442                         // Cleanup\r
443                         m_pItems.clear();\r
444                         break;\r
445         }\r
446 \r
447         return WndProcDefault(uMsg, wParam, lParam);\r
448 }\r
449 \r
450 ///////////////////////////////////\r
451 //TreeItemData function definitions\r
452 CMyTreeView::TreeItemData::TreeItemData(Cpidl& cpidl)\r
453 {\r
454         m_cpidlRel  = cpidl;\r
455         m_cpidlFull = cpidl;\r
456 }\r
457 \r
458 CMyTreeView::TreeItemData::TreeItemData(Cpidl& cpidlParent, Cpidl& cpidlRel, CShellFolder& cParentFolder)\r
459 {\r
460         m_cParentFolder = cParentFolder;\r
461         m_cpidlFull     = cpidlParent + cpidlRel;\r
462         m_cpidlRel      = cpidlRel;\r
463 }\r
464 \r
465 CMyTreeView::TreeItemData::~TreeItemData()\r
466 {\r
467 }\r

UCC git Repository :: git.ucc.asn.au