diff --git a/dll/win32/msgina/shutdown.c b/dll/win32/msgina/shutdown.c new file mode 100644 index 00000000000..96f22b8604d --- /dev/null +++ b/dll/win32/msgina/shutdown.c @@ -0,0 +1,272 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS msgina.dll + * FILE: lib/msgina/shutdown.c + * PURPOSE: Shutdown Dialog Box + * PROGRAMMER: Lee Schroeder (spaceseel at gmail dot com) + * UPDATE HISTORY: + * 24-11-2003 Created + */ + +#include "msgina.h" +#include +#include +#include +#include + +int g_shutdownCode = 0; +BOOL g_logoffHideState = FALSE; + +VOID UpdateShutdownShellDesc(HWND hwnd) +{ + WCHAR tmpBuffer[256]; + UINT shutdownDescId = 0; + HWND shutdownHwnd = GetDlgItem(hwnd, IDC_SHUTDOWN_DESCRIPTION); + int shutdownCode = 0; + + shutdownCode = SendDlgItemMessageW(hwnd, IDC_SHUTDOWN_LIST, CB_GETCURSEL, 0, 0); + + if(!g_logoffHideState) + { + switch (shutdownCode) + { + case 0: /* Log off */ + shutdownDescId = IDS_SHUTDOWN_LOGOFF_DESC; + break; + case 1: /* Shut down */ + shutdownDescId = IDS_SHUTDOWN_SHUTDOWN_DESC; + break; + case 2: /* Restart */ + shutdownDescId = IDS_SHUTDOWN_RESTART_DESC; + break; + default: + break; + } + + if (IsPwrSuspendAllowed()) + { + if (shutdownCode == 3) /* Sleep */ + { + shutdownDescId = IDS_SHUTDOWN_SLEEP_DESC; + } + else if (shutdownCode == 4) /* Hibernate */ + { + shutdownDescId = IDS_SHUTDOWN_HIBERNATE_DESC; + } + } + else + { + if (shutdownCode == 3) /* Hibernate */ + { + shutdownDescId = IDS_SHUTDOWN_SLEEP_DESC; + } + } + } + else + { + switch (shutdownCode) + { + case 0: /* Shut down */ + shutdownDescId = IDS_SHUTDOWN_SHUTDOWN_DESC; + break; + case 1: /* Restart */ + shutdownDescId = IDS_SHUTDOWN_RESTART_DESC; + break; + default: + break; + } + + if (IsPwrSuspendAllowed()) + { + if (shutdownCode == 2) /* Sleep */ + { + shutdownDescId = IDS_SHUTDOWN_SLEEP_DESC; + } + else if (shutdownCode == 3) /* Hibernate */ + { + shutdownDescId = IDS_SHUTDOWN_HIBERNATE_DESC; + } + } + else + { + if (shutdownCode == 2) /* Hibernate */ + { + shutdownDescId = IDS_SHUTDOWN_SLEEP_DESC; + } + } + } + + LoadStringW(hDllInstance, shutdownDescId, tmpBuffer, sizeof(tmpBuffer)); + SetWindowTextW(shutdownHwnd, tmpBuffer); +} + +BOOL CALLBACK ExitWindowsDialogShellProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) +{ + PGINA_CONTEXT pgContext; + + pgContext = (PGINA_CONTEXT)GetWindowLongPtr(hwnd, GWL_USERDATA); + + switch (Message) + { + case WM_INITDIALOG: + { + int defSelect = 0; + WCHAR userBuffer[256]; + DWORD userBufferSize = _countof(userBuffer); + WCHAR tmpBuffer[256]; + WCHAR tmpBuffer2[512]; + + pgContext = (PGINA_CONTEXT)lParam; + SetWindowLongPtr(hwnd, GWL_USERDATA, (DWORD_PTR)pgContext); + + /* Clears the content before it's used */ + SendDlgItemMessageW(hwnd, IDC_SHUTDOWN_LIST, CB_RESETCONTENT, 0, 0); + + if(!g_logoffHideState) + { + /* Log off */ + LoadStringW(hDllInstance, IDS_SHUTDOWN_LOGOFF, tmpBuffer, sizeof(tmpBuffer)/sizeof(WCHAR)); + GetUserNameW(userBuffer, &userBufferSize); + StringCchPrintfW(tmpBuffer2, 512, tmpBuffer, userBuffer); + SendDlgItemMessageW(hwnd, IDC_SHUTDOWN_LIST, CB_ADDSTRING, 0, (LPARAM)tmpBuffer2); + } + + /* Shut down - DEFAULT */ + LoadStringW(hDllInstance, IDS_SHUTDOWN_SHUTDOWN, tmpBuffer, sizeof(tmpBuffer)/sizeof(WCHAR)); + defSelect = SendDlgItemMessageW(hwnd, IDC_SHUTDOWN_LIST, CB_ADDSTRING, 0, (LPARAM)tmpBuffer); + + /* Restart */ + LoadStringW(hDllInstance, IDS_SHUTDOWN_RESTART, tmpBuffer, sizeof(tmpBuffer)/sizeof(WCHAR)); + SendDlgItemMessageW(hwnd, IDC_SHUTDOWN_LIST, CB_ADDSTRING, 0, (LPARAM)tmpBuffer); + + /* Sleep */ + if (IsPwrSuspendAllowed()) + { + LoadStringW(hDllInstance, IDS_SHUTDOWN_SLEEP, tmpBuffer, sizeof(tmpBuffer)/sizeof(WCHAR)); + SendDlgItemMessageW(hwnd, IDC_SHUTDOWN_LIST, CB_ADDSTRING, 0, (LPARAM)tmpBuffer); + } + + /* Hibernate */ + if (IsPwrHibernateAllowed()) + { + LoadStringW(hDllInstance, IDS_SHUTDOWN_HIBERNATE, tmpBuffer, sizeof(tmpBuffer)/sizeof(WCHAR)); + SendDlgItemMessageW(hwnd, IDC_SHUTDOWN_LIST, CB_ADDSTRING, 0, (LPARAM)tmpBuffer); + } + + /* Sets the default shut down selection */ + SendDlgItemMessageW(hwnd, IDC_SHUTDOWN_LIST, CB_SETCURSEL, defSelect, 0); + + /* Updates the choice description based on the current selection */ + UpdateShutdownShellDesc(hwnd); + + /* Draw the logo graphic */ + pgContext->hBitmap = LoadImage(hDllInstance, MAKEINTRESOURCE(IDI_ROSLOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); + + return TRUE; + } + case WM_PAINT: + { + PAINTSTRUCT ps; + HDC hdc; + if (pgContext->hBitmap) + { + hdc = BeginPaint(hwnd, &ps); + DrawStateW(hdc, NULL, NULL, (LPARAM)pgContext->hBitmap, (WPARAM)0, 0, 0, 0, 0, DST_BITMAP); + EndPaint(hwnd, &ps); + } + return TRUE; + } + case WM_DESTROY: + { + DeleteObject(pgContext->hBitmap); + return TRUE; + } + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDOK: + g_shutdownCode = SendDlgItemMessageW(hwnd, IDC_SHUTDOWN_LIST, CB_GETCURSEL, (WPARAM)0, (LPARAM)0); + EndDialog(hwnd, IDOK); + break; + case IDCANCEL: + EndDialog(hwnd, IDCANCEL); + break; + case IDHELP: + EndDialog(hwnd, IDHELP); + break; + case IDC_SHUTDOWN_LIST: + UpdateShutdownShellDesc(hwnd); + break; + } + break; + default: + return FALSE; + } + return TRUE; +} + +/* + * NOTES: + * - Based upon observations on the ShellShutdownDialog() function, the function doesn't actually + * do anything except show a dialog box and returning a value based upon the value chosen. That + * means that any code that calls the function has to execute the chosen action (shut down, + * restart, etc.). + * - When this function is called in Windows XP, it shows the classic dialog box regardless if + * SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\LogonType is enabled or not. + * - When the Help button is pushed, it sends the same return value as IDCANCEL (0x00), but + * at the same time, it calls the help file directly from the dialog box. + * - When the dialog is created, it doesn't disable all other input from the other windows. + * This is done elsewhere. When running the function ShellShutdownDialog() from XP/2K3, if the user clicks + * out of the window, it automatically closes itself. + * - The parameter, lpUsername never seems to be used when calling the function from Windows XP. Either + * it was a parameter that was never used in the final version before release, or it has a use that + * is currently not known. + */ +DWORD WINAPI +ShellShutdownDialog( + HWND hParent, + LPWSTR lpUsername, + BOOL bHideLogoff) +{ + int dlgValue = 0; + + g_logoffHideState = bHideLogoff; + + UNREFERENCED_PARAMETER(lpUsername); + + // Loads the shut down dialog box + dlgValue = DialogBox(hDllInstance, + MAKEINTRESOURCE(IDD_SHUTDOWN_SHELL), + hParent, + ExitWindowsDialogShellProc); + + // Determines what to do based on user selection + if (dlgValue == IDOK) + { + switch (g_shutdownCode) + { + case 0: /* Log off */ + return 0x01; + case 1: /* Shut down */ + return 0x02; + case 2: /* Reboot */ + return 0x04; + case 3: /* Sleep */ + return 0x10; + case 4: /* Hibernate */ + return 0x40; + } + } + /* Help file is called directly here */ + else if (dlgValue == IDHELP) + { + FIXME("Help is not implemented yet."); + MessageBoxW(hParent, L"Help is not implemented yet.", L"Message", MB_OK | MB_ICONEXCLAMATION); + } + else if (dlgValue == -1) + { + ERR("Failed to create dialog\n"); + } + + return 0x00; +}