https://git.reactos.org/?p=reactos.git;a=commitdiff;h=79e4efe04e2b00ae6fbae…
commit 79e4efe04e2b00ae6fbae09657264a2ff23c3655
Author: Arnav Bhatt <arnavbhatt288(a)gmail.com>
AuthorDate: Fri Jul 14 12:02:40 2023 +0000
Commit: GitHub <noreply(a)github.com>
CommitDate: Fri Jul 14 15:02:40 2023 +0300
[MSGINA] Convert shutdown/logoff boxes back to modal dialog boxes (#5114)
- Convert all modeless dialog boxes back to modal dialog boxes.
- Use WM_TIMER to detect SHIFT key press instead, as you can't
directly intercept messages on modal dialog boxes.
- Remove some unused functions.
Fixes explorer crash on shutdown cancel. CORE-17749
---
dll/win32/msgina/resource.h | 16 +-
dll/win32/msgina/shutdown.c | 389 ++++++++++++----------------------
dll/win32/shell32/dialogs/dialogs.cpp | 134 ++++++------
3 files changed, 209 insertions(+), 330 deletions(-)
diff --git a/dll/win32/msgina/resource.h b/dll/win32/msgina/resource.h
index 7116ab5cbac..5020c6dfb7d 100644
--- a/dll/win32/msgina/resource.h
+++ b/dll/win32/msgina/resource.h
@@ -58,10 +58,10 @@
#define IDC_SHUTDOWN_STATIC 3004
#define IDC_RESTART_STATIC 3005
-#define IDC_BUTTON_HIBERNATE 1901
-#define IDC_BUTTON_SLEEP 1902
-#define IDC_BUTTON_SHUTDOWN 1903
-#define IDC_BUTTON_REBOOT 1904
+#define IDC_BUTTON_SHUTDOWN 1901
+#define IDC_BUTTON_REBOOT 1902
+#define IDC_BUTTON_SLEEP 1903
+#define IDC_BUTTON_HIBERNATE 1904
#define IDD_LEGALNOTICE 2100
#define IDC_LEGALNOTICE_TEXT 2101
@@ -111,14 +111,14 @@
#define IDS_INVALIDWORKSTATION 40023
#define IDS_ACCOUNTRESTRICTION 40024
-#define IDS_SHUTDOWN_SHUTDOWN 50000
-#define IDS_SHUTDOWN_LOGOFF 50001
+#define IDS_SHUTDOWN_LOGOFF 50000
+#define IDS_SHUTDOWN_SHUTDOWN 50001
#define IDS_SHUTDOWN_RESTART 50002
#define IDS_SHUTDOWN_SLEEP 50003
#define IDS_SHUTDOWN_HIBERNATE 50004
/* Shut down descriptions */
-#define IDS_SHUTDOWN_SHUTDOWN_DESC 50005
-#define IDS_SHUTDOWN_LOGOFF_DESC 50006
+#define IDS_SHUTDOWN_LOGOFF_DESC 50005
+#define IDS_SHUTDOWN_SHUTDOWN_DESC 50006
#define IDS_SHUTDOWN_RESTART_DESC 50007
#define IDS_SHUTDOWN_SLEEP_DESC 50008
#define IDS_SHUTDOWN_HIBERNATE_DESC 50009
diff --git a/dll/win32/msgina/shutdown.c b/dll/win32/msgina/shutdown.c
index 559b6c5b243..f2f5f3c2a01 100644
--- a/dll/win32/msgina/shutdown.c
+++ b/dll/win32/msgina/shutdown.c
@@ -48,11 +48,18 @@
#define BUTTON_SLEEP_FOCUSED (CY_BITMAP + BUTTON_SLEEP_PRESSED)
#define BUTTON_SLEEP_DISABLED (CY_BITMAP + BUTTON_SLEEP_FOCUSED)
+/* For bIsButtonHot */
+#define SHUTDOWN_BUTTON_HOT 0
+#define REBOOT_BUTTON_HOT 1
+#define SLEEP_BUTTON_HOT 2
+#define HIBERNATE_BUTTON_HOT 3
+
typedef struct _SHUTDOWN_DLG_CONTEXT
{
PGINA_CONTEXT pgContext;
HBITMAP hBitmap;
HBITMAP hImageStrip;
+ DWORD ShutdownDialogId;
DWORD ShutdownOptions;
HBRUSH hBrush;
HFONT hfFont;
@@ -61,7 +68,8 @@ typedef struct _SHUTDOWN_DLG_CONTEXT
BOOL bReasonUI;
BOOL bFriendlyUI;
BOOL bIsButtonHot[NUMBER_OF_BUTTONS];
- BOOL bIsDialogModal;
+ BOOL bTimer;
+ UINT_PTR iTimer;
WNDPROC OldButtonProc;
} SHUTDOWN_DLG_CONTEXT, *PSHUTDOWN_DLG_CONTEXT;
@@ -333,7 +341,7 @@ DrawIconOnOwnerDrawnButtons(
{
y = BUTTON_SHUTDOWN_PRESSED;
}
- else if (pContext->bIsButtonHot[0] || (pdis->itemState &
ODS_FOCUS))
+ else if (pContext->bIsButtonHot[SHUTDOWN_BUTTON_HOT] ||
(pdis->itemState & ODS_FOCUS))
{
y = BUTTON_SHUTDOWN_FOCUSED;
}
@@ -356,7 +364,7 @@ DrawIconOnOwnerDrawnButtons(
{
y = BUTTON_REBOOT_PRESSED;
}
- else if (pContext->bIsButtonHot[1] || (pdis->itemState &
ODS_FOCUS))
+ else if (pContext->bIsButtonHot[REBOOT_BUTTON_HOT] ||
(pdis->itemState & ODS_FOCUS))
{
y = BUTTON_REBOOT_FOCUSED;
}
@@ -384,8 +392,8 @@ DrawIconOnOwnerDrawnButtons(
{
y = BUTTON_SLEEP_PRESSED;
}
- else if ((pdis->CtlID == IDC_BUTTON_SLEEP &&
pContext->bIsButtonHot[2]) ||
- (pdis->CtlID == IDC_BUTTON_HIBERNATE &&
pContext->bIsButtonHot[3]) ||
+ else if ((pdis->CtlID == IDC_BUTTON_SLEEP &&
pContext->bIsButtonHot[SLEEP_BUTTON_HOT]) ||
+ (pdis->CtlID == IDC_BUTTON_HIBERNATE &&
pContext->bIsButtonHot[HIBERNATE_BUTTON_HOT]) ||
(pdis->itemState & ODS_FOCUS))
{
y = BUTTON_SLEEP_FOCUSED;
@@ -504,8 +512,7 @@ OwnerDrawButtonSubclass(
LPARAM lParam)
{
PSHUTDOWN_DLG_CONTEXT pContext;
- pContext = (PSHUTDOWN_DLG_CONTEXT)GetWindowLongPtrW(hButton, GWLP_USERDATA);
-
+ pContext = (PSHUTDOWN_DLG_CONTEXT)GetWindowLongPtrW(GetParent(hButton),
GWLP_USERDATA);
int buttonID = GetDlgCtrlID(hButton);
switch (uMsg)
@@ -520,19 +527,19 @@ OwnerDrawButtonSubclass(
SetCapture(hButton);
if (buttonID == IDC_BUTTON_SHUTDOWN)
{
- pContext->bIsButtonHot[0] = TRUE;
+ pContext->bIsButtonHot[SHUTDOWN_BUTTON_HOT] = TRUE;
}
else if (buttonID == IDC_BUTTON_REBOOT)
{
- pContext->bIsButtonHot[1] = TRUE;
+ pContext->bIsButtonHot[REBOOT_BUTTON_HOT] = TRUE;
}
else if (buttonID == IDC_BUTTON_SLEEP)
{
- pContext->bIsButtonHot[2] = TRUE;
+ pContext->bIsButtonHot[SLEEP_BUTTON_HOT] = TRUE;
}
else if (buttonID == IDC_BUTTON_HIBERNATE)
{
- pContext->bIsButtonHot[3] = TRUE;
+ pContext->bIsButtonHot[HIBERNATE_BUTTON_HOT] = TRUE;
}
SetCursor(LoadCursorW(NULL, MAKEINTRESOURCEW(IDC_HAND)));
}
@@ -545,19 +552,19 @@ OwnerDrawButtonSubclass(
ReleaseCapture();
if (buttonID == IDC_BUTTON_SHUTDOWN)
{
- pContext->bIsButtonHot[0] = FALSE;
+ pContext->bIsButtonHot[SHUTDOWN_BUTTON_HOT] = FALSE;
}
else if (buttonID == IDC_BUTTON_REBOOT)
{
- pContext->bIsButtonHot[1] = FALSE;
+ pContext->bIsButtonHot[REBOOT_BUTTON_HOT] = FALSE;
}
else if (buttonID == IDC_BUTTON_SLEEP)
{
- pContext->bIsButtonHot[2] = FALSE;
+ pContext->bIsButtonHot[SLEEP_BUTTON_HOT] = FALSE;
}
else if (buttonID == IDC_BUTTON_HIBERNATE)
{
- pContext->bIsButtonHot[3] = FALSE;
+ pContext->bIsButtonHot[HIBERNATE_BUTTON_HOT] = FALSE;
}
}
InvalidateRect(hButton, NULL, FALSE);
@@ -581,26 +588,6 @@ OwnerDrawButtonSubclass(
return CallWindowProcW(pContext->OldButtonProc, hButton, uMsg, wParam, lParam);
}
-VOID
-AddPrefixToStaticTexts(
- HWND hDlg,
- BOOL bIsSleepButtonReplaced)
-{
- WCHAR szBuffer[30];
-
- for (int i = 0; i < NUMBER_OF_BUTTONS; i++)
- {
- GetDlgItemTextW(hDlg, IDC_BUTTON_HIBERNATE + i, szBuffer, _countof(szBuffer));
- SetDlgItemTextW(hDlg, IDC_HIBERNATE_STATIC + i, szBuffer);
- }
-
- if (bIsSleepButtonReplaced)
- {
- GetDlgItemTextW(hDlg, IDC_BUTTON_HIBERNATE, szBuffer, _countof(szBuffer));
- SetDlgItemTextW(hDlg, IDC_SLEEP_STATIC, szBuffer);
- }
-}
-
VOID
CreateToolTipForButtons(
int controlID,
@@ -637,11 +624,33 @@ CreateToolTipForButtons(
}
VOID
-ReplaceRequiredButton(
+EndFriendlyDialog(
+ HWND hDlg,
+ PSHUTDOWN_DLG_CONTEXT pContext)
+{
+ if (pContext->bTimer)
+ {
+ KillTimer(hDlg, pContext->iTimer);
+ }
+
+ DeleteObject(pContext->hBitmap);
+ DeleteObject(pContext->hBrush);
+ DeleteObject(pContext->hImageStrip);
+ DeleteObject(pContext->hfFont);
+
+ /* Remove the subclass from the buttons */
+ for (int i = 0; i < NUMBER_OF_BUTTONS; i++)
+ {
+ SetWindowLongPtrW(GetDlgItem(hDlg, IDC_BUTTON_SHUTDOWN + i),
+ GWLP_WNDPROC,
+ (LONG_PTR)pContext->OldButtonProc);
+ }
+}
+
+VOID
+ChangeRequiredButton(
HWND hDlg,
- HINSTANCE hInstance,
- BOOL bIsAltKeyPressed,
- BOOL bIsSleepButtonReplaced)
+ PSHUTDOWN_DLG_CONTEXT pContext)
{
int destID = IDC_BUTTON_SLEEP;
int targetedID = IDC_BUTTON_HIBERNATE;
@@ -650,7 +659,7 @@ ReplaceRequiredButton(
WCHAR szBuffer[30];
/* If the sleep button has been already replaced earlier, bring sleep button back to
its original position */
- if (bIsSleepButtonReplaced)
+ if (pContext->bIsSleepButtonReplaced)
{
destID = IDC_BUTTON_HIBERNATE;
targetedID = IDC_BUTTON_SLEEP;
@@ -678,31 +687,35 @@ ReplaceRequiredButton(
ShowWindow(hwndTarget, SW_SHOW);
SetFocus(hwndTarget);
- if (bIsAltKeyPressed)
+ if (!pContext->bIsSleepButtonReplaced)
{
- if (!bIsSleepButtonReplaced)
- {
- GetDlgItemTextW(hDlg, IDC_BUTTON_HIBERNATE, szBuffer, _countof(szBuffer));
- SetDlgItemTextW(hDlg, IDC_SLEEP_STATIC, szBuffer);
- }
- else
- {
- GetDlgItemTextW(hDlg, IDC_BUTTON_SLEEP, szBuffer, _countof(szBuffer));
- SetDlgItemTextW(hDlg, IDC_SLEEP_STATIC, szBuffer);
- }
+ LoadStringW(pContext->pgContext->hDllInstance, IDS_SHUTDOWN_HIBERNATE,
szBuffer, _countof(szBuffer));
+ SetDlgItemTextW(hDlg, IDC_SLEEP_STATIC, szBuffer);
}
else
{
- if (!bIsSleepButtonReplaced)
- {
- LoadStringW(hInstance, IDS_SHUTDOWN_HIBERNATE, szBuffer,
_countof(szBuffer));
- SetDlgItemTextW(hDlg, IDC_SLEEP_STATIC, szBuffer);
- }
- else
- {
- LoadStringW(hInstance, IDS_SHUTDOWN_SLEEP, szBuffer, _countof(szBuffer));
- SetDlgItemTextW(hDlg, IDC_SLEEP_STATIC, szBuffer);
- }
+ LoadStringW(pContext->pgContext->hDllInstance, IDS_SHUTDOWN_SLEEP,
szBuffer, _countof(szBuffer));
+ SetDlgItemTextW(hDlg, IDC_SLEEP_STATIC, szBuffer);
+ }
+
+ InvalidateRect(hDlg, NULL, FALSE);
+}
+
+VOID OnTimer(
+ HWND hDlg,
+ PSHUTDOWN_DLG_CONTEXT pContext)
+{
+ BOOL ReplaceButton = !!(GetKeyState(VK_SHIFT) & 0x8000);
+
+ if (ReplaceButton && !pContext->bIsSleepButtonReplaced)
+ {
+ ChangeRequiredButton(hDlg, pContext);
+ pContext->bIsSleepButtonReplaced = TRUE;
+ }
+ else if (!ReplaceButton && pContext->bIsSleepButtonReplaced)
+ {
+ ChangeRequiredButton(hDlg, pContext);
+ pContext->bIsSleepButtonReplaced = FALSE;
}
}
@@ -836,15 +849,11 @@ UpdateShutdownDesc(
}
static VOID
-ShutdownOnInit(
+ShutdownOnFriendlyInit(
IN HWND hDlg,
IN PSHUTDOWN_DLG_CONTEXT pContext)
{
PGINA_CONTEXT pgContext = pContext->pgContext;
- HWND hwndList;
- INT idx, count, i;
- WCHAR szBuffer[256];
- WCHAR szBuffer2[256];
HDC hdc;
LONG lfHeight;
@@ -858,21 +867,61 @@ ShutdownOnInit(
/* Create a brush for static controls for fancy shut down dialog */
pContext->hBrush = CreateSolidBrush(DARK_GREY_COLOR);
+ /* Gather image strip */
pContext->hImageStrip = LoadBitmapW(pgContext->hDllInstance,
MAKEINTRESOURCEW(IDB_IMAGE_STRIP));
- hwndList = GetDlgItem(hDlg, IDC_SHUTDOWN_ACTION);
-
- /* Clear the content before it's used */
- SendMessageW(hwndList, CB_RESETCONTENT, 0, 0);
-
/* Set the boolean flags to false */
pContext->bIsSleepButtonReplaced = FALSE;
+ pContext->bTimer = FALSE;
+
+ EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_HIBERNATE), FALSE);
+ EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_SLEEP), IsPwrSuspendAllowed());
+
+ /* Gather old button func */
+ pContext->OldButtonProc = (WNDPROC)GetWindowLongPtrW(GetDlgItem(hDlg,
IDC_BUTTON_HIBERNATE), GWLP_WNDPROC);
+ /* Set bIsButtonHot to false, create tooltips for each buttons, make buttons to
remember pContext and subclass the buttons */
for (int i = 0; i < NUMBER_OF_BUTTONS; i++)
{
pContext->bIsButtonHot[i] = FALSE;
+ SetWindowLongPtrW(GetDlgItem(hDlg, IDC_BUTTON_SHUTDOWN + i),
+ GWLP_WNDPROC,
+ (LONG_PTR)OwnerDrawButtonSubclass);
+ CreateToolTipForButtons(IDC_BUTTON_SHUTDOWN + i,
+ IDS_SHUTDOWN_SHUTDOWN_DESC + i,
+ hDlg, IDS_SHUTDOWN_SHUTDOWN + i,
+ pContext->pgContext->hDllInstance);
}
+ if (pContext->ShutdownDialogId == IDD_SHUTDOWN_FANCY &&
IsPwrSuspendAllowed())
+ {
+ pContext->iTimer = SetTimer(hDlg, 0, 50, NULL);
+ pContext->bTimer = TRUE;
+ }
+}
+
+static VOID
+ShutdownOnInit(
+ IN HWND hDlg,
+ IN PSHUTDOWN_DLG_CONTEXT pContext)
+{
+ PGINA_CONTEXT pgContext = pContext->pgContext;
+ HWND hwndList;
+ INT idx, count, i;
+ WCHAR szBuffer[256];
+ WCHAR szBuffer2[256];
+
+ if (pContext->bFriendlyUI)
+ {
+ ShutdownOnFriendlyInit(hDlg, pContext);
+ return;
+ }
+
+ hwndList = GetDlgItem(hDlg, IDC_SHUTDOWN_ACTION);
+
+ /* Clear the content before it's used */
+ SendMessageW(hwndList, CB_RESETCONTENT, 0, 0);
+
/* Log off */
if (pContext->ShutdownOptions & WLX_SHUTDOWN_STATE_LOGOFF)
{
@@ -891,10 +940,6 @@ ShutdownOnInit(
if (idx != CB_ERR)
SendMessageW(hwndList, CB_SETITEMDATA, idx,
WLX_SAS_ACTION_SHUTDOWN_POWER_OFF);
}
- else if (pContext->bFriendlyUI)
- {
- EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_SHUTDOWN), FALSE);
- }
/* Restart */
if (pContext->ShutdownOptions & WLX_SHUTDOWN_STATE_REBOOT)
@@ -904,10 +949,6 @@ ShutdownOnInit(
if (idx != CB_ERR)
SendMessageW(hwndList, CB_SETITEMDATA, idx, WLX_SAS_ACTION_SHUTDOWN_REBOOT);
}
- else if (pContext->bFriendlyUI)
- {
- EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_REBOOT), FALSE);
- }
// if (pContext->ShutdownOptions & 0x08) {}
@@ -919,10 +960,6 @@ ShutdownOnInit(
if (idx != CB_ERR)
SendMessageW(hwndList, CB_SETITEMDATA, idx, WLX_SAS_ACTION_SHUTDOWN_SLEEP);
}
- else if (pContext->bFriendlyUI)
- {
- EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_SLEEP), IsPwrSuspendAllowed());
- }
// if (pContext->ShutdownOptions & 0x20) {}
@@ -934,10 +971,6 @@ ShutdownOnInit(
if (idx != CB_ERR)
SendMessageW(hwndList, CB_SETITEMDATA, idx,
WLX_SAS_ACTION_SHUTDOWN_HIBERNATE);
}
- else if (pContext->bFriendlyUI)
- {
- EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_HIBERNATE), FALSE);
- }
// if (pContext->ShutdownOptions & 0x80) {}
@@ -952,34 +985,6 @@ ShutdownOnInit(
}
}
- /* Create tool tips for the buttons of fancy log off dialog */
- CreateToolTipForButtons(IDC_BUTTON_HIBERNATE,
- IDS_SHUTDOWN_HIBERNATE_DESC,
- hDlg, IDS_SHUTDOWN_HIBERNATE,
- pContext->pgContext->hDllInstance);
- CreateToolTipForButtons(IDC_BUTTON_SHUTDOWN,
- IDS_SHUTDOWN_SHUTDOWN_DESC,
- hDlg, IDS_SHUTDOWN_SHUTDOWN,
- pContext->pgContext->hDllInstance);
- CreateToolTipForButtons(IDC_BUTTON_REBOOT,
- IDS_SHUTDOWN_RESTART_DESC,
- hDlg, IDS_SHUTDOWN_RESTART,
- pContext->pgContext->hDllInstance);
- CreateToolTipForButtons(IDC_BUTTON_SLEEP,
- IDS_SHUTDOWN_SLEEP_DESC,
- hDlg, IDS_SHUTDOWN_SLEEP,
- pContext->pgContext->hDllInstance);
-
- /* Gather old button func */
- pContext->OldButtonProc = (WNDPROC)GetWindowLongPtrW(GetDlgItem(hDlg,
IDC_BUTTON_HIBERNATE), GWLP_WNDPROC);
-
- /* Make buttons to remember pContext and subclass the buttons */
- for (int i = 0; i < NUMBER_OF_BUTTONS; i++)
- {
- SetWindowLongPtrW(GetDlgItem(hDlg, IDC_BUTTON_HIBERNATE + i), GWLP_USERDATA,
(LONG_PTR)pContext);
- SetWindowLongPtrW(GetDlgItem(hDlg, IDC_BUTTON_HIBERNATE + i), GWLP_WNDPROC,
(LONG_PTR)OwnerDrawButtonSubclass);
- }
-
/* Update the choice description based on the current selection */
UpdateShutdownDesc(hDlg, pContext);
}
@@ -1027,23 +1032,13 @@ ShutdownDialogProc(
SetWindowLongPtrW(hDlg, GWLP_USERDATA, (LONG_PTR)pContext);
ShutdownOnInit(hDlg, pContext);
-
- /* Draw the logo bitmap */
- pContext->hBitmap =
- LoadImageW(pContext->pgContext->hDllInstance,
MAKEINTRESOURCEW(IDI_ROSLOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
return TRUE;
}
case WM_DESTROY:
- DeleteObject(pContext->hBitmap);
- DeleteObject(pContext->hBrush);
- DeleteObject(pContext->hImageStrip);
- DeleteObject(pContext->hfFont);
-
- /* Remove the subclass from the buttons */
- for (int i = 0; i < NUMBER_OF_BUTTONS; i++)
+ if (pContext->bFriendlyUI)
{
- SetWindowLongPtrW(GetDlgItem(hDlg, IDC_BUTTON_HIBERNATE + i),
GWLP_WNDPROC, (LONG_PTR)pContext->OldButtonProc);
+ EndFriendlyDialog(hDlg, pContext);
}
return TRUE;
@@ -1059,45 +1054,15 @@ ShutdownDialogProc(
if (!pContext->bCloseDlg)
{
pContext->bCloseDlg = TRUE;
-
- if (pContext->bIsDialogModal)
- {
- EndDialog(hDlg, 0);
- }
- else
- {
- DestroyWindow(hDlg);
- PostQuitMessage(0);
- }
+ EndDialog(hDlg, IDCANCEL);
}
}
return FALSE;
}
- case WM_PAINT:
- {
- PAINTSTRUCT ps;
- if (pContext->hBitmap)
- {
- BeginPaint(hDlg, &ps);
- DrawStateW(ps.hdc, NULL, NULL, (LPARAM)pContext->hBitmap, (WPARAM)0,
0, 0, 0, 0, DST_BITMAP);
- EndPaint(hDlg, &ps);
- }
- return TRUE;
- }
-
case WM_CLOSE:
pContext->bCloseDlg = TRUE;
-
- if (pContext->bIsDialogModal)
- {
- EndDialog(hDlg, IDCANCEL);
- }
- else
- {
- DestroyWindow(hDlg);
- PostQuitMessage(IDCANCEL);
- }
+ EndDialog(hDlg, IDCANCEL);
break;
case WM_COMMAND:
@@ -1122,16 +1087,7 @@ ShutdownDialogProc(
case IDCANCEL:
case IDHELP:
pContext->bCloseDlg = TRUE;
-
- if (pContext->bIsDialogModal)
- {
- EndDialog(hDlg, LOWORD(wParam));
- }
- else
- {
- DestroyWindow(hDlg);
- PostQuitMessage(LOWORD(wParam));
- }
+ EndDialog(hDlg, LOWORD(wParam));
break;
case IDC_SHUTDOWN_ACTION:
@@ -1179,6 +1135,10 @@ ShutdownDialogProc(
break;
}
+ case WM_TIMER:
+ OnTimer(hDlg, pContext);
+ return TRUE;
+
default:
return FALSE;
}
@@ -1193,10 +1153,6 @@ ShutdownDialog(
{
INT_PTR ret;
SHUTDOWN_DLG_CONTEXT Context;
- BOOL bIsAltKeyPressed = FALSE;
- DWORD ShutdownDialogId = IDD_SHUTDOWN;
- MSG Msg;
- HWND hDlg;
#if 0
DWORD ShutdownOptions;
@@ -1208,13 +1164,13 @@ ShutdownDialog(
Context.pgContext = pgContext;
Context.ShutdownOptions = ShutdownOptions;
+ Context.ShutdownDialogId = IDD_SHUTDOWN;
Context.bCloseDlg = FALSE;
Context.bReasonUI = GetShutdownReasonUI();
Context.bFriendlyUI = ShellIsFriendlyUIActive();
if (pgContext->hWlx && pgContext->pWlxFuncs &&
!Context.bFriendlyUI)
{
- Context.bIsDialogModal = TRUE;
ret = pgContext->pWlxFuncs->WlxDialogBoxParam(pgContext->hWlx,
pgContext->hDllInstance,
MAKEINTRESOURCEW(Context.bReasonUI
? IDD_SHUTDOWN_REASON : IDD_SHUTDOWN),
@@ -1228,90 +1184,19 @@ ShutdownDialog(
{
if (IsShowHibernateButtonActive())
{
- ShutdownDialogId = IDD_SHUTDOWN_FANCY_LONG;
+ Context.ShutdownDialogId = IDD_SHUTDOWN_FANCY_LONG;
}
else
{
- ShutdownDialogId = IDD_SHUTDOWN_FANCY;
+ Context.ShutdownDialogId = IDD_SHUTDOWN_FANCY;
}
}
- Context.bIsDialogModal = FALSE;
- hDlg = CreateDialogParamW(pgContext->hDllInstance,
- MAKEINTRESOURCEW(Context.bReasonUI ?
IDD_SHUTDOWN_REASON : ShutdownDialogId),
- hwndDlg,
- ShutdownDialogProc,
- (LPARAM)&Context);
-
- ShowWindow(hDlg, SW_SHOW);
-
- /* Detect either Alt or Shift key have been pressed or released */
- while (GetMessageW(&Msg, NULL, 0, 0))
- {
- if (!IsDialogMessageW(hDlg, &Msg))
- {
- TranslateMessage(&Msg);
- DispatchMessageW(&Msg);
- }
-
- switch (Msg.message)
- {
- case WM_SYSKEYDOWN:
- {
- /* If the Alt key has been pressed once, add prefix to static
controls */
- if (Msg.wParam == VK_MENU && !bIsAltKeyPressed)
- {
- AddPrefixToStaticTexts(hDlg, Context.bIsSleepButtonReplaced);
- bIsAltKeyPressed = TRUE;
- }
- }
- break;
-
- case WM_KEYDOWN:
- {
- /*
- * If the Shift key has been pressed once, and both hibernate button
and sleep button are enabled
- * replace the sleep button with hibernate button
- */
- if (Msg.wParam == VK_SHIFT)
- {
- if (ShutdownDialogId == IDD_SHUTDOWN_FANCY &&
!Context.bIsSleepButtonReplaced)
- {
- if (IsPwrHibernateAllowed() &&
IsPwrSuspendAllowed())
- {
- ReplaceRequiredButton(hDlg,
- pgContext->hDllInstance,
- bIsAltKeyPressed,
- Context.bIsSleepButtonReplaced);
- Context.bIsSleepButtonReplaced = TRUE;
- }
- }
- }
- }
- break;
-
- case WM_KEYUP:
- {
- /* If the Shift key has been released after being pressed, replace
the hibernate button with sleep button again */
- if (Msg.wParam == VK_SHIFT)
- {
- if (ShutdownDialogId == IDD_SHUTDOWN_FANCY &&
Context.bIsSleepButtonReplaced)
- {
- if (IsPwrHibernateAllowed() &&
IsPwrSuspendAllowed())
- {
- ReplaceRequiredButton(hDlg,
- pgContext->hDllInstance,
- bIsAltKeyPressed,
- Context.bIsSleepButtonReplaced);
- Context.bIsSleepButtonReplaced = FALSE;
- }
- }
- }
- }
- break;
- }
- }
- ret = Msg.wParam;
+ ret = DialogBoxParamW(pgContext->hDllInstance,
+ MAKEINTRESOURCEW(Context.bReasonUI ? IDD_SHUTDOWN_REASON :
Context.ShutdownDialogId),
+ hwndDlg,
+ ShutdownDialogProc,
+ (LPARAM)&Context);
}
#if 0
diff --git a/dll/win32/shell32/dialogs/dialogs.cpp
b/dll/win32/shell32/dialogs/dialogs.cpp
index 4b05a92ef31..f2ee6aa2278 100644
--- a/dll/win32/shell32/dialogs/dialogs.cpp
+++ b/dll/win32/shell32/dialogs/dialogs.cpp
@@ -1124,6 +1124,10 @@ int WINAPI RestartDialogEx(HWND hWndOwner, LPCWSTR lpwstrReason,
DWORD uFlags, D
#define BUTTON_LOG_OFF_FOCUSED (CY_BITMAP + BUTTON_LOG_OFF_PRESSED)
#define BUTTON_SWITCH_USER_DISABLED (CY_BITMAP + BUTTON_LOG_OFF_FOCUSED) //
Temporary
+/* For bIsButtonHot */
+#define LOG_OFF_BUTTON_HOT 0
+#define SWITCH_USER_BUTTON_HOT 1
+
BOOL DrawIconOnOwnerDrawnButtons(DRAWITEMSTRUCT* pdis, PLOGOFF_DLG_CONTEXT pContext)
{
BOOL bRet = FALSE;
@@ -1152,7 +1156,7 @@ BOOL DrawIconOnOwnerDrawnButtons(DRAWITEMSTRUCT* pdis,
PLOGOFF_DLG_CONTEXT pCont
{
y = BUTTON_LOG_OFF_PRESSED;
}
- else if (pContext->bIsButtonHot[0] || (pdis->itemState &
ODS_FOCUS))
+ else if (pContext->bIsButtonHot[LOG_OFF_BUTTON_HOT] ||
(pdis->itemState & ODS_FOCUS))
{
y = BUTTON_LOG_OFF_FOCUSED;
}
@@ -1175,7 +1179,7 @@ BOOL DrawIconOnOwnerDrawnButtons(DRAWITEMSTRUCT* pdis,
PLOGOFF_DLG_CONTEXT pCont
{
y = BUTTON_SWITCH_USER_PRESSED;
}
- else if (pContext->bIsButtonHot[1] || (pdis->itemState &
ODS_FOCUS))
+ else if (pContext->bIsButtonHot[SWITCH_USER_BUTTON_HOT] ||
(pdis->itemState & ODS_FOCUS))
{
y = BUTTON_SWITCH_USER_FOCUSED;
}
@@ -1210,7 +1214,7 @@ BOOL DrawIconOnOwnerDrawnButtons(DRAWITEMSTRUCT* pdis,
PLOGOFF_DLG_CONTEXT pCont
INT_PTR CALLBACK OwnerDrawButtonSubclass(HWND hButton, UINT uMsg, WPARAM wParam, LPARAM
lParam)
{
PLOGOFF_DLG_CONTEXT pContext;
- pContext = (PLOGOFF_DLG_CONTEXT)GetWindowLongPtrW(hButton, GWLP_USERDATA);
+ pContext = (PLOGOFF_DLG_CONTEXT)GetWindowLongPtrW(GetParent(hButton),
GWLP_USERDATA);
int buttonID = GetDlgCtrlID(hButton);
@@ -1224,13 +1228,19 @@ INT_PTR CALLBACK OwnerDrawButtonSubclass(HWND hButton, UINT uMsg,
WPARAM wParam,
if (GetCapture() != hButton)
{
SetCapture(hButton);
- if (buttonID == IDC_LOG_OFF_BUTTON)
- {
- pContext->bIsButtonHot[0] = TRUE;
- }
- else if (buttonID == IDC_SWITCH_USER_BUTTON)
+
+ switch (buttonID)
{
- pContext->bIsButtonHot[1] = TRUE;
+ case IDC_LOG_OFF_BUTTON:
+ {
+ pContext->bIsButtonHot[LOG_OFF_BUTTON_HOT] = TRUE;
+ break;
+ }
+ case IDC_SWITCH_USER_BUTTON:
+ {
+ pContext->bIsButtonHot[SWITCH_USER_BUTTON_HOT] = TRUE;
+ break;
+ }
}
SetCursor(LoadCursorW(NULL, MAKEINTRESOURCEW(IDC_HAND)));
}
@@ -1241,13 +1251,19 @@ INT_PTR CALLBACK OwnerDrawButtonSubclass(HWND hButton, UINT uMsg,
WPARAM wParam,
if (hwndTarget != hButton)
{
ReleaseCapture();
- if (buttonID == IDC_LOG_OFF_BUTTON)
- {
- pContext->bIsButtonHot[0] = FALSE;
- }
- else if (buttonID == IDC_SWITCH_USER_BUTTON)
+
+ switch (buttonID)
{
- pContext->bIsButtonHot[1] = FALSE;
+ case IDC_LOG_OFF_BUTTON:
+ {
+ pContext->bIsButtonHot[LOG_OFF_BUTTON_HOT] = FALSE;
+ break;
+ }
+ case IDC_SWITCH_USER_BUTTON:
+ {
+ pContext->bIsButtonHot[SWITCH_USER_BUTTON_HOT] = FALSE;
+ break;
+ }
}
}
InvalidateRect(hButton, NULL, FALSE);
@@ -1300,6 +1316,21 @@ VOID CreateToolTipForButtons(int controlID, int detailID, HWND
hDlg, int titleID
SendMessageW(hwndTip, TTM_SETMAXTIPWIDTH, 0, 250);
}
+VOID EndFriendlyDialog(HWND hwnd, PLOGOFF_DLG_CONTEXT pContext)
+{
+ DeleteObject(pContext->hBrush);
+ DeleteObject(pContext->hImageStrip);
+ DeleteObject(pContext->hfFont);
+
+ /* Remove the subclass from the buttons */
+ for (int i = 0; i < NUMBER_OF_BUTTONS; i++)
+ {
+ SetWindowLongPtrW(GetDlgItem(hwnd, IDC_LOG_OFF_BUTTON + i),
+ GWLP_WNDPROC,
+ (LONG_PTR)pContext->OldButtonProc);
+ }
+}
+
static BOOL IsFriendlyUIActive(VOID)
{
DWORD dwType = 0, dwValue = 0, dwSize = 0;
@@ -1389,18 +1420,20 @@ static VOID FancyLogoffOnInit(HWND hwnd, PLOGOFF_DLG_CONTEXT
pContext)
pContext->hImageStrip = LoadBitmapW(shell32_hInstance,
MAKEINTRESOURCEW(IDB_IMAGE_STRIP));
- CreateToolTipForButtons(IDC_LOG_OFF_BUTTON, IDS_LOG_OFF_DESC, hwnd,
IDS_LOG_OFF_TITLE);
- CreateToolTipForButtons(IDC_SWITCH_USER_BUTTON, IDS_SWITCH_USER_DESC, hwnd,
IDS_SWITCH_USER_TITLE);
-
/* Gather old button func */
pContext->OldButtonProc = (WNDPROC)GetWindowLongPtrW(GetDlgItem(hwnd,
IDC_LOG_OFF_BUTTON), GWLP_WNDPROC);
- /* Make buttons to remember pContext and subclass the buttons as well as set
bIsButtonHot boolean flags to false */
+ /* Set bIsButtonHot to false, create tooltips for each buttons and subclass the
buttons */
for (int i = 0; i < NUMBER_OF_BUTTONS; i++)
{
pContext->bIsButtonHot[i] = FALSE;
- SetWindowLongPtrW(GetDlgItem(hwnd, IDC_LOG_OFF_BUTTON + i), GWLP_USERDATA,
(LONG_PTR)pContext);
- SetWindowLongPtrW(GetDlgItem(hwnd, IDC_LOG_OFF_BUTTON + i), GWLP_WNDPROC,
(LONG_PTR)OwnerDrawButtonSubclass);
+ SetWindowLongPtrW(GetDlgItem(hwnd, IDC_LOG_OFF_BUTTON + i),
+ GWLP_WNDPROC,
+ (LONG_PTR)OwnerDrawButtonSubclass);
+ CreateToolTipForButtons(IDC_LOG_OFF_BUTTON + i,
+ IDS_LOG_OFF_DESC + i,
+ hwnd,
+ IDS_LOG_OFF_TITLE + i);
}
}
@@ -1428,8 +1461,7 @@ INT_PTR CALLBACK LogOffDialogProc(HWND hwnd, UINT uMsg, WPARAM
wParam, LPARAM lP
}
case WM_CLOSE:
- DestroyWindow(hwnd);
- PostQuitMessage(IDCANCEL);
+ EndDialog(hwnd, IDCANCEL);
break;
/*
@@ -1441,8 +1473,7 @@ INT_PTR CALLBACK LogOffDialogProc(HWND hwnd, UINT uMsg, WPARAM
wParam, LPARAM lP
{
if (LOWORD(wParam) == WA_INACTIVE)
{
- DestroyWindow(hwnd);
- PostQuitMessage(0);
+ EndDialog(hwnd, IDCANCEL);
}
return FALSE;
}
@@ -1456,22 +1487,14 @@ INT_PTR CALLBACK LogOffDialogProc(HWND hwnd, UINT uMsg, WPARAM
wParam, LPARAM lP
break;
case IDCANCEL:
- DestroyWindow(hwnd);
- PostQuitMessage(IDCANCEL);
+ EndDialog(hwnd, IDCANCEL);
break;
}
break;
case WM_DESTROY:
- DeleteObject(pContext->hBrush);
- DeleteObject(pContext->hImageStrip);
- DeleteObject(pContext->hfFont);
-
- /* Remove the subclass from the buttons */
- for (int i = 0; i < NUMBER_OF_BUTTONS; i++)
- {
- SetWindowLongPtrW(GetDlgItem(hwnd, IDC_LOG_OFF_BUTTON + i), GWLP_WNDPROC,
(LONG_PTR)pContext->OldButtonProc);
- }
+ if (pContext->bFriendlyUI)
+ EndFriendlyDialog(hwnd, pContext);
return TRUE;
case WM_CTLCOLORSTATIC:
@@ -1522,11 +1545,7 @@ INT_PTR CALLBACK LogOffDialogProc(HWND hwnd, UINT uMsg, WPARAM
wParam, LPARAM lP
EXTERN_C int WINAPI LogoffWindowsDialog(HWND hWndOwner)
{
CComPtr<IUnknown> fadeHandler;
- BOOL bIsAltKeyPressed = FALSE;
- MSG Msg;
HWND parent = NULL;
- HWND hWndChild = NULL;
- WCHAR szBuffer[30];
DWORD LogoffDialogID = IDD_LOG_OFF;
LOGOFF_DLG_CONTEXT Context;
@@ -1539,36 +1558,11 @@ EXTERN_C int WINAPI LogoffWindowsDialog(HWND hWndOwner)
LogoffDialogID = IDD_LOG_OFF_FANCY;
}
- hWndChild = CreateDialogParamW(shell32_hInstance, MAKEINTRESOURCEW(LogoffDialogID),
parent, LogOffDialogProc, (LPARAM)&Context);
- ShowWindow(hWndChild, SW_SHOWNORMAL);
-
- /* Detect either Alt key has been pressed */
- while (GetMessageW(&Msg, NULL, 0, 0))
- {
- if(!IsDialogMessageW(hWndChild, &Msg))
- {
- TranslateMessage(&Msg);
- DispatchMessageW(&Msg);
- }
-
- switch (Msg.message)
- {
- case WM_SYSKEYDOWN:
- {
- /* If the Alt key has been pressed once, add prefix to static controls
*/
- if (Msg.wParam == VK_MENU && !bIsAltKeyPressed &&
Context.bFriendlyUI)
- {
- for (int i = 0; i < NUMBER_OF_BUTTONS; i++)
- {
- GetDlgItemTextW(hWndChild, IDC_LOG_OFF_BUTTON + i, szBuffer,
_countof(szBuffer));
- SetDlgItemTextW(hWndChild, IDC_LOG_OFF_STATIC + i, szBuffer);
- }
- bIsAltKeyPressed = TRUE;
- }
- }
- break;
- }
- }
+ DialogBoxParamW(shell32_hInstance,
+ MAKEINTRESOURCEW(LogoffDialogID),
+ parent,
+ LogOffDialogProc,
+ (LPARAM)&Context);
return 0;
}