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