more code changes

This commit is contained in:
Hermès Bélusca-Maïto 2024-10-30 12:23:47 +01:00
parent fc7f51044a
commit 6b8c98a532
No known key found for this signature in database
GPG Key ID: 3B2539C65E7B93D0
3 changed files with 153 additions and 60 deletions

View File

@ -346,6 +346,13 @@ StartDlgProc(
SendDlgItemMessage(hwndDlg, IDC_WARNTEXT3,
WM_SETFONT, (WPARAM)pSetupData->hBoldFont, (LPARAM)TRUE);
/* Change the "Cancel" button text to "Close" */
// GetDlgItemTextW(GetParent(hwndDlg), IDCANCEL,
// szOrgWizNextBtnText, ARRAYSIZE(szOrgWizNextBtnText));
SetWindowResTextW(GetDlgItem(GetParent(hwndDlg), IDCANCEL),
GetModuleHandleW(L"comctl32.dll"),
IDS_CLOSE);
/* Center the wizard window */
CenterWindow(GetParent(hwndDlg));
break;
@ -465,6 +472,14 @@ TypeDlgProc(
case PSN_WIZNEXT: /* Set the selected data */
{
/////////////////////////
#if 0
Sleep(5000);
SetWindowLongPtrW(hwndDlg, DWLP_MSGRESULT, IDD_FINISHPAGE);
return TRUE;
#endif
/////////////////////////
/*
* Go update only if we have available NT installations
* and we choose to do so.
@ -1068,6 +1083,7 @@ SummaryDlgProc(
{
if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_CONFIRM_INSTALL)
{
// Ideally we could add the PSWIZBF_ELEVATIONREQUIRED style.
if (IsDlgButtonChecked(hwndDlg, IDC_CONFIRM_INSTALL) == BST_CHECKED)
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
else
@ -1792,8 +1808,10 @@ RegistryStatus(IN REGISTRY_STATUS RegStatus, ...)
/**
* @brief
* Enables or disables the Cancel and the Close title-bar
* property-sheet window buttons.
* Enable or disable the Cancel and the Close title-bar property-sheet buttons.
*
* The buttons are however kept visible in case they are disabled
* (this informs the user they are disabled only temporarily).
**/
VOID
PropSheet_SetCloseCancel(
@ -1801,7 +1819,6 @@ PropSheet_SetCloseCancel(
_In_ BOOL Enable)
{
EnableDlgItem(hWndWiz, IDCANCEL, Enable);
// ShowDlgItem(hWndWiz, IDCANCEL, Enable ? SW_SHOW : SW_HIDE);
EnableMenuItem(GetSystemMenu(hWndWiz, FALSE),
SC_CLOSE,
MF_BYCOMMAND | (Enable ? MF_ENABLED : MF_GRAYED));
@ -2344,6 +2361,62 @@ GetSetupType(VOID)
return dwSetupType;
}
typedef struct _CLOSABLE_WND_INFO
{
HWND hWndExclude; ///< Window to exclude from search
BOOL Found; ///< TRUE if a closable window was found; FALSE if not.
} CLOSABLE_WND_INFO, *PCLOSABLE_WND_INFO;
static BOOL
CALLBACK
FindUserClosableWindowProc(
_In_ HWND hWnd,
_In_ LPARAM lParam)
{
PCLOSABLE_WND_INFO pInfo = (PCLOSABLE_WND_INFO)lParam;
HMENU hSysMenu;
MENUITEMINFOW mii;
/* Skip the window to exclude */
if (hWnd == pInfo->hWndExclude)
return TRUE;
/* Skip non-interactive windows */
if (!IsWindowEnabled(hWnd) || !IsWindowVisible(hWnd))
return TRUE;
hSysMenu = GetSystemMenu(hWnd, FALSE);
if (!hSysMenu)
return TRUE; /* No menu: skip the window */
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STATE;
if (!GetMenuItemInfoW(hSysMenu, SC_CLOSE, FALSE, &mii))
return TRUE; /* No close item: skip the window */
pInfo->Found |= !(mii.fState & MFS_DISABLED);
/* Continue enumeration (return TRUE) if no close item is enabled;
* otherwise stop the enumeration (return FALSE) */
return !pInfo->Found;
}
static BOOL
AreThereInteractiveWindows(
_In_opt_ HWND hWndExclude)
{
/* Return success if a shell is present */
if (GetShellWindow())
{
return TRUE;
}
/* Otherwise, check for user-interactive closable windows */
else
{
CLOSABLE_WND_INFO Info = {hWndExclude, FALSE};
EnumWindows(FindUserClosableWindowProc, (LPARAM)&Info);
return Info.Found;
}
}
static INT_PTR CALLBACK
FinishDlgProc(
IN HWND hwndDlg,
@ -2360,6 +2433,8 @@ FinishDlgProc(
{
case WM_INITDIALOG:
{
DWORD dwSetupType;
/* Save pointer to the global setup data */
pSetupData = (PSETUPDATA)((LPPROPSHEETPAGE)lParam)->lParam;
SetWindowLongPtrW(hwndDlg, GWLP_USERDATA, (DWORD_PTR)pSetupData);
@ -2371,25 +2446,22 @@ FinishDlgProc(
(WPARAM)pSetupData->hTitleFont,
(LPARAM)TRUE);
#if 1 // FIXME FIXME: This is for testing only!!
SetDlgItemTextW(GetParent(hwndDlg), ID_WIZNEXT, L"Test button");
#endif
/* Retrieve the HKLM\SYSTEM\Setup:SetupType value to determine
* whether we need to restart at the end of the installation */
//pSetupData->dwSetupType = GetSetupType();
pSetupData->dwSetupType = 1;
dwSetupType = GetSetupType();
pSetupData->bMustReboot = (dwSetupType == 1 || dwSetupType == 4); // FIXME: Use defines/enum
if (pSetupData->dwSetupType == 1 || pSetupData->dwSetupType == 4) // FIXME: Use defines/enum
/* Force "Restart Now" if there are no other user-interactive windows */
pSetupData->bMustReboot |= !AreThereInteractiveWindows(GetParent(hwndDlg));
/* If we must restart, display the countdown gauge, show the "Stop Countdown" and the "Restart" buttons.
* If we don't need to restart right now, let the user to restart now or later. */
if (pSetupData->bMustReboot)
{
EnableDlgItem(hwndDlg, IDC_RESTART_PROGRESS, TRUE);
EnableDlgItem(hwndDlg, IDC_PAUSE_COUNTDOWN, TRUE);
EnableDlgItem(hwndDlg, IDC_RESTARTNOW, FALSE);
ShowWindow(GetDlgItem(hwndDlg, IDC_RESTART_PROGRESS), SW_SHOW);
ShowWindow(GetDlgItem(hwndDlg, IDC_PAUSE_COUNTDOWN), SW_SHOW);
ShowWindow(GetDlgItem(hwndDlg, IDC_RESTARTNOW), SW_HIDE);
CheckDlgButton(hwndDlg, IDC_PAUSE_COUNTDOWN, BST_UNCHECKED);
EnableDlgItem(hwndDlg, IDC_STOP_COUNTDOWN, TRUE);
ShowDlgItem(hwndDlg, IDC_RESTART_PROGRESS, SW_SHOW);
ShowDlgItem(hwndDlg, IDC_STOP_COUNTDOWN, SW_SHOW);
}
else
{
@ -2398,14 +2470,16 @@ FinishDlgProc(
pSetupData->hInstance,
IDS_FINISH_NO_REBOOT);
/* Hide and disable the countdown gauge and the "Stop Countdown" button */
EnableDlgItem(hwndDlg, IDC_RESTART_PROGRESS, FALSE);
EnableDlgItem(hwndDlg, IDC_PAUSE_COUNTDOWN, FALSE);
EnableDlgItem(hwndDlg, IDC_RESTARTNOW, TRUE);
ShowWindow(GetDlgItem(hwndDlg, IDC_RESTART_PROGRESS), SW_HIDE);
ShowWindow(GetDlgItem(hwndDlg, IDC_PAUSE_COUNTDOWN), SW_HIDE);
ShowWindow(GetDlgItem(hwndDlg, IDC_RESTARTNOW), SW_SHOW);
EnableDlgItem(hwndDlg, IDC_STOP_COUNTDOWN, FALSE);
ShowDlgItem(hwndDlg, IDC_RESTART_PROGRESS, SW_HIDE);
ShowDlgItem(hwndDlg, IDC_STOP_COUNTDOWN, SW_HIDE);
}
/* Ensure that the installer wizard window is made visible and focused */
ShowWindow(GetParent(hwndDlg), SW_SHOW);
SwitchToThisWindow(GetParent(hwndDlg), TRUE);
break;
}
@ -2439,20 +2513,22 @@ FinishDlgProc(
{
case PSN_SETACTIVE:
{
/* Only "Finish" for closing the wizard */
ShowDlgItem(GetParent(hwndDlg), IDCANCEL, SW_HIDE);
/* Only "Finish" for closing the wizard, and hide "Next" and "Back" */
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_FINISH);
// PropSheet_ShowWizButtons(GetParent(hwndDlg), 0, PSWIZB_BACK | PSWIZB_NEXT | PSWIZB_CANCEL);
ShowDlgItem(GetParent(hwndDlg), ID_WIZBACK, SW_HIDE);
ShowDlgItem(GetParent(hwndDlg), ID_WIZNEXT, SW_HIDE);
// NOTE: Alternative buttons suggestion:
// "Back" (disabled/hidden), "Restart Now" (instead of "Finish"), Cancel/Exit
/* Change the "Finish" button text to "Restart" */
SetWindowResTextW(GetDlgItem(GetParent(hwndDlg), ID_WIZFINISH),
pSetupData->hInstance,
IDS_RESTARTBTN);
if (pSetupData->dwSetupType == 1 || pSetupData->dwSetupType == 4) // FIXME: Use defines/enum
if (pSetupData->bMustReboot)
{
/* Change the "Next" button text to "Restart" */
// PropSheet_SetNextText(GetParent(hwndDlg), ...);
SetWindowResTextW(GetDlgItem(GetParent(hwndDlg), ID_WIZFINISH),
pSetupData->hInstance,
IDS_REBOOTBTN);
/* Hide and disable also the "Close"/"Cancel" buttons since we can only finish now */
ShowDlgItem(GetParent(hwndDlg), IDCANCEL, SW_HIDE);
PropSheet_SetCloseCancel(GetParent(hwndDlg), FALSE);
/* Set up the reboot progress bar and countdown timer.
* 300 steps at 50 ms each: 15 seconds */
@ -2460,10 +2536,27 @@ FinishDlgProc(
SendDlgItemMessage(hwndDlg, IDC_RESTART_PROGRESS, PBM_SETPOS, 0, 0);
SetTimer(hwndDlg, 1, 50, NULL);
}
else
{
/* Keep the "Cancel" button shown and change its text to "Postpone" */
// PropSheet_ShowWizButtons(GetParent(hwndDlg), 0, PSWIZB_BACK | PSWIZB_NEXT);
SetWindowResTextW(GetDlgItem(GetParent(hwndDlg), IDCANCEL),
pSetupData->hInstance,
IDS_POSTPONEBTN);
}
break;
}
case PSN_WIZNEXT:
case PSN_WIZFINISH:
{
/* Press on "Finish"/"Restart" button */
pSetupData->bMustReboot = TRUE;
__fallthrough;
}
case PSN_QUERYCANCEL:
/* Press on "Cancel"/"Postpone" button */
default:
break;
}
@ -2477,26 +2570,18 @@ FinishDlgProc(
switch (LOWORD(wParam))
{
case IDC_PAUSE_COUNTDOWN:
case IDC_STOP_COUNTDOWN:
{
/* Pause the shutdown countdown */
// BST_UNCHECKED or BST_INDETERMINATE => FALSE
if (IsDlgButtonChecked(hwndDlg, IDC_PAUSE_COUNTDOWN) == BST_CHECKED)
{
/* It is, pause countdown */
KillTimer(hwndDlg, 1);
}
else
{
/* It is not, re-enable countdown */
SetTimer(hwndDlg, 1, 50, NULL);
}
/* Stop the shutdown countdown */
KillTimer(hwndDlg, 1);
/* Hide and disable the countdown gauge and the "Stop Countdown" button */
EnableDlgItem(hwndDlg, IDC_RESTART_PROGRESS, FALSE);
EnableDlgItem(hwndDlg, IDC_STOP_COUNTDOWN, FALSE);
ShowDlgItem(hwndDlg, IDC_RESTART_PROGRESS, SW_HIDE);
ShowDlgItem(hwndDlg, IDC_STOP_COUNTDOWN, SW_HIDE);
break;
}
case IDC_RESTARTNOW:
// TODO
break;
}
break;
}
@ -3046,7 +3131,6 @@ _tWinMain(HINSTANCE hInst,
psp.pszTemplate = MAKEINTRESOURCEW(IDD_STARTPAGE);
ahpsp[nPages++] = CreatePropertySheetPage(&psp);
#if 0
/* Create the install type selection page */
psp.dwSize = sizeof(PROPSHEETPAGE);
psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
@ -3058,6 +3142,7 @@ _tWinMain(HINSTANCE hInst,
psp.pszTemplate = MAKEINTRESOURCEW(IDD_TYPEPAGE);
ahpsp[nPages++] = CreatePropertySheetPage(&psp);
#if 1
/* Create the upgrade/repair selection page */
psp.dwSize = sizeof(PROPSHEETPAGE);
psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
@ -3104,7 +3189,7 @@ _tWinMain(HINSTANCE hInst,
#endif
}
#if 0
#if 1
/* Create the installation progress page */
psp.dwSize = sizeof(PROPSHEETPAGE);
psp.dwFlags = PSP_DEFAULT | PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
@ -3169,12 +3254,20 @@ Quit:
/* Free the NT to Win32 path prefix mapping list */
FreeNtToWin32PathMappingList(&SetupData.MappingList);
/* Force "Restart Now" if there are no other user-interactive windows */
SetupData.bMustReboot |= !AreThereInteractiveWindows(NULL);
/* System rebooting will be done by Winlogon if necessary */
if (SetupData.bMustReboot)
{
#if 0
EnablePrivilege(SE_SHUTDOWN_NAME, TRUE);
ExitWindowsEx(EWX_REBOOT, 0);
EnablePrivilege(SE_SHUTDOWN_NAME, FALSE);
EnablePrivilege(SE_SHUTDOWN_NAME, TRUE);
ExitWindowsEx(EWX_REBOOT, 0);
EnablePrivilege(SE_SHUTDOWN_NAME, FALSE);
#else
DisplayMessage(NULL, MB_ICONWARNING, L"Restarting", L"Setup is now restarting your computer!");
#endif
}
return 0;
}

View File

@ -51,6 +51,8 @@
#define ShowDlgItem(hDlg, nID, nCmdShow) \
ShowWindow(GetDlgItem((hDlg), (nID)), (nCmdShow))
// Property Sheet string IDs
#define IDS_CLOSE 4160 // 0x1040
/* These are public names and values determined from MFC, and compatible with Windows */
// Property Sheet control id's (determined with Spy++)
#define IDC_TAB_CONTROL 0x3020
@ -132,7 +134,7 @@ typedef struct _SETUPDATA
/* General */
HINSTANCE hInstance;
BOOL bUnattend;
DWORD dwSetupType; // From HKLM\SYSTEM\Setup:SetupType registry value.
BOOL bMustReboot;
HFONT hTitleFont;
HFONT hBoldFont;

View File

@ -66,8 +66,7 @@
#define IDC_FINISHTITLE 2071
#define IDC_FINISHTEXT 2072
#define IDC_RESTART_PROGRESS 2073
#define IDC_PAUSE_COUNTDOWN 2074
#define IDC_RESTARTNOW 2075
#define IDC_STOP_COUNTDOWN 2074
#define IDD_ADVINSTOPTS 2080
#define IDC_PATH 2081
@ -97,14 +96,13 @@
#define IDS_SUMMARYSUBTITLE 5008
#define IDS_PROCESSTITLE 5009
#define IDS_PROCESSSUBTITLE 5010
#define IDS_RESTARTTITLE 5011
#define IDS_RESTARTSUBTITLE 5012
#define IDS_ABORTSETUP 5020
#define IDS_ABORTSETUP2 5021
#define IDS_NO_TXTSETUP_SIF 5022
#define IDS_FINISH_NO_REBOOT 5023
#define IDS_INSTALLBTN 5030
#define IDS_REBOOTBTN 5031
#define IDS_RESTARTBTN 5031
#define IDS_POSTPONEBTN 5032
#define IDS_VOLUME_NOFORMAT 5040
#define IDS_INSTALLATION_NAME 5100