f186361c93fa8a64f8d6729e6f40ff7f066ffe2a
[reactos.git] / reactos / subsys / system / servman / servman.c
1 /*
2 * PROJECT: ReactOS Services
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: subsys/system/servman/servman.c
5 * PURPOSE: Main window message handler
6 * COPYRIGHT: Copyright 2005 - 2006 Ged Murphy <gedmurphy@gmail.com>
7 *
8 */
9
10 #include "servman.h"
11
12 const TCHAR ClassName[] = _T("ServiceManager");
13
14 HINSTANCE hInstance;
15 HWND hMainWnd;
16 HWND hListView;
17 HWND hStatus;
18 HWND hTool;
19 HWND hProgDlg;
20 HMENU hShortcutMenu;
21 INT SelectedItem;
22
23
24 INT GetSelectedItem(VOID)
25 {
26 return SelectedItem;
27 }
28
29
30 LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
31 {
32 switch(msg)
33 {
34 case WM_CREATE:
35 {
36 TBADDBITMAP tbab;
37 INT iImageOffset;
38 INT statwidths[] = {110, -1}; /* widths of status bar */
39 TCHAR szTemp[256];
40 LVCOLUMN lvc = { 0 };
41
42 /* Toolbar buttons */
43 TBBUTTON tbb [NUM_BUTTONS] =
44 { /* iBitmap, idCommand, fsState, fsStyle, bReserved[2], dwData, iString */
45 {TBICON_PROP, ID_PROP, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0}, /* properties */
46 {TBICON_REFRESH, ID_REFRESH, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0}, /* refresh */
47 {TBICON_EXPORT, ID_EXPORT, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0}, /* export */
48
49 /* Note: First item for a seperator is its width in pixels */
50 {15, 0, TBSTATE_ENABLED, BTNS_SEP, {0}, 0, 0}, /* separator */
51
52 {TBICON_NEW, ID_NEW, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0 }, /* create */
53
54 {15, 0, TBSTATE_ENABLED, BTNS_SEP, {0}, 0, 0}, /* separator */
55
56 {TBICON_START, ID_START, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0 }, /* start */
57 {TBICON_STOP, ID_STOP, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0 }, /* stop */
58 {TBICON_PAUSE, ID_PAUSE, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0 }, /* pause */
59 {TBICON_RESTART, ID_RESTART, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0 }, /* restart */
60
61 {15, 0, TBSTATE_ENABLED, BTNS_SEP, {0}, 0, 0}, /* separator */
62
63 {TBICON_HELP, ID_HELP, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0 }, /* help */
64 {TBICON_EXIT, ID_EXIT, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0 }, /* exit */
65
66 };
67
68 /* ======================== Create Toolbar ============================== */
69
70 /* Create Toolbar */
71 hTool = CreateWindowEx(0,
72 TOOLBARCLASSNAME,
73 NULL,
74 WS_CHILD | WS_VISIBLE | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS,
75 0, 0, 0, 0,
76 hwnd,
77 (HMENU)IDC_TOOLBAR,
78 hInstance,
79 NULL);
80 if(hTool == NULL)
81 MessageBox(hwnd, _T("Could not create tool bar."), _T("Error"), MB_OK | MB_ICONERROR);
82
83 /* Send the TB_BUTTONSTRUCTSIZE message, which is required for backward compatibility */
84 SendMessage(hTool, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
85
86 /* Add custom images */
87 tbab.hInst = hInstance;
88 tbab.nID = IDB_BUTTONS;
89 iImageOffset = (INT)SendMessage(hTool, TB_ADDBITMAP, NUM_BUTTONS, (LPARAM)&tbab);
90 tbb[0].iBitmap += iImageOffset; /* properties */
91 tbb[1].iBitmap += iImageOffset; /* refresh */
92 tbb[2].iBitmap += iImageOffset; /* export */
93 tbb[4].iBitmap += iImageOffset; /* new */
94 tbb[6].iBitmap += iImageOffset; /* start */
95 tbb[7].iBitmap += iImageOffset; /* stop */
96 tbb[8].iBitmap += iImageOffset; /* pause */
97 tbb[9].iBitmap += iImageOffset; /* restart */
98 tbb[11].iBitmap += iImageOffset; /* help */
99 tbb[12].iBitmap += iImageOffset; /* exit */
100
101 /* Add buttons to toolbar */
102 SendMessage(hTool, TB_ADDBUTTONS, NUM_BUTTONS, (LPARAM) &tbb);
103
104 /* Show toolbar */
105 ShowWindow(hTool, SW_SHOWNORMAL);
106
107
108
109 /* ======================== Create List View ============================== */
110
111 hListView = CreateWindowEx(0,
112 WC_LISTVIEW,
113 NULL,
114 WS_CHILD | WS_VISIBLE | LVS_REPORT | WS_BORDER |
115 LBS_NOTIFY | LVS_SORTASCENDING | LBS_NOREDRAW,
116 0, 0, 0, 0, /* sized via WM_SIZE */
117 hwnd,
118 (HMENU) IDC_SERVLIST,
119 hInstance,
120 NULL);
121 if (hListView == NULL)
122 MessageBox(hwnd, _T("Could not create List View."), _T("Error"), MB_OK | MB_ICONERROR);
123
124 ListView_SetExtendedListViewStyle(hListView, LVS_EX_FULLROWSELECT |
125 LVS_EX_GRIDLINES | LVS_EX_HEADERDRAGDROP);
126
127 lvc.mask = LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH | LVCF_FMT;
128 lvc.fmt = LVCFMT_LEFT;
129
130 /* Add columns to the list-view */
131
132 /* name */
133 lvc.iSubItem = 0;
134 lvc.cx = 150;
135 LoadString(hInstance, IDS_FIRSTCOLUMN, szTemp, 256);
136 lvc.pszText = szTemp;
137 ListView_InsertColumn(hListView, 0, &lvc);
138
139 /* description */
140 lvc.iSubItem = 1;
141 lvc.cx = 240;
142 LoadString(hInstance, IDS_SECONDCOLUMN, szTemp, 256);
143 lvc.pszText = szTemp;
144 ListView_InsertColumn(hListView, 1, &lvc);
145
146 /* status */
147 lvc.iSubItem = 2;
148 lvc.cx = 55;
149 LoadString(hInstance, IDS_THIRDCOLUMN, szTemp, 256);
150 lvc.pszText = szTemp;
151 ListView_InsertColumn(hListView, 2, &lvc);
152
153 /* startup type */
154 lvc.iSubItem = 3;
155 lvc.cx = 80;
156 LoadString(hInstance, IDS_FOURTHCOLUMN, szTemp, 256);
157 lvc.pszText = szTemp;
158 ListView_InsertColumn(hListView, 3, &lvc);
159
160 /* logon as */
161 lvc.iSubItem = 4;
162 lvc.cx = 100;
163 LoadString(hInstance, IDS_FITHCOLUMN, szTemp, 256);
164 lvc.pszText = szTemp;
165 ListView_InsertColumn(hListView, 4, &lvc);
166
167
168
169 /* ======================== Create Status Bar ============================== */
170
171 hStatus = CreateWindowEx(0,
172 STATUSCLASSNAME,
173 NULL,
174 WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP,
175 0, 0, 0, 0,
176 hwnd,
177 (HMENU)IDC_STATUSBAR,
178 hInstance,
179 NULL);
180 if(hStatus == NULL)
181 MessageBox(hwnd, _T("Could not create status bar."),
182 _T("Error!"), MB_OK | MB_ICONERROR);
183
184 SendMessage(hStatus, SB_SETPARTS, sizeof(statwidths)/sizeof(int), (LPARAM)statwidths);
185
186
187 /* ======================== Create Popup Menu ============================== */
188
189 hShortcutMenu = LoadMenu(hInstance, MAKEINTRESOURCE (IDR_POPUP));
190 hShortcutMenu = GetSubMenu(hShortcutMenu, 0);
191
192
193
194
195 /* ================= populate the list view with all services =================== */
196
197 RefreshServiceList();
198
199 }
200 break;
201
202 case WM_SIZE:
203 {
204 RECT rcTool;
205 int iToolHeight;
206
207 RECT rcStatus;
208 int iStatusHeight;
209
210 int lvHeight;
211 RECT rcClient;
212
213 /* Size toolbar and get height */
214 hTool = GetDlgItem(hwnd, IDC_TOOLBAR);
215 SendMessage(hTool, TB_AUTOSIZE, 0, 0);
216
217 GetWindowRect(hTool, &rcTool);
218 iToolHeight = rcTool.bottom - rcTool.top;
219
220 /* Size status bar and get height */
221 hStatus = GetDlgItem(hwnd, IDC_STATUSBAR);
222 SendMessage(hStatus, WM_SIZE, 0, 0);
223
224 GetWindowRect(hStatus, &rcStatus);
225 iStatusHeight = rcStatus.bottom - rcStatus.top;
226
227 /* Calculate remaining height and size list view */
228 GetClientRect(hwnd, &rcClient);
229
230 lvHeight = rcClient.bottom - iToolHeight - iStatusHeight;
231
232 hListView = GetDlgItem(hwnd, IDC_SERVLIST);
233 SetWindowPos(hListView, NULL, 0, iToolHeight, rcClient.right, lvHeight, SWP_NOZORDER);
234 }
235 break;
236
237 case WM_NOTIFY:
238 {
239 NMHDR* nm = (NMHDR*) lParam;
240
241 switch (nm->code)
242 {
243 case NM_DBLCLK:
244 OpenPropSheet(hwnd);
245 break;
246
247 case LVN_ITEMCHANGED:
248 {
249 LPNMLISTVIEW pnmv = (LPNMLISTVIEW) lParam;
250
251 SelectedItem = pnmv->iItem;
252
253 }
254 break;
255
256 case TTN_GETDISPINFO:
257 {
258 LPTOOLTIPTEXT lpttt;
259 UINT idButton;
260
261 lpttt = (LPTOOLTIPTEXT) lParam;
262
263 /* Specify the resource identifier of the descriptive
264 * text for the given button. */
265 idButton = (UINT)lpttt->hdr.idFrom;
266 switch (idButton)
267 {
268 case ID_PROP:
269 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_PROP);
270 break;
271
272 case ID_REFRESH:
273 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_REFRESH);
274 break;
275
276 case ID_EXPORT:
277 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_EXPORT);
278 break;
279
280 case ID_START:
281 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_START);
282 break;
283
284 case ID_STOP:
285 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_STOP);
286 break;
287
288 case ID_PAUSE:
289 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_PAUSE);
290 break;
291
292 case ID_RESTART:
293 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_RESTART);
294 break;
295
296 case ID_NEW:
297 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_NEW);
298 break;
299
300 case ID_HELP:
301 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_HELP);
302 break;
303
304 case ID_EXIT:
305 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_EXIT);
306 break;
307
308 }
309 }
310 break;
311
312 default:
313 break;
314 }
315 }
316 break;
317
318 case WM_CONTEXTMENU:
319 {
320 int xPos, yPos;
321
322 xPos = GET_X_LPARAM(lParam);
323 yPos = GET_Y_LPARAM(lParam);
324
325 TrackPopupMenuEx(hShortcutMenu, TPM_RIGHTBUTTON,
326 xPos, yPos, hwnd, NULL);
327 }
328 break;
329
330 case WM_COMMAND:
331
332 switch(LOWORD(wParam))
333 {
334 case ID_PROP:
335 OpenPropSheet(hwnd);
336
337 break;
338
339 case ID_REFRESH:
340 RefreshServiceList();
341 break;
342
343 case ID_EXPORT:
344 break;
345
346 case ID_START:
347 {
348 ENUM_SERVICE_STATUS_PROCESS *Service = NULL;
349 TCHAR buf1[100];
350 TCHAR buf2[100];
351 /* open the progress dialog */
352 hProgDlg = CreateDialog(GetModuleHandle(NULL),
353 MAKEINTRESOURCE(IDD_DLG_PROGRESS),
354 hMainWnd,
355 (DLGPROC)ProgressDialogProc);
356 if (hProgDlg != NULL)
357 {
358 ShowWindow(hProgDlg, SW_SHOW);
359
360 /* write the info to the progress dialog */
361 LoadString(hInstance, IDS_PROGRESS_INFO, buf1,
362 sizeof(buf1) / sizeof(TCHAR));
363 _sntprintf(buf2, 100, buf1, _T("start"));
364 SendDlgItemMessage(hProgDlg, IDC_SERVCON_INFO, WM_SETTEXT, 0, (LPARAM)buf2);
365
366 /* get pointer to selected service */
367 Service = GetSelectedService();
368
369 /* write the service name to the progress dialog */
370 SendDlgItemMessage(hProgDlg, IDC_SERVCON_NAME, WM_SETTEXT, 0,
371 (LPARAM)Service->lpServiceName);
372 }
373
374 if ( DoStartService(hProgDlg) )
375 {
376 LVITEM item;
377 TCHAR szStatus[64];
378
379 LoadString(hInstance, IDS_SERVICES_STARTED, szStatus,
380 sizeof(szStatus) / sizeof(TCHAR));
381 item.pszText = szStatus;
382 item.iItem = GetSelectedItem();
383 item.iSubItem = 2;
384 SendMessage(hListView, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item);
385 }
386
387 SendMessage(hProgDlg, WM_DESTROY, 0, 0);
388 }
389 break;
390
391 case ID_STOP:
392 {
393 ENUM_SERVICE_STATUS_PROCESS *Service = NULL;
394 TCHAR buf1[100];
395 TCHAR buf2[100];
396 /* open the progress dialog */
397 hProgDlg = CreateDialog(GetModuleHandle(NULL),
398 MAKEINTRESOURCE(IDD_DLG_PROGRESS),
399 hMainWnd,
400 (DLGPROC)ProgressDialogProc);
401 if (hProgDlg != NULL)
402 {
403 ShowWindow(hProgDlg, SW_SHOW);
404
405 /* write the info to the progress dialog */
406 LoadString(hInstance, IDS_PROGRESS_INFO, buf1,
407 sizeof(buf1) / sizeof(TCHAR));
408 _sntprintf(buf2, 100, buf1, _T("stop"));
409 SendDlgItemMessage(hProgDlg, IDC_SERVCON_INFO, WM_SETTEXT, 0, (LPARAM)buf2);
410
411 /* get pointer to selected service */
412 Service = GetSelectedService();
413
414 /* write the service name to the progress dialog */
415 SendDlgItemMessage(hProgDlg, IDC_SERVCON_NAME, WM_SETTEXT, 0,
416 (LPARAM)Service->lpServiceName);
417 }
418
419 if( Control(hProgDlg, SERVICE_CONTROL_STOP) )
420 {
421 LVITEM item;
422
423 item.pszText = '\0';
424 item.iItem = GetSelectedItem();
425 item.iSubItem = 2;
426 SendMessage(hListView, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item);
427 }
428
429 SendMessage(hProgDlg, WM_DESTROY, 0, 0);
430 }
431 break;
432
433 case ID_PAUSE:
434 Control(hProgDlg, SERVICE_CONTROL_PAUSE);
435 break;
436
437 case ID_RESUME:
438 Control(hProgDlg, SERVICE_CONTROL_CONTINUE );
439 break;
440
441 case ID_RESTART:
442 SendMessage(hMainWnd, WM_COMMAND, 0, ID_STOP);
443 SendMessage(hMainWnd, WM_COMMAND, 0, ID_START);
444 break;
445
446 case ID_NEW:
447 break;
448
449 case ID_HELP:
450 MessageBox(NULL, _T("Help is not yet implemented\n"),
451 _T("Note!"), MB_OK | MB_ICONINFORMATION);
452 break;
453
454 case ID_EXIT:
455 PostMessage(hwnd, WM_CLOSE, 0, 0);
456 break;
457
458 case ID_VIEW_CUSTOMIZE:
459 break;
460
461 case ID_ABOUT:
462 DialogBox(hInstance,
463 MAKEINTRESOURCE(IDD_ABOUTBOX),
464 hMainWnd,
465 (DLGPROC)AboutDialogProc);
466 break;
467
468 }
469 break;
470
471 case WM_CLOSE:
472 FreeMemory(); /* free the service array */
473 DestroyMenu(hShortcutMenu);
474 DestroyWindow(hwnd);
475 break;
476
477 case WM_DESTROY:
478 PostQuitMessage(0);
479 break;
480
481 default:
482 return DefWindowProc(hwnd, msg, wParam, lParam);
483 }
484 return 0;
485 }
486
487 #ifdef _MSC_VER
488 #pragma warning(disable : 4100)
489 #endif
490 int WINAPI WinMain(HINSTANCE hThisInstance, HINSTANCE hPrevInstance,
491 LPSTR lpCmdLine, int nCmdShow)
492 {
493 WNDCLASSEX wc;
494 MSG Msg;
495
496 hInstance = hThisInstance;
497
498 InitCommonControls();
499
500 wc.cbSize = sizeof(WNDCLASSEX);
501 wc.style = 0;
502 wc.lpfnWndProc = WndProc;
503 wc.cbClsExtra = 0;
504 wc.cbWndExtra = 0;
505 wc.hInstance = hInstance;
506 wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SM_ICON));
507 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
508 wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
509 wc.lpszMenuName = MAKEINTRESOURCE(IDR_MAINMENU);
510 wc.lpszClassName = ClassName;
511 wc.hIconSm = (HICON)LoadImage(hInstance,
512 MAKEINTRESOURCE(IDI_SM_ICON), IMAGE_ICON, 16, 16, 0);
513
514 if(!RegisterClassEx(&wc))
515 {
516 MessageBox(NULL, _T("Window Registration Failed!"), _T("Error!"),
517 MB_ICONEXCLAMATION | MB_OK);
518 return 0;
519 }
520
521 hMainWnd = CreateWindowEx(
522 0,
523 ClassName,
524 _T("ReactOS Service Manager"),
525 WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
526 CW_USEDEFAULT, CW_USEDEFAULT, 650, 450,
527 NULL, NULL, hInstance, NULL);
528
529 if(hMainWnd == NULL)
530 {
531 MessageBox(NULL, _T("Window Creation Failed!"), _T("Error!"),
532 MB_ICONEXCLAMATION | MB_OK);
533 return 0;
534 }
535
536 ShowWindow(hMainWnd, nCmdShow);
537 UpdateWindow(hMainWnd);
538
539 while( GetMessage( &Msg, NULL, 0, 0 ) )
540 {
541 if(! IsDialogMessage(hProgDlg, &Msg) )
542 {
543 TranslateMessage(&Msg);
544 DispatchMessage(&Msg);
545 }
546
547 }
548 return (int)Msg.wParam;
549 }
550
551
552