Reformat regedit in a consistent manner.
[wine.git] / programs / regedit / treeview.c
blob0e260cd4fff6d83d12c9a7ceeda6678e9db54819
1 /*
2 * Regedit treeview
4 * Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #define WIN32_LEAN_AND_MEAN /* Exclude rarely-used stuff from Windows headers */
23 #define NONAMELESSUNION
24 #define NONAMELESSSTRUCT
25 #include <windows.h>
26 #include <commctrl.h>
27 #include <stdlib.h>
28 #include <tchar.h>
29 #include <process.h>
30 #include <stdio.h>
32 #include "main.h"
34 /* Global variables and constants */
35 /* Image_Open, Image_Closed, and Image_Root - integer variables for indexes of the images. */
36 /* CX_BITMAP and CY_BITMAP - width and height of an icon. */
37 /* NUM_BITMAPS - number of bitmaps to add to the image list. */
38 int Image_Open;
39 int Image_Closed;
40 int Image_Root;
42 #define CX_BITMAP 16
43 #define CY_BITMAP 16
44 #define NUM_BITMAPS 3
47 HKEY FindRegRoot(HWND hwndTV, HTREEITEM hItem, LPTSTR keyPath, int* pPathLen, int max)
49 HKEY hKey = NULL;
50 TVITEM item;
52 if (!hItem) hItem = TreeView_GetSelection(hwndTV);
54 item.mask = TVIF_PARAM;
55 item.hItem = TreeView_GetParent(hwndTV, hItem);
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);
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);
83 return hKey;
86 static HTREEITEM AddEntryToTree(HWND hwndTV, HTREEITEM hParent, LPTSTR label, HKEY hKey, DWORD dwChildren)
88 HTREEITEM hItem = 0;
89 TVITEM tvi;
90 TVINSERTSTRUCT tvins;
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.u.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;
108 static BOOL InitTreeViewItems(HWND hwndTV, LPTSTR pHostName)
110 TVITEM tvi;
111 TVINSERTSTRUCT tvins;
112 HTREEITEM hRoot;
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.u.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);
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);
136 return TRUE;
140 * InitTreeViewImageLists - creates an image list, adds three bitmaps
141 * to it, and associates the image list with a tree view control.
142 * Returns TRUE if successful, or FALSE otherwise.
143 * hwndTV - handle to the tree view control.
146 static BOOL InitTreeViewImageLists(HWND hwndTV)
148 HIMAGELIST himl; /* handle to image list */
149 HBITMAP hbmp; /* handle to bitmap */
151 /* Create the image list. */
152 if ((himl = ImageList_Create(CX_BITMAP, CY_BITMAP,
153 FALSE, NUM_BITMAPS, 0)) == NULL)
154 return FALSE;
156 /* Add the open file, closed file, and document bitmaps. */
157 hbmp = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_OPEN_FILE));
158 Image_Open = ImageList_Add(himl, hbmp, (HBITMAP) NULL);
159 DeleteObject(hbmp);
161 hbmp = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_CLOSED_FILE));
162 Image_Closed = ImageList_Add(himl, hbmp, (HBITMAP) NULL);
163 DeleteObject(hbmp);
165 hbmp = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_ROOT));
166 Image_Root = ImageList_Add(himl, hbmp, (HBITMAP) NULL);
167 DeleteObject(hbmp);
169 /* Fail if not all of the images were added. */
170 if (ImageList_GetImageCount(himl) < 3)
171 return FALSE;
173 /* Associate the image list with the tree view control. */
174 TreeView_SetImageList(hwndTV, himl, TVSIL_NORMAL);
176 return TRUE;
179 BOOL OnTreeExpanding(HWND hwndTV, NMTREEVIEW* pnmtv)
181 HKEY hKey;
182 TCHAR keyPath[1000];
183 int keyPathLen = 0;
185 static int expanding;
186 if (expanding) return FALSE;
187 if (pnmtv->itemNew.state & TVIS_EXPANDEDONCE ) {
188 return TRUE;
190 expanding = TRUE;
192 /* check if this is either the root or a subkey item... */
193 if ((HKEY)pnmtv->itemNew.lParam == NULL) {
194 keyPath[0] = _T('\0');
195 hKey = FindRegRoot(hwndTV, pnmtv->itemNew.hItem, keyPath, &keyPathLen, sizeof(keyPath)/sizeof(TCHAR));
196 } else {
197 hKey = (HKEY)pnmtv->itemNew.lParam;
198 keyPath[0] = _T('\0');
201 if (hKey != NULL) {
202 HKEY hNewKey;
203 LONG errCode = RegOpenKeyEx(hKey, keyPath, 0, KEY_READ, &hNewKey);
204 if (errCode == ERROR_SUCCESS) {
205 TCHAR Name[MAX_NAME_LEN];
206 DWORD cName = MAX_NAME_LEN;
207 FILETIME LastWriteTime;
208 DWORD dwIndex = 0L;
209 /*ShowWindow(hwndTV, SW_HIDE); */
210 while (RegEnumKeyEx(hNewKey, dwIndex, Name, &cName, NULL, NULL, NULL, &LastWriteTime) == ERROR_SUCCESS) {
211 DWORD dwCount = 0L;
212 errCode = RegOpenKeyEx(hNewKey, Name, 0, KEY_READ, &hKey);
213 if (errCode == ERROR_SUCCESS) {
214 TCHAR SubName[MAX_NAME_LEN];
215 DWORD cSubName = MAX_NAME_LEN;
216 /* if (RegEnumKeyEx(hKey, 0, SubName, &cSubName, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { */
217 while (RegEnumKeyEx(hKey, dwCount, SubName, &cSubName, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) {
218 ++dwCount;
221 RegCloseKey(hKey);
222 AddEntryToTree(hwndTV, pnmtv->itemNew.hItem, Name, NULL, dwCount);
223 cName = MAX_NAME_LEN;
224 ++dwIndex;
226 /*ShowWindow(hwndTV, SW_SHOWNOACTIVATE); */
227 RegCloseKey(hNewKey);
230 expanding = FALSE;
231 return TRUE;
235 * CreateTreeView - creates a tree view control.
236 * Returns the handle to the new control if successful, or NULL otherwise.
237 * hwndParent - handle to the control's parent window.
240 HWND CreateTreeView(HWND hwndParent, LPTSTR pHostName, int id)
242 RECT rcClient;
243 HWND hwndTV;
245 /* Get the dimensions of the parent window's client area, and create the tree view control. */
246 GetClientRect(hwndParent, &rcClient);
247 hwndTV = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, _T("Tree View"),
248 WS_VISIBLE | WS_CHILD | TVS_HASLINES | TVS_HASBUTTONS | TVS_LINESATROOT,
249 0, 0, rcClient.right, rcClient.bottom,
250 hwndParent, (HMENU)id, hInst, NULL);
251 /* Initialize the image list, and add items to the control. */
252 if (!InitTreeViewImageLists(hwndTV) || !InitTreeViewItems(hwndTV, pHostName)) {
253 DestroyWindow(hwndTV);
254 return NULL;
256 return hwndTV;