From 5c57703c708ddfc384175d8210086672c9a120e9 Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Thu, 19 Apr 2018 12:25:11 +0100 Subject: [PATCH] [ui] add marquee progress bar mode * Also fix x86_64 warnings --- src/net.c | 4 +- src/rufus.c | 128 +++++++++++++++++++++++++++++++++++---------------- src/rufus.h | 6 ++- src/rufus.rc | 10 ++-- src/ui.h | 9 ++++ 5 files changed, 108 insertions(+), 49 deletions(-) diff --git a/src/net.c b/src/net.c index 3c3a0072..7d4a89f4 100644 --- a/src/net.c +++ b/src/net.c @@ -223,7 +223,6 @@ DWORD DownloadFile(const char* url, const char* file, HWND hProgressDialog) BOOL r = FALSE; DWORD dwFlags, dwSize, dwDownloaded, dwTotalSize; FILE* fd = NULL; - LONG progress_style; const char* accept_types[] = {"*/*\0", NULL}; unsigned char buf[DOWNLOAD_BUFFER_SIZE]; char agent[64], hostname[64], urlpath[128]; @@ -238,8 +237,7 @@ DWORD DownloadFile(const char* url, const char* file, HWND hProgressDialog) // Use the progress control provided, if any hProgressBar = GetDlgItem(hProgressDialog, IDC_PROGRESS); if (hProgressBar != NULL) { - progress_style = GetWindowLong(hProgressBar, GWL_STYLE); - SetWindowLong(hProgressBar, GWL_STYLE, progress_style & (~PBS_MARQUEE)); + SendMessage(hProgressBar, PBM_SETMARQUEE, FALSE, 0); SendMessage(hProgressBar, PBM_SETPOS, 0, 0); } SendMessage(hProgressDialog, UM_PROGRESS_INIT, 0, 0); diff --git a/src/rufus.c b/src/rufus.c index 4fe4afae..0249b07f 100644 --- a/src/rufus.c +++ b/src/rufus.c @@ -1774,28 +1774,31 @@ static INT_PTR CALLBACK ProgressCallback(HWND hCtrl, UINT message, WPARAM wParam SIZE size; LONG full_right; wchar_t winfo[128]; - static WORD pos = 0, min = 0, max = 0xFFFF; - static COLORREF color = RGB(0x06, 0xB0, 0x25); + 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 = RGB(0x06, 0xB0, 0x25); + color = PROGRESS_BAR_NORMAL_COLOR; break; case PBST_PAUSED: - color = RGB(0xDA, 0xCB, 0x26); + color = PROGRESS_BAR_PAUSED_COLOR; break; case PBST_ERROR: - color = RGB(0xDA, 0x26, 0x26); + color = PROGRESS_BAR_ERROR_COLOR; break; } return (INT_PTR)TRUE; case PBM_SETRANGE: - min = lParam & 0xFFFF; - max = lParam >> 16; + // 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: @@ -1803,34 +1806,95 @@ static INT_PTR CALLBACK ProgressCallback(HWND hCtrl, UINT message, WPARAM 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); SelectObject(hDC, GetStockObject(DC_PEN)); SelectObject(hDC, GetStockObject(NULL_BRUSH)); - SetDCPenColor(hDC, RGB(0xBC, 0xBC, 0xBC)); + SetDCPenColor(hDC, PROGRESS_BAR_BOX_COLOR); Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom); InflateRect(&rc, -1, -1); // TODO: Handle SetText message so we can avoid this call GetWindowTextW(hProgress, winfo, ARRAYSIZE(winfo)); - full_right = rc.right; - rc.right = (pos > min) ? MulDiv(pos - min, rc.right, max - min) : rc.left; SelectObject(hDC, hInfoFont); - GetTextExtentPoint32(hDC, winfo, wcslen(winfo), &size); - // First half - SetTextColor(hDC, RGB(0xFF, 0xFF, 0xFF)); - SetBkColor(hDC, color); - ExtTextOut(hDC, (full_right - size.cx) / 2, (rc.bottom - size.cy) / 2, - ETO_CLIPPED | ETO_OPAQUE | ETO_NUMERICSLOCAL | (right_to_left_mode ? ETO_RTLREADING : 0), - &rc, winfo, wcslen(winfo), NULL); - // Second half - SetTextColor(hDC, RGB(0x00, 0x00, 0x00)); - SetBkColor(hDC, RGB(0xE6, 0xE6, 0xE6)); + 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 | (right_to_left_mode ? ETO_RTLREADING : 0), + &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 | (right_to_left_mode ? ETO_RTLREADING : 0), + &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 | (right_to_left_mode ? ETO_RTLREADING : 0), + &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 | (right_to_left_mode ? ETO_RTLREADING : 0), + &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 | (right_to_left_mode ? ETO_RTLREADING : 0), - &rc, winfo, wcslen(winfo), NULL); + &rc, winfo, (int)wcslen(winfo), NULL); EndPaint(hCtrl, &ps); return (INT_PTR)TRUE; } @@ -2865,7 +2929,6 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA HDROP droppedFileInfo; POINT Point; RECT rc, DialogRect, DesktopRect; - LONG progress_style; HDC hDC; PAINTSTRUCT ps; int nDeviceIndex, i, nWidth, nHeight, nb_devices, selected_language, offset; @@ -3468,30 +3531,20 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA case UM_PROGRESS_INIT: isMarquee = (wParam == PBS_MARQUEE); - if (isMarquee) { - progress_style = GetWindowLong(hProgress, GWL_STYLE); - SetWindowLong(hProgress, GWL_STYLE, progress_style | PBS_MARQUEE); + if (isMarquee) SendMessage(hProgress, PBM_SETMARQUEE, TRUE, 0); - } else { + else SendMessage(hProgress, PBM_SETPOS, 0, 0); - } SetTaskbarProgressState(TASKBAR_NORMAL); SetTaskbarProgressValue(0, MAX_PROGRESS); break; case UM_PROGRESS_EXIT: if (isMarquee) { - // Remove marquee style if previously set - progress_style = GetWindowLong(hProgress, GWL_STYLE); - SetWindowLong(hProgress, GWL_STYLE, progress_style & (~PBS_MARQUEE)); + SendMessage(hProgress, PBM_SETMARQUEE, FALSE, 0); SetTaskbarProgressValue(0, MAX_PROGRESS); - SendMessage(hProgress, PBM_SETPOS, 0, 0); } else if (!IS_ERROR(FormatStatus)) { SetTaskbarProgressValue(MAX_PROGRESS, MAX_PROGRESS); - // This is the only way to achieve instantaneous progress transition to 100% - SendMessage(hProgress, PBM_SETRANGE, 0, ((MAX_PROGRESS+1)<<16) & 0xFFFF0000); - SendMessage(hProgress, PBM_SETPOS, (MAX_PROGRESS+1), 0); - SendMessage(hProgress, PBM_SETRANGE, 0, (MAX_PROGRESS<<16) & 0xFFFF0000); } SendMessage(hProgress, PBM_SETSTATE, (WPARAM)PBST_NORMAL, 0); SetTaskbarProgressState(TASKBAR_NORMAL); @@ -3517,10 +3570,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA GetDevices(DeviceNum); } if (!IS_ERROR(FormatStatus)) { - // This is the only way to achieve instantaneous progress transition to 100% - SendMessage(hProgress, PBM_SETRANGE, 0, ((MAX_PROGRESS+1)<<16) & 0xFFFF0000); - SendMessage(hProgress, PBM_SETPOS, (MAX_PROGRESS+1), 0); - SendMessage(hProgress, PBM_SETRANGE, 0, (MAX_PROGRESS<<16) & 0xFFFF0000); + SendMessage(hProgress, PBM_SETPOS, MAX_PROGRESS, 0); SetTaskbarProgressState(TASKBAR_NOPROGRESS); PrintInfo(0, MSG_210); MessageBeep(MB_OK); diff --git a/src/rufus.h b/src/rufus.h index b5f994b0..ad38f775 100644 --- a/src/rufus.h +++ b/src/rufus.h @@ -53,7 +53,7 @@ #define MAX_TOOLTIPS 128 #define MAX_SIZE_SUFFIXES 6 // bytes, KB, MB, GB, TB, PB #define MAX_CLUSTER_SIZES 18 -#define MAX_PROGRESS (0xFFFF-1) // leave room for 1 more for insta-progress workaround +#define MAX_PROGRESS 0xFFFF #define MAX_LOG_SIZE 0x7FFFFFFE #define MAX_REFRESH 25 // How long we should wait to refresh UI elements (in ms) #define MAX_GUID_STRING_LENGTH 40 @@ -62,6 +62,7 @@ #define MBR_UEFI_MARKER 0x49464555 // 'U', 'E', 'F', 'I', as a 32 bit little endian longword #define STATUS_MSG_TIMEOUT 3500 // How long should cheat mode messages appear for on the status bar #define WRITE_RETRIES 3 +#define MARQUEE_TIMER_REFRESH 10 // Time between progress bar marquee refreshes, in ms #define FS_DEFAULT FS_FAT32 #define SINGLE_CLUSTERSIZE_DEFAULT 0x00000100 #define BADBLOCK_PATTERNS {0xaa, 0x55, 0xff, 0x00} @@ -185,7 +186,8 @@ enum timer_type { TID_BADBLOCKS_UPDATE, TID_APP_TIMER, TID_BLOCKING_TIMER, - TID_REFRESH_TIMER + TID_REFRESH_TIMER, + TID_MARQUEE_TIMER }; /* Action type, for progress bar breakdown */ diff --git a/src/rufus.rc b/src/rufus.rc index 7324aea9..066487e3 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.0.1251" +CAPTION "Rufus 3.0.1252" FONT 9, "Segoe UI Symbol", 400, 0, 0x0 BEGIN LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP @@ -371,8 +371,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,0,1251,0 - PRODUCTVERSION 3,0,1251,0 + FILEVERSION 3,0,1252,0 + PRODUCTVERSION 3,0,1252,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -389,13 +389,13 @@ BEGIN BEGIN VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "3.0.1251" + VALUE "FileVersion", "3.0.1252" 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.0.1251" + VALUE "ProductVersion", "3.0.1252" END END BLOCK "VarFileInfo" diff --git a/src/ui.h b/src/ui.h index 179b927b..b6d9aa06 100644 --- a/src/ui.h +++ b/src/ui.h @@ -22,6 +22,15 @@ #pragma once +// Progress bar colors +#define PROGRESS_BAR_NORMAL_TEXT_COLOR RGB(0x00, 0x00, 0x00) +#define PROGRESS_BAR_INVERTED_TEXT_COLOR RGB(0xFF, 0xFF, 0xFF) +#define PROGRESS_BAR_BACKGROUND_COLOR RGB(0xE6, 0xE6, 0xE6) +#define PROGRESS_BAR_BOX_COLOR RGB(0xBC, 0xBC, 0xBC) +#define PROGRESS_BAR_NORMAL_COLOR RGB(0x06, 0xB0, 0x25) +#define PROGRESS_BAR_PAUSED_COLOR RGB(0xDA, 0xCB, 0x26) +#define PROGRESS_BAR_ERROR_COLOR RGB(0xDA, 0x26, 0x26) + static int image_option_move_ids[] = { IDS_PARTITION_TYPE_TXT, IDC_PARTITION_TYPE,