1 /*
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-2017 Ged Murphy <gedmurphy@reactos.org>
7 *
8 */
9
10 #include "precomp.h"
11
12 #include <windowsx.h>
13 #include <shellapi.h>
14
15 static const WCHAR szMainWndClass[] = L"ServManWndClass";
16
17 /* Toolbar buttons */
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 */
23
24 /* Note: First item for a separator is its width in pixels */
25 {15, 0, TBSTATE_ENABLED, BTNS_SEP, {0}, 0, 0}, /* separator */
26
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 */
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
38
39 /* menu hints */
40 static const MENU_HINT MainMenuHintTable[] = {
41 /* File Menu */
42 {ID_EXPORT, IDS_HINT_EXPORT},
43 {ID_EXIT, IDS_HINT_EXIT},
44
45 /* Action Menu */
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},
57
58 /* View menu */
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},
64
65 /* Help Menu */
66 {ID_HELP, IDS_HINT_HELP},
67 {ID_ABOUT, IDS_HINT_ABOUT}
68 };
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},
77 };
78
79
80 static BOOL
MainWndMenuHint(PMAIN_WND_INFO Info,WORD CmdId,const MENU_HINT * HintArray,DWORD HintsCount,UINT DefHintId)81 MainWndMenuHint(PMAIN_WND_INFO Info,
82 WORD CmdId,
83 const MENU_HINT *HintArray,
84 DWORD HintsCount,
85 UINT DefHintId)
86 {
87 BOOL Found = FALSE;
88 const MENU_HINT *LastHint;
89 UINT HintId = DefHintId;
90
91 LastHint = HintArray + HintsCount;
92 while (HintArray != LastHint)
93 {
94 if (HintArray->CmdId == CmdId)
95 {
96 HintId = HintArray->HintId;
97 Found = TRUE;
98 break;
99 }
100 HintArray++;
101 }
102
103 StatusBarLoadString(Info->hStatus,
104 SB_SIMPLEID,
105 hInstance,
106 HintId);
107
108 return Found;
109 }
110
111
112 static VOID
UpdateMainStatusBar(PMAIN_WND_INFO Info)113 UpdateMainStatusBar(PMAIN_WND_INFO Info)
114 {
115 if (Info->hStatus != NULL)
116 {
117 SendMessage(Info->hStatus,
118 SB_SIMPLE,
119 (WPARAM)Info->bInMenuLoop,
120 0);
121 }
122 }
123
124 VOID
UpdateServiceCount(PMAIN_WND_INFO Info)125 UpdateServiceCount(PMAIN_WND_INFO Info)
126 {
127 LPWSTR lpNumServices;
128
129 if (AllocAndLoadString(&lpNumServices,
130 hInstance,
131 IDS_NUM_SERVICES))
132 {
133 WCHAR szNumServices[32];
134
135 INT NumListedServ = ListView_GetItemCount(Info->hListView);
136
137 _snwprintf(szNumServices,
138 31,
139 lpNumServices,
140 NumListedServ);
141
142 SendMessage(Info->hStatus,
143 SB_SETTEXT,
144 0,
145 (LPARAM)szNumServices);
146
147 LocalFree(lpNumServices);
148 }
149 }
150
151
SetMenuAndButtonStates(PMAIN_WND_INFO Info)152 VOID SetMenuAndButtonStates(PMAIN_WND_INFO Info)
153 {
154 HMENU hMainMenu;
155 UINT i;
156
157 /* get handle to menu */
158 hMainMenu = GetMenu(Info->hMainWnd);
159
160 /* set all to greyed */
161 for (i = ID_START; i <= ID_RESTART; i++)
162 {
163 EnableMenuItem(hMainMenu, i, MF_GRAYED);
164 EnableMenuItem(GetSubMenu(Info->hShortcutMenu, 0), i, MF_GRAYED);
165 SendMessage(Info->hTool, TB_SETSTATE, i,
166 (LPARAM)MAKELONG(TBSTATE_INDETERMINATE, 0));
167 }
168
169 if (Info->SelectedItem != NO_ITEM_SELECTED)
170 {
171 LPQUERY_SERVICE_CONFIG lpServiceConfig = NULL;
172 DWORD Flags, State;
173
174 /* allow user to delete service */
175 if (Info->bIsUserAnAdmin)
176 {
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);
181 }
182
183 Flags = Info->pCurrentService->ServiceStatusProcess.dwControlsAccepted;
184 State = Info->pCurrentService->ServiceStatusProcess.dwCurrentState;
185
186 lpServiceConfig = GetServiceConfig(Info->pCurrentService->lpServiceName);
187
188 if (lpServiceConfig && lpServiceConfig->dwStartType != SERVICE_DISABLED)
189 {
190 if (State == SERVICE_STOPPED)
191 {
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));
196 }
197
198 if ( (Flags & SERVICE_ACCEPT_STOP) && (State == SERVICE_RUNNING) )
199 {
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));
204 }
205 }
206
207 if(lpServiceConfig)
208 HeapFree(GetProcessHeap(), 0, lpServiceConfig);
209
210 if ( (Flags & SERVICE_ACCEPT_STOP) && (State == SERVICE_RUNNING) )
211 {
212 EnableMenuItem(hMainMenu, ID_STOP, MF_ENABLED);
213 EnableMenuItem(GetSubMenu(Info->hShortcutMenu, 0), ID_STOP, MF_ENABLED);
214 SendMessage(Info->hTool, TB_SETSTATE, ID_STOP,
215 (LPARAM)MAKELONG(TBSTATE_ENABLED, 0));
216 }
217
218 if ( (Flags & SERVICE_ACCEPT_PAUSE_CONTINUE) && (State == SERVICE_RUNNING) )
219 {
220 EnableMenuItem(hMainMenu, ID_PAUSE, MF_ENABLED);
221 EnableMenuItem(GetSubMenu(Info->hShortcutMenu, 0), ID_PAUSE, MF_ENABLED);
222 SendMessage(Info->hTool, TB_SETSTATE, ID_PAUSE,
223 (LPARAM)MAKELONG(TBSTATE_ENABLED, 0));
224 }
225 }
226 else
227 {
228 /* disable tools which rely on a selected service */
229 EnableMenuItem(hMainMenu, ID_PROP, MF_GRAYED);
230 EnableMenuItem(hMainMenu, ID_DELETE, MF_GRAYED);
231 EnableMenuItem(GetSubMenu(Info->hShortcutMenu, 0), ID_PROP, MF_GRAYED);
232 EnableMenuItem(GetSubMenu(Info->hShortcutMenu, 0), ID_DELETE, MF_GRAYED);
233 SendMessage(Info->hTool, TB_SETSTATE, ID_PROP,
234 (LPARAM)MAKELONG(TBSTATE_INDETERMINATE, 0));
235 SendMessage(Info->hTool, TB_SETSTATE, ID_DELETE,
236 (LPARAM)MAKELONG(TBSTATE_INDETERMINATE, 0));
237 }
238
239 }
240
241
242 static INT CALLBACK
CompareFunc(LPARAM lParam1,LPARAM lParam2,LPARAM lParamSort)243 CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
244 {
245 PMAIN_WND_INFO Info = (PMAIN_WND_INFO)lParamSort;
246 WCHAR Item1[256], Item2[256];
247
248 ListView_GetItemText(Info->hListView, lParam1, Info->SortSelection, Item1, sizeof(Item1) / sizeof(WCHAR));
249 ListView_GetItemText(Info->hListView, lParam2, Info->SortSelection, Item2, sizeof(Item2) / sizeof(WCHAR));
250
251 return wcscmp(Item1, Item2) * Info->SortDirection;
252 }
253
254
255 static BOOL
pCreateToolbar(PMAIN_WND_INFO Info)256 pCreateToolbar(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_RESTART,
285 GetSystemMetrics(SM_CXSMICON),
286 GetSystemMetrics(SM_CXSMICON),
287 IMAGE_BITMAP);
288 if (hImageList == NULL)
289 return FALSE;
290
291 ImageList_Destroy((HIMAGELIST)SendMessage(Info->hTool,
292 TB_SETIMAGELIST,
293 0,
294 (LPARAM)hImageList));
295
296 SendMessage(Info->hTool,
297 TB_ADDBUTTONS,
298 numButtons,
299 (LPARAM)Buttons);
300
301 return TRUE;
302 }
303
304 return FALSE;
305 }
306
307 static BOOL
CreateStatusBar(PMAIN_WND_INFO Info)308 CreateStatusBar(PMAIN_WND_INFO Info)
309 {
310 INT StatWidths[] = {130, -1}; /* widths of status bar */
311
312 Info->hStatus = CreateWindowEx(0,
313 STATUSCLASSNAME,
314 NULL,
315 WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP,
316 0, 0, 0, 0,
317 Info->hMainWnd,
318 (HMENU)IDC_STATUSBAR,
319 hInstance,
320 NULL);
321 if(Info->hStatus == NULL)
322 return FALSE;
323
324 SendMessage(Info->hStatus,
325 SB_SETPARTS,
326 sizeof(StatWidths) / sizeof(INT),
327 (LPARAM)StatWidths);
328
329 return TRUE;
330 }
331
332
333 static BOOL
InitMainWnd(PMAIN_WND_INFO Info)334 InitMainWnd(PMAIN_WND_INFO Info)
335 {
336 if (!pCreateToolbar(Info))
337 {
338 DisplayString(L"error creating toolbar");
339 return FALSE;
340 }
341
342 if (!CreateListView(Info))
343 {
344 DisplayString(L"error creating list view");
345 return FALSE;
346 }
347
348 if (!CreateStatusBar(Info))
349 DisplayString(L"error creating status bar");
350
351 /* Create Popup Menu */
352 Info->hShortcutMenu = LoadMenu(hInstance,
353 MAKEINTRESOURCE(IDR_POPUP));
354
355 Info->bIsUserAnAdmin = TRUE;// IsUserAnAdmin();
356 if (Info->bIsUserAnAdmin)
357 {
358 HMENU hMainMenu = GetMenu(Info->hMainWnd);
359
360 SendMessage(Info->hTool,
361 TB_SETSTATE,
362 ID_CREATE,
363 (LPARAM)MAKELONG(TBSTATE_ENABLED, 0));
364 if (hMainMenu)
365 {
366 EnableMenuItem(hMainMenu,
367 ID_CREATE,
368 MF_ENABLED);
369 }
370 EnableMenuItem(GetSubMenu(Info->hShortcutMenu, 0),
371 ID_CREATE,
372 MF_ENABLED);
373 }
374
375 return TRUE;
376 }
377
378 static VOID
MainWndCommand(PMAIN_WND_INFO Info,WORD CmdId,HWND hControl)379 MainWndCommand(PMAIN_WND_INFO Info,
380 WORD CmdId,
381 HWND hControl)
382 {
383 WCHAR szAppName[256];
384 WCHAR szAppAuthors[256];
385
386 UNREFERENCED_PARAMETER(hControl);
387
388 switch (CmdId)
389 {
390 case ID_PROP:
391 {
392 if (Info->SelectedItem != NO_ITEM_SELECTED)
393 {
394 Info->bDlgOpen = TRUE;
395 OpenPropSheet(Info);
396 Info->bDlgOpen = FALSE;
397 SetMenuAndButtonStates(Info);
398 }
399 }
400 break;
401
402 case ID_REFRESH:
403 {
404 RefreshServiceList(Info);
405 Info->SelectedItem = NO_ITEM_SELECTED;
406
407 /* disable menus and buttons */
408 SetMenuAndButtonStates(Info);
409
410 /* clear the service in the status bar */
411 SendMessage(Info->hStatus,
412 SB_SETTEXT,
413 1,
414 L'\0');
415 }
416 break;
417
418 case ID_EXPORT:
419 {
420 ExportFile(Info);
421 SetFocus(Info->hListView);
422 }
423 break;
424
425 case ID_CREATE:
426 {
427 INT ret;
428
429 ret = DialogBoxParam(hInstance,
430 MAKEINTRESOURCE(IDD_DLG_CREATE),
431 Info->hMainWnd,
432 CreateDialogProc,
433 (LPARAM)Info);
434 if (ret == IDOK)
435 RefreshServiceList(Info);
436
437 SetFocus(Info->hListView);
438 }
439 break;
440
441 case ID_DELETE:
442 {
443 if (Info->pCurrentService->ServiceStatusProcess.dwCurrentState != SERVICE_RUNNING)
444 {
445 DialogBoxParam(hInstance,
446 MAKEINTRESOURCE(IDD_DLG_DELETE),
447 Info->hMainWnd,
448 DeleteDialogProc,
449 (LPARAM)Info);
450 }
451 else
452 {
453 WCHAR Buf[60];
454 LoadString(hInstance,
455 IDS_DELETE_STOP,
456 Buf,
457 sizeof(Buf) / sizeof(WCHAR));
458 DisplayString(Buf);
459 }
460
461 SetFocus(Info->hListView);
462
463 }
464 break;
465
466 case ID_START:
467 {
468 RunActionWithProgress(Info->hMainWnd,
469 Info->pCurrentService->lpServiceName,
470 Info->pCurrentService->lpDisplayName,
471 ACTION_START,
472 NULL); //FIXME: Add start params
473
474 UpdateServiceStatus(Info->pCurrentService);
475 ChangeListViewText(Info, Info->pCurrentService, LVSTATUS);
476 SetMenuAndButtonStates(Info);
477 SetFocus(Info->hListView);
478
479 }
480 break;
481
482 case ID_STOP:
483 RunActionWithProgress(Info->hMainWnd,
484 Info->pCurrentService->lpServiceName,
485 Info->pCurrentService->lpDisplayName,
486 ACTION_STOP,
487 NULL);
488
489 UpdateServiceStatus(Info->pCurrentService);
490 ChangeListViewText(Info, Info->pCurrentService, LVSTATUS);
491 SetMenuAndButtonStates(Info);
492 SetFocus(Info->hListView);
493
494 break;
495
496 case ID_PAUSE:
497 RunActionWithProgress(Info->hMainWnd,
498 Info->pCurrentService->lpServiceName,
499 Info->pCurrentService->lpDisplayName,
500 ACTION_PAUSE,
501 NULL);
502
503 UpdateServiceStatus(Info->pCurrentService);
504 ChangeListViewText(Info, Info->pCurrentService, LVSTATUS);
505 SetMenuAndButtonStates(Info);
506 SetFocus(Info->hListView);
507 break;
508
509 case ID_RESUME:
510 RunActionWithProgress(Info->hMainWnd,
511 Info->pCurrentService->lpServiceName,
512 Info->pCurrentService->lpDisplayName,
513 ACTION_RESUME,
514 NULL);
515
516 UpdateServiceStatus(Info->pCurrentService);
517 ChangeListViewText(Info, Info->pCurrentService, LVSTATUS);
518 SetMenuAndButtonStates(Info);
519 SetFocus(Info->hListView);
520 break;
521
522 case ID_RESTART:
523 RunActionWithProgress(Info->hMainWnd,
524 Info->pCurrentService->lpServiceName,
525 Info->pCurrentService->lpDisplayName,
526 ACTION_RESTART,
527 NULL);
528
529 UpdateServiceStatus(Info->pCurrentService);
530 ChangeListViewText(Info, Info->pCurrentService, LVSTATUS);
531 SetMenuAndButtonStates(Info);
532 SetFocus(Info->hListView);
533 break;
534
535 case ID_HELP:
536 MessageBoxW(NULL,
537 L"Help is not yet implemented\n",
538 L"Note!",
539 MB_OK | MB_ICONINFORMATION);
540 SetFocus(Info->hListView);
541 break;
542
543 case ID_EXIT:
544 PostMessage(Info->hMainWnd,
545 WM_CLOSE,
546 0,
547 0);
548 break;
549
550 case ID_VIEW_LARGE:
551 SetListViewStyle(Info->hListView, LVS_ICON);
552 ListView_Arrange(Info->hListView, LVA_DEFAULT);
553
554 CheckMenuRadioItem(GetMenu(Info->hMainWnd),
555 ID_VIEW_LARGE,
556 ID_VIEW_DETAILS,
557 ID_VIEW_LARGE,
558 MF_BYCOMMAND);
559 break;
560
561 case ID_VIEW_SMALL:
562 SetListViewStyle(Info->hListView, LVS_SMALLICON);
563 ListView_Arrange(Info->hListView, LVA_DEFAULT);
564
565 CheckMenuRadioItem(GetMenu(Info->hMainWnd),
566 ID_VIEW_LARGE,
567 ID_VIEW_DETAILS,
568 ID_VIEW_SMALL,
569 MF_BYCOMMAND);
570 break;
571
572 case ID_VIEW_LIST:
573 SetListViewStyle(Info->hListView,
574 LVS_LIST);
575 CheckMenuRadioItem(GetMenu(Info->hMainWnd),
576 ID_VIEW_LARGE,
577 ID_VIEW_DETAILS,
578 ID_VIEW_LIST,
579 MF_BYCOMMAND);
580 break;
581
582 case ID_VIEW_DETAILS:
583 SetListViewStyle(Info->hListView,
584 LVS_REPORT);
585 CheckMenuRadioItem(GetMenu(Info->hMainWnd),
586 ID_VIEW_LARGE,
587 ID_VIEW_DETAILS,
588 ID_VIEW_DETAILS,
589 MF_BYCOMMAND);
590 break;
591
592 case ID_VIEW_CUST:
593 break;
594
595 case ID_ABOUT:
596 LoadStringW(hInstance, IDS_APPNAME, szAppName, _countof(szAppName));
597 LoadStringW(hInstance, IDS_APPAUTHORS, szAppAuthors, _countof(szAppAuthors));
598
599 ShellAboutW(Info->hMainWnd, szAppName, szAppAuthors,
600 LoadIconW(hInstance, MAKEINTRESOURCEW(IDI_SM_ICON)));
601 break;
602
603 }
604 }
605
606
607 static VOID CALLBACK
MainWndResize(PMAIN_WND_INFO Info,WORD cx,WORD cy)608 MainWndResize(PMAIN_WND_INFO Info,
609 WORD cx,
610 WORD cy)
611 {
612 RECT rcClient, rcTool, rcStatus;
613 int lvHeight, iToolHeight, iStatusHeight;
614
615 /* Size toolbar and get height */
616 SendMessage(Info->hTool, TB_AUTOSIZE, 0, 0);
617 GetWindowRect(Info->hTool, &rcTool);
618 iToolHeight = rcTool.bottom - rcTool.top;
619
620 /* Size status bar and get height */
621 SendMessage(Info->hStatus, WM_SIZE, 0, 0);
622 GetWindowRect(Info->hStatus, &rcStatus);
623 iStatusHeight = rcStatus.bottom - rcStatus.top;
624
625 /* Calculate remaining height and size list view */
626 GetClientRect(Info->hMainWnd, &rcClient);
627 lvHeight = rcClient.bottom - iToolHeight - iStatusHeight;
628 SetWindowPos(Info->hListView,
629 NULL,
630 0,
631 iToolHeight,
632 rcClient.right,
633 lvHeight,
634 SWP_NOZORDER);
635 }
636
637
638 static LRESULT CALLBACK
MainWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)639 MainWndProc(HWND hwnd,
640 UINT msg,
641 WPARAM wParam,
642 LPARAM lParam)
643 {
644 PMAIN_WND_INFO Info;
645 LRESULT Ret = 0;
646
647 /* Get the window context */
648 Info = (PMAIN_WND_INFO)GetWindowLongPtr(hwnd,
649 GWLP_USERDATA);
650 if (Info == NULL && msg != WM_CREATE)
651 {
652 goto HandleDefaultMessage;
653 }
654
655 switch(msg)
656 {
657 case WM_CREATE:
658 {
659 Info = (PMAIN_WND_INFO)(((LPCREATESTRUCT)lParam)->lpCreateParams);
660
661 /* Initialize the main window context */
662 Info->hMainWnd = hwnd;
663 Info->SelectedItem = NO_ITEM_SELECTED;
664
665 SetWindowLongPtr(hwnd,
666 GWLP_USERDATA,
667 (LONG_PTR)Info);
668
669 if (!InitMainWnd(Info))
670 return -1;
671
672 /* Fill the list-view before showing the main window */
673 RefreshServiceList(Info);
674
675 /* Show the window */
676 ShowWindow(hwnd,
677 Info->nCmdShow);
678
679 SetFocus(Info->hListView);
680 }
681 break;
682
683 case WM_SIZE:
684 {
685 MainWndResize(Info,
686 LOWORD(lParam),
687 HIWORD(lParam));
688 }
689 break;
690
691 case WM_NOTIFY:
692 {
693 LPNMHDR pnmhdr = (LPNMHDR)lParam;
694
695 switch (pnmhdr->code)
696 {
697 case NM_DBLCLK:
698 {
699 POINT pt;
700 RECT rect;
701
702 GetCursorPos(&pt);
703 GetWindowRect(Info->hListView, &rect);
704
705 if (PtInRect(&rect, pt))
706 {
707 SendMessage(hwnd,
708 WM_COMMAND,
709 //ID_PROP,
710 MAKEWPARAM((WORD)ID_PROP, (WORD)0),
711 0);
712 }
713
714 //OpenPropSheet(Info);
715 }
716 break;
717
718 case NM_RETURN:
719 {
720 SendMessage(hwnd,
721 WM_COMMAND,
722 //ID_PROP,
723 MAKEWPARAM((WORD)ID_PROP, (WORD)0),
724 0);
725 }
726 break;
727
728 case LVN_COLUMNCLICK:
729 {
730 LPNMLISTVIEW pnmv = (LPNMLISTVIEW) lParam;
731 HDITEM hdi;
732
733 /* get pending sort direction for clicked column */
734 hdi.mask = HDI_LPARAM;
735 (void)Header_GetItem(Info->hHeader, pnmv->iSubItem, &hdi);
736
737 /* get new sort parameters */
738 Info->SortSelection = pnmv->iSubItem;
739 Info->SortDirection = hdi.lParam;
740
741 /* set new sort direction and save */
742 hdi.lParam = (hdi.lParam == ORD_ASCENDING) ?
743 ORD_DESCENDING : ORD_ASCENDING;
744
745 (void)Header_SetItem(Info->hHeader, pnmv->iSubItem, &hdi);
746
747 (void)ListView_SortItemsEx(Info->hListView,
748 CompareFunc,
749 (LPARAM)Info);
750 }
751 break;
752 case LVN_ITEMCHANGED:
753 {
754 LPNMLISTVIEW pnmv = (LPNMLISTVIEW) lParam;
755
756 if (pnmv->uNewState != 0)
757 {
758 ListViewSelectionChanged(Info, pnmv);
759 SetMenuAndButtonStates(Info);
760 }
761 }
762 break;
763
764 case TTN_GETDISPINFO:
765 {
766 LPTOOLTIPTEXT lpttt;
767 UINT idButton;
768
769 lpttt = (LPTOOLTIPTEXT)lParam;
770
771 /* Specify the resource identifier of the descriptive
772 * text for the given button. */
773 idButton = (UINT)lpttt->hdr.idFrom;
774 switch (idButton)
775 {
776 case ID_PROP:
777 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_PROP);
778 break;
779
780 case ID_REFRESH:
781 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_REFRESH);
782 break;
783
784 case ID_EXPORT:
785 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_EXPORT);
786 break;
787
788 case ID_CREATE:
789 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_CREATE);
790 break;
791
792 case ID_DELETE:
793 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_DELETE);
794 break;
795
796 case ID_START:
797 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_START);
798 break;
799
800 case ID_STOP:
801 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_STOP);
802 break;
803
804 case ID_PAUSE:
805 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_PAUSE);
806 break;
807
808 case ID_RESTART:
809 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_RESTART);
810 break;
811 }
812 }
813 break;
814 }
815 }
816 break;
817
818 case WM_CONTEXTMENU:
819 {
820 POINT pt;
821 RECT lvRect;
822
823 INT xPos = GET_X_LPARAM(lParam);
824 INT yPos = GET_Y_LPARAM(lParam);
825
826 GetCursorPos(&pt);
827
828 /* display popup when cursor is in the list view */
829 GetWindowRect(Info->hListView, &lvRect);
830 if (PtInRect(&lvRect, pt))
831 {
832 TrackPopupMenuEx(GetSubMenu(Info->hShortcutMenu, 0),
833 TPM_RIGHTBUTTON,
834 xPos,
835 yPos,
836 Info->hMainWnd,
837 NULL);
838 }
839 }
840 break;
841
842 case WM_COMMAND:
843 {
844 MainWndCommand(Info,
845 LOWORD(wParam),
846 (HWND)lParam);
847 goto HandleDefaultMessage;
848 }
849
850 case WM_MENUSELECT:
851 {
852 if (Info->hStatus != NULL)
853 {
854 if (!MainWndMenuHint(Info,
855 LOWORD(wParam),
856 MainMenuHintTable,
857 sizeof(MainMenuHintTable) / sizeof(MainMenuHintTable[0]),
858 IDS_HINT_BLANK))
859 {
860 MainWndMenuHint(Info,
861 LOWORD(wParam),
862 SystemMenuHintTable,
863 sizeof(SystemMenuHintTable) / sizeof(SystemMenuHintTable[0]),
864 IDS_HINT_BLANK);
865 }
866 }
867 }
868 break;
869
870 case WM_ENTERMENULOOP:
871 {
872 Info->bInMenuLoop = TRUE;
873 UpdateMainStatusBar(Info);
874 break;
875 }
876
877 case WM_EXITMENULOOP:
878 {
879 Info->bInMenuLoop = FALSE;
880 UpdateMainStatusBar(Info);
881 break;
882 }
883
884 case WM_CLOSE:
885 {
886 FreeServiceList(Info);
887 DestroyMenu(Info->hShortcutMenu);
888 DestroyWindow(hwnd);
889 }
890 break;
891
892 case WM_DESTROY:
893 {
894 HeapFree(ProcessHeap,
895 0,
896 Info);
897 SetWindowLongPtr(hwnd,
898 GWLP_USERDATA,
899 0);
900
901 PostQuitMessage(0);
902 }
903 break;
904
905 default:
906 {
907 HandleDefaultMessage:
908
909 Ret = DefWindowProc(hwnd,
910 msg,
911 wParam,
912 lParam);
913 }
914 break;
915 }
916
917 return Ret;
918 }
919
920
921
922 HWND
CreateMainWindow(LPCTSTR lpCaption,int nCmdShow)923 CreateMainWindow(LPCTSTR lpCaption,
924 int nCmdShow)
925 {
926 PMAIN_WND_INFO Info;
927 HWND hMainWnd = NULL;
928
929 Info = (MAIN_WND_INFO*) HeapAlloc(ProcessHeap,
930 HEAP_ZERO_MEMORY,
931 sizeof(MAIN_WND_INFO));
932
933 if (Info != NULL)
934 {
935 Info->nCmdShow = nCmdShow;
936
937 hMainWnd = CreateWindowEx(WS_EX_WINDOWEDGE,
938 szMainWndClass,
939 lpCaption,
940 WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
941 CW_USEDEFAULT,
942 CW_USEDEFAULT,
943 680,
944 450,
945 NULL,
946 NULL,
947 hInstance,
948 Info);
949 if (hMainWnd == NULL)
950 {
951 //int ret;
952 //ret = GetLastError();
953 GetError();
954 HeapFree(ProcessHeap,
955 0,
956 Info);
957 }
958 }
959
960 return hMainWnd;
961 }
962
963 BOOL
InitMainWindowImpl(VOID)964 InitMainWindowImpl(VOID)
965 {
966 WNDCLASSEX wc = {0};
967
968 wc.cbSize = sizeof(WNDCLASSEX);
969 wc.lpfnWndProc = MainWndProc;
970 wc.hInstance = hInstance;
971 wc.hIcon = LoadIcon(hInstance,
972 MAKEINTRESOURCE(IDI_SM_ICON));
973 wc.hCursor = LoadCursor(NULL,
974 IDC_ARROW);
975 wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
976 wc.lpszMenuName = MAKEINTRESOURCE(IDR_MAINMENU);
977 wc.lpszClassName = szMainWndClass;
978 wc.hIconSm = (HICON)LoadImage(hInstance,
979 MAKEINTRESOURCE(IDI_SM_ICON),
980 IMAGE_ICON,
981 16,
982 16,
983 LR_SHARED);
984
985 return RegisterClassEx(&wc) != (ATOM)0;
986 }
987
988
989 VOID
UninitMainWindowImpl(VOID)990 UninitMainWindowImpl(VOID)
991 {
992 UnregisterClass(szMainWndClass,
993 hInstance);
994 }
995