Recurse the tree and clean up all the strings tagged to the items. Servman now has...
[reactos.git] / reactos / base / applications / mscutils / servman / propsheet_depends.c
1 /*
2 * PROJECT: ReactOS Services
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/applications/mscutils/servman/propsheet_depends.c
5 * PURPOSE: Property dialog box message handler
6 * COPYRIGHT: Copyright 2006-2009 Ged Murphy <gedmurphy@reactos.org>
7 *
8 */
9
10 #include "precomp.h"
11
12
13 HTREEITEM
14 AddItemToTreeView(HWND hTreeView,
15 HTREEITEM hParent,
16 LPTSTR lpDisplayName,
17 LPTSTR lpServiceName,
18 ULONG ServiceType,
19 BOOL bHasChildren)
20 {
21 TV_ITEM tvi;
22 TV_INSERTSTRUCT tvins;
23
24 ZeroMemory(&tvi, sizeof(tvi));
25 ZeroMemory(&tvins, sizeof(tvins));
26
27 tvi.mask = TVIF_TEXT | TVIF_PARAM | TVIF_SELECTEDIMAGE | TVIF_IMAGE | TVIF_CHILDREN;
28 tvi.pszText = lpDisplayName;
29 tvi.cchTextMax = _tcslen(lpDisplayName);
30 tvi.cChildren = bHasChildren;
31
32 /* Select the image for this service */
33 switch (ServiceType)
34 {
35 case SERVICE_WIN32_OWN_PROCESS:
36 case SERVICE_WIN32_SHARE_PROCESS:
37 tvi.iImage = 1;
38 tvi.iSelectedImage = 1;
39 break;
40
41 case SERVICE_KERNEL_DRIVER:
42 case SERVICE_FILE_SYSTEM_DRIVER:
43 tvi.iImage = 2;
44 tvi.iSelectedImage = 2;
45 break;
46
47 default:
48 tvi.iImage = 0;
49 tvi.iSelectedImage = 0;
50 break;
51 }
52
53 if (lpServiceName)
54 {
55 /* Attach the service name */
56 tvi.lParam = (LPARAM)(LPTSTR)HeapAlloc(GetProcessHeap(),
57 0,
58 (_tcslen(lpServiceName) + 1) * sizeof(TCHAR));
59 if (tvi.lParam)
60 {
61 _tcscpy((LPTSTR)tvi.lParam, lpServiceName);
62 }
63 }
64
65 tvins.item = tvi;
66 tvins.hParent = hParent;
67
68 return TreeView_InsertItem(hTreeView, &tvins);
69 }
70
71 static LPARAM
72 TreeView_GetItemParam(HWND hTreeView,
73 HTREEITEM hItem)
74 {
75 LPARAM lParam = 0;
76 TVITEM tv = {0};
77
78 tv.mask = TVIF_PARAM | TVIF_HANDLE;
79 tv.hItem = hItem;
80
81 if (TreeView_GetItem(hTreeView, &tv))
82 {
83 lParam = tv.lParam;
84 }
85
86 return lParam;
87 }
88
89 static VOID
90 DestroyItem(HWND hTreeView,
91 HTREEITEM hItem)
92 {
93 HTREEITEM hChildItem;
94 LPTSTR lpServiceName;
95
96 /* Does this item have any children */
97 hChildItem = TreeView_GetChild(hTreeView, hItem);
98 if (hChildItem)
99 {
100 /* It does, recurse to that one */
101 DestroyItem(hTreeView, hChildItem);
102 }
103
104 /* Get the string and free it */
105 lpServiceName = (LPTSTR)TreeView_GetItemParam(hTreeView, hItem);
106 if (lpServiceName)
107 {
108 HeapFree(GetProcessHeap(),
109 0,
110 lpServiceName);
111 }
112 }
113
114 static VOID
115 DestroyTreeView(HWND hTreeView)
116 {
117 HTREEITEM hItem;
118
119 /* Get the first item in the top level */
120 hItem = TreeView_GetFirstVisible(hTreeView);
121 if (hItem)
122 {
123 /* Kill it and all children */
124 DestroyItem(hTreeView, hItem);
125
126 /* Kill all remaining top level items */
127 while (hItem)
128 {
129 /* Are there any more items at the top level */
130 hItem = TreeView_GetNextSibling(hTreeView, hItem);
131 if (hItem)
132 {
133 /* Kill it and all children */
134 DestroyItem(hTreeView, hItem);
135 }
136 }
137 }
138 }
139
140 /*
141 static BOOL
142 TreeView_GetItemText(HWND hTreeView,
143 HTREEITEM hItem,
144 LPTSTR lpBuffer,
145 DWORD cbBuffer)
146 {
147 TVITEM tv = {0};
148
149 tv.mask = TVIF_TEXT | TVIF_HANDLE;
150 tv.hItem = hItem;
151 tv.pszText = lpBuffer;
152 tv.cchTextMax = (int)cbBuffer;
153
154 return TreeView_GetItem(hTreeView, &tv);
155 }
156 */
157
158 static VOID
159 InitDependPage(PSERVICEPROPSHEET pDlgInfo)
160 {
161 /* Initialize the image list */
162 pDlgInfo->hDependsImageList = InitImageList(IDI_NODEPENDS,
163 IDI_DRIVER,
164 GetSystemMetrics(SM_CXSMICON),
165 GetSystemMetrics(SM_CXSMICON),
166 IMAGE_ICON);
167
168 /* Set the first tree view */
169 TV1_Initialize(pDlgInfo, pDlgInfo->pService->lpServiceName);
170
171 /* Set the second tree view */
172 TV2_Initialize(pDlgInfo, pDlgInfo->pService->lpServiceName);
173 }
174
175
176 /*
177 * Dependancies Property dialog callback.
178 * Controls messages to the Dependancies dialog
179 */
180 INT_PTR CALLBACK
181 DependenciesPageProc(HWND hwndDlg,
182 UINT uMsg,
183 WPARAM wParam,
184 LPARAM lParam)
185 {
186 PSERVICEPROPSHEET pDlgInfo;
187
188 /* Get the window context */
189 pDlgInfo = (PSERVICEPROPSHEET)GetWindowLongPtr(hwndDlg,
190 GWLP_USERDATA);
191 if (pDlgInfo == NULL && uMsg != WM_INITDIALOG)
192 {
193 return FALSE;
194 }
195
196 switch (uMsg)
197 {
198 case WM_INITDIALOG:
199 {
200 pDlgInfo = (PSERVICEPROPSHEET)(((LPPROPSHEETPAGE)lParam)->lParam);
201 if (pDlgInfo != NULL)
202 {
203 SetWindowLongPtr(hwndDlg,
204 GWLP_USERDATA,
205 (LONG_PTR)pDlgInfo);
206
207 pDlgInfo->hDependsWnd = hwndDlg;
208
209 InitDependPage(pDlgInfo);
210 }
211 }
212 break;
213
214 case WM_NOTIFY:
215 {
216 switch (((LPNMHDR)lParam)->code)
217 {
218 case TVN_ITEMEXPANDING:
219 {
220 LPNMTREEVIEW lpnmtv = (LPNMTREEVIEW)lParam;
221
222 if (lpnmtv->action == TVE_EXPAND)
223 {
224 if (lpnmtv->hdr.idFrom == IDC_DEPEND_TREE1)
225 {
226 TV1_AddDependantsToTree(pDlgInfo, lpnmtv->itemNew.hItem, (LPTSTR)lpnmtv->itemNew.lParam);
227 }
228 else if (lpnmtv->hdr.idFrom == IDC_DEPEND_TREE2)
229 {
230 TV2_AddDependantsToTree(pDlgInfo, lpnmtv->itemNew.hItem, (LPTSTR)lpnmtv->itemNew.lParam);
231 }
232 }
233 break;
234 }
235 }
236 break;
237 }
238
239 case WM_COMMAND:
240 switch(LOWORD(wParam))
241 {
242
243 }
244 break;
245
246 case WM_DESTROY:
247 DestroyTreeView(pDlgInfo->hDependsTreeView1);
248 DestroyTreeView(pDlgInfo->hDependsTreeView2);
249
250 if (pDlgInfo->hDependsImageList)
251 ImageList_Destroy(pDlgInfo->hDependsImageList);
252 }
253
254 return FALSE;
255 }