From 949ad746ab7b9312e7455e98294a2bd9916af259 Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Sat, 29 Jun 2013 18:45:09 +0100 Subject: [PATCH] [localization] fix dialog titles and hyperlinks * Dialogs must be created as Unicode (W) for titles to be updated * Also add more Chinese translation and autogenerated control codes --- src/.msvc/rufus.loc | 23 ++++++-- src/localization.c | 6 +-- src/localization.h | 3 +- src/localization_data.h | 11 +++- src/localization_data.sh | 13 ++++- src/net.c | 2 +- src/parser.c | 4 +- src/rufus.c | 10 ++-- src/rufus.rc | 7 ++- src/stdlg.c | 112 ++++++++++++++++++++++++++------------- 10 files changed, 131 insertions(+), 60 deletions(-) diff --git a/src/.msvc/rufus.loc b/src/.msvc/rufus.loc index fbb27d8b..c05cef8a 100644 --- a/src/.msvc/rufus.loc +++ b/src/.msvc/rufus.loc @@ -59,16 +59,30 @@ t IDC_ADVANCED_GROUP "高级选项" t IDC_ENABLE_FIXED_DISKS "列表固定(非flash)或USB磁盘分区" t IDC_EXTRA_PARTITION "添加修复旧的BIOS(额外的分区,校准等等)" t IDC_RUFUS_MBR "使用 Rufus MBR BIOS ID:" -# TODO: dialog title t IDD_DIALOG "Does this work?" p IDD_ABOUTBOX +t IDD_ABOUTBOX "关于 Rufus" t IDC_ABOUT_LICENSE "许可证" t IDC_ABOUT_UPDATES "更新" t IDOK "确定" -t IDD_ABOUTBOX "关于" + +p IDD_ISO_EXTRACT +t IDD_ISO_EXTRACT "复制ISO文件..." +t IDC_ISO_FILENAME "打开ISO映像 - 请稍候..." +t IDC_ISO_ABORT "取消" + +p IDD_LICENSE +t IDD_LICENSE "Rufus 许可证" +t IDOK "取消" + +p IDD_NOTIFICATION +t IDC_MORE_INFO "更多信息" +t IDYES "是" +t IDNO "否" p IDD_LOG +t IDD_LOG "日志" t IDC_LOG_CLEAR "清除日志" t IDC_LOG_SAVE "保存日志" t IDCANCEL "关闭日志" @@ -77,6 +91,7 @@ p IDD_LICENSE t IDOK "取消" p IDD_UPDATE_POLICY +t IDD_UPDATE_POLICY "更新方案和设置" t IDS_UPDATE_SETTINGS_TXT "设置" t IDS_UPDATE_FREQUENCY_TXT "检查更新:" t IDS_INCLUDE_BETAS_TXT "包括测试版本:" @@ -84,8 +99,10 @@ t IDC_CHECK_NOW "立即检查" t IDCANCEL "取消" p IDD_NEW_VERSION +t IDD_NEW_VERSION "检查更新 - Rufus" t IDS_NEW_VERSION_AVAIL_TXT "更新的版本可用。请下载最新版本!" -t IDC_WEBSITE "点击这里进入网站" +t IDC_WEBSITE "点击这里进入网站" t IDS_NEW_VERSION_NOTES_TXT "发行说明" t IDS_NEW_VERSION_DOWNLOAD_TXT "下载" t IDC_DOWNLOAD "下载" +t IDCANCEL "取消" diff --git a/src/localization.c b/src/localization.c index dbdb3d56..77b32965 100644 --- a/src/localization.c +++ b/src/localization.c @@ -36,7 +36,8 @@ #include "localization_data.h" /* c control ID (no space, no quotes), s: quoted string, i: 32 bit signed integer, */ -loc_parse parse_cmd[] = { +// Remember to update the size of the array in localization.h when adding/removing elements +const loc_parse parse_cmd[8] = { { 'l', LC_LOCALE, "s" }, { 'v', LC_VERSION, "ii" }, { 't', LC_TEXT, "cs" }, @@ -46,7 +47,6 @@ loc_parse parse_cmd[] = { { 'f', LC_FONT, "si" }, { 'd', LC_DIRECTION, "i" }, }; -const size_t PARSE_CMD_SIZE = ARRAYSIZE(parse_cmd); int loc_line_nr = 0; char loc_filename[32]; @@ -123,7 +123,7 @@ void apply_localization(int dlg_id, HWND hDlg) if (lcmd->command <= LC_TEXT) { // TODO: should always be the case if (lcmd->ctrl_id == dlg_id) { if (dlg_id == IDD_DIALOG) { - luprint("changing the title of the main dialog is not allowed"); + luprint("operation forbidden (main dialog title cannot be changed)"); continue; } hCtrl = hDlg; diff --git a/src/localization.h b/src/localization.h index 16681aa9..45e5cd9f 100644 --- a/src/localization.h +++ b/src/localization.h @@ -150,8 +150,7 @@ typedef struct loc_dlg_list_struct { struct list_head list; } loc_dlg_list; -loc_parse parse_cmd[]; -const size_t PARSE_CMD_SIZE; +extern const loc_parse parse_cmd[8]; int loc_line_nr; char loc_filename[32]; diff --git a/src/localization_data.h b/src/localization_data.h index 0998f576..4733ece9 100644 --- a/src/localization_data.h +++ b/src/localization_data.h @@ -97,7 +97,16 @@ const loc_control_id control_id[] = { LOC_CTRL(IDS_NEW_VERSION_DOWNLOAD_TXT), LOC_CTRL(IDS_NEW_VERSION_NOTES_TXT), LOC_CTRL(IDOK), - LOC_CTRL(IDCANCEL) + LOC_CTRL(IDCANCEL), + LOC_CTRL(IDABORT), + LOC_CTRL(IDRETRY), + LOC_CTRL(IDIGNORE), + LOC_CTRL(IDYES), + LOC_CTRL(IDNO), + LOC_CTRL(IDCLOSE), + LOC_CTRL(IDHELP), + LOC_CTRL(IDTRYAGAIN), + LOC_CTRL(IDCONTINUE) }; // Dialog data diff --git a/src/localization_data.sh b/src/localization_data.sh index 3158b019..7abb77ba 100644 --- a/src/localization_data.sh +++ b/src/localization_data.sh @@ -42,10 +42,19 @@ const loc_control_id control_id[] = {\ # Add the control entries - must be in IDD_, IDC_ or IDS_ s/^#define \(ID[D|C|S][^ ]*\) .*/\ LOC_CTRL(\1),/ -# Add IDs that aren't present in resource.h and close table +# Add standard IDs from windows.h and close table $a\ LOC_CTRL(IDOK),\ - LOC_CTRL(IDCANCEL)\ + LOC_CTRL(IDCANCEL),\ + LOC_CTRL(IDABORT),\ + LOC_CTRL(IDRETRY),\ + LOC_CTRL(IDIGNORE),\ + LOC_CTRL(IDYES),\ + LOC_CTRL(IDNO),\ + LOC_CTRL(IDCLOSE),\ + LOC_CTRL(IDHELP),\ + LOC_CTRL(IDTRYAGAIN),\ + LOC_CTRL(IDCONTINUE)\ \};\ # Remove everything else diff --git a/src/net.c b/src/net.c index 15f10f25..9b72dc48 100644 --- a/src/net.c +++ b/src/net.c @@ -364,7 +364,7 @@ out: _unlink(file); PrintStatus(0, FALSE, "Failed to download file."); SetLastError(error_code); - MessageBoxA(hMainDialog, IS_ERROR(FormatStatus)?StrError(FormatStatus):WinInetErrorString(), + MessageBoxU(hMainDialog, IS_ERROR(FormatStatus)?StrError(FormatStatus):WinInetErrorString(), "File download", MB_OK|MB_ICONERROR); } if (hRequest) InternetCloseHandle(hRequest); diff --git a/src/parser.c b/src/parser.c index 72619957..16c188ab 100644 --- a/src/parser.c +++ b/src/parser.c @@ -45,11 +45,11 @@ static loc_cmd* get_loc_cmd(wchar_t wc, wchar_t* wline) { wchar_t *endptr, *expected_endptr; loc_cmd* lcmd = NULL; - for (j=0; j= PARSE_CMD_SIZE) { + if (j >= ARRAYSIZE(parse_cmd)) { luprint("unknown command"); return NULL; } diff --git a/src/rufus.c b/src/rufus.c index 503c71e9..a425be8e 100644 --- a/src/rufus.c +++ b/src/rufus.c @@ -857,7 +857,7 @@ static void EnableControls(BOOL bEnable) EnableWindow(GetDlgItem(hMainDialog, IDC_SET_ICON), bEnable); EnableWindow(GetDlgItem(hMainDialog, IDC_ADVANCED), bEnable); EnableWindow(GetDlgItem(hMainDialog, IDC_ENABLE_FIXED_DISKS), bEnable); - SetDlgItemTextA(hMainDialog, IDCANCEL, bEnable?"Close":"Cancel"); + SetDlgItemTextU(hMainDialog, IDCANCEL, bEnable?"Close":"Cancel"); } /* Callback for the log window */ @@ -974,6 +974,7 @@ BOOL CALLBACK ISOProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: + apply_localization(IDD_ISO_EXTRACT, hDlg); hISOProgressBar = GetDlgItem(hDlg, IDC_PROGRESS); hISOFileName = GetDlgItem(hDlg, IDC_ISO_FILENAME); // Use maximum granularity for the progress bar @@ -1484,7 +1485,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA apply_localization(IDD_DIALOG, hDlg); SetUpdateCheck(); // Create the log window (hidden) - hLogDlg = CreateDialogA(hMainInstance, MAKEINTRESOURCEA(IDD_LOG), hDlg, (DLGPROC)LogProc); + hLogDlg = CreateDialogW(hMainInstance, MAKEINTRESOURCEW(IDD_LOG), hDlg, (DLGPROC)LogProc); InitDialog(hDlg); GetUSBDevices(0); CheckForUpdates(FALSE); @@ -1801,7 +1802,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA // You'd think that Windows would let you instantiate a modeless dialog wherever // but you'd be wrong. It must be done in the main callback, hence the custom message. if (!IsWindow(hISOProgressDlg)) { - hISOProgressDlg = CreateDialogA(hMainInstance, MAKEINTRESOURCEA(IDD_ISO_EXTRACT), + hISOProgressDlg = CreateDialogW(hMainInstance, MAKEINTRESOURCEW(IDD_ISO_EXTRACT), hDlg, (DLGPROC)ISOProc); // The window is not visible by default but takes focus => restore it SetFocus(hDlg); @@ -1813,6 +1814,7 @@ static INT_PTR CALLBACK MainCallback(HWND hDlg, UINT message, WPARAM wParam, LPA // Stop the timer KillTimer(hMainDialog, TID_APP_TIMER); // Close the cancel MessageBox and Blocking notification if active + // TODO: if we allow localization to change the title of these Windows, we'll have to update this SendMessage(FindWindowA(MAKEINTRESOURCEA(32770), RUFUS_CANCELBOX_TITLE), WM_COMMAND, IDNO, 0); SendMessage(FindWindowA(MAKEINTRESOURCEA(32770), RUFUS_BLOCKING_IO_TITLE), WM_COMMAND, IDYES, 0); EnableWindow(GetDlgItem(hISOProgressDlg, IDC_ISO_ABORT), TRUE); @@ -2004,7 +2006,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine SetLGP(FALSE, &existing_key, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", "NoDriveTypeAutorun", 0x9e); // Create the main Window - hDlg = CreateDialogA(hInstance, MAKEINTRESOURCEA(IDD_DIALOG), NULL, MainCallback); + hDlg = CreateDialogW(hInstance, MAKEINTRESOURCEW(IDD_DIALOG), NULL, MainCallback); if (hDlg == NULL) { MessageBoxU(NULL, "Could not create Window", "DialogBox failure", MB_ICONSTOP); goto out; diff --git a/src/rufus.rc b/src/rufus.rc index ee508b8c..22487f27 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -152,12 +152,11 @@ BEGIN DEFPUSHBUTTON "Download",IDC_DOWNLOAD,293,211,74,14,WS_GROUP CONTROL "",IDC_PROGRESS,"msctls_progress32",WS_BORDER,15,212,270,11 GROUPBOX "Release Notes",IDS_NEW_VERSION_NOTES_TXT,8,63,367,111 - LTEXT "A newer version is available. Please download the latest version!",IDC_STATIC,10,32,229,8 + LTEXT "A newer version is available. Please download the latest version!",IDS_NEW_VERSION_AVAIL_TXT,10,32,229,8 LTEXT "[...]",IDC_YOUR_VERSION,10,8,124,8 LTEXT "[...]",IDC_LATEST_VERSION,10,19,129,8 - CONTROL "Click here to go to the website",IDC_WEBSITE, - "SysLink",WS_TABSTOP,143,49,96,9 - GROUPBOX "Download",IDC_STATIC,8,177,367,58 + LTEXT " Click here to go to the website",IDC_WEBSITE,138,49,108,9,SS_NOTIFY + GROUPBOX "Download",IDS_NEW_VERSION_DOWNLOAD_TXT,8,177,367,58 EDITTEXT IDC_DOWNLOAD_URL,15,191,351,13,ES_AUTOHSCROLL | ES_READONLY END diff --git a/src/stdlg.c b/src/stdlg.c index af714ea5..524e35ac 100644 --- a/src/stdlg.c +++ b/src/stdlg.c @@ -67,6 +67,7 @@ static const SETTEXTEX friggin_microsoft_unicode_amateurs = {ST_DEFAULT, CP_UTF8 static BOOL notification_is_question; static const notification_info* notification_more_info; static BOOL reg_commcheck = FALSE; +static WNDPROC original_wndproc = NULL; /* * We need a sub-callback to read the content of the edit box on exit and update @@ -538,10 +539,10 @@ INT_PTR CALLBACK AboutCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lP EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; case IDC_ABOUT_LICENSE: - DialogBoxA(hMainInstance, MAKEINTRESOURCEA(IDD_LICENSE), hDlg, LicenseCallback); + DialogBoxW(hMainInstance, MAKEINTRESOURCEW(IDD_LICENSE), hDlg, LicenseCallback); break; case IDC_ABOUT_UPDATES: - DialogBoxA(hMainInstance, MAKEINTRESOURCEA(IDD_UPDATE_POLICY), hDlg, UpdateCallback); + DialogBoxW(hMainInstance, MAKEINTRESOURCEW(IDD_UPDATE_POLICY), hDlg, UpdateCallback); break; } break; @@ -553,7 +554,7 @@ INT_PTR CreateAboutBox(void) { INT_PTR r; dialog_showing++; - r = DialogBoxA(hMainInstance, MAKEINTRESOURCEA(IDD_ABOUTBOX), hMainDialog, AboutCallback); + r = DialogBoxW(hMainInstance, MAKEINTRESOURCEW(IDD_ABOUTBOX), hMainDialog, AboutCallback); dialog_showing--; return r; } @@ -582,11 +583,11 @@ INT_PTR CALLBACK NotificationCallback(HWND hDlg, UINT message, WPARAM wParam, LP } // Set the dialog title if (szMessageTitle != NULL) { - SetWindowTextA(hDlg, szMessageTitle); + SetWindowTextU(hDlg, szMessageTitle); } // Enable/disable the buttons and set text if (!notification_is_question) { - SetWindowTextA(GetDlgItem(hDlg, IDNO), "Close"); + SetWindowTextU(GetDlgItem(hDlg, IDNO), "Close"); } else { ShowWindow(GetDlgItem(hDlg, IDYES), SW_SHOW); } @@ -595,7 +596,7 @@ INT_PTR CALLBACK NotificationCallback(HWND hDlg, UINT message, WPARAM wParam, LP } // Set the control text if (szMessageText != NULL) { - SetWindowTextA(GetDlgItem(hDlg, IDC_NOTIFICATION_TEXT), szMessageText); + SetWindowTextU(GetDlgItem(hDlg, IDC_NOTIFICATION_TEXT), szMessageText); } return (INT_PTR)TRUE; case WM_CTLCOLORSTATIC: @@ -624,7 +625,7 @@ INT_PTR CALLBACK NotificationCallback(HWND hDlg, UINT message, WPARAM wParam, LP return (INT_PTR)TRUE; case IDC_MORE_INFO: if (notification_more_info != NULL) - DialogBoxA(hMainInstance, MAKEINTRESOURCEA(notification_more_info->id), + DialogBoxW(hMainInstance, MAKEINTRESOURCEW(notification_more_info->id), hDlg, notification_more_info->callback); break; } @@ -1078,6 +1079,48 @@ BOOL SetUpdateCheck(void) return TRUE; } +static void CreateStaticFont(HDC dc, HFONT* hyperlink_font) { + TEXTMETRIC tm; + LOGFONT lf; + + if (*hyperlink_font != NULL) + return; + GetTextMetrics(dc, &tm); + lf.lfHeight = tm.tmHeight; + lf.lfWidth = 0; + lf.lfEscapement = 0; + lf.lfOrientation = 0; + lf.lfWeight = tm.tmWeight; + lf.lfItalic = tm.tmItalic; + lf.lfUnderline = TRUE; + lf.lfStrikeOut = tm.tmStruckOut; + lf.lfCharSet = tm.tmCharSet; + lf.lfOutPrecision = OUT_DEFAULT_PRECIS; + lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; + lf.lfQuality = DEFAULT_QUALITY; + lf.lfPitchAndFamily = tm.tmPitchAndFamily; + GetTextFace(dc, LF_FACESIZE, lf.lfFaceName); + *hyperlink_font = CreateFontIndirect(&lf); +} + +/* + * Work around the limitations of edit control, to display a hand cursor for hyperlinks + * NB: The LTEXT control must have SS_NOTIFY attribute for this to work + */ +INT_PTR CALLBACK subclass_callback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_SETCURSOR: + if ((HWND)wParam == GetDlgItem(hDlg, IDC_WEBSITE)) { + SetCursor(LoadCursor(NULL, IDC_HAND)); + return (INT_PTR)TRUE; + } + break; + } + return CallWindowProc(original_wndproc, hDlg, message, wParam, lParam); +} + /* * New version notification dialog */ @@ -1085,20 +1128,21 @@ INT_PTR CALLBACK NewVersionCallback(HWND hDlg, UINT message, WPARAM wParam, LPAR { int i; HWND hNotes; - TEXTRANGEW tr; - ENLINK* enl; - wchar_t wUrl[256]; char tmp[128]; static char* filepath = NULL; static int download_status = 0; STARTUPINFOA si; PROCESS_INFORMATION pi; + HFONT hyperlink_font = NULL; switch (message) { case WM_INITDIALOG: + apply_localization(IDD_NEW_VERSION, hDlg); download_status = 0; SetTitleBarIcon(hDlg); CenterDialog(hDlg); + // Subclass the callback so that we can change the cursor + original_wndproc = (WNDPROC)SetWindowLongPtr(hDlg, GWLP_WNDPROC, (LONG_PTR)subclass_callback); hNotes = GetDlgItem(hDlg, IDC_RELEASE_NOTES); SendMessage(hNotes, EM_AUTOURLDETECT, 1, 0); SendMessageA(hNotes, EM_SETTEXTEX, (WPARAM)&friggin_microsoft_unicode_amateurs, (LPARAM)update.release_notes); @@ -1106,43 +1150,35 @@ INT_PTR CALLBACK NewVersionCallback(HWND hDlg, UINT message, WPARAM wParam, LPAR 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); + SetWindowTextU(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); + SetWindowTextU(GetDlgItem(hDlg, IDC_LATEST_VERSION), tmp); + SetWindowTextU(GetDlgItem(hDlg, IDC_DOWNLOAD_URL), update.download_url); SendMessage(GetDlgItem(hDlg, IDC_PROGRESS), PBM_SETRANGE, 0, (MAX_PROGRESS<<16) & 0xFFFF0000); if (update.download_url == NULL) EnableWindow(GetDlgItem(hDlg, IDC_DOWNLOAD), FALSE); break; - case WM_NOTIFY: - 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: - enl = (ENLINK*) lParam; - if (enl->msg == WM_LBUTTONUP) { - tr.lpstrText = wUrl; - tr.chrg.cpMin = enl->chrg.cpMin; - tr.chrg.cpMax = enl->chrg.cpMax; - SendMessageW(enl->nmhdr.hwndFrom, EM_GETTEXTRANGE, 0, (LPARAM)&tr); - wUrl[ARRAYSIZE(wUrl)-1] = 0; - ShellExecuteW(hDlg, L"open", wUrl, NULL, NULL, SW_SHOWNORMAL); - } - break; - } - break; + case WM_CTLCOLORSTATIC: + if ((HWND)lParam != GetDlgItem(hDlg, IDC_WEBSITE)) + return FALSE; + // Change the font for the hyperlink + SetBkMode((HDC)wParam, TRANSPARENT); + CreateStaticFont((HDC)wParam, &hyperlink_font); + SelectObject((HDC)wParam, hyperlink_font); + SetTextColor((HDC)wParam, RGB(0,0,125)); // DARK_BLUE + return (INT_PTR)CreateSolidBrush(GetSysColor(COLOR_BTNFACE)); case WM_COMMAND: switch (LOWORD(wParam)) { case IDCLOSE: case IDCANCEL: + reset_localization(IDD_NEW_VERSION); safe_free(filepath); EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; + case IDC_WEBSITE: + ShellExecuteA(hDlg, "open", RUFUS_URL, NULL, NULL, SW_SHOWNORMAL); + break; case IDC_DOWNLOAD: // Also doubles as abort and launch function switch(download_status) { case 1: // Abort @@ -1178,14 +1214,14 @@ INT_PTR CALLBACK NewVersionCallback(HWND hDlg, UINT message, WPARAM wParam, LPAR case UM_ISO_INIT: FormatStatus = 0; download_status = 1; - SetWindowTextA(GetDlgItem(hDlg, IDC_DOWNLOAD), "Abort"); + SetWindowTextU(GetDlgItem(hDlg, IDC_DOWNLOAD), "Abort"); return (INT_PTR)TRUE; case UM_ISO_EXIT: if (wParam) { - SetWindowTextA(GetDlgItem(hDlg, IDC_DOWNLOAD), "Launch"); + SetWindowTextU(GetDlgItem(hDlg, IDC_DOWNLOAD), "Launch"); download_status = 2; } else { - SetWindowTextA(GetDlgItem(hDlg, IDC_DOWNLOAD), "Download"); + SetWindowTextU(GetDlgItem(hDlg, IDC_DOWNLOAD), "Download"); download_status = 0; } return (INT_PTR)TRUE; @@ -1195,7 +1231,7 @@ INT_PTR CALLBACK NewVersionCallback(HWND hDlg, UINT message, WPARAM wParam, LPAR void DownloadNewVersion(void) { - DialogBoxA(hMainInstance, MAKEINTRESOURCEA(IDD_NEW_VERSION), hMainDialog, NewVersionCallback); + DialogBoxW(hMainInstance, MAKEINTRESOURCEW(IDD_NEW_VERSION), hMainDialog, NewVersionCallback); } void SetTitleBarIcon(HWND hDlg)