ReactOS  0.4.12-dev-57-g7050ac4
treeview.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Applications
3  * LICENSE: LGPL - See COPYING in the top level directory
4  * FILE: base/applications/msconfig/treeview.c
5  * PURPOSE: Tree-View helper functions.
6  * COPYRIGHT: Copyright 2011-2012 Hermes BELUSCA - MAITO <hermes.belusca@sfr.fr>
7  */
8 
9 // For TVIF_EXPANDEDIMAGE and TVIF_STATEEX (are they really useful ?)
10 #if !defined(_WIN32_IE) || (_WIN32_IE < 0x0600)
11  #define _WIN32_IE 0x0600
12 #endif
13 
14 // Fake _WIN32_WINNT to 0x0600 in order to get Vista+ style flags
15 #undef _WIN32_WINNT
16 #define _WIN32_WINNT 0x0600
17 
18 #include "precomp.h"
19 #include "treeview.h"
20 
21 #include <wingdi.h> // For RGB macro
22 
23 
25 {
26  LONG_PTR lStyle;
27  DWORD dwExStyle;
28 
29  DWORD Major, Minor, Build;
30  GetComCtl32Version(&Major, &Minor, &Build);
31 
32  /*
33  * Choose the best way to handle 3-state TreeView checkboxes
34  * according to the version of comctl32.dll we are running against.
35  *
36  * Starting version comctl32 version 6.10 (Vista+, via SxS)
37  * we have native 3-state checkboxes available.
38  * Only when comctl32 version 5.82 (no SxS) is available,
39  * use its build number to know whether we should use 2k3-style
40  * or Vista+ style check-boxes.
41  */
42  if (Major > 6 || (Major == 6 && Minor >= 10))
43  {
44  /*
45  * NOTE: As explained in the following link:
46  * http://stackoverflow.com/questions/31488233/treeview-setextendedstyle-does-not-apply-certain-styles-what-am-i-doing-wrong
47  * the TreeView control should have the extended check-box style set
48  * *BEFORE* actually setting the check-box window style, because it is
49  * only at that step that the TreeView control builds its image list
50  * containing the three check-box states. Indeed, if the extended
51  * check-box style was applied after setting the window style, then
52  * the image list would be already built with the default two states
53  * and would not be updated.
54  *
55  * The MSDN documentation is not very clear on that point.
56  *
57  * Let me also take this opportunity to document what those
58  * extended check-box state styles look like on Windows Vista+ :
59  *
60  * - TVS_EX_DIMMEDCHECKBOXES creates a grey tone version of the normal checked box state.
61  * - TVS_EX_EXCLUSIONCHECKBOXES creates a red 'X'-style cross check-box state.
62  * - TVS_EX_PARTIALCHECKBOXES creates a filled box.
63  */
64  dwExStyle = TreeView_GetExtendedStyle(hTree);
65  TreeView_SetExtendedStyle(hTree, dwExStyle | TVS_EX_PARTIALCHECKBOXES, 0);
66 
67  lStyle = GetWindowLongPtr(hTree, GWL_STYLE);
68  SetWindowLongPtr(hTree, GWL_STYLE, lStyle | TVS_CHECKBOXES);
69  }
70  else
71  {
72  lStyle = GetWindowLongPtr(hTree, GWL_STYLE);
73  SetWindowLongPtr(hTree, GWL_STYLE, lStyle | TVS_CHECKBOXES);
74 
75  // TODO: Implement this function which should build at runtime
76  // the image list with either two or three check-box states
77  // (as it is done by the real common control TreeView), instead
78  // of storing resource bitmaps.
79  //
80  // hCheckImageList = CreateCheckBoxImagelist(NULL, TRUE, TRUE, FALSE);
82  ImageList_LoadBitmap(hInst, (Build >= 6000 ? MAKEINTRESOURCEW(IDB_V7CHECK) : MAKEINTRESOURCEW(IDB_2K3CHECK)), 16, 4, RGB(255, 255, 255)),
83  TVSIL_STATE);
84  }
85 }
86 
88 {
89  // FIXME: Should we do it always, or only when the custom image list was set?
91 }
92 
93 
98  HTREEITEM hInsertAfter)
99 {
100  TVINSERTSTRUCTW tvis;
101  SecureZeroMemory(&tvis, sizeof(tvis));
102 
103  tvis.hParent = hParent;
104  tvis.hInsertAfter = hInsertAfter;
105  tvis.itemex.mask = TVIF_TEXT;
106  tvis.itemex.pszText = (LPWSTR)szName;
107 
108  return (tvis.itemex.hItem = TreeView_InsertItem(hTree, &tvis));
109 }
110 
112 {
113 #define OP(a, b) ((a) == (b) ? (a) : 2)
114 
115  HTREEITEM htiIterator = TreeView_GetChild(hTree, htiSubtreeItem);
116  UINT uRealSubtreeState = TreeView_GetCheckState(hTree, htiIterator);
117  /*
118  while (htiIterator)
119  {
120  UINT temp = TreeView_GetCheckState(hTree, htiIterator);
121  uRealSubtreeState = OP(uRealSubtreeState, temp);
122 
123  htiIterator = TreeView_GetNextSibling(hTree, htiIterator);
124  }
125  */
126  while ( htiIterator && ( (htiIterator = TreeView_GetNextSibling(hTree, htiIterator)) != NULL ) )
127  {
128  UINT temp = TreeView_GetCheckState(hTree, htiIterator);
129  uRealSubtreeState = OP(uRealSubtreeState, temp);
130  }
131 
132  return uRealSubtreeState;
133 }
134 
136 {
137  HTREEITEM htiParent;
138  UINT uGlobalSiblingsCheckState;
139 
140  if (!hTree || !htiItem /* || htiItem == TVI_ROOT */)
141  return;
142 
143  htiParent = TreeView_GetParent(hTree, htiItem);
144  if (!htiParent)
145  return;
146 
147  uGlobalSiblingsCheckState = TreeView_GetRealSubtreeState(hTree, htiParent);
148  TreeView_SetItemState(hTree, htiParent, INDEXTOSTATEIMAGEMASK(uGlobalSiblingsCheckState + 1), TVIS_STATEIMAGEMASK);
149  TreeView_PropagateStateOfItemToParent(hTree, htiParent);
150 
151  return;
152 }
153 
155 {
156  HTREEITEM htiIterator;
157  TVINSERTSTRUCTW tvis;
159 
160  if (!hTree || !hSourceItem || !hInsertAfter)
161  return NULL;
162 
163  // 1- Retrieve properties.
164  SecureZeroMemory(&tvis, sizeof(tvis));
165 
166  tvis.itemex.hItem = hSourceItem; // Handle of the item to be retrieved.
170  tvis.itemex.pszText = label;
172  TreeView_GetItem(hTree, &tvis.itemex);
173 
174  // 2- Now, copy to destination.
175  tvis.hParent = hParent;
176  tvis.hInsertAfter = hInsertAfter;
177  tvis.itemex.stateMask = tvis.itemex.state;
178  tvis.itemex.hItem = TreeView_InsertItem(hTree, &tvis);
179 
180  for (htiIterator = TreeView_GetChild(hTree, hSourceItem) ; htiIterator ; htiIterator = TreeView_GetNextSibling(hTree, htiIterator))
181  Tree_Item_Copy(hTree, htiIterator, tvis.itemex.hItem, TVI_LAST);
182 
183  return tvis.itemex.hItem;
184 }
185 
186 void TreeView_DownItem(HWND hTree, HTREEITEM htiItemToDown)
187 {
188  HTREEITEM htiNextItem, htiNewItem;
189 
190  if (!hTree || !htiItemToDown)
191  return;
192 
193  htiNextItem = TreeView_GetNextSibling(hTree, htiItemToDown);
194  if (!htiNextItem)
195  htiNextItem = TVI_LAST;
196 
197  htiNewItem = Tree_Item_Copy(hTree, htiItemToDown, TreeView_GetParent(hTree, htiItemToDown), htiNextItem);
198  TreeView_DeleteItem(hTree, htiItemToDown); // Delete the item and ALL its children.
199  TreeView_SelectItem(hTree, htiNewItem);
200 
201  return;
202 }
203 
205 {
206  HTREEITEM htiPrevItem, htiPrevPrevItem, htiNewItem;
207 
208  if (!hTree || !htiItemToUp)
209  return;
210 
211  htiPrevItem = TreeView_GetPrevSibling(hTree, htiItemToUp);
212  htiPrevPrevItem = TreeView_GetPrevSibling(hTree, htiPrevItem);
213  if (!htiPrevPrevItem)
214  htiPrevPrevItem = TVI_FIRST;
215  // if htiPrevItem == NULL , htiPrevPrevItem == NULL.
216 
217  htiNewItem = Tree_Item_Copy(hTree, htiItemToUp, TreeView_GetParent(hTree, htiItemToUp), htiPrevPrevItem);
218  TreeView_DeleteItem(hTree, htiItemToUp); // Delete the item and ALL its children.
219  TreeView_SelectItem(hTree, htiNewItem);
220 
221  return;
222 }
223 
225 {
226  return TreeView_GetRoot(hTree);
227 }
228 
230 {
231  HTREEITEM htiRet = NULL;
232  HTREEITEM htiIterator;
233 
234  for (htiIterator = hItem ; htiIterator ; htiIterator = TreeView_GetNextSibling(hTree, htiIterator))
235  htiRet = htiIterator;
236 
237  return htiRet;
238 }
239 
241 {
242  return TreeView_GetLastFromItem(hTree, TreeView_GetRoot(hTree));
243 }
244 
246 {
247  HTREEITEM hPrev, hTmp;
248 
249  if (!hTree)
250  return NULL;
251 
252  hPrev = TreeView_GetPrevSibling(hTree, hItem);
253  if (!hPrev)
254  return TreeView_GetParent(hTree, hItem);
255 
256  hTmp = TreeView_GetChild(hTree, hPrev);
257  if (hTmp)
258  return TreeView_GetLastFromItem(hTree, hTmp);
259  else
260  return hPrev;
261 }
262 
264 {
265  HTREEITEM hNext;
266 
267  if (!hTree)
268  return NULL;
269 
270  hNext = TreeView_GetChild(hTree, hItem);
271  if (hNext)
272  return hNext;
273 
274  hNext = TreeView_GetNextSibling(hTree, hItem);
275  if (hNext)
276  return hNext;
277  else
278  return TreeView_GetNextSibling(hTree, TreeView_GetParent(hTree, hItem));
279 }
280 
281 /* EOF */
_Out_opt_ PULONG Minor
Definition: cmfuncs.h:44
#define TVIF_DI_SETITEM
Definition: commctrl.h:3626
HTREEITEM hParent
Definition: commctrl.h:3360
HTREEITEM TreeView_GetPrev(HWND hTree, HTREEITEM hItem)
Definition: treeview.c:245
void TreeView_Cleanup(HWND hTree)
Definition: treeview.c:87
#define TVIF_EXPANDEDIMAGE
Definition: commctrl.h:3246
#define IDB_V7CHECK
Definition: resource.h:152
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define SecureZeroMemory
Definition: winbase.h:1636
#define TreeView_GetChild(hwnd, hitem)
Definition: commctrl.h:3433
LPWSTR pszText
Definition: commctrl.h:3317
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
UINT stateMask
Definition: commctrl.h:3316
HTREEITEM InsertItem(HWND hTree, LPCWSTR szName, HTREEITEM hParent, HTREEITEM hInsertAfter)
Definition: treeview.c:95
#define TreeView_GetNextSibling(hwnd, hitem)
Definition: commctrl.h:3434
#define TVIF_SELECTEDIMAGE
Definition: commctrl.h:3238
#define SetWindowLongPtr
Definition: treelist.c:70
HTREEITEM TreeView_GetLast(HWND hTree)
Definition: treeview.c:240
#define TreeView_GetImageList(hwnd, iImage)
Definition: commctrl.h:3408
void TreeView_PropagateStateOfItemToParent(HWND hTree, HTREEITEM htiItem)
Definition: treeview.c:135
BOOL WINAPI ImageList_Destroy(HIMAGELIST himl)
Definition: imagelist.c:893
#define TreeView_InsertItem(hwnd, lpis)
Definition: commctrl.h:3379
HTREEITEM Tree_Item_Copy(HWND hTree, HTREEITEM hSourceItem, HTREEITEM hParent, HTREEITEM hInsertAfter)
Definition: treeview.c:154
#define TVIF_CHILDREN
Definition: commctrl.h:3239
HTREEITEM hInsertAfter
Definition: commctrl.h:3361
HRESULT GetComCtl32Version(OUT PDWORD pdwMajor, OUT PDWORD pdwMinor, OUT PDWORD pdwBuild)
Definition: comctl32supp.c:11
#define TVI_FIRST
Definition: commctrl.h:3336
smooth NULL
Definition: ftsmooth.c:416
#define MAX_VALUE_NAME
Definition: control.c:23
#define TreeView_GetCheckState(hwndTV, hti)
Definition: commctrl.h:3563
#define TVI_LAST
Definition: commctrl.h:3337
#define TreeView_SetImageList(hwnd, himl, iImage)
Definition: commctrl.h:3414
#define TreeView_DeleteItem(hwnd, hitem)
Definition: commctrl.h:3382
void TreeView_Set3StateCheck(HWND hTree)
Definition: treeview.c:24
TVITEMEXW itemex
Definition: commctrl.h:3363
#define TVIF_INTEGRAL
Definition: commctrl.h:3241
#define OP(a, b)
#define INDEXTOSTATEIMAGEMASK(i)
Definition: commctrl.h:2298
#define RGB(r, g, b)
Definition: wingdi.h:2917
unsigned int UINT
Definition: ndis.h:50
static HWND hTree
Definition: systempage.cpp:52
unsigned long DWORD
Definition: ntddk_ex.h:95
#define TVS_CHECKBOXES
Definition: commctrl.h:3222
void TreeView_UpItem(HWND hTree, HTREEITEM htiItemToUp)
Definition: treeview.c:204
int cchTextMax
Definition: commctrl.h:3318
static const WCHAR L[]
Definition: oid.c:1087
#define TreeView_SetItemState(hwndTV, hti, data, _mask)
Definition: commctrl.h:3559
const DOCKBAR PVOID HWND hParent
Definition: tooldock.h:22
#define TreeView_GetParent(hwnd, hitem)
Definition: commctrl.h:3436
static stack_node_t temp
Definition: rpn.c:18
uint8_t label[11]
Definition: fsck.fat.h:65
#define TVIF_HANDLE
Definition: commctrl.h:3237
#define GWL_STYLE
Definition: winuser.h:846
HTREEITEM hItem
Definition: commctrl.h:3314
HINSTANCE hInst
Definition: dxdiag.c:13
#define TreeView_GetRoot(hwnd)
Definition: commctrl.h:3442
#define TVIF_TEXT
Definition: commctrl.h:3233
#define TreeView_SelectItem(hwnd, hitem)
Definition: commctrl.h:3448
UINT TreeView_GetRealSubtreeState(HWND hTree, HTREEITEM htiSubtreeItem)
Definition: treeview.c:111
#define ImageList_LoadBitmap(hi, lpbmp, cx, cGrow, crMask)
Definition: commctrl.h:543
#define TVIF_IMAGE
Definition: commctrl.h:3234
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
static const WCHAR szName[]
Definition: msipriv.h:1194
HTREEITEM TreeView_GetNext(HWND hTree, HTREEITEM hItem)
Definition: treeview.c:263
void TreeView_DownItem(HWND hTree, HTREEITEM htiItemToDown)
Definition: treeview.c:186
#define TVIF_STATE
Definition: commctrl.h:3236
#define TVSIL_STATE
Definition: commctrl.h:3411
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
#define TVIF_PARAM
Definition: commctrl.h:3235
#define GetWindowLongPtr
Definition: treelist.c:73
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define TreeView_GetPrevSibling(hwnd, hitem)
Definition: commctrl.h:3435
HTREEITEM TreeView_GetFirst(HWND hTree)
Definition: treeview.c:224
HTREEITEM TreeView_GetLastFromItem(HWND hTree, HTREEITEM hItem)
Definition: treeview.c:229
#define TreeView_GetItem(hwnd, pitem)
Definition: commctrl.h:3457
#define TVIS_STATEIMAGEMASK
Definition: commctrl.h:3255
#define IDB_2K3CHECK
Definition: resource.h:151