[ui] Display progress on the Windows 7 taskbar icon

* Also updates dialog progress handling
* Closes #72
This commit is contained in:
Pete Batard 2012-03-29 18:16:06 +01:00
parent 98ff7a931a
commit 8d2fd913b0
4 changed files with 169 additions and 21 deletions

View file

@ -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;
}

View file

@ -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
#endif

View file

@ -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 "<a href=""http://rufus.akeo.ie"">http://rufus.akeo.ie</a>",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"

View file

@ -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")