ReactOS 0.4.16-dev-136-g52192f1
treeview.c
Go to the documentation of this file.
1/*
2 * Regedit treeview
3 *
4 * Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
5 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
6 */
7
8#include "regedit.h"
9
10/* Global variables and constants */
11/* Image_Open, Image_Closed, and Image_Root - integer variables for indexes of the images */
12static int Image_Open;
13static int Image_Closed;
14static int Image_Root;
15
17
18#define NUM_ICONS 3 /* number of icons to add to the image list */
19
20/* External resources in shell32.dll */
21#define IDI_SHELL_FOLDER 4
22#define IDI_SHELL_FOLDER_OPEN 5
23#define IDI_SHELL_MY_COMPUTER 16
24
25static BOOL get_item_path(HWND hwndTV, HTREEITEM hItem, HKEY* phKey, LPWSTR* pKeyPath, int* pPathLen, int* pMaxLen)
26{
28 size_t maxLen, len;
29 LPWSTR newStr;
30
31 item.mask = TVIF_PARAM;
32 item.hItem = hItem;
33 if (!TreeView_GetItem(hwndTV, &item)) return FALSE;
34
35 if (item.lParam)
36 {
37 /* found root key with valid key value */
38 *phKey = (HKEY)item.lParam;
39 return TRUE;
40 }
41
42 if(!get_item_path(hwndTV, TreeView_GetParent(hwndTV, hItem), phKey, pKeyPath, pPathLen, pMaxLen)) return FALSE;
43 if (*pPathLen)
44 {
45 (*pKeyPath)[*pPathLen] = L'\\';
46 ++(*pPathLen);
47 }
48
49 do
50 {
51 item.mask = TVIF_TEXT;
52 item.hItem = hItem;
53 item.pszText = *pKeyPath + *pPathLen;
54 maxLen = *pMaxLen - *pPathLen;
55 item.cchTextMax = (int) maxLen;
56 if (!TreeView_GetItem(hwndTV, &item)) return FALSE;
57 len = wcslen(item.pszText);
58 if (len < maxLen - 1)
59 {
60 *pPathLen += (int) len;
61 break;
62 }
63 newStr = HeapReAlloc(GetProcessHeap(), 0, *pKeyPath, *pMaxLen * 2);
64 if (!newStr) return FALSE;
65 *pKeyPath = newStr;
66 *pMaxLen *= 2;
67 }
68 while(TRUE);
69
70 return TRUE;
71}
72
74{
75 int pathLen = 0, maxLen;
76
77 *phRootKey = NULL;
78
79 if (!pathBuffer)
81 if (!pathBuffer)
82 return NULL;
83
85
86 maxLen = (int)HeapSize(GetProcessHeap(), 0, pathBuffer);
87
88 if (!hItem)
89 {
91 }
92 if (maxLen == -1 || !hItem || !get_item_path(hwndTV, hItem, phRootKey, &pathBuffer, &pathLen, &maxLen))
93 {
94 return NULL;
95 }
96 return pathBuffer;
97}
98
100{
101 if (!hItem) hItem = TreeView_GetSelection(hwndTV);
102 if (!hItem) return FALSE;
103 return TreeView_DeleteItem(hwndTV, hItem);
104}
105
106/* Add an entry to the tree. Only give hKey for root nodes (HKEY_ constants) */
107static HTREEITEM AddEntryToTree(HWND hwndTV, HTREEITEM hParent, LPWSTR label, HKEY hKey, DWORD dwChildren)
108{
109 TVITEMW tvi;
110 TVINSERTSTRUCTW tvins;
111
112 if (hKey)
113 {
114 if (RegQueryInfoKeyW(hKey, 0, 0, 0, &dwChildren, 0, 0, 0, 0, 0, 0, 0) != ERROR_SUCCESS)
115 {
116 dwChildren = 0;
117 }
118 }
119
121 tvi.pszText = label;
122 tvi.cchTextMax = wcslen(tvi.pszText);
123 tvi.iImage = Image_Closed;
125 tvi.cChildren = dwChildren;
126 tvi.lParam = (LPARAM)hKey;
127 tvins.item = tvi;
129 tvins.hParent = hParent;
130 return TreeView_InsertItem(hwndTV, &tvins);
131}
132
134{
135 HKEY hRoot, hKey, hSubKey;
136 HTREEITEM childItem;
137 LPCWSTR KeyPath;
138 DWORD dwCount, dwIndex, dwMaxSubKeyLen;
139 LPWSTR Name = NULL;
140 TVITEMW tvItem;
141 LPWSTR pszNodes = NULL;
143 LPWSTR s;
144 BOOL bAddedAny;
145
146 KeyPath = GetItemPath(hwndTV, hItem, &hRoot);
147
148 if (*KeyPath)
149 {
150 if (RegOpenKeyExW(hRoot, KeyPath, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
151 {
152 goto done;
153 }
154 }
155 else
156 {
157 hKey = hRoot;
158 }
159
160 if (RegQueryInfoKeyW(hKey, 0, 0, 0, &dwCount, &dwMaxSubKeyLen, 0, 0, 0, 0, 0, 0) != ERROR_SUCCESS)
161 {
162 goto done;
163 }
164
165 /* Set the number of children again */
166 tvItem.mask = TVIF_CHILDREN;
167 tvItem.hItem = hItem;
168 tvItem.cChildren = dwCount;
169 if (!TreeView_SetItem(hwndTV, &tvItem))
170 {
171 goto done;
172 }
173
174 /* We don't have to bother with the rest if it's not expanded. */
175 if (TreeView_GetItemState(hwndTV, hItem, TVIS_EXPANDED) == 0)
176 {
178 bSuccess = TRUE;
179 goto done;
180 }
181
182 dwMaxSubKeyLen++; /* account for the \0 terminator */
183 if (!(Name = HeapAlloc(GetProcessHeap(), 0, dwMaxSubKeyLen * sizeof(WCHAR))))
184 {
185 goto done;
186 }
187 tvItem.cchTextMax = dwMaxSubKeyLen;
188 /*if (!(tvItem.pszText = HeapAlloc(GetProcessHeap(), 0, dwMaxSubKeyLen * sizeof(WCHAR)))) {
189 goto done;
190 }*/
191
192 /* Get all of the tree node siblings in one contiguous block of memory */
193 {
194 DWORD dwPhysicalSize = 0;
195 DWORD dwActualSize = 0;
196 DWORD dwNewPhysicalSize;
197 LPWSTR pszNewNodes;
198 DWORD dwStep = 10000;
199
200 for (childItem = TreeView_GetChild(hwndTV, hItem); childItem;
201 childItem = TreeView_GetNextSibling(hwndTV, childItem))
202 {
203
204 if (dwActualSize + dwMaxSubKeyLen + 1 > dwPhysicalSize)
205 {
206 dwNewPhysicalSize = dwActualSize + dwMaxSubKeyLen + 1 + dwStep;
207
208 if (pszNodes)
209 pszNewNodes = (LPWSTR) HeapReAlloc(GetProcessHeap(), 0, pszNodes, dwNewPhysicalSize * sizeof(WCHAR));
210 else
211 pszNewNodes = (LPWSTR) HeapAlloc(GetProcessHeap(), 0, dwNewPhysicalSize * sizeof(WCHAR));
212 if (!pszNewNodes)
213 goto done;
214
215 dwPhysicalSize = dwNewPhysicalSize;
216 pszNodes = pszNewNodes;
217 }
218
219 tvItem.mask = TVIF_TEXT;
220 tvItem.hItem = childItem;
221 tvItem.pszText = &pszNodes[dwActualSize];
222 tvItem.cchTextMax = dwPhysicalSize - dwActualSize;
223 if (!TreeView_GetItem(hwndTV, &tvItem))
224 goto done;
225
226 dwActualSize += (DWORD) wcslen(&pszNodes[dwActualSize]) + 1;
227 }
228
229 if (pszNodes)
230 pszNodes[dwActualSize] = L'\0';
231 }
232
233 /* Now go through all the children in the tree, and check if any have to be removed. */
234 childItem = TreeView_GetChild(hwndTV, hItem);
235 while (childItem)
236 {
237 HTREEITEM nextItem = TreeView_GetNextSibling(hwndTV, childItem);
238 if (RefreshTreeItem(hwndTV, childItem) == FALSE)
239 {
240 (void)TreeView_DeleteItem(hwndTV, childItem);
241 }
242 childItem = nextItem;
243 }
244
245 /* Now go through all the children in the registry, and check if any have to be added. */
246 bAddedAny = FALSE;
247 for (dwIndex = 0; dwIndex < dwCount; dwIndex++)
248 {
249 DWORD cName = dwMaxSubKeyLen, dwSubCount;
250 BOOL found;
251
252 found = FALSE;
253 if (RegEnumKeyExW(hKey, dwIndex, Name, &cName, 0, 0, 0, NULL) != ERROR_SUCCESS)
254 {
255 continue;
256 }
257
258 /* Check if the node is already in there. */
259 if (pszNodes)
260 {
261 for (s = pszNodes; *s; s += wcslen(s) + 1)
262 {
263 if (!wcscmp(s, Name))
264 {
265 found = TRUE;
266 break;
267 }
268 }
269 }
270
271 if (found == FALSE)
272 {
273 /* Find the number of children of the node. */
274 dwSubCount = 0;
275 if (RegOpenKeyExW(hKey, Name, 0, KEY_QUERY_VALUE, &hSubKey) == ERROR_SUCCESS)
276 {
277 if (RegQueryInfoKeyW(hSubKey, 0, 0, 0, &dwSubCount, 0, 0, 0, 0, 0, 0, 0) != ERROR_SUCCESS)
278 {
279 dwSubCount = 0;
280 }
281 RegCloseKey(hSubKey);
282 }
283
284 AddEntryToTree(hwndTV, hItem, Name, NULL, dwSubCount);
285 bAddedAny = TRUE;
286 }
287 }
289
290 if (bAddedAny)
292
293 bSuccess = TRUE;
294
295done:
296 if (pszNodes)
297 HeapFree(GetProcessHeap(), 0, pszNodes);
298 if (Name)
300 return bSuccess;
301}
302
304{
306 HTREEITEM hSelectedItem;
307 HCURSOR hcursorOld;
308
309 hSelectedItem = TreeView_GetSelection(hwndTV);
310 hcursorOld = SetCursor(LoadCursor(NULL, IDC_WAIT));
311 SendMessageW(hwndTV, WM_SETREDRAW, FALSE, 0);
312
313 hItem = TreeView_GetChild(hwndTV, TreeView_GetRoot(hwndTV));
314 while (hItem)
315 {
316 RefreshTreeItem(hwndTV, hItem);
318 }
319
320 SendMessageW(hwndTV, WM_SETREDRAW, TRUE, 0);
321 SetCursor(hcursorOld);
322
323 /* We reselect the currently selected node, this will prompt a refresh of the listview. */
324 (void)TreeView_SelectItem(hwndTV, hSelectedItem);
325 return TRUE;
326}
327
329{
331 HTREEITEM hNewItem = 0;
333
334 /* Default to the current selection */
335 if (!hItem)
336 {
338 if (!hItem)
339 return FALSE;
340 }
341
342 memset(&item, 0, sizeof(item));
343 item.hItem = hItem;
345 if (!TreeView_GetItem(hwndTV, &item))
346 return FALSE;
347
348 if (item.state & TVIS_EXPANDEDONCE)
349 {
350 hNewItem = AddEntryToTree(hwndTV, hItem, name, 0, 0);
352 }
353 else
354 {
356 item.hItem = hItem;
357 item.cChildren = 1;
358 if (!TreeView_SetItem(hwndTV, &item))
359 return FALSE;
360 }
361
363 if (!hNewItem)
364 {
365 for(hNewItem = TreeView_GetChild(hwndTV, hItem); hNewItem; hNewItem = TreeView_GetNextSibling(hwndTV, hNewItem))
366 {
367 item.mask = TVIF_HANDLE | TVIF_TEXT;
368 item.hItem = hNewItem;
369 item.pszText = buf;
370 item.cchTextMax = ARRAY_SIZE(buf);
371 if (!TreeView_GetItem(hwndTV, &item)) continue;
372 if (wcscmp(name, item.pszText) == 0) break;
373 }
374 }
375 if (hNewItem) (void)TreeView_SelectItem(hwndTV, hNewItem);
376
377 return hNewItem;
378}
379
381{
383
384 if(!(hItem = TreeView_GetSelection(hwndTV))) return 0;
385 return TreeView_EditLabel(hwndTV, hItem);
386}
387
388static BOOL InitTreeViewItems(HWND hwndTV, LPWSTR pHostName)
389{
390 TVITEMW tvi;
391 TVINSERTSTRUCTW tvins;
393
395 /* Set the text of the item. */
396 tvi.pszText = pHostName;
397 tvi.cchTextMax = wcslen(tvi.pszText);
398 /* Assume the item is not a parent item, so give it an image. */
399 tvi.iImage = Image_Root;
401 tvi.cChildren = 5;
402 /* Save the heading level in the item's application-defined data area. */
403 tvi.lParam = (LPARAM)NULL;
404 tvins.item = tvi;
406 tvins.hParent = TVI_ROOT;
407 /* Add the item to the tree view control. */
408 if (!(hRoot = TreeView_InsertItem(hwndTV, &tvins))) return FALSE;
409
410 if (!AddEntryToTree(hwndTV, hRoot, L"HKEY_CLASSES_ROOT", HKEY_CLASSES_ROOT, 1)) return FALSE;
411 if (!AddEntryToTree(hwndTV, hRoot, L"HKEY_CURRENT_USER", HKEY_CURRENT_USER, 1)) return FALSE;
412 if (!AddEntryToTree(hwndTV, hRoot, L"HKEY_LOCAL_MACHINE", HKEY_LOCAL_MACHINE, 1)) return FALSE;
413 if (!AddEntryToTree(hwndTV, hRoot, L"HKEY_USERS", HKEY_USERS, 1)) return FALSE;
414 if (!AddEntryToTree(hwndTV, hRoot, L"HKEY_CURRENT_CONFIG", HKEY_CURRENT_CONFIG, 1)) return FALSE;
415
416 if (GetVersion() & 0x80000000)
417 {
418 /* Win9x specific key */
419 if (!AddEntryToTree(hwndTV, hRoot, L"HKEY_DYN_DATA", HKEY_DYN_DATA, 1)) return FALSE;
420 }
421
422 /* expand and select host name */
425 return TRUE;
426}
427
428/*
429 * InitTreeViewImageLists - creates an image list, adds three bitmaps
430 * to it, and associates the image list with a tree view control.
431 * Returns TRUE if successful, or FALSE otherwise.
432 * hwndTV - handle to the tree view control.
433 */
435{
436 HIMAGELIST himl; /* handle to image list */
437 HICON hico; /* handle to icon */
440 HMODULE hShell32 = GetModuleHandleW(L"shell32.dll");
441
442 /* Create the image list. */
444 return FALSE;
445
446 /* Add the open file, closed file, and document bitmaps. */
450 cx,
451 cy,
453 if (hico)
454 {
457 }
458
462 cx,
463 cy,
465 if (hico)
466 {
469 }
470
474 cx,
475 cy,
477 if (hico)
478 {
481 }
482
483 /* Fail if not all of the images were added. */
485 {
487 return FALSE;
488 }
489
490 /* Associate the image list with the tree view control. */
492
493 return TRUE;
494}
495
497{
498 DWORD dwCount, dwIndex, dwMaxSubKeyLen;
499 HKEY hRoot, hNewKey, hKey;
500 LPCWSTR keyPath;
501 LPWSTR Name;
502 LONG errCode;
503 HCURSOR hcursorOld;
504
505 static int expanding;
506 if (expanding) return FALSE;
507 if (pnmtv->itemNew.state & TVIS_EXPANDEDONCE )
508 {
509 return TRUE;
510 }
511 expanding = TRUE;
512 hcursorOld = SetCursor(LoadCursor(NULL, IDC_WAIT));
513 SendMessageW(hwndTV, WM_SETREDRAW, FALSE, 0);
514
515 keyPath = GetItemPath(hwndTV, pnmtv->itemNew.hItem, &hRoot);
516 if (!keyPath) goto done;
517
518 if (*keyPath)
519 {
520 errCode = RegOpenKeyExW(hRoot, keyPath, 0, KEY_READ, &hNewKey);
521 if (errCode != ERROR_SUCCESS) goto done;
522 }
523 else
524 {
525 hNewKey = hRoot;
526 }
527
528 errCode = RegQueryInfoKeyW(hNewKey, 0, 0, 0, &dwCount, &dwMaxSubKeyLen, 0, 0, 0, 0, 0, 0);
529 if (errCode != ERROR_SUCCESS) goto done;
530 dwMaxSubKeyLen++; /* account for the \0 terminator */
531 Name = HeapAlloc(GetProcessHeap(), 0, dwMaxSubKeyLen * sizeof(WCHAR));
532 if (!Name) goto done;
533
534 for (dwIndex = 0; dwIndex < dwCount; dwIndex++)
535 {
536 DWORD cName = dwMaxSubKeyLen, dwSubCount;
537
538 errCode = RegEnumKeyExW(hNewKey, dwIndex, Name, &cName, 0, 0, 0, 0);
539 if (errCode != ERROR_SUCCESS) continue;
540 errCode = RegOpenKeyExW(hNewKey, Name, 0, KEY_QUERY_VALUE, &hKey);
541 if (errCode == ERROR_SUCCESS)
542 {
543 errCode = RegQueryInfoKeyW(hKey, 0, 0, 0, &dwSubCount, 0, 0, 0, 0, 0, 0, 0);
545 }
546 if (errCode != ERROR_SUCCESS) dwSubCount = 0;
547 AddEntryToTree(hwndTV, pnmtv->itemNew.hItem, Name, NULL, dwSubCount);
548 }
549
550 SendMessageW(hwndTV, TVM_SORTCHILDREN, 0, (LPARAM)pnmtv->itemNew.hItem);
551
552 RegCloseKey(hNewKey);
554
555done:
556 SendMessageW(hwndTV, WM_SETREDRAW, TRUE, 0);
557 SetCursor(hcursorOld);
558 expanding = FALSE;
559
560 return TRUE;
561}
562
564{
565 WCHAR szNewKeyFormat[128];
566 WCHAR szNewKey[128];
567 LPCWSTR pszKeyPath;
568 int iIndex = 1;
569 LONG nResult;
570 HKEY hRootKey = NULL, hKey = NULL, hNewKey = NULL;
572 DWORD dwDisposition;
573 HTREEITEM hNewItem;
574
575 pszKeyPath = GetItemPath(hwndTV, hItem, &hRootKey);
576 if (!pszKeyPath)
577 return bSuccess;
578 if (pszKeyPath[0] == L'\0')
579 hKey = hRootKey;
580 else if (RegOpenKeyW(hRootKey, pszKeyPath, &hKey) != ERROR_SUCCESS)
581 goto done;
582
583 if (LoadStringW(hInst, IDS_NEW_KEY, szNewKeyFormat, ARRAY_SIZE(szNewKeyFormat)) <= 0)
584 goto done;
585
586 /* Need to create a new key with a unique name */
587 do
588 {
589 wsprintf(szNewKey, szNewKeyFormat, iIndex++);
590 nResult = RegCreateKeyExW(hKey, szNewKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hNewKey, &dwDisposition);
591 if (hNewKey && dwDisposition == REG_OPENED_EXISTING_KEY)
592 {
593 RegCloseKey(hNewKey);
594 hNewKey = NULL;
595 }
596 else if (!hNewKey)
597 {
598 InfoMessageBox(hFrameWnd, MB_OK | MB_ICONERROR, NULL, L"Cannot create new key!\n\nError Code: %d", nResult);
599 goto done;
600 }
601 }
602 while(!hNewKey);
603
604 /* Insert the new key */
605 hNewItem = InsertNode(hwndTV, hItem, szNewKey);
606 if (!hNewItem)
607 goto done;
608
609 /* The new key's name is probably not appropriate yet */
610 (void)TreeView_EditLabel(hwndTV, hNewItem);
611
612 bSuccess = TRUE;
613
614done:
615 if (hKey != hRootKey && hKey)
617 if (hNewKey)
618 RegCloseKey(hNewKey);
619 return bSuccess;
620}
621
623{
625 *Result = TRUE;
626
627 switch (((LPNMHDR)lParam)->code)
628 {
631 return TRUE;
632 case TVN_SELCHANGED:
633 {
634 NMTREEVIEW* pnmtv = (NMTREEVIEW*)lParam;
635 /* Get the parent of the current item */
636 HTREEITEM hParentItem = TreeView_GetParent(g_pChildWnd->hTreeWnd, pnmtv->itemNew.hItem);
637
638 UpdateAddress(pnmtv->itemNew.hItem, NULL, NULL, TRUE);
639
640 /* Disable the Permissions and new key menu items for 'My Computer' */
643
644 /*
645 * Disable Delete/Rename menu options for 'My Computer' (first item so doesn't have any parent)
646 * and HKEY_* keys (their parent is 'My Computer' and the previous remark applies).
647 */
648 if (!hParentItem || !TreeView_GetParent(g_pChildWnd->hTreeWnd, hParentItem))
649 {
654 }
655 else
656 {
661 }
662
663 return TRUE;
664 }
665 case NM_SETFOCUS:
667 break;
669 {
671 /* cancel label edit for rootkeys */
672 if (!TreeView_GetParent(g_pChildWnd->hTreeWnd, ptvdi->item.hItem) ||
674 {
675 *Result = TRUE;
676 }
677 else
678 {
679 *Result = FALSE;
680 }
681 return TRUE;
682 }
683 case TVN_ENDLABELEDIT:
684 {
685 LPCWSTR keyPath;
686 HKEY hRootKey;
687 HKEY hKey = NULL;
689 LONG nRenResult;
690 LONG lResult = TRUE;
691 WCHAR szBuffer[MAX_PATH];
692 WCHAR Caption[128];
693
694 if (ptvdi->item.pszText)
695 {
696 keyPath = GetItemPath(g_pChildWnd->hTreeWnd, TreeView_GetParent(g_pChildWnd->hTreeWnd, ptvdi->item.hItem), &hRootKey);
697 if (wcslen(keyPath))
698 _snwprintf(szBuffer, ARRAY_SIZE(szBuffer), L"%s\\%s", keyPath, ptvdi->item.pszText);
699 else
700 _snwprintf(szBuffer, ARRAY_SIZE(szBuffer), L"%s", ptvdi->item.pszText);
701 keyPath = GetItemPath(g_pChildWnd->hTreeWnd, ptvdi->item.hItem, &hRootKey);
702 if (RegOpenKeyExW(hRootKey, szBuffer, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
703 {
704 lResult = FALSE;
706 TreeView_EditLabel(g_pChildWnd->hTreeWnd, ptvdi->item.hItem);
707 }
708 else
709 {
710 nRenResult = RenameKey(hRootKey, keyPath, ptvdi->item.pszText);
711 if (nRenResult != ERROR_SUCCESS)
712 {
713 LoadStringW(hInst, IDS_ERROR, Caption, ARRAY_SIZE(Caption));
714 ErrorMessageBox(hWnd, Caption, nRenResult);
715 lResult = FALSE;
716 }
717 else
718 UpdateAddress(ptvdi->item.hItem, hRootKey, szBuffer, FALSE);
719 }
720 *Result = lResult;
721 }
722 return TRUE;
723 }
724 }
725 return FALSE;
726}
727
728/*
729 * CreateTreeView - creates a tree view control.
730 * Returns the handle to the new control if successful, or NULL otherwise.
731 * hwndParent - handle to the control's parent window.
732 */
734{
735 RECT rcClient;
736 HWND hwndTV;
737
738 /* Get the dimensions of the parent window's client area, and create the tree view control. */
739 GetClientRect(hwndParent, &rcClient);
742 0, 0, rcClient.right, rcClient.bottom,
743 hwndParent, id, hInst, NULL);
744 if (!hwndTV) return NULL;
745
746 /* Initialize the image list, and add items to the control. */
747 if (!InitTreeViewImageLists(hwndTV) || !InitTreeViewItems(hwndTV, pHostName))
748 {
749 DestroyWindow(hwndTV);
750 return NULL;
751 }
752 return hwndTV;
753}
754
756{
758
760
761 /* Destroy the image list associated with the tree view control */
764}
765
766BOOL SelectNode(HWND hwndTV, LPCWSTR keyPath)
767{
769 HTREEITEM hChildItem;
770 WCHAR szPathPart[128];
771 WCHAR szBuffer[128];
772 LPCWSTR s;
773 TVITEMW tvi;
774
775 /* Load "My Computer" string... */
776 LoadStringW(hInst, IDS_MY_COMPUTER, szBuffer, ARRAY_SIZE(szBuffer));
777 StringCbCatW(szBuffer, sizeof(szBuffer), L"\\");
778
779 /* ... and remove it from the key path */
780 if (!_wcsnicmp(keyPath, szBuffer, wcslen(szBuffer)))
781 keyPath += wcslen(szBuffer);
782
783 /* Reinitialize szBuffer */
784 szBuffer[0] = L'\0';
785
786 hRoot = TreeView_GetRoot(hwndTV);
787 hItem = hRoot;
788
789 while(keyPath[0])
790 {
791 size_t copyLength;
792 s = wcschr(keyPath, L'\\');
793 if (s != NULL)
794 {
795 copyLength = (s - keyPath) * sizeof(WCHAR);
796 }
797 else
798 {
799 copyLength = sizeof(szPathPart);
800 }
801 StringCbCopyNW(szPathPart, sizeof(szPathPart), keyPath, copyLength);
802
803 /* Special case for root to expand root key abbreviations */
804 if (hItem == hRoot)
805 {
806 if (!_wcsicmp(szPathPart, L"HKCR"))
807 StringCbCopyW(szPathPart, sizeof(szPathPart), L"HKEY_CLASSES_ROOT");
808 else if (!_wcsicmp(szPathPart, L"HKCU"))
809 StringCbCopyW(szPathPart, sizeof(szPathPart), L"HKEY_CURRENT_USER");
810 else if (!_wcsicmp(szPathPart, L"HKLM"))
811 StringCbCopyW(szPathPart, sizeof(szPathPart), L"HKEY_LOCAL_MACHINE");
812 else if (!_wcsicmp(szPathPart, L"HKU"))
813 StringCbCopyW(szPathPart, sizeof(szPathPart), L"HKEY_USERS");
814 else if (!_wcsicmp(szPathPart, L"HKCC"))
815 StringCbCopyW(szPathPart, sizeof(szPathPart), L"HKEY_CURRENT_CONFIG");
816 else if (!_wcsicmp(szPathPart, L"HKDD"))
817 StringCbCopyW(szPathPart, sizeof(szPathPart), L"HKEY_DYN_DATA");
818 }
819
820 for (hChildItem = TreeView_GetChild(hwndTV, hItem); hChildItem;
821 hChildItem = TreeView_GetNextSibling(hwndTV, hChildItem))
822 {
823 memset(&tvi, 0, sizeof(tvi));
824 tvi.hItem = hChildItem;
826 tvi.pszText = szBuffer;
827 tvi.cchTextMax = ARRAY_SIZE(szBuffer);
828
829 (void)TreeView_GetItem(hwndTV, &tvi);
830
831 if (!_wcsicmp(szBuffer, szPathPart))
832 break;
833 }
834
835 if (!hChildItem)
836 return FALSE;
837
838 if (tvi.cChildren > 0)
839 {
840 if (!TreeView_Expand(hwndTV, hChildItem, TVE_EXPAND))
841 return FALSE;
842 }
843
844 keyPath = s ? s + 1 : L"";
845 hItem = hChildItem;
846 }
847
850
851 return TRUE;
852}
853
854/* EOF */
struct NameRec_ * Name
Definition: cdprocs.h:460
HWND hWnd
Definition: settings.c:17
#define IDS_ERROR
Definition: resource.h:18
ChildWnd * g_pChildWnd
Definition: childwnd.c:13
VOID UpdateAddress(HTREEITEM hItem, HKEY hRootKey, LPCWSTR pszPath, BOOL bSelectNone)
Definition: childwnd.c:300
LONG RenameKey(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpNewName)
Definition: edit.c:1971
int InfoMessageBox(HWND hWnd, UINT uType, LPCWSTR lpTitle, LPCWSTR lpMessage,...)
Definition: error.c:38
int ErrorMessageBox(HWND hWnd, LPCWSTR lpTitle, DWORD dwErrorCode,...)
Definition: error.c:11
HMENU hPopupMenus
Definition: main.c:25
HWND hFrameWnd
Definition: main.c:22
HMENU hMenuFrame
Definition: main.c:24
#define ARRAY_SIZE(A)
Definition: main.h:20
#define MAX_NEW_KEY_LEN
Definition: main.h:28
#define IDS_MY_COMPUTER
Definition: resource.h:82
#define IDS_NEW_KEY
Definition: resource.h:145
#define ID_EDIT_DELETE
Definition: resource.h:43
#define ID_EDIT_NEW_KEY
Definition: resource.h:49
#define ID_EDIT_RENAME
Definition: resource.h:44
#define ID_TREE_RENAME
Definition: resource.h:105
#define ID_TREE_DELETE
Definition: resource.h:104
#define ID_EDIT_PERMISSIONS
Definition: resource.h:103
BOOL DeleteNode(HWND hwndTV, HTREEITEM hItem)
Definition: treeview.c:99
static BOOL InitTreeViewImageLists(HWND hwndTV)
Definition: treeview.c:434
HWND CreateTreeView(HWND hwndParent, LPWSTR pHostName, HMENU id)
Definition: treeview.c:733
static HTREEITEM AddEntryToTree(HWND hwndTV, HTREEITEM hParent, LPWSTR label, HKEY hKey, DWORD dwChildren)
Definition: treeview.c:107
void DestroyTreeView(HWND hwndTV)
Definition: treeview.c:755
BOOL RefreshTreeItem(HWND hwndTV, HTREEITEM hItem)
Definition: treeview.c:133
BOOL SelectNode(HWND hwndTV, LPCWSTR keyPath)
Definition: treeview.c:766
BOOL TreeWndNotifyProc(HWND hWnd, WPARAM wParam, LPARAM lParam, BOOL *Result)
Definition: treeview.c:622
#define IDI_SHELL_FOLDER
Definition: treeview.c:21
BOOL OnTreeExpanding(HWND hwndTV, NMTREEVIEW *pnmtv)
Definition: treeview.c:496
LPCWSTR GetItemPath(HWND hwndTV, HTREEITEM hItem, HKEY *phRootKey)
Definition: treeview.c:73
#define NUM_ICONS
Definition: treeview.c:18
static int Image_Open
Definition: treeview.c:12
HWND StartKeyRename(HWND hwndTV)
Definition: treeview.c:380
static BOOL get_item_path(HWND hwndTV, HTREEITEM hItem, HKEY *phKey, LPWSTR *pKeyPath, int *pPathLen, int *pMaxLen)
Definition: treeview.c:25
static BOOL InitTreeViewItems(HWND hwndTV, LPWSTR pHostName)
Definition: treeview.c:388
BOOL RefreshTreeView(HWND hwndTV)
Definition: treeview.c:303
static int Image_Root
Definition: treeview.c:14
HTREEITEM InsertNode(HWND hwndTV, HTREEITEM hItem, LPWSTR name)
Definition: treeview.c:328
#define IDI_SHELL_MY_COMPUTER
Definition: treeview.c:23
static int Image_Closed
Definition: treeview.c:13
static LPWSTR pathBuffer
Definition: treeview.c:16
#define IDI_SHELL_FOLDER_OPEN
Definition: treeview.c:22
BOOL CreateNewKey(HWND hwndTV, HTREEITEM hItem)
Definition: treeview.c:563
HANDLE HKEY
Definition: registry.h:26
#define RegCloseKey(hKey)
Definition: registry.h:49
HICON hico
HIMAGELIST himl
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
static HWND hwndParent
Definition: cryptui.c:300
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
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:1096
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
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:2504
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3268
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:3662
BOOL WINAPI ImageList_Destroy(HIMAGELIST himl)
Definition: imagelist.c:928
INT WINAPI ImageList_GetImageCount(HIMAGELIST himl)
Definition: imagelist.c:2063
HIMAGELIST WINAPI ImageList_Create(INT cx, INT cy, UINT flags, INT cInitial, INT cGrow)
Definition: imagelist.c:804
#define wcschr
Definition: compat.h:17
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
static BOOLEAN bSuccess
Definition: drive.cpp:477
HINSTANCE hInst
Definition: dxdiag.c:13
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxAutoRegKey hKey
GLdouble s
Definition: gl.h:2039
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLsizei len
Definition: glext.h:6722
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format,...)
static HICON
Definition: imagelist.c:80
static HTREEITEM hRoot
Definition: treeview.c:383
static const WCHAR label[]
Definition: itemdlg.c:1546
static HMODULE hShell32
Definition: string.c:34
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:63
static ATOM item
Definition: dde.c:856
#define KEY_READ
Definition: nt_native.h:1023
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define KEY_WRITE
Definition: nt_native.h:1031
#define DWORD
Definition: nt_native.h:44
#define REG_OPENED_EXISTING_KEY
Definition: nt_native.h:1085
#define UNICODE_NULL
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define L(x)
Definition: ntvdm.h:50
#define WS_CHILD
Definition: pedump.c:617
#define WS_TABSTOP
Definition: pedump.c:634
#define WS_VISIBLE
Definition: pedump.c:620
long LONG
Definition: pedump.c:60
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:586
#define TVN_SELCHANGED
Definition: commctrl.h:3740
#define TreeView_Select(hwnd, hitem, code)
Definition: commctrl.h:3484
#define TVS_LINESATROOT
Definition: commctrl.h:3254
#define TVI_LAST
Definition: commctrl.h:3375
#define TVIF_TEXT
Definition: commctrl.h:3271
#define TreeView_SelectItem(hwnd, hitem)
Definition: commctrl.h:3486
#define TreeView_Expand(hwnd, hitem, code)
Definition: commctrl.h:3425
#define TreeView_GetChild(hwnd, hitem)
Definition: commctrl.h:3471
#define TVN_BEGINLABELEDIT
Definition: commctrl.h:3748
#define TVIF_IMAGE
Definition: commctrl.h:3272
#define TVIS_EXPANDEDONCE
Definition: commctrl.h:3290
#define TVSIL_NORMAL
Definition: commctrl.h:3448
#define TreeView_EnsureVisible(hwnd, hitem)
Definition: commctrl.h:3550
#define TreeView_GetItemState(hwndTV, hti, mask)
Definition: commctrl.h:3600
_Out_opt_ int * cx
Definition: commctrl.h:585
#define TVI_FIRST
Definition: commctrl.h:3374
#define TreeView_GetParent(hwnd, hitem)
Definition: commctrl.h:3474
#define TVS_SHOWSELALWAYS
Definition: commctrl.h:3257
#define ILC_COLOR32
Definition: commctrl.h:358
#define TreeView_GetImageList(hwnd, iImage)
Definition: commctrl.h:3446
#define TreeView_GetSelection(hwnd)
Definition: commctrl.h:3478
#define TreeView_GetItem(hwnd, pitem)
Definition: commctrl.h:3495
struct _TREEITEM * HTREEITEM
Definition: commctrl.h:3269
#define TVN_ENDLABELEDIT
Definition: commctrl.h:3749
#define TVS_HASLINES
Definition: commctrl.h:3253
#define TVE_EXPAND
Definition: commctrl.h:3428
#define TVI_ROOT
Definition: commctrl.h:3373
#define TVM_SORTCHILDREN
Definition: commctrl.h:3546
#define WC_TREEVIEW
Definition: commctrl.h:3250
#define NMTREEVIEW
Definition: commctrl.h:3647
#define TreeView_GetRoot(hwnd)
Definition: commctrl.h:3480
#define TVIF_HANDLE
Definition: commctrl.h:3275
#define TreeView_GetNextSibling(hwnd, hitem)
Definition: commctrl.h:3472
#define TVIS_EXPANDED
Definition: commctrl.h:3289
#define ImageList_AddIcon(himl, hicon)
Definition: commctrl.h:415
#define NM_SETFOCUS
Definition: commctrl.h:135
#define TVN_ITEMEXPANDING
Definition: commctrl.h:3743
#define TVGN_CARET
Definition: commctrl.h:3466
#define TVS_HASBUTTONS
Definition: commctrl.h:3252
#define ILC_MASK
Definition: commctrl.h:351
#define TreeView_EditLabel(hwnd, hitem)
Definition: commctrl.h:3509
#define TVIF_PARAM
Definition: commctrl.h:3273
#define LPNMTVDISPINFO
Definition: commctrl.h:3681
#define TVS_EDITLABELS
Definition: commctrl.h:3255
#define TreeView_SetImageList(hwnd, himl, iImage)
Definition: commctrl.h:3452
#define TVIF_CHILDREN
Definition: commctrl.h:3277
#define TreeView_InsertItem(hwnd, lpis)
Definition: commctrl.h:3417
#define TVIF_SELECTEDIMAGE
Definition: commctrl.h:3276
#define TreeView_SetItem(hwnd, pitem)
Definition: commctrl.h:3502
#define TVIF_STATE
Definition: commctrl.h:3274
#define TreeView_DeleteItem(hwnd, hitem)
Definition: commctrl.h:3420
DWORD WINAPI GetVersion()
Definition: redirtest.c:5
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
_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)
#define memset(x, y, z)
Definition: compat.h:39
STRSAFEAPI StringCbCopyNW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszSrc, size_t cbToCopy)
Definition: strsafe.h:255
STRSAFEAPI StringCbCopyW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:166
STRSAFEAPI StringCbCatW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:342
int nFocusPanel
Definition: main.h:55
HWND hTreeWnd
Definition: main.h:50
Definition: inflate.c:139
Definition: name.c:39
LONG right
Definition: windef.h:308
LONG bottom
Definition: windef.h:309
HTREEITEM hParent
Definition: commctrl.h:3398
HTREEITEM hInsertAfter
Definition: commctrl.h:3399
HTREEITEM hItem
Definition: commctrl.h:3322
LPARAM lParam
Definition: commctrl.h:3330
UINT mask
Definition: commctrl.h:3321
LPWSTR pszText
Definition: commctrl.h:3325
int cchTextMax
Definition: commctrl.h:3326
int iImage
Definition: commctrl.h:3327
int cChildren
Definition: commctrl.h:3329
int iSelectedImage
Definition: commctrl.h:3328
HTREEITEM hItem
Definition: treelist.h:37
int32_t INT
Definition: typedefs.h:58
SIZE_T WINAPI HeapSize(HANDLE, DWORD, LPCVOID)
LONG_PTR LPARAM
Definition: windef.h:208
UINT_PTR WPARAM
Definition: windef.h:207
HICON HCURSOR
Definition: windef.h:299
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_CURRENT_CONFIG
Definition: winreg.h:15
#define HKEY_DYN_DATA
Definition: winreg.h:16
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
#define HKEY_USERS
Definition: winreg.h:13
#define MF_BYCOMMAND
Definition: winuser.h:202
#define IMAGE_ICON
Definition: winuser.h:212
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
HANDLE WINAPI LoadImageW(_In_opt_ HINSTANCE hInst, _In_ LPCWSTR name, _In_ UINT type, _In_ int cx, _In_ int cy, _In_ UINT fuLoad)
Definition: cursoricon.c:2255
#define SM_CYSMICON
Definition: winuser.h:1016
HCURSOR WINAPI SetCursor(_In_opt_ HCURSOR)
#define MB_ICONERROR
Definition: winuser.h:790
#define SM_CXSMICON
Definition: winuser.h:1015
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
#define MF_ENABLED
Definition: winuser.h:128
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 LoadCursor
Definition: winuser.h:5824
#define MB_OK
Definition: winuser.h:793
#define wsprintf
Definition: winuser.h:5877
#define IDC_WAIT
Definition: winuser.h:689
#define LR_DEFAULTCOLOR
Definition: winuser.h:1090
#define WS_EX_CLIENTEDGE
Definition: winuser.h:384
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
BOOL WINAPI DestroyWindow(_In_ HWND)
BOOL WINAPI EnableMenuItem(_In_ HMENU, _In_ UINT, _In_ UINT)
int WINAPI GetSystemMetrics(_In_ int)
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
BOOL WINAPI DestroyIcon(_In_ HICON)
Definition: cursoricon.c:2105
#define MF_GRAYED
Definition: winuser.h:129
#define WM_SETREDRAW
Definition: winuser.h:1619
_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:409
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185