2 * PROJECT: ReactOS Services
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/applications/mscutils/servman/mainwnd.c
5 * PURPOSE: Main window message handler
6 * COPYRIGHT: Copyright 2006-2007 Ged Murphy <gedmurphy@reactos.org>
12 static const TCHAR szMainWndClass
[] = TEXT("ServManWndClass");
14 BOOL bSortAscending
= TRUE
;
18 static const TBBUTTON 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 */
24 /* Note: First item for a seperator is its width in pixels */
25 {15, 0, TBSTATE_ENABLED
, BTNS_SEP
, {0}, 0, 0}, /* separator */
27 {TBICON_CREATE
, ID_CREATE
, TBSTATE_INDETERMINATE
, BTNS_BUTTON
, {0}, 0, 0 }, /* create */
28 {TBICON_DELETE
, ID_DELETE
, TBSTATE_INDETERMINATE
, BTNS_BUTTON
, {0}, 0, 0 }, /* delete */
30 {15, 0, TBSTATE_ENABLED
, BTNS_SEP
, {0}, 0, 0}, /* separator */
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 */
40 static const MENU_HINT MainMenuHintTable
[] = {
42 {ID_EXPORT
, IDS_HINT_EXPORT
},
43 {ID_EXIT
, IDS_HINT_EXIT
},
46 {ID_CONNECT
, IDS_HINT_CONNECT
},
47 {ID_START
, IDS_HINT_START
},
48 {ID_STOP
, IDS_HINT_STOP
},
49 {ID_PAUSE
, IDS_HINT_PAUSE
},
50 {ID_RESUME
, IDS_HINT_RESUME
},
51 {ID_RESTART
, IDS_HINT_RESTART
},
52 {ID_REFRESH
, IDS_HINT_REFRESH
},
53 {ID_EDIT
, IDS_HINT_EDIT
},
54 {ID_CREATE
, IDS_HINT_CREATE
},
55 {ID_DELETE
, IDS_HINT_DELETE
},
56 {ID_PROP
, IDS_HINT_PROP
},
59 {ID_VIEW_LARGE
, IDS_HINT_LARGE
},
60 {ID_VIEW_SMALL
, IDS_HINT_SMALL
},
61 {ID_VIEW_LIST
, IDS_HINT_LIST
},
62 {ID_VIEW_DETAILS
, IDS_HINT_DETAILS
},
63 {ID_VIEW_CUST
, IDS_HINT_CUST
},
66 {ID_HELP
, IDS_HINT_HELP
},
67 {ID_ABOUT
, IDS_HINT_ABOUT
}
69 /* system menu hints */
70 static const MENU_HINT SystemMenuHintTable
[] = {
71 {SC_RESTORE
, IDS_HINT_SYS_RESTORE
},
72 {SC_MOVE
, IDS_HINT_SYS_MOVE
},
73 {SC_SIZE
, IDS_HINT_SYS_SIZE
},
74 {SC_MINIMIZE
, IDS_HINT_SYS_MINIMIZE
},
75 {SC_MAXIMIZE
, IDS_HINT_SYS_MAXIMIZE
},
76 {SC_CLOSE
, IDS_HINT_SYS_CLOSE
},
81 MainWndMenuHint(PMAIN_WND_INFO Info
,
83 const MENU_HINT
*HintArray
,
88 const MENU_HINT
*LastHint
;
89 UINT HintId
= DefHintId
;
91 LastHint
= HintArray
+ HintsCount
;
92 while (HintArray
!= LastHint
)
94 if (HintArray
->CmdId
== CmdId
)
96 HintId
= HintArray
->HintId
;
103 StatusBarLoadString(Info
->hStatus
,
113 UpdateMainStatusBar(PMAIN_WND_INFO Info
)
115 if (Info
->hStatus
!= NULL
)
117 SendMessage(Info
->hStatus
,
119 (WPARAM
)Info
->bInMenuLoop
,
125 UpdateServiceCount(PMAIN_WND_INFO Info
)
127 LPTSTR lpNumServices
;
129 if (AllocAndLoadString(&lpNumServices
,
133 TCHAR szNumServices
[32];
135 INT NumListedServ
= ListView_GetItemCount(Info
->hListView
);
137 _sntprintf(szNumServices
,
142 SendMessage(Info
->hStatus
,
145 (LPARAM
)szNumServices
);
147 LocalFree(lpNumServices
);
152 VOID
SetMenuAndButtonStates(PMAIN_WND_INFO Info
)
157 /* get handle to menu */
158 hMainMenu
= GetMenu(Info
->hMainWnd
);
160 /* set all to greyed */
161 for (i
= ID_START
; i
<= ID_RESTART
; i
++)
163 EnableMenuItem(hMainMenu
, i
, MF_GRAYED
);
164 EnableMenuItem(GetSubMenu(Info
->hShortcutMenu
, 0), ID_START
, MF_GRAYED
);
165 SendMessage(Info
->hTool
, TB_SETSTATE
, i
,
166 (LPARAM
)MAKELONG(TBSTATE_INDETERMINATE
, 0));
169 if (Info
->SelectedItem
!= NO_ITEM_SELECTED
)
171 LPQUERY_SERVICE_CONFIG lpServiceConfig
= NULL
;
174 /* allow user to delete service */
175 if (Info
->bIsUserAnAdmin
)
177 SendMessage(Info
->hTool
, TB_SETSTATE
, ID_DELETE
,
178 (LPARAM
)MAKELONG(TBSTATE_ENABLED
, 0));
179 EnableMenuItem(hMainMenu
, ID_DELETE
, MF_ENABLED
);
180 EnableMenuItem(GetSubMenu(Info
->hShortcutMenu
, 0), ID_DELETE
, MF_ENABLED
);
183 Flags
= Info
->pCurrentService
->ServiceStatusProcess
.dwControlsAccepted
;
184 State
= Info
->pCurrentService
->ServiceStatusProcess
.dwCurrentState
;
186 lpServiceConfig
= GetServiceConfig(Info
->pCurrentService
->lpServiceName
);
188 if (lpServiceConfig
&& lpServiceConfig
->dwStartType
!= SERVICE_DISABLED
)
190 if (State
== SERVICE_STOPPED
)
192 EnableMenuItem(hMainMenu
, ID_START
, MF_ENABLED
);
193 EnableMenuItem(GetSubMenu(Info
->hShortcutMenu
, 0), ID_START
, MF_ENABLED
);
194 SendMessage(Info
->hTool
, TB_SETSTATE
, ID_START
,
195 (LPARAM
)MAKELONG(TBSTATE_ENABLED
, 0));
198 if ( (Flags
& SERVICE_ACCEPT_STOP
) && (State
== SERVICE_RUNNING
) )
200 EnableMenuItem(hMainMenu
, ID_RESTART
, MF_ENABLED
);
201 EnableMenuItem(GetSubMenu(Info
->hShortcutMenu
, 0), ID_RESTART
, MF_ENABLED
);
202 SendMessage(Info
->hTool
, TB_SETSTATE
, ID_RESTART
,
203 (LPARAM
)MAKELONG(TBSTATE_ENABLED
, 0));
206 HeapFree(GetProcessHeap(), 0, lpServiceConfig
);
209 if ( (Flags
& SERVICE_ACCEPT_STOP
) && (State
== SERVICE_RUNNING
) )
211 EnableMenuItem(hMainMenu
, ID_STOP
, MF_ENABLED
);
212 EnableMenuItem(GetSubMenu(Info
->hShortcutMenu
, 0), ID_STOP
, MF_ENABLED
);
213 SendMessage(Info
->hTool
, TB_SETSTATE
, ID_STOP
,
214 (LPARAM
)MAKELONG(TBSTATE_ENABLED
, 0));
217 if ( (Flags
& SERVICE_ACCEPT_PAUSE_CONTINUE
) && (State
== SERVICE_RUNNING
) )
219 EnableMenuItem(hMainMenu
, ID_PAUSE
, MF_ENABLED
);
220 EnableMenuItem(GetSubMenu(Info
->hShortcutMenu
, 0), ID_PAUSE
, MF_ENABLED
);
221 SendMessage(Info
->hTool
, TB_SETSTATE
, ID_PAUSE
,
222 (LPARAM
)MAKELONG(TBSTATE_ENABLED
, 0));
227 /* disable tools which rely on a selected service */
228 EnableMenuItem(hMainMenu
, ID_PROP
, MF_GRAYED
);
229 EnableMenuItem(hMainMenu
, ID_DELETE
, MF_GRAYED
);
230 EnableMenuItem(GetSubMenu(Info
->hShortcutMenu
, 0), ID_PROP
, MF_GRAYED
);
231 EnableMenuItem(GetSubMenu(Info
->hShortcutMenu
, 0), ID_DELETE
, MF_GRAYED
);
232 SendMessage(Info
->hTool
, TB_SETSTATE
, ID_PROP
,
233 (LPARAM
)MAKELONG(TBSTATE_INDETERMINATE
, 0));
234 SendMessage(Info
->hTool
, TB_SETSTATE
, ID_DELETE
,
235 (LPARAM
)MAKELONG(TBSTATE_INDETERMINATE
, 0));
242 CompareFunc(LPARAM lParam1
, LPARAM lParam2
, LPARAM lParamSort
)
244 ENUM_SERVICE_STATUS_PROCESS
*Param1
;
245 ENUM_SERVICE_STATUS_PROCESS
*Param2
;
246 // INT iSubItem = (LPARAM)lParamSort;
248 if (bSortAscending
) {
249 Param1
= (ENUM_SERVICE_STATUS_PROCESS
*)lParam1
;
250 Param2
= (ENUM_SERVICE_STATUS_PROCESS
*)lParam2
;
254 Param1
= (ENUM_SERVICE_STATUS_PROCESS
*)lParam2
;
255 Param2
= (ENUM_SERVICE_STATUS_PROCESS
*)lParam1
;
257 return _tcsicmp(Param1
->lpDisplayName
, Param2
->lpDisplayName
);
262 pCreateToolbar(PMAIN_WND_INFO Info
)
264 INT numButtons
= sizeof(Buttons
) / sizeof(Buttons
[0]);
266 Info
->hTool
= CreateWindowEx(0,
269 WS_CHILD
| WS_VISIBLE
| TBSTYLE_FLAT
| TBSTYLE_TOOLTIPS
,
275 if(Info
->hTool
!= NULL
)
277 HIMAGELIST hImageList
;
279 SendMessage(Info
->hTool
,
282 TBSTYLE_EX_HIDECLIPPEDBUTTONS
);
284 SendMessage(Info
->hTool
,
289 hImageList
= InitImageList(IDB_PROP
,
293 if (hImageList
== NULL
)
296 ImageList_Destroy((HIMAGELIST
)SendMessage(Info
->hTool
,
299 (LPARAM
)hImageList
));
301 SendMessage(Info
->hTool
,
313 CreateStatusBar(PMAIN_WND_INFO Info
)
315 INT StatWidths
[] = {110, -1}; /* widths of status bar */
317 Info
->hStatus
= CreateWindowEx(0,
320 WS_CHILD
| WS_VISIBLE
| SBARS_SIZEGRIP
,
323 (HMENU
)IDC_STATUSBAR
,
326 if(Info
->hStatus
== NULL
)
329 SendMessage(Info
->hStatus
,
331 sizeof(StatWidths
) / sizeof(INT
),
339 InitMainWnd(PMAIN_WND_INFO Info
)
341 if (!pCreateToolbar(Info
))
343 DisplayString(_T("error creating toolbar"));
347 if (!CreateListView(Info
))
349 DisplayString(_T("error creating list view"));
353 if (!CreateStatusBar(Info
))
354 DisplayString(_T("error creating status bar"));
356 /* Create Popup Menu */
357 Info
->hShortcutMenu
= LoadMenu(hInstance
,
358 MAKEINTRESOURCE(IDR_POPUP
));
360 Info
->bIsUserAnAdmin
= IsUserAnAdmin();
361 if (Info
->bIsUserAnAdmin
)
363 HMENU hMainMenu
= GetMenu(Info
->hMainWnd
);
365 SendMessage(Info
->hTool
,
368 (LPARAM
)MAKELONG(TBSTATE_ENABLED
, 0));
371 EnableMenuItem(hMainMenu
,
375 EnableMenuItem(GetSubMenu(Info
->hShortcutMenu
, 0),
385 MainWndCommand(PMAIN_WND_INFO Info
,
389 UNREFERENCED_PARAMETER(hControl
);
395 if (Info
->SelectedItem
!= NO_ITEM_SELECTED
)
397 Info
->bDlgOpen
= TRUE
;
399 Info
->bDlgOpen
= FALSE
;
400 SetMenuAndButtonStates(Info
);
407 RefreshServiceList(Info
);
408 Info
->SelectedItem
= NO_ITEM_SELECTED
;
410 /* disable menus and buttons */
411 SetMenuAndButtonStates(Info
);
413 /* clear the service in the status bar */
414 SendMessage(Info
->hStatus
,
424 SetFocus(Info
->hListView
);
432 ret
= DialogBoxParam(hInstance
,
433 MAKEINTRESOURCE(IDD_DLG_CREATE
),
435 (DLGPROC
)CreateDialogProc
,
438 RefreshServiceList(Info
);
440 SetFocus(Info
->hListView
);
446 if (Info
->pCurrentService
->ServiceStatusProcess
.dwCurrentState
!= SERVICE_RUNNING
)
448 DialogBoxParam(hInstance
,
449 MAKEINTRESOURCE(IDD_DLG_DELETE
),
451 (DLGPROC
)DeleteDialogProc
,
457 LoadString(hInstance
,
460 sizeof(Buf
) / sizeof(TCHAR
));
464 SetFocus(Info
->hListView
);
473 UpdateServiceStatus(Info
->pCurrentService
);
474 ChangeListViewText(Info
, Info
->pCurrentService
, LVSTATUS
);
475 SetMenuAndButtonStates(Info
);
476 SetFocus(Info
->hListView
);
484 UpdateServiceStatus(Info
->pCurrentService
);
485 ChangeListViewText(Info
, Info
->pCurrentService
, LVSTATUS
);
486 SetMenuAndButtonStates(Info
);
487 SetFocus(Info
->hListView
);
503 UpdateServiceStatus(Info
->pCurrentService
);
504 ChangeListViewText(Info
, Info
->pCurrentService
, LVSTATUS
);
505 SetMenuAndButtonStates(Info
);
506 SetFocus(Info
->hListView
);
512 _T("Help is not yet implemented\n"),
514 MB_OK
| MB_ICONINFORMATION
);
515 SetFocus(Info
->hListView
);
519 PostMessage(Info
->hMainWnd
,
526 SetListViewStyle(Info
->hListView
,
528 CheckMenuRadioItem(GetMenu(Info
->hMainWnd
),
536 SetListViewStyle(Info
->hListView
,
538 CheckMenuRadioItem(GetMenu(Info
->hMainWnd
),
546 SetListViewStyle(Info
->hListView
,
548 CheckMenuRadioItem(GetMenu(Info
->hMainWnd
),
555 case ID_VIEW_DETAILS
:
556 SetListViewStyle(Info
->hListView
,
558 CheckMenuRadioItem(GetMenu(Info
->hMainWnd
),
570 MAKEINTRESOURCE(IDD_ABOUTBOX
),
572 (DLGPROC
)AboutDialogProc
);
573 SetFocus(Info
->hListView
);
581 MainWndResize(PMAIN_WND_INFO Info
,
585 RECT rcClient
, rcTool
, rcStatus
;
586 int lvHeight
, iToolHeight
, iStatusHeight
;
588 /* Size toolbar and get height */
589 SendMessage(Info
->hTool
, TB_AUTOSIZE
, 0, 0);
590 GetWindowRect(Info
->hTool
, &rcTool
);
591 iToolHeight
= rcTool
.bottom
- rcTool
.top
;
593 /* Size status bar and get height */
594 SendMessage(Info
->hStatus
, WM_SIZE
, 0, 0);
595 GetWindowRect(Info
->hStatus
, &rcStatus
);
596 iStatusHeight
= rcStatus
.bottom
- rcStatus
.top
;
598 /* Calculate remaining height and size list view */
599 GetClientRect(Info
->hMainWnd
, &rcClient
);
600 lvHeight
= rcClient
.bottom
- iToolHeight
- iStatusHeight
;
601 SetWindowPos(Info
->hListView
,
611 static LRESULT CALLBACK
612 MainWndProc(HWND hwnd
,
620 /* Get the window context */
621 Info
= (PMAIN_WND_INFO
)GetWindowLongPtr(hwnd
,
623 if (Info
== NULL
&& msg
!= WM_CREATE
)
625 goto HandleDefaultMessage
;
632 Info
= (PMAIN_WND_INFO
)(((LPCREATESTRUCT
)lParam
)->lpCreateParams
);
634 /* Initialize the main window context */
635 Info
->hMainWnd
= hwnd
;
636 Info
->SelectedItem
= NO_ITEM_SELECTED
;
638 SetWindowLongPtr(hwnd
,
642 if (!InitMainWnd(Info
))
645 /* Show the window */
649 RefreshServiceList(Info
);
663 LPNMHDR pnmhdr
= (LPNMHDR
)lParam
;
665 switch (pnmhdr
->code
)
673 GetWindowRect(Info
->hListView
, &rect
);
675 if (PtInRect(&rect
, pt
))
680 MAKEWPARAM((WORD
)ID_PROP
, (WORD
)0),
684 //OpenPropSheet(Info);
688 case LVN_COLUMNCLICK
:
690 LPNMLISTVIEW pnmv
= (LPNMLISTVIEW
) lParam
;
692 (void)ListView_SortItems(Info
->hListView
,
695 bSortAscending
= !bSortAscending
;
699 case LVN_ITEMCHANGED
:
701 LPNMLISTVIEW pnmv
= (LPNMLISTVIEW
) lParam
;
703 if (pnmv
->uNewState
!= 0)
705 ListViewSelectionChanged(Info
, pnmv
);
706 SetMenuAndButtonStates(Info
);
711 case TTN_GETDISPINFO
:
716 lpttt
= (LPTOOLTIPTEXT
)lParam
;
718 /* Specify the resource identifier of the descriptive
719 * text for the given button. */
720 idButton
= (UINT
)lpttt
->hdr
.idFrom
;
724 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_PROP
);
728 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_REFRESH
);
732 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_EXPORT
);
736 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_CREATE
);
740 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_DELETE
);
744 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_START
);
748 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_STOP
);
752 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_PAUSE
);
756 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_RESTART
);
770 INT xPos
= GET_X_LPARAM(lParam
);
771 INT yPos
= GET_Y_LPARAM(lParam
);
775 /* display popup when cursor is in the list view */
776 GetWindowRect(Info
->hListView
, &lvRect
);
777 if (PtInRect(&lvRect
, pt
))
779 TrackPopupMenuEx(GetSubMenu(Info
->hShortcutMenu
, 0),
794 goto HandleDefaultMessage
;
799 if (Info
->hStatus
!= NULL
)
801 if (!MainWndMenuHint(Info
,
804 sizeof(MainMenuHintTable
) / sizeof(MainMenuHintTable
[0]),
807 MainWndMenuHint(Info
,
810 sizeof(SystemMenuHintTable
) / sizeof(SystemMenuHintTable
[0]),
817 case WM_ENTERMENULOOP
:
819 Info
->bInMenuLoop
= TRUE
;
820 UpdateMainStatusBar(Info
);
824 case WM_EXITMENULOOP
:
826 Info
->bInMenuLoop
= FALSE
;
827 UpdateMainStatusBar(Info
);
833 HeapFree(ProcessHeap
,
837 DestroyMenu(Info
->hShortcutMenu
);
844 HeapFree(ProcessHeap
,
847 SetWindowLongPtr(hwnd
,
857 HandleDefaultMessage
:
859 Ret
= DefWindowProc(hwnd
,
873 CreateMainWindow(LPCTSTR lpCaption
,
877 HWND hMainWnd
= NULL
;
879 Info
= (MAIN_WND_INFO
*) HeapAlloc(ProcessHeap
,
881 sizeof(MAIN_WND_INFO
));
885 Info
->nCmdShow
= nCmdShow
;
887 hMainWnd
= CreateWindowEx(WS_EX_WINDOWEDGE
,
890 WS_OVERLAPPEDWINDOW
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
,
899 if (hMainWnd
== NULL
)
902 ret
= GetLastError();
904 HeapFree(ProcessHeap
,
914 InitMainWindowImpl(VOID
)
918 wc
.cbSize
= sizeof(WNDCLASSEX
);
919 wc
.lpfnWndProc
= MainWndProc
;
920 wc
.hInstance
= hInstance
;
921 wc
.hIcon
= LoadIcon(hInstance
,
922 MAKEINTRESOURCE(IDI_SM_ICON
));
923 wc
.hCursor
= LoadCursor(NULL
,
925 wc
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
926 wc
.lpszMenuName
= MAKEINTRESOURCE(IDR_MAINMENU
);
927 wc
.lpszClassName
= szMainWndClass
;
928 wc
.hIconSm
= (HICON
)LoadImage(hInstance
,
929 MAKEINTRESOURCE(IDI_SM_ICON
),
935 return RegisterClassEx(&wc
) != (ATOM
)0;
940 UninitMainWindowImpl(VOID
)
942 UnregisterClass(szMainWndClass
,