From 9690742d914c08e04e8d0e7aee2e86c2f882cf7b Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Mon, 20 Jun 2022 13:47:43 +0100 Subject: [PATCH] [ui] extend SelectionDialog() to support checkbox selection --- src/format.c | 17 +++++++++-------- src/missing.h | 12 +++++++++++- src/resource.h | 21 --------------------- src/rufus.c | 24 ++++++++++-------------- src/rufus.h | 4 ++-- src/rufus.rc | 10 +++++----- src/stdlg.c | 30 ++++++++++++++++++++---------- 7 files changed, 57 insertions(+), 61 deletions(-) diff --git a/src/format.c b/src/format.c index 263642d9..3a4a5f29 100644 --- a/src/format.c +++ b/src/format.c @@ -1268,11 +1268,11 @@ int SetWinToGoIndex(void) if (img_report.wininst_index > 1) { for (i = 0; i < img_report.wininst_index; i++) install_names[i] = &img_report.wininst_path[i][2]; - wininst_index = SelectionDialog(lmprintf(MSG_130), lmprintf(MSG_131), install_names, img_report.wininst_index); + wininst_index = _log2(SelectionDialog(BS_AUTORADIOBUTTON, lmprintf(MSG_130), + lmprintf(MSG_131), install_names, img_report.wininst_index, 1)); if (wininst_index < 0) return -2; - wininst_index--; - if ((wininst_index < 0) || (wininst_index >= MAX_WININST)) + if (wininst_index >= MAX_WININST) wininst_index = 0; } @@ -1323,14 +1323,15 @@ int SetWinToGoIndex(void) uprintf("Warning: Nonstandard Windows image (missing entries)"); if (i > 1) - i = SelectionDialog(lmprintf(MSG_291), lmprintf(MSG_292), version_name.String, i); - if (i < 0) { + // NB: _log2 returns -2 if SelectionDialog() returns negative (user cancelled) + i = _log2(SelectionDialog(BS_AUTORADIOBUTTON, + lmprintf(MSG_291), lmprintf(MSG_292), version_name.String, i, 1)) + 1; + if (i < 0) wintogo_index = -2; // Cancelled by the user - } else if (i == 0) { + else if (i == 0) wintogo_index = 1; - } else { + else wintogo_index = atoi(version_index.String[i - 1]); - } if (i > 0) { // Get the build version build = get_token_data_file_indexed("BUILD", xml_file, i); diff --git a/src/missing.h b/src/missing.h index 0689b827..04539604 100644 --- a/src/missing.h +++ b/src/missing.h @@ -1,7 +1,7 @@ /* * Rufus: The Reliable USB Formatting Utility * Constants and defines missing from various toolchains -* Copyright © 2016-2017 Pete Batard +* Copyright © 2016-2022 Pete Batard * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -105,6 +105,16 @@ static __inline void *_reallocf(void *ptr, size_t size) { return ret; } +static __inline int _log2(register int val) +{ + int ret = 0; + if (val < 0) + return -2; + while (val >>= 1) + ret++; + return ret; +} + /* Why oh why does Microsoft have to make everybody suffer with their braindead use of Unicode? */ #define _RT_ICON MAKEINTRESOURCEA(3) #define _RT_DIALOG MAKEINTRESOURCEA(5) diff --git a/src/resource.h b/src/resource.h index 175a2453..8fbc9947 100644 --- a/src/resource.h +++ b/src/resource.h @@ -31,27 +31,6 @@ #define IDI_LOG_32 144 #define IDI_SAVE_32 145 #define IDI_HASH_32 146 -#define IDD_DIALOG_XP 151 -#define IDD_ABOUTBOX_XP 152 -#define IDD_NOTIFICATION_XP 153 -#define IDD_LICENSE_XP 154 -#define IDD_LOG_XP 155 -#define IDD_UPDATE_POLICY_XP 156 -#define IDD_NEW_VERSION_XP 157 -#define IDD_DIALOG_RTL 201 -#define IDD_ABOUTBOX_RTL 202 -#define IDD_NOTIFICATION_RTL 203 -#define IDD_LICENSE_RTL 204 -#define IDD_LOG_RTL 205 -#define IDD_UPDATE_POLICY_RTL 206 -#define IDD_NEW_VERSION_RTL 207 -#define IDD_DIALOG_RTL_XP 251 -#define IDD_ABOUTBOX_RTL_XP 252 -#define IDD_NOTIFICATION_RTL_XP 253 -#define IDD_LICENSE_RTL_XP 254 -#define IDD_LOG_RTL_XP 255 -#define IDD_UPDATE_POLICY_RTL_XP 256 -#define IDD_NEW_VERSION_RTL_XP 257 #define IDR_FD_COMMAND_COM 300 #define IDR_FD_KERNEL_SYS 301 #define IDR_FD_DISPLAY_EXE 302 diff --git a/src/rufus.c b/src/rufus.c index bd35047d..ac35ddc4 100755 --- a/src/rufus.c +++ b/src/rufus.c @@ -1,6 +1,6 @@ /* * Rufus: The Reliable USB Formatting Utility - * Copyright © 2011-2021 Pete Batard + * Copyright © 2011-2022 Pete Batard * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -1454,23 +1454,20 @@ static DWORD WINAPI BootCheckThread(LPVOID param) if ((img_report.projected_size < MAX_ISO_TO_ESP_SIZE * MB) && HAS_REGULAR_EFI(img_report) && (partition_type == PARTITION_STYLE_GPT) && IS_FAT(fs_type)) { char* choices[3] = { lmprintf(MSG_276, iso_image), lmprintf(MSG_277, "ISO → ESP"), lmprintf(MSG_277, dd_image) }; - i = SelectionDialog(lmprintf(MSG_274, "ISOHybrid"), lmprintf(MSG_275, iso_image, dd_image, iso_image, dd_image), - choices, 3); + i = SelectionDialog(BS_AUTORADIOBUTTON, lmprintf(MSG_274, "ISOHybrid"), + lmprintf(MSG_275, iso_image, dd_image, iso_image, dd_image), choices, 3, 1); if (i < 0) // Cancel goto out; - else if (i == 2) - write_as_esp = TRUE; - else if (i == 3) - write_as_image = TRUE; + write_as_esp = (i & 2); + write_as_image = (i & 4); esp_already_asked = TRUE; } else { char* choices[2] = { lmprintf(MSG_276, iso_image), lmprintf(MSG_277, dd_image) }; - i = SelectionDialog(lmprintf(MSG_274, "ISOHybrid"), lmprintf(MSG_275, iso_image, dd_image, iso_image, dd_image), - choices, 2); + i = SelectionDialog(BS_AUTORADIOBUTTON, lmprintf(MSG_274, "ISOHybrid"), + lmprintf(MSG_275, iso_image, dd_image, iso_image, dd_image), choices, 2, 1); if (i < 0) // Cancel goto out; - else if (i == 2) - write_as_image = TRUE; + write_as_image = (i & 2); } } } @@ -1541,11 +1538,10 @@ static DWORD WINAPI BootCheckThread(LPVOID param) // so ask the users if they want to write it as an ESP. char* iso_image = lmprintf(MSG_036); char* choices[2] = { lmprintf(MSG_276, iso_image), lmprintf(MSG_277, "ISO → ESP") }; - i = SelectionDialog(lmprintf(MSG_274, "ESP"), lmprintf(MSG_310), choices, 2); + i = SelectionDialog(BS_AUTORADIOBUTTON, lmprintf(MSG_274, "ESP"), lmprintf(MSG_310), choices, 2, 1); if (i < 0) // Cancel goto out; - else if (i == 2) - write_as_esp = TRUE; + write_as_esp = (i & 2); } // If the selected target doesn't include BIOS, skip file downloads for GRUB/Syslinux diff --git a/src/rufus.h b/src/rufus.h index 3e8f32ee..e9a0f01f 100644 --- a/src/rufus.h +++ b/src/rufus.h @@ -1,6 +1,6 @@ /* * Rufus: The Reliable USB Formatting Utility - * Copyright © 2011-2021 Pete Batard + * Copyright © 2011-2022 Pete Batard * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -558,7 +558,7 @@ extern BOOL CreateTooltip(HWND hControl, const char* message, int duration); extern void DestroyTooltip(HWND hWnd); extern void DestroyAllTooltips(void); extern BOOL Notification(int type, const char* dont_display_setting, const notification_info* more_info, char* title, char* format, ...); -extern int SelectionDialog(char* title, char* message, char** choices, int size); +extern int SelectionDialog(int style, char* title, char* message, char** choices, int size, int mask); extern void ListDialog(char* title, char* message, char** items, int size); extern SIZE GetTextSize(HWND hCtrl, char* txt); extern BOOL ExtractAppIcon(const char* filename, BOOL bSilent); diff --git a/src/rufus.rc b/src/rufus.rc index 33bf9381..43468f55 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDD_DIALOG DIALOGEX 12, 12, 232, 326 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_ACCEPTFILES -CAPTION "Rufus 3.19.1898" +CAPTION "Rufus 3.19.1899" FONT 9, "Segoe UI Symbol", 400, 0, 0x0 BEGIN LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP @@ -395,8 +395,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,19,1898,0 - PRODUCTVERSION 3,19,1898,0 + FILEVERSION 3,19,1899,0 + PRODUCTVERSION 3,19,1899,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -414,13 +414,13 @@ BEGIN VALUE "Comments", "https://rufus.ie" VALUE "CompanyName", "Akeo Consulting" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "3.19.1898" + VALUE "FileVersion", "3.19.1899" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "© 2011-2022 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" VALUE "OriginalFilename", "rufus-3.19.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "3.19.1898" + VALUE "ProductVersion", "3.19.1899" END END BLOCK "VarFileInfo" diff --git a/src/stdlg.c b/src/stdlg.c index 4db60a4d..48660b93 100644 --- a/src/stdlg.c +++ b/src/stdlg.c @@ -1,7 +1,7 @@ /* * Rufus: The Reliable USB Formatting Utility * Standard Dialog Routines (Browse for folder, About, etc) - * Copyright © 2011-2021 Pete Batard + * Copyright © 2011-2022 Pete Batard * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -859,13 +859,16 @@ BOOL Notification(int type, const char* dont_display_setting, const notification return ret; } +// We only ever display one selection dialog, so set some params as globals +static int selection_dialog_style, selection_dialog_mask; + /* * Custom dialog for radio button selection dialog */ INT_PTR CALLBACK SelectionCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { LRESULT loc; - int i, dh, r = -1; + int i, m, dh, r = -1; // Prevent resizing static LRESULT disabled[9] = { HTLEFT, HTRIGHT, HTTOP, HTBOTTOM, HTSIZE, HTTOPLEFT, HTTOPRIGHT, HTBOTTOMLEFT, HTBOTTOMRIGHT }; @@ -885,6 +888,9 @@ INT_PTR CALLBACK SelectionCallback(HWND hDlg, UINT message, WPARAM wParam, LPARA nDialogItems, IDC_SELECTION_CHOICEMAX - IDC_SELECTION_CHOICE1); nDialogItems = IDC_SELECTION_CHOICEMAX - IDC_SELECTION_CHOICE1; } + // Switch to checkboxes or some other style if requested + for (i = 0; i < nDialogItems; i++) + Button_SetStyle(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + i), selection_dialog_style, TRUE); // Get the system message box font. See http://stackoverflow.com/a/6057761 ncm.cbSize = sizeof(ncm); SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0); @@ -936,9 +942,9 @@ INT_PTR CALLBACK SelectionCallback(HWND hDlg, UINT message, WPARAM wParam, LPARA ResizeButtonHeight(hDlg, IDOK); ResizeButtonHeight(hDlg, IDCANCEL); - // Set the radio selection - Button_SetCheck(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1), BST_CHECKED); - Button_SetCheck(GetDlgItem(hDlg, IDC_SELECTION_CHOICE2), BST_UNCHECKED); + // Set the default selection + for (i = 0, m = 1; i < nDialogItems; i++, m <<= 1) + Button_SetCheck(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + i), (m & selection_dialog_mask) ? BST_CHECKED : BST_UNCHECKED); return (INT_PTR)TRUE; case WM_CTLCOLORSTATIC: // Change the background colour for static text and icon @@ -959,10 +965,9 @@ INT_PTR CALLBACK SelectionCallback(HWND hDlg, UINT message, WPARAM wParam, LPARA case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: - for (i = 0; (i < nDialogItems) && - (Button_GetCheck(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + i)) != BST_CHECKED); i++); - if (i < nDialogItems) - r = i + 1; + for (r = 0, i = 0, m = 1; i < nDialogItems; i++, m <<= 1) + if (Button_GetCheck(GetDlgItem(hDlg, IDC_SELECTION_CHOICE1 + i)) == BST_CHECKED) + r += m; // Fall through case IDNO: case IDCANCEL: @@ -977,7 +982,7 @@ INT_PTR CALLBACK SelectionCallback(HWND hDlg, UINT message, WPARAM wParam, LPARA /* * Display an item selection dialog */ -int SelectionDialog(char* title, char* message, char** choices, int size) +int SelectionDialog(int style, char* title, char* message, char** choices, int size, int mask) { int ret; @@ -986,6 +991,9 @@ int SelectionDialog(char* title, char* message, char** choices, int size) szMessageText = message; szDialogItem = choices; nDialogItems = size; + selection_dialog_style = style; + selection_dialog_mask = mask; + assert(selection_dialog_style == BS_AUTORADIOBUTTON || selection_dialog_style == BS_AUTOCHECKBOX); ret = (int)MyDialogBox(hMainInstance, IDD_SELECTION, hMainDialog, SelectionCallback); dialog_showing--; @@ -1971,6 +1979,7 @@ LPCDLGTEMPLATE GetDialogTemplate(int Dialog_ID) HWND MyCreateDialog(HINSTANCE hInstance, int Dialog_ID, HWND hWndParent, DLGPROC lpDialogFunc) { LPCDLGTEMPLATE rcTemplate = GetDialogTemplate(Dialog_ID); + assert(rcTemplate != NULL); HWND hDlg = CreateDialogIndirect(hInstance, rcTemplate, hWndParent, lpDialogFunc); safe_free(rcTemplate); return hDlg; @@ -1987,6 +1996,7 @@ INT_PTR MyDialogBox(HINSTANCE hInstance, int Dialog_ID, HWND hWndParent, DLGPROC // main dialog was reduced => Ensure the main dialog is visible before we display anything. ShowWindow(hMainDialog, SW_NORMAL); + assert(rcTemplate != NULL); ret = DialogBoxIndirect(hMainInstance, rcTemplate, hWndParent, lpDialogFunc); safe_free(rcTemplate); return ret;