set most of trunk svn property eol-style:native
[reactos.git] / reactos / base / applications / servman / mainwnd.c
1 /*
2 * PROJECT: ReactOS Services
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/system/servman/mainwnd.c
5 * PURPOSE: Main window message handler
6 * COPYRIGHT: Copyright 2005 - 2006 Ged Murphy <gedmurphy@gmail.com>
7 *
8 */
9
10 #include "precomp.h"
11
12 static const TCHAR szMainWndClass[] = TEXT("ServManWndClass");
13
14 BOOL bSortAscending = TRUE;
15
16
17 /* Toolbar buttons */
18 TBBUTTON Buttons [NUM_BUTTONS] =
19 { /* iBitmap, idCommand, fsState, fsStyle, bReserved[2], dwData, iString */
20 {TBICON_PROP, ID_PROP, TBSTATE_INDETERMINATE, BTNS_BUTTON, {0}, 0, 0}, /* properties */
21 {TBICON_REFRESH, ID_REFRESH, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0}, /* refresh */
22 {TBICON_EXPORT, ID_EXPORT, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0}, /* export */
23
24 /* Note: First item for a seperator is its width in pixels */
25 {15, 0, TBSTATE_ENABLED, BTNS_SEP, {0}, 0, 0}, /* separator */
26
27 {TBICON_CREATE, ID_CREATE, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0 }, /* create */
28 {TBICON_DELETE, ID_DELETE, TBSTATE_INDETERMINATE, BTNS_BUTTON, {0}, 0, 0 }, /* delete */
29
30 {15, 0, TBSTATE_ENABLED, BTNS_SEP, {0}, 0, 0}, /* separator */
31
32 {TBICON_START, ID_START, TBSTATE_INDETERMINATE, BTNS_BUTTON, {0}, 0, 0 }, /* start */
33 {TBICON_STOP, ID_STOP, TBSTATE_INDETERMINATE, BTNS_BUTTON, {0}, 0, 0 }, /* stop */
34 {TBICON_PAUSE, ID_PAUSE, TBSTATE_INDETERMINATE, BTNS_BUTTON, {0}, 0, 0 }, /* pause */
35 {TBICON_RESTART, ID_RESTART, TBSTATE_INDETERMINATE, BTNS_BUTTON, {0}, 0, 0 }, /* restart */
36
37 {15, 0, TBSTATE_ENABLED, BTNS_SEP, {0}, 0, 0}, /* separator */
38
39 {TBICON_HELP, ID_HELP, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0 }, /* help */
40 {TBICON_EXIT, ID_EXIT, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0 }, /* exit */
41
42 };
43
44
45 /* menu hints */
46 static const MENU_HINT MainMenuHintTable[] = {
47 /* File Menu */
48 {ID_EXPORT, IDS_HINT_EXPORT},
49 {ID_EXIT, IDS_HINT_EXIT},
50
51 /* Action Menu */
52 {ID_CONNECT, IDS_HINT_CONNECT},
53 {ID_START, IDS_HINT_START},
54 {ID_STOP, IDS_HINT_STOP},
55 {ID_PAUSE, IDS_HINT_PAUSE},
56 {ID_RESUME, IDS_HINT_RESUME},
57 {ID_RESTART, IDS_HINT_RESTART},
58 {ID_REFRESH, IDS_HINT_REFRESH},
59 {ID_EDIT, IDS_HINT_EDIT},
60 {ID_CREATE, IDS_HINT_CREATE},
61 {ID_DELETE, IDS_HINT_DELETE},
62 {ID_PROP, IDS_HINT_PROP},
63
64 /* View menu */
65 {ID_VIEW_LARGE, IDS_HINT_LARGE},
66 {ID_VIEW_SMALL, IDS_HINT_SMALL},
67 {ID_VIEW_LIST, IDS_HINT_LIST},
68 {ID_VIEW_DETAILS, IDS_HINT_DETAILS},
69 {ID_VIEW_CUST, IDS_HINT_CUST},
70
71 /* Help Menu */
72 {ID_HELP, IDS_HINT_HELP},
73 {ID_ABOUT, IDS_HINT_ABOUT}
74 };
75 /* system menu hints */
76 static const MENU_HINT SystemMenuHintTable[] = {
77 {SC_RESTORE, IDS_HINT_SYS_RESTORE},
78 {SC_MOVE, IDS_HINT_SYS_MOVE},
79 {SC_SIZE, IDS_HINT_SYS_SIZE},
80 {SC_MINIMIZE, IDS_HINT_SYS_MINIMIZE},
81 {SC_MAXIMIZE, IDS_HINT_SYS_MAXIMIZE},
82 {SC_CLOSE, IDS_HINT_SYS_CLOSE},
83 };
84
85
86 static BOOL
87 MainWndMenuHint(PMAIN_WND_INFO Info,
88 WORD CmdId,
89 const MENU_HINT *HintArray,
90 DWORD HintsCount,
91 UINT DefHintId)
92 {
93 BOOL Found = FALSE;
94 const MENU_HINT *LastHint;
95 UINT HintId = DefHintId;
96
97 LastHint = HintArray + HintsCount;
98 while (HintArray != LastHint)
99 {
100 if (HintArray->CmdId == CmdId)
101 {
102 HintId = HintArray->HintId;
103 Found = TRUE;
104 break;
105 }
106 HintArray++;
107 }
108
109 StatusBarLoadString(Info->hStatus,
110 SB_SIMPLEID,
111 hInstance,
112 HintId);
113
114 return Found;
115 }
116
117
118 static VOID
119 UpdateMainStatusBar(PMAIN_WND_INFO Info)
120 {
121 if (Info->hStatus != NULL)
122 {
123 SendMessage(Info->hStatus,
124 SB_SIMPLE,
125 (WPARAM)Info->InMenuLoop,
126 0);
127 }
128 }
129
130
131 static VOID
132 SetListViewStyle(HWND hListView,
133 DWORD View)
134 {
135 DWORD Style = GetWindowLong(hListView, GWL_STYLE);
136
137 if ((Style & LVS_TYPEMASK) != View)
138 {
139 SetWindowLong(hListView,
140 GWL_STYLE,
141 (Style & ~LVS_TYPEMASK) | View);
142 }
143 }
144
145
146 VOID SetMenuAndButtonStates(PMAIN_WND_INFO Info)
147 {
148 HMENU hMainMenu;
149 DWORD Flags, State;
150
151 /* get handle to menu */
152 hMainMenu = GetMenu(Info->hMainWnd);
153
154 /* set all to greyed */
155 EnableMenuItem(hMainMenu, ID_START, MF_GRAYED);
156 EnableMenuItem(hMainMenu, ID_STOP, MF_GRAYED);
157 EnableMenuItem(hMainMenu, ID_PAUSE, MF_GRAYED);
158 EnableMenuItem(hMainMenu, ID_RESUME, MF_GRAYED);
159 EnableMenuItem(hMainMenu, ID_RESTART, MF_GRAYED);
160
161 EnableMenuItem(Info->hShortcutMenu, ID_START, MF_GRAYED);
162 EnableMenuItem(Info->hShortcutMenu, ID_STOP, MF_GRAYED);
163 EnableMenuItem(Info->hShortcutMenu, ID_PAUSE, MF_GRAYED);
164 EnableMenuItem(Info->hShortcutMenu, ID_RESUME, MF_GRAYED);
165 EnableMenuItem(Info->hShortcutMenu, ID_RESTART, MF_GRAYED);
166
167 SendMessage(Info->hTool, TB_SETSTATE, ID_START,
168 (LPARAM)MAKELONG(TBSTATE_INDETERMINATE, 0));
169 SendMessage(Info->hTool, TB_SETSTATE, ID_STOP,
170 (LPARAM)MAKELONG(TBSTATE_INDETERMINATE, 0));
171 SendMessage(Info->hTool, TB_SETSTATE, ID_PAUSE,
172 (LPARAM)MAKELONG(TBSTATE_INDETERMINATE, 0));
173 SendMessage(Info->hTool, TB_SETSTATE, ID_RESTART,
174 (LPARAM)MAKELONG(TBSTATE_INDETERMINATE, 0));
175
176 if (Info->SelectedItem != NO_ITEM_SELECTED)
177 {
178 /* allow user to delete service */
179 SendMessage(Info->hTool, TB_SETSTATE, ID_DELETE,
180 (LPARAM)MAKELONG(TBSTATE_ENABLED, 0));
181 EnableMenuItem(hMainMenu, ID_DELETE, MF_ENABLED);
182 EnableMenuItem(Info->hShortcutMenu, ID_DELETE, MF_ENABLED);
183
184 Flags = Info->CurrentService->ServiceStatusProcess.dwControlsAccepted;
185 State = Info->CurrentService->ServiceStatusProcess.dwCurrentState;
186
187 if (State == SERVICE_STOPPED)
188 {
189 EnableMenuItem(hMainMenu, ID_START, MF_ENABLED);
190 EnableMenuItem(Info->hShortcutMenu, ID_START, MF_ENABLED);
191 SendMessage(Info->hTool, TB_SETSTATE, ID_START,
192 (LPARAM)MAKELONG(TBSTATE_ENABLED, 0));
193 }
194
195 if ( (Flags & SERVICE_ACCEPT_STOP) && (State == SERVICE_RUNNING) )
196 {
197 EnableMenuItem(hMainMenu, ID_STOP, MF_ENABLED);
198 EnableMenuItem(Info->hShortcutMenu, ID_STOP, MF_ENABLED);
199 SendMessage(Info->hTool, TB_SETSTATE, ID_STOP,
200 (LPARAM)MAKELONG(TBSTATE_ENABLED, 0));
201 }
202
203 if ( (Flags & SERVICE_ACCEPT_PAUSE_CONTINUE) && (State == SERVICE_RUNNING) )
204 {
205 EnableMenuItem(hMainMenu, ID_PAUSE, MF_ENABLED);
206 EnableMenuItem(Info->hShortcutMenu, ID_PAUSE, MF_ENABLED);
207 SendMessage(Info->hTool, TB_SETSTATE, ID_PAUSE,
208 (LPARAM)MAKELONG(TBSTATE_ENABLED, 0));
209 }
210
211 if ( (Flags & SERVICE_ACCEPT_STOP) && (State == SERVICE_RUNNING) )
212 {
213 EnableMenuItem(hMainMenu, ID_RESTART, MF_ENABLED);
214 EnableMenuItem(Info->hShortcutMenu, ID_RESTART, MF_ENABLED);
215 SendMessage(Info->hTool, TB_SETSTATE, ID_RESTART,
216 (LPARAM)MAKELONG(TBSTATE_ENABLED, 0));
217 }
218 }
219 else
220 {
221 /* disable tools which rely on a selected service */
222 EnableMenuItem(hMainMenu, ID_PROP, MF_GRAYED);
223 EnableMenuItem(hMainMenu, ID_DELETE, MF_GRAYED);
224 EnableMenuItem(Info->hShortcutMenu, ID_PROP, MF_GRAYED);
225 EnableMenuItem(Info->hShortcutMenu, ID_DELETE, MF_GRAYED);
226 SendMessage(Info->hTool, TB_SETSTATE, ID_PROP,
227 (LPARAM)MAKELONG(TBSTATE_INDETERMINATE, 0));
228 SendMessage(Info->hTool, TB_SETSTATE, ID_DELETE,
229 (LPARAM)MAKELONG(TBSTATE_INDETERMINATE, 0));
230 }
231
232 }
233
234
235 static INT CALLBACK
236 CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
237 {
238 ENUM_SERVICE_STATUS_PROCESS *Param1;
239 ENUM_SERVICE_STATUS_PROCESS *Param2;
240 // INT iSubItem = (LPARAM)lParamSort;
241
242 if (bSortAscending) {
243 Param1 = (ENUM_SERVICE_STATUS_PROCESS *)lParam1;
244 Param2 = (ENUM_SERVICE_STATUS_PROCESS *)lParam2;
245 }
246 else
247 {
248 Param1 = (ENUM_SERVICE_STATUS_PROCESS *)lParam2;
249 Param2 = (ENUM_SERVICE_STATUS_PROCESS *)lParam1;
250 }
251 return _tcsicmp(Param1->lpDisplayName, Param2->lpDisplayName);
252 }
253
254
255 static BOOL
256 CreateToolbar(PMAIN_WND_INFO Info)
257 {
258 INT NumButtons = sizeof(Buttons) / sizeof(Buttons[0]);
259
260 Info->hTool = CreateWindowEx(0,
261 TOOLBARCLASSNAME,
262 NULL,
263 WS_CHILD | WS_VISIBLE | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS,
264 0, 0, 0, 0,
265 Info->hMainWnd,
266 0,
267 hInstance,
268 NULL);
269 if(Info->hTool != NULL)
270 {
271 HIMAGELIST hImageList;
272
273 SendMessage(Info->hTool,
274 TB_SETEXTENDEDSTYLE,
275 0,
276 TBSTYLE_EX_HIDECLIPPEDBUTTONS);
277
278 SendMessage(Info->hTool,
279 TB_BUTTONSTRUCTSIZE,
280 sizeof(Buttons[0]),
281 0);
282
283 hImageList = InitImageList(IDB_PROP,
284 IDB_EXIT,
285 16,
286 16);
287 if (hImageList == NULL)
288 return FALSE;
289
290 ImageList_Destroy((HIMAGELIST)SendMessage(Info->hTool,
291 TB_SETIMAGELIST,
292 0,
293 (LPARAM)hImageList));
294
295 SendMessage(Info->hTool,
296 TB_ADDBUTTONS,
297 NumButtons,
298 (LPARAM)Buttons);
299
300 return TRUE;
301 }
302
303 return FALSE;
304 }
305
306
307 static BOOL
308 CreateListView(PMAIN_WND_INFO Info)
309 {
310 LVCOLUMN lvc = { 0 };
311 TCHAR szTemp[256];
312
313 Info->hListView = CreateWindowEx(0,
314 WC_LISTVIEW,
315 NULL,
316 WS_CHILD | WS_VISIBLE | LVS_REPORT | WS_BORDER |
317 LBS_NOTIFY | LVS_SORTASCENDING | LBS_NOREDRAW,
318 0, 0, 0, 0,
319 Info->hMainWnd,
320 (HMENU) IDC_SERVLIST,
321 hInstance,
322 NULL);
323 if (Info->hListView == NULL)
324 {
325 MessageBox(Info->hMainWnd,
326 _T("Could not create List View."),
327 _T("Error"),
328 MB_OK | MB_ICONERROR);
329 return FALSE;
330 }
331
332 (void)ListView_SetExtendedListViewStyle(Info->hListView,
333 LVS_EX_FULLROWSELECT | LVS_EX_HEADERDRAGDROP);/*LVS_EX_GRIDLINES |*/
334
335 lvc.mask = LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH | LVCF_FMT;
336 lvc.fmt = LVCFMT_LEFT;
337
338 /* Add columns to the list-view */
339
340 /* name */
341 lvc.iSubItem = 0;
342 lvc.cx = 150;
343 LoadString(hInstance,
344 IDS_FIRSTCOLUMN,
345 szTemp,
346 sizeof(szTemp) / sizeof(TCHAR));
347 lvc.pszText = szTemp;
348 (void)ListView_InsertColumn(Info->hListView,
349 0,
350 &lvc);
351
352 /* description */
353 lvc.iSubItem = 1;
354 lvc.cx = 240;
355 LoadString(hInstance,
356 IDS_SECONDCOLUMN,
357 szTemp,
358 sizeof(szTemp) / sizeof(TCHAR));
359 lvc.pszText = szTemp;
360 (void)ListView_InsertColumn(Info->hListView,
361 1,
362 &lvc);
363
364 /* status */
365 lvc.iSubItem = 2;
366 lvc.cx = 55;
367 LoadString(hInstance,
368 IDS_THIRDCOLUMN,
369 szTemp,
370 sizeof(szTemp) / sizeof(TCHAR));
371 lvc.pszText = szTemp;
372 (void)ListView_InsertColumn(Info->hListView,
373 2,
374 &lvc);
375
376 /* startup type */
377 lvc.iSubItem = 3;
378 lvc.cx = 80;
379 LoadString(hInstance,
380 IDS_FOURTHCOLUMN,
381 szTemp,
382 sizeof(szTemp) / sizeof(TCHAR));
383 lvc.pszText = szTemp;
384 (void)ListView_InsertColumn(Info->hListView,
385 3,
386 &lvc);
387
388 /* logon as */
389 lvc.iSubItem = 4;
390 lvc.cx = 100;
391 LoadString(hInstance,
392 IDS_FITHCOLUMN,
393 szTemp,
394 sizeof(szTemp) / sizeof(TCHAR));
395 lvc.pszText = szTemp;
396 (void)ListView_InsertColumn(Info->hListView,
397 4,
398 &lvc);
399
400 return TRUE;
401 }
402
403 static BOOL
404 CreateStatusBar(PMAIN_WND_INFO Info)
405 {
406 INT StatWidths[] = {110, -1}; /* widths of status bar */
407
408 Info->hStatus = CreateWindowEx(0,
409 STATUSCLASSNAME,
410 NULL,
411 WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP,
412 0, 0, 0, 0,
413 Info->hMainWnd,
414 (HMENU)IDC_STATUSBAR,
415 hInstance,
416 NULL);
417 if(Info->hStatus == NULL)
418 return FALSE;
419
420
421 SendMessage(Info->hStatus,
422 SB_SETPARTS,
423 sizeof(StatWidths) / sizeof(INT),
424 (LPARAM)StatWidths);
425
426 return TRUE;
427 }
428
429 static VOID
430 ListViewSelectionChanged(PMAIN_WND_INFO Info,
431 LPNMLISTVIEW pnmv)
432 {
433
434 HMENU hMainMenu;
435
436 /* get handle to menu */
437 hMainMenu = GetMenu(Info->hMainWnd);
438
439 /* activate properties menu item, if not already */
440 if (GetMenuState(hMainMenu,
441 ID_PROP,
442 MF_BYCOMMAND) != MF_ENABLED)
443 {
444 EnableMenuItem(hMainMenu,
445 ID_PROP,
446 MF_ENABLED);
447 }
448
449 /* activate delete menu item, if not already */
450 if (GetMenuState(hMainMenu,
451 ID_DELETE,
452 MF_BYCOMMAND) != MF_ENABLED)
453 {
454 EnableMenuItem(hMainMenu,
455 ID_DELETE,
456 MF_ENABLED);
457 EnableMenuItem(Info->hShortcutMenu,
458 ID_DELETE,
459 MF_ENABLED);
460 }
461
462
463 /* set selected service */
464 Info->SelectedItem = pnmv->iItem;
465
466 /* get pointer to selected service */
467 Info->CurrentService = GetSelectedService(Info);
468
469 /* alter options for the service */
470 SetMenuAndButtonStates(Info);
471
472 /* set current selected service in the status bar */
473 SendMessage(Info->hStatus,
474 SB_SETTEXT,
475 1,
476 (LPARAM)Info->CurrentService->lpDisplayName);
477
478 /* show the properties button */
479 SendMessage(Info->hTool,
480 TB_SETSTATE,
481 ID_PROP,
482 (LPARAM)MAKELONG(TBSTATE_ENABLED, 0));
483
484
485 }
486
487
488 static VOID
489 InitMainWnd(PMAIN_WND_INFO Info)
490 {
491 if (!CreateToolbar(Info))
492 DisplayString(_T("error creating toolbar"));
493
494 if (!CreateListView(Info))
495 {
496 DisplayString(_T("error creating list view"));
497 return;
498 }
499
500 if (!CreateStatusBar(Info))
501 DisplayString(_T("error creating status bar"));
502
503 /* Create Popup Menu */
504 Info->hShortcutMenu = LoadMenu(hInstance,
505 MAKEINTRESOURCE(IDR_POPUP));
506 Info->hShortcutMenu = GetSubMenu(Info->hShortcutMenu,
507 0);
508 }
509
510
511 static VOID
512 MainWndCommand(PMAIN_WND_INFO Info,
513 WORD CmdId,
514 HWND hControl)
515 {
516 UNREFERENCED_PARAMETER(hControl);
517
518 switch (CmdId)
519 {
520 case ID_PROP:
521 {
522 if (Info->SelectedItem != NO_ITEM_SELECTED)
523 {
524 PPROP_DLG_INFO PropSheet;
525
526 PropSheet = HeapAlloc(ProcessHeap,
527 HEAP_ZERO_MEMORY,
528 sizeof(PROP_DLG_INFO));
529 if (PropSheet != NULL)
530 {
531 Info->PropSheet = PropSheet;
532 OpenPropSheet(Info);
533 }
534
535 HeapFree(ProcessHeap,
536 0,
537 PropSheet);
538
539 Info->PropSheet = NULL;
540 }
541 }
542 break;
543
544 case ID_REFRESH:
545 {
546 RefreshServiceList(Info);
547 Info->SelectedItem = NO_ITEM_SELECTED;
548
549 /* disable menus and buttons */
550 SetMenuAndButtonStates(Info);
551
552 /* clear the service in the status bar */
553 SendMessage(Info->hStatus,
554 SB_SETTEXT,
555 1,
556 _T('\0'));
557 }
558 break;
559
560 case ID_EXPORT:
561 {
562 ExportFile(Info);
563 SetFocus(Info->hListView);
564 }
565 break;
566
567 case ID_CREATE:
568 {
569 DialogBoxParam(hInstance,
570 MAKEINTRESOURCE(IDD_DLG_CREATE),
571 Info->hMainWnd,
572 (DLGPROC)CreateDialogProc,
573 (LPARAM)Info);
574
575 SetFocus(Info->hListView);
576 }
577 break;
578
579 case ID_DELETE:
580 {
581 if (Info->CurrentService->ServiceStatusProcess.dwCurrentState != SERVICE_RUNNING)
582 {
583 DialogBoxParam(hInstance,
584 MAKEINTRESOURCE(IDD_DLG_DELETE),
585 Info->hMainWnd,
586 (DLGPROC)DeleteDialogProc,
587 (LPARAM)Info);
588 }
589 else
590 {
591 TCHAR Buf[60];
592 LoadString(hInstance,
593 IDS_DELETE_STOP,
594 Buf,
595 sizeof(Buf) / sizeof(TCHAR));
596 DisplayString(Buf);
597 }
598
599 SetFocus(Info->hListView);
600
601 }
602 break;
603
604 case ID_START:
605 {
606 DoStart(Info);
607 }
608 break;
609
610 case ID_STOP:
611 {
612 DoStop(Info);
613 }
614 break;
615
616 case ID_PAUSE:
617 {
618 Control(Info,
619 SERVICE_CONTROL_PAUSE);
620 }
621 break;
622
623 case ID_RESUME:
624 {
625 Control(Info,
626 SERVICE_CONTROL_CONTINUE );
627 }
628 break;
629
630 case ID_RESTART:
631 {
632 /* FIXME: remove this hack */
633 SendMessage(Info->hMainWnd,
634 WM_COMMAND,
635 0,
636 ID_STOP);
637 SendMessage(Info->hMainWnd,
638 WM_COMMAND,
639 0,
640 ID_START);
641 }
642 break;
643
644 case ID_HELP:
645 MessageBox(NULL,
646 _T("Help is not yet implemented\n"),
647 _T("Note!"),
648 MB_OK | MB_ICONINFORMATION);
649 SetFocus(Info->hListView);
650 break;
651
652 case ID_EXIT:
653 PostMessage(Info->hMainWnd,
654 WM_CLOSE,
655 0,
656 0);
657 break;
658
659 case ID_VIEW_LARGE:
660 SetListViewStyle(Info->hListView,
661 LVS_ICON);
662 break;
663
664 case ID_VIEW_SMALL:
665 SetListViewStyle(Info->hListView,
666 LVS_SMALLICON);
667 break;
668
669 case ID_VIEW_LIST:
670 SetListViewStyle(Info->hListView,
671 LVS_LIST);
672 break;
673
674 case ID_VIEW_DETAILS:
675 SetListViewStyle(Info->hListView,
676 LVS_REPORT);
677 break;
678
679 case ID_VIEW_CUST:
680 break;
681
682 case ID_ABOUT:
683 DialogBox(hInstance,
684 MAKEINTRESOURCE(IDD_ABOUTBOX),
685 Info->hMainWnd,
686 (DLGPROC)AboutDialogProc);
687 SetFocus(Info->hListView);
688 break;
689
690 }
691 }
692
693
694 static VOID CALLBACK
695 MainWndResize(PMAIN_WND_INFO Info,
696 WORD cx,
697 WORD cy)
698 {
699 RECT rcClient, rcTool, rcStatus;
700 int lvHeight, iToolHeight, iStatusHeight;
701
702 /* Size toolbar and get height */
703 SendMessage(Info->hTool, TB_AUTOSIZE, 0, 0);
704 GetWindowRect(Info->hTool, &rcTool);
705 iToolHeight = rcTool.bottom - rcTool.top;
706
707 /* Size status bar and get height */
708 SendMessage(Info->hStatus, WM_SIZE, 0, 0);
709 GetWindowRect(Info->hStatus, &rcStatus);
710 iStatusHeight = rcStatus.bottom - rcStatus.top;
711
712 /* Calculate remaining height and size list view */
713 GetClientRect(Info->hMainWnd, &rcClient);
714 lvHeight = rcClient.bottom - iToolHeight - iStatusHeight;
715 SetWindowPos(Info->hListView,
716 NULL,
717 0,
718 iToolHeight,
719 rcClient.right,
720 lvHeight,
721 SWP_NOZORDER);
722 }
723
724
725 static LRESULT CALLBACK
726 MainWndProc(HWND hwnd,
727 UINT msg,
728 WPARAM wParam,
729 LPARAM lParam)
730 {
731 PMAIN_WND_INFO Info;
732 LRESULT Ret = 0;
733
734 /* Get the window context */
735 Info = (PMAIN_WND_INFO)GetWindowLongPtr(hwnd,
736 GWLP_USERDATA);
737 if (Info == NULL && msg != WM_CREATE)
738 {
739 goto HandleDefaultMessage;
740 }
741
742 switch(msg)
743 {
744 case WM_CREATE:
745 {
746 Info = (PMAIN_WND_INFO)(((LPCREATESTRUCT)lParam)->lpCreateParams);
747
748 /* Initialize the main window context */
749 Info->hMainWnd = hwnd;
750 Info->SelectedItem = NO_ITEM_SELECTED;
751
752 SetWindowLongPtr(hwnd,
753 GWLP_USERDATA,
754 (LONG_PTR)Info);
755
756 InitMainWnd(Info);
757
758 /* Show the window */
759 ShowWindow(hwnd,
760 Info->nCmdShow);
761
762 RefreshServiceList(Info);
763 }
764 break;
765
766 case WM_SIZE:
767 {
768 MainWndResize(Info,
769 LOWORD(lParam),
770 HIWORD(lParam));
771 }
772 break;
773
774 case WM_NOTIFY:
775 {
776 LPNMHDR pnmhdr = (LPNMHDR)lParam;
777
778 switch (pnmhdr->code)
779 {
780 case NM_DBLCLK:
781 {
782 POINT pt;
783 RECT rect;
784
785 GetCursorPos(&pt);
786 GetWindowRect(Info->hListView, &rect);
787
788 if (PtInRect(&rect, pt))
789 {
790 SendMessage(hwnd,
791 WM_COMMAND,
792 //ID_PROP,
793 MAKEWPARAM((WORD)ID_PROP, (WORD)0),
794 0);
795 }
796
797 //OpenPropSheet(Info);
798 }
799 break;
800
801 case LVN_COLUMNCLICK:
802 {
803 LPNMLISTVIEW pnmv = (LPNMLISTVIEW) lParam;
804
805 (void)ListView_SortItems(Info->hListView,
806 CompareFunc,
807 pnmv->iSubItem);
808 bSortAscending = !bSortAscending;
809 }
810 break;
811
812 case LVN_ITEMCHANGED:
813 {
814 LPNMLISTVIEW pnmv = (LPNMLISTVIEW) lParam;
815
816 ListViewSelectionChanged(Info, pnmv);
817
818 }
819 break;
820
821 case TTN_GETDISPINFO:
822 {
823 LPTOOLTIPTEXT lpttt;
824 UINT idButton;
825
826 lpttt = (LPTOOLTIPTEXT)lParam;
827
828 /* Specify the resource identifier of the descriptive
829 * text for the given button. */
830 idButton = (UINT)lpttt->hdr.idFrom;
831 switch (idButton)
832 {
833 case ID_PROP:
834 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_PROP);
835 break;
836
837 case ID_REFRESH:
838 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_REFRESH);
839 break;
840
841 case ID_EXPORT:
842 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_EXPORT);
843 break;
844
845 case ID_CREATE:
846 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_CREATE);
847 break;
848
849 case ID_DELETE:
850 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_DELETE);
851 break;
852
853 case ID_START:
854 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_START);
855 break;
856
857 case ID_STOP:
858 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_STOP);
859 break;
860
861 case ID_PAUSE:
862 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_PAUSE);
863 break;
864
865 case ID_RESTART:
866 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_RESTART);
867 break;
868
869 case ID_HELP:
870 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_HELP);
871 break;
872
873 case ID_EXIT:
874 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_EXIT);
875 break;
876
877 }
878 }
879 break;
880 }
881 }
882 break;
883
884 case WM_CONTEXTMENU:
885 {
886 POINT pt;
887 RECT lvRect;
888
889 INT xPos = GET_X_LPARAM(lParam);
890 INT yPos = GET_Y_LPARAM(lParam);
891
892 GetCursorPos(&pt);
893
894 /* display popup when cursor is in the list view */
895 GetWindowRect(Info->hListView, &lvRect);
896 if (PtInRect(&lvRect, pt))
897 {
898 TrackPopupMenuEx(Info->hShortcutMenu,
899 TPM_RIGHTBUTTON,
900 xPos,
901 yPos,
902 Info->hMainWnd,
903 NULL);
904 }
905 }
906 break;
907
908 case WM_COMMAND:
909 {
910 MainWndCommand(Info,
911 LOWORD(wParam),
912 (HWND)lParam);
913 goto HandleDefaultMessage;
914 }
915
916 case WM_MENUSELECT:
917 {
918 if (Info->hStatus != NULL)
919 {
920 if (!MainWndMenuHint(Info,
921 LOWORD(wParam),
922 MainMenuHintTable,
923 sizeof(MainMenuHintTable) / sizeof(MainMenuHintTable[0]),
924 IDS_HINT_BLANK))
925 {
926 MainWndMenuHint(Info,
927 LOWORD(wParam),
928 SystemMenuHintTable,
929 sizeof(SystemMenuHintTable) / sizeof(SystemMenuHintTable[0]),
930 IDS_HINT_BLANK);
931 }
932 }
933 }
934 break;
935
936 case WM_ENTERMENULOOP:
937 {
938 Info->InMenuLoop = TRUE;
939 UpdateMainStatusBar(Info);
940 break;
941 }
942
943 case WM_EXITMENULOOP:
944 {
945 Info->InMenuLoop = FALSE;
946 UpdateMainStatusBar(Info);
947 break;
948 }
949
950 case WM_CLOSE:
951 {
952 /* Free service array */
953 HeapFree(ProcessHeap,
954 0,
955 Info->pServiceStatus);
956
957 DestroyMenu(Info->hShortcutMenu);
958 DestroyWindow(hwnd);
959 }
960 break;
961
962 case WM_DESTROY:
963 {
964 //DestroyMainWnd(Info);
965
966 HeapFree(ProcessHeap,
967 0,
968 Info);
969 SetWindowLongPtr(hwnd,
970 GWLP_USERDATA,
971 0);
972
973 /* Break the message queue loop */
974 PostQuitMessage(0);
975 }
976 break;
977
978 default:
979 {
980 HandleDefaultMessage:
981
982 Ret = DefWindowProc(hwnd,
983 msg,
984 wParam,
985 lParam);
986 }
987 break;
988 }
989 return Ret;
990 }
991
992
993
994 HWND
995 CreateMainWindow(LPCTSTR lpCaption,
996 int nCmdShow)
997 {
998 PMAIN_WND_INFO Info;
999 HWND hMainWnd = NULL;
1000
1001 Info = HeapAlloc(ProcessHeap,
1002 HEAP_ZERO_MEMORY,
1003 sizeof(MAIN_WND_INFO));
1004
1005 if (Info != NULL)
1006 {
1007 Info->nCmdShow = nCmdShow;
1008
1009 hMainWnd = CreateWindowEx(WS_EX_WINDOWEDGE,
1010 szMainWndClass,
1011 lpCaption,
1012 WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
1013 CW_USEDEFAULT,
1014 CW_USEDEFAULT,
1015 650,
1016 450,
1017 NULL,
1018 NULL,
1019 hInstance,
1020 Info);
1021 if (hMainWnd == NULL)
1022 {
1023 int ret;
1024 ret = GetLastError();
1025 GetError();
1026 HeapFree(ProcessHeap,
1027 0,
1028 Info);
1029 }
1030 }
1031
1032 return hMainWnd;
1033 }
1034
1035 BOOL
1036 InitMainWindowImpl(VOID)
1037 {
1038 WNDCLASSEX wc = {0};
1039
1040 wc.cbSize = sizeof(WNDCLASSEX);
1041 wc.lpfnWndProc = MainWndProc;
1042 wc.hInstance = hInstance;
1043 wc.hIcon = LoadIcon(hInstance,
1044 MAKEINTRESOURCE(IDI_SM_ICON));
1045 wc.hCursor = LoadCursor(NULL,
1046 IDC_ARROW);
1047 wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
1048 wc.lpszMenuName = MAKEINTRESOURCE(IDR_MAINMENU);
1049 wc.lpszClassName = szMainWndClass;
1050 wc.hIconSm = (HICON)LoadImage(hInstance,
1051 MAKEINTRESOURCE(IDI_SM_ICON),
1052 IMAGE_ICON,
1053 16,
1054 16,
1055 LR_SHARED);
1056
1057 return RegisterClassEx(&wc) != (ATOM)0;
1058 }
1059
1060
1061 VOID
1062 UninitMainWindowImpl(VOID)
1063 {
1064 UnregisterClass(szMainWndClass,
1065 hInstance);
1066 }
1067