1c2c66affSColin Finck /*
2c2c66affSColin Finck * Regedit treeview
3c2c66affSColin Finck *
4c2c66affSColin Finck * Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
5470cef7bSJoachim Henze * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
6c2c66affSColin Finck */
7c2c66affSColin Finck
8c2c66affSColin Finck #include "regedit.h"
9c2c66affSColin Finck
10c2c66affSColin Finck /* Global variables and constants */
11470cef7bSJoachim Henze /* Image_Open, Image_Closed, and Image_Root - integer variables for indexes of the images */
12470cef7bSJoachim Henze static int Image_Open;
13470cef7bSJoachim Henze static int Image_Closed;
14470cef7bSJoachim Henze static int Image_Root;
15c2c66affSColin Finck
16c2c66affSColin Finck static LPWSTR pathBuffer;
17c2c66affSColin Finck
18470cef7bSJoachim Henze #define NUM_ICONS 3 /* number of icons to add to the image list */
19c2c66affSColin Finck
205daf5cd0SStanislav Motylkov /* External resources in shell32.dll */
215daf5cd0SStanislav Motylkov #define IDI_SHELL_FOLDER 4
225daf5cd0SStanislav Motylkov #define IDI_SHELL_FOLDER_OPEN 5
235daf5cd0SStanislav Motylkov #define IDI_SHELL_MY_COMPUTER 16
245daf5cd0SStanislav Motylkov
get_item_path(HWND hwndTV,HTREEITEM hItem,HKEY * phKey,LPWSTR * pKeyPath,int * pPathLen,int * pMaxLen)25c2c66affSColin Finck static BOOL get_item_path(HWND hwndTV, HTREEITEM hItem, HKEY* phKey, LPWSTR* pKeyPath, int* pPathLen, int* pMaxLen)
26c2c66affSColin Finck {
27c2c66affSColin Finck TVITEMW item;
28c2c66affSColin Finck size_t maxLen, len;
29c2c66affSColin Finck LPWSTR newStr;
30c2c66affSColin Finck
31c2c66affSColin Finck item.mask = TVIF_PARAM;
32c2c66affSColin Finck item.hItem = hItem;
33c2c66affSColin Finck if (!TreeView_GetItem(hwndTV, &item)) return FALSE;
34c2c66affSColin Finck
35c2c66affSColin Finck if (item.lParam)
36c2c66affSColin Finck {
37c2c66affSColin Finck /* found root key with valid key value */
38c2c66affSColin Finck *phKey = (HKEY)item.lParam;
39c2c66affSColin Finck return TRUE;
40c2c66affSColin Finck }
41c2c66affSColin Finck
42c2c66affSColin Finck if(!get_item_path(hwndTV, TreeView_GetParent(hwndTV, hItem), phKey, pKeyPath, pPathLen, pMaxLen)) return FALSE;
43c2c66affSColin Finck if (*pPathLen)
44c2c66affSColin Finck {
45c2c66affSColin Finck (*pKeyPath)[*pPathLen] = L'\\';
46c2c66affSColin Finck ++(*pPathLen);
47c2c66affSColin Finck }
48c2c66affSColin Finck
49c2c66affSColin Finck do
50c2c66affSColin Finck {
51c2c66affSColin Finck item.mask = TVIF_TEXT;
52c2c66affSColin Finck item.hItem = hItem;
53c2c66affSColin Finck item.pszText = *pKeyPath + *pPathLen;
54c2c66affSColin Finck maxLen = *pMaxLen - *pPathLen;
55c2c66affSColin Finck item.cchTextMax = (int) maxLen;
56c2c66affSColin Finck if (!TreeView_GetItem(hwndTV, &item)) return FALSE;
57c2c66affSColin Finck len = wcslen(item.pszText);
58c2c66affSColin Finck if (len < maxLen - 1)
59c2c66affSColin Finck {
60c2c66affSColin Finck *pPathLen += (int) len;
61c2c66affSColin Finck break;
62c2c66affSColin Finck }
63c2c66affSColin Finck newStr = HeapReAlloc(GetProcessHeap(), 0, *pKeyPath, *pMaxLen * 2);
64c2c66affSColin Finck if (!newStr) return FALSE;
65c2c66affSColin Finck *pKeyPath = newStr;
66c2c66affSColin Finck *pMaxLen *= 2;
67c2c66affSColin Finck }
68c2c66affSColin Finck while(TRUE);
69c2c66affSColin Finck
70c2c66affSColin Finck return TRUE;
71c2c66affSColin Finck }
72c2c66affSColin Finck
GetItemPath(HWND hwndTV,HTREEITEM hItem,HKEY * phRootKey)73c2c66affSColin Finck LPCWSTR GetItemPath(HWND hwndTV, HTREEITEM hItem, HKEY* phRootKey)
74c2c66affSColin Finck {
75c2c66affSColin Finck int pathLen = 0, maxLen;
76c2c66affSColin Finck
77c2c66affSColin Finck *phRootKey = NULL;
787f45cac9SJose Carlos Jesus
797f45cac9SJose Carlos Jesus if (!pathBuffer)
807f45cac9SJose Carlos Jesus pathBuffer = HeapAlloc(GetProcessHeap(), 0, 1024);
817f45cac9SJose Carlos Jesus if (!pathBuffer)
827f45cac9SJose Carlos Jesus return NULL;
837f45cac9SJose Carlos Jesus
847f45cac9SJose Carlos Jesus *pathBuffer = UNICODE_NULL;
857f45cac9SJose Carlos Jesus
86c2c66affSColin Finck maxLen = (int)HeapSize(GetProcessHeap(), 0, pathBuffer);
877f45cac9SJose Carlos Jesus
887f45cac9SJose Carlos Jesus if (!hItem)
897f45cac9SJose Carlos Jesus {
907f45cac9SJose Carlos Jesus hItem = TreeView_GetSelection(hwndTV);
917f45cac9SJose Carlos Jesus }
927f45cac9SJose Carlos Jesus if (maxLen == -1 || !hItem || !get_item_path(hwndTV, hItem, phRootKey, &pathBuffer, &pathLen, &maxLen))
93c2c66affSColin Finck {
94c2c66affSColin Finck return NULL;
95c2c66affSColin Finck }
96c2c66affSColin Finck return pathBuffer;
97c2c66affSColin Finck }
98c2c66affSColin Finck
DeleteNode(HWND hwndTV,HTREEITEM hItem)99c2c66affSColin Finck BOOL DeleteNode(HWND hwndTV, HTREEITEM hItem)
100c2c66affSColin Finck {
101c2c66affSColin Finck if (!hItem) hItem = TreeView_GetSelection(hwndTV);
102c2c66affSColin Finck if (!hItem) return FALSE;
103c2c66affSColin Finck return TreeView_DeleteItem(hwndTV, hItem);
104c2c66affSColin Finck }
105c2c66affSColin Finck
106c2c66affSColin Finck /* Add an entry to the tree. Only give hKey for root nodes (HKEY_ constants) */
AddEntryToTree(HWND hwndTV,HTREEITEM hParent,LPWSTR label,HKEY hKey,DWORD dwChildren)107c2c66affSColin Finck static HTREEITEM AddEntryToTree(HWND hwndTV, HTREEITEM hParent, LPWSTR label, HKEY hKey, DWORD dwChildren)
108c2c66affSColin Finck {
109c2c66affSColin Finck TVITEMW tvi;
110c2c66affSColin Finck TVINSERTSTRUCTW tvins;
111c2c66affSColin Finck
112c2c66affSColin Finck if (hKey)
113c2c66affSColin Finck {
114c2c66affSColin Finck if (RegQueryInfoKeyW(hKey, 0, 0, 0, &dwChildren, 0, 0, 0, 0, 0, 0, 0) != ERROR_SUCCESS)
115c2c66affSColin Finck {
116c2c66affSColin Finck dwChildren = 0;
117c2c66affSColin Finck }
118c2c66affSColin Finck }
119c2c66affSColin Finck
120c2c66affSColin Finck tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN | TVIF_PARAM;
121c2c66affSColin Finck tvi.pszText = label;
122c2c66affSColin Finck tvi.cchTextMax = wcslen(tvi.pszText);
123c2c66affSColin Finck tvi.iImage = Image_Closed;
124c2c66affSColin Finck tvi.iSelectedImage = Image_Open;
125c2c66affSColin Finck tvi.cChildren = dwChildren;
126c2c66affSColin Finck tvi.lParam = (LPARAM)hKey;
127c2c66affSColin Finck tvins.item = tvi;
128c2c66affSColin Finck tvins.hInsertAfter = (HTREEITEM)(hKey ? TVI_LAST : TVI_FIRST);
129c2c66affSColin Finck tvins.hParent = hParent;
130c2c66affSColin Finck return TreeView_InsertItem(hwndTV, &tvins);
131c2c66affSColin Finck }
132c2c66affSColin Finck
RefreshTreeItem(HWND hwndTV,HTREEITEM hItem)133c2c66affSColin Finck BOOL RefreshTreeItem(HWND hwndTV, HTREEITEM hItem)
134c2c66affSColin Finck {
135c2c66affSColin Finck HKEY hRoot, hKey, hSubKey;
136c2c66affSColin Finck HTREEITEM childItem;
137c2c66affSColin Finck LPCWSTR KeyPath;
138c2c66affSColin Finck DWORD dwCount, dwIndex, dwMaxSubKeyLen;
139c2c66affSColin Finck LPWSTR Name = NULL;
140c2c66affSColin Finck TVITEMW tvItem;
141c2c66affSColin Finck LPWSTR pszNodes = NULL;
142c2c66affSColin Finck BOOL bSuccess = FALSE;
143c2c66affSColin Finck LPWSTR s;
144c2c66affSColin Finck BOOL bAddedAny;
145c2c66affSColin Finck
146c2c66affSColin Finck KeyPath = GetItemPath(hwndTV, hItem, &hRoot);
147c2c66affSColin Finck
148c2c66affSColin Finck if (*KeyPath)
149c2c66affSColin Finck {
150c2c66affSColin Finck if (RegOpenKeyExW(hRoot, KeyPath, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
151c2c66affSColin Finck {
152c2c66affSColin Finck goto done;
153c2c66affSColin Finck }
154c2c66affSColin Finck }
155c2c66affSColin Finck else
156c2c66affSColin Finck {
157c2c66affSColin Finck hKey = hRoot;
158c2c66affSColin Finck }
159c2c66affSColin Finck
160c2c66affSColin Finck if (RegQueryInfoKeyW(hKey, 0, 0, 0, &dwCount, &dwMaxSubKeyLen, 0, 0, 0, 0, 0, 0) != ERROR_SUCCESS)
161c2c66affSColin Finck {
162c2c66affSColin Finck goto done;
163c2c66affSColin Finck }
164c2c66affSColin Finck
165c2c66affSColin Finck /* Set the number of children again */
166c2c66affSColin Finck tvItem.mask = TVIF_CHILDREN;
167c2c66affSColin Finck tvItem.hItem = hItem;
168c2c66affSColin Finck tvItem.cChildren = dwCount;
169c2c66affSColin Finck if (!TreeView_SetItem(hwndTV, &tvItem))
170c2c66affSColin Finck {
171c2c66affSColin Finck goto done;
172c2c66affSColin Finck }
173c2c66affSColin Finck
174c2c66affSColin Finck /* We don't have to bother with the rest if it's not expanded. */
175c2c66affSColin Finck if (TreeView_GetItemState(hwndTV, hItem, TVIS_EXPANDED) == 0)
176c2c66affSColin Finck {
177c2c66affSColin Finck RegCloseKey(hKey);
178c2c66affSColin Finck bSuccess = TRUE;
179c2c66affSColin Finck goto done;
180c2c66affSColin Finck }
181c2c66affSColin Finck
182c2c66affSColin Finck dwMaxSubKeyLen++; /* account for the \0 terminator */
183c2c66affSColin Finck if (!(Name = HeapAlloc(GetProcessHeap(), 0, dwMaxSubKeyLen * sizeof(WCHAR))))
184c2c66affSColin Finck {
185c2c66affSColin Finck goto done;
186c2c66affSColin Finck }
187c2c66affSColin Finck tvItem.cchTextMax = dwMaxSubKeyLen;
188c2c66affSColin Finck /*if (!(tvItem.pszText = HeapAlloc(GetProcessHeap(), 0, dwMaxSubKeyLen * sizeof(WCHAR)))) {
189c2c66affSColin Finck goto done;
190c2c66affSColin Finck }*/
191c2c66affSColin Finck
192c2c66affSColin Finck /* Get all of the tree node siblings in one contiguous block of memory */
193c2c66affSColin Finck {
194c2c66affSColin Finck DWORD dwPhysicalSize = 0;
195c2c66affSColin Finck DWORD dwActualSize = 0;
196c2c66affSColin Finck DWORD dwNewPhysicalSize;
197c2c66affSColin Finck LPWSTR pszNewNodes;
198c2c66affSColin Finck DWORD dwStep = 10000;
199c2c66affSColin Finck
200c2c66affSColin Finck for (childItem = TreeView_GetChild(hwndTV, hItem); childItem;
201c2c66affSColin Finck childItem = TreeView_GetNextSibling(hwndTV, childItem))
202c2c66affSColin Finck {
203c2c66affSColin Finck
204c2c66affSColin Finck if (dwActualSize + dwMaxSubKeyLen + 1 > dwPhysicalSize)
205c2c66affSColin Finck {
206c2c66affSColin Finck dwNewPhysicalSize = dwActualSize + dwMaxSubKeyLen + 1 + dwStep;
207c2c66affSColin Finck
208c2c66affSColin Finck if (pszNodes)
209c2c66affSColin Finck pszNewNodes = (LPWSTR) HeapReAlloc(GetProcessHeap(), 0, pszNodes, dwNewPhysicalSize * sizeof(WCHAR));
210c2c66affSColin Finck else
211c2c66affSColin Finck pszNewNodes = (LPWSTR) HeapAlloc(GetProcessHeap(), 0, dwNewPhysicalSize * sizeof(WCHAR));
212c2c66affSColin Finck if (!pszNewNodes)
213c2c66affSColin Finck goto done;
214c2c66affSColin Finck
215c2c66affSColin Finck dwPhysicalSize = dwNewPhysicalSize;
216c2c66affSColin Finck pszNodes = pszNewNodes;
217c2c66affSColin Finck }
218c2c66affSColin Finck
219c2c66affSColin Finck tvItem.mask = TVIF_TEXT;
220c2c66affSColin Finck tvItem.hItem = childItem;
221c2c66affSColin Finck tvItem.pszText = &pszNodes[dwActualSize];
222c2c66affSColin Finck tvItem.cchTextMax = dwPhysicalSize - dwActualSize;
223c2c66affSColin Finck if (!TreeView_GetItem(hwndTV, &tvItem))
224c2c66affSColin Finck goto done;
225c2c66affSColin Finck
226c2c66affSColin Finck dwActualSize += (DWORD) wcslen(&pszNodes[dwActualSize]) + 1;
227c2c66affSColin Finck }
228c2c66affSColin Finck
229c2c66affSColin Finck if (pszNodes)
230c2c66affSColin Finck pszNodes[dwActualSize] = L'\0';
231c2c66affSColin Finck }
232c2c66affSColin Finck
233c2c66affSColin Finck /* Now go through all the children in the tree, and check if any have to be removed. */
234c2c66affSColin Finck childItem = TreeView_GetChild(hwndTV, hItem);
235c2c66affSColin Finck while (childItem)
236c2c66affSColin Finck {
237c2c66affSColin Finck HTREEITEM nextItem = TreeView_GetNextSibling(hwndTV, childItem);
238c2c66affSColin Finck if (RefreshTreeItem(hwndTV, childItem) == FALSE)
239c2c66affSColin Finck {
240c2c66affSColin Finck (void)TreeView_DeleteItem(hwndTV, childItem);
241c2c66affSColin Finck }
242c2c66affSColin Finck childItem = nextItem;
243c2c66affSColin Finck }
244c2c66affSColin Finck
245c2c66affSColin Finck /* Now go through all the children in the registry, and check if any have to be added. */
246c2c66affSColin Finck bAddedAny = FALSE;
247c2c66affSColin Finck for (dwIndex = 0; dwIndex < dwCount; dwIndex++)
248c2c66affSColin Finck {
249c2c66affSColin Finck DWORD cName = dwMaxSubKeyLen, dwSubCount;
250c2c66affSColin Finck BOOL found;
251c2c66affSColin Finck
252c2c66affSColin Finck found = FALSE;
253c2c66affSColin Finck if (RegEnumKeyExW(hKey, dwIndex, Name, &cName, 0, 0, 0, NULL) != ERROR_SUCCESS)
254c2c66affSColin Finck {
255c2c66affSColin Finck continue;
256c2c66affSColin Finck }
257c2c66affSColin Finck
258c2c66affSColin Finck /* Check if the node is already in there. */
259c2c66affSColin Finck if (pszNodes)
260c2c66affSColin Finck {
261c2c66affSColin Finck for (s = pszNodes; *s; s += wcslen(s) + 1)
262c2c66affSColin Finck {
263c2c66affSColin Finck if (!wcscmp(s, Name))
264c2c66affSColin Finck {
265c2c66affSColin Finck found = TRUE;
266c2c66affSColin Finck break;
267c2c66affSColin Finck }
268c2c66affSColin Finck }
269c2c66affSColin Finck }
270c2c66affSColin Finck
271c2c66affSColin Finck if (found == FALSE)
272c2c66affSColin Finck {
273c2c66affSColin Finck /* Find the number of children of the node. */
274c2c66affSColin Finck dwSubCount = 0;
275c2c66affSColin Finck if (RegOpenKeyExW(hKey, Name, 0, KEY_QUERY_VALUE, &hSubKey) == ERROR_SUCCESS)
276c2c66affSColin Finck {
277c2c66affSColin Finck if (RegQueryInfoKeyW(hSubKey, 0, 0, 0, &dwSubCount, 0, 0, 0, 0, 0, 0, 0) != ERROR_SUCCESS)
278c2c66affSColin Finck {
279c2c66affSColin Finck dwSubCount = 0;
280c2c66affSColin Finck }
281c2c66affSColin Finck RegCloseKey(hSubKey);
282c2c66affSColin Finck }
283c2c66affSColin Finck
284c2c66affSColin Finck AddEntryToTree(hwndTV, hItem, Name, NULL, dwSubCount);
285c2c66affSColin Finck bAddedAny = TRUE;
286c2c66affSColin Finck }
287c2c66affSColin Finck }
288c2c66affSColin Finck RegCloseKey(hKey);
289c2c66affSColin Finck
290c2c66affSColin Finck if (bAddedAny)
291c2c66affSColin Finck SendMessageW(hwndTV, TVM_SORTCHILDREN, 0, (LPARAM) hItem);
292c2c66affSColin Finck
293c2c66affSColin Finck bSuccess = TRUE;
294c2c66affSColin Finck
295c2c66affSColin Finck done:
296c2c66affSColin Finck if (pszNodes)
297c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, pszNodes);
298c2c66affSColin Finck if (Name)
299c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, Name);
300c2c66affSColin Finck return bSuccess;
301c2c66affSColin Finck }
302c2c66affSColin Finck
RefreshTreeView(HWND hwndTV)303c2c66affSColin Finck BOOL RefreshTreeView(HWND hwndTV)
304c2c66affSColin Finck {
305c2c66affSColin Finck HTREEITEM hItem;
306c2c66affSColin Finck HTREEITEM hSelectedItem;
307c2c66affSColin Finck HCURSOR hcursorOld;
308c2c66affSColin Finck
309c2c66affSColin Finck hSelectedItem = TreeView_GetSelection(hwndTV);
310c2c66affSColin Finck hcursorOld = SetCursor(LoadCursor(NULL, IDC_WAIT));
311c2c66affSColin Finck SendMessageW(hwndTV, WM_SETREDRAW, FALSE, 0);
312c2c66affSColin Finck
313c2c66affSColin Finck hItem = TreeView_GetChild(hwndTV, TreeView_GetRoot(hwndTV));
314c2c66affSColin Finck while (hItem)
315c2c66affSColin Finck {
316c2c66affSColin Finck RefreshTreeItem(hwndTV, hItem);
317c2c66affSColin Finck hItem = TreeView_GetNextSibling(hwndTV, hItem);
318c2c66affSColin Finck }
319c2c66affSColin Finck
320c2c66affSColin Finck SendMessageW(hwndTV, WM_SETREDRAW, TRUE, 0);
321c2c66affSColin Finck SetCursor(hcursorOld);
322c2c66affSColin Finck
323c2c66affSColin Finck /* We reselect the currently selected node, this will prompt a refresh of the listview. */
324c2c66affSColin Finck (void)TreeView_SelectItem(hwndTV, hSelectedItem);
325c2c66affSColin Finck return TRUE;
326c2c66affSColin Finck }
327c2c66affSColin Finck
InsertNode(HWND hwndTV,HTREEITEM hItem,LPWSTR name)328c2c66affSColin Finck HTREEITEM InsertNode(HWND hwndTV, HTREEITEM hItem, LPWSTR name)
329c2c66affSColin Finck {
330c2c66affSColin Finck WCHAR buf[MAX_NEW_KEY_LEN];
331c2c66affSColin Finck HTREEITEM hNewItem = 0;
332c2c66affSColin Finck TVITEMEXW item;
333c2c66affSColin Finck
334c2c66affSColin Finck /* Default to the current selection */
335c2c66affSColin Finck if (!hItem)
336c2c66affSColin Finck {
337c2c66affSColin Finck hItem = TreeView_GetSelection(hwndTV);
338c2c66affSColin Finck if (!hItem)
339c2c66affSColin Finck return FALSE;
340c2c66affSColin Finck }
341c2c66affSColin Finck
342c2c66affSColin Finck memset(&item, 0, sizeof(item));
343c2c66affSColin Finck item.hItem = hItem;
344c2c66affSColin Finck item.mask = TVIF_CHILDREN | TVIF_HANDLE | TVIF_STATE;
345c2c66affSColin Finck if (!TreeView_GetItem(hwndTV, &item))
346c2c66affSColin Finck return FALSE;
347c2c66affSColin Finck
3487f45cac9SJose Carlos Jesus if (item.state & TVIS_EXPANDEDONCE)
349c2c66affSColin Finck {
350c2c66affSColin Finck hNewItem = AddEntryToTree(hwndTV, hItem, name, 0, 0);
351c2c66affSColin Finck SendMessageW(hwndTV, TVM_SORTCHILDREN, 0, (LPARAM) hItem);
352c2c66affSColin Finck }
353c2c66affSColin Finck else
354c2c66affSColin Finck {
355c2c66affSColin Finck item.mask = TVIF_CHILDREN | TVIF_HANDLE;
356c2c66affSColin Finck item.hItem = hItem;
357c2c66affSColin Finck item.cChildren = 1;
358c2c66affSColin Finck if (!TreeView_SetItem(hwndTV, &item))
359c2c66affSColin Finck return FALSE;
360c2c66affSColin Finck }
361c2c66affSColin Finck
362c2c66affSColin Finck (void)TreeView_Expand(hwndTV, hItem, TVE_EXPAND);
363c2c66affSColin Finck if (!hNewItem)
364c2c66affSColin Finck {
365c2c66affSColin Finck for(hNewItem = TreeView_GetChild(hwndTV, hItem); hNewItem; hNewItem = TreeView_GetNextSibling(hwndTV, hNewItem))
366c2c66affSColin Finck {
367c2c66affSColin Finck item.mask = TVIF_HANDLE | TVIF_TEXT;
368c2c66affSColin Finck item.hItem = hNewItem;
369c2c66affSColin Finck item.pszText = buf;
37036a7f0dcSRobert Naumann item.cchTextMax = ARRAY_SIZE(buf);
371c2c66affSColin Finck if (!TreeView_GetItem(hwndTV, &item)) continue;
372c2c66affSColin Finck if (wcscmp(name, item.pszText) == 0) break;
373c2c66affSColin Finck }
374c2c66affSColin Finck }
375c2c66affSColin Finck if (hNewItem) (void)TreeView_SelectItem(hwndTV, hNewItem);
376c2c66affSColin Finck
377c2c66affSColin Finck return hNewItem;
378c2c66affSColin Finck }
379c2c66affSColin Finck
StartKeyRename(HWND hwndTV)380c2c66affSColin Finck HWND StartKeyRename(HWND hwndTV)
381c2c66affSColin Finck {
382c2c66affSColin Finck HTREEITEM hItem;
383c2c66affSColin Finck
384c2c66affSColin Finck if(!(hItem = TreeView_GetSelection(hwndTV))) return 0;
385c2c66affSColin Finck return TreeView_EditLabel(hwndTV, hItem);
386c2c66affSColin Finck }
387c2c66affSColin Finck
InitTreeViewItems(HWND hwndTV,LPWSTR pHostName)388c2c66affSColin Finck static BOOL InitTreeViewItems(HWND hwndTV, LPWSTR pHostName)
389c2c66affSColin Finck {
390c2c66affSColin Finck TVITEMW tvi;
391c2c66affSColin Finck TVINSERTSTRUCTW tvins;
392c2c66affSColin Finck HTREEITEM hRoot;
393c2c66affSColin Finck
394c2c66affSColin Finck tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN | TVIF_PARAM;
395c2c66affSColin Finck /* Set the text of the item. */
396c2c66affSColin Finck tvi.pszText = pHostName;
397c2c66affSColin Finck tvi.cchTextMax = wcslen(tvi.pszText);
398c2c66affSColin Finck /* Assume the item is not a parent item, so give it an image. */
399c2c66affSColin Finck tvi.iImage = Image_Root;
400c2c66affSColin Finck tvi.iSelectedImage = Image_Root;
401c2c66affSColin Finck tvi.cChildren = 5;
402c2c66affSColin Finck /* Save the heading level in the item's application-defined data area. */
403c2c66affSColin Finck tvi.lParam = (LPARAM)NULL;
404c2c66affSColin Finck tvins.item = tvi;
405c2c66affSColin Finck tvins.hInsertAfter = (HTREEITEM)TVI_FIRST;
406c2c66affSColin Finck tvins.hParent = TVI_ROOT;
407c2c66affSColin Finck /* Add the item to the tree view control. */
408c2c66affSColin Finck if (!(hRoot = TreeView_InsertItem(hwndTV, &tvins))) return FALSE;
409c2c66affSColin Finck
410c2c66affSColin Finck if (!AddEntryToTree(hwndTV, hRoot, L"HKEY_CLASSES_ROOT", HKEY_CLASSES_ROOT, 1)) return FALSE;
411c2c66affSColin Finck if (!AddEntryToTree(hwndTV, hRoot, L"HKEY_CURRENT_USER", HKEY_CURRENT_USER, 1)) return FALSE;
412c2c66affSColin Finck if (!AddEntryToTree(hwndTV, hRoot, L"HKEY_LOCAL_MACHINE", HKEY_LOCAL_MACHINE, 1)) return FALSE;
413c2c66affSColin Finck if (!AddEntryToTree(hwndTV, hRoot, L"HKEY_USERS", HKEY_USERS, 1)) return FALSE;
414c2c66affSColin Finck if (!AddEntryToTree(hwndTV, hRoot, L"HKEY_CURRENT_CONFIG", HKEY_CURRENT_CONFIG, 1)) return FALSE;
415c2c66affSColin Finck
416c2c66affSColin Finck if (GetVersion() & 0x80000000)
417c2c66affSColin Finck {
418c2c66affSColin Finck /* Win9x specific key */
419c2c66affSColin Finck if (!AddEntryToTree(hwndTV, hRoot, L"HKEY_DYN_DATA", HKEY_DYN_DATA, 1)) return FALSE;
420c2c66affSColin Finck }
421c2c66affSColin Finck
422c2c66affSColin Finck /* expand and select host name */
423c2c66affSColin Finck (void)TreeView_Expand(hwndTV, hRoot, TVE_EXPAND);
424c2c66affSColin Finck (void)TreeView_Select(hwndTV, hRoot, TVGN_CARET);
425c2c66affSColin Finck return TRUE;
426c2c66affSColin Finck }
427c2c66affSColin Finck
428c2c66affSColin Finck /*
429c2c66affSColin Finck * InitTreeViewImageLists - creates an image list, adds three bitmaps
430c2c66affSColin Finck * to it, and associates the image list with a tree view control.
431c2c66affSColin Finck * Returns TRUE if successful, or FALSE otherwise.
432c2c66affSColin Finck * hwndTV - handle to the tree view control.
433c2c66affSColin Finck */
InitTreeViewImageLists(HWND hwndTV)434c2c66affSColin Finck static BOOL InitTreeViewImageLists(HWND hwndTV)
435c2c66affSColin Finck {
436c2c66affSColin Finck HIMAGELIST himl; /* handle to image list */
437c2c66affSColin Finck HICON hico; /* handle to icon */
43836a7f0dcSRobert Naumann INT cx = GetSystemMetrics(SM_CXSMICON);
43936a7f0dcSRobert Naumann INT cy = GetSystemMetrics(SM_CYSMICON);
4405daf5cd0SStanislav Motylkov HMODULE hShell32 = GetModuleHandleW(L"shell32.dll");
441c2c66affSColin Finck
442c2c66affSColin Finck /* Create the image list. */
443683d81b7SRobert Naumann if ((himl = ImageList_Create(cx, cy, ILC_MASK | ILC_COLOR32, 0, NUM_ICONS)) == NULL)
444c2c66affSColin Finck return FALSE;
445c2c66affSColin Finck
446c2c66affSColin Finck /* Add the open file, closed file, and document bitmaps. */
4475daf5cd0SStanislav Motylkov hico = LoadImageW(hShell32,
4485daf5cd0SStanislav Motylkov MAKEINTRESOURCEW(IDI_SHELL_FOLDER_OPEN),
449c2c66affSColin Finck IMAGE_ICON,
4505daf5cd0SStanislav Motylkov cx,
4515daf5cd0SStanislav Motylkov cy,
4525daf5cd0SStanislav Motylkov LR_DEFAULTCOLOR);
453c2c66affSColin Finck if (hico)
454c2c66affSColin Finck {
455c2c66affSColin Finck Image_Open = ImageList_AddIcon(himl, hico);
456c2c66affSColin Finck DestroyIcon(hico);
457c2c66affSColin Finck }
458c2c66affSColin Finck
4595daf5cd0SStanislav Motylkov hico = LoadImageW(hShell32,
4605daf5cd0SStanislav Motylkov MAKEINTRESOURCEW(IDI_SHELL_FOLDER),
461c2c66affSColin Finck IMAGE_ICON,
4625daf5cd0SStanislav Motylkov cx,
4635daf5cd0SStanislav Motylkov cy,
4645daf5cd0SStanislav Motylkov LR_DEFAULTCOLOR);
465c2c66affSColin Finck if (hico)
466c2c66affSColin Finck {
467c2c66affSColin Finck Image_Closed = ImageList_AddIcon(himl, hico);
468c2c66affSColin Finck DestroyIcon(hico);
469c2c66affSColin Finck }
470c2c66affSColin Finck
4715daf5cd0SStanislav Motylkov hico = LoadImageW(hShell32,
4725daf5cd0SStanislav Motylkov MAKEINTRESOURCEW(IDI_SHELL_MY_COMPUTER),
473c2c66affSColin Finck IMAGE_ICON,
4745daf5cd0SStanislav Motylkov cx,
4755daf5cd0SStanislav Motylkov cy,
4765daf5cd0SStanislav Motylkov LR_DEFAULTCOLOR);
477c2c66affSColin Finck if (hico)
478c2c66affSColin Finck {
479c2c66affSColin Finck Image_Root = ImageList_AddIcon(himl, hico);
480c2c66affSColin Finck DestroyIcon(hico);
481c2c66affSColin Finck }
482c2c66affSColin Finck
483c2c66affSColin Finck /* Fail if not all of the images were added. */
484c2c66affSColin Finck if (ImageList_GetImageCount(himl) < NUM_ICONS)
485c2c66affSColin Finck {
486c2c66affSColin Finck ImageList_Destroy(himl);
487c2c66affSColin Finck return FALSE;
488c2c66affSColin Finck }
489c2c66affSColin Finck
490c2c66affSColin Finck /* Associate the image list with the tree view control. */
491c2c66affSColin Finck (void)TreeView_SetImageList(hwndTV, himl, TVSIL_NORMAL);
492c2c66affSColin Finck
493c2c66affSColin Finck return TRUE;
494c2c66affSColin Finck }
495c2c66affSColin Finck
OnTreeExpanding(HWND hwndTV,NMTREEVIEW * pnmtv)496c2c66affSColin Finck BOOL OnTreeExpanding(HWND hwndTV, NMTREEVIEW* pnmtv)
497c2c66affSColin Finck {
498c2c66affSColin Finck DWORD dwCount, dwIndex, dwMaxSubKeyLen;
499c2c66affSColin Finck HKEY hRoot, hNewKey, hKey;
500c2c66affSColin Finck LPCWSTR keyPath;
501c2c66affSColin Finck LPWSTR Name;
502c2c66affSColin Finck LONG errCode;
503c2c66affSColin Finck HCURSOR hcursorOld;
504c2c66affSColin Finck
505c2c66affSColin Finck static int expanding;
506c2c66affSColin Finck if (expanding) return FALSE;
507c2c66affSColin Finck if (pnmtv->itemNew.state & TVIS_EXPANDEDONCE )
508c2c66affSColin Finck {
509c2c66affSColin Finck return TRUE;
510c2c66affSColin Finck }
511c2c66affSColin Finck expanding = TRUE;
512c2c66affSColin Finck hcursorOld = SetCursor(LoadCursor(NULL, IDC_WAIT));
513c2c66affSColin Finck SendMessageW(hwndTV, WM_SETREDRAW, FALSE, 0);
514c2c66affSColin Finck
515c2c66affSColin Finck keyPath = GetItemPath(hwndTV, pnmtv->itemNew.hItem, &hRoot);
516c2c66affSColin Finck if (!keyPath) goto done;
517c2c66affSColin Finck
518c2c66affSColin Finck if (*keyPath)
519c2c66affSColin Finck {
520c2c66affSColin Finck errCode = RegOpenKeyExW(hRoot, keyPath, 0, KEY_READ, &hNewKey);
521c2c66affSColin Finck if (errCode != ERROR_SUCCESS) goto done;
522c2c66affSColin Finck }
523c2c66affSColin Finck else
524c2c66affSColin Finck {
525c2c66affSColin Finck hNewKey = hRoot;
526c2c66affSColin Finck }
527c2c66affSColin Finck
528c2c66affSColin Finck errCode = RegQueryInfoKeyW(hNewKey, 0, 0, 0, &dwCount, &dwMaxSubKeyLen, 0, 0, 0, 0, 0, 0);
529c2c66affSColin Finck if (errCode != ERROR_SUCCESS) goto done;
530c2c66affSColin Finck dwMaxSubKeyLen++; /* account for the \0 terminator */
531c2c66affSColin Finck Name = HeapAlloc(GetProcessHeap(), 0, dwMaxSubKeyLen * sizeof(WCHAR));
532c2c66affSColin Finck if (!Name) goto done;
533c2c66affSColin Finck
534c2c66affSColin Finck for (dwIndex = 0; dwIndex < dwCount; dwIndex++)
535c2c66affSColin Finck {
536c2c66affSColin Finck DWORD cName = dwMaxSubKeyLen, dwSubCount;
537c2c66affSColin Finck
538c2c66affSColin Finck errCode = RegEnumKeyExW(hNewKey, dwIndex, Name, &cName, 0, 0, 0, 0);
539c2c66affSColin Finck if (errCode != ERROR_SUCCESS) continue;
540c2c66affSColin Finck errCode = RegOpenKeyExW(hNewKey, Name, 0, KEY_QUERY_VALUE, &hKey);
541c2c66affSColin Finck if (errCode == ERROR_SUCCESS)
542c2c66affSColin Finck {
543c2c66affSColin Finck errCode = RegQueryInfoKeyW(hKey, 0, 0, 0, &dwSubCount, 0, 0, 0, 0, 0, 0, 0);
544c2c66affSColin Finck RegCloseKey(hKey);
545c2c66affSColin Finck }
546c2c66affSColin Finck if (errCode != ERROR_SUCCESS) dwSubCount = 0;
547c2c66affSColin Finck AddEntryToTree(hwndTV, pnmtv->itemNew.hItem, Name, NULL, dwSubCount);
548c2c66affSColin Finck }
549c2c66affSColin Finck
550c2c66affSColin Finck SendMessageW(hwndTV, TVM_SORTCHILDREN, 0, (LPARAM)pnmtv->itemNew.hItem);
551c2c66affSColin Finck
552c2c66affSColin Finck RegCloseKey(hNewKey);
553c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, Name);
554c2c66affSColin Finck
555c2c66affSColin Finck done:
556c2c66affSColin Finck SendMessageW(hwndTV, WM_SETREDRAW, TRUE, 0);
557c2c66affSColin Finck SetCursor(hcursorOld);
558c2c66affSColin Finck expanding = FALSE;
559c2c66affSColin Finck
560c2c66affSColin Finck return TRUE;
561c2c66affSColin Finck }
562c2c66affSColin Finck
CreateNewKey(HWND hwndTV,HTREEITEM hItem)563c2c66affSColin Finck BOOL CreateNewKey(HWND hwndTV, HTREEITEM hItem)
564c2c66affSColin Finck {
565c2c66affSColin Finck WCHAR szNewKeyFormat[128];
566c2c66affSColin Finck WCHAR szNewKey[128];
567c2c66affSColin Finck LPCWSTR pszKeyPath;
568c2c66affSColin Finck int iIndex = 1;
569c2c66affSColin Finck LONG nResult;
570c2c66affSColin Finck HKEY hRootKey = NULL, hKey = NULL, hNewKey = NULL;
571c2c66affSColin Finck BOOL bSuccess = FALSE;
572c2c66affSColin Finck DWORD dwDisposition;
573c2c66affSColin Finck HTREEITEM hNewItem;
574c2c66affSColin Finck
575c2c66affSColin Finck pszKeyPath = GetItemPath(hwndTV, hItem, &hRootKey);
576e79c8965SMaj Soklič if (!pszKeyPath)
577e79c8965SMaj Soklič return bSuccess;
578c2c66affSColin Finck if (pszKeyPath[0] == L'\0')
579c2c66affSColin Finck hKey = hRootKey;
580c2c66affSColin Finck else if (RegOpenKeyW(hRootKey, pszKeyPath, &hKey) != ERROR_SUCCESS)
581c2c66affSColin Finck goto done;
582c2c66affSColin Finck
58336a7f0dcSRobert Naumann if (LoadStringW(hInst, IDS_NEW_KEY, szNewKeyFormat, ARRAY_SIZE(szNewKeyFormat)) <= 0)
584c2c66affSColin Finck goto done;
585c2c66affSColin Finck
586c2c66affSColin Finck /* Need to create a new key with a unique name */
587c2c66affSColin Finck do
588c2c66affSColin Finck {
589c2c66affSColin Finck wsprintf(szNewKey, szNewKeyFormat, iIndex++);
590c2c66affSColin Finck nResult = RegCreateKeyExW(hKey, szNewKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hNewKey, &dwDisposition);
591c2c66affSColin Finck if (hNewKey && dwDisposition == REG_OPENED_EXISTING_KEY)
592c2c66affSColin Finck {
593c2c66affSColin Finck RegCloseKey(hNewKey);
594c2c66affSColin Finck hNewKey = NULL;
595c2c66affSColin Finck }
596c2c66affSColin Finck else if (!hNewKey)
597c2c66affSColin Finck {
598c2c66affSColin Finck InfoMessageBox(hFrameWnd, MB_OK | MB_ICONERROR, NULL, L"Cannot create new key!\n\nError Code: %d", nResult);
599c2c66affSColin Finck goto done;
600c2c66affSColin Finck }
601c2c66affSColin Finck }
602c2c66affSColin Finck while(!hNewKey);
603c2c66affSColin Finck
604c2c66affSColin Finck /* Insert the new key */
605c2c66affSColin Finck hNewItem = InsertNode(hwndTV, hItem, szNewKey);
606c2c66affSColin Finck if (!hNewItem)
607c2c66affSColin Finck goto done;
608c2c66affSColin Finck
609c2c66affSColin Finck /* The new key's name is probably not appropriate yet */
610c2c66affSColin Finck (void)TreeView_EditLabel(hwndTV, hNewItem);
611c2c66affSColin Finck
612c2c66affSColin Finck bSuccess = TRUE;
613c2c66affSColin Finck
614c2c66affSColin Finck done:
615c2c66affSColin Finck if (hKey != hRootKey && hKey)
616c2c66affSColin Finck RegCloseKey(hKey);
617c2c66affSColin Finck if (hNewKey)
618c2c66affSColin Finck RegCloseKey(hNewKey);
619c2c66affSColin Finck return bSuccess;
620c2c66affSColin Finck }
621c2c66affSColin Finck
TreeWndNotifyProc(HWND hWnd,WPARAM wParam,LPARAM lParam,BOOL * Result)6224d1cd723SKyle Katarn BOOL TreeWndNotifyProc(HWND hWnd, WPARAM wParam, LPARAM lParam, BOOL *Result)
6234d1cd723SKyle Katarn {
6244d1cd723SKyle Katarn UNREFERENCED_PARAMETER(wParam);
6254d1cd723SKyle Katarn *Result = TRUE;
6264d1cd723SKyle Katarn
6274d1cd723SKyle Katarn switch (((LPNMHDR)lParam)->code)
6284d1cd723SKyle Katarn {
6294d1cd723SKyle Katarn case TVN_ITEMEXPANDING:
6304d1cd723SKyle Katarn *Result = !OnTreeExpanding(g_pChildWnd->hTreeWnd, (NMTREEVIEW*)lParam);
6314d1cd723SKyle Katarn return TRUE;
6324d1cd723SKyle Katarn case TVN_SELCHANGED:
6334d1cd723SKyle Katarn {
6344d1cd723SKyle Katarn NMTREEVIEW* pnmtv = (NMTREEVIEW*)lParam;
6354d1cd723SKyle Katarn /* Get the parent of the current item */
6364d1cd723SKyle Katarn HTREEITEM hParentItem = TreeView_GetParent(g_pChildWnd->hTreeWnd, pnmtv->itemNew.hItem);
6374d1cd723SKyle Katarn
63884e580b6SKatayama Hirofumi MZ UpdateAddress(pnmtv->itemNew.hItem, NULL, NULL, TRUE);
6394d1cd723SKyle Katarn
6407f45cac9SJose Carlos Jesus /* Disable the Permissions and new key menu items for 'My Computer' */
6414d1cd723SKyle Katarn EnableMenuItem(hMenuFrame, ID_EDIT_PERMISSIONS, MF_BYCOMMAND | (hParentItem ? MF_ENABLED : MF_GRAYED));
6427f45cac9SJose Carlos Jesus EnableMenuItem(hMenuFrame, ID_EDIT_NEW_KEY, MF_BYCOMMAND | (hParentItem ? MF_ENABLED : MF_GRAYED));
6434d1cd723SKyle Katarn
6444d1cd723SKyle Katarn /*
6454d1cd723SKyle Katarn * Disable Delete/Rename menu options for 'My Computer' (first item so doesn't have any parent)
6464d1cd723SKyle Katarn * and HKEY_* keys (their parent is 'My Computer' and the previous remark applies).
6474d1cd723SKyle Katarn */
6484d1cd723SKyle Katarn if (!hParentItem || !TreeView_GetParent(g_pChildWnd->hTreeWnd, hParentItem))
6494d1cd723SKyle Katarn {
6504d1cd723SKyle Katarn EnableMenuItem(hMenuFrame , ID_EDIT_DELETE, MF_BYCOMMAND | MF_GRAYED);
6514d1cd723SKyle Katarn EnableMenuItem(hMenuFrame , ID_EDIT_RENAME, MF_BYCOMMAND | MF_GRAYED);
6524d1cd723SKyle Katarn EnableMenuItem(hPopupMenus, ID_TREE_DELETE, MF_BYCOMMAND | MF_GRAYED);
6534d1cd723SKyle Katarn EnableMenuItem(hPopupMenus, ID_TREE_RENAME, MF_BYCOMMAND | MF_GRAYED);
6544d1cd723SKyle Katarn }
6554d1cd723SKyle Katarn else
6564d1cd723SKyle Katarn {
6574d1cd723SKyle Katarn EnableMenuItem(hMenuFrame , ID_EDIT_DELETE, MF_BYCOMMAND | MF_ENABLED);
6584d1cd723SKyle Katarn EnableMenuItem(hMenuFrame , ID_EDIT_RENAME, MF_BYCOMMAND | MF_ENABLED);
6594d1cd723SKyle Katarn EnableMenuItem(hPopupMenus, ID_TREE_DELETE, MF_BYCOMMAND | MF_ENABLED);
6604d1cd723SKyle Katarn EnableMenuItem(hPopupMenus, ID_TREE_RENAME, MF_BYCOMMAND | MF_ENABLED);
6614d1cd723SKyle Katarn }
6624d1cd723SKyle Katarn
6634d1cd723SKyle Katarn return TRUE;
6644d1cd723SKyle Katarn }
6654d1cd723SKyle Katarn case NM_SETFOCUS:
6664d1cd723SKyle Katarn g_pChildWnd->nFocusPanel = 0;
6674d1cd723SKyle Katarn break;
6684d1cd723SKyle Katarn case TVN_BEGINLABELEDIT:
6694d1cd723SKyle Katarn {
6704d1cd723SKyle Katarn LPNMTVDISPINFO ptvdi = (LPNMTVDISPINFO)lParam;
671*087979eeSWhindmar Saksit HWND hWndFocus = GetFocus();
672*087979eeSWhindmar Saksit
6734d1cd723SKyle Katarn /* cancel label edit for rootkeys */
6744d1cd723SKyle Katarn if (!TreeView_GetParent(g_pChildWnd->hTreeWnd, ptvdi->item.hItem) ||
6754d1cd723SKyle Katarn !TreeView_GetParent(g_pChildWnd->hTreeWnd, TreeView_GetParent(g_pChildWnd->hTreeWnd, ptvdi->item.hItem)))
6764d1cd723SKyle Katarn {
6774d1cd723SKyle Katarn *Result = TRUE;
6784d1cd723SKyle Katarn }
6794d1cd723SKyle Katarn else
6804d1cd723SKyle Katarn {
6814d1cd723SKyle Katarn *Result = FALSE;
6824d1cd723SKyle Katarn }
683*087979eeSWhindmar Saksit
684*087979eeSWhindmar Saksit /* cancel label edit if VK_DELETE accelerator opened a MessageBox */
685*087979eeSWhindmar Saksit if (hWndFocus != g_pChildWnd->hTreeWnd && hWndFocus != TreeView_GetEditControl(g_pChildWnd->hTreeWnd))
686*087979eeSWhindmar Saksit {
687*087979eeSWhindmar Saksit *Result = TRUE;
688*087979eeSWhindmar Saksit }
6894d1cd723SKyle Katarn return TRUE;
6904d1cd723SKyle Katarn }
6914d1cd723SKyle Katarn case TVN_ENDLABELEDIT:
6924d1cd723SKyle Katarn {
6934d1cd723SKyle Katarn LPCWSTR keyPath;
6944d1cd723SKyle Katarn HKEY hRootKey;
6954d1cd723SKyle Katarn HKEY hKey = NULL;
6964d1cd723SKyle Katarn LPNMTVDISPINFO ptvdi = (LPNMTVDISPINFO)lParam;
6974d1cd723SKyle Katarn LONG nRenResult;
6984d1cd723SKyle Katarn LONG lResult = TRUE;
6994d1cd723SKyle Katarn WCHAR szBuffer[MAX_PATH];
7004d1cd723SKyle Katarn WCHAR Caption[128];
7014d1cd723SKyle Katarn
7024d1cd723SKyle Katarn if (ptvdi->item.pszText)
7034d1cd723SKyle Katarn {
7044d1cd723SKyle Katarn keyPath = GetItemPath(g_pChildWnd->hTreeWnd, TreeView_GetParent(g_pChildWnd->hTreeWnd, ptvdi->item.hItem), &hRootKey);
7054d1cd723SKyle Katarn if (wcslen(keyPath))
70636a7f0dcSRobert Naumann _snwprintf(szBuffer, ARRAY_SIZE(szBuffer), L"%s\\%s", keyPath, ptvdi->item.pszText);
7074d1cd723SKyle Katarn else
70836a7f0dcSRobert Naumann _snwprintf(szBuffer, ARRAY_SIZE(szBuffer), L"%s", ptvdi->item.pszText);
7094d1cd723SKyle Katarn keyPath = GetItemPath(g_pChildWnd->hTreeWnd, ptvdi->item.hItem, &hRootKey);
7104d1cd723SKyle Katarn if (RegOpenKeyExW(hRootKey, szBuffer, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
7114d1cd723SKyle Katarn {
7124d1cd723SKyle Katarn lResult = FALSE;
7134d1cd723SKyle Katarn RegCloseKey(hKey);
7144d1cd723SKyle Katarn TreeView_EditLabel(g_pChildWnd->hTreeWnd, ptvdi->item.hItem);
7154d1cd723SKyle Katarn }
7164d1cd723SKyle Katarn else
7174d1cd723SKyle Katarn {
7184d1cd723SKyle Katarn nRenResult = RenameKey(hRootKey, keyPath, ptvdi->item.pszText);
7194d1cd723SKyle Katarn if (nRenResult != ERROR_SUCCESS)
7204d1cd723SKyle Katarn {
72136a7f0dcSRobert Naumann LoadStringW(hInst, IDS_ERROR, Caption, ARRAY_SIZE(Caption));
7224d1cd723SKyle Katarn ErrorMessageBox(hWnd, Caption, nRenResult);
7234d1cd723SKyle Katarn lResult = FALSE;
7244d1cd723SKyle Katarn }
7254d1cd723SKyle Katarn else
72684e580b6SKatayama Hirofumi MZ UpdateAddress(ptvdi->item.hItem, hRootKey, szBuffer, FALSE);
7274d1cd723SKyle Katarn }
7284d1cd723SKyle Katarn *Result = lResult;
7294d1cd723SKyle Katarn }
7304d1cd723SKyle Katarn return TRUE;
7314d1cd723SKyle Katarn }
7324d1cd723SKyle Katarn }
7334d1cd723SKyle Katarn return FALSE;
7344d1cd723SKyle Katarn }
735c2c66affSColin Finck
736c2c66affSColin Finck /*
737c2c66affSColin Finck * CreateTreeView - creates a tree view control.
738c2c66affSColin Finck * Returns the handle to the new control if successful, or NULL otherwise.
739c2c66affSColin Finck * hwndParent - handle to the control's parent window.
740c2c66affSColin Finck */
CreateTreeView(HWND hwndParent,LPWSTR pHostName,HMENU id)741c2c66affSColin Finck HWND CreateTreeView(HWND hwndParent, LPWSTR pHostName, HMENU id)
742c2c66affSColin Finck {
743c2c66affSColin Finck RECT rcClient;
744c2c66affSColin Finck HWND hwndTV;
745c2c66affSColin Finck
746c2c66affSColin Finck /* Get the dimensions of the parent window's client area, and create the tree view control. */
747c2c66affSColin Finck GetClientRect(hwndParent, &rcClient);
748c2c66affSColin Finck hwndTV = CreateWindowExW(WS_EX_CLIENTEDGE, WC_TREEVIEW, NULL,
749c2c66affSColin Finck WS_VISIBLE | WS_CHILD | WS_TABSTOP | TVS_HASLINES | TVS_HASBUTTONS | TVS_LINESATROOT | TVS_EDITLABELS | TVS_SHOWSELALWAYS,
750c2c66affSColin Finck 0, 0, rcClient.right, rcClient.bottom,
751c2c66affSColin Finck hwndParent, id, hInst, NULL);
7524d1cd723SKyle Katarn if (!hwndTV) return NULL;
7534d1cd723SKyle Katarn
754c2c66affSColin Finck /* Initialize the image list, and add items to the control. */
755c2c66affSColin Finck if (!InitTreeViewImageLists(hwndTV) || !InitTreeViewItems(hwndTV, pHostName))
756c2c66affSColin Finck {
757c2c66affSColin Finck DestroyWindow(hwndTV);
758c2c66affSColin Finck return NULL;
759c2c66affSColin Finck }
760c2c66affSColin Finck return hwndTV;
761c2c66affSColin Finck }
762c2c66affSColin Finck
DestroyTreeView(HWND hwndTV)763c2c66affSColin Finck void DestroyTreeView(HWND hwndTV)
764c2c66affSColin Finck {
765c2c66affSColin Finck HIMAGELIST himl;
766c2c66affSColin Finck
767c2c66affSColin Finck if (pathBuffer) HeapFree(GetProcessHeap(), 0, pathBuffer);
768c2c66affSColin Finck
769c2c66affSColin Finck /* Destroy the image list associated with the tree view control */
770c2c66affSColin Finck himl = TreeView_GetImageList(hwndTV, TVSIL_NORMAL);
771c2c66affSColin Finck if (himl) ImageList_Destroy(himl);
772c2c66affSColin Finck }
773c2c66affSColin Finck
SelectNode(HWND hwndTV,LPCWSTR keyPath)774c2c66affSColin Finck BOOL SelectNode(HWND hwndTV, LPCWSTR keyPath)
775c2c66affSColin Finck {
776c2c66affSColin Finck HTREEITEM hRoot, hItem;
777c2c66affSColin Finck HTREEITEM hChildItem;
778c2c66affSColin Finck WCHAR szPathPart[128];
779c2c66affSColin Finck WCHAR szBuffer[128];
780c2c66affSColin Finck LPCWSTR s;
781c2c66affSColin Finck TVITEMW tvi;
782c2c66affSColin Finck
783c2c66affSColin Finck /* Load "My Computer" string... */
78436a7f0dcSRobert Naumann LoadStringW(hInst, IDS_MY_COMPUTER, szBuffer, ARRAY_SIZE(szBuffer));
7851ee9ea45SThomas Faber StringCbCatW(szBuffer, sizeof(szBuffer), L"\\");
786c2c66affSColin Finck
787c2c66affSColin Finck /* ... and remove it from the key path */
788c2c66affSColin Finck if (!_wcsnicmp(keyPath, szBuffer, wcslen(szBuffer)))
789c2c66affSColin Finck keyPath += wcslen(szBuffer);
790c2c66affSColin Finck
791c2c66affSColin Finck /* Reinitialize szBuffer */
792c2c66affSColin Finck szBuffer[0] = L'\0';
793c2c66affSColin Finck
794c2c66affSColin Finck hRoot = TreeView_GetRoot(hwndTV);
795c2c66affSColin Finck hItem = hRoot;
796c2c66affSColin Finck
797c2c66affSColin Finck while(keyPath[0])
798c2c66affSColin Finck {
7991ee9ea45SThomas Faber size_t copyLength;
800c2c66affSColin Finck s = wcschr(keyPath, L'\\');
8011ee9ea45SThomas Faber if (s != NULL)
8021ee9ea45SThomas Faber {
8031ee9ea45SThomas Faber copyLength = (s - keyPath) * sizeof(WCHAR);
8041ee9ea45SThomas Faber }
8051ee9ea45SThomas Faber else
8061ee9ea45SThomas Faber {
8071ee9ea45SThomas Faber copyLength = sizeof(szPathPart);
8081ee9ea45SThomas Faber }
8091ee9ea45SThomas Faber StringCbCopyNW(szPathPart, sizeof(szPathPart), keyPath, copyLength);
810c2c66affSColin Finck
811c2c66affSColin Finck /* Special case for root to expand root key abbreviations */
812c2c66affSColin Finck if (hItem == hRoot)
813c2c66affSColin Finck {
814c2c66affSColin Finck if (!_wcsicmp(szPathPart, L"HKCR"))
8151ee9ea45SThomas Faber StringCbCopyW(szPathPart, sizeof(szPathPart), L"HKEY_CLASSES_ROOT");
816c2c66affSColin Finck else if (!_wcsicmp(szPathPart, L"HKCU"))
8171ee9ea45SThomas Faber StringCbCopyW(szPathPart, sizeof(szPathPart), L"HKEY_CURRENT_USER");
818c2c66affSColin Finck else if (!_wcsicmp(szPathPart, L"HKLM"))
8191ee9ea45SThomas Faber StringCbCopyW(szPathPart, sizeof(szPathPart), L"HKEY_LOCAL_MACHINE");
820c2c66affSColin Finck else if (!_wcsicmp(szPathPart, L"HKU"))
8211ee9ea45SThomas Faber StringCbCopyW(szPathPart, sizeof(szPathPart), L"HKEY_USERS");
822c2c66affSColin Finck else if (!_wcsicmp(szPathPart, L"HKCC"))
8231ee9ea45SThomas Faber StringCbCopyW(szPathPart, sizeof(szPathPart), L"HKEY_CURRENT_CONFIG");
824c2c66affSColin Finck else if (!_wcsicmp(szPathPart, L"HKDD"))
8251ee9ea45SThomas Faber StringCbCopyW(szPathPart, sizeof(szPathPart), L"HKEY_DYN_DATA");
826c2c66affSColin Finck }
827c2c66affSColin Finck
828c2c66affSColin Finck for (hChildItem = TreeView_GetChild(hwndTV, hItem); hChildItem;
829c2c66affSColin Finck hChildItem = TreeView_GetNextSibling(hwndTV, hChildItem))
830c2c66affSColin Finck {
831c2c66affSColin Finck memset(&tvi, 0, sizeof(tvi));
832c2c66affSColin Finck tvi.hItem = hChildItem;
833c2c66affSColin Finck tvi.mask = TVIF_TEXT | TVIF_CHILDREN;
834c2c66affSColin Finck tvi.pszText = szBuffer;
83536a7f0dcSRobert Naumann tvi.cchTextMax = ARRAY_SIZE(szBuffer);
836c2c66affSColin Finck
837c2c66affSColin Finck (void)TreeView_GetItem(hwndTV, &tvi);
838c2c66affSColin Finck
839c2c66affSColin Finck if (!_wcsicmp(szBuffer, szPathPart))
840c2c66affSColin Finck break;
841c2c66affSColin Finck }
842c2c66affSColin Finck
843c2c66affSColin Finck if (!hChildItem)
844c2c66affSColin Finck return FALSE;
845c2c66affSColin Finck
846c2c66affSColin Finck if (tvi.cChildren > 0)
847c2c66affSColin Finck {
848c2c66affSColin Finck if (!TreeView_Expand(hwndTV, hChildItem, TVE_EXPAND))
849c2c66affSColin Finck return FALSE;
850c2c66affSColin Finck }
851c2c66affSColin Finck
852c2c66affSColin Finck keyPath = s ? s + 1 : L"";
853c2c66affSColin Finck hItem = hChildItem;
854c2c66affSColin Finck }
855c2c66affSColin Finck
856c2c66affSColin Finck (void)TreeView_SelectItem(hwndTV, hItem);
857c2c66affSColin Finck (void)TreeView_EnsureVisible(hwndTV, hItem);
858c2c66affSColin Finck
859c2c66affSColin Finck return TRUE;
860c2c66affSColin Finck }
861c2c66affSColin Finck
862c2c66affSColin Finck /* EOF */
863