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 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 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 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 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 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 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 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 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 379 MainWndCommand(PMAIN_WND_INFO Info, 380 WORD CmdId, 381 HWND hControl) 382 { 383 WCHAR szAppName[256]; 384 WCHAR szAppAuthors[256]; 385 HICON hIcon; 386 387 UNREFERENCED_PARAMETER(hControl); 388 389 switch (CmdId) 390 { 391 case ID_PROP: 392 { 393 if (Info->SelectedItem != NO_ITEM_SELECTED) 394 { 395 Info->bDlgOpen = TRUE; 396 OpenPropSheet(Info); 397 Info->bDlgOpen = FALSE; 398 SetMenuAndButtonStates(Info); 399 } 400 } 401 break; 402 403 case ID_REFRESH: 404 { 405 RefreshServiceList(Info); 406 Info->SelectedItem = NO_ITEM_SELECTED; 407 408 /* disable menus and buttons */ 409 SetMenuAndButtonStates(Info); 410 411 /* clear the service in the status bar */ 412 SendMessage(Info->hStatus, 413 SB_SETTEXT, 414 1, 415 L'\0'); 416 } 417 break; 418 419 case ID_EXPORT: 420 { 421 ExportFile(Info); 422 SetFocus(Info->hListView); 423 } 424 break; 425 426 case ID_CREATE: 427 { 428 INT ret; 429 430 ret = DialogBoxParam(hInstance, 431 MAKEINTRESOURCE(IDD_DLG_CREATE), 432 Info->hMainWnd, 433 CreateDialogProc, 434 (LPARAM)Info); 435 if (ret == IDOK) 436 RefreshServiceList(Info); 437 438 SetFocus(Info->hListView); 439 } 440 break; 441 442 case ID_DELETE: 443 { 444 if (Info->pCurrentService->ServiceStatusProcess.dwCurrentState != SERVICE_RUNNING) 445 { 446 DialogBoxParam(hInstance, 447 MAKEINTRESOURCE(IDD_DLG_DELETE), 448 Info->hMainWnd, 449 DeleteDialogProc, 450 (LPARAM)Info); 451 } 452 else 453 { 454 WCHAR Buf[60]; 455 LoadString(hInstance, 456 IDS_DELETE_STOP, 457 Buf, 458 sizeof(Buf) / sizeof(WCHAR)); 459 DisplayString(Buf); 460 } 461 462 SetFocus(Info->hListView); 463 464 } 465 break; 466 467 case ID_START: 468 { 469 RunActionWithProgress(Info->hMainWnd, 470 Info->pCurrentService->lpServiceName, 471 Info->pCurrentService->lpDisplayName, 472 ACTION_START, 473 NULL); //FIXME: Add start params 474 475 UpdateServiceStatus(Info->pCurrentService); 476 ChangeListViewText(Info, Info->pCurrentService, LVSTATUS); 477 SetMenuAndButtonStates(Info); 478 SetFocus(Info->hListView); 479 480 } 481 break; 482 483 case ID_STOP: 484 RunActionWithProgress(Info->hMainWnd, 485 Info->pCurrentService->lpServiceName, 486 Info->pCurrentService->lpDisplayName, 487 ACTION_STOP, 488 NULL); 489 490 UpdateServiceStatus(Info->pCurrentService); 491 ChangeListViewText(Info, Info->pCurrentService, LVSTATUS); 492 SetMenuAndButtonStates(Info); 493 SetFocus(Info->hListView); 494 495 break; 496 497 case ID_PAUSE: 498 RunActionWithProgress(Info->hMainWnd, 499 Info->pCurrentService->lpServiceName, 500 Info->pCurrentService->lpDisplayName, 501 ACTION_PAUSE, 502 NULL); 503 504 UpdateServiceStatus(Info->pCurrentService); 505 ChangeListViewText(Info, Info->pCurrentService, LVSTATUS); 506 SetMenuAndButtonStates(Info); 507 SetFocus(Info->hListView); 508 break; 509 510 case ID_RESUME: 511 RunActionWithProgress(Info->hMainWnd, 512 Info->pCurrentService->lpServiceName, 513 Info->pCurrentService->lpDisplayName, 514 ACTION_RESUME, 515 NULL); 516 517 UpdateServiceStatus(Info->pCurrentService); 518 ChangeListViewText(Info, Info->pCurrentService, LVSTATUS); 519 SetMenuAndButtonStates(Info); 520 SetFocus(Info->hListView); 521 break; 522 523 case ID_RESTART: 524 RunActionWithProgress(Info->hMainWnd, 525 Info->pCurrentService->lpServiceName, 526 Info->pCurrentService->lpDisplayName, 527 ACTION_RESTART, 528 NULL); 529 530 UpdateServiceStatus(Info->pCurrentService); 531 ChangeListViewText(Info, Info->pCurrentService, LVSTATUS); 532 SetMenuAndButtonStates(Info); 533 SetFocus(Info->hListView); 534 break; 535 536 case ID_HELP: 537 MessageBoxW(NULL, 538 L"Help is not yet implemented\n", 539 L"Note!", 540 MB_OK | MB_ICONINFORMATION); 541 SetFocus(Info->hListView); 542 break; 543 544 case ID_EXIT: 545 PostMessage(Info->hMainWnd, 546 WM_CLOSE, 547 0, 548 0); 549 break; 550 551 case ID_VIEW_LARGE: 552 SetListViewStyle(Info->hListView, LVS_ICON); 553 ListView_Arrange(Info->hListView, LVA_DEFAULT); 554 555 CheckMenuRadioItem(GetMenu(Info->hMainWnd), 556 ID_VIEW_LARGE, 557 ID_VIEW_DETAILS, 558 ID_VIEW_LARGE, 559 MF_BYCOMMAND); 560 break; 561 562 case ID_VIEW_SMALL: 563 SetListViewStyle(Info->hListView, LVS_SMALLICON); 564 ListView_Arrange(Info->hListView, LVA_DEFAULT); 565 566 CheckMenuRadioItem(GetMenu(Info->hMainWnd), 567 ID_VIEW_LARGE, 568 ID_VIEW_DETAILS, 569 ID_VIEW_SMALL, 570 MF_BYCOMMAND); 571 break; 572 573 case ID_VIEW_LIST: 574 SetListViewStyle(Info->hListView, 575 LVS_LIST); 576 CheckMenuRadioItem(GetMenu(Info->hMainWnd), 577 ID_VIEW_LARGE, 578 ID_VIEW_DETAILS, 579 ID_VIEW_LIST, 580 MF_BYCOMMAND); 581 break; 582 583 case ID_VIEW_DETAILS: 584 SetListViewStyle(Info->hListView, 585 LVS_REPORT); 586 CheckMenuRadioItem(GetMenu(Info->hMainWnd), 587 ID_VIEW_LARGE, 588 ID_VIEW_DETAILS, 589 ID_VIEW_DETAILS, 590 MF_BYCOMMAND); 591 break; 592 593 case ID_VIEW_CUST: 594 break; 595 596 case ID_ABOUT: 597 LoadStringW(hInstance, IDS_APPNAME, szAppName, _countof(szAppName)); 598 LoadStringW(hInstance, IDS_APPAUTHORS, szAppAuthors, _countof(szAppAuthors)); 599 600 hIcon = LoadIconW(hInstance, MAKEINTRESOURCEW(IDI_SM_ICON)); 601 ShellAboutW(Info->hMainWnd, szAppName, szAppAuthors, hIcon); 602 DestroyIcon(hIcon); 603 break; 604 605 } 606 } 607 608 609 static VOID CALLBACK 610 MainWndResize(PMAIN_WND_INFO Info, 611 WORD cx, 612 WORD cy) 613 { 614 RECT rcClient, rcTool, rcStatus; 615 int lvHeight, iToolHeight, iStatusHeight; 616 617 /* Size toolbar and get height */ 618 SendMessage(Info->hTool, TB_AUTOSIZE, 0, 0); 619 GetWindowRect(Info->hTool, &rcTool); 620 iToolHeight = rcTool.bottom - rcTool.top; 621 622 /* Size status bar and get height */ 623 SendMessage(Info->hStatus, WM_SIZE, 0, 0); 624 GetWindowRect(Info->hStatus, &rcStatus); 625 iStatusHeight = rcStatus.bottom - rcStatus.top; 626 627 /* Calculate remaining height and size list view */ 628 GetClientRect(Info->hMainWnd, &rcClient); 629 lvHeight = rcClient.bottom - iToolHeight - iStatusHeight; 630 SetWindowPos(Info->hListView, 631 NULL, 632 0, 633 iToolHeight, 634 rcClient.right, 635 lvHeight, 636 SWP_NOZORDER); 637 } 638 639 640 static LRESULT CALLBACK 641 MainWndProc(HWND hwnd, 642 UINT msg, 643 WPARAM wParam, 644 LPARAM lParam) 645 { 646 PMAIN_WND_INFO Info; 647 LRESULT Ret = 0; 648 649 /* Get the window context */ 650 Info = (PMAIN_WND_INFO)GetWindowLongPtr(hwnd, 651 GWLP_USERDATA); 652 if (Info == NULL && msg != WM_CREATE) 653 { 654 goto HandleDefaultMessage; 655 } 656 657 switch(msg) 658 { 659 case WM_CREATE: 660 { 661 Info = (PMAIN_WND_INFO)(((LPCREATESTRUCT)lParam)->lpCreateParams); 662 663 /* Initialize the main window context */ 664 Info->hMainWnd = hwnd; 665 Info->SelectedItem = NO_ITEM_SELECTED; 666 667 SetWindowLongPtr(hwnd, 668 GWLP_USERDATA, 669 (LONG_PTR)Info); 670 671 if (!InitMainWnd(Info)) 672 return -1; 673 674 /* Fill the list-view before showing the main window */ 675 RefreshServiceList(Info); 676 677 /* Show the window */ 678 ShowWindow(hwnd, 679 Info->nCmdShow); 680 681 SetFocus(Info->hListView); 682 } 683 break; 684 685 case WM_SIZE: 686 { 687 MainWndResize(Info, 688 LOWORD(lParam), 689 HIWORD(lParam)); 690 } 691 break; 692 693 case WM_NOTIFY: 694 { 695 LPNMHDR pnmhdr = (LPNMHDR)lParam; 696 697 switch (pnmhdr->code) 698 { 699 case NM_DBLCLK: 700 { 701 POINT pt; 702 RECT rect; 703 704 GetCursorPos(&pt); 705 GetWindowRect(Info->hListView, &rect); 706 707 if (PtInRect(&rect, pt)) 708 { 709 SendMessage(hwnd, 710 WM_COMMAND, 711 //ID_PROP, 712 MAKEWPARAM((WORD)ID_PROP, (WORD)0), 713 0); 714 } 715 716 //OpenPropSheet(Info); 717 } 718 break; 719 720 case NM_RETURN: 721 { 722 SendMessage(hwnd, 723 WM_COMMAND, 724 //ID_PROP, 725 MAKEWPARAM((WORD)ID_PROP, (WORD)0), 726 0); 727 } 728 break; 729 730 case LVN_COLUMNCLICK: 731 { 732 LPNMLISTVIEW pnmv = (LPNMLISTVIEW) lParam; 733 HDITEM hdi; 734 735 /* get pending sort direction for clicked column */ 736 hdi.mask = HDI_LPARAM; 737 (void)Header_GetItem(Info->hHeader, pnmv->iSubItem, &hdi); 738 739 /* get new sort parameters */ 740 Info->SortSelection = pnmv->iSubItem; 741 Info->SortDirection = hdi.lParam; 742 743 /* set new sort direction and save */ 744 hdi.lParam = (hdi.lParam == ORD_ASCENDING) ? 745 ORD_DESCENDING : ORD_ASCENDING; 746 747 (void)Header_SetItem(Info->hHeader, pnmv->iSubItem, &hdi); 748 749 (void)ListView_SortItemsEx(Info->hListView, 750 CompareFunc, 751 (LPARAM)Info); 752 } 753 break; 754 case LVN_ITEMCHANGED: 755 { 756 LPNMLISTVIEW pnmv = (LPNMLISTVIEW) lParam; 757 758 if (pnmv->uNewState != 0) 759 { 760 ListViewSelectionChanged(Info, pnmv); 761 SetMenuAndButtonStates(Info); 762 } 763 } 764 break; 765 766 case TTN_GETDISPINFO: 767 { 768 LPTOOLTIPTEXT lpttt; 769 UINT idButton; 770 771 lpttt = (LPTOOLTIPTEXT)lParam; 772 773 /* Specify the resource identifier of the descriptive 774 * text for the given button. */ 775 idButton = (UINT)lpttt->hdr.idFrom; 776 switch (idButton) 777 { 778 case ID_PROP: 779 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_PROP); 780 break; 781 782 case ID_REFRESH: 783 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_REFRESH); 784 break; 785 786 case ID_EXPORT: 787 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_EXPORT); 788 break; 789 790 case ID_CREATE: 791 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_CREATE); 792 break; 793 794 case ID_DELETE: 795 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_DELETE); 796 break; 797 798 case ID_START: 799 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_START); 800 break; 801 802 case ID_STOP: 803 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_STOP); 804 break; 805 806 case ID_PAUSE: 807 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_PAUSE); 808 break; 809 810 case ID_RESTART: 811 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_RESTART); 812 break; 813 } 814 } 815 break; 816 } 817 } 818 break; 819 820 case WM_CONTEXTMENU: 821 { 822 POINT pt; 823 RECT lvRect; 824 825 INT xPos = GET_X_LPARAM(lParam); 826 INT yPos = GET_Y_LPARAM(lParam); 827 828 GetCursorPos(&pt); 829 830 /* display popup when cursor is in the list view */ 831 GetWindowRect(Info->hListView, &lvRect); 832 if (PtInRect(&lvRect, pt)) 833 { 834 TrackPopupMenuEx(GetSubMenu(Info->hShortcutMenu, 0), 835 TPM_RIGHTBUTTON, 836 xPos, 837 yPos, 838 Info->hMainWnd, 839 NULL); 840 } 841 } 842 break; 843 844 case WM_COMMAND: 845 { 846 MainWndCommand(Info, 847 LOWORD(wParam), 848 (HWND)lParam); 849 goto HandleDefaultMessage; 850 } 851 852 case WM_MENUSELECT: 853 { 854 if (Info->hStatus != NULL) 855 { 856 if (!MainWndMenuHint(Info, 857 LOWORD(wParam), 858 MainMenuHintTable, 859 sizeof(MainMenuHintTable) / sizeof(MainMenuHintTable[0]), 860 IDS_HINT_BLANK)) 861 { 862 MainWndMenuHint(Info, 863 LOWORD(wParam), 864 SystemMenuHintTable, 865 sizeof(SystemMenuHintTable) / sizeof(SystemMenuHintTable[0]), 866 IDS_HINT_BLANK); 867 } 868 } 869 } 870 break; 871 872 case WM_ENTERMENULOOP: 873 { 874 Info->bInMenuLoop = TRUE; 875 UpdateMainStatusBar(Info); 876 break; 877 } 878 879 case WM_EXITMENULOOP: 880 { 881 Info->bInMenuLoop = FALSE; 882 UpdateMainStatusBar(Info); 883 break; 884 } 885 886 case WM_CLOSE: 887 { 888 FreeServiceList(Info); 889 DestroyMenu(Info->hShortcutMenu); 890 DestroyWindow(hwnd); 891 } 892 break; 893 894 case WM_DESTROY: 895 { 896 HeapFree(ProcessHeap, 897 0, 898 Info); 899 SetWindowLongPtr(hwnd, 900 GWLP_USERDATA, 901 0); 902 903 PostQuitMessage(0); 904 } 905 break; 906 907 default: 908 { 909 HandleDefaultMessage: 910 911 Ret = DefWindowProc(hwnd, 912 msg, 913 wParam, 914 lParam); 915 } 916 break; 917 } 918 919 return Ret; 920 } 921 922 923 924 HWND 925 CreateMainWindow(LPCTSTR lpCaption, 926 int nCmdShow) 927 { 928 PMAIN_WND_INFO Info; 929 HWND hMainWnd = NULL; 930 931 Info = (MAIN_WND_INFO*) HeapAlloc(ProcessHeap, 932 HEAP_ZERO_MEMORY, 933 sizeof(MAIN_WND_INFO)); 934 935 if (Info != NULL) 936 { 937 Info->nCmdShow = nCmdShow; 938 939 hMainWnd = CreateWindowEx(WS_EX_WINDOWEDGE, 940 szMainWndClass, 941 lpCaption, 942 WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 943 CW_USEDEFAULT, 944 CW_USEDEFAULT, 945 680, 946 450, 947 NULL, 948 NULL, 949 hInstance, 950 Info); 951 if (hMainWnd == NULL) 952 { 953 //int ret; 954 //ret = GetLastError(); 955 GetError(); 956 HeapFree(ProcessHeap, 957 0, 958 Info); 959 } 960 } 961 962 return hMainWnd; 963 } 964 965 BOOL 966 InitMainWindowImpl(VOID) 967 { 968 WNDCLASSEX wc = {0}; 969 970 wc.cbSize = sizeof(WNDCLASSEX); 971 wc.lpfnWndProc = MainWndProc; 972 wc.hInstance = hInstance; 973 wc.hIcon = LoadIcon(hInstance, 974 MAKEINTRESOURCE(IDI_SM_ICON)); 975 wc.hCursor = LoadCursor(NULL, 976 IDC_ARROW); 977 wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); 978 wc.lpszMenuName = MAKEINTRESOURCE(IDR_MAINMENU); 979 wc.lpszClassName = szMainWndClass; 980 wc.hIconSm = (HICON)LoadImage(hInstance, 981 MAKEINTRESOURCE(IDI_SM_ICON), 982 IMAGE_ICON, 983 16, 984 16, 985 LR_SHARED); 986 987 return RegisterClassEx(&wc) != (ATOM)0; 988 } 989 990 991 VOID 992 UninitMainWindowImpl(VOID) 993 { 994 UnregisterClass(szMainWndClass, 995 hInstance); 996 } 997