1 /*
2  * PROJECT:     ReactOS Services
3  * LICENSE:     GPL - See COPYING in the top level directory
4  * FILE:        base/applications/mscutils/servman/listview.c
5  * PURPOSE:     service listview manipulation functions
6  * COPYRIGHT:   Copyright 2006-2007 Ged Murphy <gedmurphy@reactos.org>
7  *
8  */
9 
10 #include "precomp.h"
11 
12 typedef struct _COLUMN_LIST
13 {
14     int  iSubItem;
15     int  cx;
16     UINT idsText;
17 } COLUMN_LIST;
18 
19 static const COLUMN_LIST Columns[] =
20 {
21     /* name */
22     { LVNAME,    150, IDS_FIRSTCOLUMN  },
23     /* description */
24     { LVDESC,    240, IDS_SECONDCOLUMN },
25     /* status */
26     { LVSTATUS,   55, IDS_THIRDCOLUMN  },
27     /* startup type */
28     { LVSTARTUP,  80, IDS_FOURTHCOLUMN },
29     /* logon as */
30     { LVLOGONAS, 100, IDS_FITHCOLUMN   },
31 };
32 
33 VOID
SetListViewStyle(HWND hListView,DWORD View)34 SetListViewStyle(HWND hListView,
35                  DWORD View)
36 {
37     DWORD Style = GetWindowLongPtr(hListView, GWL_STYLE);
38 
39     if ((Style & LVS_TYPEMASK) != View)
40     {
41         SetWindowLongPtr(hListView,
42                          GWL_STYLE,
43                          (Style & ~LVS_TYPEMASK) | View);
44     }
45 }
46 
47 VOID
ListViewSelectionChanged(PMAIN_WND_INFO Info,LPNMLISTVIEW pnmv)48 ListViewSelectionChanged(PMAIN_WND_INFO Info,
49                          LPNMLISTVIEW pnmv)
50 {
51     HMENU hMainMenu;
52 
53     /* get handle to menu */
54     hMainMenu = GetMenu(Info->hMainWnd);
55 
56     /* activate properties menu item, if not already */
57     if (GetMenuState(hMainMenu,
58                      ID_PROP,
59                      MF_BYCOMMAND) != MF_ENABLED)
60     {
61         EnableMenuItem(hMainMenu,
62                        ID_PROP,
63                        MF_ENABLED);
64         EnableMenuItem(GetSubMenu(Info->hShortcutMenu, 0),
65                        ID_PROP,
66                        MF_ENABLED);
67         SetMenuDefaultItem(GetSubMenu(Info->hShortcutMenu, 0),
68                            ID_PROP,
69                            MF_BYCOMMAND);
70     }
71 
72     /* activate delete menu item, if not already */
73     if (GetMenuState(hMainMenu,
74                      ID_DELETE,
75                      MF_BYCOMMAND) != MF_ENABLED)
76     {
77         EnableMenuItem(hMainMenu,
78                        ID_DELETE,
79                        MF_ENABLED);
80         EnableMenuItem(GetSubMenu(Info->hShortcutMenu, 0),
81                        ID_DELETE,
82                        MF_ENABLED);
83     }
84 
85     /* set selected service */
86     Info->SelectedItem = pnmv->iItem;
87 
88     /* get pointer to selected service */
89     Info->pCurrentService = GetSelectedService(Info);
90 
91     /* set current selected service in the status bar */
92     SendMessage(Info->hStatus,
93                 SB_SETTEXT,
94                 1,
95                 (LPARAM)Info->pCurrentService->lpDisplayName);
96 
97     /* show the properties button */
98     SendMessage(Info->hTool,
99                 TB_SETSTATE,
100                 ID_PROP,
101                 (LPARAM)MAKELONG(TBSTATE_ENABLED, 0));
102 }
103 
104 VOID
ChangeListViewText(PMAIN_WND_INFO Info,ENUM_SERVICE_STATUS_PROCESS * pService,UINT Column)105 ChangeListViewText(PMAIN_WND_INFO Info,
106                    ENUM_SERVICE_STATUS_PROCESS* pService,
107                    UINT Column)
108 {
109     LVFINDINFO lvfi;
110     LVITEM lvItem;
111     INT index;
112 
113     lvfi.flags = LVFI_PARAM;
114     lvfi.lParam = (LPARAM)pService;
115     index = ListView_FindItem(Info->hListView,
116                               -1,
117                               &lvfi);
118     if (index != -1)
119     {
120         lvItem.iItem = index;
121         lvItem.iSubItem = Column;
122 
123         switch (Column)
124         {
125             case LVNAME:
126             {
127                 LPQUERY_SERVICE_CONFIG lpServiceConfig;
128 
129                 lpServiceConfig = GetServiceConfig(pService->lpServiceName);
130                 if (lpServiceConfig)
131                 {
132                     lvItem.pszText = lpServiceConfig->lpDisplayName;
133                     SendMessage(Info->hListView,
134                                 LVM_SETITEMTEXT,
135                                 lvItem.iItem,
136                                 (LPARAM)&lvItem);
137 
138                     HeapFree(ProcessHeap,
139                              0,
140                              lpServiceConfig);
141                 }
142             }
143             break;
144 
145             case LVDESC:
146             {
147                 LPWSTR lpDescription;
148 
149                 lpDescription = GetServiceDescription(pService->lpServiceName);
150 
151                 lvItem.pszText = lpDescription;
152                 SendMessage(Info->hListView,
153                             LVM_SETITEMTEXTW,
154                             lvItem.iItem,
155                             (LPARAM) &lvItem);
156 
157                 HeapFree(ProcessHeap,
158                          0,
159                          lpDescription);
160             }
161             break;
162 
163             case LVSTATUS:
164             {
165                 WCHAR szStatus[64];
166 
167                 if (pService->ServiceStatusProcess.dwCurrentState == SERVICE_RUNNING)
168                 {
169                     LoadStringW(hInstance,
170                                 IDS_SERVICES_STARTED,
171                                 szStatus,
172                                 sizeof(szStatus) / sizeof(WCHAR));
173                 }
174                 else
175                 {
176                     szStatus[0] = 0;
177                 }
178 
179                 lvItem.pszText = szStatus;
180                 SendMessageW(Info->hListView,
181                              LVM_SETITEMTEXT,
182                              lvItem.iItem,
183                              (LPARAM) &lvItem);
184             }
185             break;
186 
187             case LVSTARTUP:
188             {
189                 LPQUERY_SERVICE_CONFIGW lpServiceConfig;
190                 LPWSTR lpStartup = NULL;
191                 DWORD StringId = 0;
192 
193                 lpServiceConfig = GetServiceConfig(pService->lpServiceName);
194 
195                 if (lpServiceConfig)
196                 {
197                     switch (lpServiceConfig->dwStartType)
198                     {
199                         case 2: StringId = IDS_SERVICES_AUTO; break;
200                         case 3: StringId = IDS_SERVICES_MAN; break;
201                         case 4: StringId = IDS_SERVICES_DIS; break;
202                     }
203                 }
204 
205                 if (StringId)
206                     AllocAndLoadString(&lpStartup,
207                                        hInstance,
208                                        StringId);
209 
210                 lvItem.pszText = lpStartup;
211                 SendMessageW(Info->hListView,
212                              LVM_SETITEMTEXTW,
213                              lvItem.iItem,
214                              (LPARAM)&lvItem);
215 
216                 LocalFree(lpStartup);
217                 HeapFree(ProcessHeap,
218                          0,
219                          lpServiceConfig);
220             }
221             break;
222 
223             case LVLOGONAS:
224             {
225                 LPQUERY_SERVICE_CONFIG lpServiceConfig;
226 
227                 lpServiceConfig = GetServiceConfig(pService->lpServiceName);
228                 if (lpServiceConfig)
229                 {
230                     lvItem.pszText = lpServiceConfig->lpServiceStartName;
231                     SendMessageW(Info->hListView,
232                                  LVM_SETITEMTEXT,
233                                  lvItem.iItem,
234                                  (LPARAM)&lvItem);
235 
236                     HeapFree(ProcessHeap,
237                              0,
238                              lpServiceConfig);
239                 }
240             }
241             break;
242         }
243     }
244 }
245 
246 BOOL
RefreshServiceList(PMAIN_WND_INFO Info)247 RefreshServiceList(PMAIN_WND_INFO Info)
248 {
249     ENUM_SERVICE_STATUS_PROCESS *pService;
250     LVITEMW lvItem;
251     DWORD Index;
252 
253     SendMessage (Info->hListView,
254                  WM_SETREDRAW,
255                  FALSE,
256                  0);
257 
258     (void)ListView_DeleteAllItems(Info->hListView);
259 
260     if (GetServiceList(Info))
261     {
262         for (Index = 0; Index < Info->NumServices; Index++)
263         {
264             INT i;
265 
266             pService = &Info->pAllServices[Index];
267 
268             /* set the display name */
269             ZeroMemory(&lvItem, sizeof(LVITEMW));
270             lvItem.mask = LVIF_TEXT | LVIF_PARAM;
271             lvItem.pszText = pService->lpDisplayName;
272 
273             /* Add the service pointer */
274             lvItem.lParam = (LPARAM)pService;
275 
276             /* add it to the listview */
277             lvItem.iItem = ListView_InsertItem(Info->hListView, &lvItem);
278 
279             /* fill out all the column data */
280             for (i = LVDESC; i <= LVLOGONAS; i++)
281             {
282                 ChangeListViewText(Info, pService, i);
283             }
284         }
285 
286         UpdateServiceCount(Info);
287     }
288 
289     /* turn redraw flag on. */
290     SendMessageW(Info->hListView,
291                  WM_SETREDRAW,
292                  TRUE,
293                  0);
294 
295     return TRUE;
296 }
297 
298 static VOID
InitListViewImage(PMAIN_WND_INFO Info)299 InitListViewImage(PMAIN_WND_INFO Info)
300 {
301     HICON hSmIconItem, hLgIconItem;
302     HIMAGELIST hSmall, hLarge;
303 
304     hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON),
305                               GetSystemMetrics(SM_CYSMICON),
306                               ILC_MASK | ILC_COLOR32,
307                               1,
308                               1);
309     if (hSmall)
310     {
311         hSmIconItem = LoadImageW(hInstance,
312                                  MAKEINTRESOURCE(IDI_SM_ICON),
313                                  IMAGE_ICON,
314                                  16,
315                                  16,
316                                  0);
317         if (hSmIconItem)
318         {
319             ImageList_AddIcon(hSmall,
320                               hSmIconItem);
321             (void)ListView_SetImageList(Info->hListView,
322                                         hSmall,
323                                         LVSIL_SMALL);
324 
325             DestroyIcon(hSmIconItem);
326         }
327     }
328 
329     hLarge = ImageList_Create(GetSystemMetrics(SM_CXICON),
330                               GetSystemMetrics(SM_CYICON),
331                               ILC_MASK | ILC_COLOR32,
332                               1,
333                               1);
334     if (hLarge)
335     {
336         hLgIconItem = LoadImageW(hInstance,
337                                  MAKEINTRESOURCE(IDI_SM_ICON),
338                                  IMAGE_ICON,
339                                  32,
340                                  32,
341                                  0);
342         if (hLgIconItem)
343         {
344             ImageList_AddIcon(hLarge,
345                               hLgIconItem);
346             (void)ListView_SetImageList(Info->hListView,
347                                         hLarge,
348                                         LVSIL_NORMAL);
349             DestroyIcon(hLgIconItem);
350         }
351     }
352 }
353 
354 BOOL
CreateListView(PMAIN_WND_INFO Info)355 CreateListView(PMAIN_WND_INFO Info)
356 {
357     LVCOLUMNW lvc = { 0 };
358     WCHAR szTemp[256];
359     HDITEM hdi;
360     int i, n;
361 
362     Info->hListView = CreateWindowExW(WS_EX_CLIENTEDGE,
363                                       WC_LISTVIEWW,
364                                       NULL,
365                                       WS_CHILD | WS_VISIBLE | LVS_REPORT | WS_BORDER |
366                                          LBS_NOTIFY | LVS_SORTASCENDING | LBS_NOREDRAW,
367                                       0, 0, 0, 0,
368                                       Info->hMainWnd,
369                                       (HMENU) IDC_SERVLIST,
370                                       hInstance,
371                                       NULL);
372     if (Info->hListView == NULL)
373     {
374         MessageBoxW(Info->hMainWnd,
375                     L"Could not create List View.",
376                     L"Error",
377                     MB_OK | MB_ICONERROR);
378         return FALSE;
379     }
380 
381     Info->hHeader = ListView_GetHeader(Info->hListView);
382 
383     (void)ListView_SetExtendedListViewStyle(Info->hListView,
384                                             LVS_EX_FULLROWSELECT | LVS_EX_HEADERDRAGDROP);/*LVS_EX_GRIDLINES |*/
385 
386     lvc.mask = LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH  | LVCF_FMT;
387     lvc.fmt  = LVCFMT_LEFT;
388     lvc.pszText = szTemp;
389 
390     /* Add columns to the list-view */
391     for (n = 0; n < sizeof(Columns) / sizeof(Columns[0]); n++)
392     {
393         lvc.iSubItem = Columns[n].iSubItem;
394         lvc.cx = Columns[n].cx;
395 
396         LoadStringW(hInstance,
397                     Columns[n].idsText,
398                     szTemp,
399                     sizeof(szTemp) / sizeof(szTemp[0]));
400 
401         i = ListView_InsertColumn(Info->hListView, Columns[n].iSubItem, &lvc);
402 
403         hdi.mask = HDI_LPARAM;
404         hdi.lParam = ORD_ASCENDING;
405         (void)Header_SetItem(Info->hHeader, i, &hdi);
406     }
407 
408     InitListViewImage(Info);
409 
410     /* check the details view menu item */
411     CheckMenuRadioItem(GetMenu(Info->hMainWnd),
412                        ID_VIEW_LARGE,
413                        ID_VIEW_DETAILS,
414                        ID_VIEW_DETAILS,
415                        MF_BYCOMMAND);
416 
417     return TRUE;
418 }
419