diff --git a/base/setup/reactos/drivepage.c b/base/setup/reactos/drivepage.c index eb4bc69084e..de9f772a023 100644 --- a/base/setup/reactos/drivepage.c +++ b/base/setup/reactos/drivepage.c @@ -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)); diff --git a/base/setup/reactos/reactos.c b/base/setup/reactos/reactos.c index bf39fe551d5..d24fbeb6a0d 100644 --- a/base/setup/reactos/reactos.c +++ b/base/setup/reactos/reactos.c @@ -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;