Files
yuanyuanxianganddeepseek-v4-pro 6220335f63 Fix: Decode GBK dialog/toolbar text on non-Chinese systems
MBCS dialog templates are decoded with the system ANSI code page, so on
non-Chinese systems the GBK template strings turn into "?" before
TranslateDialog can read them. Set those strings explicitly in OnInitDialog
(PluginSettings save/close, the three Advanced dialogs, the file-manager
search buttons/checkboxes, and Trigger Settings) so they are re-decoded
with the thread locale. Also fix the language-selection dialog and the
toolbar "Lang/语言" button: the language dialog's template is built as
WCHAR strings but created through the ANSI path, so its title, label, and
buttons are set explicitly in OnInitDialog (AppendString stays on CP_ACP),
with the title looked up via _TR("切换语言") and set through SetWindowTextW
after an explicit GBK conversion; new en_US ("Switch Language") and zh_TW
("切換語言") translations accompany it. The toolbar button is set through
the Unicode TB_SETBUTTONINFOW message after an explicit GBK conversion. Add
en_US/zh_TW translations for the experimental-features context menu items.

Co-Authored-By: deepseek-v4-pro
2026-10-08 21:53:53 +02:00

177 lines
6.2 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// QualityLevelsDlg.h
// 远程桌面质量等级配置对话框:编辑 6 档 QualityProfile(帧率/宽度/算法/码率)。
// 纯主控端 UI 偏好,持久化由 CMy2015RemoteDlg::SaveQualityProfilesToCfg() 负责。
// 仅在 2015RemoteDlg.cpp 中 include 一次(头文件内联实现,勿多处包含)。
#pragma once
#include "LangManager.h"
class CQualityLevelsDlg : public CDialog
{
public:
enum { IDD = IDD_QUALITY_LEVELS };
// profiles: 指向 6 元素 QualityProfile 数组,确认后写回
CQualityLevelsDlg(QualityProfile* profiles, CWnd* pParent = NULL)
: CDialog(CQualityLevelsDlg::IDD, pParent), m_profiles(profiles)
{
}
protected:
QualityProfile* m_profiles;
QualityProfile m_working[QUALITY_COUNT];
static const char* AlgorithmName(int algo)
{
switch (algo) {
case ALGORITHM_GRAY: return "GRAY";
case ALGORITHM_DIFF: return "DIFF";
case ALGORITHM_H264: return "H264";
case ALGORITHM_RGB565: return "RGB565";
default: return "?";
}
}
static const char* LevelName(int i)
{
static const char* names[QUALITY_COUNT] = {
"Ultra", "High", "Good", "Medium", "Low", "Minimal"
};
return (i >= 0 && i < QUALITY_COUNT) ? names[i] : "?";
}
void FillAlgoCombo(int i)
{
CComboBox* cb = (CComboBox*)GetDlgItem(IDC_QLEVEL_ALGO + i);
if (!cb) return;
for (int a = 0; a < 4; a++) {
cb->AddString(CString(AlgorithmName(a)));
}
cb->SetCurSel(m_working[i].algorithm);
}
void LoadToControls()
{
CString s;
for (int i = 0; i < QUALITY_COUNT; i++) {
s.Format(_T("%d"), m_working[i].maxFPS);
SetDlgItemText(IDC_QLEVEL_FPS + i, s);
s.Format(_T("%d"), m_working[i].maxWidth);
SetDlgItemText(IDC_QLEVEL_WIDTH + i, s);
s.Format(_T("%d"), m_working[i].bitRate);
SetDlgItemText(IDC_QLEVEL_BITRATE + i, s);
FillAlgoCombo(i);
}
}
bool ReadInt(int id, int& out)
{
CString s;
GetDlgItemText(id, s);
s.Trim();
if (s.IsEmpty()) return false;
int v = 0;
for (int k = 0; k < s.GetLength(); k++) {
TCHAR ch = s[k];
if (ch < _T('0') || ch > _T('9')) return false;
v = v * 10 + (ch - _T('0'));
}
out = v;
return true;
}
bool ReadFromControls(CString& err)
{
for (int i = 0; i < QUALITY_COUNT; i++) {
int fps, w, br;
if (!ReadInt(IDC_QLEVEL_FPS + i, fps))
{ err.Format(_T("等级 %s 的帧率不是有效数字"), LevelName(i)); return false; }
if (!ReadInt(IDC_QLEVEL_WIDTH + i, w))
{ err.Format(_T("等级 %s 的最大宽度不是有效数字"), LevelName(i)); return false; }
if (!ReadInt(IDC_QLEVEL_BITRATE + i, br))
{ err.Format(_T("等级 %s 的码率不是有效数字"), LevelName(i)); return false; }
if (fps < 1 || fps > 60)
{ err.Format(_T("等级 %s 的帧率需在 1~60 之间"), LevelName(i)); return false; }
if (w < 0 || w > 8192)
{ err.Format(_T("等级 %s 的最大宽度需在 0~8192 之间(0=原始分辨率)"), LevelName(i)); return false; }
if (br < 0 || br > 50000)
{ err.Format(_T("等级 %s 的码率需在 0~50000 之间"), LevelName(i)); return false; }
CComboBox* cb = (CComboBox*)GetDlgItem(IDC_QLEVEL_ALGO + i);
int algo = cb ? cb->GetCurSel() : -1;
if (algo < 0 || algo > 3)
{ err.Format(_T("等级 %s 的编码算法未选择"), LevelName(i)); return false; }
m_working[i].maxFPS = fps;
m_working[i].maxWidth = w;
m_working[i].bitRate = br;
m_working[i].algorithm = algo;
}
return true;
}
void ResetToDefaults()
{
for (int i = 0; i < QUALITY_COUNT; i++) {
m_working[i] = GetQualityProfile(i);
}
LoadToControls();
}
virtual BOOL OnInitDialog() override
{
CDialog::OnInitDialog();
// 非中文系统上 MBCS 对话框模板的中文会被系统 ACP 转成 "?",TranslateDialog
// 拿到的是已乱码文本无法还原,故在此显式设置(参照 NotifySettingsDlg)。
// 均经 _TR/_L 支持多语言翻译。
SetWindowText(_TR("远程桌面质量等级"));
SetDlgItemText(IDC_QLEVEL_LABEL_LEVEL, _TR("等级"));
SetDlgItemText(IDC_QLEVEL_LABEL_FPS, _TR("帧率(FPS)"));
SetDlgItemText(IDC_QLEVEL_LABEL_WIDTH, _TR("最大宽度"));
SetDlgItemText(IDC_QLEVEL_LABEL_ALGO, _TR("编码算法"));
SetDlgItemText(IDC_QLEVEL_LABEL_BITRATE, _TR("码率(kbps)"));
static const TCHAR* kLevelNames[QUALITY_COUNT] = {
_T("Ultra 极佳"), _T("High 优秀"), _T("Good 良好"),
_T("Medium 一般"), _T("Low 较差"), _T("Minimal 最低")
};
for (int i = 0; i < QUALITY_COUNT; i++)
SetDlgItemText(IDC_QLEVEL_LABEL_LEVEL0 + i, _L(kLevelNames[i]));
SetDlgItemText(IDC_QLEVEL_LABEL_HINT,
_TR("最大宽度 0 表示原始分辨率;DIFF/RGB565 适合局域网,H264 适合跨网"));
SetDlgItemText(IDC_QLEVEL_RESET, _TR("恢复默认"));
SetDlgItemText(IDOK, _TR("确定"));
SetDlgItemText(IDCANCEL, _TR("取消"));
for (int i = 0; i < QUALITY_COUNT; i++) {
m_working[i] = m_profiles[i];
}
LoadToControls();
return TRUE;
}
virtual void OnOK() override
{
CString err;
if (!ReadFromControls(err)) {
MessageBox(err, _TR("提示"), MB_ICONWARNING);
return;
}
for (int i = 0; i < QUALITY_COUNT; i++) {
m_profiles[i] = m_working[i];
}
CDialog::OnOK();
}
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam) override
{
if (LOWORD(wParam) == IDC_QLEVEL_RESET && HIWORD(wParam) == BN_CLICKED) {
ResetToDefaults();
return TRUE;
}
return CDialog::OnCommand(wParam, lParam);
}
};