mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-26 19:33:31 +00:00
[SETUP:REACTOS] Improve navigation in the setup wizard
- Support double-clicking on the Installation type page radio buttons. The Installation type page offers two self-excluding options: "Install ReactOS", and "Upgrade an existing ReactOS installation", and no other controls are available (except for the wizard navigation buttons). Thus, we can implement the UI feature of supporting double- clicked radio buttons as an abbreviation for "select + Next". For this, add the `BS_NOTIFY` style to both radio buttons, so as to receive the `BN_DBLCLK` notification via the `WM_COMMAND` message. Based on a suggestion by Raymond Chen, https://devblogs.microsoft.com/oldnewthing/20050804-10/?p=34713 - Ensure the correct radio button is selected when activating the Installation type page: ensure the "Install ReactOS" radio button is checked if we don't have a selected installation (default case), which can also happen if the user clicked on the "Do not upgrade" button on the Upgrade/Repair selection page, then went back. - In the Upgrade/Repair selection page, go to the next page if the user double-clicked on a listed installation. - In the Drives/Partitions page: * support pressing DELETE key to delete an existing partition; * support pressing ENTER key to install ReactOS on a eligible partition; * enable the "Create" partition button only if the selected disk region is not partitioned, and can be partitioned according to the disk's partitioning scheme (e.g. for MBR disks, no more than 4 primary partitions).
This commit is contained in:
@@ -1372,12 +1372,12 @@ DoCreatePartition(
|
||||
_In_opt_ ULONGLONG SizeBytes,
|
||||
_In_opt_ ULONG_PTR PartitionInfo)
|
||||
{
|
||||
BOOLEAN Success;
|
||||
PPARTITEM PartItem;
|
||||
PPARTENTRY PartEntry;
|
||||
HTLITEM hParentItem;
|
||||
HTLITEM hInsertAfter;
|
||||
PPARTENTRY NextPart;
|
||||
BOOLEAN Success;
|
||||
|
||||
PartItem = (pPartItem ? *pPartItem : GetItemPartition(hList, *phItem));
|
||||
if (!PartItem)
|
||||
@@ -1870,8 +1870,8 @@ DriveDlgProc(
|
||||
PartItem = GetSelectedPartition(hList, &hItem);
|
||||
if (!PartItem)
|
||||
{
|
||||
// If the button was clicked, a partition
|
||||
// should have been selected first...
|
||||
/* If the button was clicked, a partition
|
||||
* should have been selected first */
|
||||
ASSERT(FALSE);
|
||||
break;
|
||||
}
|
||||
@@ -1914,6 +1914,33 @@ DriveDlgProc(
|
||||
{
|
||||
LPNMHDR lpnm = (LPNMHDR)lParam;
|
||||
|
||||
if (lpnm->idFrom == IDC_PARTITION) switch (lpnm->code)
|
||||
{
|
||||
case NM_RETURN:
|
||||
{
|
||||
/* If the currently selected item is a partition (and so, if
|
||||
* the wizard "Next" button is enabled), pressing "Next" will
|
||||
* attempt to select an install partition and go to the next
|
||||
* page if successful. */
|
||||
HWND hWndParent = GetParent(hwndDlg);
|
||||
if (IsWindowEnabled(GetDlgItem(hWndParent, ID_WIZNEXT)))
|
||||
PropSheet_PressButton(hWndParent, PSBTN_NEXT);
|
||||
break;
|
||||
}
|
||||
|
||||
case TVN_KEYDOWN:
|
||||
{
|
||||
if (((LPTV_KEYDOWN_EX)lParam)->wVKey == VK_DELETE)
|
||||
{
|
||||
/* Send the delete command only if IDC_PARTDELETE is
|
||||
* enabled (i.e. the selected item IS a partition) */
|
||||
if (IsWindowEnabled(GetDlgItem(hwndDlg, IDC_PARTDELETE)))
|
||||
PostMessageW(hwndDlg, WM_COMMAND, MAKEWPARAM(IDC_PARTDELETE, BN_CLICKED), 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// On Vista+ we can use TVN_ITEMCHANGED instead, with NMTVITEMCHANGE* pointer
|
||||
if (lpnm->idFrom == IDC_PARTITION && lpnm->code == TVN_SELCHANGED)
|
||||
{
|
||||
@@ -1969,6 +1996,7 @@ DriveDlgProc(
|
||||
/* Partition or unpartitioned space */
|
||||
PPARTITEM PartItem = (PPARTITEM)pnmv->itemNew.lParam;
|
||||
PPARTENTRY PartEntry;
|
||||
BOOL CanBePartitioned;
|
||||
ASSERT(PartItem);
|
||||
PartEntry = PartItem->PartEntry;
|
||||
ASSERT(PartEntry);
|
||||
@@ -1977,11 +2005,17 @@ DriveDlgProc(
|
||||
ShowDlgItem(hwndDlg, IDC_INITDISK, SW_HIDE);
|
||||
EnableDlgItem(hwndDlg, IDC_INITDISK, FALSE);
|
||||
|
||||
/* Check whether the selected disk region is not partitioned, and
|
||||
* can be partitioned according to the disk's partitioning scheme */
|
||||
CanBePartitioned = (!PartEntry->IsPartitioned &&
|
||||
(PartitionCreateChecks(PartEntry, 0ULL, 0) == NOT_AN_ERROR));
|
||||
|
||||
if (!PartEntry->IsPartitioned)
|
||||
{
|
||||
/* Show and enable the "Create" partition button */
|
||||
/* Show the "Create" partition button, but enable it
|
||||
* only if the selected disk region can be partitioned */
|
||||
ShowDlgItem(hwndDlg, IDC_PARTCREATE, SW_SHOW);
|
||||
EnableDlgItem(hwndDlg, IDC_PARTCREATE, TRUE);
|
||||
EnableDlgItem(hwndDlg, IDC_PARTCREATE, CanBePartitioned);
|
||||
|
||||
/* Hide and disable the "Format" button */
|
||||
ShowDlgItem(hwndDlg, IDC_PARTFORMAT, SW_HIDE);
|
||||
@@ -1993,12 +2027,14 @@ DriveDlgProc(
|
||||
ShowDlgItem(hwndDlg, IDC_PARTCREATE, SW_HIDE);
|
||||
EnableDlgItem(hwndDlg, IDC_PARTCREATE, FALSE);
|
||||
|
||||
/* Show the "Format" button, but enable or disable it if a formattable volume is present */
|
||||
/* Show the "Format" button, but enable it only
|
||||
* if a formattable volume is present */
|
||||
ShowDlgItem(hwndDlg, IDC_PARTFORMAT, SW_SHOW);
|
||||
EnableDlgItem(hwndDlg, IDC_PARTFORMAT, !!PartEntry->Volume);
|
||||
}
|
||||
|
||||
/* Show the "Delete" partition button, but enable or disable it if the disk region is partitioned */
|
||||
/* Show the "Delete" partition button, but enable it
|
||||
* only if the disk region is partitioned */
|
||||
ShowDlgItem(hwndDlg, IDC_PARTDELETE, SW_SHOW);
|
||||
EnableDlgItem(hwndDlg, IDC_PARTDELETE, PartEntry->IsPartitioned);
|
||||
|
||||
@@ -2011,7 +2047,7 @@ DriveDlgProc(
|
||||
* or it's not yet formatted (the installer will prompt
|
||||
* for formatting parameters).
|
||||
*
|
||||
* 2. Or, the selected disk region is not partitioned but
|
||||
* 2. Or, the selected disk region is not partitioned, but
|
||||
* can be partitioned according to the disk's partitioning
|
||||
* scheme (the installer will auto-partition the region
|
||||
* and prompt for formatting parameters).
|
||||
@@ -2021,8 +2057,7 @@ DriveDlgProc(
|
||||
|
||||
// TODO: In the future: first test needs to be augmented with:
|
||||
// (... && PartEntry->Volume->IsSimpleVolume)
|
||||
if ((PartEntry->IsPartitioned && PartEntry->Volume) ||
|
||||
(!PartEntry->IsPartitioned && (PartitionCreateChecks(PartEntry, 0ULL, 0) == NOT_AN_ERROR)))
|
||||
if ((PartEntry->IsPartitioned && PartEntry->Volume) || CanBePartitioned)
|
||||
{
|
||||
// ASSERT(PartEntry != PartEntry->DiskEntry->ExtendedPartition);
|
||||
ASSERT(!IsContainerPartition(PartEntry->PartitionType));
|
||||
|
||||
@@ -447,8 +447,16 @@ TypeDlgProc(
|
||||
SetDlgItemFont(hwndDlg, IDC_INSTALL, pSetupData->hBoldFont, TRUE);
|
||||
SetDlgItemFont(hwndDlg, IDC_UPDATE, pSetupData->hBoldFont, TRUE);
|
||||
|
||||
/* Check the "Install" radio button */
|
||||
CheckDlgButton(hwndDlg, IDC_INSTALL, BST_CHECKED);
|
||||
/*
|
||||
* Enable double-click handling with the BS_NOTIFY style for both options.
|
||||
* Idea adapted from: https://devblogs.microsoft.com/oldnewthing/20050804-10/?p=34713
|
||||
*/
|
||||
{
|
||||
HWND hRadio = GetDlgItem(hwndDlg, IDC_INSTALL);
|
||||
SetWindowLongPtrW(hRadio, GWL_STYLE, GetWindowLongPtrW(hRadio, GWL_STYLE) | BS_NOTIFY);
|
||||
hRadio = GetDlgItem(hwndDlg, IDC_UPDATE);
|
||||
SetWindowLongPtrW(hRadio, GWL_STYLE, GetWindowLongPtrW(hRadio, GWL_STYLE) | BS_NOTIFY);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable the "Update" radio button and text only if we have
|
||||
@@ -466,11 +474,28 @@ TypeDlgProc(
|
||||
EnableDlgItem(hwndDlg, IDC_UPDATETEXT, FALSE);
|
||||
}
|
||||
|
||||
/* Ensure "Install ReactOS" is initially focused */
|
||||
/* Check the "Install ReactOS" radio button and ensure it is initially focused */
|
||||
CheckRadioButton(hwndDlg, IDC_INSTALL, IDC_UPDATE, IDC_INSTALL);
|
||||
SetFocus(GetDlgItem(hwndDlg, IDC_INSTALL));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
case WM_COMMAND:
|
||||
{
|
||||
/*
|
||||
* Go to the next page if the user double-clicked one of the options.
|
||||
* Idea adapted from: https://devblogs.microsoft.com/oldnewthing/20050804-10/?p=34713
|
||||
*/
|
||||
if (HIWORD(wParam) == BN_DBLCLK) switch (LOWORD(wParam))
|
||||
{
|
||||
case IDC_INSTALL:
|
||||
case IDC_UPDATE:
|
||||
PropSheet_PressButton(GetParent(hwndDlg), PSBTN_NEXT);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_NOTIFY:
|
||||
{
|
||||
LPNMHDR lpnm = (LPNMHDR)lParam;
|
||||
@@ -478,8 +503,19 @@ TypeDlgProc(
|
||||
switch (lpnm->code)
|
||||
{
|
||||
case PSN_SETACTIVE:
|
||||
{
|
||||
/* Ensure the "Install ReactOS" radio button is checked if we don't have
|
||||
* a selected installation (default case), which can also happen if the
|
||||
* user clicked on the "Do not upgrade" button on the Upgrade/Repair
|
||||
* selection page, then went back here. */
|
||||
if (!pSetupData->CurrentInstallation)
|
||||
CheckRadioButton(hwndDlg, IDC_INSTALL, IDC_UPDATE, IDC_INSTALL);
|
||||
else
|
||||
CheckRadioButton(hwndDlg, IDC_INSTALL, IDC_UPDATE, IDC_UPDATE);
|
||||
|
||||
PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
|
||||
break;
|
||||
}
|
||||
|
||||
case PSN_QUERYCANCEL:
|
||||
{
|
||||
@@ -866,6 +902,15 @@ UpgradeRepairDlgProc(
|
||||
{
|
||||
LPNMHDR lpnm = (LPNMHDR)lParam;
|
||||
|
||||
if (lpnm->idFrom == IDC_NTOSLIST && lpnm->code == NM_DBLCLK)
|
||||
{
|
||||
/* Go to the next page if the user double-clicked on an installation */
|
||||
LPNMLISTVIEW pnmv = (LPNMLISTVIEW)lParam;
|
||||
if (pnmv->iItem != -1)
|
||||
PropSheet_PressButton(GetParent(hwndDlg), PSBTN_NEXT);
|
||||
break;
|
||||
}
|
||||
|
||||
if (lpnm->idFrom == IDC_NTOSLIST && lpnm->code == LVN_ITEMCHANGED)
|
||||
{
|
||||
LPNMLISTVIEW pnmv = (LPNMLISTVIEW)lParam;
|
||||
|
||||
Reference in New Issue
Block a user