ReactOS  0.4.12-dev-75-g00dd17e
treeview.c
Go to the documentation of this file.
1 /*
2  * Regedit treeview
3  *
4  * Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "regedit.h"
22 
23 /* Global variables and constants */
24 /* Image_Open, Image_Closed, and Image_Root - integer variables for indexes of the images. */
25 /* CX_ICON and CY_ICON - width and height of an icon. */
26 /* NUM_ICON - number of icons to add to the image list. */
27 static int Image_Open = 0;
28 static int Image_Closed = 0;
29 static int Image_Root = 0;
30 
32 
33 #define NUM_ICONS 3
34 
35 static BOOL get_item_path(HWND hwndTV, HTREEITEM hItem, HKEY* phKey, LPWSTR* pKeyPath, int* pPathLen, int* pMaxLen)
36 {
37  TVITEMW item;
38  size_t maxLen, len;
39  LPWSTR newStr;
40 
41  item.mask = TVIF_PARAM;
42  item.hItem = hItem;
43  if (!TreeView_GetItem(hwndTV, &item)) return FALSE;
44 
45  if (item.lParam)
46  {
47  /* found root key with valid key value */
48  *phKey = (HKEY)item.lParam;
49  return TRUE;
50  }
51 
52  if(!get_item_path(hwndTV, TreeView_GetParent(hwndTV, hItem), phKey, pKeyPath, pPathLen, pMaxLen)) return FALSE;
53  if (*pPathLen)
54  {
55  (*pKeyPath)[*pPathLen] = L'\\';
56  ++(*pPathLen);
57  }
58 
59  do
60  {
61  item.mask = TVIF_TEXT;
62  item.hItem = hItem;
63  item.pszText = *pKeyPath + *pPathLen;
64  maxLen = *pMaxLen - *pPathLen;
65  item.cchTextMax = (int) maxLen;
66  if (!TreeView_GetItem(hwndTV, &item)) return FALSE;
67  len = wcslen(item.pszText);
68  if (len < maxLen - 1)
69  {
70  *pPathLen += (int) len;
71  break;
72  }
73  newStr = HeapReAlloc(GetProcessHeap(), 0, *pKeyPath, *pMaxLen * 2);
74  if (!newStr) return FALSE;
75  *pKeyPath = newStr;
76  *pMaxLen *= 2;
77  }
78  while(TRUE);
79 
80  return TRUE;
81 }
82 
84 {
85  int pathLen = 0, maxLen;
86 
87  *phRootKey = NULL;
88  if (!pathBuffer) pathBuffer = HeapAlloc(GetProcessHeap(), 0, 1024);
89  if (!pathBuffer) return NULL;
90  *pathBuffer = 0;
91  maxLen = (int) HeapSize(GetProcessHeap(), 0, pathBuffer);
92  if (maxLen == -1) return NULL;
93  if (!hItem) hItem = TreeView_GetSelection(hwndTV);
94  if (!hItem) return NULL;
95  if (!get_item_path(hwndTV, hItem, phRootKey, &pathBuffer, &pathLen, &maxLen))
96  {
97  return NULL;
98  }
99  return pathBuffer;
100 }
101 
103 {
104  if (!hItem) hItem = TreeView_GetSelection(hwndTV);
105  if (!hItem) return FALSE;
106  return TreeView_DeleteItem(hwndTV, hItem);
107 }
108 
109 /* Add an entry to the tree. Only give hKey for root nodes (HKEY_ constants) */
110 static HTREEITEM AddEntryToTree(HWND hwndTV, HTREEITEM hParent, LPWSTR label, HKEY hKey, DWORD dwChildren)
111 {
112  TVITEMW tvi;
113  TVINSERTSTRUCTW tvins;
114 
115  if (hKey)
116  {
117  if (RegQueryInfoKeyW(hKey, 0, 0, 0, &dwChildren, 0, 0, 0, 0, 0, 0, 0) != ERROR_SUCCESS)
118  {
119  dwChildren = 0;
120  }
121  }
122 
124  tvi.pszText = label;
125  tvi.cchTextMax = wcslen(tvi.pszText);
126  tvi.iImage = Image_Closed;
128  tvi.cChildren = dwChildren;
129  tvi.lParam = (LPARAM)hKey;
130  tvins.item = tvi;
131  tvins.hInsertAfter = (HTREEITEM)(hKey ? TVI_LAST : TVI_FIRST);
132  tvins.hParent = hParent;
133  return TreeView_InsertItem(hwndTV, &tvins);
134 }
135 
137 {
138  HKEY hRoot, hKey, hSubKey;
139  HTREEITEM childItem;
140  LPCWSTR KeyPath;
141  DWORD dwCount, dwIndex, dwMaxSubKeyLen;
142  LPWSTR Name = NULL;
143  TVITEMW tvItem;
144  LPWSTR pszNodes = NULL;
145  BOOL bSuccess = FALSE;
146  LPWSTR s;
147  BOOL bAddedAny;
148 
149  KeyPath = GetItemPath(hwndTV, hItem, &hRoot);
150 
151  if (*KeyPath)
152  {
153  if (RegOpenKeyExW(hRoot, KeyPath, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
154  {
155  goto done;
156  }
157  }
158  else
159  {
160  hKey = hRoot;
161  }
162 
163  if (RegQueryInfoKeyW(hKey, 0, 0, 0, &dwCount, &dwMaxSubKeyLen, 0, 0, 0, 0, 0, 0) != ERROR_SUCCESS)
164  {
165  goto done;
166  }
167 
168  /* Set the number of children again */
169  tvItem.mask = TVIF_CHILDREN;
170  tvItem.hItem = hItem;
171  tvItem.cChildren = dwCount;
172  if (!TreeView_SetItem(hwndTV, &tvItem))
173  {
174  goto done;
175  }
176 
177  /* We don't have to bother with the rest if it's not expanded. */
178  if (TreeView_GetItemState(hwndTV, hItem, TVIS_EXPANDED) == 0)
179  {
180  RegCloseKey(hKey);
181  bSuccess = TRUE;
182  goto done;
183  }
184 
185  dwMaxSubKeyLen++; /* account for the \0 terminator */
186  if (!(Name = HeapAlloc(GetProcessHeap(), 0, dwMaxSubKeyLen * sizeof(WCHAR))))
187  {
188  goto done;
189  }
190  tvItem.cchTextMax = dwMaxSubKeyLen;
191  /*if (!(tvItem.pszText = HeapAlloc(GetProcessHeap(), 0, dwMaxSubKeyLen * sizeof(WCHAR)))) {
192  goto done;
193  }*/
194 
195  /* Get all of the tree node siblings in one contiguous block of memory */
196  {
197  DWORD dwPhysicalSize = 0;
198  DWORD dwActualSize = 0;
199  DWORD dwNewPhysicalSize;
200  LPWSTR pszNewNodes;
201  DWORD dwStep = 10000;
202 
203  for (childItem = TreeView_GetChild(hwndTV, hItem); childItem;
204  childItem = TreeView_GetNextSibling(hwndTV, childItem))
205  {
206 
207  if (dwActualSize + dwMaxSubKeyLen + 1 > dwPhysicalSize)
208  {
209  dwNewPhysicalSize = dwActualSize + dwMaxSubKeyLen + 1 + dwStep;
210 
211  if (pszNodes)
212  pszNewNodes = (LPWSTR) HeapReAlloc(GetProcessHeap(), 0, pszNodes, dwNewPhysicalSize * sizeof(WCHAR));
213  else
214  pszNewNodes = (LPWSTR) HeapAlloc(GetProcessHeap(), 0, dwNewPhysicalSize * sizeof(WCHAR));
215  if (!pszNewNodes)
216  goto done;
217 
218  dwPhysicalSize = dwNewPhysicalSize;
219  pszNodes = pszNewNodes;
220  }
221 
222  tvItem.mask = TVIF_TEXT;
223  tvItem.hItem = childItem;
224  tvItem.pszText = &pszNodes[dwActualSize];
225  tvItem.cchTextMax = dwPhysicalSize - dwActualSize;
226  if (!TreeView_GetItem(hwndTV, &tvItem))
227  goto done;
228 
229  dwActualSize += (DWORD) wcslen(&pszNodes[dwActualSize]) + 1;
230  }
231 
232  if (pszNodes)
233  pszNodes[dwActualSize] = L'\0';
234  }
235 
236  /* Now go through all the children in the tree, and check if any have to be removed. */
237  childItem = TreeView_GetChild(hwndTV, hItem);
238  while (childItem)
239  {
240  HTREEITEM nextItem = TreeView_GetNextSibling(hwndTV, childItem);
241  if (RefreshTreeItem(hwndTV, childItem) == FALSE)
242  {
243  (void)TreeView_DeleteItem(hwndTV, childItem);
244  }
245  childItem = nextItem;
246  }
247 
248  /* Now go through all the children in the registry, and check if any have to be added. */
249  bAddedAny = FALSE;
250  for (dwIndex = 0; dwIndex < dwCount; dwIndex++)
251  {
252  DWORD cName = dwMaxSubKeyLen, dwSubCount;
253  BOOL found;
254 
255  found = FALSE;
256  if (RegEnumKeyExW(hKey, dwIndex, Name, &cName, 0, 0, 0, NULL) != ERROR_SUCCESS)
257  {
258  continue;
259  }
260 
261  /* Check if the node is already in there. */
262  if (pszNodes)
263  {
264  for (s = pszNodes; *s; s += wcslen(s) + 1)
265  {
266  if (!wcscmp(s, Name))
267  {
268  found = TRUE;
269  break;
270  }
271  }
272  }
273 
274  if (found == FALSE)
275  {
276  /* Find the number of children of the node. */
277  dwSubCount = 0;
278  if (RegOpenKeyExW(hKey, Name, 0, KEY_QUERY_VALUE, &hSubKey) == ERROR_SUCCESS)
279  {
280  if (RegQueryInfoKeyW(hSubKey, 0, 0, 0, &dwSubCount, 0, 0, 0, 0, 0, 0, 0) != ERROR_SUCCESS)
281  {
282  dwSubCount = 0;
283  }
284  RegCloseKey(hSubKey);
285  }
286 
287  AddEntryToTree(hwndTV, hItem, Name, NULL, dwSubCount);
288  bAddedAny = TRUE;
289  }
290  }
291  RegCloseKey(hKey);
292 
293  if (bAddedAny)
294  SendMessageW(hwndTV, TVM_SORTCHILDREN, 0, (LPARAM) hItem);
295 
296  bSuccess = TRUE;
297 
298 done:
299  if (pszNodes)
300  HeapFree(GetProcessHeap(), 0, pszNodes);
301  if (Name)
302  HeapFree(GetProcessHeap(), 0, Name);
303  return bSuccess;
304 }
305 
307 {
309  HTREEITEM hSelectedItem;
310  HCURSOR hcursorOld;
311 
312  hSelectedItem = TreeView_GetSelection(hwndTV);
313  hcursorOld = SetCursor(LoadCursor(NULL, IDC_WAIT));
314  SendMessageW(hwndTV, WM_SETREDRAW, FALSE, 0);
315 
316  hItem = TreeView_GetChild(hwndTV, TreeView_GetRoot(hwndTV));
317  while (hItem)
318  {
319  RefreshTreeItem(hwndTV, hItem);
320  hItem = TreeView_GetNextSibling(hwndTV, hItem);
321  }
322 
323  SendMessageW(hwndTV, WM_SETREDRAW, TRUE, 0);
324  SetCursor(hcursorOld);
325 
326  /* We reselect the currently selected node, this will prompt a refresh of the listview. */
327  (void)TreeView_SelectItem(hwndTV, hSelectedItem);
328  return TRUE;
329 }
330 
332 {
334  HTREEITEM hNewItem = 0;
335  TVITEMEXW item;
336 
337  /* Default to the current selection */
338  if (!hItem)
339  {
340  hItem = TreeView_GetSelection(hwndTV);
341  if (!hItem)
342  return FALSE;
343  }
344 
345  memset(&item, 0, sizeof(item));
346  item.hItem = hItem;
348  if (!TreeView_GetItem(hwndTV, &item))
349  return FALSE;
350 
351  if ((item.state & TVIS_EXPANDEDONCE) && (item.cChildren > 0))
352  {
353  hNewItem = AddEntryToTree(hwndTV, hItem, name, 0, 0);
354  SendMessageW(hwndTV, TVM_SORTCHILDREN, 0, (LPARAM) hItem);
355  }
356  else
357  {
358  item.mask = TVIF_CHILDREN | TVIF_HANDLE;
359  item.hItem = hItem;
360  item.cChildren = 1;
361  if (!TreeView_SetItem(hwndTV, &item))
362  return FALSE;
363  }
364 
365  (void)TreeView_Expand(hwndTV, hItem, TVE_EXPAND);
366  if (!hNewItem)
367  {
368  for(hNewItem = TreeView_GetChild(hwndTV, hItem); hNewItem; hNewItem = TreeView_GetNextSibling(hwndTV, hNewItem))
369  {
370  item.mask = TVIF_HANDLE | TVIF_TEXT;
371  item.hItem = hNewItem;
372  item.pszText = buf;
373  item.cchTextMax = COUNT_OF(buf);
374  if (!TreeView_GetItem(hwndTV, &item)) continue;
375  if (wcscmp(name, item.pszText) == 0) break;
376  }
377  }
378  if (hNewItem) (void)TreeView_SelectItem(hwndTV, hNewItem);
379 
380  return hNewItem;
381 }
382 
384 {
386 
387  if(!(hItem = TreeView_GetSelection(hwndTV))) return 0;
388  return TreeView_EditLabel(hwndTV, hItem);
389 }
390 
391 static BOOL InitTreeViewItems(HWND hwndTV, LPWSTR pHostName)
392 {
393  TVITEMW tvi;
394  TVINSERTSTRUCTW tvins;
396 
398  /* Set the text of the item. */
399  tvi.pszText = pHostName;
400  tvi.cchTextMax = wcslen(tvi.pszText);
401  /* Assume the item is not a parent item, so give it an image. */
402  tvi.iImage = Image_Root;
404  tvi.cChildren = 5;
405  /* Save the heading level in the item's application-defined data area. */
406  tvi.lParam = (LPARAM)NULL;
407  tvins.item = tvi;
409  tvins.hParent = TVI_ROOT;
410  /* Add the item to the tree view control. */
411  if (!(hRoot = TreeView_InsertItem(hwndTV, &tvins))) return FALSE;
412 
413  if (!AddEntryToTree(hwndTV, hRoot, L"HKEY_CLASSES_ROOT", HKEY_CLASSES_ROOT, 1)) return FALSE;
414  if (!AddEntryToTree(hwndTV, hRoot, L"HKEY_CURRENT_USER", HKEY_CURRENT_USER, 1)) return FALSE;
415  if (!AddEntryToTree(hwndTV, hRoot, L"HKEY_LOCAL_MACHINE", HKEY_LOCAL_MACHINE, 1)) return FALSE;
416  if (!AddEntryToTree(hwndTV, hRoot, L"HKEY_USERS", HKEY_USERS, 1)) return FALSE;
417  if (!AddEntryToTree(hwndTV, hRoot, L"HKEY_CURRENT_CONFIG", HKEY_CURRENT_CONFIG, 1)) return FALSE;
418 
419  if (GetVersion() & 0x80000000)
420  {
421  /* Win9x specific key */
422  if (!AddEntryToTree(hwndTV, hRoot, L"HKEY_DYN_DATA", HKEY_DYN_DATA, 1)) return FALSE;
423  }
424 
425  /* expand and select host name */
426  (void)TreeView_Expand(hwndTV, hRoot, TVE_EXPAND);
427  (void)TreeView_Select(hwndTV, hRoot, TVGN_CARET);
428  return TRUE;
429 }
430 
431 
432 /*
433  * InitTreeViewImageLists - creates an image list, adds three bitmaps
434  * to it, and associates the image list with a tree view control.
435  * Returns TRUE if successful, or FALSE otherwise.
436  * hwndTV - handle to the tree view control.
437  */
439 {
440  HIMAGELIST himl; /* handle to image list */
441  HICON hico; /* handle to icon */
442 
443  /* Create the image list. */
447  0,
448  NUM_ICONS)) == NULL)
449  {
450  return FALSE;
451  }
452 
453  /* Add the open file, closed file, and document bitmaps. */
454  hico = LoadImageW(hInst,
456  IMAGE_ICON,
459  0);
460  if (hico)
461  {
462  Image_Open = ImageList_AddIcon(himl, hico);
463  DestroyIcon(hico);
464  }
465 
466  hico = LoadImageW(hInst,
468  IMAGE_ICON,
471  0);
472  if (hico)
473  {
474  Image_Closed = ImageList_AddIcon(himl, hico);
475  DestroyIcon(hico);
476  }
477 
478  hico = LoadImageW(hInst,
480  IMAGE_ICON,
483  0);
484  if (hico)
485  {
486  Image_Root = ImageList_AddIcon(himl, hico);
487  DestroyIcon(hico);
488  }
489 
490  /* Fail if not all of the images were added. */
492  {
493  ImageList_Destroy(himl);
494  return FALSE;
495  }
496 
497  /* Associate the image list with the tree view control. */
498  (void)TreeView_SetImageList(hwndTV, himl, TVSIL_NORMAL);
499 
500  return TRUE;
501 }
502 
504 {
505  DWORD dwCount, dwIndex, dwMaxSubKeyLen;
506  HKEY hRoot, hNewKey, hKey;
507  LPCWSTR keyPath;
508  LPWSTR Name;
509  LONG errCode;
510  HCURSOR hcursorOld;
511 
512  static int expanding;
513  if (expanding) return FALSE;
514  if (pnmtv->itemNew.state & TVIS_EXPANDEDONCE )
515  {
516  return TRUE;
517  }
518  expanding = TRUE;
519  hcursorOld = SetCursor(LoadCursor(NULL, IDC_WAIT));
520  SendMessageW(hwndTV, WM_SETREDRAW, FALSE, 0);
521 
522  keyPath = GetItemPath(hwndTV, pnmtv->itemNew.hItem, &hRoot);
523  if (!keyPath) goto done;
524 
525  if (*keyPath)
526  {
527  errCode = RegOpenKeyExW(hRoot, keyPath, 0, KEY_READ, &hNewKey);
528  if (errCode != ERROR_SUCCESS) goto done;
529  }
530  else
531  {
532  hNewKey = hRoot;
533  }
534 
535  errCode = RegQueryInfoKeyW(hNewKey, 0, 0, 0, &dwCount, &dwMaxSubKeyLen, 0, 0, 0, 0, 0, 0);
536  if (errCode != ERROR_SUCCESS) goto done;
537  dwMaxSubKeyLen++; /* account for the \0 terminator */
538  Name = HeapAlloc(GetProcessHeap(), 0, dwMaxSubKeyLen * sizeof(WCHAR));
539  if (!Name) goto done;
540 
541  for (dwIndex = 0; dwIndex < dwCount; dwIndex++)
542  {
543  DWORD cName = dwMaxSubKeyLen, dwSubCount;
544 
545  errCode = RegEnumKeyExW(hNewKey, dwIndex, Name, &cName, 0, 0, 0, 0);
546  if (errCode != ERROR_SUCCESS) continue;
547  errCode = RegOpenKeyExW(hNewKey, Name, 0, KEY_QUERY_VALUE, &hKey);
548  if (errCode == ERROR_SUCCESS)
549  {
550  errCode = RegQueryInfoKeyW(hKey, 0, 0, 0, &dwSubCount, 0, 0, 0, 0, 0, 0, 0);
551  RegCloseKey(hKey);
552  }
553  if (errCode != ERROR_SUCCESS) dwSubCount = 0;
554  AddEntryToTree(hwndTV, pnmtv->itemNew.hItem, Name, NULL, dwSubCount);
555  }
556 
557  SendMessageW(hwndTV, TVM_SORTCHILDREN, 0, (LPARAM)pnmtv->itemNew.hItem);
558 
559  RegCloseKey(hNewKey);
560  HeapFree(GetProcessHeap(), 0, Name);
561 
562 done:
563  SendMessageW(hwndTV, WM_SETREDRAW, TRUE, 0);
564  SetCursor(hcursorOld);
565  expanding = FALSE;
566 
567  return TRUE;
568 }
569 
570 
572 {
573  WCHAR szNewKeyFormat[128];
574  WCHAR szNewKey[128];
575  LPCWSTR pszKeyPath;
576  int iIndex = 1;
577  LONG nResult;
578  HKEY hRootKey = NULL, hKey = NULL, hNewKey = NULL;
579  BOOL bSuccess = FALSE;
580  DWORD dwDisposition;
581  HTREEITEM hNewItem;
582 
583  pszKeyPath = GetItemPath(hwndTV, hItem, &hRootKey);
584  if (pszKeyPath[0] == L'\0')
585  hKey = hRootKey;
586  else if (RegOpenKeyW(hRootKey, pszKeyPath, &hKey) != ERROR_SUCCESS)
587  goto done;
588 
589  if (LoadStringW(hInst, IDS_NEW_KEY, szNewKeyFormat, COUNT_OF(szNewKeyFormat)) <= 0)
590  goto done;
591 
592  /* Need to create a new key with a unique name */
593  do
594  {
595  wsprintf(szNewKey, szNewKeyFormat, iIndex++);
596  nResult = RegCreateKeyExW(hKey, szNewKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hNewKey, &dwDisposition);
597  if (hNewKey && dwDisposition == REG_OPENED_EXISTING_KEY)
598  {
599  RegCloseKey(hNewKey);
600  hNewKey = NULL;
601  }
602  else if (!hNewKey)
603  {
604  InfoMessageBox(hFrameWnd, MB_OK | MB_ICONERROR, NULL, L"Cannot create new key!\n\nError Code: %d", nResult);
605  goto done;
606  }
607  }
608  while(!hNewKey);
609 
610  /* Insert the new key */
611  hNewItem = InsertNode(hwndTV, hItem, szNewKey);
612  if (!hNewItem)
613  goto done;
614 
615  /* The new key's name is probably not appropriate yet */
616  (void)TreeView_EditLabel(hwndTV, hNewItem);
617 
618  bSuccess = TRUE;
619 
620 done:
621  if (hKey != hRootKey && hKey)
622  RegCloseKey(hKey);
623  if (hNewKey)
624  RegCloseKey(hNewKey);
625  return bSuccess;
626 }
627 
628 
629 /*
630  * CreateTreeView - creates a tree view control.
631  * Returns the handle to the new control if successful, or NULL otherwise.
632  * hwndParent - handle to the control's parent window.
633  */
635 {
636  RECT rcClient;
637  HWND hwndTV;
638 
639  /* Get the dimensions of the parent window's client area, and create the tree view control. */
640  GetClientRect(hwndParent, &rcClient);
643  0, 0, rcClient.right, rcClient.bottom,
644  hwndParent, id, hInst, NULL);
645  /* Initialize the image list, and add items to the control. */
646  if (!InitTreeViewImageLists(hwndTV) || !InitTreeViewItems(hwndTV, pHostName))
647  {
648  DestroyWindow(hwndTV);
649  return NULL;
650  }
651  return hwndTV;
652 }
653 
654 void DestroyTreeView(HWND hwndTV)
655 {
657 
659 
660  /* Destroy the image list associated with the tree view control */
661  himl = TreeView_GetImageList(hwndTV, TVSIL_NORMAL);
662  if (himl) ImageList_Destroy(himl);
663 }
664 
665 BOOL SelectNode(HWND hwndTV, LPCWSTR keyPath)
666 {
668  HTREEITEM hChildItem;
669  WCHAR szPathPart[128];
670  WCHAR szBuffer[128];
671  LPCWSTR s;
672  TVITEMW tvi;
673 
674  /* Load "My Computer" string... */
675  LoadStringW(hInst, IDS_MY_COMPUTER, szBuffer, COUNT_OF(szBuffer));
676  wcscat(szBuffer, L"\\");
677 
678  /* ... and remove it from the key path */
679  if (!_wcsnicmp(keyPath, szBuffer, wcslen(szBuffer)))
680  keyPath += wcslen(szBuffer);
681 
682  /* Reinitialize szBuffer */
683  szBuffer[0] = L'\0';
684 
685  hRoot = TreeView_GetRoot(hwndTV);
686  hItem = hRoot;
687 
688  while(keyPath[0])
689  {
690  s = wcschr(keyPath, L'\\');
691  lstrcpynW(szPathPart, keyPath, s ? s - keyPath + 1 : wcslen(keyPath) + 1);
692 
693  /* Special case for root to expand root key abbreviations */
694  if (hItem == hRoot)
695  {
696  if (!_wcsicmp(szPathPart, L"HKCR"))
697  wcscpy(szPathPart, L"HKEY_CLASSES_ROOT");
698  else if (!_wcsicmp(szPathPart, L"HKCU"))
699  wcscpy(szPathPart, L"HKEY_CURRENT_USER");
700  else if (!_wcsicmp(szPathPart, L"HKLM"))
701  wcscpy(szPathPart, L"HKEY_LOCAL_MACHINE");
702  else if (!_wcsicmp(szPathPart, L"HKU"))
703  wcscpy(szPathPart, L"HKEY_USERS");
704  else if (!_wcsicmp(szPathPart, L"HKCC"))
705  wcscpy(szPathPart, L"HKEY_CURRENT_CONFIG");
706  else if (!_wcsicmp(szPathPart, L"HKDD"))
707  wcscpy(szPathPart, L"HKEY_DYN_DATA");
708  }
709 
710  for (hChildItem = TreeView_GetChild(hwndTV, hItem); hChildItem;
711  hChildItem = TreeView_GetNextSibling(hwndTV, hChildItem))
712  {
713  memset(&tvi, 0, sizeof(tvi));
714  tvi.hItem = hChildItem;
715  tvi.mask = TVIF_TEXT | TVIF_CHILDREN;
716  tvi.pszText = szBuffer;
717  tvi.cchTextMax = COUNT_OF(szBuffer);
718 
719  (void)TreeView_GetItem(hwndTV, &tvi);
720 
721  if (!_wcsicmp(szBuffer, szPathPart))
722  break;
723  }
724 
725  if (!hChildItem)
726  return FALSE;
727 
728  if (tvi.cChildren > 0)
729  {
730  if (!TreeView_Expand(hwndTV, hChildItem, TVE_EXPAND))
731  return FALSE;
732  }
733 
734  keyPath = s ? s + 1 : L"";
735  hItem = hChildItem;
736  }
737 
738  (void)TreeView_SelectItem(hwndTV, hItem);
739  (void)TreeView_EnsureVisible(hwndTV, hItem);
740 
741  return TRUE;
742 }
743 
744 /* EOF */
#define HKEY_USERS
Definition: winreg.h:13
INT WINAPI ImageList_GetImageCount(HIMAGELIST himl)
Definition: imagelist.c:1967
static LPWSTR pathBuffer
Definition: treeview.c:31
BOOL OnTreeExpanding(HWND hwndTV, NMTREEVIEW *pnmtv)
Definition: treeview.c:503
int cchTextMax
Definition: commctrl.h:3288
static HICON
Definition: imagelist.c:84
#define TRUE
Definition: types.h:120
#define IMAGE_ICON
Definition: winuser.h:212
BOOL SelectNode(HWND hwndTV, LPCWSTR keyPath)
Definition: treeview.c:665
HTREEITEM hParent
Definition: commctrl.h:3360
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:47
#define ERROR_SUCCESS
Definition: deptool.c:10
static BOOL InitTreeViewItems(HWND hwndTV, LPWSTR pHostName)
Definition: treeview.c:391
#define TVM_SORTCHILDREN
Definition: commctrl.h:3508
#define TVGN_CARET
Definition: commctrl.h:3428
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
BOOL WINAPI DestroyIcon(_In_ HICON)
Definition: cursoricon.c:2022
#define KEY_READ
Definition: nt_native.h:1023
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define DWORD
Definition: msvc.h:34
int iImage
Definition: commctrl.h:3289
#define TreeView_EditLabel(hwnd, hitem)
Definition: commctrl.h:3471
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define TreeView_GetChild(hwnd, hitem)
Definition: commctrl.h:3433
#define TVS_LINESATROOT
Definition: commctrl.h:3216
LPWSTR pszText
Definition: commctrl.h:3317
struct _TREEITEM * HTREEITEM
Definition: commctrl.h:3231
#define WM_SETREDRAW
Definition: winuser.h:1598
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
LPARAM lParam
Definition: commctrl.h:3292
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
BOOL RefreshTreeView(HWND hwndTV)
Definition: treeview.c:306
#define SM_CYSMICON
Definition: winuser.h:1003
int InfoMessageBox(HWND hWnd, UINT uType, LPCWSTR lpTitle, LPCWSTR lpMessage,...)
Definition: error.c:51
#define HKEY_DYN_DATA
Definition: winreg.h:16
#define TVIS_EXPANDEDONCE
Definition: commctrl.h:3252
#define WS_CHILD
Definition: pedump.c:617
#define REG_OPENED_EXISTING_KEY
Definition: nt_native.h:1085
#define TreeView_GetNextSibling(hwnd, hitem)
Definition: commctrl.h:3434
#define TVIF_SELECTEDIMAGE
Definition: commctrl.h:3238
HICON HCURSOR
Definition: windef.h:289
UINT mask
Definition: commctrl.h:3283
#define HKEY_CURRENT_CONFIG
Definition: winreg.h:15
#define WCHAR
Definition: msvc.h:43
LONG right
Definition: windef.h:298
HIMAGELIST himl
BOOL WINAPI DestroyWindow(_In_ HWND)
LPWSTR pszText
Definition: commctrl.h:3287
SIZE_T WINAPI HeapSize(HANDLE, DWORD, LPCVOID)
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
void DestroyTreeView(HWND hwndTV)
Definition: treeview.c:654
static BOOLEAN bSuccess
Definition: drive.cpp:417
#define TreeView_GetImageList(hwnd, iImage)
Definition: commctrl.h:3408
DWORD WINAPI GetVersion(VOID)
Definition: version.c:22
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1094
#define lstrcpynW
Definition: compat.h:397
static BOOL get_item_path(HWND hwndTV, HTREEITEM hItem, HKEY *phKey, LPWSTR *pKeyPath, int *pPathLen, int *pMaxLen)
Definition: treeview.c:35
BOOL WINAPI ImageList_Destroy(HIMAGELIST himl)
Definition: imagelist.c:893
#define ILC_COLOR32
Definition: commctrl.h:343
static HTREEITEM AddEntryToTree(HWND hwndTV, HTREEITEM hParent, LPWSTR label, HKEY hKey, DWORD dwChildren)
Definition: treeview.c:110
#define IDS_NEW_KEY
Definition: resource.h:191
#define TreeView_InsertItem(hwnd, lpis)
Definition: commctrl.h:3379
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
HIMAGELIST WINAPI ImageList_Create(INT cx, INT cy, UINT flags, INT cInitial, INT cGrow)
Definition: imagelist.c:769
#define TVIF_CHILDREN
Definition: commctrl.h:3239
HTREEITEM InsertNode(HWND hwndTV, HTREEITEM hItem, LPWSTR name)
Definition: treeview.c:331
HTREEITEM hInsertAfter
Definition: commctrl.h:3361
HANDLE WINAPI LoadImageW(_In_opt_ HINSTANCE, _In_ LPCWSTR, _In_ UINT, _In_ int, _In_ int, _In_ UINT)
Definition: cursoricon.c:2172
long LONG
Definition: pedump.c:60
#define NMTREEVIEW
Definition: commctrl.h:3609
LONG_PTR LPARAM
Definition: windef.h:208
static HTREEITEM hRoot
Definition: treeview.c:381
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3311
#define TVS_HASBUTTONS
Definition: commctrl.h:3214
static int Image_Closed
Definition: treeview.c:28
struct NameRec_ * Name
Definition: cdprocs.h:464
#define TVI_FIRST
Definition: commctrl.h:3336
HTREEITEM hItem
Definition: treelist.h:37
smooth NULL
Definition: ftsmooth.c:416
static HWND hwndParent
Definition: cryptui.c:300
#define IDC_WAIT
Definition: winuser.h:684
HWND CreateTreeView(HWND hwndParent, LPWSTR pHostName, HMENU id)
Definition: treeview.c:634
static int Image_Open
Definition: treeview.c:27
#define TVI_LAST
Definition: commctrl.h:3337
int cChildren
Definition: commctrl.h:3291
#define TreeView_SetImageList(hwnd, himl, iImage)
Definition: commctrl.h:3414
#define TreeView_DeleteItem(hwnd, hitem)
Definition: commctrl.h:3382
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define KEY_WRITE
Definition: nt_native.h:1031
static int Image_Root
Definition: treeview.c:29
#define COUNT_OF(a)
Definition: main.h:33
#define TreeView_GetSelection(hwnd)
Definition: commctrl.h:3440
unsigned int BOOL
Definition: ntddk_ex.h:94
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
#define WC_TREEVIEW
Definition: commctrl.h:3212
#define IDI_CLOSED_FILE
Definition: resource.h:43
HANDLE HKEY
Definition: registry.h:24
#define TreeView_GetItemState(hwndTV, hti, mask)
Definition: commctrl.h:3562
BOOL RefreshTreeItem(HWND hwndTV, HTREEITEM hItem)
Definition: treeview.c:136
int WINAPI GetSystemMetrics(_In_ int)
unsigned long DWORD
Definition: ntddk_ex.h:95
#define IDS_MY_COMPUTER
Definition: resource.h:131
INT WINAPI ImageList_AddIcon(HIMAGELIST himl, HICON hIcon)
Definition: imagelist.c:505
HICON hico
LONG WINAPI RegQueryInfoKeyW(HKEY hKey, LPWSTR lpClass, LPDWORD lpcClass, LPDWORD lpReserved, LPDWORD lpcSubKeys, LPDWORD lpcMaxSubKeyLen, LPDWORD lpcMaxClassLen, LPDWORD lpcValues, LPDWORD lpcMaxValueNameLen, LPDWORD lpcMaxValueLen, LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime)
Definition: reg.c:3704
#define TVE_EXPAND
Definition: commctrl.h:3390
#define TVI_ROOT
Definition: commctrl.h:3335
#define SM_CXSMICON
Definition: winuser.h:1002
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
int cchTextMax
Definition: commctrl.h:3318
static const WCHAR L[]
Definition: oid.c:1087
HWND WINAPI CreateWindowExW(_In_ DWORD dwExStyle, _In_opt_ LPCWSTR lpClassName, _In_opt_ LPCWSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
#define MB_ICONERROR
Definition: winuser.h:781
const DOCKBAR PVOID HWND hParent
Definition: tooldock.h:22
#define ILC_MASK
Definition: commctrl.h:336
GLenum GLsizei len
Definition: glext.h:6722
GLdouble s
Definition: gl.h:2039
#define TreeView_GetParent(hwnd, hitem)
Definition: commctrl.h:3436
#define WS_TABSTOP
Definition: pedump.c:634
uint8_t label[11]
Definition: fsck.fat.h:65
BOOL DeleteNode(HWND hwndTV, HTREEITEM hItem)
Definition: treeview.c:102
#define LoadCursor
Definition: winuser.h:5678
#define TVIF_HANDLE
Definition: commctrl.h:3237
#define TVIS_EXPANDED
Definition: commctrl.h:3251
LPCWSTR GetItemPath(HWND hwndTV, HTREEITEM hItem, HKEY *phRootKey)
Definition: treeview.c:83
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
HWND hFrameWnd
Definition: main.c:30
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
HTREEITEM hItem
Definition: commctrl.h:3314
static BOOL InitTreeViewImageLists(HWND hwndTV)
Definition: treeview.c:438
#define TreeView_EnsureVisible(hwnd, hitem)
Definition: commctrl.h:3512
HINSTANCE hInst
Definition: dxdiag.c:13
static ATOM item
Definition: dde.c:856
#define WS_EX_CLIENTEDGE
Definition: winuser.h:384
#define TreeView_GetRoot(hwnd)
Definition: commctrl.h:3442
HCURSOR WINAPI SetCursor(_In_opt_ HCURSOR)
#define TVIF_TEXT
Definition: commctrl.h:3233
#define TreeView_SelectItem(hwnd, hitem)
Definition: commctrl.h:3448
int iSelectedImage
Definition: commctrl.h:3290
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define IDI_OPEN_FILE
Definition: resource.h:42
#define HeapReAlloc
Definition: compat.h:393
#define TreeView_Select(hwnd, hitem, code)
Definition: commctrl.h:3446
#define TVIF_IMAGE
Definition: commctrl.h:3234
_CRTIMP wchar_t *__cdecl wcscat(_Inout_updates_z_(_String_length_(_Dest)+_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
#define MB_OK
Definition: winuser.h:784
HTREEITEM hItem
Definition: commctrl.h:3284
#define TreeView_SetItem(hwnd, pitem)
Definition: commctrl.h:3464
#define TVS_SHOWSELALWAYS
Definition: commctrl.h:3219
#define IDI_ROOT
Definition: resource.h:44
#define TVS_HASLINES
Definition: commctrl.h:3215
#define TVSIL_NORMAL
Definition: commctrl.h:3410
Definition: name.c:36
HWND StartKeyRename(HWND hwndTV)
Definition: treeview.c:383
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3381
LONG bottom
Definition: windef.h:299
#define TVIF_STATE
Definition: commctrl.h:3236
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
#define TVIF_PARAM
Definition: commctrl.h:3235
LONG WINAPI RegEnumKeyExW(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPWSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPWSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2541
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define wsprintf
Definition: winuser.h:5731
#define NUM_ICONS
Definition: treeview.c:33
#define TreeView_Expand(hwnd, hitem, code)
Definition: commctrl.h:3387
#define WS_VISIBLE
Definition: pedump.c:620
#define memset(x, y, z)
Definition: compat.h:39
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:60
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define HeapFree(x, y, z)
Definition: compat.h:394
#define TreeView_GetItem(hwnd, pitem)
Definition: commctrl.h:3457
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
BOOL CreateNewKey(HWND hwndTV, HTREEITEM hItem)
Definition: treeview.c:571
#define TVS_EDITLABELS
Definition: commctrl.h:3217
#define LPARAM
Definition: msvc.h:38
#define MAX_NEW_KEY_LEN
Definition: main.h:40
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:29
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12