use GET_X/Y_LPARAM as per MSDN
[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 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 HMENU hShortcutMenu;
20
21
22 LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
23 {
24 switch(msg)
25 {
26 case WM_CREATE:
27 {
28 //HFONT hfDefault;
29
30 TBADDBITMAP tbab;
31 INT iImageOffset;
32 INT statwidths[] = {110, -1}; /* widths of status bar */
33 TCHAR szTemp[256];
34 LVCOLUMN lvc = { 0 };
35
36 /* Toolbar buttons */
37 TBBUTTON tbb [NUM_BUTTONS] =
38 { /* iBitmap, idCommand, fsState, fsStyle, bReserved[2], dwData, iString */
39 {TBICON_PROP, ID_PROP, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0}, /* properties */
40 {TBICON_REFRESH, ID_REFRESH, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0}, /* refresh */
41 {TBICON_EXPORT, ID_EXPORT, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0}, /* export */
42
43 /* Note: First item for a seperator is its width in pixels */
44 {25, 0, TBSTATE_ENABLED, BTNS_SEP, {0}, 0, 0}, /* separator */
45
46 {TBICON_START, ID_START, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0 }, /* start */
47 {TBICON_STOP, ID_STOP, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0 }, /* stop */
48 {TBICON_PAUSE, ID_PAUSE, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0 }, /* pause */
49 {TBICON_RESTART, ID_RESTART, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0 }, /* restart */
50
51 {25, 0, TBSTATE_ENABLED, BTNS_SEP, {0}, 0, 0}, /* separator */
52
53 {TBICON_NEW, ID_NEW, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0 }, /* start */
54 {TBICON_HELP, ID_HELP, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0 }, /* stop */
55 {TBICON_EXIT, ID_EXIT, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0 }, /* pause */
56
57 };
58
59 /* ======================== Create Toolbar ============================== */
60
61 /* Create Toolbar */
62 hTool = CreateWindowEx(0,
63 TOOLBARCLASSNAME,
64 NULL,
65 WS_CHILD | WS_VISIBLE | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS,
66 0, 0, 0, 0,
67 hwnd,
68 (HMENU)IDC_TOOLBAR,
69 hInstance,
70 NULL);
71 if(hTool == NULL)
72 MessageBox(hwnd, _T("Could not create tool bar."), _T("Error"), MB_OK | MB_ICONERROR);
73
74 /* Send the TB_BUTTONSTRUCTSIZE message, which is required for backward compatibility */
75 SendMessage(hTool, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
76
77 /* Add standard image list */
78 tbab.hInst = HINST_COMMCTRL;
79 tbab.nID = IDB_STD_SMALL_COLOR;
80 SendMessage(hTool, TB_ADDBITMAP, 0, (LPARAM) &tbab);
81
82 /* Add custom images */
83 tbab.hInst = hInstance;
84 tbab.nID = IDB_BUTTONS;
85 iImageOffset = (INT)SendMessage(hTool, TB_ADDBITMAP, 11, (LPARAM)&tbab);
86 tbb[0].iBitmap += iImageOffset; /* properties */
87 tbb[1].iBitmap += iImageOffset; /* refresh */
88 tbb[2].iBitmap += iImageOffset; /* export */
89 tbb[4].iBitmap += iImageOffset; /* start */
90 tbb[5].iBitmap += iImageOffset; /* stop */
91 tbb[6].iBitmap += iImageOffset; /* pause */
92 tbb[7].iBitmap += iImageOffset; /* restart */
93 tbb[9].iBitmap += iImageOffset; /* new */
94 tbb[10].iBitmap += iImageOffset; /* help */
95 tbb[11].iBitmap += iImageOffset; /* exit */
96
97 /* Add buttons to toolbar */
98 SendMessage(hTool, TB_ADDBUTTONS, NUM_BUTTONS, (LPARAM) &tbb);
99
100 /* Show toolbar */
101 ShowWindow(hTool, SW_SHOWNORMAL);
102
103
104
105 /* ======================== Create List View ============================== */
106
107 hListView = CreateWindow(WC_LISTVIEW,
108 NULL,
109 WS_CHILD | WS_VISIBLE | LVS_REPORT | WS_BORDER |
110 LVS_EDITLABELS | LVS_SORTASCENDING,
111 0, 0, 0, 0, /* sized via WM_SIZE */
112 hwnd,
113 (HMENU) IDC_SERVLIST,
114 hInstance,
115 NULL);
116 if (hListView == NULL)
117 MessageBox(hwnd, _T("Could not create List View."), _T("Error"), MB_OK | MB_ICONERROR);
118
119 ListView_SetExtendedListViewStyle(hListView, LVS_EX_FULLROWSELECT |
120 LVS_EX_GRIDLINES | LVS_EX_HEADERDRAGDROP);
121
122 lvc.mask = LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH | LVCF_FMT;
123 lvc.fmt = LVCFMT_LEFT;
124
125 /* Add columns to the list-view */
126
127 /* name */
128 lvc.iSubItem = 0;
129 lvc.cx = 160;
130 LoadString(hInstance, IDS_FIRSTCOLUMN, szTemp, 256);
131 lvc.pszText = szTemp;
132 ListView_InsertColumn(hListView, 0, &lvc);
133
134 /* description */
135 lvc.iSubItem = 1;
136 lvc.cx = 260;
137 LoadString(hInstance, IDS_SECONDCOLUMN, szTemp, 256);
138 lvc.pszText = szTemp;
139 ListView_InsertColumn(hListView, 1, &lvc);
140
141 /* status */
142 lvc.iSubItem = 2;
143 lvc.cx = 75;
144 LoadString(hInstance, IDS_THIRDCOLUMN, szTemp, 256);
145 lvc.pszText = szTemp;
146 ListView_InsertColumn(hListView, 2, &lvc);
147
148 /* startup type */
149 lvc.iSubItem = 3;
150 lvc.cx = 80;
151 LoadString(hInstance, IDS_FOURTHCOLUMN, szTemp, 256);
152 lvc.pszText = szTemp;
153 ListView_InsertColumn(hListView, 3, &lvc);
154
155 /* logon as */
156 lvc.iSubItem = 4;
157 lvc.cx = 100;
158 LoadString(hInstance, IDS_FITHCOLUMN, szTemp, 256);
159 lvc.pszText = szTemp;
160 ListView_InsertColumn(hListView, 4, &lvc);
161
162
163
164 /* ======================== Create Status Bar ============================== */
165
166 hStatus = CreateWindowEx(0,
167 STATUSCLASSNAME,
168 NULL,
169 WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP,
170 0, 0, 0, 0,
171 hwnd,
172 (HMENU)IDC_STATUSBAR,
173 hInstance,
174 NULL);
175 if(hStatus == NULL)
176 MessageBox(hwnd, _T("Could not create status bar."),
177 _T("Error!"), MB_OK | MB_ICONERROR);
178
179 SendMessage(hStatus, SB_SETPARTS, sizeof(statwidths)/sizeof(int), (LPARAM)statwidths);
180
181
182 /* ======================== Create Popup Menu ============================== */
183
184 hShortcutMenu = LoadMenu(hInstance, MAKEINTRESOURCE (IDR_POPUP));
185 hShortcutMenu = GetSubMenu(hShortcutMenu, 0);
186
187
188
189
190 /* ================= populate the list view with all services =================== */
191
192 RefreshServiceList();
193
194 }
195 break;
196
197 case WM_SIZE:
198 {
199 RECT rcTool;
200 int iToolHeight;
201
202 RECT rcStatus;
203 int iStatusHeight;
204
205 int lvHeight;
206 RECT rcClient;
207
208 /* Size toolbar and get height */
209 hTool = GetDlgItem(hwnd, IDC_TOOLBAR);
210 SendMessage(hTool, TB_AUTOSIZE, 0, 0);
211
212 GetWindowRect(hTool, &rcTool);
213 iToolHeight = rcTool.bottom - rcTool.top;
214
215 /* Size status bar and get height */
216 hStatus = GetDlgItem(hwnd, IDC_STATUSBAR);
217 SendMessage(hStatus, WM_SIZE, 0, 0);
218
219 GetWindowRect(hStatus, &rcStatus);
220 iStatusHeight = rcStatus.bottom - rcStatus.top;
221
222 /* Calculate remaining height and size list view */
223 GetClientRect(hwnd, &rcClient);
224
225 lvHeight = rcClient.bottom - iToolHeight - iStatusHeight;
226
227 hListView = GetDlgItem(hwnd, IDC_SERVLIST);
228 SetWindowPos(hListView, NULL, 0, iToolHeight, rcClient.right, lvHeight, SWP_NOZORDER);
229 }
230 break;
231
232 case WM_NOTIFY:
233 {
234 LPNMITEMACTIVATE item;
235
236
237 switch (((LPNMHDR) lParam)->code)
238 {
239 case NM_DBLCLK:
240 item = (LPNMITEMACTIVATE) lParam;
241 PropSheets(hwnd);
242 break;
243
244 case TTN_GETDISPINFO:
245 {
246 LPTOOLTIPTEXT lpttt;
247 UINT idButton;
248
249 lpttt = (LPTOOLTIPTEXT) lParam;
250 lpttt->hinst = hInstance;
251
252 // Specify the resource identifier of the descriptive
253 // text for the given button.
254 idButton = (UINT)lpttt->hdr.idFrom;
255 switch (idButton)
256 {
257 case ID_PROP:
258 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_PROP);
259 break;
260
261 case ID_REFRESH:
262 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_REFRESH);
263 break;
264
265 case ID_EXPORT:
266 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_EXPORT);
267 break;
268
269 case ID_START:
270 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_START);
271 break;
272
273 case ID_STOP:
274 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_STOP);
275 break;
276
277 case ID_PAUSE:
278 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_PAUSE);
279 break;
280
281 case ID_RESTART:
282 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_RESTART);
283 break;
284
285 case ID_NEW:
286 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_NEW);
287 break;
288
289 case ID_HELP:
290 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_HELP);
291 break;
292
293 case ID_EXIT:
294 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_EXIT);
295 break;
296
297 }
298 }
299 break;
300
301 default:
302 break;
303 }
304 }
305 break;
306
307 case WM_CLOSE:
308 FreeMemory(); /* free the service array */
309 DestroyMenu(hShortcutMenu);
310 DestroyWindow(hwnd);
311 break;
312
313 case WM_DESTROY:
314 PostQuitMessage(0);
315 break;
316
317 case WM_CONTEXTMENU:
318 {
319 int xPos, yPos;
320
321 xPos = GET_X_LPARAM(lParam);
322 yPos = GET_Y_LPARAM(lParam);
323
324 TrackPopupMenuEx(hShortcutMenu, TPM_RIGHTBUTTON, xPos, yPos, hwnd, NULL);
325 }
326 break;
327
328 case WM_COMMAND:
329 switch(LOWORD(wParam))
330 {
331 case ID_PROP:
332 PropSheets(hwnd);
333 break;
334
335 case ID_REFRESH:
336 if (! RefreshServiceList() )
337 GetError(0);
338
339 case ID_EXPORT:
340 break;
341
342 case ID_START:
343 break;
344
345 case ID_STOP:
346 break;
347
348 case ID_PAUSE:
349 break;
350
351 case ID_RESUME:
352 break;
353
354 case ID_RESTART:
355 break;
356
357 case ID_NEW:
358 break;
359
360 case ID_HELP:
361 MessageBox(NULL, _T("Help is not yet implemented\n"),
362 _T("Note!"), MB_OK | MB_ICONINFORMATION);
363 break;
364
365 case ID_EXIT:
366 PostMessage(hwnd, WM_CLOSE, 0, 0);
367 break;
368
369 case ID_VIEW_CUSTOMIZE:
370 break;
371
372 case ID_ABOUT:
373 DialogBox(hInstance,
374 MAKEINTRESOURCE(IDD_ABOUTBOX),
375 hwnd,
376 AboutDialogProc);
377 break;
378
379 }
380 break;
381
382 default:
383 return DefWindowProc(hwnd, msg, wParam, lParam);
384 }
385 return 0;
386 }
387
388 #ifdef _MSC_VER
389 #pragma warning(disable : 4100)
390 #endif
391 int WINAPI WinMain(HINSTANCE hThisInstance, HINSTANCE hPrevInstance,
392 LPSTR lpCmdLine, int nCmdShow)
393 {
394 WNDCLASSEX wc;
395 MSG Msg;
396 BOOL bRet;
397
398 hInstance = hThisInstance;
399
400 InitCommonControls();
401
402 wc.cbSize = sizeof(WNDCLASSEX);
403 wc.style = 0;
404 wc.lpfnWndProc = WndProc;
405 wc.cbClsExtra = 0;
406 wc.cbWndExtra = 0;
407 wc.hInstance = hInstance;
408 wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SM_ICON));
409 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
410 wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
411 wc.lpszMenuName = MAKEINTRESOURCE(IDR_MAINMENU);
412 wc.lpszClassName = ClassName;
413 wc.hIconSm = (HICON)LoadImage(hInstance,
414 MAKEINTRESOURCE(IDI_SM_ICON), IMAGE_ICON, 16, 16, 0);
415
416 if(!RegisterClassEx(&wc))
417 {
418 MessageBox(NULL, _T("Window Registration Failed!"), _T("Error!"),
419 MB_ICONEXCLAMATION | MB_OK);
420 return 0;
421 }
422
423 hMainWnd = CreateWindowEx(
424 0,
425 ClassName,
426 _T("ReactOS Service Manager"),
427 WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
428 CW_USEDEFAULT, CW_USEDEFAULT, 700, 500,
429 NULL, NULL, hInstance, NULL);
430
431 if(hMainWnd == NULL)
432 {
433 MessageBox(NULL, _T("Window Creation Failed!"), _T("Error!"),
434 MB_ICONEXCLAMATION | MB_OK);
435 return 0;
436 }
437
438 ShowWindow(hMainWnd, nCmdShow);
439 UpdateWindow(hMainWnd);
440
441 while( (bRet = GetMessage( &Msg, NULL, 0, 0 )) != 0)
442 {
443 if (bRet == -1)
444 {
445 /* handle the error and possibly exit */
446 }
447 else
448 {
449 TranslateMessage(&Msg);
450 DispatchMessage(&Msg);
451 }
452 }
453 return (int)Msg.wParam;
454 }
455
456