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
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. */
47 HKEY
FindRegRoot(HWND hwndTV
, HTREEITEM hItem
, LPTSTR keyPath
, int* pPathLen
, int max
)
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) {
60 hKey
= FindRegRoot(hwndTV
, item
.hItem
, keyPath
, pPathLen
, max
);
61 keyPath
[*pPathLen
] = _T('\\');
63 item
.mask
= TVIF_TEXT
;
65 item
.pszText
= &keyPath
[*pPathLen
];
66 item
.cchTextMax
= max
- *pPathLen
;
67 if (TreeView_GetItem(hwndTV
, &item
)) {
68 *pPathLen
+= _tcslen(item
.pszText
);
71 /* found root key with valid key value */
72 hKey
= (HKEY
)item
.lParam
;
73 item
.mask
= TVIF_TEXT
;
75 /* item.pszText = &keyPath[*pPathLen]; */
76 item
.pszText
= keyPath
;
77 item
.cchTextMax
= max
;
78 if (TreeView_GetItem(hwndTV
, &item
)) {
79 *pPathLen
+= _tcslen(item
.pszText
);
86 static HTREEITEM
AddEntryToTree(HWND hwndTV
, HTREEITEM hParent
, LPTSTR label
, HKEY hKey
, DWORD dwChildren
)
92 tvi
.mask
= TVIF_TEXT
| TVIF_IMAGE
| TVIF_SELECTEDIMAGE
| TVIF_CHILDREN
| TVIF_PARAM
;
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
;
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
);
108 static BOOL
InitTreeViewItems(HWND hwndTV
, LPTSTR pHostName
)
111 TVINSERTSTRUCT tvins
;
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
;
122 /* Save the heading level in the item's application-defined data area. */
123 tvi
.lParam
= (LPARAM
)NULL
;
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);
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
)
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
);
161 hbmp
= LoadBitmap(hInst
, MAKEINTRESOURCE(IDB_CLOSED_FILE
));
162 Image_Closed
= ImageList_Add(himl
, hbmp
, (HBITMAP
) NULL
);
165 hbmp
= LoadBitmap(hInst
, MAKEINTRESOURCE(IDB_ROOT
));
166 Image_Root
= ImageList_Add(himl
, hbmp
, (HBITMAP
) NULL
);
169 /* Fail if not all of the images were added. */
170 if (ImageList_GetImageCount(himl
) < 3)
173 /* Associate the image list with the tree view control. */
174 TreeView_SetImageList(hwndTV
, himl
, TVSIL_NORMAL
);
179 BOOL
OnTreeExpanding(HWND hwndTV
, NMTREEVIEW
* pnmtv
)
185 static int expanding
;
186 if (expanding
) return FALSE
;
187 if (pnmtv
->itemNew
.state
& TVIS_EXPANDEDONCE
) {
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
));
197 hKey
= (HKEY
)pnmtv
->itemNew
.lParam
;
198 keyPath
[0] = _T('\0');
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
;
209 /*ShowWindow(hwndTV, SW_HIDE); */
210 while (RegEnumKeyEx(hNewKey
, dwIndex
, Name
, &cName
, NULL
, NULL
, NULL
, &LastWriteTime
) == ERROR_SUCCESS
) {
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
) {
222 AddEntryToTree(hwndTV
, pnmtv
->itemNew
.hItem
, Name
, NULL
, dwCount
);
223 cName
= MAX_NAME_LEN
;
226 /*ShowWindow(hwndTV, SW_SHOWNOACTIVATE); */
227 RegCloseKey(hNewKey
);
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
)
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
);