mirror of
https://github.com/reactos/reactos.git
synced 2025-07-29 09:22:04 +00:00
[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
This commit is contained in:
parent
22ab8c812a
commit
79e4efe04e
3 changed files with 212 additions and 333 deletions
|
@ -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)
|
||||
|
||||
switch (buttonID)
|
||||
{
|
||||
pContext->bIsButtonHot[0] = TRUE;
|
||||
}
|
||||
else if (buttonID == IDC_SWITCH_USER_BUTTON)
|
||||
{
|
||||
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)
|
||||
|
||||
switch (buttonID)
|
||||
{
|
||||
pContext->bIsButtonHot[0] = FALSE;
|
||||
}
|
||||
else if (buttonID == IDC_SWITCH_USER_BUTTON)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue