[ui] Why, it's the check for application update (part 6)

* Use TortoiseGit inspired notification and download dialog
This commit is contained in:
Pete Batard 2012-12-05 01:53:10 +00:00
parent 4251e78fcd
commit 25e999ded9
8 changed files with 130 additions and 56 deletions

View file

@ -81,6 +81,10 @@ const char* additional_copyrights =
"http://winscp.net\\line\n" "http://winscp.net\\line\n"
"GNU General Public License (GPL) v3 or later\\line\n" "GNU General Public License (GPL) v3 or later\\line\n"
"\\line\n" "\\line\n"
"Check for Update dialog inspired by TortoiseSVN & TortoiseGit\\line\n"
"http://tortoisesvn.net/, http://code.google.com/p/tortoisegit/\\line\n"
"GNU General Public License (GPL) v2 or later\\line\n"
"\\line\n"
"\\line\n" "\\line\n"
"All other references can be found in the source.\\line\n}"; "All other references can be found in the source.\\line\n}";

View file

@ -233,7 +233,7 @@ const char* WinInetErrorString(void)
* Download a file from an URL * Download a file from an URL
* Mostly taken from http://support.microsoft.com/kb/234913 * Mostly taken from http://support.microsoft.com/kb/234913
*/ */
BOOL DownloadFile(const char* url, const char* file) BOOL DownloadFile(const char* url, const char* file, HWND hProgressDialog, HWND hProgressBar)
{ {
BOOL r = FALSE; BOOL r = FALSE;
DWORD dwFlags, dwSize, dwDownloaded, dwTotalSize, dwStatus; DWORD dwFlags, dwSize, dwDownloaded, dwTotalSize, dwStatus;
@ -247,12 +247,15 @@ BOOL DownloadFile(const char* url, const char* file)
int i; int i;
// We reuse the ISO progress dialog for download progress // We reuse the ISO progress dialog for download progress
SetWindowTextU(hISOProgressDlg, "Downloading file..."); if (hProgressDialog != NULL)
SetWindowTextU(hISOFileName, url); SetWindowTextU(hProgressDialog, "Downloading file...");
progress_style = GetWindowLong(hISOProgressBar, GWL_STYLE); if (hProgressBar != NULL) {
SetWindowLong(hISOProgressBar, GWL_STYLE, progress_style & (~PBS_MARQUEE)); progress_style = GetWindowLong(hProgressBar, GWL_STYLE);
SendMessage(hISOProgressBar, PBM_SETPOS, 0, 0); SetWindowLong(hProgressBar, GWL_STYLE, progress_style & (~PBS_MARQUEE));
SendMessage(hISOProgressDlg, UM_ISO_INIT, 0, 0); SendMessage(hProgressBar, PBM_SETPOS, 0, 0);
}
if (hProgressDialog != NULL)
SendMessage(hProgressDialog, UM_ISO_INIT, 0, 0);
PrintStatus(0, FALSE, "Downloading %s: Connecting...\n", file); PrintStatus(0, FALSE, "Downloading %s: Connecting...\n", file);
uprintf("Downloading %s from %s\n", file, url); uprintf("Downloading %s from %s\n", file, url);
@ -329,7 +332,7 @@ BOOL DownloadFile(const char* url, const char* file)
if (!InternetReadFile(hRequest, buf, sizeof(buf), &dwDownloaded) || (dwDownloaded == 0)) if (!InternetReadFile(hRequest, buf, sizeof(buf), &dwDownloaded) || (dwDownloaded == 0))
break; break;
dwSize += dwDownloaded; dwSize += dwDownloaded;
SendMessage(hISOProgressBar, PBM_SETPOS, (WPARAM)(MAX_PROGRESS*((1.0f*dwSize)/(1.0f*dwTotalSize))), 0); SendMessage(hProgressBar, PBM_SETPOS, (WPARAM)(MAX_PROGRESS*((1.0f*dwSize)/(1.0f*dwTotalSize))), 0);
PrintStatus(0, FALSE, "Downloading %s: %0.1f%%\n", file, (100.0f*dwSize)/(1.0f*dwTotalSize)); PrintStatus(0, FALSE, "Downloading %s: %0.1f%%\n", file, (100.0f*dwSize)/(1.0f*dwTotalSize));
if (fwrite(buf, 1, dwDownloaded, fd) != dwDownloaded) { if (fwrite(buf, 1, dwDownloaded, fd) != dwDownloaded) {
uprintf("Error writing file %s: %s\n", file, WinInetErrorString()); uprintf("Error writing file %s: %s\n", file, WinInetErrorString());
@ -347,7 +350,8 @@ BOOL DownloadFile(const char* url, const char* file)
} }
out: out:
SendMessage(hISOProgressDlg, UM_ISO_EXIT, 0, 0); if (hProgressDialog != NULL)
SendMessage(hProgressDialog, UM_ISO_EXIT, 0, 0);
if (fd != NULL) fclose(fd); if (fd != NULL) fclose(fd);
if (!r) { if (!r) {
_unlink(file); _unlink(file);

View file

@ -34,17 +34,6 @@
#include "rufus.h" #include "rufus.h"
#include "msapi_utf8.h" #include "msapi_utf8.h"
typedef struct {
uint8_t version[4];
char* type; // "release", "beta", "notice"
char* platform; // target platform ("windows", "linux", etc.)
char* platform_arch; // "x86", "x64", "arm"
char* platform_min; // minimum platform version required
char* download_url;
char* release_notes;
} rufus_update;
// Parse a line of UTF-16 text and return the data if it matches the 'token' // Parse a line of UTF-16 text and return the data if it matches the 'token'
// The parsed line is of the form: [ ]token[ ]=[ ]["]data["][ ] and the line // The parsed line is of the form: [ ]token[ ]=[ ]["]data["][ ] and the line
// is modified by the parser // is modified by the parser
@ -214,14 +203,12 @@ static __inline char* get_sanitized_token_data_buffer(const char* token, unsigne
// NB: since this is remote data, and we're running elevated, it *IS* considered // NB: since this is remote data, and we're running elevated, it *IS* considered
// potentially malicious, even if it comes from a supposedly trusted server. // potentially malicious, even if it comes from a supposedly trusted server.
// len should be the size of the buffer, including the zero terminator // len should be the size of the buffer, including the zero terminator
extern INT_PTR NewVersionDialog(const char* notes, const char* url);
void parse_update(char* buf, size_t len) void parse_update(char* buf, size_t len)
{ {
size_t i; size_t i;
char *data = NULL, *token; char *data = NULL, *token;
char allowed_rtf_chars[] = "abcdefghijklmnopqrstuvwxyz|~-_:*'"; char allowed_rtf_chars[] = "abcdefghijklmnopqrstuvwxyz|~-_:*'";
char allowed_std_chars[] = "\r\n ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\"$%^&+=<>(){}[].,;#@/?"; char allowed_std_chars[] = "\r\n ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\"$%^&+=<>(){}[].,;#@/?";
rufus_update update;
// strchr includes the NUL terminator in the search, so take care of backslash before NUL // strchr includes the NUL terminator in the search, so take care of backslash before NUL
if ((buf == NULL) || (len < 2) || (len > 65536) || (buf[len-1] != 0) || (buf[len-2] == '\\')) if ((buf == NULL) || (len < 2) || (len > 65536) || (buf[len-1] != 0) || (buf[len-2] == '\\'))
@ -264,8 +251,7 @@ void parse_update(char* buf, size_t len)
while (iso_op_in_progress || format_op_in_progress) { while (iso_op_in_progress || format_op_in_progress) {
Sleep(3000); Sleep(3000);
} }
NewVersionDialog(update.release_notes, update.download_url); DownloadNewVersion();
// TODO: free all these strings! // TODO: free all these strings!
} }

View file

@ -89,6 +89,11 @@
#define IDC_INCLUDE_BETAS 1063 #define IDC_INCLUDE_BETAS 1063
#define IDC_RELEASE_NOTES 1064 #define IDC_RELEASE_NOTES 1064
#define IDC_DOWNLOAD 1065 #define IDC_DOWNLOAD 1065
#define IDC_UPDATE_PROGRESS 1066
#define IDC_WEBSITE 1067
#define IDC_YOUR_VERSION 1068
#define IDC_LATEST_VERSION 1069
#define IDC_DOWNLOAD_URL 1070
// Next default values for new objects // Next default values for new objects
// //
@ -97,7 +102,7 @@
#define _APS_NO_MFC 1 #define _APS_NO_MFC 1
#define _APS_NEXT_RESOURCE_VALUE 113 #define _APS_NEXT_RESOURCE_VALUE 113
#define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1066 #define _APS_NEXT_CONTROL_VALUE 1071
#define _APS_NEXT_SYMED_VALUE 101 #define _APS_NEXT_SYMED_VALUE 101
#endif #endif
#endif #endif

View file

@ -106,6 +106,7 @@ HWND hISOProgressDlg = NULL, hLogDlg = NULL, hISOProgressBar, hISOFileName, hDis
BOOL use_own_vesamenu = FALSE, detect_fakes = TRUE, mbr_selected_by_user = FALSE; BOOL use_own_vesamenu = FALSE, detect_fakes = TRUE, mbr_selected_by_user = FALSE;
BOOL iso_op_in_progress = FALSE, format_op_in_progress = FALSE; BOOL iso_op_in_progress = FALSE, format_op_in_progress = FALSE;
int rufus_version[4]; int rufus_version[4];
RUFUS_UPDATE update;
extern char szStatusMessage[256]; extern char szStatusMessage[256];
static HANDLE format_thid = NULL; static HANDLE format_thid = NULL;
@ -1282,7 +1283,8 @@ DWORD WINAPI ISOScanThread(LPVOID param)
"Note: the file will be downloaded in the current directory. Once a\n" "Note: the file will be downloaded in the current directory. Once a\n"
"vesamenu.c32 exists there, it will always be used as replacement.\n", "Replace vesamenu.c32?", "vesamenu.c32 exists there, it will always be used as replacement.\n", "Replace vesamenu.c32?",
MB_YESNO|MB_ICONWARNING) == IDYES) { MB_YESNO|MB_ICONWARNING) == IDYES) {
if (DownloadFile(VESAMENU_URL, vesamenu_filename)) SetWindowTextU(hISOFileName, VESAMENU_URL);
if (DownloadFile(VESAMENU_URL, vesamenu_filename, hISOProgressDlg, hISOProgressBar))
use_own_vesamenu = TRUE; use_own_vesamenu = TRUE;
} }
} }
@ -1371,7 +1373,6 @@ void InitDialog(HWND hDlg)
HINSTANCE hDllInst; HINSTANCE hDllInst;
HDC hDC; HDC hDC;
int i, i16, s16, s32; int i, i16, s16, s32;
HICON hSmallIcon, hBigIcon;
char tmp[128], *token; char tmp[128], *token;
#ifdef RUFUS_TEST #ifdef RUFUS_TEST
@ -1418,10 +1419,7 @@ void InitDialog(HWND hDlg)
s32 = 24; s32 = 24;
// Create the title bar icon // Create the title bar icon
hSmallIcon = (HICON)LoadImage(hMainInstance, MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON, s16, s16, 0); SetTitleBarIcon(hDlg);
SendMessage (hDlg, WM_SETICON, ICON_SMALL, (LPARAM)hSmallIcon);
hBigIcon = (HICON)LoadImage(hMainInstance, MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON, s32, s32, 0);
SendMessage (hDlg, WM_SETICON, ICON_BIG, (LPARAM)hBigIcon);
GetWindowTextA(hDlg, tmp, sizeof(tmp)); GetWindowTextA(hDlg, tmp, sizeof(tmp));
// Count of Microsoft for making it more attractive to read a // Count of Microsoft for making it more attractive to read a
// version using strtok() than using GetFileVersionInfo() // version using strtok() than using GetFileVersionInfo()

View file

@ -175,6 +175,16 @@ typedef struct {
BOOL uses_minint; BOOL uses_minint;
} RUFUS_ISO_REPORT; } RUFUS_ISO_REPORT;
typedef struct {
uint8_t version[4];
char* type; // "release", "beta", "notice"
char* platform; // target platform ("windows", "linux", etc.)
char* platform_arch; // "x86", "x64", "arm"
char* platform_min; // minimum platform version required
char* download_url;
char* release_notes;
} RUFUS_UPDATE;
/* Duplication of the TBPFLAG enum for Windows 7 taskbar progress */ /* Duplication of the TBPFLAG enum for Windows 7 taskbar progress */
typedef enum TASKBAR_PROGRESS_FLAGS typedef enum TASKBAR_PROGRESS_FLAGS
{ {
@ -215,6 +225,7 @@ extern RUFUS_ISO_REPORT iso_report;
extern int64_t iso_blocking_status; extern int64_t iso_blocking_status;
extern int rufus_version[4]; extern int rufus_version[4];
extern enum WindowsVersion nWindowsVersion; extern enum WindowsVersion nWindowsVersion;
extern RUFUS_UPDATE update;
/* /*
* Shared prototypes * Shared prototypes
@ -227,6 +238,7 @@ extern void UpdateProgress(int op, float percent);
extern const char* StrError(DWORD error_code); extern const char* StrError(DWORD error_code);
extern void CenterDialog(HWND hDlg); extern void CenterDialog(HWND hDlg);
extern void CreateStatusBar(void); extern void CreateStatusBar(void);
extern void SetTitleBarIcon(HWND hDlg);
extern BOOL CreateTaskbarList(void); extern BOOL CreateTaskbarList(void);
extern BOOL SetTaskbarProgressState(TASKBAR_PROGRESS_FLAGS tbpFlags); extern BOOL SetTaskbarProgressState(TASKBAR_PROGRESS_FLAGS tbpFlags);
extern BOOL SetTaskbarProgressValue(ULONGLONG ullCompleted, ULONGLONG ullTotal); extern BOOL SetTaskbarProgressValue(ULONGLONG ullCompleted, ULONGLONG ullTotal);
@ -250,10 +262,11 @@ extern BOOL SetAutorun(const char* path);
extern char* FileDialog(BOOL save, char* path, char* filename, char* ext, char* ext_desc); extern char* FileDialog(BOOL save, char* path, char* filename, char* ext, char* ext_desc);
extern BOOL FileIO(BOOL save, char* path, char** buffer, DWORD* size); extern BOOL FileIO(BOOL save, char* path, char** buffer, DWORD* size);
extern LONG GetEntryWidth(HWND hDropDown, const char* entry); extern LONG GetEntryWidth(HWND hDropDown, const char* entry);
extern BOOL DownloadFile(const char* url, const char* file); extern BOOL DownloadFile(const char* url, const char* file, HWND hProgressDialog, HWND hProgressBar);
extern INT_PTR CALLBACK UpdateCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); extern INT_PTR CALLBACK UpdateCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
extern BOOL SetUpdateCheck(void); extern BOOL SetUpdateCheck(void);
extern BOOL CheckForUpdates(void); extern BOOL CheckForUpdates(void);
extern void DownloadNewVersion(void);
extern BOOL IsShown(HWND hDlg); extern BOOL IsShown(HWND hDlg);
extern char* get_token_data_file(const char* token, const char* filename); extern char* get_token_data_file(const char* token, const char* filename);
extern char* get_token_data_buffer(const char* token, unsigned int n, const char* buffer, size_t buffer_size); extern char* get_token_data_buffer(const char* token, unsigned int n, const char* buffer, size_t buffer_size);

View file

@ -30,7 +30,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 206, 316 IDD_DIALOG DIALOGEX 12, 12, 206, 316
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW EXSTYLE WS_EX_APPWINDOW
CAPTION "Rufus v1.2.1.202" CAPTION "Rufus v1.2.1.203"
FONT 8, "MS Shell Dlg", 400, 0, 0x1 FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN BEGIN
DEFPUSHBUTTON "Start",IDC_START,94,278,50,14 DEFPUSHBUTTON "Start",IDC_START,94,278,50,14
@ -138,14 +138,23 @@ BEGIN
GROUPBOX "Settings",IDC_STATIC,46,145,173,45 GROUPBOX "Settings",IDC_STATIC,46,145,173,45
END END
IDD_NEW_VERSION DIALOGEX 0, 0, 287, 198 IDD_NEW_VERSION DIALOGEX 0, 0, 384, 268
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "New version available" CAPTION "Check For Updates - Rufus"
FONT 8, "Microsoft Sans Serif", 400, 0, 0x0 FONT 8, "Microsoft Sans Serif", 400, 0, 0x0
BEGIN BEGIN
PUSHBUTTON "Close",IDCANCEL,229,177,50,14,WS_GROUP PUSHBUTTON "Close",IDCANCEL,167,244,50,14,WS_GROUP
CONTROL "",IDC_RELEASE_NOTES,"RichEdit20W",ES_MULTILINE | ES_READONLY | WS_VSCROLL,4,4,279,167,WS_EX_STATICEDGE CONTROL "",IDC_RELEASE_NOTES,"RichEdit20W",ES_MULTILINE | ES_READONLY | WS_VSCROLL,15,77,352,88,WS_EX_STATICEDGE
DEFPUSHBUTTON "Download",IDC_DOWNLOAD,173,177,50,14,WS_GROUP DEFPUSHBUTTON "Download",IDC_DOWNLOAD,293,211,74,14,WS_GROUP
CONTROL "",IDC_UPDATE_PROGRESS,"msctls_progress32",WS_BORDER,15,212,270,11
GROUPBOX "Release Notes",IDC_STATIC,8,63,367,111
LTEXT "A newer version is available. Please download the latest version!",IDC_STATIC,10,32,229,8
LTEXT "[...]",IDC_YOUR_VERSION,10,8,124,8
LTEXT "[...]",IDC_LATEST_VERSION,10,19,129,8
CONTROL "<a href=""http://rufus.akeo.ie"">Click here to go to the website</a>",IDC_WEBSITE,
"SysLink",WS_TABSTOP,143,49,96,9
GROUPBOX "Download",IDC_STATIC,8,177,367,58
EDITTEXT IDC_DOWNLOAD_URL,15,191,351,13,ES_AUTOHSCROLL | ES_READONLY
END END
@ -263,8 +272,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,2,1,202 FILEVERSION 1,2,1,203
PRODUCTVERSION 1,2,1,202 PRODUCTVERSION 1,2,1,203
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -281,13 +290,13 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)"
VALUE "FileDescription", "Rufus" VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "1.2.1.202" VALUE "FileVersion", "1.2.1.203"
VALUE "InternalName", "Rufus" VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "(c) 2011-2012 Pete Batard (GPL v3)" VALUE "LegalCopyright", "(c) 2011-2012 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html"
VALUE "OriginalFilename", "rufus.exe" VALUE "OriginalFilename", "rufus.exe"
VALUE "ProductName", "Rufus" VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "1.2.1.202" VALUE "ProductVersion", "1.2.1.203"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View file

@ -662,6 +662,7 @@ INT_PTR CALLBACK AboutCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lP
switch (message) { switch (message) {
case WM_INITDIALOG: case WM_INITDIALOG:
SetTitleBarIcon(hDlg);
CenterDialog(hDlg); CenterDialog(hDlg);
if (reg_commcheck) if (reg_commcheck)
ShowWindow(GetDlgItem(hDlg, IDC_ABOUT_UPDATES), SW_SHOW); ShowWindow(GetDlgItem(hDlg, IDC_ABOUT_UPDATES), SW_SHOW);
@ -733,6 +734,7 @@ INT_PTR CALLBACK NotificationCallback(HWND hDlg, UINT message, WPARAM wParam, LP
case WM_INITDIALOG: case WM_INITDIALOG:
white_brush = CreateSolidBrush(WHITE); white_brush = CreateSolidBrush(WHITE);
separator_brush = CreateSolidBrush(SEPARATOR_GREY); separator_brush = CreateSolidBrush(SEPARATOR_GREY);
SetTitleBarIcon(hDlg);
CenterDialog(hDlg); CenterDialog(hDlg);
// Change the default icon // Change the default icon
if (Static_SetIcon(GetDlgItem(hDlg, IDC_NOTIFICATION_ICON), hMessageIcon) == 0) { if (Static_SetIcon(GetDlgItem(hDlg, IDC_NOTIFICATION_ICON), hMessageIcon) == 0) {
@ -1118,6 +1120,7 @@ INT_PTR CALLBACK UpdateCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM l
switch (message) { switch (message) {
case WM_INITDIALOG: case WM_INITDIALOG:
SetTitleBarIcon(hDlg);
CenterDialog(hDlg); CenterDialog(hDlg);
hFrequency = GetDlgItem(hDlg, IDC_UPDATE_FREQUENCY); hFrequency = GetDlgItem(hDlg, IDC_UPDATE_FREQUENCY);
IGNORE_RETVAL(ComboBox_SetItemData(hFrequency, ComboBox_AddStringU(hFrequency, "Disabled"), -1)); IGNORE_RETVAL(ComboBox_SetItemData(hFrequency, ComboBox_AddStringU(hFrequency, "Disabled"), -1));
@ -1194,8 +1197,6 @@ BOOL SetUpdateCheck(void)
/* /*
* New version notification dialog * New version notification dialog
*/ */
static const char* release_notes;
static const char* download_url;
INT_PTR CALLBACK NewVersionCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) INT_PTR CALLBACK NewVersionCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{ {
int i; int i;
@ -1203,19 +1204,36 @@ INT_PTR CALLBACK NewVersionCallback(HWND hDlg, UINT message, WPARAM wParam, LPAR
TEXTRANGEW tr; TEXTRANGEW tr;
ENLINK* enl; ENLINK* enl;
wchar_t wUrl[256]; wchar_t wUrl[256];
char tmp[128];
char* filepath; char* filepath;
static BOOL was_downloaded = FALSE;
switch (message) { switch (message) {
case WM_INITDIALOG: case WM_INITDIALOG:
SetTitleBarIcon(hDlg);
CenterDialog(hDlg); CenterDialog(hDlg);
hNotes = GetDlgItem(hDlg, IDC_RELEASE_NOTES); hNotes = GetDlgItem(hDlg, IDC_RELEASE_NOTES);
SendMessage(hNotes, EM_AUTOURLDETECT, 1, 0); SendMessage(hNotes, EM_AUTOURLDETECT, 1, 0);
SendMessageA(hNotes, EM_SETTEXTEX, (WPARAM)&friggin_microsoft_unicode_amateurs, (LPARAM)release_notes); SendMessageA(hNotes, EM_SETTEXTEX, (WPARAM)&friggin_microsoft_unicode_amateurs, (LPARAM)update.release_notes);
SendMessage(hNotes, EM_SETSEL, -1, -1); SendMessage(hNotes, EM_SETSEL, -1, -1);
SendMessage(hNotes, EM_SETEVENTMASK, 0, ENM_LINK); SendMessage(hNotes, EM_SETEVENTMASK, 0, ENM_LINK);
safe_sprintf(tmp, sizeof(tmp), "Your version: %d.%d.%d (Build %d)",
rufus_version[0], rufus_version[1], rufus_version[2], rufus_version[3]);
SetWindowTextA(GetDlgItem(hDlg, IDC_YOUR_VERSION), tmp);
safe_sprintf(tmp, sizeof(tmp), "Latest version: %d.%d.%d (Build %d)",
update.version[0], update.version[1], update.version[2], update.version[3]);
SetWindowTextA(GetDlgItem(hDlg, IDC_LATEST_VERSION), tmp);
SetWindowTextA(GetDlgItem(hDlg, IDC_DOWNLOAD_URL), update.download_url);
SendMessage(GetDlgItem(hDlg, IDC_UPDATE_PROGRESS), PBM_SETRANGE, 0, MAX_PROGRESS<<16);
break; break;
case WM_NOTIFY: case WM_NOTIFY:
switch (((LPNMHDR)lParam)->code) { switch (((LPNMHDR)lParam)->code) {
case NM_CLICK:
case NM_RETURN:
if (LOWORD(wParam) == IDC_WEBSITE) {
ShellExecuteA(hDlg, "open", RUFUS_URL, NULL, NULL, SW_SHOWNORMAL);
}
break;
case EN_LINK: case EN_LINK:
enl = (ENLINK*) lParam; enl = (ENLINK*) lParam;
if (enl->msg == WM_LBUTTONUP) { if (enl->msg == WM_LBUTTONUP) {
@ -1235,15 +1253,16 @@ INT_PTR CALLBACK NewVersionCallback(HWND hDlg, UINT message, WPARAM wParam, LPAR
EndDialog(hDlg, LOWORD(wParam)); EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE; return (INT_PTR)TRUE;
case IDC_DOWNLOAD: case IDC_DOWNLOAD:
if (download_url == NULL) if (update.download_url == NULL)
return (INT_PTR)TRUE; return (INT_PTR)TRUE;
for (i=(int)safe_strlen(download_url); (i>0)&&(download_url[i]!='/'); i--); for (i=(int)safe_strlen(update.download_url); (i>0)&&(update.download_url[i]!='/'); i--);
filepath = FileDialog(TRUE, app_dir, (char*)&download_url[i+1], "exe", "Application"); filepath = FileDialog(TRUE, app_dir, (char*)&update.download_url[i+1], "exe", "Application");
if (filepath != NULL) { if (filepath != NULL) {
// TODO: Do we want to close the release notes once download starts? if (DownloadFile(update.download_url, filepath, NULL, GetDlgItem(hDlg, IDC_UPDATE_PROGRESS))) {
// EndDialog(hDlg, 0); // TODO: create a thread and allow aborts + invoke a launcher when successful
// SetFocus(hMainDialog); SetWindowTextA(GetDlgItem(hDlg, IDC_DOWNLOAD), "Done");
DownloadFile(download_url, filepath); EnableWindow(GetDlgItem(hDlg, IDC_DOWNLOAD), FALSE);
}
safe_free(filepath); safe_free(filepath);
} }
return (INT_PTR)TRUE; return (INT_PTR)TRUE;
@ -1253,9 +1272,45 @@ INT_PTR CALLBACK NewVersionCallback(HWND hDlg, UINT message, WPARAM wParam, LPAR
return (INT_PTR)FALSE; return (INT_PTR)FALSE;
} }
INT_PTR NewVersionDialog(const char* notes, const char* url) void DownloadNewVersion(void)
{ {
release_notes = notes; DialogBoxA(hMainInstance, MAKEINTRESOURCEA(IDD_NEW_VERSION), hMainDialog, NewVersionCallback);
download_url = url; }
return DialogBoxA(hMainInstance, MAKEINTRESOURCEA(IDD_NEW_VERSION), hMainDialog, NewVersionCallback);
void SetTitleBarIcon(HWND hDlg)
{
HDC hDC;
int i16, s16, s32;
HICON hSmallIcon, hBigIcon;
// High DPI scaling
i16 = GetSystemMetrics(SM_CXSMICON);
hDC = GetDC(hDlg);
fScale = GetDeviceCaps(hDC, LOGPIXELSX) / 96.0f;
ReleaseDC(hDlg, hDC);
// Adjust icon size lookup
s16 = i16;
s32 = (int)(32.0f*fScale);
if (s16 >= 54)
s16 = 64;
else if (s16 >= 40)
s16 = 48;
else if (s16 >= 28)
s16 = 32;
else if (s16 >= 20)
s16 = 24;
if (s32 >= 54)
s32 = 64;
else if (s32 >= 40)
s32 = 48;
else if (s32 >= 28)
s32 = 32;
else if (s32 >= 20)
s32 = 24;
// Create the title bar icon
hSmallIcon = (HICON)LoadImage(hMainInstance, MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON, s16, s16, 0);
SendMessage (hDlg, WM_SETICON, ICON_SMALL, (LPARAM)hSmallIcon);
hBigIcon = (HICON)LoadImage(hMainInstance, MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON, s32, s32, 0);
SendMessage (hDlg, WM_SETICON, ICON_BIG, (LPARAM)hBigIcon);
} }