diff --git a/.vs/rufus.vcxproj b/.vs/rufus.vcxproj
index a3068c82..6d48ff29 100644
--- a/.vs/rufus.vcxproj
+++ b/.vs/rufus.vcxproj
@@ -340,6 +340,7 @@
+
@@ -367,6 +368,7 @@
+
diff --git a/.vs/rufus.vcxproj.filters b/.vs/rufus.vcxproj.filters
index 11d17ffc..e3af5eba 100644
--- a/.vs/rufus.vcxproj.filters
+++ b/.vs/rufus.vcxproj.filters
@@ -78,6 +78,9 @@
Source Files
+
+ Source Files
+
@@ -152,6 +155,9 @@
Header Files
+
+ Header Files
+
diff --git a/src/Makefile.am b/src/Makefile.am
index 9cb4676b..dc259ab6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -11,7 +11,7 @@ AM_V_WINDRES = $(AM_V_WINDRES_$(V))
$(AM_V_WINDRES) $(AM_RCFLAGS) -i $< -o $@
rufus_SOURCES = badblocks.c checksum.c dev.c dos.c dos_locale.c drive.c format.c icon.c iso.c localization.c \
- net.c parser.c pki.c process.c rufus.c smart.c stdfn.c stdio.c stdlg.c syslinux.c vhd.c
+ net.c parser.c pki.c process.c rufus.c smart.c stdfn.c stdio.c stdlg.c syslinux.c ui.c vhd.c
rufus_CFLAGS = -I./ms-sys/inc -I./syslinux/libfat -I./syslinux/libinstaller -I./syslinux/win -I./libcdio $(AM_CFLAGS)
rufus_LDFLAGS = $(AM_LDFLAGS) -mwindows
rufus_LDADD = rufus_rc.o bled/libbled.a ms-sys/libmssys.a syslinux/libfat/libfat.a syslinux/libinstaller/libinstaller.a syslinux/win/libwin.a \
diff --git a/src/Makefile.in b/src/Makefile.in
index 694be9d7..e5feeb0e 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -96,7 +96,8 @@ am_rufus_OBJECTS = rufus-badblocks.$(OBJEXT) rufus-checksum.$(OBJEXT) \
rufus-process.$(OBJEXT) rufus-rufus.$(OBJEXT) \
rufus-smart.$(OBJEXT) rufus-stdfn.$(OBJEXT) \
rufus-stdio.$(OBJEXT) rufus-stdlg.$(OBJEXT) \
- rufus-syslinux.$(OBJEXT) rufus-vhd.$(OBJEXT)
+ rufus-syslinux.$(OBJEXT) rufus-ui.$(OBJEXT) \
+ rufus-vhd.$(OBJEXT)
rufus_OBJECTS = $(am_rufus_OBJECTS)
rufus_DEPENDENCIES = rufus_rc.o bled/libbled.a ms-sys/libmssys.a \
syslinux/libfat/libfat.a syslinux/libinstaller/libinstaller.a \
@@ -271,7 +272,7 @@ AM_V_WINDRES_1 = $(WINDRES)
AM_V_WINDRES_ = $(AM_V_WINDRES_$(AM_DEFAULT_VERBOSITY))
AM_V_WINDRES = $(AM_V_WINDRES_$(V))
rufus_SOURCES = badblocks.c checksum.c dev.c dos.c dos_locale.c drive.c format.c icon.c iso.c localization.c \
- net.c parser.c pki.c process.c rufus.c smart.c stdfn.c stdio.c stdlg.c syslinux.c vhd.c
+ net.c parser.c pki.c process.c rufus.c smart.c stdfn.c stdio.c stdlg.c syslinux.c ui.c vhd.c
rufus_CFLAGS = -I./ms-sys/inc -I./syslinux/libfat -I./syslinux/libinstaller -I./syslinux/win -I./libcdio $(AM_CFLAGS)
rufus_LDFLAGS = $(AM_LDFLAGS) -mwindows
@@ -452,6 +453,12 @@ rufus-syslinux.o: syslinux.c
rufus-syslinux.obj: syslinux.c
$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-syslinux.obj `if test -f 'syslinux.c'; then $(CYGPATH_W) 'syslinux.c'; else $(CYGPATH_W) '$(srcdir)/syslinux.c'; fi`
+rufus-ui.o: ui.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-ui.o `test -f 'ui.c' || echo '$(srcdir)/'`ui.c
+
+rufus-ui.obj: ui.c
+ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-ui.obj `if test -f 'ui.c'; then $(CYGPATH_W) 'ui.c'; else $(CYGPATH_W) '$(srcdir)/ui.c'; fi`
+
rufus-vhd.o: vhd.c
$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rufus_CFLAGS) $(CFLAGS) -c -o rufus-vhd.o `test -f 'vhd.c' || echo '$(srcdir)/'`vhd.c
diff --git a/src/rufus.c b/src/rufus.c
index 2fb4b975..1b1a6b45 100644
--- a/src/rufus.c
+++ b/src/rufus.c
@@ -36,7 +36,6 @@
#include
#include
#include
-#include
#include "rufus.h"
#include "missing.h"
@@ -53,11 +52,8 @@
static const char* cmdline_hogger = "rufus.com";
static const char* FileSystemLabel[FS_MAX] = { "FAT", "FAT32", "NTFS", "UDF", "exFAT", "ReFS" };
-static const char* flash_type[BADLOCKS_PATTERN_TYPES] = { "SLC", "MLC", "TLC" };
static const char* ep_reg = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer";
static const char* vs_reg = "Software\\Microsoft\\VisualStudio";
-// Number of steps for each FS for FCC_STRUCTURE_PROGRESS
-const int nb_steps[FS_MAX] = { 5, 5, 12, 1, 10 };
static BOOL existing_key = FALSE; // For LGP set/restore
static BOOL size_check = TRUE;
static BOOL log_displayed = FALSE;
@@ -69,19 +65,13 @@ static BOOL user_changed_label = FALSE;
static BOOL app_changed_label = FALSE;
static BOOL allowed_filesystem[FS_MAX] = { 0 };
static int64_t last_iso_blocking_status;
-static int windows_to_go_selection = 0, selected_pt = -1, selected_fs = -1;
-static int selection_default, row_height, advanced_device_section_height, advanced_format_section_height, image_index;
-static int ddh, bw, hw, fw; // DropDown Height, Main button width, half dropdown width, full dropdown width
-static int sw, mw, bsw, sbw, ssw, tw, dbw; // See GetFullWidth() for details on how these values are used
-static UINT_PTR UM_LANGUAGE_MENU_MAX = UM_LANGUAGE_MENU;
+static int selected_pt = -1, selected_fs = -1;
+static int image_index;
static RECT relaunch_rc = { -65536, -65536, 0, 0};
static UINT uQFChecked = BST_CHECKED, uMBRChecked = BST_UNCHECKED;
-static HFONT hInfoFont;
-static WNDPROC progress_original_proc = NULL;
static HANDLE format_thid = NULL, dialog_handle = NULL;
static HWND hSelectImage = NULL, hStart = NULL;
static char szTimer[12] = "00:00:00";
-static wchar_t wtbtext[2][128];
static unsigned int timer;
static char uppercase_select[64], uppercase_start[64], uppercase_close[64], uppercase_cancel[64];
@@ -91,7 +81,6 @@ extern long grub2_len;
extern char* szStatusMessage;
extern const char* old_c32_name[NB_OLD_C32];
extern const char* cert_name[3];
-extern const char* sfd_name;
/*
* Globals
@@ -100,7 +89,7 @@ OPENED_LIBRARIES_VARS;
RUFUS_UPDATE update = { { 0,0,0 },{ 0,0 }, NULL, NULL };
HINSTANCE hMainInstance;
HWND hMainDialog, hMultiToolbar, hSaveToolbar, hHashToolbar, hAdvancedDeviceToolbar, hAdvancedFormatToolbar, hUpdatesDlg = NULL;
-HIMAGELIST hUpImageList, hDownImageList;
+HFONT hInfoFont;
uint8_t image_options = 0x00;
uint16_t rufus_version[3], embedded_sl_version[2];
uint32_t dur_mins, dur_secs, DrivePort[MAX_DRIVES];;
@@ -116,46 +105,21 @@ BOOL advanced_mode_device, advanced_mode_format, allow_dual_uefi_bios, detect_fa
BOOL use_fake_units, preserve_timestamps = FALSE;
BOOL zero_drive = FALSE, list_non_usb_removable_drives = FALSE, enable_file_indexing, large_drive = FALSE, write_as_image = FALSE;
float fScale = 1.0f;
-int dialog_showing = 0;
+int dialog_showing = 0, selection_default, windows_to_go_selection = 0;
int default_fs, fs, bt, pt, tt; // file system, boot type, partition type, target type
-int cbw, ddw, ddbh = 0, bh = 0; // (empty) check box width, (empty) drop down width, button height (for and without dropdown match)
char szFolderPath[MAX_PATH], app_dir[MAX_PATH], system_dir[MAX_PATH], temp_dir[MAX_PATH], sysnative_dir[MAX_PATH];
char embedded_sl_version_str[2][12] = { "?.??", "?.??" };
char embedded_sl_version_ext[2][32];
char ClusterSizeLabel[MAX_CLUSTER_SIZES][64];
char msgbox[1024], msgbox_title[32], *ini_file = NULL, *image_path = NULL, *short_image_path;
StrArray DriveID, DriveLabel, DriveHub, BlockingProcess, ImageList;
-
-static void ToggleImageOption(uint8_t mask);
-
-/*
- * The following is used to allocate slots within the progress bar
- * 0 means unused (no operation or no progress allocated to it)
- * +n means allocate exactly n bars (n percent of the progress bar)
- * -n means allocate a weighted slot of n from all remaining
- * bars. E.g. if 80 slots remain and the sum of all negative entries
- * is 10, -4 will allocate 4/10*80 = 32 bars (32%) for OP progress
- */
-static int nb_slots[OP_MAX];
-static float slot_end[OP_MAX+1]; // shifted +1 so that we can subtract 1 to OP indexes
-static float previous_end;
+// Number of steps for each FS for FCC_STRUCTURE_PROGRESS
+const int nb_steps[FS_MAX] = { 5, 5, 12, 1, 10 };
+const char* flash_type[BADLOCKS_PATTERN_TYPES] = { "SLC", "MLC", "TLC" };
// TODO: Remember to update copyright year in stdlg's AboutCallback() WM_INITDIALOG,
// localization_data.sh and the .rc when the year changes!
-// Set the combo selection according to the data
-static void SetComboEntry(HWND hDlg, int data) {
- int i;
- for (i = 0; i < ComboBox_GetCount(hDlg); i++) {
- if (ComboBox_GetItemData(hDlg, i) == data) {
- IGNORE_RETVAL(ComboBox_SetCurSel(hDlg, i));
- break;
- }
- }
- if (i == ComboBox_GetCount(hDlg))
- IGNORE_RETVAL(ComboBox_SetCurSel(hDlg, 0));
-}
-
// Fill in the cluster size names
static void SetClusterSizeLabels(void)
{
@@ -656,6 +620,41 @@ static void SetImageOptions(void)
}
}
+static void SetProposedLabel(int ComboIndex)
+{
+ const char no_label[] = STR_NO_LABEL, empty[] = "";
+
+ app_changed_label = TRUE;
+ // If bootable ISO creation is selected, and we have an ISO selected with a valid name, use that
+ // Also some distros (eg. Arch) require the USB to have the same label as the ISO
+ if ((bt == BT_IMAGE) && (image_path != NULL) && (img_report.label[0] != 0)) {
+ SetWindowTextU(hLabel, img_report.label);
+ // If we force the ISO label, we need to reset the user_changed_label flag
+ user_changed_label = FALSE;
+ return;
+ }
+
+ // If the user manually changed the label, try to preserve it
+ if (user_changed_label) {
+ app_changed_label = FALSE;
+ return;
+ }
+
+ // Empty the label if no device is currently selected
+ if (ComboIndex < 0) {
+ SetWindowTextU(hLabel, "");
+ return;
+ }
+
+ // Else if no existing label is available, propose one according to the size (eg: "256MB", "8GB")
+ if ((_stricmp(no_label, DriveLabel.String[ComboIndex]) == 0) || (_stricmp(no_label, empty) == 0)
+ || (safe_stricmp(lmprintf(MSG_207), DriveLabel.String[ComboIndex]) == 0)) {
+ SetWindowTextU(hLabel, SelectedDrive.proposed_label);
+ } else {
+ SetWindowTextU(hLabel, DriveLabel.String[ComboIndex]);
+ }
+}
+
// This handles the enabling/disabling of the "Add fixes for old BIOSes" and "Use Rufus MBR" controls
static void EnableMBRBootOptions(BOOL enable, BOOL remove_checkboxes)
{
@@ -740,41 +739,6 @@ static void EnableBootOptions(BOOL enable, BOOL remove_checkboxes)
EnableWindow(GetDlgItem(hMainDialog, IDC_EXTENDED_LABEL), actual_enable);
}
-static void SetProposedLabel(int ComboIndex)
-{
- const char no_label[] = STR_NO_LABEL, empty[] = "";
-
- app_changed_label = TRUE;
- // If bootable ISO creation is selected, and we have an ISO selected with a valid name, use that
- // Also some distros (eg. Arch) require the USB to have the same label as the ISO
- if ((bt == BT_IMAGE) && (image_path != NULL) && (img_report.label[0] != 0)) {
- SetWindowTextU(hLabel, img_report.label);
- // If we force the ISO label, we need to reset the user_changed_label flag
- user_changed_label = FALSE;
- return;
- }
-
- // If the user manually changed the label, try to preserve it
- if (user_changed_label) {
- app_changed_label = FALSE;
- return;
- }
-
- // Empty the label if no device is currently selected
- if (ComboIndex < 0) {
- SetWindowTextU(hLabel, "");
- return;
- }
-
- // Else if no existing label is available, propose one according to the size (eg: "256MB", "8GB")
- if ((_stricmp(no_label, DriveLabel.String[ComboIndex]) == 0) || (_stricmp(no_label, empty) == 0)
- || (safe_stricmp(lmprintf(MSG_207), DriveLabel.String[ComboIndex]) == 0)) {
- SetWindowTextU(hLabel, SelectedDrive.proposed_label);
- } else {
- SetWindowTextU(hLabel, DriveLabel.String[ComboIndex]);
- }
-}
-
// Toggle controls according to operation
static void EnableControls(BOOL bEnable)
{
@@ -865,128 +829,6 @@ out:
return TRUE;
}
-// Set up progress bar real estate allocation
-static void InitProgress(BOOL bOnlyFormat)
-{
- int i;
- float last_end = 0.0f, slots_discrete = 0.0f, slots_analog = 0.0f;
-
- memset(nb_slots, 0, sizeof(nb_slots));
- memset(slot_end, 0, sizeof(slot_end));
- previous_end = 0.0f;
-
- if (bOnlyFormat) {
- nb_slots[OP_FORMAT] = -1;
- } else {
- nb_slots[OP_ANALYZE_MBR] = 1;
- if (IsChecked(IDC_BAD_BLOCKS)) {
- nb_slots[OP_BADBLOCKS] = -1;
- }
- if (bt != BT_NON_BOOTABLE) {
- // 1 extra slot for PBR writing
- switch (selection_default) {
- case BT_MSDOS:
- nb_slots[OP_DOS] = 3+1;
- break;
- case BT_FREEDOS:
- nb_slots[OP_DOS] = 5+1;
- break;
- case BT_IMAGE:
- nb_slots[OP_DOS] = img_report.is_iso ? -1 : 0;
- break;
- default:
- nb_slots[OP_DOS] = 2+1;
- break;
- }
- }
- if (selection_default == BT_IMAGE && !img_report.is_iso) {
- nb_slots[OP_FORMAT] = -1;
- } else {
- nb_slots[OP_ZERO_MBR] = 1;
- nb_slots[OP_PARTITION] = 1;
- nb_slots[OP_FIX_MBR] = 1;
- nb_slots[OP_CREATE_FS] =
- nb_steps[ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem))];
- if ( (!IsChecked(IDC_QUICK_FORMAT))
- || ((fs == FS_FAT32) && ((SelectedDrive.DiskSize >= LARGE_FAT32_SIZE) || (force_large_fat32))) ) {
- nb_slots[OP_FORMAT] = -1;
- }
- nb_slots[OP_FINALIZE] = ((selection_default == BT_IMAGE) && (fs == FS_NTFS))?3:2;
- }
- }
-
- for (i=0; i 0) {
- slots_discrete += nb_slots[i]*1.0f;
- }
- if (nb_slots[i] < 0) {
- slots_analog += nb_slots[i]*1.0f;
- }
- }
-
- for (i=0; i 0) {
- slot_end[i+1] = last_end + (1.0f * nb_slots[i]);
- } else if (nb_slots[i] < 0) {
- slot_end[i+1] = last_end + (( (100.0f-slots_discrete) * nb_slots[i]) / slots_analog);
- }
- last_end = slot_end[i+1];
- }
-
- // If there's no analog, adjust our discrete ends to fill the whole bar
- if (slots_analog == 0.0f) {
- for (i=0; i= OP_MAX)) {
- duprintf("UpdateProgress: invalid op %d\n", op);
- return;
- }
- if (percent > 100.1f) {
-// duprintf("UpdateProgress(%d): invalid percentage %0.2f\n", op, percent);
- return;
- }
- if ((percent < 0.0f) && (nb_slots[op] <= 0)) {
- duprintf("UpdateProgress(%d): error negative percentage sent for negative slot value\n", op);
- return;
- }
- if (nb_slots[op] == 0)
- return;
- if (previous_end < slot_end[op]) {
- previous_end = slot_end[op];
- }
-
- if (percent < 0.0f) {
- // Negative means advance one slot (1.0%) - requires a positive slot allocation
- previous_end += (slot_end[op+1] - slot_end[op]) / (1.0f * nb_slots[op]);
- pos = (int)(previous_end / 100.0f * MAX_PROGRESS);
- } else {
- pos = (int)((previous_end + ((slot_end[op+1] - previous_end) * (percent / 100.0f))) / 100.0f * MAX_PROGRESS);
- }
- if (pos > MAX_PROGRESS) {
- duprintf("UpdateProgress(%d): rounding error - pos %d is greater than %d\n", op, pos, MAX_PROGRESS);
- pos = MAX_PROGRESS;
- }
-
- // Reduce the refresh rate, to avoid weird effects on the sliding part of progress bar
- if (GetTickCount64() > LastRefresh + (2 * MAX_REFRESH)) {
- LastRefresh = GetTickCount64();
- SendMessage(hProgress, PBM_SETPOS, (WPARAM)pos, 0);
- SetTaskbarProgressValue(pos, MAX_PROGRESS);
- }
-}
-
// Callback for the log window
BOOL CALLBACK LogCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
@@ -1160,196 +1002,6 @@ static void DisplayISOProps(void)
SetImageOptions();
}
-// Move a control along the Y axis
-static __inline void MoveCtrlY(HWND hDlg, int nID, int vertical_shift) {
- ResizeMoveCtrl(hDlg, GetDlgItem(hDlg, nID), 0, vertical_shift, 0, 0, 1.0f);
-}
-
-static void SetPassesTooltip(void)
-{
- const unsigned int pattern[BADLOCKS_PATTERN_TYPES][BADBLOCK_PATTERN_COUNT] =
- { BADBLOCK_PATTERN_SLC, BADCLOCK_PATTERN_MLC, BADBLOCK_PATTERN_TLC };
- int sel = ComboBox_GetCurSel(hNBPasses);
- int type = (sel < 2) ? 0 : sel - 2;
- CreateTooltip(hNBPasses, lmprintf(MSG_153 + ((sel >= 2) ? 3 : sel),
- pattern[type][0], pattern[type][1], pattern[type][2], pattern[type][3]), -1);
-}
-
-static void ResizeDialogs(int shift)
-{
- RECT rc;
- POINT point;
-
- // Resize the main dialog
- GetWindowRect(hMainDialog, &rc);
- point.x = (rc.right - rc.left);
- point.y = (rc.bottom - rc.top);
- MoveWindow(hMainDialog, rc.left, rc.top, point.x, point.y + shift, TRUE);
-
- // Resize the log
- GetWindowRect(hLogDialog, &rc);
- point.x = (rc.right - rc.left);
- point.y = (rc.bottom - rc.top);
- MoveWindow(hLogDialog, rc.left, rc.top, point.x, point.y + shift, TRUE);
- MoveCtrlY(hLogDialog, IDC_LOG_CLEAR, shift);
- MoveCtrlY(hLogDialog, IDC_LOG_SAVE, shift);
- MoveCtrlY(hLogDialog, IDCANCEL, shift);
- GetWindowRect(hLog, &rc);
- point.x = (rc.right - rc.left);
- point.y = (rc.bottom - rc.top) + shift;
- SetWindowPos(hLog, NULL, 0, 0, point.x, point.y, SWP_NOZORDER);
- // Don't forget to scroll the edit to the bottom after resize
- Edit_Scroll(hLog, 0, Edit_GetLineCount(hLog));
-}
-
-// Toggle "advanced" options
-static void ToggleAdvancedDeviceOptions(BOOL enable)
-{
- RECT rc;
- SIZE sz;
- TBBUTTONINFO button_info;
- int i, shift = advanced_device_section_height;
-
- if (!enable)
- shift = -shift;
- section_vpos[1] += shift;
- section_vpos[2] += shift;
-
- // Toggle the Hide/Show toolbar text
- utf8_to_wchar_no_alloc(lmprintf((enable) ? MSG_122 : MSG_121, lmprintf(MSG_119)), wtbtext[0], ARRAYSIZE(wtbtext[0]));
- button_info.cbSize = sizeof(button_info);
- button_info.dwMask = TBIF_TEXT;
- button_info.pszText = wtbtext[0];
- SendMessage(hAdvancedDeviceToolbar, TB_SETBUTTONINFO, (WPARAM)IDC_ADVANCED_DRIVE_PROPERTIES, (LPARAM)&button_info);
- SendMessage(hAdvancedDeviceToolbar, TB_SETIMAGELIST, (WPARAM)0, (LPARAM)((enable) ? hUpImageList : hDownImageList));
- GetWindowRect(hAdvancedDeviceToolbar, &rc);
- MapWindowPoints(NULL, hMainDialog, (POINT*)&rc, 2);
- SendMessage(hAdvancedDeviceToolbar, TB_GETIDEALSIZE, (WPARAM)FALSE, (LPARAM)&sz);
- SetWindowPos(hAdvancedDeviceToolbar, hTargetSystem, rc.left, rc.top, sz.cx, rc.bottom - rc.top, 0);
-
- // Move the controls up or down
- for (i = 0; i= 2) ? 0 : row_height;
-
- assert(__popcnt16(mask) <= 1);
-
- if (mask & IMOP_WINTOGO) {
- if (nWindowsVersion < WINDOWS_8)
- return;
- image_options ^= IMOP_WINTOGO;
- // Set the Windows To Go selection in the dropdown
- IGNORE_RETVAL(ComboBox_SetCurSel(GetDlgItem(hMainDialog, IDC_IMAGE_OPTION), windows_to_go_selection));
- } else if (mask & IMOP_PERSISTENCE) {
- image_options ^= IMOP_PERSISTENCE;
- }
-
- if (__popcnt16(image_options) >= 2)
- shift = 0;
-
- if (shift != 0) {
- if ((mask == 0) || (image_options == 0))
- shift = -shift;
- section_vpos[1] += shift;
- section_vpos[2] += shift;
-
- if (__popcnt16(image_options) <= 1) {
- // Move the controls up or down
- for (i = 0; i < ARRAYSIZE(image_option_move_ids); i++)
- MoveCtrlY(hMainDialog, image_option_move_ids[i], shift);
-
- // Resize the main dialog and log window
- ResizeDialogs(shift);
- }
- }
-
- // Hide or show the boot options
- for (i = 0; i < ARRAYSIZE(image_option_toggle_ids); i++) {
- ShowWindow(GetDlgItem(hMainDialog, image_option_toggle_ids[i][0]),
- (image_options & image_option_toggle_ids[i][1]) ? SW_SHOW : SW_HIDE);
- }
-
- // If you don't force a redraw here, all kind of bad UI artifacts happen...
- InvalidateRect(hMainDialog, NULL, TRUE);
-}
-
-static void SetBootTypeDropdownWidth(void)
-{
- HDC hDC;
- HFONT hFont;
- SIZE sz;
- RECT rc;
-
- if (image_path == NULL)
- return;
- // Set the maximum width of the dropdown according to the image selected
- GetWindowRect(hBootType, &rc);
- MapWindowPoints(NULL, hMainDialog, (POINT*)&rc, 2);
- hDC = GetDC(hBootType);
- hFont = (HFONT)SendMessageA(hBootType, WM_GETFONT, 0, 0);
- SelectObject(hDC, hFont);
- GetTextExtentPointU(hDC, short_image_path, &sz);
- safe_release_dc(hBootType, hDC);
- SendMessage(hBootType, CB_SETDROPPEDWIDTH, (WPARAM)max(sz.cx + 10, rc.right - rc.left), (LPARAM)0);
-}
-
// Insert the image name into the Boot selection dropdown
static void UpdateImage(void)
{
@@ -1812,751 +1464,6 @@ static __inline const char* IsAlphaOrBeta(void)
#endif
}
-static INT_PTR CALLBACK ProgressCallback(HWND hCtrl, UINT message, WPARAM wParam, LPARAM lParam)
-{
- HDC hDC;
- RECT rc, rc2;
- PAINTSTRUCT ps;
- SIZE size;
- LONG full_right;
- wchar_t winfo[128];
- static BOOL marquee_mode = FALSE;
- static uint32_t pos = 0, min = 0, max = 0xFFFF;
- static COLORREF color = PROGRESS_BAR_NORMAL_COLOR;
-
- switch (message) {
-
- case PBM_SETSTATE:
- switch (wParam) {
- case PBST_NORMAL:
- color = PROGRESS_BAR_NORMAL_COLOR;
- break;
- case PBST_PAUSED:
- color = PROGRESS_BAR_PAUSED_COLOR;
- break;
- case PBST_ERROR:
- color = PROGRESS_BAR_ERROR_COLOR;
- break;
- }
- return (INT_PTR)TRUE;
-
- case PBM_SETRANGE:
- // Don't bother sanity checking min and max: If *you* want to
- // be an ass about the progress bar range, it's *your* problem.
- min = (uint32_t)(lParam & 0xFFFF);
- max = (uint32_t)(lParam >> 16);
- return (INT_PTR)TRUE;
-
- case PBM_SETPOS:
- pos = (WORD)wParam;
- InvalidateRect(hProgress, NULL, TRUE);
- return (INT_PTR)TRUE;
-
- case PBM_SETMARQUEE:
- if ((wParam == TRUE) && (!marquee_mode)) {
- marquee_mode = TRUE;
- pos = min;
- color = PROGRESS_BAR_NORMAL_COLOR;
- SetTimer(hCtrl, TID_MARQUEE_TIMER, MARQUEE_TIMER_REFRESH, NULL);
- InvalidateRect(hProgress, NULL, TRUE);
- } else if ((wParam == FALSE) && (marquee_mode)) {
- marquee_mode = FALSE;
- KillTimer(hCtrl, TID_MARQUEE_TIMER);
- pos = min;
- InvalidateRect(hProgress, NULL, TRUE);
- }
- return (INT_PTR)TRUE;
-
- case WM_TIMER:
- if ((wParam == TID_MARQUEE_TIMER) && marquee_mode) {
- pos += max((max - min) / (1000 / MARQUEE_TIMER_REFRESH), 1);
- if ((pos > max) || (pos < min))
- pos = min;
- InvalidateRect(hProgress, NULL, TRUE);
- return (INT_PTR)TRUE;
- }
- return (INT_PTR)FALSE;
-
- case WM_PAINT:
- hDC = BeginPaint(hCtrl, &ps);
- GetClientRect(hCtrl, &rc);
- rc2 = rc;
- InflateRect(&rc, -1, -1);
- SelectObject(hDC, GetStockObject(DC_PEN));
- SelectObject(hDC, GetStockObject(NULL_BRUSH));
- // TODO: Handle SetText message so we can avoid this call
- GetWindowTextW(hProgress, winfo, ARRAYSIZE(winfo));
- SelectObject(hDC, hInfoFont);
- GetTextExtentPoint32(hDC, winfo, (int)wcslen(winfo), &size);
- if (size.cx > rc.right)
- size.cx = rc.right;
- if (size.cy > rc.bottom)
- size.cy = rc.bottom;
- full_right = rc.right;
- if (marquee_mode) {
- // Optional first segment
- if (pos + ((max - min) / 5) > max) {
- rc.right = MulDiv(pos + ((max - min) / 5) - max, rc.right, max - min);
- SetTextColor(hDC, PROGRESS_BAR_INVERTED_TEXT_COLOR);
- SetBkColor(hDC, color);
- ExtTextOut(hDC, (full_right - size.cx) / 2, (rc.bottom - size.cy) / 2,
- ETO_CLIPPED | ETO_OPAQUE | ETO_NUMERICSLOCAL, &rc, winfo, (int)wcslen(winfo), NULL);
- rc.left = rc.right;
- rc.right = full_right;
- }
- // Optional second segment
- if (pos > min) {
- rc.right = MulDiv(pos - min, rc.right, max - min);
- SetTextColor(hDC, PROGRESS_BAR_NORMAL_TEXT_COLOR);
- SetBkColor(hDC, PROGRESS_BAR_BACKGROUND_COLOR);
- ExtTextOut(hDC, (full_right - size.cx) / 2, (rc.bottom - size.cy) / 2,
- ETO_CLIPPED | ETO_OPAQUE | ETO_NUMERICSLOCAL, &rc, winfo, (int)wcslen(winfo), NULL);
- rc.left = rc.right;
- rc.right = full_right;
- }
- // Second to last segment
- rc.right = MulDiv(pos - min + ((max - min) / 5), rc.right, max - min);
- SetTextColor(hDC, PROGRESS_BAR_INVERTED_TEXT_COLOR);
- SetBkColor(hDC, color);
- ExtTextOut(hDC, (full_right - size.cx) / 2, (rc.bottom - size.cy) / 2,
- ETO_CLIPPED | ETO_OPAQUE | ETO_NUMERICSLOCAL, &rc, winfo, (int)wcslen(winfo), NULL);
- } else {
- // First segment
- rc.right = (pos > min) ? MulDiv(pos - min, rc.right, max - min) : rc.left;
- SetTextColor(hDC, PROGRESS_BAR_INVERTED_TEXT_COLOR);
- SetBkColor(hDC, color);
- ExtTextOut(hDC, (full_right - size.cx) / 2, (rc.bottom - size.cy) / 2,
- ETO_CLIPPED | ETO_OPAQUE | ETO_NUMERICSLOCAL, &rc, winfo, (int)wcslen(winfo), NULL);
- }
- // Last segment
- rc.left = rc.right;
- rc.right = full_right;
- SetTextColor(hDC, PROGRESS_BAR_NORMAL_TEXT_COLOR);
- SetBkColor(hDC, PROGRESS_BAR_BACKGROUND_COLOR);
- ExtTextOut(hDC, (full_right - size.cx) / 2, (rc.bottom - size.cy) / 2,
- ETO_CLIPPED | ETO_OPAQUE | ETO_NUMERICSLOCAL, &rc, winfo, (int)wcslen(winfo), NULL);
- // Bounding rectangle
- SetDCPenColor(hDC, PROGRESS_BAR_BOX_COLOR);
- Rectangle(hDC, rc2.left, rc2.top, rc2.right, rc2.bottom);
- EndPaint(hCtrl, &ps);
- return (INT_PTR)TRUE;
- }
-
- return CallWindowProc(progress_original_proc, hCtrl, message, wParam, lParam);
-}
-
-// We need to create the small toolbar buttons first so that we can compute their width
-static void CreateSmallButtons(HWND hDlg)
-{
- HIMAGELIST hImageList;
- HICON hIconSave, hIconHash;
- int icon_offset = 0, i16 = GetSystemMetrics(SM_CXSMICON);
- TBBUTTON tbToolbarButtons[1];
- unsigned char* buffer;
- DWORD bufsize;
-
- if (i16 >= 28)
- icon_offset = 20;
- else if (i16 >= 20)
- icon_offset = 10;
-
- hSaveToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, TOOLBAR_STYLE,
- 0, 0, 0, 0, hMainDialog, (HMENU)IDC_SAVE_TOOLBAR, hMainInstance, NULL);
- hImageList = ImageList_Create(i16, i16, ILC_COLOR32 | ILC_HIGHQUALITYSCALE | ILC_MIRROR, 1, 0);
- buffer = GetResource(hMainInstance, MAKEINTRESOURCEA(IDI_SAVE_16 + icon_offset), _RT_RCDATA, "save icon", &bufsize, FALSE);
- hIconSave = CreateIconFromResourceEx(buffer, bufsize, TRUE, 0x30000, 0, 0, 0);
- ImageList_AddIcon(hImageList, hIconSave);
- DestroyIcon(hIconSave);
- SendMessage(hSaveToolbar, TB_SETIMAGELIST, (WPARAM)0, (LPARAM)hImageList);
- SendMessage(hSaveToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
- memset(tbToolbarButtons, 0, sizeof(TBBUTTON));
- tbToolbarButtons[0].idCommand = IDC_SAVE;
- tbToolbarButtons[0].fsStyle = BTNS_AUTOSIZE;
- tbToolbarButtons[0].fsState = TBSTATE_ENABLED;
- tbToolbarButtons[0].iBitmap = 0;
- SendMessage(hSaveToolbar, TB_ADDBUTTONS, (WPARAM)1, (LPARAM)&tbToolbarButtons);
-
- hHashToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, TOOLBAR_STYLE,
- 0, 0, 0, 0, hMainDialog, (HMENU)IDC_HASH_TOOLBAR, hMainInstance, NULL);
- hImageList = ImageList_Create(i16, i16, ILC_COLOR32 | ILC_HIGHQUALITYSCALE | ILC_MIRROR, 1, 0);
- buffer = GetResource(hMainInstance, MAKEINTRESOURCEA(IDI_HASH_16 + icon_offset), _RT_RCDATA, "hash icon", &bufsize, FALSE);
- hIconHash = CreateIconFromResourceEx(buffer, bufsize, TRUE, 0x30000, 0, 0, 0);
- ImageList_AddIcon(hImageList, hIconHash);
- DestroyIcon(hIconHash);
- SendMessage(hHashToolbar, TB_SETIMAGELIST, (WPARAM)0, (LPARAM)hImageList);
- SendMessage(hHashToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
- memset(tbToolbarButtons, 0, sizeof(TBBUTTON));
- tbToolbarButtons[0].idCommand = IDC_HASH;
- tbToolbarButtons[0].fsStyle = BTNS_AUTOSIZE;
- tbToolbarButtons[0].fsState = TBSTATE_ENABLED;
- tbToolbarButtons[0].iBitmap = 0;
- SendMessage(hHashToolbar, TB_ADDBUTTONS, (WPARAM)1, (LPARAM)&tbToolbarButtons);
-}
-
-static void CreateAdditionalControls(HWND hDlg)
-{
- HINSTANCE hDll;
- HIMAGELIST hToolbarImageList;
- HICON hIcon, hIconUp, hIconDown;
- RECT rc;
- SIZE sz;
- int icon_offset = 0, i, i16, s16, toolbar_dx = -4 - ((fScale > 1.49f) ? 1 : 0) - ((fScale > 1.99f) ? 1 : 0);
- TBBUTTON tbToolbarButtons[7];
- unsigned char* buffer;
- DWORD bufsize;
-
- s16 = i16 = GetSystemMetrics(SM_CXSMICON);
- if (s16 >= 54)
- s16 = 64;
- else if (s16 >= 40)
- s16 = 48;
- else if (s16 >= 28)
- s16 = 32;
- else if (s16 >= 20)
- s16 = 24;
- if (i16 >= 28)
- icon_offset = 20;
- else if (i16 >= 20)
- icon_offset = 10;
-
- // Fetch the up and down expand icons for the advanced options toolbar
- hDll = GetLibraryHandle("ComDlg32");
- hIconDown = (HICON)LoadImage(hDll, MAKEINTRESOURCE(577), IMAGE_ICON, s16, s16, LR_DEFAULTCOLOR | LR_SHARED);
- hIconUp = (HICON)LoadImage(hDll, MAKEINTRESOURCE(578), IMAGE_ICON, s16, s16, LR_DEFAULTCOLOR | LR_SHARED);
- // Fallback to using Shell32 if we can't locate the icons we want in ComDlg32
- hDll = GetLibraryHandle("Shell32");
- if (hIconUp == NULL)
- hIconUp = (HICON)LoadImage(hDll, MAKEINTRESOURCE(16749), IMAGE_ICON, s16, s16, LR_DEFAULTCOLOR | LR_SHARED);
- if (hIconDown == NULL)
- hIconDown = (HICON)LoadImage(hDll, MAKEINTRESOURCE(16750), IMAGE_ICON, s16, s16, LR_DEFAULTCOLOR | LR_SHARED);
- hUpImageList = ImageList_Create(i16, i16, ILC_COLOR32 | ILC_HIGHQUALITYSCALE, 1, 0);
- hDownImageList = ImageList_Create(i16, i16, ILC_COLOR32 | ILC_HIGHQUALITYSCALE, 1, 0);
- ImageList_AddIcon(hUpImageList, hIconUp);
- ImageList_AddIcon(hDownImageList, hIconDown);
-
- // Create the advanced options toolbars
- memset(wtbtext, 0, sizeof(wtbtext));
- utf8_to_wchar_no_alloc(lmprintf((advanced_mode_device) ? MSG_122 : MSG_121, lmprintf(MSG_119)), wtbtext[0], ARRAYSIZE(wtbtext[0]));
- hAdvancedDeviceToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, TOOLBAR_STYLE,
- 0, 0, 0, 0, hMainDialog, (HMENU)IDC_ADVANCED_DEVICE_TOOLBAR, hMainInstance, NULL);
- SendMessage(hAdvancedDeviceToolbar, CCM_SETVERSION, (WPARAM)6, 0);
- memset(tbToolbarButtons, 0, sizeof(TBBUTTON));
- tbToolbarButtons[0].idCommand = IDC_ADVANCED_DRIVE_PROPERTIES;
- tbToolbarButtons[0].fsStyle = BTNS_SHOWTEXT | BTNS_AUTOSIZE;
- tbToolbarButtons[0].fsState = TBSTATE_ENABLED;
- tbToolbarButtons[0].iString = (INT_PTR)wtbtext[0];
- tbToolbarButtons[0].iBitmap = 0;
- SendMessage(hAdvancedDeviceToolbar, TB_SETIMAGELIST, 0, (LPARAM)hUpImageList);
- SendMessage(hAdvancedDeviceToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
- SendMessage(hAdvancedDeviceToolbar, TB_ADDBUTTONS, 1, (LPARAM)&tbToolbarButtons);
- GetWindowRect(GetDlgItem(hDlg, IDC_ADVANCED_DRIVE_PROPERTIES), &rc);
- MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
- SendMessage(hAdvancedDeviceToolbar, TB_GETIDEALSIZE, (WPARAM)FALSE, (LPARAM)&sz);
- // Yeah, so, like, TB_GETIDEALSIZE totally super doesn't work on Windows 7, for low zoom factor and when compiled with MSVC...
- if (sz.cx < 16)
- sz.cx = fw;
- SetWindowPos(hAdvancedDeviceToolbar, hTargetSystem, rc.left + toolbar_dx, rc.top, sz.cx, rc.bottom - rc.top, 0);
-
- utf8_to_wchar_no_alloc(lmprintf((advanced_mode_format) ? MSG_122 : MSG_121, lmprintf(MSG_120)), wtbtext[1], ARRAYSIZE(wtbtext[1]));
- hAdvancedFormatToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, TOOLBAR_STYLE,
- 0, 0, 0, 0, hMainDialog, (HMENU)IDC_ADVANCED_FORMAT_TOOLBAR, hMainInstance, NULL);
- SendMessage(hAdvancedFormatToolbar, CCM_SETVERSION, (WPARAM)6, 0);
- memset(tbToolbarButtons, 0, sizeof(TBBUTTON));
- tbToolbarButtons[0].idCommand = IDC_ADVANCED_FORMAT_OPTIONS;
- tbToolbarButtons[0].fsStyle = BTNS_SHOWTEXT | BTNS_AUTOSIZE;
- tbToolbarButtons[0].fsState = TBSTATE_ENABLED;
- tbToolbarButtons[0].iString = (INT_PTR)wtbtext[1];
- tbToolbarButtons[0].iBitmap = 0;
- SendMessage(hAdvancedFormatToolbar, TB_SETIMAGELIST, (WPARAM)0, (LPARAM)hUpImageList);
- SendMessage(hAdvancedFormatToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
- SendMessage(hAdvancedFormatToolbar, TB_ADDBUTTONS, (WPARAM)1, (LPARAM)&tbToolbarButtons);
- GetWindowRect(GetDlgItem(hDlg, IDC_ADVANCED_FORMAT_OPTIONS), &rc);
- MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
- SendMessage(hAdvancedFormatToolbar, TB_GETIDEALSIZE, (WPARAM)FALSE, (LPARAM)&sz);
- if (sz.cx < 16)
- sz.cx = fw;
- SetWindowPos(hAdvancedFormatToolbar, hClusterSize, rc.left + toolbar_dx, rc.top, sz.cx, rc.bottom - rc.top, 0);
-
- // Create the multi toolbar
- hMultiToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, TOOLBAR_STYLE,
- 0, 0, 0, 0, hMainDialog, (HMENU)IDC_MULTI_TOOLBAR, hMainInstance, NULL);
- hToolbarImageList = ImageList_Create(i16, i16, ILC_COLOR32 | ILC_HIGHQUALITYSCALE, 8, 0);
- for (i = 0; i < ARRAYSIZE(multitoolbar_icons); i++) {
- buffer = GetResource(hMainInstance, MAKEINTRESOURCEA(multitoolbar_icons[i] + icon_offset),
- _RT_RCDATA, "toolbar icon", &bufsize, FALSE);
- hIcon = CreateIconFromResourceEx(buffer, bufsize, TRUE, 0x30000, 0, 0, 0);
- // Mirror the "world" icon on RTL since we can't use an ImageList mirroring flag for that...
- if (right_to_left_mode && (i == 0))
- hIcon = CreateMirroredIcon(hIcon);
- ImageList_AddIcon(hToolbarImageList, hIcon);
- DestroyIcon(hIcon);
- }
- SendMessage(hMultiToolbar, TB_SETIMAGELIST, (WPARAM)0, (LPARAM)hToolbarImageList);
- SendMessage(hMultiToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
- memset(tbToolbarButtons, 0, sizeof(TBBUTTON) * ARRAYSIZE(tbToolbarButtons));
- tbToolbarButtons[0].idCommand = IDC_LANG;
- tbToolbarButtons[0].fsStyle = BTNS_BUTTON;
- tbToolbarButtons[0].fsState = TBSTATE_ENABLED;
- tbToolbarButtons[0].iBitmap = 0;
- tbToolbarButtons[1].fsStyle = BTNS_AUTOSIZE;
- tbToolbarButtons[1].fsState = TBSTATE_INDETERMINATE;
- tbToolbarButtons[1].iBitmap = I_IMAGENONE;
- tbToolbarButtons[1].iString = (fScale < 1.5f) ? (INT_PTR)L"" : (INT_PTR)L" ";
- tbToolbarButtons[2].idCommand = IDC_ABOUT;
- tbToolbarButtons[2].fsStyle = BTNS_BUTTON;
- tbToolbarButtons[2].fsState = TBSTATE_ENABLED;
- tbToolbarButtons[2].iBitmap = 1;
- tbToolbarButtons[3].fsStyle = BTNS_AUTOSIZE;
- tbToolbarButtons[3].fsState = TBSTATE_INDETERMINATE;
- tbToolbarButtons[3].iBitmap = I_IMAGENONE;
- tbToolbarButtons[3].iString = (fScale < 1.5f) ? (INT_PTR)L"" : (INT_PTR)L" ";
- tbToolbarButtons[4].idCommand = IDC_SETTINGS;
- tbToolbarButtons[4].fsStyle = BTNS_BUTTON;
- tbToolbarButtons[4].fsState = TBSTATE_ENABLED;
- tbToolbarButtons[4].iBitmap = 2;
- tbToolbarButtons[5].fsStyle = BTNS_AUTOSIZE;
- tbToolbarButtons[5].fsState = TBSTATE_INDETERMINATE;
- tbToolbarButtons[5].iBitmap = I_IMAGENONE;
- tbToolbarButtons[5].iString = (fScale < 1.5f) ? (INT_PTR)L"" : (INT_PTR)L" ";
- tbToolbarButtons[6].idCommand = IDC_LOG;
- tbToolbarButtons[6].fsStyle = BTNS_BUTTON;
- tbToolbarButtons[6].fsState = TBSTATE_ENABLED;
- tbToolbarButtons[6].iBitmap = 3;
- SendMessage(hMultiToolbar, TB_ADDBUTTONS, (WPARAM)7, (LPARAM)&tbToolbarButtons);
- SendMessage(hMultiToolbar, TB_SETBUTTONSIZE, 0, MAKELPARAM(i16, ddbh));
-}
-
-// https://stackoverflow.com/a/20926332/1069307
-// https://msdn.microsoft.com/en-us/library/windows/desktop/bb226818.aspx
-static void GetBasicControlsWidth(HWND hDlg)
-{
- int checkbox_internal_spacing = 12, dropdown_internal_spacing = 15;
- RECT rc = { 0, 0, 4, 8 };
- SIZE sz;
-
- // Compute base unit sizes since GetDialogBaseUnits() returns garbage data.
- // See http://support.microsoft.com/kb/125681
- MapDialogRect(hDlg, &rc);
- sz.cx = rc.right;
- sz.cy = rc.bottom;
-
- // TODO: figure out the specifics of each Windows version
- if (nWindowsVersion == WINDOWS_10) {
- checkbox_internal_spacing = 10;
- dropdown_internal_spacing = 13;
- }
-
- // Checkbox and (blank) dropdown widths
- cbw = MulDiv(checkbox_internal_spacing, sz.cx, 4);
- ddw = MulDiv(dropdown_internal_spacing, sz.cx, 4);
-
- // Spacing width between half-length dropdowns (sep) as well as left margin
- GetWindowRect(GetDlgItem(hDlg, IDC_TARGET_SYSTEM), &rc);
- MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
- sw = rc.left;
- GetWindowRect(GetDlgItem(hDlg, IDC_PARTITION_TYPE), &rc);
- MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
- sw -= rc.right;
- mw = rc.left;
-
- // Small button width
- SendMessage(hSaveToolbar, TB_GETIDEALSIZE, (WPARAM)FALSE, (LPARAM)&sz);
- sbw = sz.cx;
-
- // Small separator widths and button height
- GetWindowRect(GetDlgItem(hDlg, IDC_SAVE), &rc);
- MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
- bh = rc.bottom - rc.top;
- ssw = rc.left;
- GetWindowRect(hDeviceList, &rc);
- MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
- ssw -= rc.right;
-
- // CSM tooltip separator width
- GetWindowRect(GetDlgItem(hDlg, IDS_CSM_HELP_TXT), &rc);
- MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
- tw = rc.left;
- GetWindowRect(hTargetSystem, &rc);
- MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
- tw -= rc.right;
-}
-
-// Compute the minimum size of the main buttons
-static void GetMainButtonsWidth(HWND hDlg)
-{
- unsigned int i;
- RECT rc;
-
- GetWindowRect(GetDlgItem(hDlg, main_button_ids[0]), &rc);
- MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
- bw = rc.right - rc.left;
-
- for (i = 0; i < ARRAYSIZE(main_button_ids); i++)
- bw = max(bw, GetTextWidth(hDlg, main_button_ids[i]) + cbw);
- // The 'CLOSE' button is also be used to display 'CANCEL' => measure that too
- bw = max(bw, GetTextSize(GetDlgItem(hDlg, IDCANCEL), lmprintf(MSG_007)).cx + cbw);
-}
-
-// The following goes over the data that gets populated into the half-width dropdowns
-// (Partition scheme, Target System, Disk ID, File system, Cluster size, Nb passes)
-// to figure out the minimum width we should allocate.
-static void GetHalfDropwdownWidth(HWND hDlg)
-{
- RECT rc;
- unsigned int i, j, msg_id;
- char tmp[256];
-
- // Initialize half width to the UI's default size
- GetWindowRect(GetDlgItem(hDlg, IDC_PARTITION_TYPE), &rc);
- MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
- hw = rc.right - rc.left - ddw;
-
- // "Super Floppy Disk" is the longuest entry in the Partition Scheme dropdown
- hw = max(hw, GetTextSize(GetDlgItem(hDlg, IDC_PARTITION_TYPE), (char*)sfd_name).cx);
-
- // This is basically the same as SetClusterSizeLabels() except we're adding (Default) to each entry
- for (i = 512, j = 1, msg_id = MSG_026; j 8192) {
- i /= 1024;
- msg_id++;
- }
- safe_sprintf(tmp, 64, "%d %s", i, lmprintf(msg_id));
- hw = max(hw, GetTextSize(GetDlgItem(hDlg, IDC_CLUSTER_SIZE), lmprintf(MSG_030, tmp)).cx);
- }
- // We don't go over file systems, because none of them will be longer than "Super Floppy Disk"
- // We do however go over the BIOS vs UEFI entries, as some of these are translated
- for (msg_id = MSG_031; msg_id <= MSG_033; msg_id++)
- hw = max(hw, GetTextSize(GetDlgItem(hDlg, IDC_TARGET_SYSTEM), lmprintf(msg_id)).cx);
-
- // Just in case, we also do the number of passes
- for (i = 1; i <= 5; i++) {
- char* msg = (i == 1) ? lmprintf(MSG_034, 1) : lmprintf(MSG_035, (i == 2) ? 2 : 4, (i == 2) ? "" : lmprintf(MSG_087, flash_type[i - 3]));
- hw = max(hw, GetTextSize(GetDlgItem(hDlg, IDC_TARGET_SYSTEM), msg).cx);
- }
-
- // Finally, we must ensure that we'll have enough space for the 2 checkbox controls
- // that end up with a half dropdown
- hw = max(hw, GetTextWidth(hDlg, IDC_RUFUS_MBR) - sw);
- hw = max(hw, GetTextWidth(hDlg, IDC_BAD_BLOCKS) - sw);
-
- // Add the width of a blank dropdown
- hw += ddw;
-}
-
-/*
- * dbw = dialog border width
- * mw = margin width
- * fw = full dropdown width
- * hd = half dropdown width
- * bsw = boot selection dropdown width
- * sw = separator width
- * ssw = small separator width
- * bw = button width
- * sbw = small button width
- *
- * | fw |
- * | bsw | ssw | sbw | ssw | bw |
- * 8 ->|<- 96 ->|<- 24 ->|<- 96 ->|<- 8
- * mw | hw | sw | hw | mw
- * | bw | ssw | bw |
- */
-static void GetFullWidth(HWND hDlg)
-{
- RECT rc;
- int i;
-
- // Get the dialog border width
- GetWindowRect(hDlg, &rc);
- dbw = rc.right - rc.left;
- GetClientRect(hDlg, &rc);
- dbw -= rc.right - rc.left;
-
- // Compute the minimum size needed for the Boot Selection dropdown
- GetWindowRect(GetDlgItem(hDlg, IDC_BOOT_SELECTION), &rc);
- MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
-
- bsw = max(rc.right - rc.left, GetTextSize(hBootType, lmprintf(MSG_279)).cx + ddw);
- bsw = max(bsw, GetTextSize(hBootType, lmprintf(MSG_281, lmprintf(MSG_280))).cx + ddw);
-
- // Initialize full width to the UI's default size
- GetWindowRect(GetDlgItem(hDlg, IDC_IMAGE_OPTION), &rc);
- MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
- fw = rc.right - rc.left - ddw;
-
- // Go through the Image Options for Windows To Go
- fw = max(fw, GetTextSize(GetDlgItem(hDlg, IDC_IMAGE_OPTION), lmprintf(MSG_117)).cx);
- fw = max(fw, GetTextSize(GetDlgItem(hDlg, IDC_IMAGE_OPTION), lmprintf(MSG_118)).cx);
-
- // Now deal with full length checkbox lines
- for (i=0; i> 16;
- SendMessage(hSaveToolbar, TB_SETPADDING, 0, MAKELPARAM(sz.cx + 3, sz.cy + 2));
- SetWindowPos(hSaveToolbar, hDeviceList, mw + fw - sbw, rc.top, sbw, ddbh, 0);
-
- // Reposition the Hash button
- hCtrl = GetDlgItem(hDlg, IDC_HASH);
- GetWindowRect(hCtrl, &rc);
- MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
- SendMessage(hHashToolbar, TB_GETIDEALSIZE, (WPARAM)FALSE, (LPARAM)&sz);
- SendMessage(hHashToolbar, TB_SETBUTTONSIZE, 0, MAKELPARAM(sz.cx, ddbh));
- padding = (DWORD) SendMessage(hHashToolbar, TB_GETPADDING, 0, 0);
- sz.cx = padding & 0xFFFF;
- sz.cy = padding >> 16;
- SendMessage(hHashToolbar, TB_SETPADDING, 0, MAKELPARAM(sz.cx + 3, sz.cy + 2));
- SetWindowPos(hHashToolbar, hBootType, mw + bsw + ssw, rc.top, sbw, ddbh, 0);
-
- // Reposition the CSM help tip
- hCtrl = GetDlgItem(hDlg, IDS_CSM_HELP_TXT);
- GetWindowRect(hCtrl, &rc);
- MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
- SetWindowPos(hCtrl, hTargetSystem, mw + fw + tw, rc.top, sbw, rc.bottom - rc.top, 0);
-
- if (advanced_mode_device) {
- // Still need to adjust the width of the device selection dropdown
- GetWindowRect(hDeviceList, &rc);
- MapWindowPoints(NULL, hMainDialog, (POINT*)&rc, 2);
- SetWindowPos(hDeviceList, HWND_TOP, rc.left, rc.top, fw - ssw - sbw, rc.bottom - rc.top, 0);
- }
-
- // Resize the full width controls
- for (i = 0; i < ARRAYSIZE(full_width_controls); i++) {
- hCtrl = GetDlgItem(hDlg, full_width_controls[i]);
- GetWindowRect(hCtrl, &rc);
- MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
- hPrevCtrl = GetNextWindow(hCtrl, GW_HWNDPREV);
- SetWindowPos(hCtrl, hPrevCtrl, rc.left, rc.top, fw, rc.bottom - rc.top, 0);
- }
-
- // Resize the half drowpdowns
- for (i = 0; i < ARRAYSIZE(half_width_ids); i++) {
- hCtrl = GetDlgItem(hDlg, half_width_ids[i]);
- GetWindowRect(hCtrl, &rc);
- MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
- // First 5 controls are on the left handside
- // First 2 controls may overflow into separator
- hPrevCtrl = GetNextWindow(hCtrl, GW_HWNDPREV);
- SetWindowPos(hCtrl, hPrevCtrl, (i < 5) ? rc.left : mw + hw + sw, rc.top,
- (i <2) ? hw + sw : hw, rc.bottom - rc.top, 0);
- }
-
- // Resize the boot selection dropdown
- hCtrl = GetDlgItem(hDlg, IDC_BOOT_SELECTION);
- GetWindowRect(hCtrl, &rc);
- MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
- hPrevCtrl = GetNextWindow(hCtrl, GW_HWNDPREV);
- SetWindowPos(hCtrl, hPrevCtrl, rc.left, rc.top, bsw, rc.bottom - rc.top, 0);
-}
-
-// Thanks to Microsoft atrocious DPI handling, we must adjust for low DPI
-static void AdjustForLowDPI(HWND hDlg)
-{
- static int ddy = 4;
- int i, j;
- RECT rc;
- HWND hCtrl, hPrevCtrl;
- int dy = 0;
-
- if (fScale >= 1.3f)
- return;
-
- for (i = 0; i < ARRAYSIZE(adjust_dpi_ids); i++) {
- dy += ddy;
- // "...and the other thing I really like about Microsoft's UI handling is how "
- //."you never have to introduce weird hardcoded constants all over the place, "
- // "just to make your UI look good...", said NO ONE ever.
- if (adjust_dpi_ids[i][0] == IDC_QUICK_FORMAT)
- dy += 1;
- for (j = 0; j < 5; j++) {
- if (adjust_dpi_ids[i][j] == 0)
- break;
- hCtrl = GetDlgItem(hDlg, adjust_dpi_ids[i][j]);
- GetWindowRect(hCtrl, &rc);
- MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
- hPrevCtrl = GetNextWindow(hCtrl, GW_HWNDPREV);
- SetWindowPos(hCtrl, hPrevCtrl, rc.left, rc.top + dy,
- rc.right - rc.left, rc.bottom - rc.top, 0);
- }
- }
-
- section_vpos[1] += 9 * ddy;
- section_vpos[2] += 16 * ddy + 1;
- advanced_device_section_height += 3 * ddy;
- advanced_format_section_height += 3 * ddy + 1;
-
- ResizeDialogs(dy + 2*ddy);
- InvalidateRect(hDlg, NULL, TRUE);
-}
-
-static void SetSectionHeaders(HWND hDlg)
-{
- RECT rc;
- HWND hCtrl;
- SIZE sz;
- HFONT hf;
- wchar_t wtmp[128];
- size_t wlen;
- int i;
-
- // Set the section header fonts and resize the static controls accordingly
- hf = CreateFontA(-MulDiv(14, GetDeviceCaps(GetDC(hMainDialog), LOGPIXELSY), 72), 0, 0, 0,
- FW_SEMIBOLD, FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0, PROOF_QUALITY, 0, "Segoe UI");
-
- for (i = 0; i < ARRAYSIZE(section_control_ids); i++) {
- SendDlgItemMessageA(hDlg, section_control_ids[i], WM_SETFONT, (WPARAM)hf, TRUE);
- hCtrl = GetDlgItem(hDlg, section_control_ids[i]);
- memset(wtmp, 0, sizeof(wtmp));
- GetWindowTextW(hCtrl, wtmp, ARRAYSIZE(wtmp));
- wlen = wcslen(wtmp);
- wtmp[wlen++] = L' ';
- wtmp[wlen++] = L' ';
- SetWindowTextW(hCtrl, wtmp);
- GetWindowRect(hCtrl, &rc);
- MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
- sz = GetTextSize(hCtrl, NULL);
- SetWindowPos(hCtrl, NULL, rc.left, rc.top, sz.cx, sz.cy, SWP_NOZORDER);
- }
-}
-
-// Create the horizontal section lines
-void OnPaint(HDC hdc)
-{
- int i;
- HPEN hp = CreatePen(0, (fScale < 1.5f)?2:3, RGB(0, 0, 0));
- SelectObject(hdc, hp);
- for (i = 0; i < ARRAYSIZE(section_vpos); i++) {
- MoveToEx(hdc, mw + 10, section_vpos[i], NULL);
- LineTo(hdc, mw + fw, section_vpos[i]);
- }
-}
-
static void InitDialog(HWND hDlg)
{
DWORD len;
@@ -2703,16 +1610,13 @@ static void InitDialog(HWND hDlg)
CreateAdditionalControls(hDlg);
SetSectionHeaders(hDlg);
- PositionControls(hDlg);
+ PositionMainControls(hDlg);
AdjustForLowDPI(hDlg);
// Because we created the log dialog before we computed our sizes, we need to send a custom message
SendMessage(hLogDialog, UM_RESIZE_BUTTONS, 0, 0);
// Create the status line and initialize the taskbar icon for progress overlay
CreateStatusBar();
- // Subclass the progress bar so that we can write on it
- progress_original_proc = (WNDPROC)SetWindowLongPtr(hProgress, GWLP_WNDPROC, (LONG_PTR)ProgressCallback);
-
// Set the various tooltips
CreateTooltip(hFileSystem, lmprintf(MSG_157), -1);
CreateTooltip(hClusterSize, lmprintf(MSG_158), -1);
@@ -2757,41 +1661,6 @@ static void PrintStatusTimeout(const char* str, BOOL val)
PrintStatus(STATUS_MSG_TIMEOUT, (val)?MSG_250:MSG_251, str);
}
-static void ShowLanguageMenu(RECT rcExclude)
-{
- TPMPARAMS tpm;
- HMENU menu;
- loc_cmd* lcmd = NULL;
- char lang[256];
- char *search = "()";
- char *l, *r, *str;
-
- UM_LANGUAGE_MENU_MAX = UM_LANGUAGE_MENU;
- menu = CreatePopupMenu();
- list_for_each_entry(lcmd, &locale_list, loc_cmd, list) {
- // The appearance of LTR languages must be fixed for RTL menus
- if ((right_to_left_mode) && (!(lcmd->ctrl_id & LOC_RIGHT_TO_LEFT))) {
- str = safe_strdup(lcmd->txt[1]);
- l = strtok(str, search);
- r = strtok(NULL, search);
- static_sprintf(lang, LEFT_TO_RIGHT_EMBEDDING "(%s) " POP_DIRECTIONAL_FORMATTING "%s", r, l);
- safe_free(str);
- } else {
- static_strcpy(lang, lcmd->txt[1]);
- }
- InsertMenuU(menu, -1, MF_BYPOSITION|((selected_locale == lcmd)?MF_CHECKED:0), UM_LANGUAGE_MENU_MAX++, lang);
- }
-
- // Open the menu such that it doesn't overlap the specified rect
- tpm.cbSize = sizeof(TPMPARAMS);
- tpm.rcExclude = rcExclude;
- TrackPopupMenuEx(menu, 0,
- right_to_left_mode ? rcExclude.right : rcExclude.left, // In RTL languages, the menu should be placed at the bottom-right of the rect
- rcExclude.bottom, hMainDialog, &tpm);
-
- DestroyMenu(menu);
-}
-
static void SaveVHD(void)
{
static IMG_SAVE img_save = { 0 };
@@ -3013,7 +1882,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA
case WM_COMMAND:
#ifdef RUFUS_TEST
if (LOWORD(wParam) == IDC_TEST) {
- DownloadSignedFile(FILES_URL "/gendb.sh", "C:\\Downloads\\gendb.sh", hProgress);
+ DownloadSignedFile(FILES_URL "/gendb.sh", "C:\\Downloads\\gendb.sh", hProgress, TRUE);
break;
}
#endif
diff --git a/src/rufus.h b/src/rufus.h
index ebd649df..d6eb8e4f 100644
--- a/src/rufus.h
+++ b/src/rufus.h
@@ -428,6 +428,7 @@ extern char* image_path;
/*
* Shared prototypes
*/
+extern uint8_t popcnt8(uint8_t val);
extern void GetWindowsVersion(void);
extern BOOL is_x64(void);
extern const char *WindowsErrorString(void);
diff --git a/src/rufus.rc b/src/rufus.rc
index b05e202e..e09246f2 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.2.1329"
+CAPTION "Rufus 3.2.1330"
FONT 9, "Segoe UI Symbol", 400, 0, 0x0
BEGIN
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
@@ -392,8 +392,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 3,2,1329,0
- PRODUCTVERSION 3,2,1329,0
+ FILEVERSION 3,2,1330,0
+ PRODUCTVERSION 3,2,1330,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -410,13 +410,13 @@ BEGIN
BEGIN
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
VALUE "FileDescription", "Rufus"
- VALUE "FileVersion", "3.2.1329"
+ VALUE "FileVersion", "3.2.1330"
VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011-2018 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
VALUE "OriginalFilename", "rufus.exe"
VALUE "ProductName", "Rufus"
- VALUE "ProductVersion", "3.2.1329"
+ VALUE "ProductVersion", "3.2.1330"
END
END
BLOCK "VarFileInfo"
diff --git a/src/stdfn.c b/src/stdfn.c
index 6f0890b6..be1c6c8c 100644
--- a/src/stdfn.c
+++ b/src/stdfn.c
@@ -36,6 +36,16 @@ int nWindowsVersion = WINDOWS_UNDEFINED;
int nWindowsBuildNumber = -1;
char WindowsVersionStr[128] = "Windows ";
+// __popcnt16, __popcnt, __popcnt64 are not available for ARM :(
+uint8_t popcnt8(uint8_t val)
+{
+ static const uint8_t nibble_lookup[16] = {
+ 0, 1, 1, 2, 1, 2, 2, 3,
+ 1, 2, 2, 3, 2, 3, 3, 4
+ };
+ return nibble_lookup[val & 0x0F] + nibble_lookup[val >> 4];
+}
+
/*
* Hash table functions - modified From glibc 2.3.2:
* [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
diff --git a/src/stdlg.c b/src/stdlg.c
index 6032f1f2..a7067b1d 100644
--- a/src/stdlg.c
+++ b/src/stdlg.c
@@ -37,6 +37,7 @@
#include "resource.h"
#include "msapi_utf8.h"
#include "localization.h"
+#include "ui.h"
#include "registry.h"
#include "settings.h"
@@ -58,9 +59,6 @@ static WNDPROC update_original_proc = NULL;
static HWINEVENTHOOK fp_weh = NULL;
static char *fp_title_str = "Microsoft Windows", *fp_button_str = "Format disk";
-extern loc_cmd* selected_locale;
-extern int cbw, ddw, ddbh, bh;
-
static int update_settings_reposition_ids[] = {
IDC_POLICY,
IDS_UPDATE_SETTINGS_GRP,
diff --git a/src/ui.c b/src/ui.c
new file mode 100644
index 00000000..5251f85f
--- /dev/null
+++ b/src/ui.c
@@ -0,0 +1,1177 @@
+/*
+ * Rufus: The Reliable USB Formatting Utility
+ * UI-related function calls
+ * Copyright © 2018 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
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+ /* Memory leaks detection - define _CRTDBG_MAP_ALLOC as preprocessor macro */
+#ifdef _CRTDBG_MAP_ALLOC
+#include
+#include
+#endif
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "rufus.h"
+#include "drive.h"
+#include "missing.h"
+#include "resource.h"
+#include "msapi_utf8.h"
+#include "localization.h"
+
+#include "ui.h"
+#include "ui_data.h"
+
+UINT_PTR UM_LANGUAGE_MENU_MAX = UM_LANGUAGE_MENU;
+HIMAGELIST hUpImageList, hDownImageList;
+int advanced_device_section_height, advanced_format_section_height;
+// (empty) check box width, (empty) drop down width, button height (for and without dropdown match)
+int cbw, ddw, ddbh = 0, bh = 0;
+// Row Height, DropDown Height, Main button width, half dropdown width, full dropdown width
+static int rh, ddh, bw, hw, fw;
+// See GetFullWidth() for details on how these values are used
+static int sw, mw, bsw, sbw, ssw, tw, dbw;
+static WNDPROC progress_original_proc = NULL;
+static wchar_t wtbtext[2][128];
+
+/*
+ * The following is used to allocate slots within the progress bar
+ * 0 means unused (no operation or no progress allocated to it)
+ * +n means allocate exactly n bars (n percent of the progress bar)
+ * -n means allocate a weighted slot of n from all remaining
+ * bars. E.g. if 80 slots remain and the sum of all negative entries
+ * is 10, -4 will allocate 4/10*80 = 32 bars (32%) for OP progress
+ */
+static int nb_slots[OP_MAX];
+static float slot_end[OP_MAX+1]; // shifted +1 so that we can subtract 1 to OP indexes
+static float previous_end;
+
+// Set the combo selection according to the data
+void SetComboEntry(HWND hDlg, int data)
+{
+ int i;
+ for (i = 0; i < ComboBox_GetCount(hDlg); i++) {
+ if (ComboBox_GetItemData(hDlg, i) == data) {
+ IGNORE_RETVAL(ComboBox_SetCurSel(hDlg, i));
+ break;
+ }
+ }
+ if (i == ComboBox_GetCount(hDlg))
+ IGNORE_RETVAL(ComboBox_SetCurSel(hDlg, 0));
+}
+
+// Move a control along the Y axis
+static __inline void MoveCtrlY(HWND hDlg, int nID, int vertical_shift) {
+ ResizeMoveCtrl(hDlg, GetDlgItem(hDlg, nID), 0, vertical_shift, 0, 0, 1.0f);
+}
+
+// https://stackoverflow.com/a/20926332/1069307
+// https://msdn.microsoft.com/en-us/library/windows/desktop/bb226818.aspx
+void GetBasicControlsWidth(HWND hDlg)
+{
+ int checkbox_internal_spacing = 12, dropdown_internal_spacing = 15;
+ RECT rc = { 0, 0, 4, 8 };
+ SIZE sz;
+
+ // Compute base unit sizes since GetDialogBaseUnits() returns garbage data.
+ // See http://support.microsoft.com/kb/125681
+ MapDialogRect(hDlg, &rc);
+ sz.cx = rc.right;
+ sz.cy = rc.bottom;
+
+ // TODO: figure out the specifics of each Windows version
+ if (nWindowsVersion == WINDOWS_10) {
+ checkbox_internal_spacing = 10;
+ dropdown_internal_spacing = 13;
+ }
+
+ // Checkbox and (blank) dropdown widths
+ cbw = MulDiv(checkbox_internal_spacing, sz.cx, 4);
+ ddw = MulDiv(dropdown_internal_spacing, sz.cx, 4);
+
+ // Spacing width between half-length dropdowns (sep) as well as left margin
+ GetWindowRect(GetDlgItem(hDlg, IDC_TARGET_SYSTEM), &rc);
+ MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
+ sw = rc.left;
+ GetWindowRect(GetDlgItem(hDlg, IDC_PARTITION_TYPE), &rc);
+ MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
+ sw -= rc.right;
+ mw = rc.left;
+
+ // Small button width
+ SendMessage(hSaveToolbar, TB_GETIDEALSIZE, (WPARAM)FALSE, (LPARAM)&sz);
+ sbw = sz.cx;
+
+ // Small separator widths and button height
+ GetWindowRect(GetDlgItem(hDlg, IDC_SAVE), &rc);
+ MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
+ bh = rc.bottom - rc.top;
+ ssw = rc.left;
+ GetWindowRect(hDeviceList, &rc);
+ MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
+ ssw -= rc.right;
+
+ // CSM tooltip separator width
+ GetWindowRect(GetDlgItem(hDlg, IDS_CSM_HELP_TXT), &rc);
+ MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
+ tw = rc.left;
+ GetWindowRect(hTargetSystem, &rc);
+ MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
+ tw -= rc.right;
+}
+
+// Compute the minimum size of the main buttons
+void GetMainButtonsWidth(HWND hDlg)
+{
+ unsigned int i;
+ RECT rc;
+
+ GetWindowRect(GetDlgItem(hDlg, main_button_ids[0]), &rc);
+ MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
+ bw = rc.right - rc.left;
+
+ for (i = 0; i < ARRAYSIZE(main_button_ids); i++)
+ bw = max(bw, GetTextWidth(hDlg, main_button_ids[i]) + cbw);
+ // The 'CLOSE' button is also be used to display 'CANCEL' => measure that too
+ bw = max(bw, GetTextSize(GetDlgItem(hDlg, IDCANCEL), lmprintf(MSG_007)).cx + cbw);
+}
+
+// The following goes over the data that gets populated into the half-width dropdowns
+// (Partition scheme, Target System, Disk ID, File system, Cluster size, Nb passes)
+// to figure out the minimum width we should allocate.
+void GetHalfDropwdownWidth(HWND hDlg)
+{
+ RECT rc;
+ unsigned int i, j, msg_id;
+ char tmp[256];
+
+ // Initialize half width to the UI's default size
+ GetWindowRect(GetDlgItem(hDlg, IDC_PARTITION_TYPE), &rc);
+ MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
+ hw = rc.right - rc.left - ddw;
+
+ // "Super Floppy Disk" is the longuest entry in the Partition Scheme dropdown
+ hw = max(hw, GetTextSize(GetDlgItem(hDlg, IDC_PARTITION_TYPE), (char*)sfd_name).cx);
+
+ // This is basically the same as SetClusterSizeLabels() except we're adding (Default) to each entry
+ for (i = 512, j = 1, msg_id = MSG_026; j 8192) {
+ i /= 1024;
+ msg_id++;
+ }
+ safe_sprintf(tmp, 64, "%d %s", i, lmprintf(msg_id));
+ hw = max(hw, GetTextSize(GetDlgItem(hDlg, IDC_CLUSTER_SIZE), lmprintf(MSG_030, tmp)).cx);
+ }
+ // We don't go over file systems, because none of them will be longer than "Super Floppy Disk"
+ // We do however go over the BIOS vs UEFI entries, as some of these are translated
+ for (msg_id = MSG_031; msg_id <= MSG_033; msg_id++)
+ hw = max(hw, GetTextSize(GetDlgItem(hDlg, IDC_TARGET_SYSTEM), lmprintf(msg_id)).cx);
+
+ // Just in case, we also do the number of passes
+ for (i = 1; i <= 5; i++) {
+ char* msg = (i == 1) ? lmprintf(MSG_034, 1) : lmprintf(MSG_035, (i == 2) ? 2 : 4, (i == 2) ? "" : lmprintf(MSG_087, flash_type[i - 3]));
+ hw = max(hw, GetTextSize(GetDlgItem(hDlg, IDC_TARGET_SYSTEM), msg).cx);
+ }
+
+ // Finally, we must ensure that we'll have enough space for the 2 checkbox controls
+ // that end up with a half dropdown
+ hw = max(hw, GetTextWidth(hDlg, IDC_RUFUS_MBR) - sw);
+ hw = max(hw, GetTextWidth(hDlg, IDC_BAD_BLOCKS) - sw);
+
+ // Add the width of a blank dropdown
+ hw += ddw;
+}
+
+/*
+* dbw = dialog border width
+* mw = margin width
+* fw = full dropdown width
+* hd = half dropdown width
+* bsw = boot selection dropdown width
+* sw = separator width
+* ssw = small separator width
+* bw = button width
+* sbw = small button width
+*
+* | fw |
+* | bsw | ssw | sbw | ssw | bw |
+* 8 ->|<- 96 ->|<- 24 ->|<- 96 ->|<- 8
+* mw | hw | sw | hw | mw
+* | bw | ssw | bw |
+*/
+void GetFullWidth(HWND hDlg)
+{
+ RECT rc;
+ int i;
+
+ // Get the dialog border width
+ GetWindowRect(hDlg, &rc);
+ dbw = rc.right - rc.left;
+ GetClientRect(hDlg, &rc);
+ dbw -= rc.right - rc.left;
+
+ // Compute the minimum size needed for the Boot Selection dropdown
+ GetWindowRect(GetDlgItem(hDlg, IDC_BOOT_SELECTION), &rc);
+ MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
+
+ bsw = max(rc.right - rc.left, GetTextSize(hBootType, lmprintf(MSG_279)).cx + ddw);
+ bsw = max(bsw, GetTextSize(hBootType, lmprintf(MSG_281, lmprintf(MSG_280))).cx + ddw);
+
+ // Initialize full width to the UI's default size
+ GetWindowRect(GetDlgItem(hDlg, IDC_IMAGE_OPTION), &rc);
+ MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
+ fw = rc.right - rc.left - ddw;
+
+ // Go through the Image Options for Windows To Go
+ fw = max(fw, GetTextSize(GetDlgItem(hDlg, IDC_IMAGE_OPTION), lmprintf(MSG_117)).cx);
+ fw = max(fw, GetTextSize(GetDlgItem(hDlg, IDC_IMAGE_OPTION), lmprintf(MSG_118)).cx);
+
+ // Now deal with full length checkbox lines
+ for (i = 0; i> 16;
+ SendMessage(hSaveToolbar, TB_SETPADDING, 0, MAKELPARAM(sz.cx + 3, sz.cy + 2));
+ SetWindowPos(hSaveToolbar, hDeviceList, mw + fw - sbw, rc.top, sbw, ddbh, 0);
+
+ // Reposition the Hash button
+ hCtrl = GetDlgItem(hDlg, IDC_HASH);
+ GetWindowRect(hCtrl, &rc);
+ MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
+ SendMessage(hHashToolbar, TB_GETIDEALSIZE, (WPARAM)FALSE, (LPARAM)&sz);
+ SendMessage(hHashToolbar, TB_SETBUTTONSIZE, 0, MAKELPARAM(sz.cx, ddbh));
+ padding = (DWORD)SendMessage(hHashToolbar, TB_GETPADDING, 0, 0);
+ sz.cx = padding & 0xFFFF;
+ sz.cy = padding >> 16;
+ SendMessage(hHashToolbar, TB_SETPADDING, 0, MAKELPARAM(sz.cx + 3, sz.cy + 2));
+ SetWindowPos(hHashToolbar, hBootType, mw + bsw + ssw, rc.top, sbw, ddbh, 0);
+
+ // Reposition the CSM help tip
+ hCtrl = GetDlgItem(hDlg, IDS_CSM_HELP_TXT);
+ GetWindowRect(hCtrl, &rc);
+ MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
+ SetWindowPos(hCtrl, hTargetSystem, mw + fw + tw, rc.top, sbw, rc.bottom - rc.top, 0);
+
+ if (advanced_mode_device) {
+ // Still need to adjust the width of the device selection dropdown
+ GetWindowRect(hDeviceList, &rc);
+ MapWindowPoints(NULL, hMainDialog, (POINT*)&rc, 2);
+ SetWindowPos(hDeviceList, HWND_TOP, rc.left, rc.top, fw - ssw - sbw, rc.bottom - rc.top, 0);
+ }
+
+ // Resize the full width controls
+ for (i = 0; i < ARRAYSIZE(full_width_controls); i++) {
+ hCtrl = GetDlgItem(hDlg, full_width_controls[i]);
+ GetWindowRect(hCtrl, &rc);
+ MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
+ hPrevCtrl = GetNextWindow(hCtrl, GW_HWNDPREV);
+ SetWindowPos(hCtrl, hPrevCtrl, rc.left, rc.top, fw, rc.bottom - rc.top, 0);
+ }
+
+ // Resize the half drowpdowns
+ for (i = 0; i < ARRAYSIZE(half_width_ids); i++) {
+ hCtrl = GetDlgItem(hDlg, half_width_ids[i]);
+ GetWindowRect(hCtrl, &rc);
+ MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
+ // First 5 controls are on the left handside
+ // First 2 controls may overflow into separator
+ hPrevCtrl = GetNextWindow(hCtrl, GW_HWNDPREV);
+ SetWindowPos(hCtrl, hPrevCtrl, (i < 5) ? rc.left : mw + hw + sw, rc.top,
+ (i <2) ? hw + sw : hw, rc.bottom - rc.top, 0);
+ }
+
+ // Resize the boot selection dropdown
+ hCtrl = GetDlgItem(hDlg, IDC_BOOT_SELECTION);
+ GetWindowRect(hCtrl, &rc);
+ MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
+ hPrevCtrl = GetNextWindow(hCtrl, GW_HWNDPREV);
+ SetWindowPos(hCtrl, hPrevCtrl, rc.left, rc.top, bsw, rc.bottom - rc.top, 0);
+}
+
+static void ResizeDialogs(int shift)
+{
+ RECT rc;
+ POINT point;
+
+ // Resize the main dialog
+ GetWindowRect(hMainDialog, &rc);
+ point.x = (rc.right - rc.left);
+ point.y = (rc.bottom - rc.top);
+ MoveWindow(hMainDialog, rc.left, rc.top, point.x, point.y + shift, TRUE);
+
+ // Resize the log
+ GetWindowRect(hLogDialog, &rc);
+ point.x = (rc.right - rc.left);
+ point.y = (rc.bottom - rc.top);
+ MoveWindow(hLogDialog, rc.left, rc.top, point.x, point.y + shift, TRUE);
+ MoveCtrlY(hLogDialog, IDC_LOG_CLEAR, shift);
+ MoveCtrlY(hLogDialog, IDC_LOG_SAVE, shift);
+ MoveCtrlY(hLogDialog, IDCANCEL, shift);
+ GetWindowRect(hLog, &rc);
+ point.x = (rc.right - rc.left);
+ point.y = (rc.bottom - rc.top) + shift;
+ SetWindowPos(hLog, NULL, 0, 0, point.x, point.y, SWP_NOZORDER);
+ // Don't forget to scroll the edit to the bottom after resize
+ Edit_Scroll(hLog, 0, Edit_GetLineCount(hLog));
+}
+
+// Thanks to Microsoft atrocious DPI handling, we must adjust for low DPI
+void AdjustForLowDPI(HWND hDlg)
+{
+ static int ddy = 4;
+ int i, j;
+ RECT rc;
+ HWND hCtrl, hPrevCtrl;
+ int dy = 0;
+
+ if (fScale >= 1.3f)
+ return;
+
+ for (i = 0; i < ARRAYSIZE(adjust_dpi_ids); i++) {
+ dy += ddy;
+ // "...and the other thing I really like about Microsoft's UI handling is how "
+ //."you never have to introduce weird hardcoded constants all over the place, "
+ // "just to make your UI look good...", said NO ONE ever.
+ if (adjust_dpi_ids[i][0] == IDC_QUICK_FORMAT)
+ dy += 1;
+ for (j = 0; j < 5; j++) {
+ if (adjust_dpi_ids[i][j] == 0)
+ break;
+ hCtrl = GetDlgItem(hDlg, adjust_dpi_ids[i][j]);
+ GetWindowRect(hCtrl, &rc);
+ MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
+ hPrevCtrl = GetNextWindow(hCtrl, GW_HWNDPREV);
+ SetWindowPos(hCtrl, hPrevCtrl, rc.left, rc.top + dy,
+ rc.right - rc.left, rc.bottom - rc.top, 0);
+ }
+ }
+
+ section_vpos[1] += 9 * ddy;
+ section_vpos[2] += 16 * ddy + 1;
+ advanced_device_section_height += 3 * ddy;
+ advanced_format_section_height += 3 * ddy + 1;
+
+ ResizeDialogs(dy + 2 * ddy);
+ InvalidateRect(hDlg, NULL, TRUE);
+}
+
+void SetSectionHeaders(HWND hDlg)
+{
+ RECT rc;
+ HWND hCtrl;
+ SIZE sz;
+ HFONT hf;
+ wchar_t wtmp[128];
+ size_t wlen;
+ int i;
+
+ // Set the section header fonts and resize the static controls accordingly
+ hf = CreateFontA(-MulDiv(14, GetDeviceCaps(GetDC(hMainDialog), LOGPIXELSY), 72), 0, 0, 0,
+ FW_SEMIBOLD, FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0, PROOF_QUALITY, 0, "Segoe UI");
+
+ for (i = 0; i < ARRAYSIZE(section_control_ids); i++) {
+ SendDlgItemMessageA(hDlg, section_control_ids[i], WM_SETFONT, (WPARAM)hf, TRUE);
+ hCtrl = GetDlgItem(hDlg, section_control_ids[i]);
+ memset(wtmp, 0, sizeof(wtmp));
+ GetWindowTextW(hCtrl, wtmp, ARRAYSIZE(wtmp));
+ wlen = wcslen(wtmp);
+ wtmp[wlen++] = L' ';
+ wtmp[wlen++] = L' ';
+ SetWindowTextW(hCtrl, wtmp);
+ GetWindowRect(hCtrl, &rc);
+ MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
+ sz = GetTextSize(hCtrl, NULL);
+ SetWindowPos(hCtrl, NULL, rc.left, rc.top, sz.cx, sz.cy, SWP_NOZORDER);
+ }
+}
+
+// Toggle "advanced" options
+void ToggleAdvancedDeviceOptions(BOOL enable)
+{
+ RECT rc;
+ SIZE sz;
+ TBBUTTONINFO button_info;
+ int i, shift = advanced_device_section_height;
+
+ if (!enable)
+ shift = -shift;
+ section_vpos[1] += shift;
+ section_vpos[2] += shift;
+
+ // Toggle the Hide/Show toolbar text
+ utf8_to_wchar_no_alloc(lmprintf((enable) ? MSG_122 : MSG_121, lmprintf(MSG_119)), wtbtext[0], ARRAYSIZE(wtbtext[0]));
+ button_info.cbSize = sizeof(button_info);
+ button_info.dwMask = TBIF_TEXT;
+ button_info.pszText = wtbtext[0];
+ SendMessage(hAdvancedDeviceToolbar, TB_SETBUTTONINFO, (WPARAM)IDC_ADVANCED_DRIVE_PROPERTIES, (LPARAM)&button_info);
+ SendMessage(hAdvancedDeviceToolbar, TB_SETIMAGELIST, (WPARAM)0, (LPARAM)((enable) ? hUpImageList : hDownImageList));
+ GetWindowRect(hAdvancedDeviceToolbar, &rc);
+ MapWindowPoints(NULL, hMainDialog, (POINT*)&rc, 2);
+ SendMessage(hAdvancedDeviceToolbar, TB_GETIDEALSIZE, (WPARAM)FALSE, (LPARAM)&sz);
+ SetWindowPos(hAdvancedDeviceToolbar, hTargetSystem, rc.left, rc.top, sz.cx, rc.bottom - rc.top, 0);
+
+ // Move the controls up or down
+ for (i = 0; i= 2) ? 0 : rh;
+
+ assert(popcnt8(mask) <= 1);
+
+ if (mask & IMOP_WINTOGO) {
+ if (nWindowsVersion < WINDOWS_8)
+ return;
+ image_options ^= IMOP_WINTOGO;
+ // Set the Windows To Go selection in the dropdown
+ IGNORE_RETVAL(ComboBox_SetCurSel(GetDlgItem(hMainDialog, IDC_IMAGE_OPTION), windows_to_go_selection));
+ } else if (mask & IMOP_PERSISTENCE) {
+ image_options ^= IMOP_PERSISTENCE;
+ }
+
+ if (popcnt8(image_options) >= 2)
+ shift = 0;
+
+ if (shift != 0) {
+ if ((mask == 0) || (image_options == 0))
+ shift = -shift;
+ section_vpos[1] += shift;
+ section_vpos[2] += shift;
+
+ if (popcnt8(image_options) <= 1) {
+ // Move the controls up or down
+ for (i = 0; i < ARRAYSIZE(image_option_move_ids); i++)
+ MoveCtrlY(hMainDialog, image_option_move_ids[i], shift);
+
+ // Resize the main dialog and log window
+ ResizeDialogs(shift);
+ }
+ }
+
+ // Hide or show the boot options
+ for (i = 0; i < ARRAYSIZE(image_option_toggle_ids); i++) {
+ ShowWindow(GetDlgItem(hMainDialog, image_option_toggle_ids[i][0]),
+ (image_options & image_option_toggle_ids[i][1]) ? SW_SHOW : SW_HIDE);
+ }
+
+ // If you don't force a redraw here, all kind of bad UI artifacts happen...
+ InvalidateRect(hMainDialog, NULL, TRUE);
+}
+
+// We need to create the small toolbar buttons first so that we can compute their width
+void CreateSmallButtons(HWND hDlg)
+{
+ HIMAGELIST hImageList;
+ HICON hIconSave, hIconHash;
+ int icon_offset = 0, i16 = GetSystemMetrics(SM_CXSMICON);
+ TBBUTTON tbToolbarButtons[1];
+ unsigned char* buffer;
+ DWORD bufsize;
+
+ if (i16 >= 28)
+ icon_offset = 20;
+ else if (i16 >= 20)
+ icon_offset = 10;
+
+ hSaveToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, TOOLBAR_STYLE,
+ 0, 0, 0, 0, hMainDialog, (HMENU)IDC_SAVE_TOOLBAR, hMainInstance, NULL);
+ hImageList = ImageList_Create(i16, i16, ILC_COLOR32 | ILC_HIGHQUALITYSCALE | ILC_MIRROR, 1, 0);
+ buffer = GetResource(hMainInstance, MAKEINTRESOURCEA(IDI_SAVE_16 + icon_offset), _RT_RCDATA, "save icon", &bufsize, FALSE);
+ hIconSave = CreateIconFromResourceEx(buffer, bufsize, TRUE, 0x30000, 0, 0, 0);
+ ImageList_AddIcon(hImageList, hIconSave);
+ DestroyIcon(hIconSave);
+ SendMessage(hSaveToolbar, TB_SETIMAGELIST, (WPARAM)0, (LPARAM)hImageList);
+ SendMessage(hSaveToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
+ memset(tbToolbarButtons, 0, sizeof(TBBUTTON));
+ tbToolbarButtons[0].idCommand = IDC_SAVE;
+ tbToolbarButtons[0].fsStyle = BTNS_AUTOSIZE;
+ tbToolbarButtons[0].fsState = TBSTATE_ENABLED;
+ tbToolbarButtons[0].iBitmap = 0;
+ SendMessage(hSaveToolbar, TB_ADDBUTTONS, (WPARAM)1, (LPARAM)&tbToolbarButtons);
+
+ hHashToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, TOOLBAR_STYLE,
+ 0, 0, 0, 0, hMainDialog, (HMENU)IDC_HASH_TOOLBAR, hMainInstance, NULL);
+ hImageList = ImageList_Create(i16, i16, ILC_COLOR32 | ILC_HIGHQUALITYSCALE | ILC_MIRROR, 1, 0);
+ buffer = GetResource(hMainInstance, MAKEINTRESOURCEA(IDI_HASH_16 + icon_offset), _RT_RCDATA, "hash icon", &bufsize, FALSE);
+ hIconHash = CreateIconFromResourceEx(buffer, bufsize, TRUE, 0x30000, 0, 0, 0);
+ ImageList_AddIcon(hImageList, hIconHash);
+ DestroyIcon(hIconHash);
+ SendMessage(hHashToolbar, TB_SETIMAGELIST, (WPARAM)0, (LPARAM)hImageList);
+ SendMessage(hHashToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
+ memset(tbToolbarButtons, 0, sizeof(TBBUTTON));
+ tbToolbarButtons[0].idCommand = IDC_HASH;
+ tbToolbarButtons[0].fsStyle = BTNS_AUTOSIZE;
+ tbToolbarButtons[0].fsState = TBSTATE_ENABLED;
+ tbToolbarButtons[0].iBitmap = 0;
+ SendMessage(hHashToolbar, TB_ADDBUTTONS, (WPARAM)1, (LPARAM)&tbToolbarButtons);
+}
+
+static INT_PTR CALLBACK ProgressCallback(HWND hCtrl, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ HDC hDC;
+ RECT rc, rc2;
+ PAINTSTRUCT ps;
+ SIZE size;
+ LONG full_right;
+ wchar_t winfo[128];
+ static BOOL marquee_mode = FALSE;
+ static uint32_t pos = 0, min = 0, max = 0xFFFF;
+ static COLORREF color = PROGRESS_BAR_NORMAL_COLOR;
+
+ switch (message) {
+
+ case PBM_SETSTATE:
+ switch (wParam) {
+ case PBST_NORMAL:
+ color = PROGRESS_BAR_NORMAL_COLOR;
+ break;
+ case PBST_PAUSED:
+ color = PROGRESS_BAR_PAUSED_COLOR;
+ break;
+ case PBST_ERROR:
+ color = PROGRESS_BAR_ERROR_COLOR;
+ break;
+ }
+ return (INT_PTR)TRUE;
+
+ case PBM_SETRANGE:
+ // Don't bother sanity checking min and max: If *you* want to
+ // be an ass about the progress bar range, it's *your* problem.
+ min = (uint32_t)(lParam & 0xFFFF);
+ max = (uint32_t)(lParam >> 16);
+ return (INT_PTR)TRUE;
+
+ case PBM_SETPOS:
+ pos = (WORD)wParam;
+ InvalidateRect(hProgress, NULL, TRUE);
+ return (INT_PTR)TRUE;
+
+ case PBM_SETMARQUEE:
+ if ((wParam == TRUE) && (!marquee_mode)) {
+ marquee_mode = TRUE;
+ pos = min;
+ color = PROGRESS_BAR_NORMAL_COLOR;
+ SetTimer(hCtrl, TID_MARQUEE_TIMER, MARQUEE_TIMER_REFRESH, NULL);
+ InvalidateRect(hProgress, NULL, TRUE);
+ } else if ((wParam == FALSE) && (marquee_mode)) {
+ marquee_mode = FALSE;
+ KillTimer(hCtrl, TID_MARQUEE_TIMER);
+ pos = min;
+ InvalidateRect(hProgress, NULL, TRUE);
+ }
+ return (INT_PTR)TRUE;
+
+ case WM_TIMER:
+ if ((wParam == TID_MARQUEE_TIMER) && marquee_mode) {
+ pos += max((max - min) / (1000 / MARQUEE_TIMER_REFRESH), 1);
+ if ((pos > max) || (pos < min))
+ pos = min;
+ InvalidateRect(hProgress, NULL, TRUE);
+ return (INT_PTR)TRUE;
+ }
+ return (INT_PTR)FALSE;
+
+ case WM_PAINT:
+ hDC = BeginPaint(hCtrl, &ps);
+ GetClientRect(hCtrl, &rc);
+ rc2 = rc;
+ InflateRect(&rc, -1, -1);
+ SelectObject(hDC, GetStockObject(DC_PEN));
+ SelectObject(hDC, GetStockObject(NULL_BRUSH));
+ // TODO: Handle SetText message so we can avoid this call
+ GetWindowTextW(hProgress, winfo, ARRAYSIZE(winfo));
+ SelectObject(hDC, hInfoFont);
+ GetTextExtentPoint32(hDC, winfo, (int)wcslen(winfo), &size);
+ if (size.cx > rc.right)
+ size.cx = rc.right;
+ if (size.cy > rc.bottom)
+ size.cy = rc.bottom;
+ full_right = rc.right;
+ if (marquee_mode) {
+ // Optional first segment
+ if (pos + ((max - min) / 5) > max) {
+ rc.right = MulDiv(pos + ((max - min) / 5) - max, rc.right, max - min);
+ SetTextColor(hDC, PROGRESS_BAR_INVERTED_TEXT_COLOR);
+ SetBkColor(hDC, color);
+ ExtTextOut(hDC, (full_right - size.cx) / 2, (rc.bottom - size.cy) / 2,
+ ETO_CLIPPED | ETO_OPAQUE | ETO_NUMERICSLOCAL, &rc, winfo, (int)wcslen(winfo), NULL);
+ rc.left = rc.right;
+ rc.right = full_right;
+ }
+ // Optional second segment
+ if (pos > min) {
+ rc.right = MulDiv(pos - min, rc.right, max - min);
+ SetTextColor(hDC, PROGRESS_BAR_NORMAL_TEXT_COLOR);
+ SetBkColor(hDC, PROGRESS_BAR_BACKGROUND_COLOR);
+ ExtTextOut(hDC, (full_right - size.cx) / 2, (rc.bottom - size.cy) / 2,
+ ETO_CLIPPED | ETO_OPAQUE | ETO_NUMERICSLOCAL, &rc, winfo, (int)wcslen(winfo), NULL);
+ rc.left = rc.right;
+ rc.right = full_right;
+ }
+ // Second to last segment
+ rc.right = MulDiv(pos - min + ((max - min) / 5), rc.right, max - min);
+ SetTextColor(hDC, PROGRESS_BAR_INVERTED_TEXT_COLOR);
+ SetBkColor(hDC, color);
+ ExtTextOut(hDC, (full_right - size.cx) / 2, (rc.bottom - size.cy) / 2,
+ ETO_CLIPPED | ETO_OPAQUE | ETO_NUMERICSLOCAL, &rc, winfo, (int)wcslen(winfo), NULL);
+ } else {
+ // First segment
+ rc.right = (pos > min) ? MulDiv(pos - min, rc.right, max - min) : rc.left;
+ SetTextColor(hDC, PROGRESS_BAR_INVERTED_TEXT_COLOR);
+ SetBkColor(hDC, color);
+ ExtTextOut(hDC, (full_right - size.cx) / 2, (rc.bottom - size.cy) / 2,
+ ETO_CLIPPED | ETO_OPAQUE | ETO_NUMERICSLOCAL, &rc, winfo, (int)wcslen(winfo), NULL);
+ }
+ // Last segment
+ rc.left = rc.right;
+ rc.right = full_right;
+ SetTextColor(hDC, PROGRESS_BAR_NORMAL_TEXT_COLOR);
+ SetBkColor(hDC, PROGRESS_BAR_BACKGROUND_COLOR);
+ ExtTextOut(hDC, (full_right - size.cx) / 2, (rc.bottom - size.cy) / 2,
+ ETO_CLIPPED | ETO_OPAQUE | ETO_NUMERICSLOCAL, &rc, winfo, (int)wcslen(winfo), NULL);
+ // Bounding rectangle
+ SetDCPenColor(hDC, PROGRESS_BAR_BOX_COLOR);
+ Rectangle(hDC, rc2.left, rc2.top, rc2.right, rc2.bottom);
+ EndPaint(hCtrl, &ps);
+ return (INT_PTR)TRUE;
+ }
+
+ return CallWindowProc(progress_original_proc, hCtrl, message, wParam, lParam);
+}
+
+void CreateAdditionalControls(HWND hDlg)
+{
+ HINSTANCE hDll;
+ HIMAGELIST hToolbarImageList;
+ HICON hIcon, hIconUp, hIconDown;
+ RECT rc;
+ SIZE sz;
+ int icon_offset = 0, i, i16, s16, toolbar_dx = -4 - ((fScale > 1.49f) ? 1 : 0) - ((fScale > 1.99f) ? 1 : 0);
+ TBBUTTON tbToolbarButtons[7];
+ unsigned char* buffer;
+ DWORD bufsize;
+
+ s16 = i16 = GetSystemMetrics(SM_CXSMICON);
+ if (s16 >= 54)
+ s16 = 64;
+ else if (s16 >= 40)
+ s16 = 48;
+ else if (s16 >= 28)
+ s16 = 32;
+ else if (s16 >= 20)
+ s16 = 24;
+ if (i16 >= 28)
+ icon_offset = 20;
+ else if (i16 >= 20)
+ icon_offset = 10;
+
+ // Fetch the up and down expand icons for the advanced options toolbar
+ hDll = GetLibraryHandle("ComDlg32");
+ hIconDown = (HICON)LoadImage(hDll, MAKEINTRESOURCE(577), IMAGE_ICON, s16, s16, LR_DEFAULTCOLOR | LR_SHARED);
+ hIconUp = (HICON)LoadImage(hDll, MAKEINTRESOURCE(578), IMAGE_ICON, s16, s16, LR_DEFAULTCOLOR | LR_SHARED);
+ // Fallback to using Shell32 if we can't locate the icons we want in ComDlg32
+ hDll = GetLibraryHandle("Shell32");
+ if (hIconUp == NULL)
+ hIconUp = (HICON)LoadImage(hDll, MAKEINTRESOURCE(16749), IMAGE_ICON, s16, s16, LR_DEFAULTCOLOR | LR_SHARED);
+ if (hIconDown == NULL)
+ hIconDown = (HICON)LoadImage(hDll, MAKEINTRESOURCE(16750), IMAGE_ICON, s16, s16, LR_DEFAULTCOLOR | LR_SHARED);
+ hUpImageList = ImageList_Create(i16, i16, ILC_COLOR32 | ILC_HIGHQUALITYSCALE, 1, 0);
+ hDownImageList = ImageList_Create(i16, i16, ILC_COLOR32 | ILC_HIGHQUALITYSCALE, 1, 0);
+ ImageList_AddIcon(hUpImageList, hIconUp);
+ ImageList_AddIcon(hDownImageList, hIconDown);
+
+ // Create the advanced options toolbars
+ memset(wtbtext, 0, sizeof(wtbtext));
+ utf8_to_wchar_no_alloc(lmprintf((advanced_mode_device) ? MSG_122 : MSG_121, lmprintf(MSG_119)), wtbtext[0], ARRAYSIZE(wtbtext[0]));
+ hAdvancedDeviceToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, TOOLBAR_STYLE,
+ 0, 0, 0, 0, hMainDialog, (HMENU)IDC_ADVANCED_DEVICE_TOOLBAR, hMainInstance, NULL);
+ SendMessage(hAdvancedDeviceToolbar, CCM_SETVERSION, (WPARAM)6, 0);
+ memset(tbToolbarButtons, 0, sizeof(TBBUTTON));
+ tbToolbarButtons[0].idCommand = IDC_ADVANCED_DRIVE_PROPERTIES;
+ tbToolbarButtons[0].fsStyle = BTNS_SHOWTEXT | BTNS_AUTOSIZE;
+ tbToolbarButtons[0].fsState = TBSTATE_ENABLED;
+ tbToolbarButtons[0].iString = (INT_PTR)wtbtext[0];
+ tbToolbarButtons[0].iBitmap = 0;
+ SendMessage(hAdvancedDeviceToolbar, TB_SETIMAGELIST, 0, (LPARAM)hUpImageList);
+ SendMessage(hAdvancedDeviceToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
+ SendMessage(hAdvancedDeviceToolbar, TB_ADDBUTTONS, 1, (LPARAM)&tbToolbarButtons);
+ GetWindowRect(GetDlgItem(hDlg, IDC_ADVANCED_DRIVE_PROPERTIES), &rc);
+ MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
+ SendMessage(hAdvancedDeviceToolbar, TB_GETIDEALSIZE, (WPARAM)FALSE, (LPARAM)&sz);
+ // Yeah, so, like, TB_GETIDEALSIZE totally super doesn't work on Windows 7, for low zoom factor and when compiled with MSVC...
+ if (sz.cx < 16)
+ sz.cx = fw;
+ SetWindowPos(hAdvancedDeviceToolbar, hTargetSystem, rc.left + toolbar_dx, rc.top, sz.cx, rc.bottom - rc.top, 0);
+
+ utf8_to_wchar_no_alloc(lmprintf((advanced_mode_format) ? MSG_122 : MSG_121, lmprintf(MSG_120)), wtbtext[1], ARRAYSIZE(wtbtext[1]));
+ hAdvancedFormatToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, TOOLBAR_STYLE,
+ 0, 0, 0, 0, hMainDialog, (HMENU)IDC_ADVANCED_FORMAT_TOOLBAR, hMainInstance, NULL);
+ SendMessage(hAdvancedFormatToolbar, CCM_SETVERSION, (WPARAM)6, 0);
+ memset(tbToolbarButtons, 0, sizeof(TBBUTTON));
+ tbToolbarButtons[0].idCommand = IDC_ADVANCED_FORMAT_OPTIONS;
+ tbToolbarButtons[0].fsStyle = BTNS_SHOWTEXT | BTNS_AUTOSIZE;
+ tbToolbarButtons[0].fsState = TBSTATE_ENABLED;
+ tbToolbarButtons[0].iString = (INT_PTR)wtbtext[1];
+ tbToolbarButtons[0].iBitmap = 0;
+ SendMessage(hAdvancedFormatToolbar, TB_SETIMAGELIST, (WPARAM)0, (LPARAM)hUpImageList);
+ SendMessage(hAdvancedFormatToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
+ SendMessage(hAdvancedFormatToolbar, TB_ADDBUTTONS, (WPARAM)1, (LPARAM)&tbToolbarButtons);
+ GetWindowRect(GetDlgItem(hDlg, IDC_ADVANCED_FORMAT_OPTIONS), &rc);
+ MapWindowPoints(NULL, hDlg, (POINT*)&rc, 2);
+ SendMessage(hAdvancedFormatToolbar, TB_GETIDEALSIZE, (WPARAM)FALSE, (LPARAM)&sz);
+ if (sz.cx < 16)
+ sz.cx = fw;
+ SetWindowPos(hAdvancedFormatToolbar, hClusterSize, rc.left + toolbar_dx, rc.top, sz.cx, rc.bottom - rc.top, 0);
+
+ // Create the multi toolbar
+ hMultiToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, TOOLBAR_STYLE,
+ 0, 0, 0, 0, hMainDialog, (HMENU)IDC_MULTI_TOOLBAR, hMainInstance, NULL);
+ hToolbarImageList = ImageList_Create(i16, i16, ILC_COLOR32 | ILC_HIGHQUALITYSCALE, 8, 0);
+ for (i = 0; i < ARRAYSIZE(multitoolbar_icons); i++) {
+ buffer = GetResource(hMainInstance, MAKEINTRESOURCEA(multitoolbar_icons[i] + icon_offset),
+ _RT_RCDATA, "toolbar icon", &bufsize, FALSE);
+ hIcon = CreateIconFromResourceEx(buffer, bufsize, TRUE, 0x30000, 0, 0, 0);
+ // Mirror the "world" icon on RTL since we can't use an ImageList mirroring flag for that...
+ if (right_to_left_mode && (i == 0))
+ hIcon = CreateMirroredIcon(hIcon);
+ ImageList_AddIcon(hToolbarImageList, hIcon);
+ DestroyIcon(hIcon);
+ }
+ SendMessage(hMultiToolbar, TB_SETIMAGELIST, (WPARAM)0, (LPARAM)hToolbarImageList);
+ SendMessage(hMultiToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
+ memset(tbToolbarButtons, 0, sizeof(TBBUTTON) * ARRAYSIZE(tbToolbarButtons));
+ tbToolbarButtons[0].idCommand = IDC_LANG;
+ tbToolbarButtons[0].fsStyle = BTNS_BUTTON;
+ tbToolbarButtons[0].fsState = TBSTATE_ENABLED;
+ tbToolbarButtons[0].iBitmap = 0;
+ tbToolbarButtons[1].fsStyle = BTNS_AUTOSIZE;
+ tbToolbarButtons[1].fsState = TBSTATE_INDETERMINATE;
+ tbToolbarButtons[1].iBitmap = I_IMAGENONE;
+ tbToolbarButtons[1].iString = (fScale < 1.5f) ? (INT_PTR)L"" : (INT_PTR)L" ";
+ tbToolbarButtons[2].idCommand = IDC_ABOUT;
+ tbToolbarButtons[2].fsStyle = BTNS_BUTTON;
+ tbToolbarButtons[2].fsState = TBSTATE_ENABLED;
+ tbToolbarButtons[2].iBitmap = 1;
+ tbToolbarButtons[3].fsStyle = BTNS_AUTOSIZE;
+ tbToolbarButtons[3].fsState = TBSTATE_INDETERMINATE;
+ tbToolbarButtons[3].iBitmap = I_IMAGENONE;
+ tbToolbarButtons[3].iString = (fScale < 1.5f) ? (INT_PTR)L"" : (INT_PTR)L" ";
+ tbToolbarButtons[4].idCommand = IDC_SETTINGS;
+ tbToolbarButtons[4].fsStyle = BTNS_BUTTON;
+ tbToolbarButtons[4].fsState = TBSTATE_ENABLED;
+ tbToolbarButtons[4].iBitmap = 2;
+ tbToolbarButtons[5].fsStyle = BTNS_AUTOSIZE;
+ tbToolbarButtons[5].fsState = TBSTATE_INDETERMINATE;
+ tbToolbarButtons[5].iBitmap = I_IMAGENONE;
+ tbToolbarButtons[5].iString = (fScale < 1.5f) ? (INT_PTR)L"" : (INT_PTR)L" ";
+ tbToolbarButtons[6].idCommand = IDC_LOG;
+ tbToolbarButtons[6].fsStyle = BTNS_BUTTON;
+ tbToolbarButtons[6].fsState = TBSTATE_ENABLED;
+ tbToolbarButtons[6].iBitmap = 3;
+ SendMessage(hMultiToolbar, TB_ADDBUTTONS, (WPARAM)7, (LPARAM)&tbToolbarButtons);
+ SendMessage(hMultiToolbar, TB_SETBUTTONSIZE, 0, MAKELPARAM(i16, ddbh));
+
+ // Subclass the progress bar so that we can write on it
+ progress_original_proc = (WNDPROC)SetWindowLongPtr(hProgress, GWLP_WNDPROC, (LONG_PTR)ProgressCallback);
+}
+
+// Set up progress bar real estate allocation
+void InitProgress(BOOL bOnlyFormat)
+{
+ int i;
+ float last_end = 0.0f, slots_discrete = 0.0f, slots_analog = 0.0f;
+
+ memset(nb_slots, 0, sizeof(nb_slots));
+ memset(slot_end, 0, sizeof(slot_end));
+ previous_end = 0.0f;
+
+ if (bOnlyFormat) {
+ nb_slots[OP_FORMAT] = -1;
+ } else {
+ nb_slots[OP_ANALYZE_MBR] = 1;
+ if (IsChecked(IDC_BAD_BLOCKS)) {
+ nb_slots[OP_BADBLOCKS] = -1;
+ }
+ if (bt != BT_NON_BOOTABLE) {
+ // 1 extra slot for PBR writing
+ switch (selection_default) {
+ case BT_MSDOS:
+ nb_slots[OP_DOS] = 3 + 1;
+ break;
+ case BT_FREEDOS:
+ nb_slots[OP_DOS] = 5 + 1;
+ break;
+ case BT_IMAGE:
+ nb_slots[OP_DOS] = img_report.is_iso ? -1 : 0;
+ break;
+ default:
+ nb_slots[OP_DOS] = 2 + 1;
+ break;
+ }
+ }
+ if (selection_default == BT_IMAGE && !img_report.is_iso) {
+ nb_slots[OP_FORMAT] = -1;
+ } else {
+ nb_slots[OP_ZERO_MBR] = 1;
+ nb_slots[OP_PARTITION] = 1;
+ nb_slots[OP_FIX_MBR] = 1;
+ nb_slots[OP_CREATE_FS] =
+ nb_steps[ComboBox_GetItemData(hFileSystem, ComboBox_GetCurSel(hFileSystem))];
+ if ((!IsChecked(IDC_QUICK_FORMAT))
+ || ((fs == FS_FAT32) && ((SelectedDrive.DiskSize >= LARGE_FAT32_SIZE) || (force_large_fat32)))) {
+ nb_slots[OP_FORMAT] = -1;
+ }
+ nb_slots[OP_FINALIZE] = ((selection_default == BT_IMAGE) && (fs == FS_NTFS)) ? 3 : 2;
+ }
+ }
+
+ for (i = 0; i 0) {
+ slots_discrete += nb_slots[i] * 1.0f;
+ }
+ if (nb_slots[i] < 0) {
+ slots_analog += nb_slots[i] * 1.0f;
+ }
+ }
+
+ for (i = 0; i 0) {
+ slot_end[i + 1] = last_end + (1.0f * nb_slots[i]);
+ } else if (nb_slots[i] < 0) {
+ slot_end[i + 1] = last_end + (((100.0f - slots_discrete) * nb_slots[i]) / slots_analog);
+ }
+ last_end = slot_end[i + 1];
+ }
+
+ // If there's no analog, adjust our discrete ends to fill the whole bar
+ if (slots_analog == 0.0f) {
+ for (i = 0; i= OP_MAX)) {
+ duprintf("UpdateProgress: invalid op %d\n", op);
+ return;
+ }
+ if (percent > 100.1f) {
+ // duprintf("UpdateProgress(%d): invalid percentage %0.2f\n", op, percent);
+ return;
+ }
+ if ((percent < 0.0f) && (nb_slots[op] <= 0)) {
+ duprintf("UpdateProgress(%d): error negative percentage sent for negative slot value\n", op);
+ return;
+ }
+ if (nb_slots[op] == 0)
+ return;
+ if (previous_end < slot_end[op]) {
+ previous_end = slot_end[op];
+ }
+
+ if (percent < 0.0f) {
+ // Negative means advance one slot (1.0%) - requires a positive slot allocation
+ previous_end += (slot_end[op + 1] - slot_end[op]) / (1.0f * nb_slots[op]);
+ pos = (int)(previous_end / 100.0f * MAX_PROGRESS);
+ } else {
+ pos = (int)((previous_end + ((slot_end[op + 1] - previous_end) * (percent / 100.0f))) / 100.0f * MAX_PROGRESS);
+ }
+ if (pos > MAX_PROGRESS) {
+ duprintf("UpdateProgress(%d): rounding error - pos %d is greater than %d\n", op, pos, MAX_PROGRESS);
+ pos = MAX_PROGRESS;
+ }
+
+ // Reduce the refresh rate, to avoid weird effects on the sliding part of progress bar
+ if (GetTickCount64() > LastRefresh + (2 * MAX_REFRESH)) {
+ LastRefresh = GetTickCount64();
+ SendMessage(hProgress, PBM_SETPOS, (WPARAM)pos, 0);
+ SetTaskbarProgressValue(pos, MAX_PROGRESS);
+ }
+}
+
+void ShowLanguageMenu(RECT rcExclude)
+{
+ TPMPARAMS tpm;
+ HMENU menu;
+ loc_cmd* lcmd = NULL;
+ char lang[256];
+ char *search = "()";
+ char *l, *r, *str;
+
+ UM_LANGUAGE_MENU_MAX = UM_LANGUAGE_MENU;
+ menu = CreatePopupMenu();
+ list_for_each_entry(lcmd, &locale_list, loc_cmd, list) {
+ // The appearance of LTR languages must be fixed for RTL menus
+ if ((right_to_left_mode) && (!(lcmd->ctrl_id & LOC_RIGHT_TO_LEFT))) {
+ str = safe_strdup(lcmd->txt[1]);
+ l = strtok(str, search);
+ r = strtok(NULL, search);
+ static_sprintf(lang, LEFT_TO_RIGHT_EMBEDDING "(%s) " POP_DIRECTIONAL_FORMATTING "%s", r, l);
+ safe_free(str);
+ } else {
+ static_strcpy(lang, lcmd->txt[1]);
+ }
+ InsertMenuU(menu, -1, MF_BYPOSITION | ((selected_locale == lcmd) ? MF_CHECKED : 0), UM_LANGUAGE_MENU_MAX++, lang);
+ }
+
+ // Open the menu such that it doesn't overlap the specified rect
+ tpm.cbSize = sizeof(TPMPARAMS);
+ tpm.rcExclude = rcExclude;
+ TrackPopupMenuEx(menu, 0,
+ // In RTL languages, the menu should be placed at the bottom-right of the rect
+ right_to_left_mode ? rcExclude.right : rcExclude.left,
+ rcExclude.bottom, hMainDialog, &tpm);
+
+ DestroyMenu(menu);
+}
+
+void SetPassesTooltip(void)
+{
+ const unsigned int pattern[BADLOCKS_PATTERN_TYPES][BADBLOCK_PATTERN_COUNT] =
+ { BADBLOCK_PATTERN_SLC, BADCLOCK_PATTERN_MLC, BADBLOCK_PATTERN_TLC };
+ int sel = ComboBox_GetCurSel(hNBPasses);
+ int type = (sel < 2) ? 0 : sel - 2;
+ CreateTooltip(hNBPasses, lmprintf(MSG_153 + ((sel >= 2) ? 3 : sel),
+ pattern[type][0], pattern[type][1], pattern[type][2], pattern[type][3]), -1);
+}
+
+void SetBootTypeDropdownWidth(void)
+{
+ HDC hDC;
+ HFONT hFont;
+ SIZE sz;
+ RECT rc;
+
+ if (image_path == NULL)
+ return;
+ // Set the maximum width of the dropdown according to the image selected
+ GetWindowRect(hBootType, &rc);
+ MapWindowPoints(NULL, hMainDialog, (POINT*)&rc, 2);
+ hDC = GetDC(hBootType);
+ hFont = (HFONT)SendMessageA(hBootType, WM_GETFONT, 0, 0);
+ SelectObject(hDC, hFont);
+ GetTextExtentPointU(hDC, short_image_path, &sz);
+ safe_release_dc(hBootType, hDC);
+ SendMessage(hBootType, CB_SETDROPPEDWIDTH, (WPARAM)max(sz.cx + 10, rc.right - rc.left), (LPARAM)0);
+}
+
+// Create the horizontal section lines
+void OnPaint(HDC hdc)
+{
+ int i;
+ HPEN hp = CreatePen(0, (fScale < 1.5f) ? 2 : 3, RGB(0, 0, 0));
+ SelectObject(hdc, hp);
+ for (i = 0; i < ARRAYSIZE(section_vpos); i++) {
+ MoveToEx(hdc, mw + 10, section_vpos[i], NULL);
+ LineTo(hdc, mw + fw, section_vpos[i]);
+ }
+}
diff --git a/src/ui.h b/src/ui.h
index ff3aeebb..254ac604 100644
--- a/src/ui.h
+++ b/src/ui.h
@@ -1,6 +1,6 @@
/*
* Rufus: The Reliable USB Formatting Utility
- * UI element lists
+ * UI-related function calls
* Copyright © 2018 Pete Batard
*
* This program is free software: you can redistribute it and/or modify
@@ -18,6 +18,7 @@
*/
#include
+#include
#include "resource.h"
#pragma once
@@ -42,180 +43,31 @@
TBSTYLE_AUTOSIZE | TBSTYLE_LIST | \
TBSTYLE_TOOLTIPS )
-static int section_control_ids[] = {
- IDS_DRIVE_PROPERTIES_TXT,
- IDS_FORMAT_OPTIONS_TXT,
- IDS_STATUS_TXT
-};
+extern HWND hMultiToolbar, hSaveToolbar, hHashToolbar, hAdvancedDeviceToolbar, hAdvancedFormatToolbar;
+extern HFONT hInfoFont;
+extern UINT_PTR UM_LANGUAGE_MENU_MAX;
+extern BOOL advanced_mode_device, advanced_mode_format, force_large_fat32;
+extern loc_cmd* selected_locale;
+extern const char *sfd_name, *flash_type[BADLOCKS_PATTERN_TYPES];
+extern char *short_image_path;
+extern int advanced_device_section_height, advanced_format_section_height, windows_to_go_selection;
+extern int selection_default, cbw, ddw, ddbh, bh;
-static int section_vpos[ARRAYSIZE(section_control_ids)];
-
-static int image_option_move_ids[] = {
- IDS_PARTITION_TYPE_TXT,
- IDC_PARTITION_TYPE,
- IDS_TARGET_SYSTEM_TXT,
- IDC_TARGET_SYSTEM,
- IDS_CSM_HELP_TXT,
- IDC_ADVANCED_DEVICE_TOOLBAR,
- IDC_LIST_USB_HDD,
- IDC_OLD_BIOS_FIXES,
- IDC_RUFUS_MBR,
- IDC_DISK_ID,
- IDS_FORMAT_OPTIONS_TXT,
- IDS_LABEL_TXT,
- IDC_LABEL,
- IDS_FILE_SYSTEM_TXT,
- IDC_FILE_SYSTEM,
- IDS_CLUSTER_SIZE_TXT,
- IDC_CLUSTER_SIZE,
- IDC_ADVANCED_FORMAT_TOOLBAR,
- IDC_QUICK_FORMAT,
- IDC_BAD_BLOCKS,
- IDC_NB_PASSES,
- IDC_EXTENDED_LABEL,
- IDS_STATUS_TXT,
- IDC_PROGRESS,
- IDC_ABOUT,
- IDC_LOG,
- IDC_MULTI_TOOLBAR,
- IDC_TEST,
- IDC_START,
- IDCANCEL,
- IDC_STATUS,
- IDC_STATUS_TOOLBAR,
-};
-
-static int image_option_toggle_ids[][2] = {
- { IDS_IMAGE_OPTION_TXT, 0x03 },
- { IDC_IMAGE_OPTION, 0x01 },
- { IDC_PERSISTENCE_SLIDER, 0x02 },
- { IDC_PERSISTENCE_SIZE, 0x02 },
- { IDC_PERSISTENCE_UNITS, 0x02 }
-};
-
-static int advanced_device_move_ids[] = {
- IDC_LIST_USB_HDD,
- IDC_OLD_BIOS_FIXES,
- IDC_RUFUS_MBR,
- IDS_FORMAT_OPTIONS_TXT,
- IDS_LABEL_TXT,
- IDC_LABEL,
- IDS_FILE_SYSTEM_TXT,
- IDC_FILE_SYSTEM,
- IDS_CLUSTER_SIZE_TXT,
- IDC_CLUSTER_SIZE,
- IDC_ADVANCED_FORMAT_TOOLBAR,
- IDC_QUICK_FORMAT,
- IDC_BAD_BLOCKS,
- IDC_NB_PASSES,
- IDC_EXTENDED_LABEL,
- IDS_STATUS_TXT,
- IDC_PROGRESS,
- IDC_ABOUT,
- IDC_LOG,
- IDC_MULTI_TOOLBAR,
- IDC_TEST,
- IDC_START,
- IDCANCEL,
- IDC_STATUS,
- IDC_STATUS_TOOLBAR,
-};
-
-static int advanced_device_toggle_ids[] = {
- IDC_SAVE_TOOLBAR,
- IDC_LIST_USB_HDD,
- IDC_OLD_BIOS_FIXES,
- IDC_RUFUS_MBR,
- IDC_DISK_ID,
-};
-
-static int advanced_format_move_ids[] = {
- IDS_STATUS_TXT,
- IDC_PROGRESS,
- IDC_ABOUT,
- IDC_LOG,
- IDC_MULTI_TOOLBAR,
- IDC_TEST,
- IDC_START,
- IDCANCEL,
- IDC_STATUS,
- IDC_STATUS_TOOLBAR,
-};
-
-static int advanced_format_toggle_ids[] = {
- IDC_QUICK_FORMAT,
- IDC_BAD_BLOCKS,
- IDC_NB_PASSES,
- IDC_EXTENDED_LABEL,
-};
-
-static int main_button_ids[] = {
- IDC_SELECT,
- IDC_START,
- IDCANCEL,
-};
-
-static int full_width_controls[] = {
- IDS_DEVICE_TXT,
- IDS_BOOT_SELECTION_TXT,
- IDS_IMAGE_OPTION_TXT,
- IDC_IMAGE_OPTION,
- IDS_LABEL_TXT,
- IDC_LABEL,
- IDC_ADVANCED_DRIVE_PROPERTIES,
- IDC_LIST_USB_HDD,
- IDC_OLD_BIOS_FIXES,
- IDC_ADVANCED_FORMAT_OPTIONS,
- IDC_QUICK_FORMAT,
- IDC_EXTENDED_LABEL,
- IDC_PROGRESS,
-};
-
-static int full_width_checkboxes[] = {
- IDC_LIST_USB_HDD,
- IDC_OLD_BIOS_FIXES,
- IDC_QUICK_FORMAT,
- IDC_EXTENDED_LABEL,
-};
-
-static int half_width_ids[] = {
- IDC_BAD_BLOCKS,
- IDC_RUFUS_MBR,
- IDS_PARTITION_TYPE_TXT,
- IDC_PARTITION_TYPE,
- IDC_FILE_SYSTEM,
- IDS_TARGET_SYSTEM_TXT,
- IDC_TARGET_SYSTEM,
- IDC_DISK_ID,
- IDS_CLUSTER_SIZE_TXT,
- IDC_CLUSTER_SIZE,
- IDC_NB_PASSES,
-};
-
-static int adjust_dpi_ids[][5] = {
- {IDS_DEVICE_TXT, IDC_DEVICE, IDC_SAVE_TOOLBAR, 0, 0},
- {IDS_BOOT_SELECTION_TXT, IDC_BOOT_SELECTION, IDC_HASH_TOOLBAR, IDC_SELECT, 0},
- {IDS_IMAGE_OPTION_TXT, IDC_IMAGE_OPTION, IDC_PERSISTENCE_SLIDER, IDC_PERSISTENCE_SIZE, IDC_PERSISTENCE_UNITS},
- {IDS_PARTITION_TYPE_TXT, IDC_PARTITION_TYPE, IDS_TARGET_SYSTEM_TXT, IDC_TARGET_SYSTEM, IDS_CSM_HELP_TXT},
- {IDC_ADVANCED_DEVICE_TOOLBAR, 0, 0, 0, 0},
- {IDC_LIST_USB_HDD, 0, 0, 0, 0 },
- {IDC_OLD_BIOS_FIXES, 0, 0, 0, 0},
- {IDC_RUFUS_MBR, IDC_DISK_ID, 0, 0, 0},
- {IDS_FORMAT_OPTIONS_TXT, 0, 0, 0, 0},
- {IDS_LABEL_TXT, IDC_LABEL, 0, 0, 0},
- {IDS_FILE_SYSTEM_TXT, IDC_FILE_SYSTEM, IDS_CLUSTER_SIZE_TXT, IDC_CLUSTER_SIZE, 0},
- {IDC_ADVANCED_FORMAT_TOOLBAR, 0, 0, 0, 0},
- {IDC_QUICK_FORMAT, 0, 0, 0, 0},
- {IDC_EXTENDED_LABEL, 0, 0, 0, 0},
- {IDC_BAD_BLOCKS, IDC_NB_PASSES, 0, 0, 0},
- {IDS_STATUS_TXT, 0, 0, 0, 0},
- {IDC_PROGRESS, 0, 0, 0, 0 },
- {IDC_MULTI_TOOLBAR, IDC_TEST, IDC_START, IDCANCEL, 0}
-};
-
-static int multitoolbar_icons[] = {
- IDI_LANG_16,
- IDI_INFO_16,
- IDI_SETTINGS_16,
- IDI_LOG_16
-};
+extern void SetComboEntry(HWND hDlg, int data);
+extern void GetBasicControlsWidth(HWND hDlg);
+extern void GetMainButtonsWidth(HWND hDlg);
+extern void GetHalfDropwdownWidth(HWND hDlg);
+extern void GetFullWidth(HWND hDlg);
+extern void PositionMainControls(HWND hDlg);
+extern void AdjustForLowDPI(HWND hDlg);
+extern void SetSectionHeaders(HWND hDlg);
+extern void ToggleAdvancedDeviceOptions(BOOL enable);
+extern void ToggleAdvancedFormatOptions(BOOL enable);
+extern void ToggleImageOption(uint8_t mask);
+extern void CreateSmallButtons(HWND hDlg);
+extern void CreateAdditionalControls(HWND hDlg);
+extern void InitProgress(BOOL bOnlyFormat);
+extern void ShowLanguageMenu(RECT rcExclude);
+extern void SetPassesTooltip(void);
+extern void SetBootTypeDropdownWidth(void);
+extern void OnPaint(HDC hdc);
diff --git a/src/ui_data.h b/src/ui_data.h
new file mode 100644
index 00000000..5401ad04
--- /dev/null
+++ b/src/ui_data.h
@@ -0,0 +1,201 @@
+/*
+ * Rufus: The Reliable USB Formatting Utility
+ * UI element lists
+ * Copyright © 2018 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
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include "resource.h"
+
+#pragma once
+
+static int section_control_ids[] = {
+ IDS_DRIVE_PROPERTIES_TXT,
+ IDS_FORMAT_OPTIONS_TXT,
+ IDS_STATUS_TXT
+};
+
+static int section_vpos[ARRAYSIZE(section_control_ids)];
+
+static int image_option_move_ids[] = {
+ IDS_PARTITION_TYPE_TXT,
+ IDC_PARTITION_TYPE,
+ IDS_TARGET_SYSTEM_TXT,
+ IDC_TARGET_SYSTEM,
+ IDS_CSM_HELP_TXT,
+ IDC_ADVANCED_DEVICE_TOOLBAR,
+ IDC_LIST_USB_HDD,
+ IDC_OLD_BIOS_FIXES,
+ IDC_RUFUS_MBR,
+ IDC_DISK_ID,
+ IDS_FORMAT_OPTIONS_TXT,
+ IDS_LABEL_TXT,
+ IDC_LABEL,
+ IDS_FILE_SYSTEM_TXT,
+ IDC_FILE_SYSTEM,
+ IDS_CLUSTER_SIZE_TXT,
+ IDC_CLUSTER_SIZE,
+ IDC_ADVANCED_FORMAT_TOOLBAR,
+ IDC_QUICK_FORMAT,
+ IDC_BAD_BLOCKS,
+ IDC_NB_PASSES,
+ IDC_EXTENDED_LABEL,
+ IDS_STATUS_TXT,
+ IDC_PROGRESS,
+ IDC_ABOUT,
+ IDC_LOG,
+ IDC_MULTI_TOOLBAR,
+ IDC_TEST,
+ IDC_START,
+ IDCANCEL,
+ IDC_STATUS,
+ IDC_STATUS_TOOLBAR,
+};
+
+static int image_option_toggle_ids[][2] = {
+ { IDS_IMAGE_OPTION_TXT, 0x03 },
+ { IDC_IMAGE_OPTION, 0x01 },
+ { IDC_PERSISTENCE_SLIDER, 0x02 },
+ { IDC_PERSISTENCE_SIZE, 0x02 },
+ { IDC_PERSISTENCE_UNITS, 0x02 }
+};
+
+static int advanced_device_move_ids[] = {
+ IDC_LIST_USB_HDD,
+ IDC_OLD_BIOS_FIXES,
+ IDC_RUFUS_MBR,
+ IDS_FORMAT_OPTIONS_TXT,
+ IDS_LABEL_TXT,
+ IDC_LABEL,
+ IDS_FILE_SYSTEM_TXT,
+ IDC_FILE_SYSTEM,
+ IDS_CLUSTER_SIZE_TXT,
+ IDC_CLUSTER_SIZE,
+ IDC_ADVANCED_FORMAT_TOOLBAR,
+ IDC_QUICK_FORMAT,
+ IDC_BAD_BLOCKS,
+ IDC_NB_PASSES,
+ IDC_EXTENDED_LABEL,
+ IDS_STATUS_TXT,
+ IDC_PROGRESS,
+ IDC_ABOUT,
+ IDC_LOG,
+ IDC_MULTI_TOOLBAR,
+ IDC_TEST,
+ IDC_START,
+ IDCANCEL,
+ IDC_STATUS,
+ IDC_STATUS_TOOLBAR,
+};
+
+static int advanced_device_toggle_ids[] = {
+ IDC_SAVE_TOOLBAR,
+ IDC_LIST_USB_HDD,
+ IDC_OLD_BIOS_FIXES,
+ IDC_RUFUS_MBR,
+ IDC_DISK_ID,
+};
+
+static int advanced_format_move_ids[] = {
+ IDS_STATUS_TXT,
+ IDC_PROGRESS,
+ IDC_ABOUT,
+ IDC_LOG,
+ IDC_MULTI_TOOLBAR,
+ IDC_TEST,
+ IDC_START,
+ IDCANCEL,
+ IDC_STATUS,
+ IDC_STATUS_TOOLBAR,
+};
+
+static int advanced_format_toggle_ids[] = {
+ IDC_QUICK_FORMAT,
+ IDC_BAD_BLOCKS,
+ IDC_NB_PASSES,
+ IDC_EXTENDED_LABEL,
+};
+
+static int main_button_ids[] = {
+ IDC_SELECT,
+ IDC_START,
+ IDCANCEL,
+};
+
+static int full_width_controls[] = {
+ IDS_DEVICE_TXT,
+ IDS_BOOT_SELECTION_TXT,
+ IDS_IMAGE_OPTION_TXT,
+ IDC_IMAGE_OPTION,
+ IDS_LABEL_TXT,
+ IDC_LABEL,
+ IDC_ADVANCED_DRIVE_PROPERTIES,
+ IDC_LIST_USB_HDD,
+ IDC_OLD_BIOS_FIXES,
+ IDC_ADVANCED_FORMAT_OPTIONS,
+ IDC_QUICK_FORMAT,
+ IDC_EXTENDED_LABEL,
+ IDC_PROGRESS,
+};
+
+static int full_width_checkboxes[] = {
+ IDC_LIST_USB_HDD,
+ IDC_OLD_BIOS_FIXES,
+ IDC_QUICK_FORMAT,
+ IDC_EXTENDED_LABEL,
+};
+
+static int half_width_ids[] = {
+ IDC_BAD_BLOCKS,
+ IDC_RUFUS_MBR,
+ IDS_PARTITION_TYPE_TXT,
+ IDC_PARTITION_TYPE,
+ IDC_FILE_SYSTEM,
+ IDS_TARGET_SYSTEM_TXT,
+ IDC_TARGET_SYSTEM,
+ IDC_DISK_ID,
+ IDS_CLUSTER_SIZE_TXT,
+ IDC_CLUSTER_SIZE,
+ IDC_NB_PASSES,
+};
+
+static int adjust_dpi_ids[][5] = {
+ { IDS_DEVICE_TXT, IDC_DEVICE, IDC_SAVE_TOOLBAR, 0, 0 },
+ { IDS_BOOT_SELECTION_TXT, IDC_BOOT_SELECTION, IDC_HASH_TOOLBAR, IDC_SELECT, 0 },
+ { IDS_IMAGE_OPTION_TXT, IDC_IMAGE_OPTION, IDC_PERSISTENCE_SLIDER, IDC_PERSISTENCE_SIZE, IDC_PERSISTENCE_UNITS },
+ { IDS_PARTITION_TYPE_TXT, IDC_PARTITION_TYPE, IDS_TARGET_SYSTEM_TXT, IDC_TARGET_SYSTEM, IDS_CSM_HELP_TXT },
+ { IDC_ADVANCED_DEVICE_TOOLBAR, 0, 0, 0, 0 },
+ { IDC_LIST_USB_HDD, 0, 0, 0, 0 },
+ { IDC_OLD_BIOS_FIXES, 0, 0, 0, 0 },
+ { IDC_RUFUS_MBR, IDC_DISK_ID, 0, 0, 0 },
+ { IDS_FORMAT_OPTIONS_TXT, 0, 0, 0, 0 },
+ { IDS_LABEL_TXT, IDC_LABEL, 0, 0, 0 },
+ { IDS_FILE_SYSTEM_TXT, IDC_FILE_SYSTEM, IDS_CLUSTER_SIZE_TXT, IDC_CLUSTER_SIZE, 0 },
+ { IDC_ADVANCED_FORMAT_TOOLBAR, 0, 0, 0, 0 },
+ { IDC_QUICK_FORMAT, 0, 0, 0, 0 },
+ { IDC_EXTENDED_LABEL, 0, 0, 0, 0 },
+ { IDC_BAD_BLOCKS, IDC_NB_PASSES, 0, 0, 0 },
+ { IDS_STATUS_TXT, 0, 0, 0, 0 },
+ { IDC_PROGRESS, 0, 0, 0, 0 },
+ { IDC_MULTI_TOOLBAR, IDC_TEST, IDC_START, IDCANCEL, 0 }
+};
+
+static int multitoolbar_icons[] = {
+ IDI_LANG_16,
+ IDI_INFO_16,
+ IDI_SETTINGS_16,
+ IDI_LOG_16
+};