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