ReactOS  0.4.15-dev-5640-g0dde428
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 /* External resources in shell32.dll */
36 #define IDI_SHELL_FOLDER 4
37 #define IDI_SHELL_FOLDER_OPEN 5
38 #define IDI_SHELL_MY_COMPUTER 16
39 
40 static BOOL get_item_path(HWND hwndTV, HTREEITEM hItem, HKEY* phKey, LPWSTR* pKeyPath, int* pPathLen, int* pMaxLen)
41 {
42  TVITEMW item;
43  size_t maxLen, len;
44  LPWSTR newStr;
45 
46  item.mask = TVIF_PARAM;
47  item.hItem = hItem;
48  if (!TreeView_GetItem(hwndTV, &item)) return FALSE;
49 
50  if (item.lParam)
51  {
52  /* found root key with valid key value */
53  *phKey = (HKEY)item.lParam;
54  return TRUE;
55  }
56 
57  if(!get_item_path(hwndTV, TreeView_GetParent(hwndTV, hItem), phKey, pKeyPath, pPathLen, pMaxLen)) return FALSE;
58  if (*pPathLen)
59  {
60  (*pKeyPath)[*pPathLen] = L'\\';
61  ++(*pPathLen);
62  }
63 
64  do
65  {
66  item.mask = TVIF_TEXT;
67  item.hItem = hItem;
68  item.pszText = *pKeyPath + *pPathLen;
69  maxLen = *pMaxLen - *pPathLen;
70  item.cchTextMax = (int) maxLen;
71  if (!TreeView_GetItem(hwndTV, &item)) return FALSE;
72  len = wcslen(item.pszText);
73  if (len < maxLen - 1)
74  {
75  *pPathLen += (int) len;
76  break;
77  }
78  newStr = HeapReAlloc(GetProcessHeap(), 0, *pKeyPath, *pMaxLen * 2);
79  if (!newStr) return FALSE;
80  *pKeyPath = newStr;
81  *pMaxLen *= 2;
82  }
83  while(TRUE);
84 
85  return TRUE;
86 }
87 
89 {
90  int pathLen = 0, maxLen;
91 
92  *phRootKey = NULL;
93  if (!pathBuffer) pathBuffer = HeapAlloc(GetProcessHeap(), 0, 1024);
94  if (!pathBuffer) return NULL;
95  *pathBuffer = 0;
96  maxLen = (int) HeapSize(GetProcessHeap(), 0, pathBuffer);
97  if (maxLen == -1) return NULL;
98  if (!hItem) hItem = TreeView_GetSelection(hwndTV);
99  if (!hItem) return NULL;
100  if (!get_item_path(hwndTV, hItem, phRootKey, &pathBuffer, &pathLen, &maxLen))
101  {
102  return NULL;
103  }
104  return pathBuffer;
105 }
106 
108 {
109  if (!hItem) hItem = TreeView_GetSelection(hwndTV);
110  if (!hItem) return FALSE;
111  return TreeView_DeleteItem(hwndTV, hItem);
112 }
113 
114 /* Add an entry to the tree. Only give hKey for root nodes (HKEY_ constants) */
115 static HTREEITEM AddEntryToTree(HWND hwndTV, HTREEITEM hParent, LPWSTR label, HKEY hKey, DWORD dwChildren)
116 {
117  TVITEMW tvi;
118  TVINSERTSTRUCTW tvins;
119 
120  if (hKey)
121  {
122  if (RegQueryInfoKeyW(hKey, 0, 0, 0, &dwChildren, 0, 0, 0, 0, 0, 0, 0) != ERROR_SUCCESS)
123  {
124  dwChildren = 0;
125  }
126  }
127 
129  tvi.pszText = label;
130  tvi.cchTextMax = wcslen(tvi.pszText);
131  tvi.iImage = Image_Closed;
133  tvi.cChildren = dwChildren;
134  tvi.lParam = (LPARAM)hKey;
135  tvins.item = tvi;
137  tvins.hParent = hParent;
138  return TreeView_InsertItem(hwndTV, &tvins);
139 }
140 
142 {
143  HKEY hRoot, hKey, hSubKey;
144  HTREEITEM childItem;
145  LPCWSTR KeyPath;
146  DWORD dwCount, dwIndex, dwMaxSubKeyLen;
147  LPWSTR Name = NULL;
148  TVITEMW tvItem;
149  LPWSTR pszNodes = NULL;
150  BOOL bSuccess = FALSE;
151  LPWSTR s;
152  BOOL bAddedAny;
153 
154  KeyPath = GetItemPath(hwndTV, hItem, &hRoot);
155 
156  if (*KeyPath)
157  {
158  if (RegOpenKeyExW(hRoot, KeyPath, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
159  {
160  goto done;
161  }
162  }
163  else
164  {
165  hKey = hRoot;
166  }
167 
168  if (RegQueryInfoKeyW(hKey, 0, 0, 0, &dwCount, &dwMaxSubKeyLen, 0, 0, 0, 0, 0, 0) != ERROR_SUCCESS)
169  {
170  goto done;
171  }
172 
173  /* Set the number of children again */
174  tvItem.mask = TVIF_CHILDREN;
175  tvItem.hItem = hItem;
176  tvItem.cChildren = dwCount;
177  if (!TreeView_SetItem(hwndTV, &tvItem))
178  {
179  goto done;
180  }
181 
182  /* We don't have to bother with the rest if it's not expanded. */
183  if (TreeView_GetItemState(hwndTV, hItem, TVIS_EXPANDED) == 0)
184  {
185  RegCloseKey(hKey);
186  bSuccess = TRUE;
187  goto done;
188  }
189 
190  dwMaxSubKeyLen++; /* account for the \0 terminator */
191  if (!(Name = HeapAlloc(GetProcessHeap(), 0, dwMaxSubKeyLen * sizeof(WCHAR))))
192  {
193  goto done;
194  }
195  tvItem.cchTextMax = dwMaxSubKeyLen;
196  /*if (!(tvItem.pszText = HeapAlloc(GetProcessHeap(), 0, dwMaxSubKeyLen * sizeof(WCHAR)))) {
197  goto done;
198  }*/
199 
200  /* Get all of the tree node siblings in one contiguous block of memory */
201  {
202  DWORD dwPhysicalSize = 0;
203  DWORD dwActualSize = 0;
204  DWORD dwNewPhysicalSize;
205  LPWSTR pszNewNodes;
206  DWORD dwStep = 10000;
207 
208  for (childItem = TreeView_GetChild(hwndTV, hItem); childItem;
209  childItem = TreeView_GetNextSibling(hwndTV, childItem))
210  {
211 
212  if (dwActualSize + dwMaxSubKeyLen + 1 > dwPhysicalSize)
213  {
214  dwNewPhysicalSize = dwActualSize + dwMaxSubKeyLen + 1 + dwStep;
215 
216  if (pszNodes)
217  pszNewNodes = (LPWSTR) HeapReAlloc(GetProcessHeap(), 0, pszNodes, dwNewPhysicalSize * sizeof(WCHAR));
218  else
219  pszNewNodes = (LPWSTR) HeapAlloc(GetProcessHeap(), 0, dwNewPhysicalSize * sizeof(WCHAR));
220  if (!pszNewNodes)
221  goto done;
222 
223  dwPhysicalSize = dwNewPhysicalSize;
224  pszNodes = pszNewNodes;
225  }
226 
227  tvItem.mask = TVIF_TEXT;
228  tvItem.hItem = childItem;
229  tvItem.pszText = &pszNodes[dwActualSize];
230  tvItem.cchTextMax = dwPhysicalSize - dwActualSize;
231  if (!TreeView_GetItem(hwndTV, &tvItem))
232  goto done;
233 
234  dwActualSize += (DWORD) wcslen(&pszNodes[dwActualSize]) + 1;
235  }
236 
237  if (pszNodes)
238  pszNodes[dwActualSize] = L'\0';
239  }
240 
241  /* Now go through all the children in the tree, and check if any have to be removed. */
242  childItem = TreeView_GetChild(hwndTV, hItem);
243  while (childItem)
244  {
245  HTREEITEM nextItem = TreeView_GetNextSibling(hwndTV, childItem);
246  if (RefreshTreeItem(hwndTV, childItem) == FALSE)
247  {
248  (void)TreeView_DeleteItem(hwndTV, childItem);
249  }
250  childItem = nextItem;
251  }
252 
253  /* Now go through all the children in the registry, and check if any have to be added. */
254  bAddedAny = FALSE;
255  for (dwIndex = 0; dwIndex < dwCount; dwIndex++)
256  {
257  DWORD cName = dwMaxSubKeyLen, dwSubCount;
258  BOOL found;
259 
260  found = FALSE;
261  if (RegEnumKeyExW(hKey, dwIndex, Name, &cName, 0, 0, 0, NULL) != ERROR_SUCCESS)
262  {
263  continue;
264  }
265 
266  /* Check if the node is already in there. */
267  if (pszNodes)
268  {
269  for (s = pszNodes; *s; s += wcslen(s) + 1)
270  {
271  if (!wcscmp(s, Name))
272  {
273  found = TRUE;
274  break;
275  }
276  }
277  }
278 
279  if (found == FALSE)
280  {
281  /* Find the number of children of the node. */
282  dwSubCount = 0;
283  if (RegOpenKeyExW(hKey, Name, 0, KEY_QUERY_VALUE, &hSubKey) == ERROR_SUCCESS)
284  {
285  if (RegQueryInfoKeyW(hSubKey, 0, 0, 0, &dwSubCount, 0, 0, 0, 0, 0, 0, 0) != ERROR_SUCCESS)
286  {
287  dwSubCount = 0;
288  }
289  RegCloseKey(hSubKey);
290  }
291 
292  AddEntryToTree(hwndTV, hItem, Name, NULL, dwSubCount);
293  bAddedAny = TRUE;
294  }
295  }
296  RegCloseKey(hKey);
297 
298  if (bAddedAny)
299  SendMessageW(hwndTV, TVM_SORTCHILDREN, 0, (LPARAM) hItem);
300 
301  bSuccess = TRUE;
302 
303 done:
304  if (pszNodes)
305  HeapFree(GetProcessHeap(), 0, pszNodes);
306  if (Name)
308  return bSuccess;
309 }
310 
312 {
314  HTREEITEM hSelectedItem;
315  HCURSOR hcursorOld;
316 
317  hSelectedItem = TreeView_GetSelection(hwndTV);
318  hcursorOld = SetCursor(LoadCursor(NULL, IDC_WAIT));
319  SendMessageW(hwndTV, WM_SETREDRAW, FALSE, 0);
320 
321  hItem = TreeView_GetChild(hwndTV, TreeView_GetRoot(hwndTV));
322  while (hItem)
323  {
324  RefreshTreeItem(hwndTV, hItem);
326  }
327 
328  SendMessageW(hwndTV, WM_SETREDRAW, TRUE, 0);
329  SetCursor(hcursorOld);
330 
331  /* We reselect the currently selected node, this will prompt a refresh of the listview. */
332  (void)TreeView_SelectItem(hwndTV, hSelectedItem);
333  return TRUE;
334 }
335 
337 {
339  HTREEITEM hNewItem = 0;
340  TVITEMEXW item;
341 
342  /* Default to the current selection */
343  if (!hItem)
344  {
345  hItem = TreeView_GetSelection(hwndTV);
346  if (!hItem)
347  return FALSE;
348  }
349 
350  memset(&item, 0, sizeof(item));
351  item.hItem = hItem;
353  if (!TreeView_GetItem(hwndTV, &item))
354  return FALSE;
355 
356  if ((item.state & TVIS_EXPANDEDONCE) && (item.cChildren > 0))
357  {
358  hNewItem = AddEntryToTree(hwndTV, hItem, name, 0, 0);
359  SendMessageW(hwndTV, TVM_SORTCHILDREN, 0, (LPARAM) hItem);
360  }
361  else
362  {
363  item.mask = TVIF_CHILDREN | TVIF_HANDLE;
364  item.hItem = hItem;
365  item.cChildren = 1;
366  if (!TreeView_SetItem(hwndTV, &item))
367  return FALSE;
368  }
369 
371  if (!hNewItem)
372  {
373  for(hNewItem = TreeView_GetChild(hwndTV, hItem); hNewItem; hNewItem = TreeView_GetNextSibling(hwndTV, hNewItem))
374  {
375  item.mask = TVIF_HANDLE | TVIF_TEXT;
376  item.hItem = hNewItem;
377  item.pszText = buf;
378  item.cchTextMax = ARRAY_SIZE(buf);
379  if (!TreeView_GetItem(hwndTV, &item)) continue;
380  if (wcscmp(name, item.pszText) == 0) break;
381  }
382  }
383  if (hNewItem) (void)TreeView_SelectItem(hwndTV, hNewItem);
384 
385  return hNewItem;
386 }
387 
389 {
391 
392  if(!(hItem = TreeView_GetSelection(hwndTV))) return 0;
393  return TreeView_EditLabel(hwndTV, hItem);
394 }
395 
396 static BOOL InitTreeViewItems(HWND hwndTV, LPWSTR pHostName)
397 {
398  TVITEMW tvi;
399  TVINSERTSTRUCTW tvins;
401 
403  /* Set the text of the item. */
404  tvi.pszText = pHostName;
405  tvi.cchTextMax = wcslen(tvi.pszText);
406  /* Assume the item is not a parent item, so give it an image. */
407  tvi.iImage = Image_Root;
409  tvi.cChildren = 5;
410  /* Save the heading level in the item's application-defined data area. */
411  tvi.lParam = (LPARAM)NULL;
412  tvins.item = tvi;
414  tvins.hParent = TVI_ROOT;
415  /* Add the item to the tree view control. */
416  if (!(hRoot = TreeView_InsertItem(hwndTV, &tvins))) return FALSE;
417 
418  if (!AddEntryToTree(hwndTV, hRoot, L"HKEY_CLASSES_ROOT", HKEY_CLASSES_ROOT, 1)) return FALSE;
419  if (!AddEntryToTree(hwndTV, hRoot, L"HKEY_CURRENT_USER", HKEY_CURRENT_USER, 1)) return FALSE;
420  if (!AddEntryToTree(hwndTV, hRoot, L"HKEY_LOCAL_MACHINE", HKEY_LOCAL_MACHINE, 1)) return FALSE;
421  if (!AddEntryToTree(hwndTV, hRoot, L"HKEY_USERS", HKEY_USERS, 1)) return FALSE;
422  if (!AddEntryToTree(hwndTV, hRoot, L"HKEY_CURRENT_CONFIG", HKEY_CURRENT_CONFIG, 1)) return FALSE;
423 
424  if (GetVersion() & 0x80000000)
425  {
426  /* Win9x specific key */
427  if (!AddEntryToTree(hwndTV, hRoot, L"HKEY_DYN_DATA", HKEY_DYN_DATA, 1)) return FALSE;
428  }
429 
430  /* expand and select host name */
433  return TRUE;
434 }
435 
436 
437 /*
438  * InitTreeViewImageLists - creates an image list, adds three bitmaps
439  * to it, and associates the image list with a tree view control.
440  * Returns TRUE if successful, or FALSE otherwise.
441  * hwndTV - handle to the tree view control.
442  */
444 {
445  HIMAGELIST himl; /* handle to image list */
446  HICON hico; /* handle to icon */
449  HMODULE hShell32 = GetModuleHandleW(L"shell32.dll");
450 
451  /* Create the image list. */
453  return FALSE;
454 
455  /* Add the open file, closed file, and document bitmaps. */
458  IMAGE_ICON,
459  cx,
460  cy,
462  if (hico)
463  {
465  DestroyIcon(hico);
466  }
467 
470  IMAGE_ICON,
471  cx,
472  cy,
474  if (hico)
475  {
477  DestroyIcon(hico);
478  }
479 
482  IMAGE_ICON,
483  cx,
484  cy,
486  if (hico)
487  {
489  DestroyIcon(hico);
490  }
491 
492  /* Fail if not all of the images were added. */
494  {
496  return FALSE;
497  }
498 
499  /* Associate the image list with the tree view control. */
501 
502  return TRUE;
503 }
504 
506 {
507  DWORD dwCount, dwIndex, dwMaxSubKeyLen;
508  HKEY hRoot, hNewKey, hKey;
509  LPCWSTR keyPath;
510  LPWSTR Name;
511  LONG errCode;
512  HCURSOR hcursorOld;
513 
514  static int expanding;
515  if (expanding) return FALSE;
516  if (pnmtv->itemNew.state & TVIS_EXPANDEDONCE )
517  {
518  return TRUE;
519  }
520  expanding = TRUE;
521  hcursorOld = SetCursor(LoadCursor(NULL, IDC_WAIT));
522  SendMessageW(hwndTV, WM_SETREDRAW, FALSE, 0);
523 
524  keyPath = GetItemPath(hwndTV, pnmtv->itemNew.hItem, &hRoot);
525  if (!keyPath) goto done;
526 
527  if (*keyPath)
528  {
529  errCode = RegOpenKeyExW(hRoot, keyPath, 0, KEY_READ, &hNewKey);
530  if (errCode != ERROR_SUCCESS) goto done;
531  }
532  else
533  {
534  hNewKey = hRoot;
535  }
536 
537  errCode = RegQueryInfoKeyW(hNewKey, 0, 0, 0, &dwCount, &dwMaxSubKeyLen, 0, 0, 0, 0, 0, 0);
538  if (errCode != ERROR_SUCCESS) goto done;
539  dwMaxSubKeyLen++; /* account for the \0 terminator */
540  Name = HeapAlloc(GetProcessHeap(), 0, dwMaxSubKeyLen * sizeof(WCHAR));
541  if (!Name) goto done;
542 
543  for (dwIndex = 0; dwIndex < dwCount; dwIndex++)
544  {
545  DWORD cName = dwMaxSubKeyLen, dwSubCount;
546 
547  errCode = RegEnumKeyExW(hNewKey, dwIndex, Name, &cName, 0, 0, 0, 0);
548  if (errCode != ERROR_SUCCESS) continue;
549  errCode = RegOpenKeyExW(hNewKey, Name, 0, KEY_QUERY_VALUE, &hKey);
550  if (errCode == ERROR_SUCCESS)
551  {
552  errCode = RegQueryInfoKeyW(hKey, 0, 0, 0, &dwSubCount, 0, 0, 0, 0, 0, 0, 0);
553  RegCloseKey(hKey);
554  }
555  if (errCode != ERROR_SUCCESS) dwSubCount = 0;
556  AddEntryToTree(hwndTV, pnmtv->itemNew.hItem, Name, NULL, dwSubCount);
557  }
558 
559  SendMessageW(hwndTV, TVM_SORTCHILDREN, 0, (LPARAM)pnmtv->itemNew.hItem);
560 
561  RegCloseKey(hNewKey);
563 
564 done:
565  SendMessageW(hwndTV, WM_SETREDRAW, TRUE, 0);
566  SetCursor(hcursorOld);
567  expanding = FALSE;
568 
569  return TRUE;
570 }
571 
572 
574 {
575  WCHAR szNewKeyFormat[128];
576  WCHAR szNewKey[128];
577  LPCWSTR pszKeyPath;
578  int iIndex = 1;
579  LONG nResult;
580  HKEY hRootKey = NULL, hKey = NULL, hNewKey = NULL;
581  BOOL bSuccess = FALSE;
582  DWORD dwDisposition;
583  HTREEITEM hNewItem;
584 
585  pszKeyPath = GetItemPath(hwndTV, hItem, &hRootKey);
586  if (pszKeyPath[0] == L'\0')
587  hKey = hRootKey;
588  else if (RegOpenKeyW(hRootKey, pszKeyPath, &hKey) != ERROR_SUCCESS)
589  goto done;
590 
591  if (LoadStringW(hInst, IDS_NEW_KEY, szNewKeyFormat, ARRAY_SIZE(szNewKeyFormat)) <= 0)
592  goto done;
593 
594  /* Need to create a new key with a unique name */
595  do
596  {
597  wsprintf(szNewKey, szNewKeyFormat, iIndex++);
598  nResult = RegCreateKeyExW(hKey, szNewKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hNewKey, &dwDisposition);
599  if (hNewKey && dwDisposition == REG_OPENED_EXISTING_KEY)
600  {
601  RegCloseKey(hNewKey);
602  hNewKey = NULL;
603  }
604  else if (!hNewKey)
605  {
606  InfoMessageBox(hFrameWnd, MB_OK | MB_ICONERROR, NULL, L"Cannot create new key!\n\nError Code: %d", nResult);
607  goto done;
608  }
609  }
610  while(!hNewKey);
611 
612  /* Insert the new key */
613  hNewItem = InsertNode(hwndTV, hItem, szNewKey);
614  if (!hNewItem)
615  goto done;
616 
617  /* The new key's name is probably not appropriate yet */
618  (void)TreeView_EditLabel(hwndTV, hNewItem);
619 
620  bSuccess = TRUE;
621 
622 done:
623  if (hKey != hRootKey && hKey)
624  RegCloseKey(hKey);
625  if (hNewKey)
626  RegCloseKey(hNewKey);
627  return bSuccess;
628 }
629 
631 {
633  *Result = TRUE;
634 
635  switch (((LPNMHDR)lParam)->code)
636  {
637  case TVN_ITEMEXPANDING:
639  return TRUE;
640  case TVN_SELCHANGED:
641  {
642  NMTREEVIEW* pnmtv = (NMTREEVIEW*)lParam;
643  /* Get the parent of the current item */
644  HTREEITEM hParentItem = TreeView_GetParent(g_pChildWnd->hTreeWnd, pnmtv->itemNew.hItem);
645 
646  UpdateAddress(pnmtv->itemNew.hItem, NULL, NULL);
647 
648  /* Disable the Permissions menu item for 'My Computer' */
650 
651  /*
652  * Disable Delete/Rename menu options for 'My Computer' (first item so doesn't have any parent)
653  * and HKEY_* keys (their parent is 'My Computer' and the previous remark applies).
654  */
655  if (!hParentItem || !TreeView_GetParent(g_pChildWnd->hTreeWnd, hParentItem))
656  {
661  }
662  else
663  {
668  }
669 
670  return TRUE;
671  }
672  case NM_SETFOCUS:
674  break;
675  case TVN_BEGINLABELEDIT:
676  {
678  /* cancel label edit for rootkeys */
679  if (!TreeView_GetParent(g_pChildWnd->hTreeWnd, ptvdi->item.hItem) ||
681  {
682  *Result = TRUE;
683  }
684  else
685  {
686  *Result = FALSE;
687  }
688  return TRUE;
689  }
690  case TVN_ENDLABELEDIT:
691  {
692  LPCWSTR keyPath;
693  HKEY hRootKey;
694  HKEY hKey = NULL;
696  LONG nRenResult;
697  LONG lResult = TRUE;
698  WCHAR szBuffer[MAX_PATH];
699  WCHAR Caption[128];
700 
701  if (ptvdi->item.pszText)
702  {
703  keyPath = GetItemPath(g_pChildWnd->hTreeWnd, TreeView_GetParent(g_pChildWnd->hTreeWnd, ptvdi->item.hItem), &hRootKey);
704  if (wcslen(keyPath))
705  _snwprintf(szBuffer, ARRAY_SIZE(szBuffer), L"%s\\%s", keyPath, ptvdi->item.pszText);
706  else
707  _snwprintf(szBuffer, ARRAY_SIZE(szBuffer), L"%s", ptvdi->item.pszText);
708  keyPath = GetItemPath(g_pChildWnd->hTreeWnd, ptvdi->item.hItem, &hRootKey);
709  if (RegOpenKeyExW(hRootKey, szBuffer, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
710  {
711  lResult = FALSE;
712  RegCloseKey(hKey);
713  TreeView_EditLabel(g_pChildWnd->hTreeWnd, ptvdi->item.hItem);
714  }
715  else
716  {
717  nRenResult = RenameKey(hRootKey, keyPath, ptvdi->item.pszText);
718  if (nRenResult != ERROR_SUCCESS)
719  {
720  LoadStringW(hInst, IDS_ERROR, Caption, ARRAY_SIZE(Caption));
721  ErrorMessageBox(hWnd, Caption, nRenResult);
722  lResult = FALSE;
723  }
724  else
725  UpdateAddress(ptvdi->item.hItem, hRootKey, szBuffer);
726  }
727  *Result = lResult;
728  }
729  return TRUE;
730  }
731  }
732  return FALSE;
733 }
734 
735 /*
736  * CreateTreeView - creates a tree view control.
737  * Returns the handle to the new control if successful, or NULL otherwise.
738  * hwndParent - handle to the control's parent window.
739  */
741 {
742  RECT rcClient;
743  HWND hwndTV;
744 
745  /* Get the dimensions of the parent window's client area, and create the tree view control. */
746  GetClientRect(hwndParent, &rcClient);
749  0, 0, rcClient.right, rcClient.bottom,
750  hwndParent, id, hInst, NULL);
751  if (!hwndTV) return NULL;
752 
753  /* Initialize the image list, and add items to the control. */
754  if (!InitTreeViewImageLists(hwndTV) || !InitTreeViewItems(hwndTV, pHostName))
755  {
756  DestroyWindow(hwndTV);
757  return NULL;
758  }
759  return hwndTV;
760 }
761 
762 void DestroyTreeView(HWND hwndTV)
763 {
765 
767 
768  /* Destroy the image list associated with the tree view control */
771 }
772 
773 BOOL SelectNode(HWND hwndTV, LPCWSTR keyPath)
774 {
776  HTREEITEM hChildItem;
777  WCHAR szPathPart[128];
778  WCHAR szBuffer[128];
779  LPCWSTR s;
780  TVITEMW tvi;
781 
782  /* Load "My Computer" string... */
783  LoadStringW(hInst, IDS_MY_COMPUTER, szBuffer, ARRAY_SIZE(szBuffer));
784  wcscat(szBuffer, L"\\");
785 
786  /* ... and remove it from the key path */
787  if (!_wcsnicmp(keyPath, szBuffer, wcslen(szBuffer)))
788  keyPath += wcslen(szBuffer);
789 
790  /* Reinitialize szBuffer */
791  szBuffer[0] = L'\0';
792 
793  hRoot = TreeView_GetRoot(hwndTV);
794  hItem = hRoot;
795 
796  while(keyPath[0])
797  {
798  s = wcschr(keyPath, L'\\');
799  lstrcpynW(szPathPart, keyPath, s ? s - keyPath + 1 : wcslen(keyPath) + 1);
800 
801  /* Special case for root to expand root key abbreviations */
802  if (hItem == hRoot)
803  {
804  if (!_wcsicmp(szPathPart, L"HKCR"))
805  wcscpy(szPathPart, L"HKEY_CLASSES_ROOT");
806  else if (!_wcsicmp(szPathPart, L"HKCU"))
807  wcscpy(szPathPart, L"HKEY_CURRENT_USER");
808  else if (!_wcsicmp(szPathPart, L"HKLM"))
809  wcscpy(szPathPart, L"HKEY_LOCAL_MACHINE");
810  else if (!_wcsicmp(szPathPart, L"HKU"))
811  wcscpy(szPathPart, L"HKEY_USERS");
812  else if (!_wcsicmp(szPathPart, L"HKCC"))
813  wcscpy(szPathPart, L"HKEY_CURRENT_CONFIG");
814  else if (!_wcsicmp(szPathPart, L"HKDD"))
815  wcscpy(szPathPart, L"HKEY_DYN_DATA");
816  }
817 
818  for (hChildItem = TreeView_GetChild(hwndTV, hItem); hChildItem;
819  hChildItem = TreeView_GetNextSibling(hwndTV, hChildItem))
820  {
821  memset(&tvi, 0, sizeof(tvi));
822  tvi.hItem = hChildItem;
823  tvi.mask = TVIF_TEXT | TVIF_CHILDREN;
824  tvi.pszText = szBuffer;
825  tvi.cchTextMax = ARRAY_SIZE(szBuffer);
826 
827  (void)TreeView_GetItem(hwndTV, &tvi);
828 
829  if (!_wcsicmp(szBuffer, szPathPart))
830  break;
831  }
832 
833  if (!hChildItem)
834  return FALSE;
835 
836  if (tvi.cChildren > 0)
837  {
838  if (!TreeView_Expand(hwndTV, hChildItem, TVE_EXPAND))
839  return FALSE;
840  }
841 
842  keyPath = s ? s + 1 : L"";
843  hItem = hChildItem;
844  }
845 
846  (void)TreeView_SelectItem(hwndTV, hItem);
848 
849  return TRUE;
850 }
851 
852 /* EOF */
#define HKEY_USERS
Definition: winreg.h:13
#define IDI_SHELL_FOLDER
Definition: treeview.c:36
INT WINAPI ImageList_GetImageCount(HIMAGELIST himl)
Definition: imagelist.c:2063
static LPWSTR pathBuffer
Definition: treeview.c:31
#define ID_TREE_RENAME
Definition: resource.h:152
BOOL TreeWndNotifyProc(HWND hWnd, WPARAM wParam, LPARAM lParam, BOOL *Result)
Definition: treeview.c:630
BOOL OnTreeExpanding(HWND hwndTV, NMTREEVIEW *pnmtv)
Definition: treeview.c:505
int cchTextMax
Definition: commctrl.h:3321
static HICON
Definition: imagelist.c:84
#define IMAGE_ICON
Definition: winuser.h:212
BOOL SelectNode(HWND hwndTV, LPCWSTR keyPath)
Definition: treeview.c:773
HTREEITEM hParent
Definition: commctrl.h:3393
int ErrorMessageBox(HWND hWnd, LPCWSTR lpTitle, DWORD dwErrorCode,...)
Definition: error.c:24
ChildWnd * g_pChildWnd
Definition: childwnd.c:23
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
#define MF_BYCOMMAND
Definition: winuser.h:202
#define ERROR_SUCCESS
Definition: deptool.c:10
static BOOL InitTreeViewItems(HWND hwndTV, LPWSTR pHostName)
Definition: treeview.c:396
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define TVM_SORTCHILDREN
Definition: commctrl.h:3541
#define TVGN_CARET
Definition: commctrl.h:3461
BOOL WINAPI DestroyIcon(_In_ HICON)
Definition: cursoricon.c:2022
#define KEY_READ
Definition: nt_native.h:1023
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
int iImage
Definition: commctrl.h:3322
#define TreeView_EditLabel(hwnd, hitem)
Definition: commctrl.h:3504
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define TreeView_GetChild(hwnd, hitem)
Definition: commctrl.h:3466
HWND hTreeWnd
Definition: main.h:63
#define TVS_LINESATROOT
Definition: commctrl.h:3249
struct _TREEITEM * HTREEITEM
Definition: commctrl.h:3264
#define WM_SETREDRAW
Definition: winuser.h:1606
_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)
HWND hWnd
Definition: settings.c:17
LPARAM lParam
Definition: commctrl.h:3325
BOOL RefreshTreeView(HWND hwndTV)
Definition: treeview.c:311
#define SM_CYSMICON
Definition: winuser.h:1007
int InfoMessageBox(HWND hWnd, UINT uType, LPCWSTR lpTitle, LPCWSTR lpMessage,...)
Definition: error.c:51
UINT_PTR WPARAM
Definition: windef.h:207
#define HKEY_DYN_DATA
Definition: winreg.h:16
#define TVIS_EXPANDEDONCE
Definition: commctrl.h:3285
#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:3467
#define TVIF_SELECTEDIMAGE
Definition: commctrl.h:3271
HICON HCURSOR
Definition: windef.h:299
UINT mask
Definition: commctrl.h:3316
#define IDI_SHELL_FOLDER_OPEN
Definition: treeview.c:37
#define HKEY_CURRENT_CONFIG
Definition: winreg.h:15
LONG right
Definition: windef.h:308
HIMAGELIST himl
BOOL WINAPI DestroyWindow(_In_ HWND)
LPWSTR pszText
Definition: commctrl.h:3320
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:762
#define DWORD
Definition: nt_native.h:44
int32_t INT
Definition: typedefs.h:58
static BOOLEAN bSuccess
Definition: drive.cpp:433
#define TreeView_GetImageList(hwnd, iImage)
Definition: commctrl.h:3441
WPARAM wParam
Definition: combotst.c:138
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:1091
#define lstrcpynW
Definition: compat.h:738
static BOOL get_item_path(HWND hwndTV, HTREEITEM hItem, HKEY *phKey, LPWSTR *pKeyPath, int *pPathLen, int *pMaxLen)
Definition: treeview.c:40
LONG RenameKey(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpNewName)
Definition: edit.c:1489
BOOL WINAPI ImageList_Destroy(HIMAGELIST himl)
Definition: imagelist.c:928
#define ILC_COLOR32
Definition: commctrl.h:358
static HTREEITEM AddEntryToTree(HWND hwndTV, HTREEITEM hParent, LPWSTR label, HKEY hKey, DWORD dwChildren)
Definition: treeview.c:115
#define IDS_NEW_KEY
Definition: resource.h:190
#define TreeView_InsertItem(hwnd, lpis)
Definition: commctrl.h:3412
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define L(x)
Definition: ntvdm.h:50
BOOL WINAPI EnableMenuItem(_In_ HMENU, _In_ UINT, _In_ UINT)
HIMAGELIST WINAPI ImageList_Create(INT cx, INT cy, UINT flags, INT cInitial, INT cGrow)
Definition: imagelist.c:804
#define TVN_ENDLABELEDIT
Definition: commctrl.h:3744
#define TVIF_CHILDREN
Definition: commctrl.h:3272
#define FALSE
Definition: types.h:117
HTREEITEM InsertNode(HWND hwndTV, HTREEITEM hItem, LPWSTR name)
Definition: treeview.c:336
HTREEITEM hInsertAfter
Definition: commctrl.h:3394
unsigned int BOOL
Definition: ntddk_ex.h:94
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:3642
#define ID_EDIT_DELETE
Definition: resource.h:57
static HTREEITEM hRoot
Definition: treeview.c:381
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3291
#define TVS_HASBUTTONS
Definition: commctrl.h:3247
#define TVN_BEGINLABELEDIT
Definition: commctrl.h:3743
static int Image_Closed
Definition: treeview.c:28
struct NameRec_ * Name
Definition: cdprocs.h:459
#define TVI_FIRST
Definition: commctrl.h:3369
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:585
#define ID_EDIT_PERMISSIONS
Definition: resource.h:150
HTREEITEM hItem
Definition: treelist.h:37
int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format,...)
static HWND hwndParent
Definition: cryptui.c:300
#define IDC_WAIT
Definition: winuser.h:684
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
LONG_PTR LPARAM
Definition: windef.h:208
HWND CreateTreeView(HWND hwndParent, LPWSTR pHostName, HMENU id)
Definition: treeview.c:740
static int Image_Open
Definition: treeview.c:27
#define TVI_LAST
Definition: commctrl.h:3370
#define ID_EDIT_RENAME
Definition: resource.h:58
int cChildren
Definition: commctrl.h:3324
#define TreeView_SetImageList(hwnd, himl, iImage)
Definition: commctrl.h:3447
#define TreeView_DeleteItem(hwnd, hitem)
Definition: commctrl.h:3415
#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 TreeView_GetSelection(hwnd)
Definition: commctrl.h:3473
#define GetProcessHeap()
Definition: compat.h:736
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:3245
__wchar_t WCHAR
Definition: xmlstorage.h:180
HMENU hPopupMenus
Definition: main.c:38
#define NM_SETFOCUS
Definition: commctrl.h:135
#define TVN_SELCHANGED
Definition: commctrl.h:3735
#define MF_ENABLED
Definition: winuser.h:128
#define TreeView_GetItemState(hwndTV, hti, mask)
Definition: commctrl.h:3595
#define MAX_PATH
Definition: compat.h:34
BOOL RefreshTreeItem(HWND hwndTV, HTREEITEM hItem)
Definition: treeview.c:141
int WINAPI GetSystemMetrics(_In_ int)
unsigned long DWORD
Definition: ntddk_ex.h:95
#define IDS_MY_COMPUTER
Definition: resource.h:129
INT WINAPI ImageList_AddIcon(HIMAGELIST himl, HICON hIcon)
Definition: imagelist.c:540
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:3690
#define TVE_EXPAND
Definition: commctrl.h:3423
#define TVI_ROOT
Definition: commctrl.h:3368
#define SM_CXSMICON
Definition: winuser.h:1006
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
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
#define ILC_MASK
Definition: commctrl.h:351
GLenum GLsizei len
Definition: glext.h:6722
GLdouble s
Definition: gl.h:2039
#define TreeView_GetParent(hwnd, hitem)
Definition: commctrl.h:3469
#define WS_TABSTOP
Definition: pedump.c:634
Definition: inflate.c:139
uint8_t label[11]
Definition: fsck.fat.h:65
BOOL DeleteNode(HWND hwndTV, HTREEITEM hItem)
Definition: treeview.c:107
#define LoadCursor
Definition: winuser.h:5802
#define TVIF_HANDLE
Definition: commctrl.h:3270
#define TVIS_EXPANDED
Definition: commctrl.h:3284
LPCWSTR GetItemPath(HWND hwndTV, HTREEITEM hItem, HKEY *phRootKey)
Definition: treeview.c:88
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
HWND hFrameWnd
Definition: main.c:35
#define TVN_ITEMEXPANDING
Definition: commctrl.h:3738
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
static BOOL InitTreeViewImageLists(HWND hwndTV)
Definition: treeview.c:443
#define TreeView_EnsureVisible(hwnd, hitem)
Definition: commctrl.h:3545
HINSTANCE hInst
Definition: dxdiag.c:13
HMENU hMenuFrame
Definition: main.c:37
static ATOM item
Definition: dde.c:856
#define WS_EX_CLIENTEDGE
Definition: winuser.h:384
#define TreeView_GetRoot(hwnd)
Definition: commctrl.h:3475
HCURSOR WINAPI SetCursor(_In_opt_ HCURSOR)
#define TVIF_TEXT
Definition: commctrl.h:3266
FxAutoRegKey hKey
#define ARRAY_SIZE(a)
Definition: main.h:24
#define TreeView_SelectItem(hwnd, hitem)
Definition: commctrl.h:3481
int iSelectedImage
Definition: commctrl.h:3323
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define HeapReAlloc
Definition: compat.h:734
#define TreeView_Select(hwnd, hitem, code)
Definition: commctrl.h:3479
#define TVIF_IMAGE
Definition: commctrl.h:3267
_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 NULL
Definition: types.h:112
#define MB_OK
Definition: winuser.h:784
HTREEITEM hItem
Definition: commctrl.h:3317
#define IDI_SHELL_MY_COMPUTER
Definition: treeview.c:38
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define TreeView_SetItem(hwnd, pitem)
Definition: commctrl.h:3497
#define LPNMTVDISPINFO
Definition: commctrl.h:3676
#define TVS_SHOWSELALWAYS
Definition: commctrl.h:3252
#define IDS_ERROR
Definition: resource.h:18
#define TVS_HASLINES
Definition: commctrl.h:3248
_Out_opt_ int * cx
Definition: commctrl.h:585
#define TVSIL_NORMAL
Definition: commctrl.h:3443
Definition: name.c:38
HWND StartKeyRename(HWND hwndTV)
Definition: treeview.c:388
HANDLE HKEY
Definition: registry.h:26
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3356
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
LONG bottom
Definition: windef.h:309
#define TVIF_STATE
Definition: commctrl.h:3269
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
#define TVIF_PARAM
Definition: commctrl.h:3268
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:2527
#define ID_TREE_DELETE
Definition: resource.h:151
#define MF_GRAYED
Definition: winuser.h:129
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define wsprintf
Definition: winuser.h:5855
#define LR_DEFAULTCOLOR
Definition: winuser.h:1081
#define NUM_ICONS
Definition: treeview.c:33
#define TreeView_Expand(hwnd, hitem, code)
Definition: commctrl.h:3420
#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
LPARAM lParam
Definition: combotst.c:139
static HMODULE hShell32
Definition: string.c:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define RegCloseKey(hKey)
Definition: registry.h:47
#define TreeView_GetItem(hwnd, pitem)
Definition: commctrl.h:3490
_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:573
#define TVS_EDITLABELS
Definition: commctrl.h:3250
#define MAX_NEW_KEY_LEN
Definition: main.h:41
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
int nFocusPanel
Definition: main.h:68
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
VOID UpdateAddress(HTREEITEM hItem, HKEY hRootKey, LPCWSTR pszPath)
Definition: childwnd.c:232