// 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(); for (int i = 0; i < QUALITY_COUNT; i++) { m_working[i] = m_profiles[i]; } LoadToControls(); TranslateDialog(this); 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); } };