diff --git a/src/rufus.c b/src/rufus.c index 9e38c77d..358a9c31 100644 --- a/src/rufus.c +++ b/src/rufus.c @@ -39,6 +39,20 @@ #include "rufus.h" #include "sys_types.h" +/* Redefinitions for the WDK */ +#ifndef PBM_SETSTATE +#define PBM_SETSTATE (WM_USER+16) +#endif +#ifndef PBST_NORMAL +#define PBST_NORMAL 1 +#endif +#ifndef PBST_ERROR +#define PBST_ERROR 2 +#endif +#ifndef PBST_PAUSED +#define PBST_PAUSED 3 +#endif + static const char* FileSystemLabel[FS_MAX] = { "FAT", "FAT32", "NTFS", "exFAT" }; // Don't ask me - just following the MS standard here static const char* ClusterSizeLabel[] = { "512 bytes", "1024 bytes","2048 bytes","4096 bytes","8192 bytes", @@ -783,6 +797,7 @@ void UpdateProgress(int op, float percent) } SendMessage(hProgress, PBM_SETPOS, (WPARAM)pos, 0); + SetTaskbarProgressValue(pos, MAX_PROGRESS); } /* @@ -1165,9 +1180,11 @@ void InitDialog(HWND hDlg) // Prefer FreeDOS to MS-DOS selection_default = DT_FREEDOS; - - // Create the status line + // Create the status line and initialize the taskbar icon for progress overlay CreateStatusBar(); + CreateTaskbarList(); + SetTaskbarProgressState(TASKBAR_NORMAL); + // Use maximum granularity for the progress bar SendMessage(hProgress, PBM_SETRANGE, 0, MAX_PROGRESS<<16); // Fill up the passes @@ -1445,6 +1462,10 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA _snwprintf(wstr, ARRAYSIZE(wstr), L"WARNING: ALL DATA ON DEVICE %s\r\nWILL BE DESTROYED.\r\n" L"To continue with this operation, click OK. To quit click CANCEL.", wtmp); if (MessageBoxW(hMainDialog, wstr, L"Rufus", MB_OKCANCEL|MB_ICONWARNING) == IDOK) { + // Reset all progress bars + SendMessage(hProgress, PBM_SETSTATE, (WPARAM)PBST_NORMAL, 0); + SetTaskbarProgressState(TASKBAR_NORMAL); + SetTaskbarProgressValue(0, MAX_PROGRESS); // Disable all controls except cancel EnableControls(FALSE); DeviceNum = (DWORD)ComboBox_GetItemData(hDeviceList, nDeviceIndex); @@ -1494,21 +1515,22 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA EnableControls(TRUE); GetUSBDevices(DeviceNum); if (!IS_ERROR(FormatStatus)) { - PrintStatus(0, FALSE, "DONE"); - } else if (SCODE_CODE(FormatStatus) == ERROR_CANCELLED) { - PrintStatus(0, FALSE, "Cancelled"); - Notification(MSG_INFO, "Cancelled", "Operation cancelled by the user."); - } else { - PrintStatus(0, FALSE, "FAILED"); - Notification(MSG_ERROR, "Error", "Error: %s", StrError(FormatStatus)); - } - if (FormatStatus) { - SendMessage(hProgress, PBM_SETPOS, 0, 0); - } else { - // This is the only way to achieve instantenous progress transition + // This is the only way to achieve instantenous progress transition to 100% SendMessage(hProgress, PBM_SETRANGE, 0, (MAX_PROGRESS+1)<<16); SendMessage(hProgress, PBM_SETPOS, (MAX_PROGRESS+1), 0); SendMessage(hProgress, PBM_SETRANGE, 0, MAX_PROGRESS<<16); + SetTaskbarProgressState(TASKBAR_NOPROGRESS); + PrintStatus(0, FALSE, "DONE"); + } else if (SCODE_CODE(FormatStatus) == ERROR_CANCELLED) { + SendMessage(hProgress, PBM_SETSTATE, (WPARAM)PBST_PAUSED, 0); + SetTaskbarProgressState(TASKBAR_PAUSED); + PrintStatus(0, FALSE, "Cancelled"); + Notification(MSG_INFO, "Cancelled", "Operation cancelled by the user."); + } else { + SendMessage(hProgress, PBM_SETSTATE, (WPARAM)PBST_ERROR, 0); + SetTaskbarProgressState(TASKBAR_ERROR); + PrintStatus(0, FALSE, "FAILED"); + Notification(MSG_ERROR, "Error", "Error: %s", StrError(FormatStatus)); } return (INT_PTR)TRUE; } diff --git a/src/rufus.h b/src/rufus.h index 2aca841b..a3756a0e 100644 --- a/src/rufus.h +++ b/src/rufus.h @@ -159,6 +159,16 @@ typedef struct { BOOL uses_minint; } RUFUS_ISO_REPORT; +/* Duplication of the TBPFLAG enum for Windows 7 taskbar progress */ +typedef enum TASKBAR_PROGRESS_FLAGS +{ + TASKBAR_NOPROGRESS = 0, + TASKBAR_INDETERMINATE = 0x1, + TASKBAR_NORMAL = 0x2, + TASKBAR_ERROR = 0x4, + TASKBAR_PAUSED = 0x8 +} TASKBAR_PROGRESS_FLAGS; + /* * Globals */ @@ -187,6 +197,9 @@ extern void UpdateProgress(int op, float percent); extern const char* StrError(DWORD error_code); extern void CenterDialog(HWND hDlg); extern void CreateStatusBar(void); +extern BOOL CreateTaskbarList(void); +extern BOOL SetTaskbarProgressState(TASKBAR_PROGRESS_FLAGS tbpFlags); +extern BOOL SetTaskbarProgressValue(ULONGLONG ullCompleted, ULONGLONG ullTotal); extern INT_PTR CreateAboutBox(void); extern HWND CreateTooltip(HWND hControl, const char* message, int duration); extern void DestroyTooltip(HWND hWnd); @@ -292,4 +305,4 @@ typedef struct { #endif #ifndef PBM_SETMARQUEE #define PBM_SETMARQUEE (WM_USER+10) -#endif \ No newline at end of file +#endif diff --git a/src/rufus.rc b/src/rufus.rc index 57788e5e..ddba868b 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -30,7 +30,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL IDD_DIALOG DIALOGEX 12, 12, 206, 289 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_APPWINDOW -CAPTION "Rufus v1.2.0.163" +CAPTION "Rufus v1.2.0.164" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN DEFPUSHBUTTON "Start",IDC_START,94,248,50,14 @@ -71,7 +71,7 @@ BEGIN DEFPUSHBUTTON "OK",IDOK,231,175,50,14,WS_GROUP CONTROL "http://rufus.akeo.ie",IDC_ABOUT_RUFUS_URL, "SysLink",WS_TABSTOP,46,47,114,9 - LTEXT "Version 1.2.0 (Build 163)",IDC_STATIC,46,19,78,8 + LTEXT "Version 1.2.0 (Build 164)",IDC_STATIC,46,19,78,8 PUSHBUTTON "License...",IDC_ABOUT_LICENSE,46,175,50,14,WS_GROUP EDITTEXT IDC_ABOUT_COPYRIGHTS,46,107,235,63,ES_MULTILINE | ES_READONLY | WS_VSCROLL LTEXT "Report bugs or request enhancements at:",IDC_STATIC,46,66,187,8 @@ -216,8 +216,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,2,0,163 - PRODUCTVERSION 1,2,0,163 + FILEVERSION 1,2,0,164 + PRODUCTVERSION 1,2,0,164 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -234,13 +234,13 @@ BEGIN BEGIN VALUE "CompanyName", "akeo.ie" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "1.2.0.163" + VALUE "FileVersion", "1.2.0.164" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "© 2011 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" VALUE "OriginalFilename", "rufus.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "1.2.0.163" + VALUE "ProductVersion", "1.2.0.164" END END BLOCK "VarFileInfo" diff --git a/src/stdlg.c b/src/stdlg.c index 2ac69f6c..5d9853db 100644 --- a/src/stdlg.c +++ b/src/stdlg.c @@ -831,3 +831,116 @@ LONG GetEntryWidth(HWND hDropDown, const char *entry) free(wentry); return size.cx; } + +/* + * Windows 7 taskbar icon handling (progress bar overlay, etc) + * Some platforms don't have these, so we redefine + */ +typedef enum MY_STPFLAG +{ + MY_STPF_NONE = 0, + MY_STPF_USEAPPTHUMBNAILALWAYS = 0x1, + MY_STPF_USEAPPTHUMBNAILWHENACTIVE = 0x2, + MY_STPF_USEAPPPEEKALWAYS = 0x4, + MY_STPF_USEAPPPEEKWHENACTIVE = 0x8 +} MY_STPFLAG; + +typedef enum MY_THUMBBUTTONMASK +{ + MY_THB_BITMAP = 0x1, + MY_THB_ICON = 0x2, + MY_THB_TOOLTIP = 0x4, + MY_THB_FLAGS = 0x8 +} MY_THUMBBUTTONMASK; + +typedef enum MY_THUMBBUTTONFLAGS +{ + MY_THBF_ENABLED = 0, + MY_THBF_DISABLED = 0x1, + MY_THBF_DISMISSONCLICK = 0x2, + MY_THBF_NOBACKGROUND = 0x4, + MY_THBF_HIDDEN = 0x8, + MY_THBF_NONINTERACTIVE = 0x10 +} MY_THUMBBUTTONFLAGS; + +typedef struct MY_THUMBBUTTON +{ + MY_THUMBBUTTONMASK dwMask; + UINT iId; + UINT iBitmap; + HICON hIcon; + WCHAR szTip[260]; + MY_THUMBBUTTONFLAGS dwFlags; +} MY_THUMBBUTTON; + +/* +typedef enum MY_TBPFLAG +{ + TASKBAR_NOPROGRESS = 0, + TASKBAR_INDETERMINATE = 0x1, + TASKBAR_NORMAL = 0x2, + TASKBAR_ERROR = 0x4, + TASKBAR_PAUSED = 0x8 +} MY_TBPFLAG; +*/ + +#pragma push_macro("INTERFACE") +#undef INTERFACE +#define INTERFACE my_ITaskbarList3 +DECLARE_INTERFACE_(my_ITaskbarList3, IUnknown) { + STDMETHOD (QueryInterface) (THIS_ REFIID riid, LPVOID *ppvObj) PURE; + STDMETHOD_(ULONG, AddRef) (THIS) PURE; + STDMETHOD_(ULONG, Release) (THIS) PURE; + STDMETHOD (HrInit) (THIS) PURE; + STDMETHOD (AddTab) (THIS_ HWND hwnd) PURE; + STDMETHOD (DeleteTab) (THIS_ HWND hwnd) PURE; + STDMETHOD (ActivateTab) (THIS_ HWND hwnd) PURE; + STDMETHOD (SetActiveAlt) (THIS_ HWND hwnd) PURE; + STDMETHOD (MarkFullscreenWindow) (THIS_ HWND hwnd, int fFullscreen) PURE; + STDMETHOD (SetProgressValue) (THIS_ HWND hwnd, ULONGLONG ullCompleted, ULONGLONG ullTotal) PURE; + STDMETHOD (SetProgressState) (THIS_ HWND hwnd, TASKBAR_PROGRESS_FLAGS tbpFlags) PURE; + STDMETHOD (RegisterTab) (THIS_ HWND hwndTab,HWND hwndMDI) PURE; + STDMETHOD (UnregisterTab) (THIS_ HWND hwndTab) PURE; + STDMETHOD (SetTabOrder) (THIS_ HWND hwndTab, HWND hwndInsertBefore) PURE; + STDMETHOD (SetTabActive) (THIS_ HWND hwndTab, HWND hwndMDI, DWORD dwReserved) PURE; + STDMETHOD (ThumbBarAddButtons) (THIS_ HWND hwnd, UINT cButtons, MY_THUMBBUTTON* pButton) PURE; + STDMETHOD (ThumbBarUpdateButtons) (THIS_ HWND hwnd, UINT cButtons, MY_THUMBBUTTON* pButton) PURE; + STDMETHOD (ThumbBarSetImageList) (THIS_ HWND hwnd, HIMAGELIST himl) PURE; + STDMETHOD (SetOverlayIcon) (THIS_ HWND hwnd, HICON hIcon, LPCWSTR pszDescription) PURE; + STDMETHOD (SetThumbnailTooltip) (THIS_ HWND hwnd, LPCWSTR pszTip) PURE; + STDMETHOD (SetThumbnailClip) (THIS_ HWND hwnd, RECT *prcClip) PURE; +}; +const IID my_IID_ITaskbarList3 = + { 0xea1afb91, 0x9e28, 0x4b86, { 0x90, 0xe9, 0x9e, 0x9f, 0x8a, 0x5e, 0xef, 0xaf } }; +const IID my_CLSID_TaskbarList = + { 0x56fdf344, 0xfd6d, 0x11d0, { 0x95, 0x8a ,0x0, 0x60, 0x97, 0xc9, 0xa0 ,0x90 } }; + +static my_ITaskbarList3* ptbl = NULL; + +BOOL CreateTaskbarList(void) +{ + HRESULT hr; + // Create the taskbar icon progressbar + hr = CoCreateInstance(&my_CLSID_TaskbarList, NULL, CLSCTX_ALL, &my_IID_ITaskbarList3, (LPVOID)&ptbl); + if (FAILED(hr)) { + uprintf("CoCreateInstance for TaskbarList failed: error %X", hr); + ptbl = NULL; + return FALSE; + } + return TRUE; +} + +BOOL SetTaskbarProgressState(TASKBAR_PROGRESS_FLAGS tbpFlags) +{ + if (ptbl == NULL) + return FALSE; + return !FAILED(ptbl->lpVtbl->SetProgressState(ptbl, hMainDialog, tbpFlags)); +} + +BOOL SetTaskbarProgressValue(ULONGLONG ullCompleted, ULONGLONG ullTotal) +{ + if (ptbl == NULL) + return FALSE; + return !FAILED(ptbl->lpVtbl->SetProgressValue(ptbl, hMainDialog, ullCompleted, ullTotal)); +} +#pragma pop_macro("INTERFACE")