reactos/base/applications/mscutils/servman/mainwnd.c
2020-11-06 01:06:11 +01:00

997 lines
30 KiB
C

/*
* PROJECT: ReactOS Services
* LICENSE: GPL - See COPYING in the top level directory
* FILE: base/applications/mscutils/servman/mainwnd.c
* PURPOSE: Main window message handler
* COPYRIGHT: Copyright 2006-2017 Ged Murphy <gedmurphy@reactos.org>
*
*/
#include "precomp.h"
#include <windowsx.h>
#include <shellapi.h>
static const WCHAR szMainWndClass[] = L"ServManWndClass";
/* Toolbar buttons */
static const TBBUTTON Buttons [] =
{ /* iBitmap, idCommand, fsState, fsStyle, bReserved[2], dwData, iString */
{TBICON_PROP, ID_PROP, TBSTATE_INDETERMINATE, BTNS_BUTTON, {0}, 0, 0}, /* properties */
{TBICON_REFRESH, ID_REFRESH, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0}, /* refresh */
{TBICON_EXPORT, ID_EXPORT, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0}, /* export */
/* Note: First item for a separator is its width in pixels */
{15, 0, TBSTATE_ENABLED, BTNS_SEP, {0}, 0, 0}, /* separator */
{TBICON_CREATE, ID_CREATE, TBSTATE_INDETERMINATE, BTNS_BUTTON, {0}, 0, 0 }, /* create */
{TBICON_DELETE, ID_DELETE, TBSTATE_INDETERMINATE, BTNS_BUTTON, {0}, 0, 0 }, /* delete */
{15, 0, TBSTATE_ENABLED, BTNS_SEP, {0}, 0, 0}, /* separator */
{TBICON_START, ID_START, TBSTATE_INDETERMINATE, BTNS_BUTTON, {0}, 0, 0 }, /* start */
{TBICON_STOP, ID_STOP, TBSTATE_INDETERMINATE, BTNS_BUTTON, {0}, 0, 0 }, /* stop */
{TBICON_PAUSE, ID_PAUSE, TBSTATE_INDETERMINATE, BTNS_BUTTON, {0}, 0, 0 }, /* pause */
{TBICON_RESTART, ID_RESTART, TBSTATE_INDETERMINATE, BTNS_BUTTON, {0}, 0, 0 }, /* restart */
};
/* menu hints */
static const MENU_HINT MainMenuHintTable[] = {
/* File Menu */
{ID_EXPORT, IDS_HINT_EXPORT},
{ID_EXIT, IDS_HINT_EXIT},
/* Action Menu */
{ID_CONNECT, IDS_HINT_CONNECT},
{ID_START, IDS_HINT_START},
{ID_STOP, IDS_HINT_STOP},
{ID_PAUSE, IDS_HINT_PAUSE},
{ID_RESUME, IDS_HINT_RESUME},
{ID_RESTART, IDS_HINT_RESTART},
{ID_REFRESH, IDS_HINT_REFRESH},
{ID_EDIT, IDS_HINT_EDIT},
{ID_CREATE, IDS_HINT_CREATE},
{ID_DELETE, IDS_HINT_DELETE},
{ID_PROP, IDS_HINT_PROP},
/* View menu */
{ID_VIEW_LARGE, IDS_HINT_LARGE},
{ID_VIEW_SMALL, IDS_HINT_SMALL},
{ID_VIEW_LIST, IDS_HINT_LIST},
{ID_VIEW_DETAILS, IDS_HINT_DETAILS},
{ID_VIEW_CUST, IDS_HINT_CUST},
/* Help Menu */
{ID_HELP, IDS_HINT_HELP},
{ID_ABOUT, IDS_HINT_ABOUT}
};
/* system menu hints */
static const MENU_HINT SystemMenuHintTable[] = {
{SC_RESTORE, IDS_HINT_SYS_RESTORE},
{SC_MOVE, IDS_HINT_SYS_MOVE},
{SC_SIZE, IDS_HINT_SYS_SIZE},
{SC_MINIMIZE, IDS_HINT_SYS_MINIMIZE},
{SC_MAXIMIZE, IDS_HINT_SYS_MAXIMIZE},
{SC_CLOSE, IDS_HINT_SYS_CLOSE},
};
static BOOL
MainWndMenuHint(PMAIN_WND_INFO Info,
WORD CmdId,
const MENU_HINT *HintArray,
DWORD HintsCount,
UINT DefHintId)
{
BOOL Found = FALSE;
const MENU_HINT *LastHint;
UINT HintId = DefHintId;
LastHint = HintArray + HintsCount;
while (HintArray != LastHint)
{
if (HintArray->CmdId == CmdId)
{
HintId = HintArray->HintId;
Found = TRUE;
break;
}
HintArray++;
}
StatusBarLoadString(Info->hStatus,
SB_SIMPLEID,
hInstance,
HintId);
return Found;
}
static VOID
UpdateMainStatusBar(PMAIN_WND_INFO Info)
{
if (Info->hStatus != NULL)
{
SendMessage(Info->hStatus,
SB_SIMPLE,
(WPARAM)Info->bInMenuLoop,
0);
}
}
VOID
UpdateServiceCount(PMAIN_WND_INFO Info)
{
LPWSTR lpNumServices;
if (AllocAndLoadString(&lpNumServices,
hInstance,
IDS_NUM_SERVICES))
{
WCHAR szNumServices[32];
INT NumListedServ = ListView_GetItemCount(Info->hListView);
_snwprintf(szNumServices,
31,
lpNumServices,
NumListedServ);
SendMessage(Info->hStatus,
SB_SETTEXT,
0,
(LPARAM)szNumServices);
LocalFree(lpNumServices);
}
}
VOID SetMenuAndButtonStates(PMAIN_WND_INFO Info)
{
HMENU hMainMenu;
UINT i;
/* get handle to menu */
hMainMenu = GetMenu(Info->hMainWnd);
/* set all to greyed */
for (i = ID_START; i <= ID_RESTART; i++)
{
EnableMenuItem(hMainMenu, i, MF_GRAYED);
EnableMenuItem(GetSubMenu(Info->hShortcutMenu, 0), i, MF_GRAYED);
SendMessage(Info->hTool, TB_SETSTATE, i,
(LPARAM)MAKELONG(TBSTATE_INDETERMINATE, 0));
}
if (Info->SelectedItem != NO_ITEM_SELECTED)
{
LPQUERY_SERVICE_CONFIG lpServiceConfig = NULL;
DWORD Flags, State;
/* allow user to delete service */
if (Info->bIsUserAnAdmin)
{
SendMessage(Info->hTool, TB_SETSTATE, ID_DELETE,
(LPARAM)MAKELONG(TBSTATE_ENABLED, 0));
EnableMenuItem(hMainMenu, ID_DELETE, MF_ENABLED);
EnableMenuItem(GetSubMenu(Info->hShortcutMenu, 0), ID_DELETE, MF_ENABLED);
}
Flags = Info->pCurrentService->ServiceStatusProcess.dwControlsAccepted;
State = Info->pCurrentService->ServiceStatusProcess.dwCurrentState;
lpServiceConfig = GetServiceConfig(Info->pCurrentService->lpServiceName);
if (lpServiceConfig && lpServiceConfig->dwStartType != SERVICE_DISABLED)
{
if (State == SERVICE_STOPPED)
{
EnableMenuItem(hMainMenu, ID_START, MF_ENABLED);
EnableMenuItem(GetSubMenu(Info->hShortcutMenu, 0), ID_START, MF_ENABLED);
SendMessage(Info->hTool, TB_SETSTATE, ID_START,
(LPARAM)MAKELONG(TBSTATE_ENABLED, 0));
}
if ( (Flags & SERVICE_ACCEPT_STOP) && (State == SERVICE_RUNNING) )
{
EnableMenuItem(hMainMenu, ID_RESTART, MF_ENABLED);
EnableMenuItem(GetSubMenu(Info->hShortcutMenu, 0), ID_RESTART, MF_ENABLED);
SendMessage(Info->hTool, TB_SETSTATE, ID_RESTART,
(LPARAM)MAKELONG(TBSTATE_ENABLED, 0));
}
}
if(lpServiceConfig)
HeapFree(GetProcessHeap(), 0, lpServiceConfig);
if ( (Flags & SERVICE_ACCEPT_STOP) && (State == SERVICE_RUNNING) )
{
EnableMenuItem(hMainMenu, ID_STOP, MF_ENABLED);
EnableMenuItem(GetSubMenu(Info->hShortcutMenu, 0), ID_STOP, MF_ENABLED);
SendMessage(Info->hTool, TB_SETSTATE, ID_STOP,
(LPARAM)MAKELONG(TBSTATE_ENABLED, 0));
}
if ( (Flags & SERVICE_ACCEPT_PAUSE_CONTINUE) && (State == SERVICE_RUNNING) )
{
EnableMenuItem(hMainMenu, ID_PAUSE, MF_ENABLED);
EnableMenuItem(GetSubMenu(Info->hShortcutMenu, 0), ID_PAUSE, MF_ENABLED);
SendMessage(Info->hTool, TB_SETSTATE, ID_PAUSE,
(LPARAM)MAKELONG(TBSTATE_ENABLED, 0));
}
}
else
{
/* disable tools which rely on a selected service */
EnableMenuItem(hMainMenu, ID_PROP, MF_GRAYED);
EnableMenuItem(hMainMenu, ID_DELETE, MF_GRAYED);
EnableMenuItem(GetSubMenu(Info->hShortcutMenu, 0), ID_PROP, MF_GRAYED);
EnableMenuItem(GetSubMenu(Info->hShortcutMenu, 0), ID_DELETE, MF_GRAYED);
SendMessage(Info->hTool, TB_SETSTATE, ID_PROP,
(LPARAM)MAKELONG(TBSTATE_INDETERMINATE, 0));
SendMessage(Info->hTool, TB_SETSTATE, ID_DELETE,
(LPARAM)MAKELONG(TBSTATE_INDETERMINATE, 0));
}
}
static INT CALLBACK
CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
PMAIN_WND_INFO Info = (PMAIN_WND_INFO)lParamSort;
WCHAR Item1[256], Item2[256];
ListView_GetItemText(Info->hListView, lParam1, Info->SortSelection, Item1, sizeof(Item1) / sizeof(WCHAR));
ListView_GetItemText(Info->hListView, lParam2, Info->SortSelection, Item2, sizeof(Item2) / sizeof(WCHAR));
return wcscmp(Item1, Item2) * Info->SortDirection;
}
static BOOL
pCreateToolbar(PMAIN_WND_INFO Info)
{
INT numButtons = sizeof(Buttons) / sizeof(Buttons[0]);
Info->hTool = CreateWindowEx(0,
TOOLBARCLASSNAME,
NULL,
WS_CHILD | WS_VISIBLE | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS,
0, 0, 0, 0,
Info->hMainWnd,
0,
hInstance,
NULL);
if(Info->hTool != NULL)
{
HIMAGELIST hImageList;
SendMessage(Info->hTool,
TB_SETEXTENDEDSTYLE,
0,
TBSTYLE_EX_HIDECLIPPEDBUTTONS);
SendMessage(Info->hTool,
TB_BUTTONSTRUCTSIZE,
sizeof(Buttons[0]),
0);
hImageList = InitImageList(IDB_PROP,
IDB_RESTART,
GetSystemMetrics(SM_CXSMICON),
GetSystemMetrics(SM_CXSMICON),
IMAGE_BITMAP);
if (hImageList == NULL)
return FALSE;
ImageList_Destroy((HIMAGELIST)SendMessage(Info->hTool,
TB_SETIMAGELIST,
0,
(LPARAM)hImageList));
SendMessage(Info->hTool,
TB_ADDBUTTONS,
numButtons,
(LPARAM)Buttons);
return TRUE;
}
return FALSE;
}
static BOOL
CreateStatusBar(PMAIN_WND_INFO Info)
{
INT StatWidths[] = {130, -1}; /* widths of status bar */
Info->hStatus = CreateWindowEx(0,
STATUSCLASSNAME,
NULL,
WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP,
0, 0, 0, 0,
Info->hMainWnd,
(HMENU)IDC_STATUSBAR,
hInstance,
NULL);
if(Info->hStatus == NULL)
return FALSE;
SendMessage(Info->hStatus,
SB_SETPARTS,
sizeof(StatWidths) / sizeof(INT),
(LPARAM)StatWidths);
return TRUE;
}
static BOOL
InitMainWnd(PMAIN_WND_INFO Info)
{
if (!pCreateToolbar(Info))
{
DisplayString(L"error creating toolbar");
return FALSE;
}
if (!CreateListView(Info))
{
DisplayString(L"error creating list view");
return FALSE;
}
if (!CreateStatusBar(Info))
DisplayString(L"error creating status bar");
/* Create Popup Menu */
Info->hShortcutMenu = LoadMenu(hInstance,
MAKEINTRESOURCE(IDR_POPUP));
Info->bIsUserAnAdmin = TRUE;// IsUserAnAdmin();
if (Info->bIsUserAnAdmin)
{
HMENU hMainMenu = GetMenu(Info->hMainWnd);
SendMessage(Info->hTool,
TB_SETSTATE,
ID_CREATE,
(LPARAM)MAKELONG(TBSTATE_ENABLED, 0));
if (hMainMenu)
{
EnableMenuItem(hMainMenu,
ID_CREATE,
MF_ENABLED);
}
EnableMenuItem(GetSubMenu(Info->hShortcutMenu, 0),
ID_CREATE,
MF_ENABLED);
}
return TRUE;
}
static VOID
MainWndCommand(PMAIN_WND_INFO Info,
WORD CmdId,
HWND hControl)
{
WCHAR szAppName[256];
WCHAR szAppAuthors[256];
HICON hIcon;
UNREFERENCED_PARAMETER(hControl);
switch (CmdId)
{
case ID_PROP:
{
if (Info->SelectedItem != NO_ITEM_SELECTED)
{
Info->bDlgOpen = TRUE;
OpenPropSheet(Info);
Info->bDlgOpen = FALSE;
SetMenuAndButtonStates(Info);
}
}
break;
case ID_REFRESH:
{
RefreshServiceList(Info);
Info->SelectedItem = NO_ITEM_SELECTED;
/* disable menus and buttons */
SetMenuAndButtonStates(Info);
/* clear the service in the status bar */
SendMessage(Info->hStatus,
SB_SETTEXT,
1,
L'\0');
}
break;
case ID_EXPORT:
{
ExportFile(Info);
SetFocus(Info->hListView);
}
break;
case ID_CREATE:
{
INT ret;
ret = DialogBoxParam(hInstance,
MAKEINTRESOURCE(IDD_DLG_CREATE),
Info->hMainWnd,
CreateDialogProc,
(LPARAM)Info);
if (ret == IDOK)
RefreshServiceList(Info);
SetFocus(Info->hListView);
}
break;
case ID_DELETE:
{
if (Info->pCurrentService->ServiceStatusProcess.dwCurrentState != SERVICE_RUNNING)
{
DialogBoxParam(hInstance,
MAKEINTRESOURCE(IDD_DLG_DELETE),
Info->hMainWnd,
DeleteDialogProc,
(LPARAM)Info);
}
else
{
WCHAR Buf[60];
LoadString(hInstance,
IDS_DELETE_STOP,
Buf,
sizeof(Buf) / sizeof(WCHAR));
DisplayString(Buf);
}
SetFocus(Info->hListView);
}
break;
case ID_START:
{
RunActionWithProgress(Info->hMainWnd,
Info->pCurrentService->lpServiceName,
Info->pCurrentService->lpDisplayName,
ACTION_START,
NULL); //FIXME: Add start params
UpdateServiceStatus(Info->pCurrentService);
ChangeListViewText(Info, Info->pCurrentService, LVSTATUS);
SetMenuAndButtonStates(Info);
SetFocus(Info->hListView);
}
break;
case ID_STOP:
RunActionWithProgress(Info->hMainWnd,
Info->pCurrentService->lpServiceName,
Info->pCurrentService->lpDisplayName,
ACTION_STOP,
NULL);
UpdateServiceStatus(Info->pCurrentService);
ChangeListViewText(Info, Info->pCurrentService, LVSTATUS);
SetMenuAndButtonStates(Info);
SetFocus(Info->hListView);
break;
case ID_PAUSE:
RunActionWithProgress(Info->hMainWnd,
Info->pCurrentService->lpServiceName,
Info->pCurrentService->lpDisplayName,
ACTION_PAUSE,
NULL);
UpdateServiceStatus(Info->pCurrentService);
ChangeListViewText(Info, Info->pCurrentService, LVSTATUS);
SetMenuAndButtonStates(Info);
SetFocus(Info->hListView);
break;
case ID_RESUME:
RunActionWithProgress(Info->hMainWnd,
Info->pCurrentService->lpServiceName,
Info->pCurrentService->lpDisplayName,
ACTION_RESUME,
NULL);
UpdateServiceStatus(Info->pCurrentService);
ChangeListViewText(Info, Info->pCurrentService, LVSTATUS);
SetMenuAndButtonStates(Info);
SetFocus(Info->hListView);
break;
case ID_RESTART:
RunActionWithProgress(Info->hMainWnd,
Info->pCurrentService->lpServiceName,
Info->pCurrentService->lpDisplayName,
ACTION_RESTART,
NULL);
UpdateServiceStatus(Info->pCurrentService);
ChangeListViewText(Info, Info->pCurrentService, LVSTATUS);
SetMenuAndButtonStates(Info);
SetFocus(Info->hListView);
break;
case ID_HELP:
MessageBoxW(NULL,
L"Help is not yet implemented\n",
L"Note!",
MB_OK | MB_ICONINFORMATION);
SetFocus(Info->hListView);
break;
case ID_EXIT:
PostMessage(Info->hMainWnd,
WM_CLOSE,
0,
0);
break;
case ID_VIEW_LARGE:
SetListViewStyle(Info->hListView, LVS_ICON);
ListView_Arrange(Info->hListView, LVA_DEFAULT);
CheckMenuRadioItem(GetMenu(Info->hMainWnd),
ID_VIEW_LARGE,
ID_VIEW_DETAILS,
ID_VIEW_LARGE,
MF_BYCOMMAND);
break;
case ID_VIEW_SMALL:
SetListViewStyle(Info->hListView, LVS_SMALLICON);
ListView_Arrange(Info->hListView, LVA_DEFAULT);
CheckMenuRadioItem(GetMenu(Info->hMainWnd),
ID_VIEW_LARGE,
ID_VIEW_DETAILS,
ID_VIEW_SMALL,
MF_BYCOMMAND);
break;
case ID_VIEW_LIST:
SetListViewStyle(Info->hListView,
LVS_LIST);
CheckMenuRadioItem(GetMenu(Info->hMainWnd),
ID_VIEW_LARGE,
ID_VIEW_DETAILS,
ID_VIEW_LIST,
MF_BYCOMMAND);
break;
case ID_VIEW_DETAILS:
SetListViewStyle(Info->hListView,
LVS_REPORT);
CheckMenuRadioItem(GetMenu(Info->hMainWnd),
ID_VIEW_LARGE,
ID_VIEW_DETAILS,
ID_VIEW_DETAILS,
MF_BYCOMMAND);
break;
case ID_VIEW_CUST:
break;
case ID_ABOUT:
LoadStringW(hInstance, IDS_APPNAME, szAppName, _countof(szAppName));
LoadStringW(hInstance, IDS_APPAUTHORS, szAppAuthors, _countof(szAppAuthors));
hIcon = LoadIconW(hInstance, MAKEINTRESOURCEW(IDI_SM_ICON));
ShellAboutW(Info->hMainWnd, szAppName, szAppAuthors, hIcon);
DestroyIcon(hIcon);
break;
}
}
static VOID CALLBACK
MainWndResize(PMAIN_WND_INFO Info,
WORD cx,
WORD cy)
{
RECT rcClient, rcTool, rcStatus;
int lvHeight, iToolHeight, iStatusHeight;
/* Size toolbar and get height */
SendMessage(Info->hTool, TB_AUTOSIZE, 0, 0);
GetWindowRect(Info->hTool, &rcTool);
iToolHeight = rcTool.bottom - rcTool.top;
/* Size status bar and get height */
SendMessage(Info->hStatus, WM_SIZE, 0, 0);
GetWindowRect(Info->hStatus, &rcStatus);
iStatusHeight = rcStatus.bottom - rcStatus.top;
/* Calculate remaining height and size list view */
GetClientRect(Info->hMainWnd, &rcClient);
lvHeight = rcClient.bottom - iToolHeight - iStatusHeight;
SetWindowPos(Info->hListView,
NULL,
0,
iToolHeight,
rcClient.right,
lvHeight,
SWP_NOZORDER);
}
static LRESULT CALLBACK
MainWndProc(HWND hwnd,
UINT msg,
WPARAM wParam,
LPARAM lParam)
{
PMAIN_WND_INFO Info;
LRESULT Ret = 0;
/* Get the window context */
Info = (PMAIN_WND_INFO)GetWindowLongPtr(hwnd,
GWLP_USERDATA);
if (Info == NULL && msg != WM_CREATE)
{
goto HandleDefaultMessage;
}
switch(msg)
{
case WM_CREATE:
{
Info = (PMAIN_WND_INFO)(((LPCREATESTRUCT)lParam)->lpCreateParams);
/* Initialize the main window context */
Info->hMainWnd = hwnd;
Info->SelectedItem = NO_ITEM_SELECTED;
SetWindowLongPtr(hwnd,
GWLP_USERDATA,
(LONG_PTR)Info);
if (!InitMainWnd(Info))
return -1;
/* Fill the list-view before showing the main window */
RefreshServiceList(Info);
/* Show the window */
ShowWindow(hwnd,
Info->nCmdShow);
SetFocus(Info->hListView);
}
break;
case WM_SIZE:
{
MainWndResize(Info,
LOWORD(lParam),
HIWORD(lParam));
}
break;
case WM_NOTIFY:
{
LPNMHDR pnmhdr = (LPNMHDR)lParam;
switch (pnmhdr->code)
{
case NM_DBLCLK:
{
POINT pt;
RECT rect;
GetCursorPos(&pt);
GetWindowRect(Info->hListView, &rect);
if (PtInRect(&rect, pt))
{
SendMessage(hwnd,
WM_COMMAND,
//ID_PROP,
MAKEWPARAM((WORD)ID_PROP, (WORD)0),
0);
}
//OpenPropSheet(Info);
}
break;
case NM_RETURN:
{
SendMessage(hwnd,
WM_COMMAND,
//ID_PROP,
MAKEWPARAM((WORD)ID_PROP, (WORD)0),
0);
}
break;
case LVN_COLUMNCLICK:
{
LPNMLISTVIEW pnmv = (LPNMLISTVIEW) lParam;
HDITEM hdi;
/* get pending sort direction for clicked column */
hdi.mask = HDI_LPARAM;
(void)Header_GetItem(Info->hHeader, pnmv->iSubItem, &hdi);
/* get new sort parameters */
Info->SortSelection = pnmv->iSubItem;
Info->SortDirection = hdi.lParam;
/* set new sort direction and save */
hdi.lParam = (hdi.lParam == ORD_ASCENDING) ?
ORD_DESCENDING : ORD_ASCENDING;
(void)Header_SetItem(Info->hHeader, pnmv->iSubItem, &hdi);
(void)ListView_SortItemsEx(Info->hListView,
CompareFunc,
(LPARAM)Info);
}
break;
case LVN_ITEMCHANGED:
{
LPNMLISTVIEW pnmv = (LPNMLISTVIEW) lParam;
if (pnmv->uNewState != 0)
{
ListViewSelectionChanged(Info, pnmv);
SetMenuAndButtonStates(Info);
}
}
break;
case TTN_GETDISPINFO:
{
LPTOOLTIPTEXT lpttt;
UINT idButton;
lpttt = (LPTOOLTIPTEXT)lParam;
/* Specify the resource identifier of the descriptive
* text for the given button. */
idButton = (UINT)lpttt->hdr.idFrom;
switch (idButton)
{
case ID_PROP:
lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_PROP);
break;
case ID_REFRESH:
lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_REFRESH);
break;
case ID_EXPORT:
lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_EXPORT);
break;
case ID_CREATE:
lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_CREATE);
break;
case ID_DELETE:
lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_DELETE);
break;
case ID_START:
lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_START);
break;
case ID_STOP:
lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_STOP);
break;
case ID_PAUSE:
lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_PAUSE);
break;
case ID_RESTART:
lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_RESTART);
break;
}
}
break;
}
}
break;
case WM_CONTEXTMENU:
{
POINT pt;
RECT lvRect;
INT xPos = GET_X_LPARAM(lParam);
INT yPos = GET_Y_LPARAM(lParam);
GetCursorPos(&pt);
/* display popup when cursor is in the list view */
GetWindowRect(Info->hListView, &lvRect);
if (PtInRect(&lvRect, pt))
{
TrackPopupMenuEx(GetSubMenu(Info->hShortcutMenu, 0),
TPM_RIGHTBUTTON,
xPos,
yPos,
Info->hMainWnd,
NULL);
}
}
break;
case WM_COMMAND:
{
MainWndCommand(Info,
LOWORD(wParam),
(HWND)lParam);
goto HandleDefaultMessage;
}
case WM_MENUSELECT:
{
if (Info->hStatus != NULL)
{
if (!MainWndMenuHint(Info,
LOWORD(wParam),
MainMenuHintTable,
sizeof(MainMenuHintTable) / sizeof(MainMenuHintTable[0]),
IDS_HINT_BLANK))
{
MainWndMenuHint(Info,
LOWORD(wParam),
SystemMenuHintTable,
sizeof(SystemMenuHintTable) / sizeof(SystemMenuHintTable[0]),
IDS_HINT_BLANK);
}
}
}
break;
case WM_ENTERMENULOOP:
{
Info->bInMenuLoop = TRUE;
UpdateMainStatusBar(Info);
break;
}
case WM_EXITMENULOOP:
{
Info->bInMenuLoop = FALSE;
UpdateMainStatusBar(Info);
break;
}
case WM_CLOSE:
{
FreeServiceList(Info);
DestroyMenu(Info->hShortcutMenu);
DestroyWindow(hwnd);
}
break;
case WM_DESTROY:
{
HeapFree(ProcessHeap,
0,
Info);
SetWindowLongPtr(hwnd,
GWLP_USERDATA,
0);
PostQuitMessage(0);
}
break;
default:
{
HandleDefaultMessage:
Ret = DefWindowProc(hwnd,
msg,
wParam,
lParam);
}
break;
}
return Ret;
}
HWND
CreateMainWindow(LPCTSTR lpCaption,
int nCmdShow)
{
PMAIN_WND_INFO Info;
HWND hMainWnd = NULL;
Info = (MAIN_WND_INFO*) HeapAlloc(ProcessHeap,
HEAP_ZERO_MEMORY,
sizeof(MAIN_WND_INFO));
if (Info != NULL)
{
Info->nCmdShow = nCmdShow;
hMainWnd = CreateWindowEx(WS_EX_WINDOWEDGE,
szMainWndClass,
lpCaption,
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
CW_USEDEFAULT,
CW_USEDEFAULT,
680,
450,
NULL,
NULL,
hInstance,
Info);
if (hMainWnd == NULL)
{
//int ret;
//ret = GetLastError();
GetError();
HeapFree(ProcessHeap,
0,
Info);
}
}
return hMainWnd;
}
BOOL
InitMainWindowImpl(VOID)
{
WNDCLASSEX wc = {0};
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpfnWndProc = MainWndProc;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(hInstance,
MAKEINTRESOURCE(IDI_SM_ICON));
wc.hCursor = LoadCursor(NULL,
IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MAINMENU);
wc.lpszClassName = szMainWndClass;
wc.hIconSm = (HICON)LoadImage(hInstance,
MAKEINTRESOURCE(IDI_SM_ICON),
IMAGE_ICON,
16,
16,
LR_SHARED);
return RegisterClassEx(&wc) != (ATOM)0;
}
VOID
UninitMainWindowImpl(VOID)
{
UnregisterClass(szMainWndClass,
hInstance);
}