[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
This commit is contained in:
Pete Batard 2013-06-29 18:45:09 +01:00
parent 7636342cf3
commit 949ad746ab
10 changed files with 131 additions and 60 deletions

View File

@ -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 "<a href="http://rufus.akeo.ie">点击这里进入网站</a>"
t IDC_WEBSITE "点击这里进入网站"
t IDS_NEW_VERSION_NOTES_TXT "发行说明"
t IDS_NEW_VERSION_DOWNLOAD_TXT "下载"
t IDC_DOWNLOAD "下载"
t IDCANCEL "取消"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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; j++) {
for (j=0; j<ARRAYSIZE(parse_cmd); j++) {
if (wc == (wchar_t)parse_cmd[j].c)
break;
}
if (j >= PARSE_CMD_SIZE) {
if (j >= ARRAYSIZE(parse_cmd)) {
luprint("unknown command");
return NULL;
}

View File

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

View File

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

View File

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