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