Reverting to 13775. Sorry for the mess. This is dedicated to Jane! 19934415.
[reactos.git] / reactos / subsys / system / regedt32 / treeview.c
1 /*
2 * ReactOS regedit
3 *
4 * treeview.c
5 *
6 * Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #ifdef _MSC_VER
24 #include "stdafx.h"
25 #else
26 #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
27 #include <windows.h>
28 #include <commctrl.h>
29 #include <stdlib.h>
30 #include <malloc.h>
31 #include <memory.h>
32 #include <tchar.h>
33 #include <process.h>
34 #include <stdio.h>
35 #endif
36
37 #include "main.h"
38 #include "treeview.h"
39
40
41 // Global variables and constants
42 // Image_Open, Image_Closed, and Image_Root - integer variables for indexes of the images.
43 // CX_BITMAP and CY_BITMAP - width and height of an icon.
44 // NUM_BITMAPS - number of bitmaps to add to the image list.
45 int Image_Open;
46 int Image_Closed;
47 int Image_Root;
48
49 #define CX_BITMAP 16
50 #define CY_BITMAP 16
51 #define NUM_BITMAPS 3
52
53
54 HKEY FindRegRoot(HWND hwndTV, HTREEITEM hItem, LPTSTR keyPath, int* pPathLen, int max)
55 {
56 HKEY hKey = NULL;
57 TVITEM item;
58 item.mask = TVIF_PARAM;
59 item.hItem = TreeView_GetParent(hwndTV, hItem);
60
61 if (TreeView_GetItem(hwndTV, &item)) {
62 if (item.lParam == 0) {
63 // recurse
64 hKey = FindRegRoot(hwndTV, item.hItem, keyPath, pPathLen, max);
65 keyPath[*pPathLen] = _T('\\');
66 ++(*pPathLen);
67 item.mask = TVIF_TEXT;
68 item.hItem = hItem;
69 item.pszText = &keyPath[*pPathLen];
70 item.cchTextMax = max - *pPathLen;
71 if (TreeView_GetItem(hwndTV, &item)) {
72 *pPathLen += _tcslen(item.pszText);
73 }
74 } else {
75 // found root key with valid key value
76 hKey = (HKEY)item.lParam;
77 item.mask = TVIF_TEXT;
78 item.hItem = hItem;
79 // item.pszText = &keyPath[*pPathLen];
80 item.pszText = keyPath;
81 item.cchTextMax = max;
82 if (TreeView_GetItem(hwndTV, &item)) {
83 *pPathLen += _tcslen(item.pszText);
84 }
85 }
86 }
87 return hKey;
88 }
89
90 static HTREEITEM AddEntryToTree(HWND hwndTV, HTREEITEM hParent, LPTSTR label, HKEY hKey, DWORD dwChildren)
91 {
92 HTREEITEM hItem = 0;
93 TVITEM tvi;
94 TVINSERTSTRUCT tvins;
95
96 tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN | TVIF_PARAM;
97 tvi.pszText = label;
98 tvi.cchTextMax = lstrlen(tvi.pszText);
99 tvi.iImage = Image_Closed;
100 tvi.iSelectedImage = Image_Open;
101 tvi.cChildren = dwChildren;
102 tvi.lParam = (LPARAM)hKey;
103 tvins.item = tvi;
104 if (hKey) tvins.hInsertAfter = (HTREEITEM)TVI_LAST;
105 else tvins.hInsertAfter = (HTREEITEM)TVI_SORT;
106 tvins.hParent = hParent;
107 hItem = (HTREEITEM)SendMessage(hwndTV, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT)&tvins);
108 return hItem;
109 }
110
111
112 static BOOL InitTreeViewItems(HWND hwndTV, LPTSTR szKeyName, HKEY hKey)
113 {
114 TVITEM tvi;
115 TVINSERTSTRUCT tvins;
116 HTREEITEM hRoot;
117
118 tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN | TVIF_PARAM;
119 // Set the text of the item.
120 tvi.pszText = szKeyName;
121 tvi.cchTextMax = lstrlen(tvi.pszText);
122 // Assume the item is not a parent item, so give it an image.
123 tvi.iImage = Image_Root;
124 tvi.iSelectedImage = Image_Root;
125 tvi.cChildren = 5;
126 // Save the heading level in the item's application-defined data area.
127 //tvi.lParam = (LPARAM)NULL;
128 tvi.lParam = (LPARAM)hKey;
129 tvins.item = tvi;
130 tvins.hInsertAfter = (HTREEITEM)TVI_FIRST;
131 tvins.hParent = TVI_ROOT;
132 // Add the item to the tree view control.
133 hRoot = (HTREEITEM)SendMessage(hwndTV, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT)&tvins);
134
135 // AddEntryToTree(hwndTV, hRoot, _T("HKEY_CLASSES_ROOT"), HKEY_CLASSES_ROOT, 1);
136 // AddEntryToTree(hwndTV, hRoot, _T("HKEY_CURRENT_USER"), HKEY_CURRENT_USER, 1);
137 // AddEntryToTree(hwndTV, hRoot, _T("HKEY_LOCAL_MACHINE"), HKEY_LOCAL_MACHINE, 1);
138 // AddEntryToTree(hwndTV, hRoot, _T("HKEY_USERS"), HKEY_USERS, 1);
139 // AddEntryToTree(hwndTV, hRoot, _T("HKEY_CURRENT_CONFIG"), HKEY_CURRENT_CONFIG, 1);
140
141 return TRUE;
142 }
143
144 // InitTreeViewImageLists - creates an image list, adds three bitmaps
145 // to it, and associates the image list with a tree view control.
146 // Returns TRUE if successful, or FALSE otherwise.
147 // hwndTV - handle to the tree view control.
148
149 static BOOL InitTreeViewImageLists(HWND hwndTV)
150 {
151 HIMAGELIST himl; // handle to image list
152 HBITMAP hbmp; // handle to bitmap
153
154 // Create the image list.
155 if ((himl = ImageList_Create(CX_BITMAP, CY_BITMAP,
156 FALSE, NUM_BITMAPS, 0)) == NULL)
157 return FALSE;
158
159 // Add the open file, closed file, and document bitmaps.
160 hbmp = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_OPEN_FILE));
161 Image_Open = ImageList_Add(himl, hbmp, (HBITMAP) NULL);
162 DeleteObject(hbmp);
163
164 hbmp = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_CLOSED_FILE));
165 Image_Closed = ImageList_Add(himl, hbmp, (HBITMAP) NULL);
166 DeleteObject(hbmp);
167
168 hbmp = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_ROOT));
169 Image_Root = ImageList_Add(himl, hbmp, (HBITMAP) NULL);
170 DeleteObject(hbmp);
171
172 // Fail if not all of the images were added.
173 if (ImageList_GetImageCount(himl) < 3)
174 return FALSE;
175
176 // Associate the image list with the tree view control.
177 TreeView_SetImageList(hwndTV, himl, TVSIL_NORMAL);
178
179 return TRUE;
180 }
181
182 BOOL OnTreeExpanding(HWND hwndTV, NMTREEVIEW* pnmtv)
183 {
184 HKEY hKey;
185 TCHAR keyPath[1000];
186 int keyPathLen = 0;
187
188 static int expanding;
189 if (expanding) return FALSE;
190 if (pnmtv->itemNew.state & TVIS_EXPANDEDONCE ) {
191 return TRUE;
192 }
193 expanding = TRUE;
194
195 // check if this is either the root or a subkey item...
196 if ((HKEY)pnmtv->itemNew.lParam == NULL) {
197 keyPath[0] = _T('\0');
198 hKey = FindRegRoot(hwndTV, pnmtv->itemNew.hItem, keyPath, &keyPathLen, sizeof(keyPath));
199 } else {
200 hKey = (HKEY)pnmtv->itemNew.lParam;
201 keyPath[0] = _T('\0');
202 }
203
204 if (hKey != NULL) {
205 HKEY hNewKey;
206 LONG errCode = RegOpenKeyEx(hKey, keyPath, 0, KEY_READ, &hNewKey);
207 if (errCode == ERROR_SUCCESS) {
208 TCHAR Name[MAX_NAME_LEN];
209 DWORD cName = MAX_NAME_LEN;
210 FILETIME LastWriteTime;
211 DWORD dwIndex = 0L;
212 //ShowWindow(hwndTV, SW_HIDE);
213 while (RegEnumKeyEx(hNewKey, dwIndex, Name, &cName, NULL, NULL, NULL, &LastWriteTime) == ERROR_SUCCESS) {
214 DWORD dwCount = 0L;
215 errCode = RegOpenKeyEx(hNewKey, Name, 0, KEY_READ, &hKey);
216 if (errCode == ERROR_SUCCESS) {
217 TCHAR SubName[MAX_NAME_LEN];
218 DWORD cSubName = MAX_NAME_LEN;
219 // if (RegEnumKeyEx(hKey, 0, SubName, &cSubName, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) {
220 while (RegEnumKeyEx(hKey, dwCount, SubName, &cSubName, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) {
221 ++dwCount;
222 }
223 }
224 RegCloseKey(hKey);
225 AddEntryToTree(hwndTV, pnmtv->itemNew.hItem, Name, NULL, dwCount);
226 cName = MAX_NAME_LEN;
227 ++dwIndex;
228 }
229 //ShowWindow(hwndTV, SW_SHOWNOACTIVATE);
230 RegCloseKey(hNewKey);
231 }
232 } else {
233 }
234 expanding = FALSE;
235 return TRUE;
236 }
237
238 // CreateTreeView - creates a tree view control.
239 // Returns the handle to the new control if successful, or NULL otherwise.
240 // hwndParent - handle to the control's parent window.
241
242 HWND CreateTreeView(HWND hwndParent, LPTSTR szKeyName, HKEY hKey)
243 {
244 RECT rcClient;
245 HWND hwndTV;
246
247 // Get the dimensions of the parent window's client area, and create the tree view control.
248 GetClientRect(hwndParent, &rcClient);
249 hwndTV = CreateWindowEx(0, WC_TREEVIEW, _T("Tree View"),
250 WS_VISIBLE | WS_CHILD | WS_EX_CLIENTEDGE | TVS_HASLINES | TVS_HASBUTTONS | TVS_LINESATROOT,
251 0, 0, rcClient.right, rcClient.bottom,
252 hwndParent, (HMENU)TREE_WINDOW, hInst, NULL);
253 // Initialize the image list, and add items to the control.
254 if (!InitTreeViewImageLists(hwndTV) || !InitTreeViewItems(hwndTV, szKeyName, hKey)) {
255 DestroyWindow(hwndTV);
256 return NULL;
257 }
258 return hwndTV;
259 }