ReactOS 0.4.15-dev-8339-g4028de8
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. */
27static int Image_Open = 0;
28static int Image_Closed = 0;
29static 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
40static BOOL get_item_path(HWND hwndTV, HTREEITEM hItem, HKEY* phKey, LPWSTR* pKeyPath, int* pPathLen, int* pMaxLen)
41{
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
94 if (!pathBuffer)
95 {
97 }
98 if (!pathBuffer)
99 {
100 return NULL;
101 }
102
104
105 maxLen = (int) HeapSize(GetProcessHeap(), 0, pathBuffer);
106
107 if (!hItem)
108 {
110 }
111 if (maxLen == -1 || !hItem || !get_item_path(hwndTV, hItem, phRootKey, &pathBuffer, &pathLen, &maxLen))
112 {
113 return NULL;
114 }
115 return pathBuffer;
116}
117
119{
120 if (!hItem) hItem = TreeView_GetSelection(hwndTV);
121 if (!hItem) return FALSE;
122 return TreeView_DeleteItem(hwndTV, hItem);
123}
124
125/* Add an entry to the tree. Only give hKey for root nodes (HKEY_ constants) */
126static HTREEITEM AddEntryToTree(HWND hwndTV, HTREEITEM hParent, LPWSTR label, HKEY hKey, DWORD dwChildren)
127{
128 TVITEMW tvi;
129 TVINSERTSTRUCTW tvins;
130
131 if (hKey)
132 {
133 if (RegQueryInfoKeyW(hKey, 0, 0, 0, &dwChildren, 0, 0, 0, 0, 0, 0, 0) != ERROR_SUCCESS)
134 {
135 dwChildren = 0;
136 }
137 }
138
140 tvi.pszText = label;
141 tvi.cchTextMax = wcslen(tvi.pszText);
142 tvi.iImage = Image_Closed;
144 tvi.cChildren = dwChildren;
145 tvi.lParam = (LPARAM)hKey;
146 tvins.item = tvi;
148 tvins.hParent = hParent;
149 return TreeView_InsertItem(hwndTV, &tvins);
150}
151
153{
154 HKEY hRoot, hKey, hSubKey;
155 HTREEITEM childItem;
156 LPCWSTR KeyPath;
157 DWORD dwCount, dwIndex, dwMaxSubKeyLen;
158 LPWSTR Name = NULL;
159 TVITEMW tvItem;
160 LPWSTR pszNodes = NULL;
162 LPWSTR s;
163 BOOL bAddedAny;
164
165 KeyPath = GetItemPath(hwndTV, hItem, &hRoot);
166
167 if (*KeyPath)
168 {
169 if (RegOpenKeyExW(hRoot, KeyPath, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
170 {
171 goto done;
172 }
173 }
174 else
175 {
176 hKey = hRoot;
177 }
178
179 if (RegQueryInfoKeyW(hKey, 0, 0, 0, &dwCount, &dwMaxSubKeyLen, 0, 0, 0, 0, 0, 0) != ERROR_SUCCESS)
180 {
181 goto done;
182 }
183
184 /* Set the number of children again */
185 tvItem.mask = TVIF_CHILDREN;
186 tvItem.hItem = hItem;
187 tvItem.cChildren = dwCount;
188 if (!TreeView_SetItem(hwndTV, &tvItem))
189 {
190 goto done;
191 }
192
193 /* We don't have to bother with the rest if it's not expanded. */
194 if (TreeView_GetItemState(hwndTV, hItem, TVIS_EXPANDED) == 0)
195 {
197 bSuccess = TRUE;
198 goto done;
199 }
200
201 dwMaxSubKeyLen++; /* account for the \0 terminator */
202 if (!(Name = HeapAlloc(GetProcessHeap(), 0, dwMaxSubKeyLen * sizeof(WCHAR))))
203 {
204 goto done;
205 }
206 tvItem.cchTextMax = dwMaxSubKeyLen;
207 /*if (!(tvItem.pszText = HeapAlloc(GetProcessHeap(), 0, dwMaxSubKeyLen * sizeof(WCHAR)))) {
208 goto done;
209 }*/
210
211 /* Get all of the tree node siblings in one contiguous block of memory */
212 {
213 DWORD dwPhysicalSize = 0;
214 DWORD dwActualSize = 0;
215 DWORD dwNewPhysicalSize;
216 LPWSTR pszNewNodes;
217 DWORD dwStep = 10000;
218
219 for (childItem = TreeView_GetChild(hwndTV, hItem); childItem;
220 childItem = TreeView_GetNextSibling(hwndTV, childItem))
221 {
222
223 if (dwActualSize + dwMaxSubKeyLen + 1 > dwPhysicalSize)
224 {
225 dwNewPhysicalSize = dwActualSize + dwMaxSubKeyLen + 1 + dwStep;
226
227 if (pszNodes)
228 pszNewNodes = (LPWSTR) HeapReAlloc(GetProcessHeap(), 0, pszNodes, dwNewPhysicalSize * sizeof(WCHAR));
229 else
230 pszNewNodes = (LPWSTR) HeapAlloc(GetProcessHeap(), 0, dwNewPhysicalSize * sizeof(WCHAR));
231 if (!pszNewNodes)
232 goto done;
233
234 dwPhysicalSize = dwNewPhysicalSize;
235 pszNodes = pszNewNodes;
236 }
237
238 tvItem.mask = TVIF_TEXT;
239 tvItem.hItem = childItem;
240 tvItem.pszText = &pszNodes[dwActualSize];
241 tvItem.cchTextMax = dwPhysicalSize - dwActualSize;
242 if (!TreeView_GetItem(hwndTV, &tvItem))
243 goto done;
244
245 dwActualSize += (DWORD) wcslen(&pszNodes[dwActualSize]) + 1;
246 }
247
248 if (pszNodes)
249 pszNodes[dwActualSize] = L'\0';
250 }
251
252 /* Now go through all the children in the tree, and check if any have to be removed. */
253 childItem = TreeView_GetChild(hwndTV, hItem);
254 while (childItem)
255 {
256 HTREEITEM nextItem = TreeView_GetNextSibling(hwndTV, childItem);
257 if (RefreshTreeItem(hwndTV, childItem) == FALSE)
258 {
259 (void)TreeView_DeleteItem(hwndTV, childItem);
260 }
261 childItem = nextItem;
262 }
263
264 /* Now go through all the children in the registry, and check if any have to be added. */
265 bAddedAny = FALSE;
266 for (dwIndex = 0; dwIndex < dwCount; dwIndex++)
267 {
268 DWORD cName = dwMaxSubKeyLen, dwSubCount;
269 BOOL found;
270
271 found = FALSE;
272 if (RegEnumKeyExW(hKey, dwIndex, Name, &cName, 0, 0, 0, NULL) != ERROR_SUCCESS)
273 {
274 continue;
275 }
276
277 /* Check if the node is already in there. */
278 if (pszNodes)
279 {
280 for (s = pszNodes; *s; s += wcslen(s) + 1)
281 {
282 if (!wcscmp(s, Name))
283 {
284 found = TRUE;
285 break;
286 }
287 }
288 }
289
290 if (found == FALSE)
291 {
292 /* Find the number of children of the node. */
293 dwSubCount = 0;
294 if (RegOpenKeyExW(hKey, Name, 0, KEY_QUERY_VALUE, &hSubKey) == ERROR_SUCCESS)
295 {
296 if (RegQueryInfoKeyW(hSubKey, 0, 0, 0, &dwSubCount, 0, 0, 0, 0, 0, 0, 0) != ERROR_SUCCESS)
297 {
298 dwSubCount = 0;
299 }
300 RegCloseKey(hSubKey);
301 }
302
303 AddEntryToTree(hwndTV, hItem, Name, NULL, dwSubCount);
304 bAddedAny = TRUE;
305 }
306 }
308
309 if (bAddedAny)
311
312 bSuccess = TRUE;
313
314done:
315 if (pszNodes)
316 HeapFree(GetProcessHeap(), 0, pszNodes);
317 if (Name)
319 return bSuccess;
320}
321
323{
325 HTREEITEM hSelectedItem;
326 HCURSOR hcursorOld;
327
328 hSelectedItem = TreeView_GetSelection(hwndTV);
329 hcursorOld = SetCursor(LoadCursor(NULL, IDC_WAIT));
330 SendMessageW(hwndTV, WM_SETREDRAW, FALSE, 0);
331
332 hItem = TreeView_GetChild(hwndTV, TreeView_GetRoot(hwndTV));
333 while (hItem)
334 {
335 RefreshTreeItem(hwndTV, hItem);
337 }
338
339 SendMessageW(hwndTV, WM_SETREDRAW, TRUE, 0);
340 SetCursor(hcursorOld);
341
342 /* We reselect the currently selected node, this will prompt a refresh of the listview. */
343 (void)TreeView_SelectItem(hwndTV, hSelectedItem);
344 return TRUE;
345}
346
348{
350 HTREEITEM hNewItem = 0;
352
353 /* Default to the current selection */
354 if (!hItem)
355 {
357 if (!hItem)
358 return FALSE;
359 }
360
361 memset(&item, 0, sizeof(item));
362 item.hItem = hItem;
364 if (!TreeView_GetItem(hwndTV, &item))
365 return FALSE;
366
367 if (item.state & TVIS_EXPANDEDONCE)
368 {
369 hNewItem = AddEntryToTree(hwndTV, hItem, name, 0, 0);
371 }
372 else
373 {
375 item.hItem = hItem;
376 item.cChildren = 1;
377 if (!TreeView_SetItem(hwndTV, &item))
378 return FALSE;
379 }
380
382 if (!hNewItem)
383 {
384 for(hNewItem = TreeView_GetChild(hwndTV, hItem); hNewItem; hNewItem = TreeView_GetNextSibling(hwndTV, hNewItem))
385 {
386 item.mask = TVIF_HANDLE | TVIF_TEXT;
387 item.hItem = hNewItem;
388 item.pszText = buf;
389 item.cchTextMax = ARRAY_SIZE(buf);
390 if (!TreeView_GetItem(hwndTV, &item)) continue;
391 if (wcscmp(name, item.pszText) == 0) break;
392 }
393 }
394 if (hNewItem) (void)TreeView_SelectItem(hwndTV, hNewItem);
395
396 return hNewItem;
397}
398
400{
402
403 if(!(hItem = TreeView_GetSelection(hwndTV))) return 0;
404 return TreeView_EditLabel(hwndTV, hItem);
405}
406
407static BOOL InitTreeViewItems(HWND hwndTV, LPWSTR pHostName)
408{
409 TVITEMW tvi;
410 TVINSERTSTRUCTW tvins;
412
414 /* Set the text of the item. */
415 tvi.pszText = pHostName;
416 tvi.cchTextMax = wcslen(tvi.pszText);
417 /* Assume the item is not a parent item, so give it an image. */
418 tvi.iImage = Image_Root;
420 tvi.cChildren = 5;
421 /* Save the heading level in the item's application-defined data area. */
422 tvi.lParam = (LPARAM)NULL;
423 tvins.item = tvi;
425 tvins.hParent = TVI_ROOT;
426 /* Add the item to the tree view control. */
427 if (!(hRoot = TreeView_InsertItem(hwndTV, &tvins))) return FALSE;
428
429 if (!AddEntryToTree(hwndTV, hRoot, L"HKEY_CLASSES_ROOT", HKEY_CLASSES_ROOT, 1)) return FALSE;
430 if (!AddEntryToTree(hwndTV, hRoot, L"HKEY_CURRENT_USER", HKEY_CURRENT_USER, 1)) return FALSE;
431 if (!AddEntryToTree(hwndTV, hRoot, L"HKEY_LOCAL_MACHINE", HKEY_LOCAL_MACHINE, 1)) return FALSE;
432 if (!AddEntryToTree(hwndTV, hRoot, L"HKEY_USERS", HKEY_USERS, 1)) return FALSE;
433 if (!AddEntryToTree(hwndTV, hRoot, L"HKEY_CURRENT_CONFIG", HKEY_CURRENT_CONFIG, 1)) return FALSE;
434
435 if (GetVersion() & 0x80000000)
436 {
437 /* Win9x specific key */
438 if (!AddEntryToTree(hwndTV, hRoot, L"HKEY_DYN_DATA", HKEY_DYN_DATA, 1)) return FALSE;
439 }
440
441 /* expand and select host name */
444 return TRUE;
445}
446
447
448/*
449 * InitTreeViewImageLists - creates an image list, adds three bitmaps
450 * to it, and associates the image list with a tree view control.
451 * Returns TRUE if successful, or FALSE otherwise.
452 * hwndTV - handle to the tree view control.
453 */
455{
456 HIMAGELIST himl; /* handle to image list */
457 HICON hico; /* handle to icon */
460 HMODULE hShell32 = GetModuleHandleW(L"shell32.dll");
461
462 /* Create the image list. */
464 return FALSE;
465
466 /* Add the open file, closed file, and document bitmaps. */
470 cx,
471 cy,
473 if (hico)
474 {
477 }
478
482 cx,
483 cy,
485 if (hico)
486 {
489 }
490
494 cx,
495 cy,
497 if (hico)
498 {
501 }
502
503 /* Fail if not all of the images were added. */
505 {
507 return FALSE;
508 }
509
510 /* Associate the image list with the tree view control. */
512
513 return TRUE;
514}
515
517{
518 DWORD dwCount, dwIndex, dwMaxSubKeyLen;
519 HKEY hRoot, hNewKey, hKey;
520 LPCWSTR keyPath;
521 LPWSTR Name;
522 LONG errCode;
523 HCURSOR hcursorOld;
524
525 static int expanding;
526 if (expanding) return FALSE;
527 if (pnmtv->itemNew.state & TVIS_EXPANDEDONCE )
528 {
529 return TRUE;
530 }
531 expanding = TRUE;
532 hcursorOld = SetCursor(LoadCursor(NULL, IDC_WAIT));
533 SendMessageW(hwndTV, WM_SETREDRAW, FALSE, 0);
534
535 keyPath = GetItemPath(hwndTV, pnmtv->itemNew.hItem, &hRoot);
536 if (!keyPath) goto done;
537
538 if (*keyPath)
539 {
540 errCode = RegOpenKeyExW(hRoot, keyPath, 0, KEY_READ, &hNewKey);
541 if (errCode != ERROR_SUCCESS) goto done;
542 }
543 else
544 {
545 hNewKey = hRoot;
546 }
547
548 errCode = RegQueryInfoKeyW(hNewKey, 0, 0, 0, &dwCount, &dwMaxSubKeyLen, 0, 0, 0, 0, 0, 0);
549 if (errCode != ERROR_SUCCESS) goto done;
550 dwMaxSubKeyLen++; /* account for the \0 terminator */
551 Name = HeapAlloc(GetProcessHeap(), 0, dwMaxSubKeyLen * sizeof(WCHAR));
552 if (!Name) goto done;
553
554 for (dwIndex = 0; dwIndex < dwCount; dwIndex++)
555 {
556 DWORD cName = dwMaxSubKeyLen, dwSubCount;
557
558 errCode = RegEnumKeyExW(hNewKey, dwIndex, Name, &cName, 0, 0, 0, 0);
559 if (errCode != ERROR_SUCCESS) continue;
560 errCode = RegOpenKeyExW(hNewKey, Name, 0, KEY_QUERY_VALUE, &hKey);
561 if (errCode == ERROR_SUCCESS)
562 {
563 errCode = RegQueryInfoKeyW(hKey, 0, 0, 0, &dwSubCount, 0, 0, 0, 0, 0, 0, 0);
565 }
566 if (errCode != ERROR_SUCCESS) dwSubCount = 0;
567 AddEntryToTree(hwndTV, pnmtv->itemNew.hItem, Name, NULL, dwSubCount);
568 }
569
570 SendMessageW(hwndTV, TVM_SORTCHILDREN, 0, (LPARAM)pnmtv->itemNew.hItem);
571
572 RegCloseKey(hNewKey);
574
575done:
576 SendMessageW(hwndTV, WM_SETREDRAW, TRUE, 0);
577 SetCursor(hcursorOld);
578 expanding = FALSE;
579
580 return TRUE;
581}
582
583
585{
586 WCHAR szNewKeyFormat[128];
587 WCHAR szNewKey[128];
588 LPCWSTR pszKeyPath;
589 int iIndex = 1;
590 LONG nResult;
591 HKEY hRootKey = NULL, hKey = NULL, hNewKey = NULL;
593 DWORD dwDisposition;
594 HTREEITEM hNewItem;
595
596 pszKeyPath = GetItemPath(hwndTV, hItem, &hRootKey);
597 if (!pszKeyPath)
598 return bSuccess;
599 if (pszKeyPath[0] == L'\0')
600 hKey = hRootKey;
601 else if (RegOpenKeyW(hRootKey, pszKeyPath, &hKey) != ERROR_SUCCESS)
602 goto done;
603
604 if (LoadStringW(hInst, IDS_NEW_KEY, szNewKeyFormat, ARRAY_SIZE(szNewKeyFormat)) <= 0)
605 goto done;
606
607 /* Need to create a new key with a unique name */
608 do
609 {
610 wsprintf(szNewKey, szNewKeyFormat, iIndex++);
611 nResult = RegCreateKeyExW(hKey, szNewKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hNewKey, &dwDisposition);
612 if (hNewKey && dwDisposition == REG_OPENED_EXISTING_KEY)
613 {
614 RegCloseKey(hNewKey);
615 hNewKey = NULL;
616 }
617 else if (!hNewKey)
618 {
619 InfoMessageBox(hFrameWnd, MB_OK | MB_ICONERROR, NULL, L"Cannot create new key!\n\nError Code: %d", nResult);
620 goto done;
621 }
622 }
623 while(!hNewKey);
624
625 /* Insert the new key */
626 hNewItem = InsertNode(hwndTV, hItem, szNewKey);
627 if (!hNewItem)
628 goto done;
629
630 /* The new key's name is probably not appropriate yet */
631 (void)TreeView_EditLabel(hwndTV, hNewItem);
632
633 bSuccess = TRUE;
634
635done:
636 if (hKey != hRootKey && hKey)
638 if (hNewKey)
639 RegCloseKey(hNewKey);
640 return bSuccess;
641}
642
644{
646 *Result = TRUE;
647
648 switch (((LPNMHDR)lParam)->code)
649 {
652 return TRUE;
653 case TVN_SELCHANGED:
654 {
655 NMTREEVIEW* pnmtv = (NMTREEVIEW*)lParam;
656 /* Get the parent of the current item */
657 HTREEITEM hParentItem = TreeView_GetParent(g_pChildWnd->hTreeWnd, pnmtv->itemNew.hItem);
658
659 UpdateAddress(pnmtv->itemNew.hItem, NULL, NULL, TRUE);
660
661 /* Disable the Permissions and new key menu items for 'My Computer' */
664
665 /*
666 * Disable Delete/Rename menu options for 'My Computer' (first item so doesn't have any parent)
667 * and HKEY_* keys (their parent is 'My Computer' and the previous remark applies).
668 */
669 if (!hParentItem || !TreeView_GetParent(g_pChildWnd->hTreeWnd, hParentItem))
670 {
675 }
676 else
677 {
682 }
683
684 return TRUE;
685 }
686 case NM_SETFOCUS:
688 break;
690 {
692 /* cancel label edit for rootkeys */
693 if (!TreeView_GetParent(g_pChildWnd->hTreeWnd, ptvdi->item.hItem) ||
695 {
696 *Result = TRUE;
697 }
698 else
699 {
700 *Result = FALSE;
701 }
702 return TRUE;
703 }
704 case TVN_ENDLABELEDIT:
705 {
706 LPCWSTR keyPath;
707 HKEY hRootKey;
708 HKEY hKey = NULL;
710 LONG nRenResult;
711 LONG lResult = TRUE;
712 WCHAR szBuffer[MAX_PATH];
713 WCHAR Caption[128];
714
715 if (ptvdi->item.pszText)
716 {
717 keyPath = GetItemPath(g_pChildWnd->hTreeWnd, TreeView_GetParent(g_pChildWnd->hTreeWnd, ptvdi->item.hItem), &hRootKey);
718 if (wcslen(keyPath))
719 _snwprintf(szBuffer, ARRAY_SIZE(szBuffer), L"%s\\%s", keyPath, ptvdi->item.pszText);
720 else
721 _snwprintf(szBuffer, ARRAY_SIZE(szBuffer), L"%s", ptvdi->item.pszText);
722 keyPath = GetItemPath(g_pChildWnd->hTreeWnd, ptvdi->item.hItem, &hRootKey);
723 if (RegOpenKeyExW(hRootKey, szBuffer, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
724 {
725 lResult = FALSE;
727 TreeView_EditLabel(g_pChildWnd->hTreeWnd, ptvdi->item.hItem);
728 }
729 else
730 {
731 nRenResult = RenameKey(hRootKey, keyPath, ptvdi->item.pszText);
732 if (nRenResult != ERROR_SUCCESS)
733 {
734 LoadStringW(hInst, IDS_ERROR, Caption, ARRAY_SIZE(Caption));
735 ErrorMessageBox(hWnd, Caption, nRenResult);
736 lResult = FALSE;
737 }
738 else
739 UpdateAddress(ptvdi->item.hItem, hRootKey, szBuffer, FALSE);
740 }
741 *Result = lResult;
742 }
743 return TRUE;
744 }
745 }
746 return FALSE;
747}
748
749/*
750 * CreateTreeView - creates a tree view control.
751 * Returns the handle to the new control if successful, or NULL otherwise.
752 * hwndParent - handle to the control's parent window.
753 */
755{
756 RECT rcClient;
757 HWND hwndTV;
758
759 /* Get the dimensions of the parent window's client area, and create the tree view control. */
760 GetClientRect(hwndParent, &rcClient);
763 0, 0, rcClient.right, rcClient.bottom,
764 hwndParent, id, hInst, NULL);
765 if (!hwndTV) return NULL;
766
767 /* Initialize the image list, and add items to the control. */
768 if (!InitTreeViewImageLists(hwndTV) || !InitTreeViewItems(hwndTV, pHostName))
769 {
770 DestroyWindow(hwndTV);
771 return NULL;
772 }
773 return hwndTV;
774}
775
777{
779
781
782 /* Destroy the image list associated with the tree view control */
785}
786
787BOOL SelectNode(HWND hwndTV, LPCWSTR keyPath)
788{
790 HTREEITEM hChildItem;
791 WCHAR szPathPart[128];
792 WCHAR szBuffer[128];
793 LPCWSTR s;
794 TVITEMW tvi;
795
796 /* Load "My Computer" string... */
797 LoadStringW(hInst, IDS_MY_COMPUTER, szBuffer, ARRAY_SIZE(szBuffer));
798 StringCbCatW(szBuffer, sizeof(szBuffer), L"\\");
799
800 /* ... and remove it from the key path */
801 if (!_wcsnicmp(keyPath, szBuffer, wcslen(szBuffer)))
802 keyPath += wcslen(szBuffer);
803
804 /* Reinitialize szBuffer */
805 szBuffer[0] = L'\0';
806
807 hRoot = TreeView_GetRoot(hwndTV);
808 hItem = hRoot;
809
810 while(keyPath[0])
811 {
812 size_t copyLength;
813 s = wcschr(keyPath, L'\\');
814 if (s != NULL)
815 {
816 copyLength = (s - keyPath) * sizeof(WCHAR);
817 }
818 else
819 {
820 copyLength = sizeof(szPathPart);
821 }
822 StringCbCopyNW(szPathPart, sizeof(szPathPart), keyPath, copyLength);
823
824 /* Special case for root to expand root key abbreviations */
825 if (hItem == hRoot)
826 {
827 if (!_wcsicmp(szPathPart, L"HKCR"))
828 StringCbCopyW(szPathPart, sizeof(szPathPart), L"HKEY_CLASSES_ROOT");
829 else if (!_wcsicmp(szPathPart, L"HKCU"))
830 StringCbCopyW(szPathPart, sizeof(szPathPart), L"HKEY_CURRENT_USER");
831 else if (!_wcsicmp(szPathPart, L"HKLM"))
832 StringCbCopyW(szPathPart, sizeof(szPathPart), L"HKEY_LOCAL_MACHINE");
833 else if (!_wcsicmp(szPathPart, L"HKU"))
834 StringCbCopyW(szPathPart, sizeof(szPathPart), L"HKEY_USERS");
835 else if (!_wcsicmp(szPathPart, L"HKCC"))
836 StringCbCopyW(szPathPart, sizeof(szPathPart), L"HKEY_CURRENT_CONFIG");
837 else if (!_wcsicmp(szPathPart, L"HKDD"))
838 StringCbCopyW(szPathPart, sizeof(szPathPart), L"HKEY_DYN_DATA");
839 }
840
841 for (hChildItem = TreeView_GetChild(hwndTV, hItem); hChildItem;
842 hChildItem = TreeView_GetNextSibling(hwndTV, hChildItem))
843 {
844 memset(&tvi, 0, sizeof(tvi));
845 tvi.hItem = hChildItem;
847 tvi.pszText = szBuffer;
848 tvi.cchTextMax = ARRAY_SIZE(szBuffer);
849
850 (void)TreeView_GetItem(hwndTV, &tvi);
851
852 if (!_wcsicmp(szBuffer, szPathPart))
853 break;
854 }
855
856 if (!hChildItem)
857 return FALSE;
858
859 if (tvi.cChildren > 0)
860 {
861 if (!TreeView_Expand(hwndTV, hChildItem, TVE_EXPAND))
862 return FALSE;
863 }
864
865 keyPath = s ? s + 1 : L"";
866 hItem = hChildItem;
867 }
868
871
872 return TRUE;
873}
874
875/* 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:24
VOID UpdateAddress(HTREEITEM hItem, HKEY hRootKey, LPCWSTR pszPath, BOOL bSelectNone)
Definition: childwnd.c:258
LONG RenameKey(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpNewName)
Definition: edit.c:2105
int InfoMessageBox(HWND hWnd, UINT uType, LPCWSTR lpTitle, LPCWSTR lpMessage,...)
Definition: error.c:51
int ErrorMessageBox(HWND hWnd, LPCWSTR lpTitle, DWORD dwErrorCode,...)
Definition: error.c:24
HMENU hPopupMenus
Definition: main.c:38
HWND hFrameWnd
Definition: main.c:35
HMENU hMenuFrame
Definition: main.c:37
#define ARRAY_SIZE(A)
Definition: main.h:33
#define MAX_NEW_KEY_LEN
Definition: main.h:41
#define IDS_MY_COMPUTER
Definition: resource.h:129
#define IDS_NEW_KEY
Definition: resource.h:192
#define ID_EDIT_DELETE
Definition: resource.h:57
#define ID_EDIT_NEW_KEY
Definition: resource.h:63
#define ID_EDIT_RENAME
Definition: resource.h:58
#define ID_TREE_RENAME
Definition: resource.h:152
#define ID_TREE_DELETE
Definition: resource.h:151
#define ID_EDIT_PERMISSIONS
Definition: resource.h:150
BOOL DeleteNode(HWND hwndTV, HTREEITEM hItem)
Definition: treeview.c:118
static BOOL InitTreeViewImageLists(HWND hwndTV)
Definition: treeview.c:454
HWND CreateTreeView(HWND hwndParent, LPWSTR pHostName, HMENU id)
Definition: treeview.c:754
static HTREEITEM AddEntryToTree(HWND hwndTV, HTREEITEM hParent, LPWSTR label, HKEY hKey, DWORD dwChildren)
Definition: treeview.c:126
void DestroyTreeView(HWND hwndTV)
Definition: treeview.c:776
BOOL RefreshTreeItem(HWND hwndTV, HTREEITEM hItem)
Definition: treeview.c:152
BOOL SelectNode(HWND hwndTV, LPCWSTR keyPath)
Definition: treeview.c:787
BOOL TreeWndNotifyProc(HWND hWnd, WPARAM wParam, LPARAM lParam, BOOL *Result)
Definition: treeview.c:643
#define IDI_SHELL_FOLDER
Definition: treeview.c:36
BOOL OnTreeExpanding(HWND hwndTV, NMTREEVIEW *pnmtv)
Definition: treeview.c:516
LPCWSTR GetItemPath(HWND hwndTV, HTREEITEM hItem, HKEY *phRootKey)
Definition: treeview.c:88
#define NUM_ICONS
Definition: treeview.c:33
static int Image_Open
Definition: treeview.c:27
HWND StartKeyRename(HWND hwndTV)
Definition: treeview.c:399
static BOOL get_item_path(HWND hwndTV, HTREEITEM hItem, HKEY *phKey, LPWSTR *pKeyPath, int *pPathLen, int *pMaxLen)
Definition: treeview.c:40
static BOOL InitTreeViewItems(HWND hwndTV, LPWSTR pHostName)
Definition: treeview.c:407
BOOL RefreshTreeView(HWND hwndTV)
Definition: treeview.c:322
static int Image_Root
Definition: treeview.c:29
HTREEITEM InsertNode(HWND hwndTV, HTREEITEM hItem, LPWSTR name)
Definition: treeview.c:347
#define IDI_SHELL_MY_COMPUTER
Definition: treeview.c:38
static int Image_Closed
Definition: treeview.c:28
static LPWSTR pathBuffer
Definition: treeview.c:31
#define IDI_SHELL_FOLDER_OPEN
Definition: treeview.c:37
BOOL CreateNewKey(HWND hwndTV, HTREEITEM hItem)
Definition: treeview.c:584
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:84
static HTREEITEM hRoot
Definition: treeview.c:381
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:3735
#define TreeView_Select(hwnd, hitem, code)
Definition: commctrl.h:3479
#define TVS_LINESATROOT
Definition: commctrl.h:3249
#define TVI_LAST
Definition: commctrl.h:3370
#define TVIF_TEXT
Definition: commctrl.h:3266
#define TreeView_SelectItem(hwnd, hitem)
Definition: commctrl.h:3481
#define TreeView_Expand(hwnd, hitem, code)
Definition: commctrl.h:3420
#define TreeView_GetChild(hwnd, hitem)
Definition: commctrl.h:3466
#define TVN_BEGINLABELEDIT
Definition: commctrl.h:3743
#define TVIF_IMAGE
Definition: commctrl.h:3267
#define TVIS_EXPANDEDONCE
Definition: commctrl.h:3285
#define TVSIL_NORMAL
Definition: commctrl.h:3443
#define TreeView_EnsureVisible(hwnd, hitem)
Definition: commctrl.h:3545
#define TreeView_GetItemState(hwndTV, hti, mask)
Definition: commctrl.h:3595
_Out_opt_ int * cx
Definition: commctrl.h:585
#define TVI_FIRST
Definition: commctrl.h:3369
#define TreeView_GetParent(hwnd, hitem)
Definition: commctrl.h:3469
#define TVS_SHOWSELALWAYS
Definition: commctrl.h:3252
#define ILC_COLOR32
Definition: commctrl.h:358
#define TreeView_GetImageList(hwnd, iImage)
Definition: commctrl.h:3441
#define TreeView_GetSelection(hwnd)
Definition: commctrl.h:3473
#define TreeView_GetItem(hwnd, pitem)
Definition: commctrl.h:3490
struct _TREEITEM * HTREEITEM
Definition: commctrl.h:3264
#define TVN_ENDLABELEDIT
Definition: commctrl.h:3744
#define TVS_HASLINES
Definition: commctrl.h:3248
#define TVE_EXPAND
Definition: commctrl.h:3423
#define TVI_ROOT
Definition: commctrl.h:3368
#define TVM_SORTCHILDREN
Definition: commctrl.h:3541
#define WC_TREEVIEW
Definition: commctrl.h:3245
#define NMTREEVIEW
Definition: commctrl.h:3642
#define TreeView_GetRoot(hwnd)
Definition: commctrl.h:3475
#define TVIF_HANDLE
Definition: commctrl.h:3270
#define TreeView_GetNextSibling(hwnd, hitem)
Definition: commctrl.h:3467
#define TVIS_EXPANDED
Definition: commctrl.h:3284
#define ImageList_AddIcon(himl, hicon)
Definition: commctrl.h:415
#define NM_SETFOCUS
Definition: commctrl.h:135
#define TVN_ITEMEXPANDING
Definition: commctrl.h:3738
#define TVGN_CARET
Definition: commctrl.h:3461
#define TVS_HASBUTTONS
Definition: commctrl.h:3247
#define ILC_MASK
Definition: commctrl.h:351
#define TreeView_EditLabel(hwnd, hitem)
Definition: commctrl.h:3504
#define TVIF_PARAM
Definition: commctrl.h:3268
#define LPNMTVDISPINFO
Definition: commctrl.h:3676
#define TVS_EDITLABELS
Definition: commctrl.h:3250
#define TreeView_SetImageList(hwnd, himl, iImage)
Definition: commctrl.h:3447
#define TVIF_CHILDREN
Definition: commctrl.h:3272
#define TreeView_InsertItem(hwnd, lpis)
Definition: commctrl.h:3412
#define TVIF_SELECTEDIMAGE
Definition: commctrl.h:3271
#define TreeView_SetItem(hwnd, pitem)
Definition: commctrl.h:3497
#define TVIF_STATE
Definition: commctrl.h:3269
#define TreeView_DeleteItem(hwnd, hitem)
Definition: commctrl.h:3415
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:68
HWND hTreeWnd
Definition: main.h:63
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:3393
HTREEITEM hInsertAfter
Definition: commctrl.h:3394
HTREEITEM hItem
Definition: commctrl.h:3317
LPARAM lParam
Definition: commctrl.h:3325
UINT mask
Definition: commctrl.h:3316
LPWSTR pszText
Definition: commctrl.h:3320
int cchTextMax
Definition: commctrl.h:3321
int iImage
Definition: commctrl.h:3322
int cChildren
Definition: commctrl.h:3324
int iSelectedImage
Definition: commctrl.h:3323
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:2247
#define SM_CYSMICON
Definition: winuser.h:1013
HCURSOR WINAPI SetCursor(_In_opt_ HCURSOR)
#define MB_ICONERROR
Definition: winuser.h:787
#define SM_CXSMICON
Definition: winuser.h:1012
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:5821
#define MB_OK
Definition: winuser.h:790
#define wsprintf
Definition: winuser.h:5874
#define IDC_WAIT
Definition: winuser.h:689
#define LR_DEFAULTCOLOR
Definition: winuser.h:1087
#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:2097
#define MF_GRAYED
Definition: winuser.h:129
#define WM_SETREDRAW
Definition: winuser.h:1616
_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