diff --git a/.gitattributes b/.gitattributes index 6692bacbd..c3f1197bd 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,2 @@ MusicPlayer2/MusicPlayer2.rc text working-tree-encoding=UTF-16LE-BOM eol=CRLF - +scintilla/win32/ScintRes.rc text working-tree-encoding=UTF-16LE-BOM eol=CRLF diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index b3880bea5..7372f807c 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -7,7 +7,7 @@ jobs: runs-on: windows-latest steps: - name: Check Out - uses: actions/checkout@v3.5.3 + uses: actions/checkout@v4 # 所有版本链接:https://docs.microsoft.com/en-us/visualstudio/releases/2022/release-history #- name: 下载 vs_enterprise.exe # run: Invoke-WebRequest "https://aka.ms/vs/17/release/vs_enterprise.exe" -OutFile vs_enterprise.exe @@ -24,22 +24,25 @@ jobs: # "--add", "Microsoft.VisualStudio.Component.VC.ATLMFC", ` # "--add", "Microsoft.VisualStudio.Component.VC.14.29.16.11.MFC" - name: 设置 msbuild - uses: microsoft/setup-msbuild@v1.3.1 + uses: microsoft/setup-msbuild@v2 - name: 编译 run: msbuild -t:Build '-p:Configuration=Release;platform=x64' -m:4 + - name: 复制文件到 Release 文件夹 + run: cp -R ./MusicPlayer2/language/ ./x64/Release/ - name: 上传文件 - uses: actions/upload-artifact@v3.1.2 + uses: actions/upload-artifact@v4 with: name: MusicPlayer2.x64 path: | ./x64/Release/*.exe ./x64/Release/*.dll + ./x64/Release/language/ - name: 打包其他文件 run: | cd x64/Release 7z a -mx9 '../../MusicPlayer2.x64.other.7z' '-x!*.exe' '-x!*.dll' './*' - name: 上传其他文件 - uses: actions/upload-artifact@v3.1.2 + uses: actions/upload-artifact@v4 with: name: MusicPlayer2.x64.other path: ./MusicPlayer2.x64.other.7z @@ -47,7 +50,7 @@ jobs: runs-on: windows-latest steps: - name: Check Out - uses: actions/checkout@v3.5.3 + uses: actions/checkout@v4 # 所有版本链接:https://docs.microsoft.com/en-us/visualstudio/releases/2022/release-history #- name: 下载 vs_enterprise.exe # run: Invoke-WebRequest "https://aka.ms/vs/17/release/vs_enterprise.exe" -OutFile vs_enterprise.exe @@ -64,22 +67,25 @@ jobs: # "--add", "Microsoft.VisualStudio.Component.VC.ATLMFC", ` # "--add", "Microsoft.VisualStudio.Component.VC.14.29.16.11.MFC" - name: 设置 msbuild - uses: microsoft/setup-msbuild@v1.3.1 + uses: microsoft/setup-msbuild@v2 - name: 编译 run: msbuild -t:Build '-p:Configuration=Release;platform=x86' -m:4 + - name: 复制文件到 Release 文件夹 + run: cp -R ./MusicPlayer2/language/ ./Release/ - name: 上传文件 - uses: actions/upload-artifact@v3.1.2 + uses: actions/upload-artifact@v4 with: name: MusicPlayer2.x86 path: | ./Release/*.exe ./Release/*.dll + ./Release/language/ - name: 打包其他文件 run: | cd Release 7z a -mx9 './../MusicPlayer2.x86.other.7z' '-x!*.exe' '-x!*.dll' './*' - name: 上传其他文件 - uses: actions/upload-artifact@v3.1.2 + uses: actions/upload-artifact@v4 with: name: MusicPlayer2.x86.other path: ./MusicPlayer2.x86.other.7z diff --git a/.gitignore b/.gitignore index c4feba770..d48180074 100644 --- a/.gitignore +++ b/.gitignore @@ -291,3 +291,4 @@ __pycache__/ *.sf2 /MusicPlayer2/compile_time.txt /MusicPlayer2/skins/test.xml +!/MusicPlayer2/language/*.ini diff --git a/MusicPlayer2/AboutDlg.cpp b/MusicPlayer2/AboutDlg.cpp index 72c4e0373..5c402de80 100644 --- a/MusicPlayer2/AboutDlg.cpp +++ b/MusicPlayer2/AboutDlg.cpp @@ -3,18 +3,82 @@ #include "AboutDlg.h" #include "CDonateDlg.h" #include "MessageDlg.h" -#include "GdiPlusTool.h" -CAboutDlg::CAboutDlg() : CDialog(IDD_ABOUTBOX) +CAboutDlg::CAboutDlg() + : CBaseDialog(IDD_ABOUTBOX) { } +CAboutDlg::~CAboutDlg() +{ +} + +CString CAboutDlg::GetDialogName() const +{ + return L"AboutDlg"; +} + +bool CAboutDlg::InitializeControls() +{ + wstring temp; + temp = theApp.m_str_table.LoadText(L"TITLE_ABOUTBOX"); + SetWindowTextW(temp.c_str()); + temp = L"MusicPlayer2,V" APP_VERSION; + +#ifdef COMPILE_IN_WIN_XP + temp += L" (For WinXP)"; +#endif // COMPILE_FOR_WINXP + +#ifdef _M_X64 + temp += L" (x64)"; +#endif + +#ifdef _DEBUG + temp += L" (Debug)"; +#endif + + SetDlgItemTextW(IDC_STATIC_VERSION, temp.c_str()); + temp = L"Copyright (C) 2017-" COPY_RIGHT_YEAR L" By ZhongYang\r\n"; + temp += theApp.m_str_table.LoadTextFormat(L"TXT_ABOUTBOX_LAST_BUILD_DATE", { CCommon::GetLastCompileTime() }); + SetDlgItemTextW(IDC_STATIC_COPYRIGHT, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_ABOUTBOX_THIRD_PARTY_LIB"); + SetDlgItemTextW(IDC_STATIC_THIRD_PARTY_LIB, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_ABOUTBOX_OTHER_SOFTWARE"); + SetDlgItemTextW(IDC_STATIC_OTHER_SOFTWARE, temp.c_str()); + temp = L"" + theApp.m_str_table.LoadText(L"TXT_ABOUTBOX_CONTRACT_AUTHOR") + L""; + SetDlgItemTextW(IDC_SYSLINK1, temp.c_str()); + temp = L"" + theApp.m_str_table.LoadText(L"TXT_ABOUTBOX_CHECK_UPDATE") + L""; + SetDlgItemTextW(IDC_SYSLINK2, temp.c_str()); + temp = L"" + theApp.m_str_table.LoadText(L"TXT_ABOUTBOX_GITHUB") + L""; + SetDlgItemTextW(IDC_GITHUB_SYSLINK, temp.c_str()); + temp = L"" + theApp.m_str_table.LoadText(L"TXT_ABOUTBOX_LICENSE") + L""; + SetDlgItemTextW(IDC_LICENSE_SYSLINK, temp.c_str()); + temp = L"" + theApp.m_str_table.LoadText(L"TXT_ABOUTBOX_DONATE") + L""; + SetDlgItemTextW(IDC_DONATE_SYSLINK, temp.c_str()); + temp = L"" + theApp.m_str_table.LoadText(L"TXT_ABOUTBOX_ACKNOWLEDGEMENT") + L""; + SetDlgItemTextW(IDC_ACKNOWLEDGEMENT_SYSLINK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OK"); + SetDlgItemTextW(IDOK, temp.c_str()); + + RepositionTextBasedControls({ + { CtrlTextInfo::L2, IDC_SYSLINK1, CtrlTextInfo::W_50 }, + { CtrlTextInfo::L1, IDC_SYSLINK2, CtrlTextInfo::W_50 }, + { CtrlTextInfo::L2, IDC_GITHUB_SYSLINK, CtrlTextInfo::W_50 }, + { CtrlTextInfo::L1, IDC_LICENSE_SYSLINK, CtrlTextInfo::W_50 }, + { CtrlTextInfo::L2, IDC_DONATE_SYSLINK, CtrlTextInfo::W_50 }, + { CtrlTextInfo::L1, IDC_ACKNOWLEDGEMENT_SYSLINK, CtrlTextInfo::W_50 }, + { CtrlTextInfo::R1, IDOK, CtrlTextInfo::W32 } + }); + + return true; +} + void CAboutDlg::DoDataExchange(CDataExchange* pDX) { - CDialog::DoDataExchange(pDX); + CBaseDialog::DoDataExchange(pDX); } -BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) +BEGIN_MESSAGE_MAP(CAboutDlg, CBaseDialog) ON_NOTIFY(NM_CLICK, IDC_SYSLINK1, &CAboutDlg::OnNMClickSyslink1) ON_NOTIFY(NM_CLICK, IDC_SYSLINK2, &CAboutDlg::OnNMClickSyslink2) ON_NOTIFY(NM_CLICK, IDC_GITHUB_SYSLINK, &CAboutDlg::OnNMClickGithubSyslink) @@ -34,45 +98,21 @@ END_MESSAGE_MAP() BOOL CAboutDlg::OnInitDialog() { - CDialog::OnInitDialog(); - - // TODO: 在此添加额外的初始化 - - CString version_info; - GetDlgItemText(IDC_STATIC_VERSION, version_info); - version_info.Replace(_T(""), APP_VERSION); -#ifdef COMPILE_IN_WIN_XP - version_info += _T(" (For WinXP)"); -#endif // COMPILE_FOR_WINXP - -#ifdef _M_X64 - version_info += _T(" (x64)"); -#endif + CBaseDialog::OnInitDialog(); -#ifdef _DEBUG - version_info += _T(" (Debug)"); -#endif - - SetDlgItemText(IDC_STATIC_VERSION, version_info); - - //设置最后编译日期 - CString temp_str; - GetDlgItemText(IDC_STATIC_COPYRIGHT, temp_str); - CString compile_time = CCommon::GetLastCompileTime(); - temp_str.Replace(_T(""), compile_time); - temp_str.Replace(_T(""), COPY_RIGHT_YEAR); - SetDlgItemText(IDC_STATIC_COPYRIGHT, temp_str); + // 设置背景色为白色,为使用CBaseDialog::OnCtlColor需要此初始化 + SetBackgroundColor(GetSysColor(COLOR_WINDOW)); m_tool_tip.Create(this); - m_tool_tip.AddTool(GetDlgItem(IDC_SYSLINK1), CCommon::LoadText(IDS_SEND_EMAIL_TO_ATHOUR, _T("\r\nmailto:zhongyang219@hotmail.com"))); - m_tool_tip.AddTool(GetDlgItem(IDC_GITHUB_SYSLINK), CCommon::LoadText(IDS_GOTO_GITHUB, _T("\r\nhttps://github.com/zhongyang219/MusicPlayer2"))); - m_tool_tip.AddTool(GetDlgItem(IDC_SYSLINK_BASS), _T("http://www.un4seen.com/bass.html")); - m_tool_tip.AddTool(GetDlgItem(IDC_SYSLINK_TAGLIB), _T("http://taglib.org/")); - m_tool_tip.AddTool(GetDlgItem(IDC_SYSLINK_TINYXML2), _T("https://github.com/leethomason/tinyxml2")); - m_tool_tip.AddTool(GetDlgItem(IDC_SYSLINK_SCINTILLA), _T("https://www.scintilla.org/index.html")); - m_tool_tip.AddTool(GetDlgItem(IDC_SYSLINK_TRAFFICMONITOR), CCommon::LoadText(IDS_TRAFFICMONITOR_DESCRIPTION, _T("\r\nhttps://github.com/zhongyang219/TrafficMonitor"))); - m_tool_tip.AddTool(GetDlgItem(IDC_SYSLINK_SIMPLENOTEPAD), CCommon::LoadText(IDS_SIMPLENOTEPAD_DESCRIPTION, _T("\r\nhttps://github.com/zhongyang219/SimpleNotePad"))); - m_tool_tip.SetDelayTime(300); //设置延迟 + m_tool_tip.AddTool(GetDlgItem(IDC_SYSLINK1), (theApp.m_str_table.LoadText(L"TIP_ABOUTBOX_SEND_EMAIL_TO_ATHOUR") + L"\r\nmailto:zhongyang219@hotmail.com").c_str()); + m_tool_tip.AddTool(GetDlgItem(IDC_GITHUB_SYSLINK), (theApp.m_str_table.LoadText(L"TIP_ABOUTBOX_GOTO_GITHUB") + L"\r\nhttps://github.com/zhongyang219/MusicPlayer2").c_str()); + m_tool_tip.AddTool(GetDlgItem(IDC_SYSLINK_BASS), L"http://www.un4seen.com/bass.html"); + m_tool_tip.AddTool(GetDlgItem(IDC_SYSLINK_TAGLIB), L"http://taglib.org/"); + m_tool_tip.AddTool(GetDlgItem(IDC_SYSLINK_TINYXML2), L"https://github.com/leethomason/tinyxml2"); + m_tool_tip.AddTool(GetDlgItem(IDC_SYSLINK_SCINTILLA), L"https://www.scintilla.org/index.html"); + m_tool_tip.AddTool(GetDlgItem(IDC_SYSLINK_TRAFFICMONITOR), (theApp.m_str_table.LoadText(L"TIP_ABOUTBOX_TRAFFICMONITOR_DESCRIPTION") + L"\r\nhttps://github.com/zhongyang219/TrafficMonitor").c_str()); + m_tool_tip.AddTool(GetDlgItem(IDC_SYSLINK_SIMPLENOTEPAD), (theApp.m_str_table.LoadText(L"TIP_ABOUTBOX_SIMPLENOTEPAD_DESCRIPTION") + L"\r\nhttps://github.com/zhongyang219/SimpleNotePad").c_str()); + m_tool_tip.SetDelayTime(300); //设置延迟 m_tool_tip.SetMaxTipWidth(theApp.DPI(400)); //设置图片的位置 @@ -84,6 +124,10 @@ BOOL CAboutDlg::OnInitDialog() m_rc_pic.bottom = rect.top - theApp.DPI(6); if (m_rc_pic.Height() <= 0) m_rc_pic.bottom = m_rc_pic.top + theApp.DPI(50); + // 计算背景白色区域高度 + ::GetWindowRect(GetDlgItem(IDC_SYSLINK1)->GetSafeHwnd(), rect); + ScreenToClient(rect); + m_white_height = rect.top - theApp.DPI(6); //载入图片 m_about_pic.LoadFromResource(AfxGetResourceHandle(), IDB_DEFAULT_COVER); @@ -96,7 +140,7 @@ void CAboutDlg::OnNMClickSyslink1(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: 在此添加控件通知处理程序代码 //点击了“联系作者” - ShellExecute(NULL, _T("open"), _T("mailto:zhongyang219@hotmail.com"), NULL, NULL, SW_SHOW); //打开超链接 + ShellExecute(NULL, _T("open"), _T("mailto:zhongyang219@hotmail.com"), NULL, NULL, SW_SHOW); //打开超链接 *pResult = 0; } @@ -111,7 +155,7 @@ void CAboutDlg::OnNMClickSyslink2(NMHDR* pNMHDR, LRESULT* pResult) void CAboutDlg::OnNMClickGithubSyslink(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: 在此添加控件通知处理程序代码 - ShellExecute(NULL, _T("open"), _T("https://github.com/zhongyang219/MusicPlayer2/"), NULL, NULL, SW_SHOW); //打开超链接 + ShellExecute(NULL, _T("open"), _T("https://github.com/zhongyang219/MusicPlayer2/"), NULL, NULL, SW_SHOW); //打开超链接 *pResult = 0; } @@ -124,14 +168,14 @@ BOOL CAboutDlg::PreTranslateMessage(MSG* pMsg) //if (pMsg->message == WM_KEYDOWN) //{ - // if ((GetKeyState(VK_CONTROL) & 0x80) && (GetKeyState(VK_SHIFT) & 0x8000) && pMsg->wParam == 'Z') - // { - // CTest::Test(); - // } + // if ((GetKeyState(VK_CONTROL) & 0x80) && (GetKeyState(VK_SHIFT) & 0x8000) && pMsg->wParam == 'Z') + // { + // CTest::Test(); + // } //} - return CDialog::PreTranslateMessage(pMsg); + return CBaseDialog::PreTranslateMessage(pMsg); } @@ -150,9 +194,9 @@ void CAboutDlg::OnPaint() { CPaintDC dc(this); // device context for painting // TODO: 在此处添加消息处理程序代码 - // 不为绘图消息调用 CDialog::OnPaint() + // 不为绘图消息调用 CBaseDialog::OnPaint() CDrawCommon draw; - draw.Create(&dc, this); + draw.Create(&dc); //填充背景 draw.GetDC()->FillSolidRect(m_rc_pic, RGB(212, 230, 255)); @@ -165,9 +209,9 @@ void CAboutDlg::OnPaint() void CAboutDlg::OnNMClickLicenseSyslink(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: 在此添加控件通知处理程序代码 - CMessageDlg dlg; - dlg.SetWindowTitle(CCommon::LoadText(IDS_LICENSE)); - dlg.SetInfoText(CCommon::LoadText(IDS_LICENSE_EXPLAIN)); + CMessageDlg dlg(L"LicenseDlg"); + dlg.SetWindowTitle(theApp.m_str_table.LoadText(L"TITLE_LICENSE")); + dlg.SetInfoText(theApp.m_str_table.LoadText(L"TXT_LICENSE_EXPLAIN")); dlg.SetMessageText(CCommon::GetTextResource(IDR_LICENSE, CodeType::UTF8_NO_BOM)); dlg.DoModal(); *pResult = 0; @@ -180,59 +224,42 @@ BOOL CAboutDlg::OnEraseBkgnd(CDC* pDC) CRect draw_rect; GetClientRect(draw_rect); - pDC->FillSolidRect(draw_rect, GetSysColor(COLOR_WINDOW)); - + int client_bottom = draw_rect.bottom; //绘制白色背景 - int white_height; //白色区域的高度 - CRect rc_ok{}; - ::GetWindowRect(GetDlgItem(IDOK)->GetSafeHwnd(), rc_ok); - ScreenToClient(rc_ok); - white_height = rc_ok.top - theApp.DPI(6); + draw_rect.bottom = m_white_height; + pDC->FillSolidRect(draw_rect, GetSysColor(COLOR_WINDOW)); //绘制“确定”按钮上方的分割线 - CRect rc_line{ draw_rect }; - rc_line.top = white_height; - rc_line.bottom = white_height + theApp.DPI(1); - pDC->FillSolidRect(rc_line, RGB(210, 210, 210)); + draw_rect.top = draw_rect.bottom; + draw_rect.bottom = draw_rect.top + max(theApp.DPI(1), 1); + pDC->FillSolidRect(draw_rect, RGB(210, 210, 210)); //绘制灰色背景 - CRect rc_gray{ rc_line }; - rc_gray.top = rc_line.bottom; - rc_gray.bottom = draw_rect.bottom; - pDC->FillSolidRect(rc_gray, GetSysColor(COLOR_BTNFACE)); + draw_rect.top = draw_rect.bottom; + draw_rect.bottom = client_bottom; + pDC->FillSolidRect(draw_rect, GetSysColor(COLOR_BTNFACE)); return TRUE; - //return CDialog::OnEraseBkgnd(pDC); } HBRUSH CAboutDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { - HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); - - // TODO: 在此更改 DC 的任何特性 - UINT ctrl_id = pWnd->GetDlgCtrlID(); - if (ctrl_id == IDC_STATIC_VERSION || ctrl_id == IDC_STATIC_COPYRIGHT || ctrl_id == IDC_STATIC - || ctrl_id == IDC_SYSLINK_BASS || ctrl_id == IDC_SYSLINK_TAGLIB || ctrl_id == IDC_SYSLINK_TINYXML2 || ctrl_id == IDC_SYSLINK_SCINTILLA - || ctrl_id == IDC_SYSLINK_TRAFFICMONITOR || ctrl_id == IDC_SYSLINK_SIMPLENOTEPAD) - { - static HBRUSH hBackBrush{}; - if (hBackBrush == NULL) - hBackBrush = CreateSolidBrush(GetSysColor(COLOR_WINDOW)); - pDC->SetBkColor(GetSysColor(COLOR_WINDOW)); - return hBackBrush; - } - - - // TODO: 如果默认的不是所需画笔,则返回另一个画笔 - return hbr; + CRect rect; + ::GetWindowRect(pWnd->GetSafeHwnd(), rect); + ScreenToClient(rect); + // 如果控件在白色区域那么使用CBaseDialog的方法修改控件背景色,灰色区域使用原版CDialog的方法 + if (rect.top < m_white_height) + return CBaseDialog::OnCtlColor(pDC, pWnd, nCtlColor); + else + return CDialog::OnCtlColor(pDC, pWnd, nCtlColor); } void CAboutDlg::OnNMClickSyslinkBass(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: 在此添加控件通知处理程序代码 - ShellExecute(NULL, _T("open"), _T("http://www.un4seen.com/bass.html"), NULL, NULL, SW_SHOW); //打开超链接 + ShellExecute(NULL, _T("open"), _T("http://www.un4seen.com/bass.html"), NULL, NULL, SW_SHOW); //打开超链接 *pResult = 0; } @@ -240,7 +267,7 @@ void CAboutDlg::OnNMClickSyslinkBass(NMHDR* pNMHDR, LRESULT* pResult) void CAboutDlg::OnNMClickSyslinkTaglib(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: 在此添加控件通知处理程序代码 - ShellExecute(NULL, _T("open"), _T("http://taglib.org/"), NULL, NULL, SW_SHOW); //打开超链接 + ShellExecute(NULL, _T("open"), _T("http://taglib.org/"), NULL, NULL, SW_SHOW); //打开超链接 *pResult = 0; } @@ -248,7 +275,7 @@ void CAboutDlg::OnNMClickSyslinkTaglib(NMHDR* pNMHDR, LRESULT* pResult) void CAboutDlg::OnNMClickSyslinkTinyxml2(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: 在此添加控件通知处理程序代码 - ShellExecute(NULL, _T("open"), _T("https://github.com/leethomason/tinyxml2"), NULL, NULL, SW_SHOW); //打开超链接 + ShellExecute(NULL, _T("open"), _T("https://github.com/leethomason/tinyxml2"), NULL, NULL, SW_SHOW); //打开超链接 *pResult = 0; } @@ -256,7 +283,7 @@ void CAboutDlg::OnNMClickSyslinkTinyxml2(NMHDR* pNMHDR, LRESULT* pResult) void CAboutDlg::OnNMClickSyslinkScintilla(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: 在此添加控件通知处理程序代码 - ShellExecute(NULL, _T("open"), _T("https://www.scintilla.org/index.html"), NULL, NULL, SW_SHOW); //打开超链接 + ShellExecute(NULL, _T("open"), _T("https://www.scintilla.org/index.html"), NULL, NULL, SW_SHOW); //打开超链接 *pResult = 0; } @@ -264,7 +291,7 @@ void CAboutDlg::OnNMClickSyslinkScintilla(NMHDR* pNMHDR, LRESULT* pResult) void CAboutDlg::OnNMClickSyslinkTrafficmonitor(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: 在此添加控件通知处理程序代码 - ShellExecute(NULL, _T("open"), _T("https://github.com/zhongyang219/TrafficMonitor"), NULL, NULL, SW_SHOW); //打开超链接 + ShellExecute(NULL, _T("open"), _T("https://github.com/zhongyang219/TrafficMonitor"), NULL, NULL, SW_SHOW); //打开超链接 *pResult = 0; } @@ -272,7 +299,7 @@ void CAboutDlg::OnNMClickSyslinkTrafficmonitor(NMHDR* pNMHDR, LRESULT* pResult) void CAboutDlg::OnNMClickSyslinkSimplenotepad(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: 在此添加控件通知处理程序代码 - ShellExecute(NULL, _T("open"), _T("https://github.com/zhongyang219/SimpleNotePad"), NULL, NULL, SW_SHOW); //打开超链接 + ShellExecute(NULL, _T("open"), _T("https://github.com/zhongyang219/SimpleNotePad"), NULL, NULL, SW_SHOW); //打开超链接 *pResult = 0; } @@ -280,9 +307,24 @@ void CAboutDlg::OnNMClickSyslinkSimplenotepad(NMHDR* pNMHDR, LRESULT* pResult) void CAboutDlg::OnNMClickAcknowledgementSyslink(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: 在此添加控件通知处理程序代码 - CMessageDlg dlg; - dlg.SetWindowTitle(CCommon::LoadText(IDS_ACKNOWLEDGEMENT)); - dlg.SetMessageText(CCommon::GetTextResource(IDR_ACKNOWLEDGEMENT, CodeType::UTF8_NO_BOM)); + CMessageDlg dlg(L"AcknowledgementDlg"); + dlg.SetWindowTitle(theApp.m_str_table.LoadText(L"TITLE_ACKNOWLEDGEMENT")); + std::wstringstream wss; + wss << theApp.m_str_table.LoadText(L"TXT_ACKNOWLEDGEMENT_INFO") << L"\r\n" + << CCommon::GetTextResource(IDR_ACKNOWLEDGEMENT, CodeType::UTF8_NO_BOM); + + // 这里排版需要重做 + wss << L"\r\nTranslators\r\n------------------------"; + const auto& lang_list = theApp.m_str_table.GetLanguageList(); + // translator保证至少有一个元素 + for (const auto& lang : lang_list) + { + wss << L"\r\n" << lang.display_name + L"(" + lang.file_name + L") " << lang.translator.front(); + for (auto iter = lang.translator.begin() + 1; iter != lang.translator.end(); ++iter) + wss << L"; " << *iter; + } + + dlg.SetMessageText(wss.str()); dlg.DoModal(); *pResult = 0; } diff --git a/MusicPlayer2/AboutDlg.h b/MusicPlayer2/AboutDlg.h index 24b98506a..e01985bf9 100644 --- a/MusicPlayer2/AboutDlg.h +++ b/MusicPlayer2/AboutDlg.h @@ -1,35 +1,40 @@ #pragma once - +#include "BaseDialog.h" // 用于应用程序“关于”菜单项的 CAboutDlg 对话框 -class CAboutDlg : public CDialog +class CAboutDlg : public CBaseDialog { public: - CAboutDlg(); + CAboutDlg(); + virtual ~CAboutDlg(); - // 对话框数据 + // 对话框数据 #ifdef AFX_DESIGN_TIME - enum { IDD = IDD_ABOUTBOX }; + enum { IDD = IDD_ABOUTBOX }; #endif protected: - CToolTipCtrl m_tool_tip; //鼠标指向时的工具提示 + CToolTipCtrl m_tool_tip; //鼠标指向时的工具提示 CRect m_rc_pic; CImage m_about_pic; + int m_white_height{}; // 背景白色区域的高度 - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 + virtual CString GetDialogName() const; + virtual bool IsRememberDialogSizeEnable() const override { return false; }; + virtual bool InitializeControls() override; + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 // 实现 protected: - DECLARE_MESSAGE_MAP() + DECLARE_MESSAGE_MAP() public: - virtual BOOL OnInitDialog(); - afx_msg void OnNMClickSyslink1(NMHDR *pNMHDR, LRESULT *pResult); - virtual BOOL PreTranslateMessage(MSG* pMsg); - afx_msg void OnNMClickSyslink2(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickGithubSyslink(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnNMClickDonateSyslink(NMHDR *pNMHDR, LRESULT *pResult); + virtual BOOL OnInitDialog(); + afx_msg void OnNMClickSyslink1(NMHDR *pNMHDR, LRESULT *pResult); + virtual BOOL PreTranslateMessage(MSG* pMsg); + afx_msg void OnNMClickSyslink2(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnNMClickGithubSyslink(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnNMClickDonateSyslink(NMHDR *pNMHDR, LRESULT *pResult); afx_msg void OnPaint(); afx_msg void OnNMClickLicenseSyslink(NMHDR *pNMHDR, LRESULT *pResult); afx_msg BOOL OnEraseBkgnd(CDC* pDC); diff --git a/MusicPlayer2/AcceleratorRes.cpp b/MusicPlayer2/AcceleratorRes.cpp index 0588b9696..9d7bb283b 100644 --- a/MusicPlayer2/AcceleratorRes.cpp +++ b/MusicPlayer2/AcceleratorRes.cpp @@ -2,6 +2,7 @@ #include "AcceleratorRes.h" #include "resource.h" #include "Common.h" +#include "MusicPlayer2.h" CAcceleratorRes::CAcceleratorRes() { @@ -143,19 +144,19 @@ std::wstring CAcceleratorRes::Key::ToString() const } else if (key == VK_LEFT) { - str += CCommon::LoadText(IDS_SHORCUT_LEFT).GetString(); + str += theApp.m_str_table.LoadText(L"TXT_SHORCUT_LEFT"); } else if (key == VK_RIGHT) { - str += CCommon::LoadText(IDS_SHOTCUT_RIGHT).GetString(); + str += theApp.m_str_table.LoadText(L"TXT_SHOTCUT_RIGHT"); } else if (key == VK_UP) { - str += CCommon::LoadText(IDS_SHOTCUT_UP).GetString(); + str += theApp.m_str_table.LoadText(L"TXT_SHOTCUT_UP"); } else if (key == VK_DOWN) { - str += CCommon::LoadText(IDS_SHOTCUT_DOWN).GetString(); + str += theApp.m_str_table.LoadText(L"TXT_SHOTCUT_DOWN"); } else if (key >= VK_F1 && key <= VK_F24) { @@ -176,7 +177,7 @@ std::wstring CAcceleratorRes::Key::ToString() const } else if (key == VK_SPACE) { - str += CCommon::LoadText(IDS_SPACE).GetString(); + str += theApp.m_str_table.LoadText(L"TXT_SHOTCUT_SPACE"); } else if (key == VK_OEM_MINUS) { diff --git a/MusicPlayer2/AddToPlaylistDlg.cpp b/MusicPlayer2/AddToPlaylistDlg.cpp index ef9909572..bf013718e 100644 --- a/MusicPlayer2/AddToPlaylistDlg.cpp +++ b/MusicPlayer2/AddToPlaylistDlg.cpp @@ -4,7 +4,8 @@ #include "stdafx.h" #include "MusicPlayer2.h" #include "AddToPlaylistDlg.h" -#include "afxdialogex.h" +#include "PlaylistMgr.h" +#include "FilePathHelper.h" // CAddToPlaylistDlg 对话框 @@ -26,10 +27,23 @@ CString CAddToPlaylistDlg::GetDialogName() const return _T("AddToPlaylistDlg"); } +bool CAddToPlaylistDlg::InitializeControls() +{ + wstring temp; + temp = theApp.m_str_table.LoadText(L"TITLE_ADD_TO_PLAYLIST"); + SetWindowTextW(temp.c_str()); + + RepositionTextBasedControls({ + { CtrlTextInfo::R1, IDOK, CtrlTextInfo::W32 }, + { CtrlTextInfo::R2, IDCANCEL, CtrlTextInfo::W32 } + }); + return true; +} + void CAddToPlaylistDlg::ShowList() { m_playlist_list_ctrl.DeleteAllItems(); - auto data_list{ m_searched ? m_search_result : m_list }; + auto& data_list{ m_searched ? m_search_result : m_list }; for (const auto& item : data_list) { m_playlist_list_ctrl.AddString(item.c_str()); @@ -61,15 +75,15 @@ BOOL CAddToPlaylistDlg::OnInitDialog() // TODO: 在此添加额外的初始化 - SetIcon(theApp.m_icon_set.show_playlist.GetIcon(true), FALSE); // 设置小图标 + SetIcon(IconMgr::IconType::IT_Playlist, FALSE); // 设置小图标 - m_search_edit.SetCueBanner(CCommon::LoadText(IDS_SEARCH_HERE), TRUE); + m_search_edit.SetCueBanner(theApp.m_str_table.LoadText(L"TXT_SEARCH_PROMPT").c_str(), TRUE); //初始化列表 for (const auto& item : CPlaylistMgr::Instance().m_recent_playlists) { CFilePathHelper playlist_path{ item.path }; - m_list.push_back(playlist_path.GetFileNameWithoutExtension().c_str()); + m_list.push_back(playlist_path.GetFileNameWithoutExtension()); } ShowList(); diff --git a/MusicPlayer2/AddToPlaylistDlg.h b/MusicPlayer2/AddToPlaylistDlg.h index d6da22522..72ea0ac4c 100644 --- a/MusicPlayer2/AddToPlaylistDlg.h +++ b/MusicPlayer2/AddToPlaylistDlg.h @@ -1,6 +1,6 @@ #pragma once -#include "CListBoxEnhanced.h" #include "BaseDialog.h" +#include "CListBoxEnhanced.h" #include "SearchEditCtrl.h" @@ -31,6 +31,8 @@ class CAddToPlaylistDlg : public CBaseDialog protected: virtual CString GetDialogName() const override; + virtual bool InitializeControls() override; + void ShowList(); void QuickSearch(const wstring& key_word); diff --git a/MusicPlayer2/AlbumCoverInfoDlg.cpp b/MusicPlayer2/AlbumCoverInfoDlg.cpp deleted file mode 100644 index f49dd6d8e..000000000 --- a/MusicPlayer2/AlbumCoverInfoDlg.cpp +++ /dev/null @@ -1,133 +0,0 @@ -// AlbumCoverInfoDlg.cpp: 实现文件 -// - -#include "stdafx.h" -#include "MusicPlayer2.h" -#include "AlbumCoverInfoDlg.h" - - -// CAlbumCoverInfoDlg 对话框 - -IMPLEMENT_DYNAMIC(CAlbumCoverInfoDlg, CBaseDialog) - -CAlbumCoverInfoDlg::CAlbumCoverInfoDlg(CWnd* pParent /*=nullptr*/) - : CBaseDialog(IDD_ADD_TO_PLAYLIST_DIALOG, pParent) -{ - -} - -CAlbumCoverInfoDlg::~CAlbumCoverInfoDlg() -{ -} - -CString CAlbumCoverInfoDlg::GetDialogName() const -{ - return _T("AlbumCoverInfoDlg"); -} - -void CAlbumCoverInfoDlg::DoDataExchange(CDataExchange* pDX) -{ - CBaseDialog::DoDataExchange(pDX); - DDX_Control(pDX, IDC_LIST1, m_list_ctrl); -} - - -BEGIN_MESSAGE_MAP(CAlbumCoverInfoDlg, CBaseDialog) -END_MESSAGE_MAP() - - -// CAlbumCoverInfoDlg 消息处理程序 - - -BOOL CAlbumCoverInfoDlg::OnInitDialog() -{ - CBaseDialog::OnInitDialog(); - - // TODO: 在此添加额外的初始化 - SetWindowText(CCommon::LoadText(IDS_ALBUM_COVER_INFO)); - SetIcon(theApp.m_icon_set.album_cover, FALSE); - - CWnd* pWnd = GetDlgItem(IDOK); - if (pWnd != nullptr) - pWnd->ShowWindow(SW_HIDE); - - //初始化列表 - CRect rect; - m_list_ctrl.GetWindowRect(rect); - m_list_ctrl.SetExtendedStyle(m_list_ctrl.GetExtendedStyle() | LVS_EX_GRIDLINES); - int width0 = theApp.DPI(85); - int width1 = rect.Width() - width0 - theApp.DPI(20) - 1; - m_list_ctrl.InsertColumn(0, CCommon::LoadText(IDS_ITEM), LVCFMT_LEFT, width0); - m_list_ctrl.InsertColumn(1, CCommon::LoadText(IDS_VLAUE), LVCFMT_LEFT, width1); - - //添加数据 - //封面路径 - m_list_ctrl.InsertItem(0, CCommon::LoadText(IDS_PATH)); - if (CPlayer::GetInstance().AlbumCoverExist()) - m_list_ctrl.SetItemText(0, 1, CPlayer::GetInstance().IsInnerCover() ? CCommon::LoadText(_T("<"), IDS_INNER_ALBUM_COVER, L">").GetString() : CPlayer::GetInstance().GetAlbumCoverPath().c_str()); - //封面类型 - m_list_ctrl.InsertItem(1, CCommon::LoadText(IDS_FORMAT)); - if (CPlayer::GetInstance().AlbumCoverExist()) - { - wstring cover_type; - if (CPlayer::GetInstance().IsInnerCover()) - { - switch (CPlayer::GetInstance().GetAlbumCoverType()) - { - case 0: - cover_type = L"jpg"; - break; - case 1: - cover_type = L"png"; - break; - case 2: - cover_type = L"gif"; - break; - case 3: - cover_type = L"bmp"; - break; - default: - break; - } - } - else - { - cover_type = CFilePathHelper(CPlayer::GetInstance().GetAlbumCoverPath()).GetFileExtension(); - } - m_list_ctrl.SetItemText(1, 1, cover_type.c_str()); - } - - AlbumCoverInfo album_cover_info{ CPlayer::GetInstance().GetAlbumCoverInfo() }; - //宽度 - m_list_ctrl.InsertItem(2, CCommon::LoadText(IDS_WIDTH)); - if(CPlayer::GetInstance().AlbumCoverExist()) - m_list_ctrl.SetItemText(2, 1, std::to_wstring(album_cover_info.width).c_str()); - - //高度 - m_list_ctrl.InsertItem(3, CCommon::LoadText(IDS_HEIGHT)); - if (CPlayer::GetInstance().AlbumCoverExist()) - m_list_ctrl.SetItemText(3, 1, std::to_wstring(album_cover_info.height).c_str()); - - //每像素位数 - m_list_ctrl.InsertItem(4, CCommon::LoadText(IDS_BPP)); - if (CPlayer::GetInstance().AlbumCoverExist()) - m_list_ctrl.SetItemText(4, 1, std::to_wstring(album_cover_info.bpp).c_str()); - - //文件大小 - m_list_ctrl.InsertItem(5, CCommon::LoadText(IDS_FILE_SIZE)); - if (CPlayer::GetInstance().AlbumCoverExist()) - { - size_t file_size = CCommon::GetFileSize(CPlayer::GetInstance().GetAlbumCoverPath()); - m_list_ctrl.SetItemText(5, 1, CCommon::DataSizeToString(file_size)); - } - - //已压缩尺寸过大的专辑封面 - m_list_ctrl.InsertItem(6, CCommon::LoadText(IDS_ALBUM_COVER_COMPRESSED)); - if (CPlayer::GetInstance().AlbumCoverExist()) - { - m_list_ctrl.SetItemText(6, 1, (album_cover_info.size_exceed ? CCommon::LoadText(IDS_YES) : CCommon::LoadText(IDS_NO))); - } - - return TRUE; // return TRUE unless you set the focus to a control - // 异常: OCX 属性页应返回 FALSE -} diff --git a/MusicPlayer2/AlbumCoverInfoDlg.h b/MusicPlayer2/AlbumCoverInfoDlg.h deleted file mode 100644 index 3a0171eb1..000000000 --- a/MusicPlayer2/AlbumCoverInfoDlg.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once -#include "BaseDialog.h" -#include "ListCtrlEx.h" - - -// CAlbumCoverInfoDlg 对话框 - -class CAlbumCoverInfoDlg : public CBaseDialog -{ - DECLARE_DYNAMIC(CAlbumCoverInfoDlg) - -public: - CAlbumCoverInfoDlg(CWnd* pParent = nullptr); // 标准构造函数 - virtual ~CAlbumCoverInfoDlg(); - -// 对话框数据 -#ifdef AFX_DESIGN_TIME - enum { IDD = IDD_ADD_TO_PLAYLIST_DIALOG }; -#endif - -private: - CListCtrlEx m_list_ctrl; - -protected: - virtual CString GetDialogName() const override; - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 - - DECLARE_MESSAGE_MAP() -public: - virtual BOOL OnInitDialog(); -}; diff --git a/MusicPlayer2/AllMediaDlg.cpp b/MusicPlayer2/AllMediaDlg.cpp index 3c51cf1d1..b50472701 100644 --- a/MusicPlayer2/AllMediaDlg.cpp +++ b/MusicPlayer2/AllMediaDlg.cpp @@ -3,6 +3,7 @@ #include "stdafx.h" #include "MusicPlayer2.h" +#include "Player.h" #include "AllMediaDlg.h" #include "MusicPlayerCmdHelper.h" #include "PropertyDlg.h" @@ -36,7 +37,8 @@ void CAllMediaDlg::RefreshSongList() { if (index >= 0 && index < static_cast(m_list_data.size())) { - m_list_songs[index].CopySongInfo(CSongDataManager::GetInstance().GetSongInfo(m_list_songs[index])); + SongInfo tmp = CSongDataManager::GetInstance().GetSongInfo3(m_list_songs[index]); + std::swap(m_list_songs[index], tmp); SetRowData(m_list_data[index], m_list_songs[index]); } } @@ -284,7 +286,10 @@ void CAllMediaDlg::OnOK() else ok = CPlayer::GetInstance().OpenSongsInTempPlaylist(songs); if (!ok) - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } else { CTabDlg::OnOK(); @@ -313,23 +318,22 @@ BOOL CAllMediaDlg::OnInitDialog() CMediaLibTabDlg::OnInitDialog(); // TODO: 在此添加额外的初始化 - CCommon::SetDialogFont(this, theApp.m_pMainWnd->GetFont()); //由于此对话框资源由不同语言共用,所以这里要设置一下字体 //初始化歌曲列表 m_song_list_ctrl.SetExtendedStyle(m_song_list_ctrl.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_LABELTIP); - m_song_list_ctrl.InsertColumn(0, CCommon::LoadText(IDS_NUMBER), LVCFMT_LEFT, theApp.DPI(40)); - m_song_list_ctrl.InsertColumn(1, CCommon::LoadText(IDS_TITLE), LVCFMT_LEFT, theApp.DPI(150)); - m_song_list_ctrl.InsertColumn(2, CCommon::LoadText(IDS_ARTIST), LVCFMT_LEFT, theApp.DPI(100)); - m_song_list_ctrl.InsertColumn(3, CCommon::LoadText(IDS_ALBUM), LVCFMT_LEFT, theApp.DPI(150)); - m_song_list_ctrl.InsertColumn(4, CCommon::LoadText(IDS_TRACK_NUM), LVCFMT_LEFT, theApp.DPI(60)); - m_song_list_ctrl.InsertColumn(5, CCommon::LoadText(IDS_GENRE), LVCFMT_LEFT, theApp.DPI(100)); - m_song_list_ctrl.InsertColumn(6, CCommon::LoadText(IDS_BITRATE), LVCFMT_LEFT, theApp.DPI(60)); - m_song_list_ctrl.InsertColumn(7, CCommon::LoadText(IDS_YEAR), LVCFMT_LEFT, theApp.DPI(60)); - m_song_list_ctrl.InsertColumn(8, CCommon::LoadText(IDS_FILE_PATH), LVCFMT_LEFT, theApp.DPI(600)); - m_song_list_ctrl.InsertColumn(9, CCommon::LoadText(IDS_LAST_PLAYED_TIME), LVCFMT_LEFT, theApp.DPI(140)); + m_song_list_ctrl.InsertColumn(0, theApp.m_str_table.LoadText(L"TXT_SERIAL_NUMBER").c_str(), LVCFMT_LEFT, theApp.DPI(40)); + m_song_list_ctrl.InsertColumn(1, theApp.m_str_table.LoadText(L"TXT_TITLE").c_str(), LVCFMT_LEFT, theApp.DPI(150)); + m_song_list_ctrl.InsertColumn(2, theApp.m_str_table.LoadText(L"TXT_ARTIST").c_str(), LVCFMT_LEFT, theApp.DPI(100)); + m_song_list_ctrl.InsertColumn(3, theApp.m_str_table.LoadText(L"TXT_ALBUM").c_str(), LVCFMT_LEFT, theApp.DPI(150)); + m_song_list_ctrl.InsertColumn(4, theApp.m_str_table.LoadText(L"TXT_TRACK_NUM").c_str(), LVCFMT_LEFT, theApp.DPI(60)); + m_song_list_ctrl.InsertColumn(5, theApp.m_str_table.LoadText(L"TXT_GENRE").c_str(), LVCFMT_LEFT, theApp.DPI(100)); + m_song_list_ctrl.InsertColumn(6, theApp.m_str_table.LoadText(L"TXT_BITRATE").c_str(), LVCFMT_LEFT, theApp.DPI(60)); + m_song_list_ctrl.InsertColumn(7, theApp.m_str_table.LoadText(L"TXT_YEAR").c_str(), LVCFMT_LEFT, theApp.DPI(60)); + m_song_list_ctrl.InsertColumn(8, theApp.m_str_table.LoadText(L"TXT_FILE_PATH").c_str(), LVCFMT_LEFT, theApp.DPI(600)); + m_song_list_ctrl.InsertColumn(9, theApp.m_str_table.LoadText(L"TXT_LAST_PLAYED_TIME").c_str(), LVCFMT_LEFT, theApp.DPI(140)); m_song_list_ctrl.SetCtrlAEnable(true); - m_search_edit.SetCueBanner(CCommon::LoadText(IDS_SEARCH_HERE), TRUE); + m_search_edit.SetCueBanner(theApp.m_str_table.LoadText(L"TXT_SEARCH_PROMPT").c_str(), TRUE); return TRUE; // return TRUE unless you set the focus to a control // 异常: OCX 属性页应返回 FALSE @@ -460,7 +464,7 @@ void CAllMediaDlg::OnNMRClickSongList(NMHDR *pNMHDR, LRESULT *pResult) if (pNMItemActivate->iItem >= 0) { //弹出右键菜单 - CMenu* pMenu = theApp.m_menu_set.m_media_lib_popup_menu.GetSubMenu(1); + CMenu* pMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::LibRightMenu); ASSERT(pMenu != nullptr); if (pMenu != nullptr) { diff --git a/MusicPlayer2/AllMediaDlg.h b/MusicPlayer2/AllMediaDlg.h index a47a6f7ce..8e3d305ca 100644 --- a/MusicPlayer2/AllMediaDlg.h +++ b/MusicPlayer2/AllMediaDlg.h @@ -1,5 +1,4 @@ #pragma once -#include "TabDlg.h" #include "ListCtrlEx.h" #include "SearchEditCtrl.h" #include "MediaLibTabDlg.h" diff --git a/MusicPlayer2/AppearanceSettingDlg.cpp b/MusicPlayer2/AppearanceSettingDlg.cpp index 3980b74cc..bf719003a 100644 --- a/MusicPlayer2/AppearanceSettingDlg.cpp +++ b/MusicPlayer2/AppearanceSettingDlg.cpp @@ -4,7 +4,7 @@ #include "stdafx.h" #include "MusicPlayer2.h" #include "AppearanceSettingDlg.h" -#include "afxdialogex.h" +#include "FilterHelper.h" // CAppearanceSettingDlg 对话框 @@ -21,6 +21,137 @@ CAppearanceSettingDlg::~CAppearanceSettingDlg() { } +bool CAppearanceSettingDlg::InitializeControls() +{ + wstring temp; + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_VISUAL_EFFECTS"); + SetDlgItemTextW(IDC_VISUAL_EFFECTS_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_SPECTRUM_SHOW"); + SetDlgItemTextW(IDC_SHOW_SPECTRUM_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_SPECTRUM_LOW_FREQ_IN_CENTER"); + SetDlgItemTextW(IDC_LOW_FREQ_IN_CENTER_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_SPECTRUM_HEIGHT"); + SetDlgItemTextW(IDC_TXT_SPECTRUM_HIGHT_STATIC, temp.c_str()); + // IDC_SPECTRUM_HEIGHT_SLIDER + // IDC_SPECTRUM_HEIGHT_STATIC + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_COVER_SHOW"); + SetDlgItemTextW(IDC_SHOW_ALBUM_COVER_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_COVER_FIT"); + SetDlgItemTextW(IDC_TXT_COVER_FIT_STATIC, temp.c_str()); + // IDC_ALBUM_FIT_COMBO + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_LYRIC_BG"); + SetDlgItemTextW(IDC_LYRIC_BACKGROUND_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_ROUND_CORNERS"); + SetDlgItemTextW(IDC_BTN_ROUND_CORNERS_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_DARK_MODE"); + SetDlgItemTextW(IDC_DARK_MODE_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_MAIN_WINDOW_TRANSPARENCY"); + SetDlgItemTextW(IDC_TXT_TRANSPARENT_STATIC, temp.c_str()); + // IDC_TRANSPARENT_SLIDER + // IDC_TRANSPARENT_STATIC + + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_BG_SETTING"); + SetDlgItemTextW(IDC_TXT_BG_SETTING_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_BG_ENABLE"); + SetDlgItemTextW(IDC_ENABLE_BACKGROUND_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_BG_USE_DESKTOP"); + SetDlgItemTextW(IDC_USE_DESKTOP_BACKGROUND_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_BG_TRANSPARENCY"); + SetDlgItemTextW(IDC_TXT_BG_TRANSPARENCY_STATIC, temp.c_str()); + // IDC_BACKGROUND_TRANSPARENCY_SLIDER + // IDC_BACKGROUND_TRANSPARENCY_STATIC + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_BG_USE_COVER"); + SetDlgItemTextW(IDC_ALBUM_COVER_BACKGROUND_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_BG_GAUSS_BLUR"); + SetDlgItemTextW(IDC_BACKGROUND_GAUSS_BLUR_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_BG_GAUSS_BLUR_RADIUS"); + SetDlgItemTextW(IDC_TXT_GAUSS_BLUR_RADIUS_STATIC, temp.c_str()); + // IDC_GAUSS_BLURE_RADIUS_SLIDER + // IDC_GAUSS_BLUR_RADIUS_STATIC + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_BG_DEFAULT_IMAGE"); + SetDlgItemTextW(IDC_TXT_DEFAULT_BG_PATH_EDIT_STATIC, temp.c_str()); + // IDC_DEFAULT_BACKGROUND_PATH_EDIT + + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_COVER_OPT"); + SetDlgItemTextW(IDC_TXT_COVER_OPT_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_COVER_USE_INNER_FIRST"); + SetDlgItemTextW(IDC_USE_INNER_IMAGE_FIRST_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_COVER_OUT_IMAGE_ALLOW"); + SetDlgItemTextW(IDC_USE_OUT_IMAGE_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_COVER_OUT_IMAGE_FILE_NAME"); + SetDlgItemTextW(IDC_TXT_EXT_COVER_FILE_NAME_STATIC, temp.c_str()); + // IDC_DEFAULT_COVER_NAME_EDIT + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_COVER_OUT_FOLDER"); + SetDlgItemTextW(IDC_TXT_EXT_COVER_FOLDER_STATIC, temp.c_str()); + // IDC_ALBUM_COVER_PATH_EDIT + + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_COLOR_THEME"); + SetDlgItemTextW(IDC_TXT_THEME_COLOR_STATIC, temp.c_str()); + // IDC_COLOR_STATIC + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_COLOR_PRESET"); + SetDlgItemTextW(IDC_PRESET_COLOR_STATIC, temp.c_str()); + // IDC_COLOR_STATIC2 + // IDC_COLOR_STATIC3 + // IDC_COLOR_STATIC4 + // IDC_COLOR_STATIC5 + // IDC_COLOR_STATIC6 + // IDC_COLOR_STATIC7 + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_COLOR_MORE"); + SetDlgItemTextW(IDC_SET_PROGRESS_COLOR_BUTTON, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_COLOR_FOLLOW_SYSTEM"); + SetDlgItemTextW(IDC_FOLLOW_SYSTEM_COLOR_CHECK, temp.c_str()); + + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_STATUS_BAR"); + SetDlgItemTextW(IDC_TXT_STATUS_BAR_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_ALWAYS_SHOW_STATUS_BAR"); + SetDlgItemTextW(IDC_ALWAYS_SHOW_STATUSBAR_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_SHOW_NEXT_TRACK"); + SetDlgItemTextW(IDC_SHOW_NEXT_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_SHOW_FPS"); + SetDlgItemTextW(IDC_SHOW_FPS_CHECK, temp.c_str()); + + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_TITLE_BAR"); + SetDlgItemTextW(IDC_TXT_TITLE_BAR_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_USE_SYSTEM_TITLE_BAR"); + SetDlgItemTextW(IDC_SHOW_SYSTEM_TITLEBAR_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_TITLE_BAR_BTN_SEL"); + SetDlgItemTextW(IDC_TXT_TITLE_BAR_BTN_SEL_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_TITLE_BAR_BTN_SETTING"); + SetDlgItemTextW(IDC_SHOW_SETTINGS_BTN_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_TITLE_BAR_BTN_SKIN"); + SetDlgItemTextW(IDC_SHOW_SKIN_BTN_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_TITLE_BAR_BTN_MINI_MODE"); + SetDlgItemTextW(IDC_SHOW_MINI_MODE_BTN_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_TITLE_BAR_BTN_FULLSCREEN"); + SetDlgItemTextW(IDC_SHOW_FULLSCREEN_BTN_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_TITLE_BAR_BTN_MINIMIZE"); + SetDlgItemTextW(IDC_SHOW_MINIMIZE_BTN_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_TITLE_BAR_BTN_MAXIMIZE"); + SetDlgItemTextW(IDC_SHOW_MAXIMIZE_BTN_CHECK, temp.c_str()); + + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_NOTIFY_ICON"); + SetDlgItemTextW(IDC_NA_ICO_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_NOTIFY_ICON_PREVIEW"); + SetDlgItemTextW(IDC_PREVIEW_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_NOTIFY_ICON_SEL"); + SetDlgItemTextW(IDC_TXT_NA_ICO_SEL_STATIC, temp.c_str()); + // IDC_COMBO1 + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_NOTIFY_ICON_AUTO_ADAPT"); + SetDlgItemTextW(IDC_NOTIFY_ICON_AUTO_ADAPT_CHECK, temp.c_str()); + + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_ADVANCED"); + SetDlgItemTextW(IDC_TXT_ADV_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_UI_REFRESH_INTERVAL"); + SetDlgItemTextW(IDC_TXT_UI_INTERVAL_STATIC, temp.c_str()); + // IDC_UI_INTERVAL_EDIT + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_UI_REFRESH_INTERVAL_RESTORE"); + SetDlgItemTextW(IDC_RESTORE_DEFAULT_BUTTON, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_APC_COVER_HQ"); + SetDlgItemTextW(IDC_DEFAULT_ALBUM_COVER_HQ, temp.c_str()); + + return true; +} + void CAppearanceSettingDlg::DoDataExchange(CDataExchange* pDX) { CTabDlg::DoDataExchange(pDX); @@ -145,6 +276,11 @@ void CAppearanceSettingDlg::GetDataFromUi() m_data.show_maximize_btn_in_titlebar = (IsDlgButtonChecked(IDC_SHOW_MAXIMIZE_BTN_CHECK) != 0); } +void CAppearanceSettingDlg::ApplyDataToUi() +{ + m_color_static.SetFillColor(theApp.m_app_setting_data.theme_color.original_color); +} + void CAppearanceSettingDlg::DrawColor() { m_color_static.SetFillColor(m_data.theme_color.original_color); @@ -168,10 +304,6 @@ BEGIN_MESSAGE_MAP(CAppearanceSettingDlg, CTabDlg) ON_STN_CLICKED(IDC_COLOR_STATIC6, &CAppearanceSettingDlg::OnStnClickedColorStatic6) ON_STN_CLICKED(IDC_COLOR_STATIC7, &CAppearanceSettingDlg::OnStnClickedColorStatic7) ON_BN_CLICKED(IDC_FOLLOW_SYSTEM_COLOR_CHECK, &CAppearanceSettingDlg::OnBnClickedFollowSystemColorCheck) - //ON_EN_CHANGE(IDC_FONT_NAME_EDIT, &CAppearanceSettingDlg::OnEnChangeFontNameEdit) - //ON_EN_CHANGE(IDC_FONT_SIZE_EDIT, &CAppearanceSettingDlg::OnEnChangeLineSpaceEdit) - //ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN1, &CAppearanceSettingDlg::OnDeltaposSpin1) - ON_WM_CTLCOLOR() ON_BN_CLICKED(IDC_SHOW_ALBUM_COVER_CHECK, &CAppearanceSettingDlg::OnBnClickedShowAlbumCoverCheck) ON_CBN_SELCHANGE(IDC_ALBUM_FIT_COMBO, &CAppearanceSettingDlg::OnCbnSelchangeAlbumFitCombo) ON_BN_CLICKED(IDC_ALBUM_COVER_BACKGROUND_CHECK, &CAppearanceSettingDlg::OnBnClickedAlbumCoverBackgroundCheck) @@ -185,8 +317,6 @@ BEGIN_MESSAGE_MAP(CAppearanceSettingDlg, CTabDlg) ON_BN_CLICKED(IDC_LOW_FREQ_IN_CENTER_CHECK, &CAppearanceSettingDlg::OnBnClickedLowFreqInCenterCheck) ON_BN_CLICKED(IDC_DEFAULT_ALBUM_COVER_HQ, &CAppearanceSettingDlg::OnBnClickedDefaultAlbumCoverHq) ON_BN_CLICKED(IDC_RESTORE_DEFAULT_BUTTON, &CAppearanceSettingDlg::OnBnClickedRestoreDefaultButton) - ON_EN_KILLFOCUS(IDC_UI_INTERVAL_EDIT, &CAppearanceSettingDlg::OnEnKillfocusUiIntervalEdit) - ON_NOTIFY(UDN_DELTAPOS, SPIN_ID, &CAppearanceSettingDlg::OnDeltaposSpin) ON_CBN_SELCHANGE(IDC_COMBO1, &CAppearanceSettingDlg::OnCbnSelchangeCombo1) ON_WM_PAINT() ON_BN_CLICKED(IDC_NOTIFY_ICON_AUTO_ADAPT_CHECK, &CAppearanceSettingDlg::OnBnClickedNotifyIconAutoAdaptCheck) @@ -232,13 +362,13 @@ BOOL CAppearanceSettingDlg::OnInitDialog() m_toolTip.Create(this); m_toolTip.SetMaxTipWidth(theApp.DPI(300)); - m_toolTip.AddTool(&m_color_static, CCommon::LoadText(IDS_CURRENT_COLOR)); - m_toolTip.AddTool(&m_color_static1, CCommon::LoadText(IDS_LIGNT_BLUE)); - m_toolTip.AddTool(&m_color_static2, CCommon::LoadText(IDS_GREEN)); - m_toolTip.AddTool(&m_color_static3, CCommon::LoadText(IDS_ORANGE)); - m_toolTip.AddTool(&m_color_static4, CCommon::LoadText(IDS_CYAN_GREEN)); - m_toolTip.AddTool(&m_color_static5, CCommon::LoadText(IDS_PINK)); - m_toolTip.AddTool(&m_color_static6, CCommon::LoadText(IDS_LIGHT_PURPLE)); + m_toolTip.AddTool(&m_color_static, theApp.m_str_table.LoadText(L"TIP_OPT_APC_COLOR_CURRENT").c_str()); + m_toolTip.AddTool(&m_color_static1, theApp.m_str_table.LoadText(L"TIP_OPT_APC_COLOR_LIGNT_BLUE").c_str()); + m_toolTip.AddTool(&m_color_static2, theApp.m_str_table.LoadText(L"TIP_OPT_APC_COLOR_GREEN").c_str()); + m_toolTip.AddTool(&m_color_static3, theApp.m_str_table.LoadText(L"TIP_OPT_APC_COLOR_ORANGE").c_str()); + m_toolTip.AddTool(&m_color_static4, theApp.m_str_table.LoadText(L"TIP_OPT_APC_COLOR_CYAN_GREEN").c_str()); + m_toolTip.AddTool(&m_color_static5, theApp.m_str_table.LoadText(L"TIP_OPT_APC_COLOR_PINK").c_str()); + m_toolTip.AddTool(&m_color_static6, theApp.m_str_table.LoadText(L"TIP_OPT_APC_COLOR_LIGHT_PURPLE").c_str()); m_toolTip.SetWindowPos(&CWnd::wndTopMost, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); @@ -258,18 +388,18 @@ BOOL CAppearanceSettingDlg::OnInitDialog() // m_show_album_cover_chk.SetCheck(m_data.show_album_cover); - m_album_cover_fit_combo.AddString(CCommon::LoadText(IDS_STRETCH)); - m_album_cover_fit_combo.AddString(CCommon::LoadText(IDS_FILL)); - m_album_cover_fit_combo.AddString(CCommon::LoadText(IDS_ADAPT)); + m_album_cover_fit_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_APC_COVER_FIT_STRETCH").c_str()); + m_album_cover_fit_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_APC_COVER_FIT_FILL").c_str()); + m_album_cover_fit_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_APC_COVER_FIT_ADAPT").c_str()); m_album_cover_fit_combo.SetCurSel(static_cast(m_data.album_cover_fit)); - m_toolTip.AddTool(&m_album_cover_fit_combo, CCommon::LoadText(IDS_COVER_FIT_TIP_INFO)); - m_toolTip.AddTool(&m_use_out_image_chk, CCommon::LoadText(IDS_USE_OUT_IMAGE_TIP_INFO)); - m_toolTip.AddTool(&m_album_cover_name_edit, CCommon::LoadText(IDS_DEFAULT_COVER_NAME_TIP_INFO)); - m_toolTip.AddTool(&m_album_cover_path_edit, CCommon::LoadText(IDS_ALBUM_COVER_PATH_EDIT_TIP_INFO)); + m_toolTip.AddTool(&m_album_cover_fit_combo, theApp.m_str_table.LoadText(L"TIP_OPT_APC_COVER_FIT").c_str()); + m_toolTip.AddTool(&m_use_out_image_chk, theApp.m_str_table.LoadText(L"TIP_OPT_APC_COVER_OUT_IMAGE_ALLOW").c_str()); + m_toolTip.AddTool(&m_album_cover_name_edit, theApp.m_str_table.LoadText(L"TIP_OPT_APC_COVER_OUT_IMAGE_FILE_NAME").c_str()); + m_toolTip.AddTool(&m_album_cover_path_edit, theApp.m_str_table.LoadText(L"TIP_OPT_APC_COVER_OUT_FOLDER").c_str()); m_album_cover_name_edit.SetWindowTextW(CCommon::StringMerge(m_data.default_album_name, L',').c_str()); m_album_cover_name_edit.SetEditBrowseMode(CBrowseEdit::EditBrowseMode::LIST); - m_album_cover_name_edit.SetPopupDlgTitle(CCommon::LoadText(IDS_SET_MULTI_OUT_ALBUM_COVER_FILE_NAME)); + m_album_cover_name_edit.SetPopupDlgTitle(theApp.m_str_table.LoadText(L"TITLE_BROWSE_EDIT_SET_MULTI_OUT_ALBUM_COVER_FILE_NAME")); m_album_cover_path_edit.SetWindowTextW(m_data.album_cover_path.c_str()); m_enable_background_chk.SetCheck(m_data.enable_background); @@ -294,18 +424,18 @@ BOOL CAppearanceSettingDlg::OnInitDialog() m_low_freq_in_center_chk.SetCheck(m_data.spectrum_low_freq_in_center); m_default_background_edit.SetWindowText(m_data.default_background.c_str()); - CString szFilter = CCommon::LoadText(IDS_IMAGE_FILE_FILTER); - m_default_background_edit.EnableFileBrowseButton(NULL, szFilter); + wstring img_fliter = FilterHelper::GetImageFileFilter(); + m_default_background_edit.EnableFileBrowseButton(NULL, img_fliter.c_str()); CheckDlgButton(IDC_USE_DESKTOP_BACKGROUND_CHECK, m_data.use_desktop_background); m_default_cover_hq_chk.SetCheck(m_data.draw_album_high_quality); - m_ui_refresh_interval_edit.SetRange(MIN_UI_INTERVAL, MAX_UI_INTERVAL); + m_ui_refresh_interval_edit.SetRange(MIN_UI_INTERVAL, MAX_UI_INTERVAL, UI_INTERVAL_STEP); m_ui_refresh_interval_edit.SetValue(m_data.ui_refresh_interval); - m_icon_select_combo.AddString(CCommon::LoadText(IDS_DEFAULT_ICON)); - m_icon_select_combo.AddString(CCommon::LoadText(IDS_LIGHT_ICON)); - m_icon_select_combo.AddString(CCommon::LoadText(IDS_DARK_ICON)); + m_icon_select_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_APC_NOTIFY_ICON_DEFAULT").c_str()); + m_icon_select_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_APC_NOTIFY_ICON_LIGHT").c_str()); + m_icon_select_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_APC_NOTIFY_ICON_DARK").c_str()); m_icon_select_combo.SetCurSel(m_data.notify_icon_selected); m_notify_icon_auto_adapt_chk.SetCheck(m_data.notify_icon_auto_adapt); @@ -408,7 +538,7 @@ void CAppearanceSettingDlg::OnBnClickedSetThemeButton() //if (m_data.theme_color.original_color == 0) // MessageBox(_T("警告:将主题颜色设置成黑色会使播放列表中正在播放的项目看不见!"), NULL, MB_ICONWARNING); //if(m_data.theme_color.original_color == RGB(255,255,255)) - // MessageBox(CCommon::LoadText(IDS_WHITE_THEME_COLOR_WARNING), NULL, MB_ICONWARNING); + // MessageBox(WHITE_THEME_COLOR_WARNING), NULL, MB_ICONWARNING); m_color_static.SetFillColor(m_data.theme_color.original_color); //设置了“更多颜色”之后,取消“跟随系统主题色”复选按钮的选中 m_data.theme_color_follow_system = false; @@ -483,55 +613,6 @@ void CAppearanceSettingDlg::OnBnClickedFollowSystemColorCheck() } -void CAppearanceSettingDlg::OnCancel() -{ - // TODO: 在此添加专用代码和/或调用基类 - - //CTabDlg::OnCancel(); -} - - -void CAppearanceSettingDlg::OnOK() -{ - // TODO: 在此添加专用代码和/或调用基类 - - //CTabDlg::OnOK(); -} - - -//void CAppearanceSettingDlg::OnEnChangeFontNameEdit() -//{ -// // TODO: 如果该控件是 RICHEDIT 控件,它将不 -// // 发送此通知,除非重写 CTabDlg::OnInitDialog() -// // 函数并调用 CRichEditCtrl().SetEventMask(), -// // 同时将 ENM_CHANGE 标志“或”运算到掩码中。 -// -// // TODO: 在此添加控件通知处理程序代码 -// CString font_name; -// GetDlgItemText(IDC_FONT_NAME_EDIT, font_name); -// m_font = font_name; -// m_font_changed = true; -//} - - - -HBRUSH CAppearanceSettingDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) -{ - HBRUSH hbr = CTabDlg::OnCtlColor(pDC, pWnd, nCtlColor); - - // TODO: 在此更改 DC 的任何特性 - if (pWnd == &m_transparency_slid || pWnd == &m_spectrum_height_slid || pWnd == &m_back_transparency_slid || pWnd == &m_gauss_blur_radius_sld) //设置滑动条控件的背景色为白色 - { - static HBRUSH brush{}; - if (brush == NULL) - brush = CreateSolidBrush(m_background_color); - return brush; - } - // TODO: 如果默认的不是所需画笔,则返回另一个画笔 - return hbr; -} - - void CAppearanceSettingDlg::OnBnClickedShowAlbumCoverCheck() { // TODO: 在此添加控件通知处理程序代码 @@ -629,58 +710,6 @@ void CAppearanceSettingDlg::OnBnClickedRestoreDefaultButton() } -void CAppearanceSettingDlg::OnEnKillfocusUiIntervalEdit() -{ - // TODO: 在此添加控件通知处理程序代码 - CString str; - GetDlgItemText(IDC_UI_INTERVAL_EDIT, str); - int value = _ttoi(str.GetString()); - if (value < MIN_UI_INTERVAL || value > MAX_UI_INTERVAL) - { - value = UI_INTERVAL_DEFAULT; - } - m_ui_refresh_interval_edit.SetValue(value); - -} - -void CAppearanceSettingDlg::OnDeltaposSpin(NMHDR* pNMHDR, LRESULT* pResult) -{ - //这里响应微调按钮(spin button)点击上下按钮时的事件, - //所有CSpinEdit类中的Spin按钮点击时的响应都在这里,因为这些Spin按钮的ID都是“SPIN_ID”。 - //通过GetBuddy的返回值判断微调按钮是属于哪个EditBox的。 - - CSpinButtonCtrl* pSpin = (CSpinButtonCtrl*)CWnd::FromHandle(pNMHDR->hwndFrom); - if (pSpin == nullptr) - return; - CWnd* pEdit = pSpin->GetBuddy(); - //设置点击“界面刷新时间间隔”微调按钮时的步长 - if (pEdit == &m_ui_refresh_interval_edit) //当用户点击了“界面刷新时间间隔”的微调按钮时 - { - LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR); - if (pNMUpDown->iDelta == -1) - { - // 用户按下了spin控件的向下箭头 - int value = m_ui_refresh_interval_edit.GetValue(); - value -= UI_INTERVAL_STEP; - value /= UI_INTERVAL_STEP; - value *= UI_INTERVAL_STEP; - m_ui_refresh_interval_edit.SetValue(value); - } - else if (pNMUpDown->iDelta == 1) - { - // 用户按下了spin控件的向上箭头 - int value = m_ui_refresh_interval_edit.GetValue(); - value += UI_INTERVAL_STEP; - value /= UI_INTERVAL_STEP; - value *= UI_INTERVAL_STEP; - m_ui_refresh_interval_edit.SetValue(value); - } - pNMUpDown->iDelta = 0; - } - *pResult = 0; -} - - void CAppearanceSettingDlg::OnCbnSelchangeCombo1() { // TODO: 在此添加控件通知处理程序代码 @@ -697,7 +726,7 @@ void CAppearanceSettingDlg::OnPaint() CalculateNotifyIconPreviewRect(); CDrawCommon drawer; - drawer.Create(&dc, this); + drawer.Create(&dc); CBitmap& bitmap{ m_data.notify_icon_selected == 2 ? m_preview_light : m_preview_dark }; //绘制背景 drawer.DrawBitmap(bitmap, m_notify_icon_preview.TopLeft(), m_notify_icon_preview.Size(), CDrawCommon::StretchMode::STRETCH); diff --git a/MusicPlayer2/AppearanceSettingDlg.h b/MusicPlayer2/AppearanceSettingDlg.h index d59989b7b..30035ef59 100644 --- a/MusicPlayer2/AppearanceSettingDlg.h +++ b/MusicPlayer2/AppearanceSettingDlg.h @@ -1,6 +1,4 @@ #pragma once -#include "afxcmn.h" -#include "afxwin.h" #include "Common.h" #include "DrawCommon.h" #include "ColorStatic.h" @@ -85,6 +83,7 @@ class CAppearanceSettingDlg : public CTabDlg CBrowseEdit m_album_cover_name_edit; CBrowseEdit m_album_cover_path_edit; + virtual bool InitializeControls() override; virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 void SetTransparency(); @@ -96,6 +95,7 @@ class CAppearanceSettingDlg : public CTabDlg void CalculateNotifyIconPreviewRect(); virtual void GetDataFromUi() override; + virtual void ApplyDataToUi() override; DECLARE_MESSAGE_MAP() public: @@ -111,9 +111,6 @@ class CAppearanceSettingDlg : public CTabDlg afx_msg void OnStnClickedColorStatic7(); virtual BOOL PreTranslateMessage(MSG* pMsg); afx_msg void OnBnClickedFollowSystemColorCheck(); - virtual void OnCancel(); - virtual void OnOK(); - afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); afx_msg void OnBnClickedShowAlbumCoverCheck(); afx_msg void OnCbnSelchangeAlbumFitCombo(); afx_msg void OnBnClickedAlbumCoverBackgroundCheck(); @@ -127,8 +124,6 @@ class CAppearanceSettingDlg : public CTabDlg afx_msg void OnBnClickedLowFreqInCenterCheck(); afx_msg void OnBnClickedDefaultAlbumCoverHq(); afx_msg void OnBnClickedRestoreDefaultButton(); - afx_msg void OnEnKillfocusUiIntervalEdit(); - afx_msg void OnDeltaposSpin(NMHDR* pNMHDR, LRESULT* pResult); afx_msg void OnCbnSelchangeCombo1(); afx_msg void OnPaint(); afx_msg void OnBnClickedNotifyIconAutoAdaptCheck(); diff --git a/MusicPlayer2/AudioCommon.cpp b/MusicPlayer2/AudioCommon.cpp index 13ac57a0e..d60197eaf 100644 --- a/MusicPlayer2/AudioCommon.cpp +++ b/MusicPlayer2/AudioCommon.cpp @@ -5,6 +5,11 @@ #include "SongDataManager.h" #include "taglib/id3v1genres.h" #include "SongInfoHelper.h" +#include "Lyric.h" +#include "AudioTag.h" +#include "FilePathHelper.h" +#include "COSUPlayerHelper.h" +#include "Player.h" void SupportedFormat::CreateExtensionsList() @@ -97,13 +102,13 @@ AudioType CAudioCommon::GetAudioTypeByFileName(const wstring & file_name) wstring CAudioCommon::GetAudioDescriptionByExtension(wstring extension) { if (extension.empty()) - return wstring(CCommon::LoadText(IDS_UNKNOW)); + return theApp.m_str_table.LoadText(L"TXT_FILE_TYPE_UNKNOWN"); CCommon::StringTransform(extension, false); for (const auto& item : m_surpported_format) { - if (item.description != CCommon::LoadText(IDS_BASIC_AUDIO_FORMAT).GetString()) + if (item.description != theApp.m_str_table.LoadText(L"TXT_FILE_TYPE_BASE")) { for (const auto& ext : item.extensions) { @@ -112,39 +117,40 @@ wstring CAudioCommon::GetAudioDescriptionByExtension(wstring extension) } } } - + wstring audio_str; if (extension == L"mp3") - return L"MPEG Audio Layer 3"; + audio_str = theApp.m_str_table.LoadText(L"TXT_FILE_TYPE_MP3"); else if (extension == L"mp1" || extension == L"mp2") - return L"MPEG Audio"; + audio_str = theApp.m_str_table.LoadText(L"TXT_FILE_TYPE_MP1_MP2"); else if (extension == L"wma") - return L"Windows Media Audio"; + audio_str = theApp.m_str_table.LoadText(L"TXT_FILE_TYPE_WMA"); else if (extension == L"asf") - return L"Advanced Streaming Format"; + audio_str = theApp.m_str_table.LoadText(L"TXT_FILE_TYPE_ASF"); else if (extension == L"wav") - return wstring(CCommon::LoadText(_T("WAV "), IDS_AUDIO_FILE)); + audio_str = theApp.m_str_table.LoadText(L"TXT_FILE_TYPE_WAV"); else if (extension == L"ogg" || extension == L"oga") - return wstring(CCommon::LoadText(_T("OGG Vorbis "), IDS_AUDIO_FILE)); + audio_str = theApp.m_str_table.LoadText(L"TXT_FILE_TYPE_OGG_OGA"); else if (extension == L"m4a" || extension == L"mp4") - return wstring(CCommon::LoadText(_T("MPEG-4 "), IDS_AUDIO_FILE)); + audio_str = theApp.m_str_table.LoadText(L"TXT_FILE_TYPE_M4A_MP4"); else if (extension == L"ape") - return wstring(L"Monkey's Audio (APE)"); + audio_str = theApp.m_str_table.LoadText(L"TXT_FILE_TYPE_APE"); else if (extension == L"aac") - return wstring(L"Advanced Audio Coding (AAC)"); + audio_str = theApp.m_str_table.LoadText(L"TXT_FILE_TYPE_ACC"); else if (extension == L"aif" || extension == L"aiff") - return wstring(L"Audio Interchange File"); + audio_str = theApp.m_str_table.LoadText(L"TXT_FILE_TYPE_AIF_AIFF"); else if (extension == L"cda") - return wstring(CCommon::LoadText(_T("CD "), IDS_AUDIO_FILE, _T(" (CDA)"))); + audio_str = theApp.m_str_table.LoadText(L"TXT_FILE_TYPE_CDA"); else if (extension == L"playlist") - return wstring(CCommon::LoadText(_T("MusicPlayer2 "), IDS_PLAYLIST)); + audio_str = theApp.m_str_table.LoadText(L"TXT_FILE_TYPE_PLAYLIST"); else if (extension == L"m3u") - return wstring(CCommon::LoadText(_T("M3U "), IDS_PLAYLIST)); + audio_str = theApp.m_str_table.LoadText(L"TXT_FILE_TYPE_M3U"); else if (extension == L"m3u8") - return wstring(CCommon::LoadText(_T("M3U8 "), IDS_PLAYLIST)); + audio_str = theApp.m_str_table.LoadText(L"TXT_FILE_TYPE_M3U8"); else if (extension == L"cue") - return L"CUE Sheets"; + audio_str = theApp.m_str_table.LoadText(L"TXT_FILE_TYPE_CUE"); else - return wstring(extension + CCommon::LoadText(_T(" "), IDS_AUDIO_FILE).GetString()); + audio_str = theApp.m_str_table.LoadTextFormat(L"TXT_FILE_TYPE_OTHER", { extension }); + return audio_str; } void CAudioCommon::GetAudioFiles(wstring path, vector& files, size_t max_file, bool include_sub_dir) @@ -278,262 +284,263 @@ void CAudioCommon::GetLyricFiles(wstring path, vector& files) _findclose(hFile); } -void CAudioCommon::GetCueTracks(vector& files, IPlayerCore* pPlayerCore, int& index, bool refresh_info) + +void CAudioCommon::FixErrorCueAudioPath(vector& track_from_text) { - for (size_t i = 0; i < files.size(); i++) + // file_path如果不存在那么试着模糊匹配一个音频文件,没能成功找到时不修改file_path + wstring audio_path; // 存储上一个存在的song的音频文件(正常情况下用来避免反复CCommon::FileExist) + for (SongInfo& song : track_from_text) // track_from_text是CCueFile给出的文本解析结果 { - //依次检查列表中的每首歌曲是否为cue文件 - if (GetAudioTypeByFileName(files[i].file_path) == AU_CUE) + // 如果循环开始时audio_path不为空说明上次已确认此文件存在 + if (!audio_path.empty() && audio_path == song.file_path) + continue; + // if (CCommon::FileExist(song.file_path) // 当cue内FILE与实际音频文件名大小写不符时以cue为准 + if (CCommon::CheckAndFixFile(song.file_path)) // 严格检查大小写,如果不正确则修正(以音频文件为准) { - CFilePathHelper file_path{ files[i].file_path }; - wstring cue_dir = file_path.GetDir(); - - //解析cue文件 - CCueFile cue_file{ file_path.GetFilePath() }; - - wstring audio_file_name; // 临时存储音频文件名 - Time audio_file_length{}; // 音频文件长度 - bool audio_already_songdatamanager{}; // 发现音轨已存在于媒体库则不进行时长/标签处理除非强制刷新 - bool audio_file_name_change = true; // 音频文件未匹配,当audio_file_name被错误检查改变,temp[j].file_path不再准确时设为true - const std::vector& temp = cue_file.GetAnalysisResult(); // cue文件的文本解析结果 - vector cue_tracks; // 储存解析到的cue音轨 - - // 遍历temp分析对应音频文件修正信息,修正后最终结果放入cue_tracks,并移除files内的原始音频文件 - for (size_t j = 0; j < temp.size(); ++j) + audio_path = song.file_path; // 更新audio_path + continue; + } + // 文件不存在,以下开始模糊匹配 + auto GetFirstMatchAudioAndFix = [&](const wstring& path_mode, const wstring& dir)->bool { + bool succeed = false; + intptr_t hFile = 0; // 文件句柄 + _wfinddata_t fileinfo; //文件信息(用Unicode保存使用_wfinddata_t,多字节字符集使用_finddata_t) + if ((hFile = _wfindfirst(path_mode.c_str(), &fileinfo)) != -1) { - CFilePathHelper audio_file_path{ temp[j].file_path }; // 用于检查与查找音频文件 - // 检查音轨是否存在于媒体库,音频不存在的话audio_file_name改变后会被重新设置 - audio_already_songdatamanager = CSongDataManager::GetInstance().IsItemExist(temp[j]); - - // audio_file_path正确时连续同一文件不再二次操作 - if (audio_file_path.GetFileName() != audio_file_name || audio_file_path.GetFileName().empty()) + do { - audio_file_name = audio_file_path.GetFileName(); - audio_file_name_change = false; // 由于audio_file_name与temp中的音频路径恢复同步所以设为false - // 如果指定音频文件不存在 - if (!CCommon::FileExist(audio_file_path.GetFilePath())) + wstring name{ fileinfo.name }; + if (CFilePathHelper(name).GetFileExtension() != L"cue" && FileIsAudio(name)) { - // 开始尝试更正cue中FILE标签的文件名 - // 先尝试寻找不同扩展名的音频文件 - vector files; - CCommon::GetFiles(cue_dir + audio_file_path.GetFileNameWithoutExtension() + L".*", files, - [](const wstring& file_name) - { - CFilePathHelper file_path(file_name); - wstring extension{ file_path.GetFileExtension() }; // 获取文件扩展名 - return extension != L"cue" && FileIsAudio(file_name); - }); - // 如果没有找到则尝试与cue同名音频文件 - if (files.empty()) - audio_file_path.SetFilePath(file_path.GetFilePath()); // 将file_path复制给audio_file_path以免改变file_path - while (files.empty()) - { - CCommon::GetFiles(cue_dir + audio_file_path.GetFileNameWithoutExtension() + L".*", files, - [](const wstring& file_name) - { - CFilePathHelper file_path(file_name); - wstring extension{ file_path.GetFileExtension() }; // 获取文件扩展名 - return extension != L"cue" && FileIsAudio(file_name); - }); - if (audio_file_path.GetFileExtension() != std::wstring()) // 逐个移除扩展名 - audio_file_path.SetFilePath(audio_file_path.GetFilePathWithoutExtension()); - else - break; - } - if (!files.empty()) // 找到了满足要求的文件 - { - audio_file_name = files.front(); - audio_file_name_change = true; - } + song.file_path = dir + name; + succeed = true; + break; } - // 音频不存在处理完成但仍然不能保证成功 - - // 媒体库不接受没有音频路径的歌曲,跳过temp[j] - if (!CCommon::FileExist(cue_dir + audio_file_name)) continue; - - // 开始取得音频文件信息(此处仅取得长度) - audio_already_songdatamanager = CSongDataManager::GetInstance().IsItemExist(CSongDataManager::SongDataMapKey{ cue_dir + audio_file_name , temp[j].track }); - // 如果还未获取对应音频文件的信息,则在这里获取 - if (!audio_already_songdatamanager || refresh_info) - { - SongInfo audo_file_info; - audo_file_info.file_path = cue_dir + audio_file_name; - if (pPlayerCore != nullptr) - { - pPlayerCore->GetAudioInfo((cue_dir + audio_file_name).c_str(), audo_file_info, AF_LENGTH); - } - audio_file_length = audo_file_info.length(); - } - - // 检查files列表中是否包含cue对应的音频文件,移除cue对应原始音频,与处理好的cue条目无关 - auto find = std::find_if(files.begin(), files.end(), [&](const SongInfo& song) - { - return CCommon::StringCompareNoCase(song.file_path, cue_dir + audio_file_name) && !song.is_cue; - }); - if (find != files.end()) - { - int index_find = static_cast(find - files.begin()); - if (index_find < static_cast(i)) // 如果删除的文件在当前文件的前面,则循环变量减1 - i--; - - if (index < index_find) // 移除文件在index之前则index自减1保持与files的对齐 - index--; - else if (index == index_find) // 移除文件就是index则让index指向此音频所属cue文件 - index = i; - - files.erase(find); // 找到cue对应的音频文件则把它删除 - } - } // 以上部分仅在新FILE标签或音频文件异常时执行以加快循环检查TRACK的速度 - - // 将temp[j]存入cue_tracks并做最后处理 - cue_tracks.push_back(temp[j]); - SongInfo& cur = cue_tracks.back(); - // 若cue_tracks.back().file_path中的信息已失效则更新 - if (audio_file_name_change) - cur.file_path = cue_dir + audio_file_name; - - ASSERT(CCommon::FileExist(cur.file_path)); - - // 媒体库内不存在或强制刷新则重新设置媒体库内项目值 - if (!audio_already_songdatamanager || refresh_info) - { - // 依据end_pos是否为0判断这个轨道是否应当按照音频文件补充结束时间与时长 - if (cur.end_pos == 0) - { - cur.end_pos = audio_file_length; - //cur.lengh = cur.end_pos - cur.start_pos; - } - // 若时长获取失败则需要将此FILE所有TRACK标记为无效文件,将时长清零 - if (audio_file_length.isZero()) - { - //cur.lengh = 0; - cur.end_pos = cur.start_pos; // 由于时长本身退出不保存,所以将差值同时清零 - } - // 直接写入媒体库 - SongInfo song_info{ CSongDataManager::GetInstance().GetSongInfo3(cur) }; - song_info.CopyAudioTag(cur); - song_info.start_pos = cur.start_pos; - //song_info.lengh = cur.lengh; - song_info.end_pos = cur.end_pos; - CSongDataManager::GetInstance().AddItem(song_info); - } + } while (_wfindnext(hFile, &fileinfo) == 0); } + _findclose(hFile); + return succeed; + }; + wstring match_name; + // 匹配任意格式的音频文件 + CFilePathHelper path(song.file_path); + if (GetFirstMatchAudioAndFix(path.ReplaceFileExtension(L"*"), path.GetDir())) + continue; + // 匹配与cue同名的任意格式音频文件 + path.SetFilePath(song.cue_file_path); + if (GetFirstMatchAudioAndFix(path.ReplaceFileExtension(L"*"), path.GetDir())) + continue; + // 处理cue有表示语言的双重后缀的情况,例如“filename.jp.cue”匹配“filename.*”的音频文件 + path.SetFilePath(path.GetDir() + path.GetFileNameWithoutExtension()); // 将path设置为不含“.cue”的cue路径 + if (GetFirstMatchAudioAndFix(path.ReplaceFileExtension(L"*"), path.GetDir())) + continue; + // 再进行一次 + path.SetFilePath(path.GetDir() + path.GetFileNameWithoutExtension()); + if (GetFirstMatchAudioAndFix(path.ReplaceFileExtension(L"*"), path.GetDir())) + continue; + } +} - /* 此时files[i]为需要移除的cue,解析结果在cue_tracks */ - /* 接下来根据是否忽略已存在文件使用cue_tracks原位代换cue */ - /* 可能的情况:cue_tracks全部插入files/部分插入/全部已存在不做更改 */ - /* 不过可以肯定完成后cue_tracks的全部条目files内都会存在 */ - - files.erase(files.begin() + i); //从列表中删除cue文件 - - // 指示此次需要为index同步files[i]位置曲目数量的增减 - bool before_index{ static_cast(i) < index }; - // 指示此次cue_tracks为索引指定cue,需要index跟踪其第一轨位置 - bool is_index{ i == index }; - - for (const auto& cue_track : cue_tracks) +void CAudioCommon::GetCueTracks(vector& files, int& update_cnt, bool& exit_flag, MediaLibRefreshMode refresh_mode) +{ + std::map> cue_file; + for (const SongInfo& song : files) + { + if (exit_flag) return; + // ASSERT(!song.file_path.empty()); // 等到m_playlist可空以后加回来 + if (song.file_path.empty()) continue; + if (song.is_cue) + { + // 设置了合适“媒体库目录”之后“强制重新加载”可以使得媒体库能够转换旧播放列表到新格式 + SongInfo song_info{ CSongDataManager::GetInstance().GetSongInfo3(song) }; + if (!song_info.cue_file_path.empty()) // 如果媒体库内仍然没有cue_file_path那么什么也不会做(和之前一样) + cue_file[song_info.cue_file_path].push_back(song_info); + } + else if (CFilePathHelper(song.file_path).GetFileExtension() == L"cue") + { + vector& a = cue_file[song.file_path]; // 此处file_path为cue路径 + a.insert(a.begin(), song); // is_cue为false的此项存在于开头说明添加全部track + } + /* 不再支持内嵌cue,主要是架构问题现有很多代码都不适于内嵌cue需要加写特殊处理 (CCueFile也没有准备好支持内嵌cue等等等) + else + { + // 支持内嵌cue影响文件夹模式的快速启动(当文件夹中有大量ape时),我认为只能二选一 + // 与refresh_mode的MR_MIN_REQUIRED有冲突 属性编辑等功能也没有支持内嵌cue + CAudioTag audio_tag(song.file_path); + wstring song_cue_text{ audio_tag.GetAudioCue() };// 对于ape文件即使是固态硬盘这步也非常慢(不适合对所有音频遍历执行) + if (!song_cue_text.empty()) // 如果音频有内嵌cue那么将其加入cue_file { - // 查找当前cue_track是否已存在于files - auto find = std::find_if(files.begin(), files.end(), [&](const SongInfo& song) - { - return song.IsSameSong(cue_track); - }); - if (find == files.end()) - { - // files中不存在当前曲目,将cue_track插入files - files.emplace(files.begin() + i++, cue_track); - if (before_index) - index++; - } - else if (is_index) // 如果此cue的第一轨已存在于files中则将索引调整到其位置 - index = find - files.begin(); - is_index = false; // 仅对cue_tracks[0]修改index + vector& a = cue_file[song.file_path]; + a.insert(a.begin(), song); // is_cue为false的此项存在于开头说明添加此cue全部track } - i--; // 解析完一个cue文件后,由于该cue文件已经被移除,所以将循环变量减1 - if (before_index) - index--; } + */ } - GetInnerCueTracks(files, pPlayerCore, index, refresh_info); -} - -void CAudioCommon::GetInnerCueTracks(vector& files, IPlayerCore* pPlayerCore, int& index, bool refresh_info) -{ - for (int i{}; i < static_cast(files.size()); ++i) + // cue同时有多个语言版本时,这里行为会有点怪,更合理应当总是取修改时间最大的那个cue但开销略大(使用一个辅助变量以cue修改时间升序遍历cue_file)我觉得暂时没必要 + std::set audio_path; // 被cue使用的音频路径,添加完cue音轨之后统一移除 + for (const auto& item : cue_file) { - if (files[i].is_cue || files[i].file_path.empty()) // 跳过已解析的cue音轨,跳过无效文件 + if (exit_flag) return; + unsigned __int64 modified_time_cue{}; + // 确认cue文件是否存在(同时获取修改时间),文件不存在时不进行接下来的步骤(原样保留files中此cue相关文件(item.second)) + if (!CCommon::GetFileLastModified(item.first, modified_time_cue)) continue; - CAudioTag audio_tag(files[i]); - wstring cue_contents = audio_tag.GetAudioCue(); - - //解析cue音轨 - if (!cue_contents.empty()) + ASSERT(CFilePathHelper(item.first).GetFileExtension() == L"cue"); // CCueFile只接受cue文件 + CCueFile cue_file{ item.first }; + // CCueFile暂时不支持内嵌cue有待修改,(这里需要内嵌cue的GetAnalysisResult返回track_from_text中cue_file_path项为音频路径) + vector track_from_text = cue_file.GetAnalysisResult(); + // 移除文本解析结果中file_path为空的项目,如果CCueFile::GetAnalysisResult保证file_path不空则这里可以换成断言 + auto new_end = std::remove_if(track_from_text.begin(), track_from_text.end(), + [&](const SongInfo& song_info) { return song_info.file_path.empty(); }); + track_from_text.erase(new_end, track_from_text.end()); + + // 试着修正文件不存在的file_path(这是可选的,但如果切换是否启用那些涉及此功能的现有条目会出问题) + FixErrorCueAudioPath(track_from_text); + + // 此处的false是个预留设置项,用于files中存在cue原始文件时控制cue新增方式 + // true时会移除原有全部音轨并集中添加到cue位置,false时不改变既有音轨位置仅将比现有多出来的音轨添加到cue位置 + bool remove_all{ false && !item.second.front().is_cue }; // 如果second含有cue文件则首个SongInfo.is_cue为false + // 此方法(GetCueTracks)仅维护参数files到SongDataMapKey级别 + // 此处使用track_from_text代换files中的item.second项目,会保证item.second全部移除(或更新) + // 其中音频路径二者有可能不同(若cue有修改(FixErrorCueAudioPath)),故此处靠音轨号匹配 + std::set added_track; // 以此记录添加过的音轨号以抵抗files内的重复(如果有) + // 逆序遍历以使得cue原始文件条目(如果存在)被最后处理 + for (auto it = item.second.rbegin(); it != item.second.rend(); ++it) { - CCueFile cue_file; - cue_file.LoadContentsDirect(cue_contents); - const vector& temp = cue_file.GetAnalysisResult(); - if (temp.empty()) continue; - // temp最后一首缺少end_time且媒体库内不存在 - if (temp.back().end_pos == 0 && (!CSongDataManager::GetInstance().IsItemExist(CSongDataManager::SongDataMapKey{ files[i].file_path, temp.back().track }) || refresh_info)) + auto iter_in_files = std::find_if(files.begin(), files.end(), + [&](const SongInfo& song_info) { return song_info.IsSameSong(*it); }); + ASSERT(iter_in_files != files.end()); + if (iter_in_files == files.end()) continue; // 理论上总能找到,保险起见 + if (iter_in_files->is_cue) { - if (pPlayerCore != nullptr) + auto iter = std::find_if(track_from_text.begin(), track_from_text.end(), + [&](const SongInfo& song_info) { return song_info.track == iter_in_files->track; }); + if (remove_all || iter == track_from_text.end() || added_track.find(iter_in_files->track) != added_track.end()) + files.erase(iter_in_files); + else { - pPlayerCore->GetAudioInfo(files[i].file_path.c_str(), files[i], AF_LENGTH); + // 更新iter_in_files代替对files插入iter + 移除iter_in_files + iter_in_files->file_path = iter->file_path; + audio_path.insert(iter->file_path); + added_track.insert(iter->track); } } - - vector cue_tracks; //储存解析到的cue音轨 - for (int j{}; j < static_cast(temp.size()); ++j) + else // iter_in_files是cue文件,此时将iter_in_files代换为track_from_text中不存在于added_track中的项目 { - cue_tracks.push_back(temp[j]); - auto& cur = cue_tracks.back(); - cur.file_path = files[i].file_path; - if (!CSongDataManager::GetInstance().IsItemExist(cur) || refresh_info) + // 将track_from_text中已存在于added_track的项目排到new_end后面(下面还使用track_from_text所以不能移除) + auto new_end = std::remove_if(track_from_text.begin(), track_from_text.end(), + [&](const SongInfo& song_info) { return added_track.find(song_info.track) != added_track.end(); }); + for (auto iter = track_from_text.begin(); iter != new_end; ++iter) { - if (j == temp.size() - 1 && cur.end_pos == 0) // 最后一首且没有结束时间 - { - cur.end_pos = files[i].length(); - //cur.lengh = cur.end_pos - cur.start_pos; - } - SongInfo song_info{ CSongDataManager::GetInstance().GetSongInfo3(cur) }; - song_info.CopyAudioTag(cur); - song_info.start_pos = cur.start_pos; - //song_info.lengh = cur.lengh; - song_info.end_pos = cur.end_pos; - CSongDataManager::GetInstance().AddItem(song_info); + audio_path.insert(iter->file_path); + added_track.insert(iter->track); // 这里仍然需要维护added_track,以处理cue文件本身重复的情况 } + auto ins_pos = files.erase(iter_in_files); + files.insert(ins_pos, track_from_text.begin(), new_end); } - - //从列表中删除原始音频文件 - files.erase(files.begin() + i); - - // 指示此次需要为index同步files[i]位置曲目数量的增减 - bool before_index{ i < index }; - // 指示此次cue_tracks为索引指定cue,需要index跟踪其第一轨位置 - bool is_index{ i == index }; - - for (const auto& cue_track : cue_tracks) + } + // 判断是否需要获取音频信息,这里将cue作为一个整体,如果需要则刷新全部 + bool need_get_info{ refresh_mode == MR_FOECE_FULL }; + for (SongInfo& song : track_from_text) + { + if (need_get_info) break; + const SongInfo& song_info = CSongDataManager::GetInstance().GetSongInfo3(song); // 这个song_info仅用来确认是否必须刷新 + need_get_info |= (song_info.modified_time == 0 || !song_info.info_acquired || !song_info.ChannelInfoAcquired()); + if (refresh_mode == MR_MIN_REQUIRED) + continue; + // 使用cue修改时间作为SongInfo修改时间(无法发现音频文件需要更新)(但按修改时间排序时比较合适,如需音频修改时间再另加变量) + need_get_info |= (modified_time_cue != song_info.modified_time); + } + if (!need_get_info) + continue; + // 找出每个FILE的最后音轨获取音频属性,以及获取还没有获取修改时间的项目的修改时间 + for (SongInfo& song : track_from_text) + { + if (song.end_pos.toInt() != 0) // 结束时间不为0说明这不是一个FILE的最后一个音轨,跳过 + continue; + // 使用cue修改时间作为SongInfo修改时间(无法发现音频文件需要更新) + song.modified_time = modified_time_cue; + // IPlayerCore::GetAudioInfo只能用于每个FILE的最后一个音轨(会把音频时长直接写入end_pos)(这是预定行为,一个cue可以含有多个FILE) + int flag = AF_LENGTH | AF_BITRATE | AF_CHANNEL_INFO; + CPlayer::GetInstance().GetPlayerCore()->GetAudioInfo(song.file_path.c_str(), song, flag); + bool info_succeed{ song.end_pos.toInt() != 0 }; + for (SongInfo& a : track_from_text) // 这个遍历也包括song自身 { - // 查找当前cue_track是否已存在于files - auto find = std::find_if(files.begin(), files.end(), [&](const SongInfo& song) - { - return song.IsSameSong(cue_track); - }); - if (find == files.end()) - { - // files中不存在当前曲目,将cue_track插入files - files.emplace(files.begin() + i++, cue_track); - if (before_index) - index++; - } - else if (is_index) // 如果此cue的第一轨已存在于files中则将索引调整到其位置 - index = find - files.begin(); - is_index = false; // 仅对cue_tracks[0]修改index + if (a.file_path != song.file_path) // 与song共有FILE的条目应当从song取得其他信息 + continue; + if (!info_succeed) // 获取时长失败则标记此FILE下所有音轨(包括song)为无效条目 + a.end_pos = a.start_pos; + // FILE可能在此次更新中由支持的文件变为不支持的文件所以即使获取时长失败以下项目也总是更新 + a.modified_time = song.modified_time; + a.bitrate = song.bitrate; + a.freq = song.freq; + a.bits = song.bits; + a.channels = song.channels; } - i--; // 解析完一个cue文件后,由于该cue文件已经被移除,所以将循环变量减1 - if (before_index) - index--; } + update_cnt += track_from_text.size(); // cue文件有不同语言版本时这里会反复刷写,这会导致update_cnt大于实际更新数 + // 更新track_from_text中的信息到媒体库 + CSongDataManager::GetInstance().SaveCueSongInfo(track_from_text); + } + // 移除files中的cue关联原始音频文件条目(在这之后才能进行普通音频的处理以避免cue关联音轨进入媒体库) + if (!audio_path.empty()) + { + auto new_end = std::remove_if(files.begin(), files.end(), + [&](const SongInfo& song_info) { return !song_info.is_cue && audio_path.find(song_info.file_path) != audio_path.end(); }); + files.erase(new_end, files.end()); + } +} + +void CAudioCommon::GetAudioInfo(vector& files, int& update_cnt, bool& exit_flag, int& process_percent, MediaLibRefreshMode refresh_mode, bool ignore_short) +{ + // GetCueTracks计算进度太难,直接为其分配5%进度 + process_percent = 5; + GetCueTracks(files, update_cnt, exit_flag, refresh_mode); + int file_too_short_ms{ theApp.m_media_lib_setting_data.file_too_short_sec * 1000 }; + unsigned int process_cnt{}, process_all = max(files.size(), 1); // 防止除0 + std::set too_short_remove; + for (const SongInfo& song : files) + { + if (exit_flag) return; + process_percent = ++process_cnt * 95 / process_all + 5; + // ASSERT(!song.file_path.empty()); // 等到m_playlist可空以后加回来 + if (song.is_cue || song.file_path.empty()) + continue; + SongInfo song_info{ CSongDataManager::GetInstance().GetSongInfo3(song) }; + // 这里的info_acquired和ChannelInfoAcquired是旧版兼容,当时程序不读取这些信息故设置标志位触发更新 + bool need_get_info{ song_info.modified_time == 0 || !song_info.info_acquired || !song_info.ChannelInfoAcquired() }; + if (refresh_mode == MR_MIN_REQUIRED && !need_get_info) + continue; + unsigned __int64 modified_time{}; + if (!CCommon::GetFileLastModified(song_info.file_path, modified_time)) // 跳过当前不存在的文件 + continue; + if (refresh_mode != MR_FOECE_FULL && song_info.modified_time == modified_time && !need_get_info) + continue; + song_info.modified_time = modified_time; + + int flag = AF_LENGTH | AF_BITRATE | AF_CHANNEL_INFO; + if (COSUPlayerHelper::IsOsuFile(song_info.file_path)) + COSUPlayerHelper::GetOSUAudioTitleArtist(song_info); + else + flag |= AF_TAG_INFO; // 原来在这里获取“分级rating”,更改到AF_TAG_INFO中(条件一致) + CPlayer::GetInstance().GetPlayerCore()->GetAudioInfo(song_info.file_path.c_str(), song_info, flag); + + if (ignore_short && song_info.length().toInt() < file_too_short_ms) + too_short_remove.insert(song_info.file_path); + else + { + song_info.info_acquired = true; + song_info.SetChannelInfoAcquired(true); + CSongDataManager::GetInstance().AddItem(song_info); + ++update_cnt; + } + } + // 移除files中过短的音频文件 + if (!too_short_remove.empty()) + { + auto new_end = std::remove_if(files.begin(), files.end(), + [&](const SongInfo& song_info) { return !song_info.is_cue && too_short_remove.find(song_info.file_path) != too_short_remove.end(); }); + files.erase(new_end, files.end()); } } @@ -613,7 +620,7 @@ wstring CAudioCommon::GetBASSChannelDescription(DWORD ctype) switch (ctype) { case 0: - return CCommon::LoadText(IDS_UNKNOW).GetString(); + return theApp.m_str_table.LoadText(L"TXT_FILE_TYPE_UNKNOWN"); // 这里使用的是文件类型描述(File type description)的 “未知”的字符串 case 1: return L"SAMPLE"; case 2: @@ -775,42 +782,6 @@ CString CAudioCommon::TrackToString(BYTE track) } } -void CAudioCommon::ClearDefaultTagStr(SongInfo & song_info) -{ - if (song_info.title == CCommon::LoadText(IDS_DEFAULT_TITLE).GetString()) - song_info.title.clear(); - if (song_info.artist == CCommon::LoadText(IDS_DEFAULT_ARTIST).GetString()) - song_info.artist.clear(); - if (song_info.album == CCommon::LoadText(IDS_DEFAULT_ALBUM).GetString()) - song_info.album.clear(); - //if (song_info.year == CCommon::LoadText(IDS_DEFAULT_YEAR).GetString()) - // song_info.year.clear(); - if (song_info.genre == CCommon::LoadText(IDS_DEFAULT_GENRE).GetString()) - song_info.genre.clear(); -} - -wstring CAudioCommon::GetFileDlgFilter() -{ - wstring filter(CCommon::LoadText(IDS_ALL_SUPPORTED_FORMAT, _T("|"))); - for (const auto& ext : m_all_surpported_extensions) - { - filter += L"*."; - filter += ext; - filter.push_back(L';'); - } - filter.pop_back(); - filter.push_back(L'|'); - for (const auto& format : m_surpported_format) - { - filter += format.description; - filter.push_back(L'|'); - filter += format.extensions_list; - filter.push_back(L'|'); - } - filter += CCommon::LoadText(IDS_ALL_FILES, _T("|*.*||")); - return filter; -} - SupportedFormat CAudioCommon::CreateSupportedFormat(const wchar_t* exts, const wchar_t* description, const wchar_t* file_name /*= L""*/) { SupportedFormat format; diff --git a/MusicPlayer2/AudioCommon.h b/MusicPlayer2/AudioCommon.h index b31030684..4a98a3b29 100644 --- a/MusicPlayer2/AudioCommon.h +++ b/MusicPlayer2/AudioCommon.h @@ -1,12 +1,6 @@ //此类用于定义音频信息相关的全局函数 #pragma once -#include "Time.h" -#include "Common.h" -#include "FilePathHelper.h" -#include "Resource.h" #include "SongInfo.h" -#include "IPlayerCore.h" -#include //音频文件类型 enum AudioType @@ -34,13 +28,24 @@ enum AudioType //排序方式 enum SortMode { - SM_FILE, - SM_PATH, - SM_TITLE, - SM_ARTIST, - SM_ALBUM, - SM_TRACK, - SM_TIME //修改日期 + SM_U_FILE = 0, + SM_D_FILE, + SM_U_PATH, + SM_D_PATH, + SM_U_TITLE, + SM_D_TITLE, + SM_U_ARTIST, + SM_D_ARTIST, + SM_U_ALBUM, + SM_D_ALBUM, + SM_U_TRACK, + SM_D_TRACK, + SM_U_LISTEN, // 累计播放时间 升序 + SM_D_LISTEN, // 累计播放时间 降序 + SM_U_TIME, // 修改日期 升序 + SM_D_TIME, // 修改日期 降序 + + SM_UNSORT = 100, // 未排序(进入播放列表模式时总是设置为此排序方式,且不进行持久化) }; @@ -67,12 +72,7 @@ struct PathInfo int track_num{}; //路径中音频文件的数量 int total_time{}; //路径中音频文件的总时间 bool contain_sub_folder{}; //是否包含子文件夹 - bool descending{}; //是否降序排列 unsigned __int64 last_played_time{}; //上次播放的时间 - - //PathInfo(wstring _path, int _track, int _position, SortMode _sort_mode) : - // path{ _path }, track{ _track }, position{ _position }, sort_mode{ _sort_mode } - //{} }; //循环模式 @@ -87,6 +87,14 @@ enum RepeatMode RM_MAX }; +// 读取音频文件元数据方法GetAudioInfo和GetCueTracks的刷新级别 +enum MediaLibRefreshMode +{ + MR_MIN_REQUIRED, // 仅获取不存在于媒体库的条目(最小化文件读取,最快但不保证最新) + MR_FILE_MODIFICATION, // 重新获取修改时间与媒体库记录不同的条目(需要读取修改时间略耗时) + MR_FOECE_FULL // 强制重新获取所有条目 +}; + struct SupportedFormat //一种支持的音频文件格式 { @@ -124,11 +132,11 @@ class CAudioCommon //查找path目录下的所有歌词文件,并将文件名保存到files容器中 static void GetLyricFiles(wstring path, vector& files); - // 处理files容器中的cue文件,并将每段分轨作为一个曲目添加到files容器中,同时维护播放索引位置 - // 返回files内仅file_path,track,is_cue是保证正确的,其他项目均不可靠 - // 获取到的标签、时长信息已写入媒体库,调用后请从媒体库重新读取 - // refresh_info为true时对媒体库内已存在项目重新获取标签、时长(仅文件夹模式有效) - static void GetCueTracks(vector& files, IPlayerCore* pPlayerCore, int& index, bool refresh_info); + // 处理files内所有cue相关条目的获取信息/拆分/移除关联音频,更新信息到媒体库,仅维护files到可转换SongDataMapKey的程度 + static void GetCueTracks(vector& files, int& update_cnt, bool& exit_flag, MediaLibRefreshMode refresh_mode); + // 处理files内所有条目的获取信息,更新到媒体库(内部调用GetCueTracks),仅维护files到可转换SongDataMapKey的程度 + // ignore_short为true时不保存短歌曲到媒体库且会移除files中的短歌曲(不包含cue) + static void GetAudioInfo(vector& files, int& update_cnt, bool& exit_flag, int& process_percent, MediaLibRefreshMode refresh_mode, bool ignore_short = false); //获得标准流派信息 static wstring GetGenre(BYTE genre); @@ -154,11 +162,6 @@ class CAudioCommon //将音轨序号转换成数字 static CString TrackToString(BYTE track); - //清除歌曲信息中的<>内的默认字符串 - static void ClearDefaultTagStr(SongInfo& song_info); - - static wstring GetFileDlgFilter(); - //返回一个SupportedFormat //exts: 格式的扩展名,多个扩展名用空格分隔 //description:格式的描述 @@ -176,6 +179,6 @@ class CAudioCommon static vector m_all_surpported_extensions; //全部支持的文件格式扩展名 protected: - //获取音频文件的内嵌cue文件,并将每段分轨作为一个曲目添加到files容器中 - static void GetInnerCueTracks(vector& files, IPlayerCore* pPlayerCore, int& index, bool refresh_info); + // 寻找并修复音频路径不正确的cue track,参数是一个cue的文件解析结果 + static void FixErrorCueAudioPath(vector& files); }; diff --git a/MusicPlayer2/AudioTag.cpp b/MusicPlayer2/AudioTag.cpp index 46195a2b8..822fb6d91 100644 --- a/MusicPlayer2/AudioTag.cpp +++ b/MusicPlayer2/AudioTag.cpp @@ -3,6 +3,7 @@ #include "TagLibHelper.h" #include "AudioTagOld.h" #include "CueFile.h" +#include "FilePathHelper.h" CAudioTag::CAudioTag(SongInfo& song_info, HSTREAM hStream) :m_song_info{ song_info }, m_hStream{ hStream } @@ -128,7 +129,6 @@ bool CAudioTag::GetAudioTag() CCommon::StringNormalize(m_song_info.album); CCommon::StringNormalize(m_song_info.genre); CCommon::StringNormalize(m_song_info.comment); - m_song_info.info_acquired = true; return succeed; } diff --git a/MusicPlayer2/AudioTagOld.cpp b/MusicPlayer2/AudioTagOld.cpp index c88a15ada..efa98800a 100644 --- a/MusicPlayer2/AudioTagOld.cpp +++ b/MusicPlayer2/AudioTagOld.cpp @@ -1,5 +1,7 @@ #include "stdafx.h" #include "AudioTagOld.h" +#include "FilePathHelper.h" +#include "Common.h" const string jpg_head{ '\xff', '\xd8', '\xff' }; const string jpg_tail{ '\xff', '\xd9' }; @@ -57,16 +59,14 @@ wstring CAudioTagOld::GetAudioLyric() return wstring(); } -bool CAudioTagOld::WriteMp3Tag(LPCTSTR file_path, const SongInfo & song_info, bool & text_cut_off) +bool CAudioTagOld::WriteMp3Tag(LPCTSTR file_path, SongInfo song_info, bool & text_cut_off) { - string title, artist, album, year, comment; - if (song_info.title != CCommon::LoadText(IDS_DEFAULT_TITLE).GetString()) - title = CCommon::UnicodeToStr(song_info.title, CodeType::ANSI); - if (song_info.artist != CCommon::LoadText(IDS_DEFAULT_ARTIST).GetString()) - artist = CCommon::UnicodeToStr(song_info.artist, CodeType::ANSI); - if (song_info.album != CCommon::LoadText(IDS_DEFAULT_ALBUM).GetString()) - album = CCommon::UnicodeToStr(song_info.album, CodeType::ANSI); - //if (song_info.year != CCommon::LoadText(IDS_DEFAULT_YEAR).GetString()) + song_info.Normalize(); + string title, artist, album, year, comment; + title = CCommon::UnicodeToStr(song_info.title, CodeType::ANSI); + artist = CCommon::UnicodeToStr(song_info.artist, CodeType::ANSI); + album = CCommon::UnicodeToStr(song_info.album, CodeType::ANSI); + year = CCommon::UnicodeToStr(song_info.get_year(), CodeType::ANSI); comment = CCommon::UnicodeToStr(song_info.comment, CodeType::ANSI); TAG_ID3V1 id3{}; diff --git a/MusicPlayer2/AudioTagOld.h b/MusicPlayer2/AudioTagOld.h index c0bdb1009..267e56bc2 100644 --- a/MusicPlayer2/AudioTagOld.h +++ b/MusicPlayer2/AudioTagOld.h @@ -14,7 +14,7 @@ class CAudioTagOld //file_path:mp3文件的路径 //text_cut_off:如果写入的文本长度超过ID3V1可容纳的长度,则过长的文本将会被截断,并将text_cut_off置为true //返回值:成功返回true,否则返回false - static bool WriteMp3Tag(LPCTSTR file_path, const SongInfo& song_info, bool& text_cut_off); + static bool WriteMp3Tag(LPCTSTR file_path, SongInfo song_info, bool& text_cut_off); bool GetTagDefault(); //通过BASS获取标签起始位置手动解析标签 string GetAlbumCoverDefault(int& image_type); //通过BASS获取id3v2标签的位置手动解析专辑封面 diff --git a/MusicPlayer2/BaseDialog.cpp b/MusicPlayer2/BaseDialog.cpp index 0f95577ad..3b61e82f2 100644 --- a/MusicPlayer2/BaseDialog.cpp +++ b/MusicPlayer2/BaseDialog.cpp @@ -3,7 +3,6 @@ #include "stdafx.h" #include "BaseDialog.h" -#include "afxdialogex.h" #include "IniHelper.h" #include "MusicPlayer2.h" @@ -13,19 +12,32 @@ std::map CBaseDialog::m_unique_hwnd; IMPLEMENT_DYNAMIC(CBaseDialog, CDialog) CBaseDialog::CBaseDialog(UINT nIDTemplate, CWnd* pParent /*=NULL*/) - : CDialog(nIDTemplate, pParent) + : CDialog(nIDTemplate, pParent) { - + m_nDialogID = nIDTemplate; } CBaseDialog::~CBaseDialog() { } -void CBaseDialog::SetMinSize(int cx, int cy) +void CBaseDialog::SetBackgroundColor(COLORREF color, BOOL bRepaint) { - m_min_size.cx = cx; - m_min_size.cy = cy; + if (m_brBkgr.GetSafeHandle() != NULL) + { + m_brBkgr.DeleteObject(); + } + + if (color != (COLORREF)-1) + { + m_brBkgr.CreateSolidBrush(color); + } + + if (bRepaint && GetSafeHwnd() != NULL) + { + Invalidate(); + UpdateWindow(); + } } HWND CBaseDialog::GetUniqueHandel(LPCTSTR dlg_name) @@ -49,32 +61,60 @@ void CBaseDialog::CloseAllWindow() void CBaseDialog::LoadConfig() { - if (!GetDialogName().IsEmpty()) - { - CIniHelper ini{ theApp.m_config_path }; - //载入窗口大小设置 - m_window_size.cx = ini.GetInt(_T("window_size"), GetDialogName() + _T("_width"), -1); - m_window_size.cy = ini.GetInt(_T("window_size"), GetDialogName() + _T("_height"), -1); - } + ASSERT(!GetDialogName().IsEmpty()); + ASSERT(IsRememberDialogSizeEnable()); + CIniHelper ini{ theApp.m_config_path }; + //载入窗口大小设置 + m_window_size.cx = ini.GetInt(_T("window_size"), GetDialogName() + _T("_width"), -1); + m_window_size.cy = ini.GetInt(_T("window_size"), GetDialogName() + _T("_height"), -1); } void CBaseDialog::SaveConfig() const { - if (!GetDialogName().IsEmpty()) + ASSERT(!GetDialogName().IsEmpty()); + ASSERT(IsRememberDialogSizeEnable()); + CIniHelper ini{ theApp.m_config_path }; + //保存窗口大小设置 + ini.WriteInt(_T("window_size"), GetDialogName() + _T("_width"), m_window_size.cx); + ini.WriteInt(_T("window_size"), GetDialogName() + _T("_height"), m_window_size.cy); + ini.Save(); +} + +void CBaseDialog::ReLoadLayoutResource() +{ + ASSERT(m_nDialogID); + CMFCDynamicLayout* pDynamicLayout = GetDynamicLayout(); + if (pDynamicLayout) { - CIniHelper ini{ theApp.m_config_path }; - //保存窗口大小设置 - ini.WriteInt(_T("window_size"), GetDialogName() + _T("_width"), m_window_size.cx); - ini.WriteInt(_T("window_size"), GetDialogName() + _T("_height"), m_window_size.cy); - ini.Save(); + HRSRC layoutRes = ::FindResourceW(NULL, MAKEINTRESOURCEW(m_nDialogID), RT_DIALOG_LAYOUT); + if (layoutRes) + { + HGLOBAL hResData = ::LoadResource(NULL, layoutRes); + if (hResData) + { + LPVOID layoutResData = ::LockResource(hResData); + DWORD layoutResSize = ::SizeofResource(NULL, layoutRes); + // std::wstring data(static_cast(layoutResData), layoutResSize / sizeof(wchar_t)); + pDynamicLayout->LoadResource(this, layoutResData, layoutResSize); + } + } } } -void CBaseDialog::SetButtonIcon(UINT id, HICON icon) +void CBaseDialog::SetIcon(IconMgr::IconType type, BOOL bBigIcon) +{ + if (bBigIcon) + CDialog::SetIcon(theApp.m_icon_mgr.GetHICON(type, IconMgr::IconStyle::IS_OutlinedDark, IconMgr::IconSize::IS_ALL), TRUE); + else + CDialog::SetIcon(theApp.m_icon_mgr.GetHICON(type, IconMgr::IconStyle::IS_OutlinedDark, IconMgr::IconSize::IS_DPI_16), FALSE); +} + +void CBaseDialog::SetButtonIcon(UINT id, IconMgr::IconType type) { - CButton* close_btn = (CButton*)(GetDlgItem(id)); + CWnd* dlgItem = GetDlgItem(id); + CButton* close_btn = static_cast(dlgItem); if (close_btn != nullptr) - close_btn->SetIcon(icon); + close_btn->SetIcon(theApp.m_icon_mgr.GetHICON(type, IconMgr::IconStyle::IS_OutlinedDark, IconMgr::IconSize::IS_DPI_16)); } void CBaseDialog::ShowDlgCtrl(UINT id, bool show) @@ -84,16 +124,137 @@ void CBaseDialog::ShowDlgCtrl(UINT id, bool show) pCtrl->ShowWindow(show); } +void CBaseDialog::EnableDlgCtrl(UINT id, bool enable) +{ + CWnd* pCtrl = GetDlgItem(id); + if (pCtrl != nullptr) + pCtrl->EnableWindow(enable); +} + +CRect CBaseDialog::GetTextExtent(const CString& text) +{ + ASSERT(m_pDC != nullptr); // m_pDC由OnInitDialog负责申请释放 + if (m_pDC == nullptr) + return CRect(); + if (text.IsEmpty()) + return CRect(); + CRect text_size; + m_pDC->DrawTextW(text, &text_size, DT_CALCRECT); // 使用CDC::DrawTextW测量文本宽度(CDC::GetTextExtent是理论宽度,不准确) + return text_size; +} + +void CBaseDialog::RepositionTextBasedControls(const vector& items, CtrlTextInfo::Width center_min_width) +{ + ASSERT(m_pDC != nullptr); // 此方法仅在InitializeControls期间可用 + if (m_pDC == nullptr) + return; + int center_width = theApp.DPI(center_min_width); + std::map> col_info; + struct itemInfo + { + int col_index; + CWnd* p; + CRect rect; + }; + vector items_info; + int center_left{ 0 }, center_right{ INT_MAX }; + + for (const auto& item : items) + { + ASSERT(item.col_index != CtrlTextInfo::UN_USE); + ASSERT(item.id != 0); + // 获取所有列所需dx,以及左贴靠元素的右边缘center_left,右贴靠元素的左边缘center_right + CWnd* pItem = GetDlgItem(item.id); + if (pItem == nullptr) + continue; + CRect rect{}; + pItem->GetWindowRect(&rect); + ScreenToClient(&rect); + CString text; + pItem->GetWindowTextW(text); + int dx = GetTextExtent(text).Width() + theApp.DPI(item.ext_width) - rect.Width(); + if (dx < 0) dx = 0; // 文字只增加控件宽度 + if (col_info[item.col_index].first < dx) // 取此列元素中宽度增长最多的 + col_info[item.col_index].first = dx; + if (item.col_index < 0 && center_left < rect.right) + center_left = rect.right; + if (item.col_index > 0 && center_right > rect.left) + center_right = rect.left; + if (item.col_index == 0) // col_index为0的控件可能有多个 + { + if(center_left < rect.left) + center_left = rect.left; + if(center_right > rect.right) + center_right = rect.right; + } + items_info.emplace_back(itemInfo{ item.col_index, pItem, std::move(rect) }); + } + + if (center_right == INT_MAX) // 如果控件全部都是左贴靠的那么以窗口右边缘作为剩余空间的右边缘 + { + CRect dlg_rect{}; + GetClientRect(&dlg_rect); + center_right = dlg_rect.Width(); + } + // 此断言触发说明资源文件中的原始布局没有给中间控件/空闲空间留够宽度 + ASSERT(center_right - center_left >= center_width); + int dx_sum_left{}, dx_sum_right{}; + // 因为同一col_index可以有多个控件&没有要求顺序所以控件的最终位置必须可以无状态的计算出来 + for (auto& a : col_info) + { + if (a.first < 0) + { + a.second.second = dx_sum_left; // 存储此列之前控件的总dx,即此列控件的右移距离 + dx_sum_left += a.second.first; + } + else if (a.first > 0) + { + a.second.second = dx_sum_right; + dx_sum_right += a.second.first; + } + } + float scale{ 1.0f }; + if (center_right - center_left - dx_sum_left - dx_sum_right < center_width) + { + // ASSERT(false); + // 现在加载的文本使此行的中间控件/空闲空间被挤压的太小 + // 这需要重新设计窗口控件排布以适应当前翻译长度,这里先简单的把缺少的空间分摊给各dx + scale = static_cast(center_right - center_left - center_width) / (dx_sum_left + dx_sum_right); + dx_sum_left = static_cast(dx_sum_left * scale + 0.5f); + dx_sum_right = static_cast(dx_sum_right * scale + 0.5f); + } + for (const auto& item : items_info) + { + const auto& rect = item.rect; + int dx = static_cast(col_info[item.col_index].first * scale + 0.5f); + int sum_dx = static_cast(col_info[item.col_index].second * scale + 0.5f); + if (item.col_index < 0) + item.p->SetWindowPos(nullptr, rect.left + sum_dx, rect.top, rect.Width() + dx, rect.Height(), SWP_NOZORDER); + else if (item.col_index > 0) + item.p->SetWindowPos(nullptr, rect.left + sum_dx - dx_sum_right, rect.top, rect.Width() + dx, rect.Height(), SWP_NOZORDER); + else if (item.col_index == 0) + item.p->SetWindowPos(nullptr, rect.left + dx_sum_left, rect.top, rect.Width() - dx_sum_left - dx_sum_right, rect.Height(), SWP_NOZORDER); + } +} + +void CBaseDialog::SetMinSize(int cx, int cy) +{ + m_min_size.cx = cx; + m_min_size.cy = cy; +} + void CBaseDialog::DoDataExchange(CDataExchange* pDX) { - CDialog::DoDataExchange(pDX); + CDialog::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CBaseDialog, CDialog) - ON_WM_DESTROY() - ON_WM_GETMINMAXINFO() - ON_WM_SIZE() + ON_WM_DESTROY() + ON_WM_GETMINMAXINFO() + ON_WM_SIZE() + ON_WM_ERASEBKGND() + ON_WM_CTLCOLOR() END_MESSAGE_MAP() @@ -102,85 +263,168 @@ END_MESSAGE_MAP() BOOL CBaseDialog::OnInitDialog() { - m_unique_hwnd[GetDialogName()] = m_hWnd; - CDialog::OnInitDialog(); + if (!GetDialogName().IsEmpty()) + { + m_unique_hwnd[GetDialogName()] = m_hWnd; + if (IsRememberDialogSizeEnable()) + CBaseDialog::LoadConfig(); // 载入设置 + } - // TODO: 在此添加额外的初始化 + CDialog::OnInitDialog(); - //获取初始时窗口的大小 - if (m_min_size.cx <= 0 || m_min_size.cy <= 0) - { - CRect rect; - GetWindowRect(rect); - m_min_size.cx = rect.Width(); - m_min_size.cy = rect.Height(); - } + // TODO: 在此添加额外的初始化 - //载入设置 - LoadConfig(); + //获取初始时窗口的大小 + if (m_min_size.cx <= 0 || m_min_size.cy <= 0) + { + CRect rect; + GetWindowRect(rect); + m_min_size.cx = rect.Width(); + m_min_size.cy = rect.Height(); + } - //初始化窗口大小 - if (m_window_size.cx > 0 && m_window_size.cy > 0) - { - SetWindowPos(nullptr, 0, 0, m_window_size.cx, m_window_size.cy, SWP_NOZORDER | SWP_NOMOVE); - } + // 通用窗口/控件初始化操作 + // 设置窗口字体 + CCommon::SetDialogFont(this, &theApp.m_font_set.dlg.GetFont()); //为按钮添加图标 - SetButtonIcon(IDCANCEL, theApp.m_icon_set.close.GetIcon(true)); - SetButtonIcon(IDOK, theApp.m_icon_set.ok); + SetButtonIcon(IDCANCEL, IconMgr::IconType::IT_Cancel); + SetButtonIcon(IDOK, IconMgr::IconType::IT_Ok); + // 设置按钮文本 + wstring temp; + temp = theApp.m_str_table.LoadText(L"TXT_OK"); + SetDlgItemTextW(IDOK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_CANCEL"); + SetDlgItemTextW(IDCANCEL, temp.c_str()); + + // 在还原窗口大小之前(当前窗口状态与资源一致),派生类执行控件文本初始化及调整控件排布 + // 与实际窗口大小相关的初始化(比如表格列宽)应在派生类的OnInitDialog进行 + m_pDC = GetDC(); + m_pDC->SelectObject(&theApp.m_font_set.dlg.GetFont()); + bool rtn = InitializeControls(); + ReleaseDC(m_pDC); + m_pDC = nullptr; + // 如果更改了控件排布那么应当返回true以向布局管理器应用控件调整(重新加载动态布局设置) + if (rtn) + ReLoadLayoutResource(); + + //初始化窗口大小 + if (m_window_size.cx > 0 && m_window_size.cy > 0) + { + SetWindowPos(nullptr, 0, 0, m_window_size.cx, m_window_size.cy, SWP_NOZORDER | SWP_NOMOVE); + } - return TRUE; // return TRUE unless you set the focus to a control - // 异常: OCX 属性页应返回 FALSE + return TRUE; // return TRUE unless you set the focus to a control + // 异常: OCX 属性页应返回 FALSE } void CBaseDialog::OnDestroy() { - CDialog::OnDestroy(); + CDialog::OnDestroy(); - // TODO: 在此处添加消息处理程序代码 - m_unique_hwnd[GetDialogName()] = NULL; - SaveConfig(); + // TODO: 在此处添加消息处理程序代码 + if (!GetDialogName().IsEmpty()) + { + m_unique_hwnd[GetDialogName()] = NULL; + if (IsRememberDialogSizeEnable()) + CBaseDialog::SaveConfig(); + } } void CBaseDialog::OnGetMinMaxInfo(MINMAXINFO* lpMMI) { - // TODO: 在此添加消息处理程序代码和/或调用默认值 - //限制窗口最小大小 - lpMMI->ptMinTrackSize.x = m_min_size.cx; //设置最小宽度 - lpMMI->ptMinTrackSize.y = m_min_size.cy; //设置最小高度 + // TODO: 在此添加消息处理程序代码和/或调用默认值 + //限制窗口最小大小 + lpMMI->ptMinTrackSize.x = m_min_size.cx; //设置最小宽度 + lpMMI->ptMinTrackSize.y = m_min_size.cy; //设置最小高度 - CDialog::OnGetMinMaxInfo(lpMMI); + CDialog::OnGetMinMaxInfo(lpMMI); } void CBaseDialog::OnSize(UINT nType, int cx, int cy) { - CDialog::OnSize(nType, cx, cy); + CDialog::OnSize(nType, cx, cy); - // TODO: 在此处添加消息处理程序代码 - if (nType != SIZE_MAXIMIZED && nType != SIZE_MINIMIZED) - { - //m_window_width = cx; - //m_window_hight = cy; - CRect rect; - GetWindowRect(&rect); - m_window_size.cx = rect.Width(); - m_window_size.cy = rect.Height(); - } + // TODO: 在此处添加消息处理程序代码 + if (nType != SIZE_MAXIMIZED && nType != SIZE_MINIMIZED) + { + CRect rect; + GetWindowRect(&rect); + m_window_size.cx = rect.Width(); + m_window_size.cy = rect.Height(); + } } INT_PTR CBaseDialog::DoModal() { - HWND unique_hwnd{ m_unique_hwnd[GetDialogName()] }; - if (unique_hwnd != NULL && !GetDialogName().IsEmpty()) ///如果对话框已存在,则显示已存在的对话框 + if (!GetDialogName().IsEmpty()) { - ::ShowWindow(unique_hwnd, SW_RESTORE); - ::SetForegroundWindow(unique_hwnd); - return 0; + HWND unique_hwnd{ m_unique_hwnd[GetDialogName()] }; + if (unique_hwnd != NULL) ///如果对话框已存在,则显示已存在的对话框 + { + ::ShowWindow(unique_hwnd, SW_RESTORE); + ::SetForegroundWindow(unique_hwnd); + return 0; + } } return CDialog::DoModal(); } + + +BOOL CBaseDialog::OnEraseBkgnd(CDC* pDC) +{ + // 修改窗口背景(CDialogEx) + if (m_brBkgr.GetSafeHandle() != NULL) + { + ASSERT_VALID(pDC); + CRect rectClient; + GetClientRect(rectClient); + pDC->FillRect(rectClient, &m_brBkgr); + return TRUE; + } + return CDialog::OnEraseBkgnd(pDC); +} + + +HBRUSH CBaseDialog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) +{ + // 修改窗口背景(CDialogEx) + if (m_brBkgr.GetSafeHandle() != NULL) + { +#define AFX_MAX_CLASS_NAME 255 +#define AFX_STATIC_CLASS _T("Static") +#define AFX_BUTTON_CLASS _T("Button") +// 上面两个是CDialogEx原有的(因为这两种比较原生,类名不在rc文件中直接出现?),下面是我自己加的 +#define AFX_SLIDER_CLASS _T("msctls_trackbar32") // 滑动条控件CSliderCtrl及其派生类 +#define AFX_SYSLINK_CLASS _T("SysLink") // 超链接控件CSysLink及其派生类 + + if (nCtlColor == CTLCOLOR_STATIC) + { + TCHAR lpszClassName[AFX_MAX_CLASS_NAME + 1]; + + ::GetClassName(pWnd->GetSafeHwnd(), lpszClassName, AFX_MAX_CLASS_NAME); + CString strClass = lpszClassName; + + if (strClass == AFX_BUTTON_CLASS || strClass == AFX_STATIC_CLASS || strClass == AFX_SLIDER_CLASS || strClass == AFX_SYSLINK_CLASS) + { + pDC->SetBkMode(TRANSPARENT); + + if (m_brBkgr.GetSafeHandle() != NULL && IsAppThemed()) + { + return (HBRUSH)m_brBkgr.GetSafeHandle(); + } + else + { + return (HBRUSH)::GetStockObject(HOLLOW_BRUSH); + } + } + } + } + + return CDialog::OnCtlColor(pDC, pWnd, nCtlColor); +} diff --git a/MusicPlayer2/BaseDialog.h b/MusicPlayer2/BaseDialog.h index 8af23bbe1..5d0167e23 100644 --- a/MusicPlayer2/BaseDialog.h +++ b/MusicPlayer2/BaseDialog.h @@ -1,49 +1,91 @@ #pragma once - +#include "IconMgr.h" // CBaseDialog 对话框 -//用于实现记住对话框大小 -//并将窗口初始大小设置为最小大小 class CBaseDialog : public CDialog { - DECLARE_DYNAMIC(CBaseDialog) + DECLARE_DYNAMIC(CBaseDialog) public: - CBaseDialog(UINT nIDTemplate, CWnd* pParent = NULL); // 标准构造函数 - virtual ~CBaseDialog(); + CBaseDialog(UINT nIDTemplate, CWnd* pParent = NULL); // 标准构造函数 + virtual ~CBaseDialog(); -// 对话框数据 -//#ifdef AFX_DESIGN_TIME -// enum { IDD = IDD_BASEDIALOG }; -//#endif + // 复制自CDialogEx,与其功能相同(新增滑动条控件和超链接控件的处理) + void SetBackgroundColor(COLORREF color, BOOL bRepaint = TRUE); - void SetMinSize(int cx, int cy); //设置窗口的最小大小,如果未设置,则使用窗口的初始大小作为最小大小 static HWND GetUniqueHandel(LPCTSTR dlg_name); //获指定窗口唯一的句柄 static const std::map& AllUniqueHandels(); //获取所有窗口的句柄 static void CloseAllWindow(); private: - void LoadConfig(); - void SaveConfig() const; + void LoadConfig(); + void SaveConfig() const; + // 重新应用布局管理器参数,这会使控件的基础大小/位置以当前为准 + void ReLoadLayoutResource(); private: - CSize m_min_size{}; - CSize m_window_size{ -1, -1 }; + UINT m_nDialogID; // 成员变量用于保存资源 ID + CSize m_min_size{}; + CSize m_window_size{ -1, -1 }; + CBrush m_brBkgr; // 在CDialogEx是保护,我改成了私有,我想集中在CBaseDialog处理,如果有需求可以改回去 + CDC* m_pDC = nullptr; // InitializeControls期间有效,用于测量文本长度 + static std::map m_unique_hwnd; //针对每一个派生类的唯一的窗口句柄 -protected: - virtual CString GetDialogName() const = 0; - void SetButtonIcon(UINT id, HICON icon); +public: + void SetIcon(IconMgr::IconType type, BOOL bBigIcon); + void SetButtonIcon(UINT id, IconMgr::IconType type); void ShowDlgCtrl(UINT id, bool show); + void EnableDlgCtrl(UINT id, bool enable); + +protected: + // 仅在InitializeControls期间可用,测量控件文本长度 + CRect GetTextExtent(const CString& text); + + struct CtrlTextInfo + { + // 这里的枚举作为能够类型检查的int使用,三个数字太容易打错很难用,如果要修改请重命名统一修改 + // Col具体值大小无意义,只表示列之间的相对顺序以及哪些控件同一列,实际上没有数量限制,需要的话可以增加 + enum Col { L4 = -4, L3 = -3, L2 = -2, L1 = -1, C0 = 0, R1 = 1, R2 = 2, R3 = 3, R4 = 4, UN_USE = 100 }; + // 按钮因为可能有图标推荐W32,超链接控件因为有额外的所以使用W_50抵消 + enum Width { W_50 = -50, W0 = 0, W16 = 16, W32 = 32, W40 = 40, W60 = 60, W64 = 64, W96 = 96, W128 = 128, W256 = 256 }; + + Col col_index{ UN_USE }; // 指示控件的位置 ,从左向右递增,小于0左贴靠,大于0右贴靠,等于0使用剩余空间 + UINT id{ 0 }; // 控件ID + Width ext_width{ W0 }; // 控件宽度至少需要“文字宽度+ext_width”(内部会执行DPI转换 theApp.DPI(ext_width)) + }; + // 仅在InitializeControls期间可用,根据文本长度重排控件,不会进行任何垂直方向调整,不会改变控件间距 + // 只会增加控件宽度故推荐在资源中设置更小的宽度,使用此方法调整到合适的状态 + // 优先保证中间的剩余宽度(或col_index为0的控件宽度)至少为center_min_width + // 空间不足时其他控件文字会无法完全显示(此时应重新设计窗口)(此方法仅适用于文字不可能太长的情况) + void RepositionTextBasedControls(const vector& items, CtrlTextInfo::Width center_min_width = CtrlTextInfo::W16); + + // 设置窗口的最小大小,如果未设置,则使用窗口的初始大小作为最小大小 + // 请在返回true的InitializeControls调用,使布局管理器能够重新获取新的窗口最小大小 + // CMFCDynamicLayout::SetMinSize的参数与GetWindowRect(含边框)对应,不是m_min_size(不含边框),不通用 + void SetMinSize(int cx, int cy); + + // 此方法返回空字符串时不启用相关功能 + // 返回字符串非空时此字符串作为标识实现记住对话框大小 / 窗口单例 / 统一关闭 + virtual CString GetDialogName() const = 0; + // 当设置DialogName时通过重载此方法返回false实现不保存对话框大小 + virtual bool IsRememberDialogSizeEnable() const { return true; }; + // 由CBaseDialog::OnInitDialog在还原配置中窗口大小前调用 + // 派生类执行部分控件初始化,比如设置控件文本,重排控件RepositionTextBasedControls + // 返回true会重新应用布局管理器参数,这会使控件动态布局管理器的基础大小/位置以当前为准 + // 与实际窗口大小相关的初始化(比如表格列宽)应在派生类的OnInitDialog进行 + virtual bool InitializeControls() { return false; }; // 此处最好是纯虚方法但迁移需要时间 - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 - DECLARE_MESSAGE_MAP() + DECLARE_MESSAGE_MAP() public: - virtual BOOL OnInitDialog(); - afx_msg void OnDestroy(); - afx_msg void OnGetMinMaxInfo(MINMAXINFO* lpMMI); - afx_msg void OnSize(UINT nType, int cx, int cy); + virtual BOOL OnInitDialog(); + afx_msg void OnDestroy(); + afx_msg void OnGetMinMaxInfo(MINMAXINFO* lpMMI); + afx_msg void OnSize(UINT nType, int cx, int cy); virtual INT_PTR DoModal(); + afx_msg BOOL OnEraseBkgnd(CDC* pDC); + afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); }; diff --git a/MusicPlayer2/BassCore.cpp b/MusicPlayer2/BassCore.cpp index df59bcfae..fc81832cd 100644 --- a/MusicPlayer2/BassCore.cpp +++ b/MusicPlayer2/BassCore.cpp @@ -3,6 +3,8 @@ #include "Common.h" #include "AudioCommon.h" #include "MusicPlayer2.h" +#include "Player.h" +#include "CommonDialogMgr.h" CBASSMidiLibrary CBassCore::m_bass_midi_lib; CBassCore::MidiLyricInfo CBassCore::m_midi_lyric; @@ -34,7 +36,7 @@ void CBassCore::InitCore() theApp.m_output_devices.clear(); DeviceInfo device{}; device.index = -1; - device.name = CCommon::LoadText(IDS_DEFAULT_OUTPUT_DEVICE); + device.name = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_DEVICE_NAME_BASS_DEFAULT"); theApp.m_output_devices.push_back(device); while (true) { @@ -78,7 +80,7 @@ void CBassCore::InitCore() //向支持的文件列表插入原生支持的文件格式 CAudioCommon::m_surpported_format.clear(); SupportedFormat format; - format.description = CCommon::LoadText(IDS_BASIC_AUDIO_FORMAT); + format.description = theApp.m_str_table.LoadText(L"TXT_FILE_TYPE_BASE"); format.extensions.insert(format.extensions.end(), theApp.m_nc_setting_data.default_file_type.begin(), theApp.m_nc_setting_data.default_file_type.end()); for (const auto& f : theApp.m_nc_setting_data.default_file_type) { @@ -132,7 +134,7 @@ void CBassCore::InitCore() if (format.description == L"MIDI") { m_bass_midi_lib.Init(plugin_dir + plugin_file); - m_sfont_name = CCommon::LoadText(_T("<"), IDS_NONE, _T(">")); + m_sfont_name = theApp.m_str_table.LoadText(L"UI_TXT_SF2_NAME_NONE"); m_sfont.font = 0; if (m_bass_midi_lib.IsSucceed()) { @@ -149,10 +151,9 @@ void CBassCore::InitCore() m_sfont.font = m_bass_midi_lib.BASS_MIDI_FontInit(sf2_path.c_str(), BASS_UNICODE); if (m_sfont.font == 0) { - CString info; - info = CCommon::LoadTextFormat(IDS_SOUND_FONT_LOAD_FAILED, { sf2_path }); - theApp.WriteLog(info.GetString()); - m_sfont_name = CCommon::LoadText(_T("<"), IDS_LOAD_FAILED, _T(">")); + wstring info = theApp.m_str_table.LoadTextFormat(L"LOG_SF2_LOAD_FAILED", { sf2_path }); + theApp.WriteLog(info); + m_sfont_name = theApp.m_str_table.LoadText(L"UI_TXT_SF2_NAME_FAILDE"); } else { @@ -271,7 +272,7 @@ void CBassCore::GetBASSAudioInfo(HSTREAM hStream, SongInfo & song_info, int flag { //获取长度 if (flag&AF_LENGTH) - song_info.setLength(CBassCore::GetBASSSongLength(hStream)); + song_info.end_pos = CBassCore::GetBASSSongLength(hStream); //获取比特率 if(flag&AF_BITRATE) { @@ -292,6 +293,7 @@ void CBassCore::GetBASSAudioInfo(HSTREAM hStream, SongInfo & song_info, int flag { CAudioTag audio_tag(song_info, hStream); audio_tag.GetAudioTag(); + audio_tag.GetAudioRating(); //获取midi音乐的标题 if (CBassCore::m_bass_midi_lib.IsSucceed() && audio_tag.GetAudioType() == AU_MIDI) { @@ -299,7 +301,6 @@ void CBassCore::GetBASSAudioInfo(HSTREAM hStream, SongInfo & song_info, int flag if (CBassCore::m_bass_midi_lib.BASS_MIDI_StreamGetMark(hStream, BASS_MIDI_MARK_TRACK, 0, &mark) && !mark.track) { song_info.title = CCommon::StrToUnicode(mark.text); - song_info.info_acquired = true; } } } @@ -532,8 +533,7 @@ bool CBassCore::EncodeAudio(SongInfo song_info, const wstring& dest_file_path, E HSTREAM hStream = BASS_StreamCreateFile(FALSE, song_info.file_path.c_str(), 0, 0, BASS_STREAM_DECODE/* | BASS_SAMPLE_FLOAT*/); if (hStream == 0) { - //::PostMessage(pthis->GetSafeHwnd(), WM_CONVERT_PROGRESS, file_index, CONVERT_ERROR_FILE_CONNOT_OPEN); - proc(CONVERT_ERROR_FILE_CONNOT_OPEN); + proc(CONVERT_ERROR_FILE_CANNOT_OPEN); return false; } @@ -673,23 +673,19 @@ bool CBassCore::EncodeAudio(SongInfo song_info, const wstring& dest_file_path, E //如果出现了错误,则写入错误日志 if (error != 0) { - CString log_str; - log_str = CCommon::LoadTextFormat(IDS_CONVERT_WMA_ERROR, { song_info.file_path }); + wstring log_str = theApp.m_str_table.LoadTextFormat(L"LOG_BASS_FORMAT_CONVERT_ERROR", { song_info.file_path, L"WMA", error }); + theApp.WriteLog(log_str); switch (error) { case BASS_ERROR_WMA: - log_str += CCommon::LoadText(IDS_NO_WMP9_OR_LATER); error_code = CONVERT_ERROR_WMA_NO_WMP9_OR_LATER; break; case BASS_ERROR_NOTAVAIL: - log_str += CCommon::LoadText(IDS_NO_SUPPORTED_ENCODER_WARNING); error_code = CONVERT_ERROR_WMA_NO_SUPPORTED_ENCODER; break; default: - log_str += CCommon::LoadText(IDS_UNKNOW_ERROR); break; } - theApp.WriteLog(wstring(log_str)); } if (hEncode == 0) { @@ -758,9 +754,9 @@ bool CBassCore::EncodeAudio(SongInfo song_info, const wstring& dest_file_path, E if (encode_format == EncodeFormat::MP3) { CFilePathHelper out_file_path_helper{ dest_file_path }; - CCommon::MoveAFile(AfxGetMainWnd()->GetSafeHwnd(), out_file_path_temp, out_file_path_helper.GetDir()); + CommonDialogMgr::MoveAFile(AfxGetMainWnd()->GetSafeHwnd(), out_file_path_temp, out_file_path_helper.GetDir()); if (CCommon::FileExist(out_file_path_helper.GetFilePath())) - CCommon::DeleteAFile(AfxGetMainWnd()->GetSafeHwnd(), out_file_path_helper.GetFilePath()); + CommonDialogMgr::DeleteAFile(AfxGetMainWnd()->GetSafeHwnd(), out_file_path_helper.GetFilePath()); CCommon::FileRename(out_file_path_helper.GetDir() + CONVERTING_TEMP_FILE_NAME, out_file_path_helper.GetFileName()); } return true; @@ -880,16 +876,17 @@ int CBassCore::GetErrorCode() std::wstring CBassCore::GetErrorInfo(int error_code) { - CString info = CCommon::LoadTextFormat(IDS_BASS_ERROR_LOG_INFO, { error_code, m_file_path }); - return std::wstring(info); + // 这个方法获取写入错误日志的字符串,后面会附加CPlayer的方法名 + wstring info = theApp.m_str_table.LoadTextFormat(L"LOG_BASS_ERROR", { error_code, m_file_path }); + return info; } std::wstring CBassCore::GetErrorInfo() { - CString info = CCommon::LoadText(IDS_ERROR_CODE, _T(": ")); + // 这个方法获取错误时状态栏显示的错误字符串“播放出错: <%1%>” int error_code = BASS_ErrorGetCode(); - info += std::to_wstring(error_code).c_str(); - return std::wstring(info); + wstring info = theApp.m_str_table.LoadTextFormat(L"UI_TXT_PLAYSTATUS_ERROR_CORE_BASS", { error_code }); + return info; } //int CBassCore::GetDeviceCount() diff --git a/MusicPlayer2/BrowseEdit.cpp b/MusicPlayer2/BrowseEdit.cpp index ca5e50e09..def37d6c0 100644 --- a/MusicPlayer2/BrowseEdit.cpp +++ b/MusicPlayer2/BrowseEdit.cpp @@ -5,7 +5,7 @@ #include "BrowseEdit.h" #include "MusicPlayer2.h" #include "DrawCommon.h" -#include "TagFromFileNameDlg.h" +#include "FileNameFormDlg.h" #include "EditStringListDlg.h" // CBrowseEdit @@ -26,7 +26,7 @@ void CBrowseEdit::OnDrawBrowseButton(CDC * pDC, CRect rect, BOOL bIsButtonPresse //使用双缓冲绘图 CDrawDoubleBuffer drawDoubleBuffer(pDC, rect); CDrawCommon drawer; - drawer.Create(drawDoubleBuffer.GetMemDC(), this); + drawer.Create(drawDoubleBuffer.GetMemDC(), GetFont()); CRect rc_draw{ rect }; rc_draw.MoveToXY(0, 0); @@ -60,19 +60,23 @@ void CBrowseEdit::OnDrawBrowseButton(CDC * pDC, CRect rect, BOOL bIsButtonPresse drawer.GetDC()->FillSolidRect(rc_draw, btn_color); } - auto& icon = GetIcon(); - CSize icon_size = icon.GetSize(); + IconMgr::IconType icon_type = IconMgr::IconType::IT_Folder; + if (m_Mode == BrowseMode_Default) + icon_type = IconMgr::IconType::IT_Edit; + + HICON hIcon = theApp.m_icon_mgr.GetHICON(icon_type, IconMgr::IconStyle::IS_OutlinedDark, IconMgr::IconSize::IS_DPI_16); + CSize icon_size = theApp.m_icon_mgr.GetIconSize(IconMgr::IconSize::IS_DPI_16); CPoint icon_top_left; icon_top_left.x = rc_draw.left + theApp.DPI(4); icon_top_left.y = rc_draw.top + (rc_draw.Height() - icon_size.cy) / 2; - drawer.DrawIcon(icon.GetIcon(true), icon_top_left, icon_size); + drawer.DrawIcon(hIcon, icon_top_left, icon_size); CRect rc_text = rc_draw; rc_text.left += theApp.DPI(20); COLORREF text_color = CColorConvert::m_gray_color.dark4; if (!IsWindowEnabled()) text_color = CColorConvert::m_gray_color.dark1; - drawer.DrawWindowText(rc_text, m_btn_str, text_color, Alignment::CENTER, true); + drawer.DrawWindowText(rc_text, m_btn_str.c_str(), text_color, Alignment::CENTER, true); } @@ -82,31 +86,26 @@ void CBrowseEdit::OnChangeLayout() ENSURE(GetSafeHwnd() != NULL); int btn_width; - CDrawCommon drawer; - drawer.Create(m_pDC, this); if (m_Mode == BrowseMode_Default) - { - //if (m_browse_mode == EditBrowseMode::RENAME) - m_btn_str = CCommon::LoadText(IDS_EDIT, _T("...")); - //else - // m_btn_str = _T(""); - } + m_btn_str = theApp.m_str_table.LoadText(L"TXT_BROWSE_EDIT_EDIT"); else - { - m_btn_str = CCommon::LoadText(IDS_BROWSE, _T("...")); - } + m_btn_str = theApp.m_str_table.LoadText(L"TXT_BROWSE_EDIT_BROWSE"); //如果编辑框的宽度小于一定值,则不显示按钮后面的文本 CRect rect_client; GetClientRect(rect_client); if (rect_client.Width() < theApp.DPI(120)) { - m_btn_str = _T(""); + m_btn_str = L""; btn_width = theApp.DPI(24); } else { - btn_width = drawer.GetTextExtent(m_btn_str).cx + theApp.DPI(28); + CDC* pDC = GetDC(); // OnChangeLayout仅在设置浏览模式时被调用,不需要保持DC + CDrawCommon drawer; + drawer.Create(pDC, GetFont()); + btn_width = drawer.GetTextExtent(m_btn_str.c_str()).cx + theApp.DPI(28); + ReleaseDC(pDC); } m_nBrowseButtonWidth = max(btn_width, m_sizeImage.cx + 8); @@ -207,10 +206,9 @@ void CBrowseEdit::OnBrowse() { CString strFile; GetWindowText(strFile); - - CTagFromFileNameDlg dlg; + // 这里无视m_poopup_dlg_title设置的对话框标题,如果有必要再加 + CFileNameFormDlg dlg; dlg.SetInitInsertFormular(strFile.GetString()); - dlg.SetDialogTitle(m_poopup_dlg_title.IsEmpty() ? CCommon::LoadText(IDS_SET_FILENAME_FORM) : m_poopup_dlg_title); if (dlg.DoModal() == IDOK && strFile != dlg.GetFormularSelected().c_str()) { @@ -242,8 +240,13 @@ void CBrowseEdit::OnBrowse() SetModify(TRUE); OnAfterUpdate(); } + + if (GetParent() != NULL) + { + GetParent()->RedrawWindow(NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN); + } } - break; + break; case CBrowseEdit::EditBrowseMode::LIST2: { // 列表模式2 下,将编辑框的文本用""包裹后以逗号分隔后以列表的形式编辑 @@ -261,9 +264,15 @@ void CBrowseEdit::OnBrowse() SetModify(TRUE); OnAfterUpdate(); } + + if (GetParent() != NULL) + { + GetParent()->RedrawWindow(NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN); + } } - break; + break; default: + ASSERT(false); break; } @@ -287,53 +296,17 @@ void CBrowseEdit::SetEditBrowseMode(EditBrowseMode browse_mode) EnableBrowseButton(TRUE); //将基类的编辑模式改成BrowseMode_Default } -void CBrowseEdit::SetPopupDlgTitle(const CString& popup_dlg_title) +void CBrowseEdit::SetPopupDlgTitle(const wstring& popup_dlg_title) { - m_poopup_dlg_title = popup_dlg_title; -} - -IconRes& CBrowseEdit::GetIcon() -{ - if (m_Mode == BrowseMode_Default) - { - //if (m_browse_mode == EditBrowseMode::RENAME) - return theApp.m_icon_set.edit; - //else - // return theApp. - } - else - { - return theApp.m_icon_set.select_folder; - } + m_poopup_dlg_title = popup_dlg_title.c_str(); } BEGIN_MESSAGE_MAP(CBrowseEdit, CMFCEditBrowseCtrl) - ON_WM_DESTROY() ON_WM_NCLBUTTONDOWN() ON_MESSAGE(WM_TABLET_QUERYSYSTEMGESTURESTATUS, &CBrowseEdit::OnTabletQuerysystemgesturestatus) END_MESSAGE_MAP() - - -void CBrowseEdit::PreSubclassWindow() -{ - // TODO: 在此添加专用代码和/或调用基类 - m_pDC = GetDC(); - - CMFCEditBrowseCtrl::PreSubclassWindow(); -} - - -void CBrowseEdit::OnDestroy() -{ - CMFCEditBrowseCtrl::OnDestroy(); - - // TODO: 在此处添加消息处理程序代码 - ReleaseDC(m_pDC); -} - - void CBrowseEdit::OnNcLButtonDown(UINT nHitTest, CPoint point) { if (HTCAPTION == nHitTest) diff --git a/MusicPlayer2/BrowseEdit.h b/MusicPlayer2/BrowseEdit.h index 0b481dde5..5d75635a6 100644 --- a/MusicPlayer2/BrowseEdit.h +++ b/MusicPlayer2/BrowseEdit.h @@ -28,23 +28,18 @@ class CBrowseEdit : public CMFCEditBrowseCtrl virtual void OnBrowse() override; virtual void OnAfterUpdate() override; void SetEditBrowseMode(EditBrowseMode browse_mode); - void SetPopupDlgTitle(const CString& popup_dlg_title); + void SetPopupDlgTitle(const wstring& popup_dlg_title); protected: DECLARE_MESSAGE_MAP() - IconRes& GetIcon(); - private: ColorTable& m_theme_color; - CString m_btn_str; - CDC* m_pDC{}; + wstring m_btn_str; EditBrowseMode m_browse_mode; //自定义的编辑模式,当基类的m_Mode设置为BrowseMode_Default时使用 CString m_poopup_dlg_title; //弹出对话框的标题 - virtual void PreSubclassWindow(); public: - afx_msg void OnDestroy(); afx_msg void OnNcLButtonDown(UINT nHitTest, CPoint point); protected: afx_msg LRESULT OnTabletQuerysystemgesturestatus(WPARAM wParam, LPARAM lParam); diff --git a/MusicPlayer2/CDonateDlg.cpp b/MusicPlayer2/CDonateDlg.cpp index 6c68e224a..c0b927ab4 100644 --- a/MusicPlayer2/CDonateDlg.cpp +++ b/MusicPlayer2/CDonateDlg.cpp @@ -4,15 +4,14 @@ #include "stdafx.h" #include "MusicPlayer2.h" #include "CDonateDlg.h" -#include "afxdialogex.h" // CDonateDlg 对话框 -IMPLEMENT_DYNAMIC(CDonateDlg, CDialogEx) +IMPLEMENT_DYNAMIC(CDonateDlg, CBaseDialog) CDonateDlg::CDonateDlg(CWnd* pParent /*=nullptr*/) - : CDialogEx(IDD_DONATE_DIALOG, pParent) + : CBaseDialog(IDD_DONATE_DIALOG, pParent) { } @@ -21,14 +20,35 @@ CDonateDlg::~CDonateDlg() { } +CString CDonateDlg::GetDialogName() const +{ + return L"DonateDlg"; +} + +bool CDonateDlg::InitializeControls() +{ + wstring temp; + temp = theApp.m_str_table.LoadText(L"TITLE_DONATE"); + SetWindowTextW(temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_DONATE_INFO"); + SetDlgItemTextW(IDC_DONATE_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_CLOSE"); + SetDlgItemTextW(IDCANCEL, temp.c_str()); + + RepositionTextBasedControls({ + { CtrlTextInfo::R1, IDCANCEL, CtrlTextInfo::W32 } + }); + return true; +} + void CDonateDlg::DoDataExchange(CDataExchange* pDX) { - CDialogEx::DoDataExchange(pDX); + CBaseDialog::DoDataExchange(pDX); } -BEGIN_MESSAGE_MAP(CDonateDlg, CDialogEx) - ON_WM_PAINT() +BEGIN_MESSAGE_MAP(CDonateDlg, CBaseDialog) + ON_WM_PAINT() END_MESSAGE_MAP() @@ -37,9 +57,10 @@ END_MESSAGE_MAP() BOOL CDonateDlg::OnInitDialog() { - CDialogEx::OnInitDialog(); + CBaseDialog::OnInitDialog(); + + // TODO: 在此添加额外的初始化 - // TODO: 在此添加额外的初始化 //计算两个二维码图片的位置 CRect rect{}; CWnd* pWnd = nullptr; @@ -68,19 +89,19 @@ BOOL CDonateDlg::OnInitDialog() m_pic2_rect = rc_pic_area; m_pic2_rect.left = m_pic2_rect.right - (rc_pic_area.Width() / 2) + theApp.DPI(4); - return TRUE; // return TRUE unless you set the focus to a control - // 异常: OCX 属性页应返回 FALSE + return TRUE; // return TRUE unless you set the focus to a control + // 异常: OCX 属性页应返回 FALSE } void CDonateDlg::OnPaint() { - CPaintDC dc(this); // device context for painting - // TODO: 在此处添加消息处理程序代码 - // 不为绘图消息调用 CDialogEx::OnPaint() + CPaintDC dc(this); // device context for painting + // TODO: 在此处添加消息处理程序代码 + // 不为绘图消息调用 CDialogEx::OnPaint() - CDrawCommon draw; - draw.Create(&dc, this); + CDrawCommon draw; + draw.Create(&dc); draw.DrawBitmap(IDB_DONATE, m_pic1_rect.TopLeft(), m_pic1_rect.Size(), CDrawCommon::StretchMode::FIT); draw.DrawBitmap(IDB_DONATE_WECHAT, m_pic2_rect.TopLeft(), m_pic2_rect.Size(), CDrawCommon::StretchMode::FIT); } diff --git a/MusicPlayer2/CDonateDlg.h b/MusicPlayer2/CDonateDlg.h index 254bc6e5f..20ec6fa7c 100644 --- a/MusicPlayer2/CDonateDlg.h +++ b/MusicPlayer2/CDonateDlg.h @@ -1,19 +1,19 @@ #pragma once - +#include "BaseDialog.h" // CDonateDlg 对话框 -class CDonateDlg : public CDialogEx +class CDonateDlg : public CBaseDialog { - DECLARE_DYNAMIC(CDonateDlg) + DECLARE_DYNAMIC(CDonateDlg) public: - CDonateDlg(CWnd* pParent = nullptr); // 标准构造函数 - virtual ~CDonateDlg(); + CDonateDlg(CWnd* pParent = nullptr); // 标准构造函数 + virtual ~CDonateDlg(); // 对话框数据 #ifdef AFX_DESIGN_TIME - enum { IDD = IDD_DONATE_DIALOG }; + enum { IDD = IDD_DONATE_DIALOG }; #endif private: @@ -21,10 +21,13 @@ class CDonateDlg : public CDialogEx CRect m_pic2_rect; protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 + virtual CString GetDialogName() const override; + virtual bool IsRememberDialogSizeEnable() const { return false; }; + virtual bool InitializeControls() override; + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 - DECLARE_MESSAGE_MAP() + DECLARE_MESSAGE_MAP() public: - virtual BOOL OnInitDialog(); - afx_msg void OnPaint(); + virtual BOOL OnInitDialog(); + afx_msg void OnPaint(); }; diff --git a/MusicPlayer2/CFloatPlaylistDlg.cpp b/MusicPlayer2/CFloatPlaylistDlg.cpp index 596886661..e7b17de84 100644 --- a/MusicPlayer2/CFloatPlaylistDlg.cpp +++ b/MusicPlayer2/CFloatPlaylistDlg.cpp @@ -4,18 +4,17 @@ #include "stdafx.h" #include "MusicPlayer2.h" #include "CFloatPlaylistDlg.h" -#include "afxdialogex.h" #include "MusicPlayerDlg.h" // CFloatPlaylistDlg 对话框 -IMPLEMENT_DYNAMIC(CFloatPlaylistDlg, CDialog) +IMPLEMENT_DYNAMIC(CFloatPlaylistDlg, CBaseDialog) CFloatPlaylistDlg::CFloatPlaylistDlg(int& item_selected, vector& items_selected, CWnd* pParent /*=nullptr*/) - : CDialog(IDD_MUSICPLAYER2_DIALOG, pParent), m_item_selected{ item_selected }, m_items_selected{ items_selected } + : CBaseDialog(IDD_MUSICPLAYER2_DIALOG, pParent), m_item_selected{ item_selected }, m_items_selected{ items_selected }, m_playlist_ctrl{ CPlayer::GetInstance().GetPlayList() } { - m_path_edit.SetTooltopText(CCommon::LoadText(IDS_RECENT_FOLDER_OR_PLAYLIST)); + m_path_edit.SetTooltopText(theApp.m_str_table.LoadText(L"UI_TIP_BTN_RECENT_FOLDER_OR_PLAYLIST").c_str()); } CFloatPlaylistDlg::~CFloatPlaylistDlg() @@ -32,74 +31,49 @@ void CFloatPlaylistDlg::RefreshData() //播放列表模式下,播放列表工具栏第一个菜单为“添加”,文件夹模式下为“文件夹” if (CPlayer::GetInstance().IsPlaylistMode()) { - m_playlist_toolbar.ModifyToolButton(0, theApp.m_icon_set.add, CCommon::LoadText(IDS_ADD), CCommon::LoadText(IDS_ADD), theApp.m_menu_set.m_playlist_toolbar_menu.GetSubMenu(0), true); + const wstring& menu_str = theApp.m_str_table.LoadText(L"UI_TXT_PLAYLIST_TOOLBAR_ADD"); + m_playlist_toolbar.ModifyToolButton(0, IconMgr::IconType::IT_Add, menu_str.c_str(), menu_str.c_str(), theApp.m_menu_mgr.GetMenu(MenuMgr::MainPlaylistAddMenu), true); } else { - m_playlist_toolbar.ModifyToolButton(0, theApp.m_icon_set.select_folder, CCommon::LoadText(IDS_FOLDER), CCommon::LoadText(IDS_FOLDER), theApp.m_menu_set.m_playlist_toolbar_menu.GetSubMenu(5), true); + const wstring& menu_str = theApp.m_str_table.LoadText(L"UI_TXT_PLAYLIST_TOOLBAR_FOLDER"); + m_playlist_toolbar.ModifyToolButton(0, IconMgr::IconType::IT_Folder, menu_str.c_str(), menu_str.c_str(), theApp.m_menu_mgr.GetMenu(MenuMgr::PlaylistToolBarFolderMenu), true); } m_playlist_ctrl.SetCurSel(-1); } void CFloatPlaylistDlg::ReSizeControl(int cx, int cy) { - //设置“当前路径”static控件大小 - CRect rect_static; - m_path_static.GetWindowRect(rect_static); - rect_static.bottom = rect_static.top + m_layout.search_edit_height; - rect_static.MoveToXY(m_layout.margin, m_layout.margin); - m_path_static.MoveWindow(rect_static); + CRect rect_base{ m_layout.margin, m_layout.margin, cx - m_layout.margin, cy - m_layout.margin }; - //计算“媒体库”按钮的宽度 - CDrawCommon draw; - CDC* pDC = GetDC(); - draw.Create(pDC, this); - CString media_lib_btn_str; - m_set_path_button.GetWindowText(media_lib_btn_str); - int media_lib_btn_width = draw.GetTextExtent(media_lib_btn_str).cx; - if (media_lib_btn_width < theApp.DPI(70)) - media_lib_btn_width = theApp.DPI(70); - media_lib_btn_width += theApp.DPI(20); - ReleaseDC(pDC); - - //设置“选择文件夹”的大小和位置 - CRect rect_select_folder{ rect_static }; - rect_select_folder.right = cx - m_layout.margin; - rect_select_folder.left = rect_select_folder.right - media_lib_btn_width; - m_set_path_button.MoveWindow(rect_select_folder); - - //设置“当前路径”edit控件大小和位置 - CRect rect_edit; - m_path_edit.GetWindowRect(rect_edit); - rect_edit.MoveToY(rect_select_folder.top + (rect_select_folder.Height() - rect_edit.Height()) / 2); - rect_edit.left = rect_static.right + m_layout.margin; - rect_edit.right = rect_select_folder.left - m_layout.margin; + // 设置IDC_PATH_STATIC/IDC_PATH_EDIT/ID_MEDIA_LIB的位置和大小 + int edit_height = m_layout.path_edit_height; + CRect rect_static{ rect_base.left, rect_base.top, rect_base.left + max(m_part_static_playlist_width, m_part_static_folder_width), rect_base.top + edit_height }; + CRect rect_media_lib{ rect_base.right - m_medialib_btn_width, rect_base.top - 1, rect_base.right, rect_base.top + edit_height + 1 }; + CRect rect_edit{ rect_static.right + m_layout.margin, rect_base.top, rect_media_lib.left - m_layout.margin, rect_base.top + edit_height }; + m_path_static.MoveWindow(rect_static); m_path_edit.MoveWindow(rect_edit); - - //设置搜索控件的大小和位置 - CRect rect_search{ }; - rect_search.top = 2 * m_layout.margin + m_layout.search_edit_height; - rect_search.left = m_layout.margin; - rect_search.right = cx - m_layout.margin; - rect_search.bottom = rect_search.top + m_layout.search_edit_height; + m_media_lib_button.MoveWindow(rect_media_lib); + + rect_base.top += edit_height + m_layout.margin; + //设置歌曲搜索框的大小和位置 + CRect rect_search; + m_search_edit.GetWindowRect(rect_search); + int search_height = rect_search.Height(); + rect_search = { rect_base.left, rect_base.top, rect_base.right, rect_base.top + search_height }; m_search_edit.MoveWindow(rect_search); - CRect rect_toolbar{ rect_search }; - rect_toolbar.top = rect_search.bottom + m_layout.margin; - rect_toolbar.right = rect_search.right; - rect_toolbar.bottom = rect_toolbar.top + m_layout.toolbar_height; + rect_base.top += search_height + m_layout.margin; + //设置播放列表工具栏的大小位置 + int toolbar_height = m_layout.toolbar_height; + CRect rect_toolbar{ rect_base.left, rect_base.top, rect_base.right, rect_base.top + toolbar_height }; m_playlist_toolbar.MoveWindow(rect_toolbar); m_playlist_toolbar.Invalidate(); - // - CRect rect_playlist; - rect_playlist.top = rect_toolbar.bottom + m_layout.margin; - rect_playlist.left = m_layout.margin; - rect_playlist.right = cx - m_layout.margin; - rect_playlist.bottom = cy - m_layout.margin; - m_playlist_ctrl.MoveWindow(rect_playlist); + rect_base.top += toolbar_height + m_layout.margin; + // 设置播放列表控件大小和位置(即rect_base剩余空间) + m_playlist_ctrl.MoveWindow(rect_base); m_playlist_ctrl.AdjustColumnWidth(); - } void CFloatPlaylistDlg::RefreshState(bool highlight_visible) @@ -157,8 +131,7 @@ void CFloatPlaylistDlg::EnableControl(bool enable) { m_playlist_ctrl.EnableWindow(enable); m_search_edit.EnableWindow(enable); - m_set_path_button.EnableWindow(enable); - //m_clear_search_button.EnableWindow(enable); + m_media_lib_button.EnableWindow(enable); m_playlist_toolbar.EnableWindow(enable); m_playlist_toolbar.Invalidate(); } @@ -185,31 +158,58 @@ void CFloatPlaylistDlg::SetInitPoint(CPoint point) bool CFloatPlaylistDlg::Initilized() const { return m_playlist_ctrl.GetSafeHwnd() != NULL && m_path_static.GetSafeHwnd() != NULL && m_path_edit.GetSafeHwnd() != NULL - && m_set_path_button.GetSafeHwnd() != NULL && m_search_edit.GetSafeHwnd() != NULL/* && m_clear_search_button.GetSafeHwnd() != NULL*/; + && m_media_lib_button.GetSafeHwnd() != NULL && m_search_edit.GetSafeHwnd() != NULL/* && m_clear_search_button.GetSafeHwnd() != NULL*/; +} + +CString CFloatPlaylistDlg::GetDialogName() const +{ + return CString(); +} + +bool CFloatPlaylistDlg::InitializeControls() +{ + // 设置最小窗口大小(为需要容纳可能较长的控件文本,调整最小宽度到与主窗口一致) + SetMinSize(theApp.DPI(340), theApp.DPI(228)); + // 设置窗口标题 + SetWindowTextW(theApp.m_str_table.LoadText(L"TXT_PLAYLIST").c_str()); + // 测量受翻译字符串影响的控件所需宽度,并应用翻译字符串到控件 + CString text; + // "播放列表:"宽度(含图标) + text = theApp.m_str_table.LoadText(L"UI_TXT_PLAYLIST").c_str(); + int playlist_width = (std::min)(GetTextExtent(text).Width() + theApp.DPI(20), theApp.DPI(150)); + m_part_static_playlist_width = (std::max)(m_part_static_playlist_width, playlist_width); + // "文件夹:"宽度(含图标) + text = theApp.m_str_table.LoadText(L"UI_TXT_FOLDER").c_str(); + m_path_static.SetWindowTextW(text); + int folder_width = (std::min)(GetTextExtent(text).Width() + theApp.DPI(20), theApp.DPI(150)); + m_part_static_folder_width = (std::max)(m_part_static_folder_width, folder_width); + // 媒体库按钮宽度 + text = theApp.m_str_table.LoadText(L"UI_TXT_BTN_MEDIA_LIB").c_str(); + m_media_lib_button.SetWindowTextW(text); + int media_lib_width = (std::min)(GetTextExtent(text).Width() + theApp.DPI(40), theApp.DPI(150)); + m_medialib_btn_width = (std::max)(m_medialib_btn_width, media_lib_width); + + return true; } void CFloatPlaylistDlg::DoDataExchange(CDataExchange* pDX) { - CDialog::DoDataExchange(pDX); + CBaseDialog::DoDataExchange(pDX); DDX_Control(pDX, IDC_PLAYLIST_LIST, m_playlist_ctrl); DDX_Control(pDX, IDC_PATH_STATIC, m_path_static); DDX_Control(pDX, IDC_PATH_EDIT, m_path_edit); - DDX_Control(pDX, ID_SET_PATH, m_set_path_button); + DDX_Control(pDX, ID_MEDIA_LIB, m_media_lib_button); DDX_Control(pDX, IDC_SEARCH_EDIT, m_search_edit); - //DDX_Control(pDX, IDC_CLEAR_SEARCH_BUTTON, m_clear_search_button); DDX_Control(pDX, IDC_PLAYLIST_TOOLBAR, m_playlist_toolbar); - DDX_Control(pDX, IDC_HSPLITER_STATIC, m_splitter_ctrl); } -BEGIN_MESSAGE_MAP(CFloatPlaylistDlg, CDialog) +BEGIN_MESSAGE_MAP(CFloatPlaylistDlg, CBaseDialog) ON_WM_SIZE() ON_NOTIFY(NM_RCLICK, IDC_PLAYLIST_LIST, &CFloatPlaylistDlg::OnNMRClickPlaylistList) ON_NOTIFY(NM_DBLCLK, IDC_PLAYLIST_LIST, &CFloatPlaylistDlg::OnNMDblclkPlaylistList) ON_EN_CHANGE(IDC_SEARCH_EDIT, &CFloatPlaylistDlg::OnEnChangeSearchEdit) - //ON_BN_CLICKED(IDC_CLEAR_SEARCH_BUTTON, &CFloatPlaylistDlg::OnBnClickedClearSearchButton) ON_WM_CLOSE() - ON_WM_GETMINMAXINFO() ON_NOTIFY(NM_CLICK, IDC_PLAYLIST_LIST, &CFloatPlaylistDlg::OnNMClickPlaylistList) ON_MESSAGE(WM_INITMENU, &CFloatPlaylistDlg::OnInitmenu) ON_MESSAGE(WM_LIST_ITEM_DRAGGED, &CFloatPlaylistDlg::OnListItemDragged) @@ -217,7 +217,6 @@ BEGIN_MESSAGE_MAP(CFloatPlaylistDlg, CDialog) ON_COMMAND(ID_LOCATE_TO_CURRENT, &CFloatPlaylistDlg::OnLocateToCurrent) ON_MESSAGE(WM_MAIN_WINDOW_ACTIVATED, &CFloatPlaylistDlg::OnMainWindowActivated) ON_WM_DROPFILES() - ON_WM_CTLCOLOR() ON_WM_COPYDATA() END_MESSAGE_MAP() @@ -227,18 +226,19 @@ END_MESSAGE_MAP() BOOL CFloatPlaylistDlg::OnInitDialog() { - CDialog::OnInitDialog(); + CBaseDialog::OnInitDialog(); // TODO: 在此添加额外的初始化 + SetBackgroundColor(CONSTVAL::BACKGROUND_COLOR); UpdateStyles(); - SetWindowText(CCommon::LoadText(IDS_PLAYLIST)); - SetIcon(AfxGetApp()->LoadIcon(IDI_PLAYLIST_D), FALSE); - - // 为浮动播放列表禁用分割条控件 - m_splitter_ctrl.EnableWindow(false); - m_splitter_ctrl.ShowWindow(SW_HIDE); + SetIcon(IconMgr::IconType::IT_Playlist, FALSE); + SetButtonIcon(ID_MEDIA_LIB, IconMgr::IconType::IT_Media_Lib); - m_set_path_button.SetIcon(theApp.m_icon_set.media_lib.GetIcon(true)); + // 为浮动播放列表禁用仅在主窗口使用的控件 + EnableDlgCtrl(IDC_HSPLITER_STATIC, false); + ShowDlgCtrl(IDC_HSPLITER_STATIC, false); + EnableDlgCtrl(IDC_UI_STATIC, false); + ShowDlgCtrl(IDC_UI_STATIC, false); //设置窗口大小和位置 if (CMusicPlayerDlg::IsPointValid(m_init_point)) @@ -250,27 +250,35 @@ BOOL CFloatPlaylistDlg::OnInitDialog() GetClientRect(rect); ReSizeControl(rect.Width(), rect.Height()); - m_search_edit.SetCueBanner(CCommon::LoadText(IDS_SEARCH_HERE), TRUE); + wstring prompt_str = theApp.m_str_table.LoadText(L"TXT_SEARCH_PROMPT") + L"(F)"; + m_search_edit.SetCueBanner(prompt_str.c_str(), TRUE); if (CPlayer::GetInstance().IsPlaylistMode()) { - m_path_static.SetWindowText(CCommon::LoadText(IDS_PLAYLIST, _T(":"))); - m_path_static.SetIcon(theApp.m_icon_set.show_playlist.GetIcon(true), theApp.m_icon_set.select_folder.GetSize()); + m_path_static.SetWindowText(theApp.m_str_table.LoadText(L"UI_TXT_PLAYLIST").c_str()); + m_path_static.SetIcon(IconMgr::IconType::IT_Playlist); } else { - m_path_static.SetWindowText(CCommon::LoadText(IDS_FOLDER, _T(":"))); - m_path_static.SetIcon(theApp.m_icon_set.select_folder.GetIcon(true), theApp.m_icon_set.select_folder.GetSize()); + m_path_static.SetWindowText(theApp.m_str_table.LoadText(L"UI_TXT_FOLDER").c_str()); + m_path_static.SetIcon(IconMgr::IconType::IT_Folder); } //初始化播放列表工具栏 + wstring menu_str; m_playlist_toolbar.SetIconSize(theApp.DPI(20)); - m_playlist_toolbar.AddToolButton(theApp.m_icon_set.add, CCommon::LoadText(IDS_ADD), CCommon::LoadText(IDS_ADD), theApp.m_menu_set.m_playlist_toolbar_menu.GetSubMenu(0), true); - m_playlist_toolbar.AddToolButton(theApp.m_icon_set.close, CCommon::LoadText(IDS_DELETE), CCommon::LoadText(IDS_DELETE), theApp.m_menu_set.m_playlist_toolbar_menu.GetSubMenu(1), true); - m_playlist_toolbar.AddToolButton(theApp.m_icon_set.sort, CCommon::LoadText(IDS_SORT), CCommon::LoadText(IDS_SORT), theApp.m_menu_set.m_playlist_toolbar_menu.GetSubMenu(2), true); - m_playlist_toolbar.AddToolButton(theApp.m_icon_set.show_playlist, CCommon::LoadText(IDS_LIST), CCommon::LoadText(IDS_LIST), theApp.m_menu_set.m_playlist_toolbar_menu.GetSubMenu(3), true); - m_playlist_toolbar.AddToolButton(theApp.m_icon_set.edit, CCommon::LoadText(IDS_EDIT), CCommon::LoadText(IDS_EDIT), theApp.m_menu_set.m_playlist_toolbar_menu.GetSubMenu(4), true); - m_playlist_toolbar.AddToolButton(theApp.m_icon_set.locate, nullptr, CCommon::LoadText(IDS_LOCATE_TO_CURRENT, CPlayerUIBase::GetCmdShortcutKeyForTooltips(ID_LOCATE_TO_CURRENT)), ID_LOCATE_TO_CURRENT); + menu_str = theApp.m_str_table.LoadText(L"UI_TXT_PLAYLIST_TOOLBAR_ADD"); + m_playlist_toolbar.AddToolButton(IconMgr::IconType::IT_Add, menu_str.c_str(), menu_str.c_str(), theApp.m_menu_mgr.GetMenu(MenuMgr::MainPlaylistAddMenu), true); + menu_str = theApp.m_str_table.LoadText(L"UI_TXT_PLAYLIST_TOOLBAR_DELETE"); + m_playlist_toolbar.AddToolButton(IconMgr::IconType::IT_Cancel, menu_str.c_str(), menu_str.c_str(), theApp.m_menu_mgr.GetMenu(MenuMgr::MainPlaylistDelMenu), true); + menu_str = theApp.m_str_table.LoadText(L"UI_TXT_PLAYLIST_TOOLBAR_SORT"); + m_playlist_toolbar.AddToolButton(IconMgr::IconType::IT_Sort_Mode, menu_str.c_str(), menu_str.c_str(), theApp.m_menu_mgr.GetMenu(MenuMgr::MainPlaylistSortMenu), true); + menu_str = theApp.m_str_table.LoadText(L"UI_TXT_PLAYLIST_TOOLBAR_LIST"); + m_playlist_toolbar.AddToolButton(IconMgr::IconType::IT_Playlist, menu_str.c_str(), menu_str.c_str(), theApp.m_menu_mgr.GetMenu(MenuMgr::PlaylistToolBarListMenu), true); + menu_str = theApp.m_str_table.LoadText(L"UI_TXT_PLAYLIST_TOOLBAR_EDIT"); + m_playlist_toolbar.AddToolButton(IconMgr::IconType::IT_Edit, menu_str.c_str(), menu_str.c_str(), theApp.m_menu_mgr.GetMenu(MenuMgr::PlaylistToolBarEditMenu), true); + menu_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_LOCATE_TO_CURRENT") + CPlayerUIBase::GetCmdShortcutKeyForTooltips(ID_LOCATE_TO_CURRENT).GetString(); + m_playlist_toolbar.AddToolButton(IconMgr::IconType::IT_Locate, nullptr, menu_str.c_str(), ID_LOCATE_TO_CURRENT); RefreshData(); RefreshState(); @@ -278,17 +286,13 @@ BOOL CFloatPlaylistDlg::OnInitDialog() SetDragEnable(); EnableControl(!CPlayer::GetInstance().m_loading); - CWnd* pWnd = GetDlgItem(IDC_UI_STATIC); - if (pWnd != nullptr) - pWnd->ShowWindow(SW_HIDE); - return TRUE; // return TRUE unless you set the focus to a control // 异常: OCX 属性页应返回 FALSE } void CFloatPlaylistDlg::OnSize(UINT nType, int cx, int cy) { - CDialog::OnSize(nType, cx, cy); + CBaseDialog::OnSize(nType, cx, cy); if (nType != SIZE_MINIMIZED && Initilized()) { @@ -328,9 +332,9 @@ void CFloatPlaylistDlg::OnNMRClickPlaylistList(NMHDR* pNMHDR, LRESULT* pResult) CMenu* pContextMenu{}; if (m_item_selected >= 0) - pContextMenu = theApp.m_menu_set.m_list_popup_menu.GetSubMenu(0); + pContextMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::PlaylistMenu); else - pContextMenu = &theApp.m_menu_set.m_playlist_toolbar_popup_menu; + pContextMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::PlaylistToolBarMenu); m_playlist_ctrl.ShowPopupMenu(pContextMenu, pNMItemActivate->iItem, this); *pResult = 0; @@ -373,32 +377,21 @@ void CFloatPlaylistDlg::OnEnChangeSearchEdit() SetDragEnable(); } -//void CFloatPlaylistDlg::OnBnClickedClearSearchButton() -//{ -// if (m_searched) -// { -// //清除搜索结果 -// m_searched = false; -// m_search_edit.SetWindowText(_T("")); -// m_playlist_ctrl.ShowPlaylist(theApp.m_media_lib_setting_data.display_format, m_searched); -// m_playlist_ctrl.EnsureVisible(CPlayer::GetInstance().GetIndex(), FALSE); //清除搜索结果后确保正在播放曲目可见 -// } -//} - void CFloatPlaylistDlg::OnCancel() { // TODO: 在此添加专用代码和/或调用基类 DestroyWindow(); - //CDialog::OnCancel(); + //CBaseDialog::OnCancel(); } void CFloatPlaylistDlg::OnClose() { theApp.m_pMainWnd->SendMessage(WM_FLOAT_PLAYLIST_CLOSED); + // 仅在用户主动关闭浮动播放列表时更改设置,在退出时会直接OnCancel关闭窗口 theApp.m_nc_setting_data.float_playlist = false; - CDialog::OnClose(); + CBaseDialog::OnClose(); } @@ -421,9 +414,9 @@ BOOL CFloatPlaylistDlg::OnCommand(WPARAM wParam, LPARAM lParam) GetPlaylistItemSelected(); break; default: - if (command == ID_SET_PATH || CCommon::IsMenuItemInMenu(theApp.m_menu_set.m_list_popup_menu.GetSubMenu(0), command) - || CCommon::IsMenuItemInMenu(&theApp.m_menu_set.m_playlist_toolbar_menu, command) - || CCommon::IsMenuItemInMenu(&theApp.m_menu_set.m_main_menu, command) + if (command == ID_MEDIA_LIB || CCommon::IsMenuItemInMenu(theApp.m_menu_mgr.GetMenu(MenuMgr::PlaylistMenu), command) + || CCommon::IsMenuItemInMenu(theApp.m_menu_mgr.GetMenu(MenuMgr::PlaylistToolBarMenu), command) // 此处使用等价的弹出菜单,含有所有独立的工具栏按钮菜单项 + || CCommon::IsMenuItemInMenu(theApp.m_menu_mgr.GetMenu(MenuMgr::MainPopupMenu), command) || (command >= ID_ADD_TO_MY_FAVOURITE && command < ID_ADD_TO_MY_FAVOURITE + ADD_TO_PLAYLIST_MAX_SIZE)) { theApp.m_pMainWnd->SendMessage(WM_COMMAND, wParam, lParam); //将菜单命令转发到主窗口 @@ -432,16 +425,7 @@ BOOL CFloatPlaylistDlg::OnCommand(WPARAM wParam, LPARAM lParam) break; } - return CDialog::OnCommand(wParam, lParam); -} - -void CFloatPlaylistDlg::OnGetMinMaxInfo(MINMAXINFO* lpMMI) -{ - //限制窗口最小大小 - lpMMI->ptMinTrackSize.x = theApp.DPI(286); //设置最小宽度 - lpMMI->ptMinTrackSize.y = theApp.DPI(228); //设置最小高度 - - CDialog::OnGetMinMaxInfo(lpMMI); + return CBaseDialog::OnCommand(wParam, lParam); } void CFloatPlaylistDlg::OnNMClickPlaylistList(NMHDR* pNMHDR, LRESULT* pResult) @@ -495,7 +479,7 @@ BOOL CFloatPlaylistDlg::PreTranslateMessage(MSG* pMsg) return TRUE; } - return CDialog::PreTranslateMessage(pMsg); + return CBaseDialog::PreTranslateMessage(pMsg); } @@ -555,23 +539,7 @@ void CFloatPlaylistDlg::OnDropFiles(HDROP hDropInfo) if (main_wnd != nullptr) main_wnd->OnDropFiles(hDropInfo); else - CDialog::OnDropFiles(hDropInfo); -} - - -HBRUSH CFloatPlaylistDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) -{ - HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); - - if (pWnd == this) - { - static HBRUSH hBackBrush{}; - if (hBackBrush == NULL) - hBackBrush = CreateSolidBrush(CONSTVAL::BACKGROUND_COLOR); - return hBackBrush; - } - - return hbr; + CBaseDialog::OnDropFiles(hDropInfo); } @@ -583,5 +551,5 @@ BOOL CFloatPlaylistDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) if (main_wnd != nullptr) return main_wnd->OnCopyData(pWnd, pCopyDataStruct); else - return CDialog::OnCopyData(pWnd, pCopyDataStruct); + return CBaseDialog::OnCopyData(pWnd, pCopyDataStruct); } diff --git a/MusicPlayer2/CFloatPlaylistDlg.h b/MusicPlayer2/CFloatPlaylistDlg.h index d7d6364d8..1ca3cfc04 100644 --- a/MusicPlayer2/CFloatPlaylistDlg.h +++ b/MusicPlayer2/CFloatPlaylistDlg.h @@ -1,17 +1,17 @@ #pragma once +#include "BaseDialog.h" #include "PlayListCtrl.h" #include "StaticEx.h" #include "CPlayerUIBase.h" #include "PlayerToolBar.h" #include "SearchEditCtrl.h" #include "MenuEditCtrl.h" -#include "HorizontalSplitter.h" #define WM_FLOAT_PLAYLIST_CLOSED (WM_USER+118) // CFloatPlaylistDlg 对话框 -class CFloatPlaylistDlg : public CDialog +class CFloatPlaylistDlg : public CBaseDialog { DECLARE_DYNAMIC(CFloatPlaylistDlg) @@ -38,16 +38,17 @@ class CFloatPlaylistDlg : public CDialog void SetInitPoint(CPoint point); private: - CPlayListCtrl m_playlist_ctrl{ CPlayer::GetInstance().GetPlayList() }; + CPlayListCtrl m_playlist_ctrl; CStaticEx m_path_static; CMenuEditCtrl m_path_edit; - CButton m_set_path_button; + CButton m_media_lib_button; CSearchEditCtrl m_search_edit; - //CButton m_clear_search_button; CPlayerToolBar m_playlist_toolbar; - CHorizontalSplitter m_splitter_ctrl; SLayoutData m_layout; //窗口布局的固定数据 + int m_part_static_playlist_width{ theApp.DPI(32) }; // 这里的值是最小宽度,窗口init时会根据文字变大 + int m_part_static_folder_width{ theApp.DPI(32) }; // 这里的值是最小宽度,窗口init时会根据文字变大 + int m_medialib_btn_width{ theApp.DPI(64) }; // 这里的值是最小宽度,窗口init时会根据文字变大 bool m_searched{ false }; //播放列表是否处于搜索状态 int& m_item_selected; //播放列表中鼠标选中的项目 @@ -59,6 +60,8 @@ class CFloatPlaylistDlg : public CDialog bool Initilized() const; protected: + virtual CString GetDialogName() const override; + virtual bool InitializeControls() override; virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() @@ -68,11 +71,9 @@ class CFloatPlaylistDlg : public CDialog afx_msg void OnNMRClickPlaylistList(NMHDR* pNMHDR, LRESULT* pResult); afx_msg void OnNMDblclkPlaylistList(NMHDR* pNMHDR, LRESULT* pResult); afx_msg void OnEnChangeSearchEdit(); - //afx_msg void OnBnClickedClearSearchButton(); virtual void OnCancel(); afx_msg void OnClose(); virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam); - afx_msg void OnGetMinMaxInfo(MINMAXINFO* lpMMI); afx_msg void OnNMClickPlaylistList(NMHDR* pNMHDR, LRESULT* pResult); virtual BOOL PreTranslateMessage(MSG* pMsg); protected: @@ -85,6 +86,5 @@ class CFloatPlaylistDlg : public CDialog afx_msg LRESULT OnMainWindowActivated(WPARAM wParam, LPARAM lParam); public: afx_msg void OnDropFiles(HDROP hDropInfo); - afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); afx_msg BOOL OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct); }; diff --git a/MusicPlayer2/CHotKeySettingDlg.cpp b/MusicPlayer2/CHotKeySettingDlg.cpp index bbe4e2e6f..1d5d4ebc6 100644 --- a/MusicPlayer2/CHotKeySettingDlg.cpp +++ b/MusicPlayer2/CHotKeySettingDlg.cpp @@ -4,7 +4,7 @@ #include "stdafx.h" #include "MusicPlayer2.h" #include "CHotKeySettingDlg.h" -#include "afxdialogex.h" +#include "WinVersionHelper.h" // CHotKeySettingDlg 对话框 @@ -53,6 +53,23 @@ void CHotKeySettingDlg::ListClicked() //m_hot_key_ctrl.SetHotKey(hot_key.key, hot_key.Modifiers()); } +bool CHotKeySettingDlg::InitializeControls() +{ + wstring temp; + temp = theApp.m_str_table.LoadText(L"TXT_OPT_HOT_KEY_HOOK_SHORTCUT_KEY_ENABLE"); + SetDlgItemTextW(IDC_HOT_KEY_ENABLE_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_HOT_KEY_HOOK_MULTI_MEDIA_KEY_ENABLE"); + SetDlgItemTextW(IDC_ENABLE_GLOBAL_MULTIMEDIA_KEY_CHECK, temp.c_str()); + // IDC_HOT_KEY_LIST + temp = theApp.m_str_table.LoadText(L"TXT_OPT_HOT_KEY_SHORTCUT_KEY_SEL"); + SetDlgItemTextW(IDC_TXT_OPT_HOT_KEY_SHORTCUT_KEY_SEL_STATIC, temp.c_str()); + // IDC_HOTKEY1 + temp = theApp.m_str_table.LoadText(L"TXT_OPT_HOT_KEY_SHORTCUT_KEY_SET"); + SetDlgItemTextW(IDC_SET_BUTTON, temp.c_str()); + + return false; +} + void CHotKeySettingDlg::DoDataExchange(CDataExchange* pDX) { CTabDlg::DoDataExchange(pDX); @@ -69,7 +86,7 @@ BEGIN_MESSAGE_MAP(CHotKeySettingDlg, CTabDlg) ON_NOTIFY(NM_RCLICK, IDC_HOT_KEY_LIST, &CHotKeySettingDlg::OnNMRClickHotKeyList) ON_BN_CLICKED(IDC_HOT_KEY_ENABLE_CHECK, &CHotKeySettingDlg::OnBnClickedHotKeyEnableCheck) ON_WM_DESTROY() - ON_BN_CLICKED(IDC_ENABLE_GLABOL_MULTIMEDIA_KEY_CHECK, &CHotKeySettingDlg::OnBnClickedEnableGlabolMultimediaKeyCheck) + ON_BN_CLICKED(IDC_ENABLE_GLOBAL_MULTIMEDIA_KEY_CHECK, &CHotKeySettingDlg::OnBnClickedEnableGlobalMultimediaKeyCheck) END_MESSAGE_MAP() @@ -89,25 +106,29 @@ BOOL CHotKeySettingDlg::OnInitDialog() m_toolTip.Create(this); m_toolTip.SetMaxTipWidth(theApp.DPI(300)); - m_toolTip.AddTool(GetDlgItem(IDC_ENABLE_GLOBAL_MULTIMEDIA_KEY_CHECK), CCommon::LoadText(IDS_MULTI_MEDIA_KEY_TIP)); + m_toolTip.AddTool(GetDlgItem(IDC_ENABLE_GLOBAL_MULTIMEDIA_KEY_CHECK), theApp.m_str_table.LoadText(L"TIP_OPT_HOT_KEY_HOOK_MULTI_MEDIA_KEY").c_str()); m_toolTip.SetWindowPos(&CWnd::wndTopMost, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); + CRect rect; + m_key_list.GetWindowRect(rect); + int width0 = theApp.DPI(180); + int width1 = rect.Width() - width0 - theApp.DPI(20) - 1; // 这里预留一个滚动条宽度但空白为两个,因为此子对话框高度不足tab滚动条没有显示,如果在OnSize重新设置就会正常了 m_key_list.SetExtendedStyle(m_key_list.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_LABELTIP); - m_key_list.InsertColumn(0, CCommon::LoadText(IDS_FUNCTION), LVCFMT_LEFT, theApp.DPI(130)); - m_key_list.InsertColumn(1, CCommon::LoadText(IDS_SHORTCUT_KEY), LVCFMT_LEFT, theApp.DPI(170)); - - m_key_list.InsertItem(0, CCommon::LoadText(IDS_PLAY_PAUSE)); - m_key_list.InsertItem(1, CCommon::LoadText(IDS_STOP)); - m_key_list.InsertItem(2, CCommon::LoadText(IDS_FAST_FORWARD)); - m_key_list.InsertItem(3, CCommon::LoadText(IDS_REWIND)); - m_key_list.InsertItem(4, CCommon::LoadText(IDS_PREVIOUS)); - m_key_list.InsertItem(5, CCommon::LoadText(IDS_NEXT)); - m_key_list.InsertItem(6, CCommon::LoadText(IDS_VOLUME_UP)); - m_key_list.InsertItem(7, CCommon::LoadText(IDS_VOLUME_DOWN)); - m_key_list.InsertItem(8, CCommon::LoadText(IDS_EXIT)); - m_key_list.InsertItem(9, CCommon::LoadText(IDS_SHOW_HIDE_PLAYER)); - m_key_list.InsertItem(10, CCommon::LoadText(IDS_SHOW_HIDE_DESKTOP_LYRIC)); + m_key_list.InsertColumn(0, theApp.m_str_table.LoadText(L"TXT_OPT_HOT_KEY_FUNCTION").c_str(), LVCFMT_LEFT, width0); + m_key_list.InsertColumn(1, theApp.m_str_table.LoadText(L"TXT_OPT_HOT_KEY_SHORTCUT_KEY").c_str(), LVCFMT_LEFT, width1); + + m_key_list.InsertItem(0, theApp.m_str_table.LoadText(L"TXT_OPT_HOT_KEY_PLAY_PAUSE").c_str()); + m_key_list.InsertItem(1, theApp.m_str_table.LoadText(L"TXT_OPT_HOT_KEY_STOP").c_str()); + m_key_list.InsertItem(2, theApp.m_str_table.LoadText(L"TXT_OPT_HOT_KEY_FAST_FORWARD").c_str()); + m_key_list.InsertItem(3, theApp.m_str_table.LoadText(L"TXT_OPT_HOT_KEY_REWIND").c_str()); + m_key_list.InsertItem(4, theApp.m_str_table.LoadText(L"TXT_OPT_HOT_KEY_PREVIOUS").c_str()); + m_key_list.InsertItem(5, theApp.m_str_table.LoadText(L"TXT_OPT_HOT_KEY_NEXT").c_str()); + m_key_list.InsertItem(6, theApp.m_str_table.LoadText(L"TXT_OPT_HOT_KEY_VOLUME_UP").c_str()); + m_key_list.InsertItem(7, theApp.m_str_table.LoadText(L"TXT_OPT_HOT_KEY_VOLUME_DOWN").c_str()); + m_key_list.InsertItem(8, theApp.m_str_table.LoadText(L"TXT_OPT_HOT_KEY_EXIT").c_str()); + m_key_list.InsertItem(9, theApp.m_str_table.LoadText(L"TXT_OPT_HOT_KEY_PLAYER_SHOW_HIDE").c_str()); + m_key_list.InsertItem(10, theApp.m_str_table.LoadText(L"TXT_OPT_HOT_KEY_DESKTOP_LYRIC_SHOW_HIDE").c_str()); ShowKeyList(); @@ -128,7 +149,8 @@ void CHotKeySettingDlg::OnBnClickedSetButton() if (modifiers == 0 && key_coke != 0) { - MessageBox(CCommon::LoadText(IDS_GLOBLE_HOT_KEY_WARNING), NULL, MB_ICONWARNING | MB_OK); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_OPT_HOT_KEY_GLOBLE_HOT_KEY_WARNING"); + MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK); return; } @@ -174,7 +196,7 @@ void CHotKeySettingDlg::OnBnClickedHotKeyEnableCheck() -void CHotKeySettingDlg::OnBnClickedEnableGlabolMultimediaKeyCheck() +void CHotKeySettingDlg::OnBnClickedEnableGlobalMultimediaKeyCheck() { // TODO: 在此添加控件通知处理程序代码 m_data.global_multimedia_key_enable = (m_enable_global_multimedia_key_check.GetCheck() != 0); diff --git a/MusicPlayer2/CHotKeySettingDlg.h b/MusicPlayer2/CHotKeySettingDlg.h index 3c7ce7fca..e8a729e63 100644 --- a/MusicPlayer2/CHotKeySettingDlg.h +++ b/MusicPlayer2/CHotKeySettingDlg.h @@ -1,6 +1,7 @@ #pragma once #include "CHotkeyManager.h" #include "TabDlg.h" +#include "ListCtrlEx.h" // CHotKeySettingDlg 对话框 @@ -34,6 +35,7 @@ class CHotKeySettingDlg : public CTabDlg void EnableControl(); void ListClicked(); + virtual bool InitializeControls() override; virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() @@ -44,6 +46,6 @@ class CHotKeySettingDlg : public CTabDlg afx_msg void OnNMClickHotKeyList(NMHDR *pNMHDR, LRESULT *pResult); afx_msg void OnNMRClickHotKeyList(NMHDR *pNMHDR, LRESULT *pResult); afx_msg void OnBnClickedHotKeyEnableCheck(); - afx_msg void OnBnClickedEnableGlabolMultimediaKeyCheck(); + afx_msg void OnBnClickedEnableGlobalMultimediaKeyCheck(); virtual BOOL PreTranslateMessage(MSG* pMsg); }; diff --git a/MusicPlayer2/CListenTimeStatisticsDlg.cpp b/MusicPlayer2/CListenTimeStatisticsDlg.cpp index de40e9b35..4ebecd2aa 100644 --- a/MusicPlayer2/CListenTimeStatisticsDlg.cpp +++ b/MusicPlayer2/CListenTimeStatisticsDlg.cpp @@ -4,16 +4,17 @@ #include "stdafx.h" #include "MusicPlayer2.h" #include "CListenTimeStatisticsDlg.h" -#include "afxdialogex.h" #include "SongDataManager.h" +#include "FilterHelper.h" +#include "AudioCommon.h" // CListenTimeStatisticsDlg 对话框 -IMPLEMENT_DYNAMIC(CListenTimeStatisticsDlg, CDialog) +IMPLEMENT_DYNAMIC(CListenTimeStatisticsDlg, CBaseDialog) CListenTimeStatisticsDlg::CListenTimeStatisticsDlg(CWnd* pParent /*=nullptr*/) - : CDialog(IDD_LISTEN_TIME_STATISTICS_DLG, pParent) + : CBaseDialog(IDD_LISTEN_TIME_STATISTICS_DLG, pParent) { } @@ -22,9 +23,35 @@ CListenTimeStatisticsDlg::~CListenTimeStatisticsDlg() { } +CString CListenTimeStatisticsDlg::GetDialogName() const +{ + return L"ListenTimeStatisticsDlg"; +} + +bool CListenTimeStatisticsDlg::InitializeControls() +{ + wstring temp; + temp = theApp.m_str_table.LoadText(L"TITLE_LISTEN_TIME"); + SetWindowTextW(temp.c_str()); + // IDC_LIST1 + temp = theApp.m_str_table.LoadText(L"TXT_LISTEN_TIME_EXPORT"); + SetDlgItemTextW(IDC_EXPORT_BUTTON, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_LISTEN_TIME_CLEAR"); + SetDlgItemTextW(IDC_CLEAR_BUTTON, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_CLOSE"); + SetDlgItemTextW(IDCANCEL, temp.c_str()); + + RepositionTextBasedControls({ + { CtrlTextInfo::L2, IDC_EXPORT_BUTTON, CtrlTextInfo::W32 }, + { CtrlTextInfo::L1, IDC_CLEAR_BUTTON, CtrlTextInfo::W32 }, + { CtrlTextInfo::R1, IDCANCEL, CtrlTextInfo::W32 } + }); + return true; +} + void CListenTimeStatisticsDlg::DoDataExchange(CDataExchange* pDX) { - CDialog::DoDataExchange(pDX); + CBaseDialog::DoDataExchange(pDX); DDX_Control(pDX, IDC_LIST1, m_list_ctrl); } @@ -53,11 +80,7 @@ void CListenTimeStatisticsDlg::ShowData(bool size_changed) str = str.Left(str.GetLength() - 2); m_list_ctrl.SetItemText(index, COL_TIMES, str); - - // 处理cue时这里的高亮是有问题的,暂不影响使用以后修 - if (CPlayer::GetInstance().GetCurrentSongInfo().file_path == data.path) - m_list_ctrl.SetHightItem(index); - + // 这里之前设置当前播放高亮,意义不大,去掉了 index++; } } @@ -82,7 +105,7 @@ CListenTimeStatisticsDlg::ListItem CListenTimeStatisticsDlg::SongInfoToListItem( return list_item; } -BEGIN_MESSAGE_MAP(CListenTimeStatisticsDlg, CDialog) +BEGIN_MESSAGE_MAP(CListenTimeStatisticsDlg, CBaseDialog) ON_BN_CLICKED(IDC_EXPORT_BUTTON, &CListenTimeStatisticsDlg::OnBnClickedExportButton) ON_WM_GETMINMAXINFO() ON_BN_CLICKED(IDC_CLEAR_BUTTON, &CListenTimeStatisticsDlg::OnBnClickedClearButton) @@ -95,31 +118,26 @@ END_MESSAGE_MAP() BOOL CListenTimeStatisticsDlg::OnInitDialog() { - CDialog::OnInitDialog(); + CBaseDialog::OnInitDialog(); // TODO: 在此添加额外的初始化 - //获取初始时窗口的大小 - CRect rect; - GetWindowRect(rect); - m_min_size.cx = rect.Width(); - m_min_size.cy = rect.Height(); - //初始化列表 + CRect rect; + m_list_ctrl.GetWindowRect(rect); int width[6]; width[0] = theApp.DPI(40); width[1] = theApp.DPI(150); width[3] = width[5] = theApp.DPI(60); width[4] = theApp.DPI(50); - m_list_ctrl.GetWindowRect(rect); width[2] = rect.Width() - width[1] - width[3] - width[4] - width[5] - width[0] - theApp.DPI(20) - 1; m_list_ctrl.SetExtendedStyle(m_list_ctrl.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_LABELTIP); - m_list_ctrl.InsertColumn(0, CCommon::LoadText(IDS_NUMBER), LVCFMT_LEFT, width[0]); - m_list_ctrl.InsertColumn(1, CCommon::LoadText(IDS_TRACK), LVCFMT_LEFT, width[1]); - m_list_ctrl.InsertColumn(2, CCommon::LoadText(IDS_PATH), LVCFMT_LEFT, width[2]); - m_list_ctrl.InsertColumn(3, CCommon::LoadText(IDS_LISTEN_TIME), LVCFMT_LEFT, width[3]); - m_list_ctrl.InsertColumn(4, CCommon::LoadText(IDS_LENGTH), LVCFMT_LEFT, width[4]); - m_list_ctrl.InsertColumn(5, CCommon::LoadText(IDS_LISTEN_TIMES), LVCFMT_LEFT, width[5]); + m_list_ctrl.InsertColumn(0, theApp.m_str_table.LoadText(L"TXT_SERIAL_NUMBER").c_str(), LVCFMT_LEFT, width[0]); + m_list_ctrl.InsertColumn(1, theApp.m_str_table.LoadText(L"TXT_TRACK").c_str(), LVCFMT_LEFT, width[1]); + m_list_ctrl.InsertColumn(2, theApp.m_str_table.LoadText(L"TXT_PATH").c_str(), LVCFMT_LEFT, width[2]); + m_list_ctrl.InsertColumn(3, theApp.m_str_table.LoadText(L"TXT_LISTEN_TIME_TOTAL_TIME").c_str(), LVCFMT_LEFT, width[3]); + m_list_ctrl.InsertColumn(4, theApp.m_str_table.LoadText(L"TXT_LENGTH").c_str(), LVCFMT_LEFT, width[4]); + m_list_ctrl.InsertColumn(5, theApp.m_str_table.LoadText(L"TXT_LISTEN_TIME_TOTAL_COUNT").c_str(), LVCFMT_LEFT, width[5]); //获取数据 //从所有歌曲信息中查找累计听的时间超过指定时间的曲目添加到vector @@ -165,35 +183,30 @@ void CListenTimeStatisticsDlg::OnBnClickedExportButton() //弹出保存对话框 - CString filter = CCommon::LoadText(IDS_LISTEN_TIME_FILE_DLG_FILTER); - CString file_name = CCommon::LoadText(IDS_LISTEN_TIME_STATISTICS); + wstring filter = FilterHelper::GetListenTimeFilter(); + wstring file_name = theApp.m_str_table.LoadText(L"TITLE_LISTEN_TIME"); CString str_cur_date; SYSTEMTIME cur_time; GetLocalTime(&cur_time); str_cur_date.Format(_T("_%.4d-%.2d-%.2d"), cur_time.wYear, cur_time.wMonth, cur_time.wDay); file_name += str_cur_date; + CCommon::FileNameNormalize(file_name); // 构造保存文件对话框 - CFileDialog fileDlg(FALSE, _T("csv"), file_name, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, filter, this); + CFileDialog fileDlg(FALSE, _T("csv"), file_name.c_str(), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, filter.c_str(), this); // 显示保存文件对话框 if (IDOK == fileDlg.DoModal()) { //生成导出的csv文本 - CString str; - int list_size = m_list_ctrl.GetItemCount(); - str += CCommon::LoadText(IDS_NUMBER); - str += _T(','); - str += CCommon::LoadText(IDS_TRACK); - str += _T(','); - str += CCommon::LoadText(IDS_PATH); - str += _T(','); - str += CCommon::LoadText(IDS_LISTEN_TIME); - str += _T(','); - str += CCommon::LoadText(IDS_LENGTH); - str += _T(','); - str += CCommon::LoadText(IDS_LISTEN_TIMES); - str += _T('\n'); + std::wstringstream wss; + wss << theApp.m_str_table.LoadText(L"TXT_SERIAL_NUMBER") << L',' + << theApp.m_str_table.LoadText(L"TXT_TRACK") << L',' + << theApp.m_str_table.LoadText(L"TXT_PATH") << L',' + << theApp.m_str_table.LoadText(L"TXT_LISTEN_TIME_TOTAL_TIME") << L',' + << theApp.m_str_table.LoadText(L"TXT_LENGTH") << L',' + << theApp.m_str_table.LoadText(L"TXT_LISTEN_TIME_TOTAL_COUNT") << L'\n'; + int list_size = m_list_ctrl.GetItemCount(); for (int i = 0; i < list_size; i++) { const int COLUMN = 6; @@ -201,36 +214,26 @@ void CListenTimeStatisticsDlg::OnBnClickedExportButton() { CString item_text{ m_list_ctrl.GetItemText(i, j).GetString() }; CCommon::StringCsvNormalize(item_text); - str += item_text; + wss << item_text.GetString(); if (j == COLUMN - 1) - str += _T('\n'); + wss << L'\n'; else - str += _T(','); + wss << L','; } } - - ofstream out_put{ fileDlg.GetPathName().GetString() }; - out_put << CCommon::UnicodeToStr(wstring(str), CodeType::ANSI); - } -} - - -void CListenTimeStatisticsDlg::OnGetMinMaxInfo(MINMAXINFO* lpMMI) -{ - // TODO: 在此添加消息处理程序代码和/或调用默认值 - //限制窗口最小大小 - lpMMI->ptMinTrackSize.x = m_min_size.cx; //设置最小宽度 - lpMMI->ptMinTrackSize.y = m_min_size.cy; //设置最小高度 - - CDialog::OnGetMinMaxInfo(lpMMI); + ofstream out_put{ fileDlg.GetPathName().GetString() }; + out_put << CCommon::UnicodeToStr(wss.str(), CodeType::UTF8); + out_put.close(); + } } void CListenTimeStatisticsDlg::OnBnClickedClearButton() { // TODO: 在此添加控件通知处理程序代码 - if (MessageBox(CCommon::LoadText(IDS_CLEAR_LISTEN_TIME_WARNING), NULL, MB_ICONINFORMATION | MB_OKCANCEL) == IDOK) + const wstring& info = theApp.m_str_table.LoadText(L"MSG_LISTEN_TIME_CLEAR_WARNING"); + if (MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OKCANCEL) == IDOK) { CSongDataManager::GetInstance().ClearPlayTime(); m_list_ctrl.DeleteAllItems(); diff --git a/MusicPlayer2/CListenTimeStatisticsDlg.h b/MusicPlayer2/CListenTimeStatisticsDlg.h index 5d63e9178..f51e77002 100644 --- a/MusicPlayer2/CListenTimeStatisticsDlg.h +++ b/MusicPlayer2/CListenTimeStatisticsDlg.h @@ -1,10 +1,10 @@ #pragma once +#include "BaseDialog.h" #include "ListCtrlEx.h" - // CListenTimeStatisticsDlg 对话框 -class CListenTimeStatisticsDlg : public CDialog +class CListenTimeStatisticsDlg : public CBaseDialog { DECLARE_DYNAMIC(CListenTimeStatisticsDlg) @@ -40,10 +40,11 @@ class CListenTimeStatisticsDlg : public CDialog protected: CListCtrlEx m_list_ctrl; - CSize m_min_size; vector m_data_list; protected: + virtual CString GetDialogName() const override; + virtual bool InitializeControls() override; virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 void ShowData(bool size_changed = true); @@ -53,7 +54,6 @@ class CListenTimeStatisticsDlg : public CDialog public: virtual BOOL OnInitDialog(); afx_msg void OnBnClickedExportButton(); - afx_msg void OnGetMinMaxInfo(MINMAXINFO* lpMMI); afx_msg void OnBnClickedClearButton(); afx_msg void OnHdnItemclickList1(NMHDR *pNMHDR, LRESULT *pResult); }; diff --git a/MusicPlayer2/CMainDialogBase.h b/MusicPlayer2/CMainDialogBase.h index 80d72c216..1d1aa7ef5 100644 --- a/MusicPlayer2/CMainDialogBase.h +++ b/MusicPlayer2/CMainDialogBase.h @@ -1,5 +1,5 @@ #pragma once -#include + class CMainDialogBase : public CDialog { diff --git a/MusicPlayer2/CMediaLibDlg.cpp b/MusicPlayer2/CMediaLibDlg.cpp index 2d4dfa6bf..b14447fd3 100644 --- a/MusicPlayer2/CMediaLibDlg.cpp +++ b/MusicPlayer2/CMediaLibDlg.cpp @@ -4,15 +4,14 @@ #include "stdafx.h" #include "MusicPlayer2.h" #include "CMediaLibDlg.h" -#include "afxdialogex.h" #include "MediaLibStatisticsDlg.h" // CMediaLibDlg 对话框 -IMPLEMENT_DYNAMIC(CMediaLibDlg, CDialog) +IMPLEMENT_DYNAMIC(CMediaLibDlg, CBaseDialog) CMediaLibDlg::CMediaLibDlg(int cur_tab, CWnd* pParent /*=nullptr*/) - : CDialog(IDD_MEDIA_LIB_DIALOG, pParent), m_init_tab(cur_tab) + : CBaseDialog(IDD_MEDIA_LIB_DIALOG, pParent), m_init_tab(cur_tab) { } @@ -36,35 +35,45 @@ bool CMediaLibDlg::NavigateToItem(const wstring& item) return false; } -void CMediaLibDlg::SaveConfig() const +CString CMediaLibDlg::GetDialogName() const { - CIniHelper ini{ theApp.m_config_path }; - ini.WriteInt(L"media_lib", L"width", m_window_size.cx); - ini.WriteInt(L"media_lib", L"height", m_window_size.cy); - ini.Save(); + return L"MediaLibDlg"; } -void CMediaLibDlg::LoadConfig() +bool CMediaLibDlg::InitializeControls() { - CIniHelper ini{ theApp.m_config_path }; - m_window_size.cx = ini.GetInt(L"media_lib", L"width", -1); - m_window_size.cy = ini.GetInt(L"media_lib", L"height", -1); + wstring temp; + temp = theApp.m_str_table.LoadText(L"TITLE_LIB"); + SetWindowTextW(temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_LIB_MEDIA_LIB_SETTING"); + SetDlgItemTextW(IDC_MEDIA_LIB_SETTINGS_BTN, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_LIB_STATISTICS_INFO"); + SetDlgItemTextW(IDC_STATISTICS_INFO_BUTTON, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_LIB_PLAY_SEL"); + SetDlgItemTextW(IDC_PLAY_SELECTED, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_CLOSE"); + SetDlgItemTextW(IDCANCEL, temp.c_str()); + + RepositionTextBasedControls({ + { CtrlTextInfo::L2, IDC_MEDIA_LIB_SETTINGS_BTN, CtrlTextInfo::W32 }, + { CtrlTextInfo::L1, IDC_STATISTICS_INFO_BUTTON, CtrlTextInfo::W32 }, + { CtrlTextInfo::R1, IDC_PLAY_SELECTED, CtrlTextInfo::W32 }, + { CtrlTextInfo::R2, IDCANCEL, CtrlTextInfo::W32 } + }); + return true; } void CMediaLibDlg::DoDataExchange(CDataExchange* pDX) { - CDialog::DoDataExchange(pDX); + CBaseDialog::DoDataExchange(pDX); DDX_Control(pDX, IDC_TAB1, m_tab_ctrl); } -BEGIN_MESSAGE_MAP(CMediaLibDlg, CDialog) +BEGIN_MESSAGE_MAP(CMediaLibDlg, CBaseDialog) ON_BN_CLICKED(IDC_PLAY_SELECTED, &CMediaLibDlg::OnBnClickedPlaySelected) - ON_WM_GETMINMAXINFO() ON_MESSAGE(WM_PLAY_SELECTED_BTN_ENABLE, &CMediaLibDlg::OnPlaySelectedBtnEnable) - ON_WM_ERASEBKGND() ON_BN_CLICKED(IDC_MEDIA_LIB_SETTINGS_BTN, &CMediaLibDlg::OnBnClickedMediaLibSettingsBtn) - ON_WM_SIZE() ON_BN_CLICKED(IDC_STATISTICS_INFO_BUTTON, &CMediaLibDlg::OnBnClickedStatisticsInfoButton) ON_WM_DESTROY() END_MESSAGE_MAP() @@ -74,30 +83,17 @@ END_MESSAGE_MAP() BOOL CMediaLibDlg::OnInitDialog() { - CDialog::OnInitDialog(); + CBaseDialog::OnInitDialog(); // TODO: 在此添加额外的初始化 ModifyStyle(0, WS_CLIPCHILDREN); - SetIcon(theApp.m_icon_set.media_lib.GetIcon(true), FALSE); - SetIcon(AfxGetApp()->LoadIcon(IDI_MEDIA_LIB_D), TRUE); - - CButton* close_btn = (CButton*)(GetDlgItem(IDCANCEL)); - if (close_btn != nullptr) - close_btn->SetIcon(theApp.m_icon_set.close.GetIcon(true)); - CButton* play_btn = (CButton*)(GetDlgItem(IDC_PLAY_SELECTED)); - if (play_btn != nullptr) - play_btn->SetIcon(theApp.m_icon_set.play_new.GetIcon(true)); - CButton* setting_btn = (CButton*)(GetDlgItem(IDC_MEDIA_LIB_SETTINGS_BTN)); - if (setting_btn != nullptr) - setting_btn->SetIcon(theApp.m_icon_set.setting.GetIcon(true)); - CButton* statistics_btn = (CButton*)(GetDlgItem(IDC_STATISTICS_INFO_BUTTON)); - if (statistics_btn != nullptr) - statistics_btn->SetIcon(theApp.m_icon_set.info.GetIcon(true)); - - //为每个标签添加图标 - CImageList ImageList; - ImageList.Create(theApp.DPI(16), theApp.DPI(16), ILC_COLOR32 | ILC_MASK, 2, 2); + SetIcon(IconMgr::IconType::IT_Media_Lib, FALSE); + SetIcon(IconMgr::IconType::IT_Media_Lib, TRUE); + + SetButtonIcon(IDC_MEDIA_LIB_SETTINGS_BTN, IconMgr::IconType::IT_Setting); + SetButtonIcon(IDC_STATISTICS_INFO_BUTTON, IconMgr::IconType::IT_Info); + SetButtonIcon(IDC_PLAY_SELECTED, IconMgr::IconType::IT_Play); // 创建子对话框,因为CMediaLibDlg不会及时析构为避免持续占用大量内存不再使用成员变量存储子窗口窗口类 m_path_dlg = new CSetPathDlg(); @@ -114,107 +110,80 @@ BOOL CMediaLibDlg::OnInitDialog() m_folder_explore_dlg = new CFolderExploreDlg(); //文件夹 m_path_dlg->Create(IDD_SET_PATH_DIALOG); - ImageList.Add(theApp.m_icon_set.select_folder.GetIcon(true)); - m_tab_ctrl.AddWindow(m_path_dlg, CCommon::LoadText(IDS_FOLDER)); + m_tab_ctrl.AddWindow(m_path_dlg, theApp.m_str_table.LoadText(L"TXT_FOLDER").c_str(), IconMgr::IconType::IT_Folder); //播放列表 m_playlist_dlg->Create(IDD_SELECT_PLAYLIST_DIALOG); - ImageList.Add(theApp.m_icon_set.show_playlist.GetIcon(true)); - m_tab_ctrl.AddWindow(m_playlist_dlg, CCommon::LoadText(IDS_PLAYLIST)); + m_tab_ctrl.AddWindow(m_playlist_dlg, theApp.m_str_table.LoadText(L"TXT_PLAYLIST").c_str(), IconMgr::IconType::IT_Playlist); //艺术家 if ((theApp.m_media_lib_setting_data.display_item & MLDI_ARTIST) || (m_tab_show_force & MLDI_ARTIST)) { m_artist_dlg->Create(IDD_MEDIA_CLASSIFY_DIALOG); - ImageList.Add(theApp.m_icon_set.artist.GetIcon(true)); - m_tab_ctrl.AddWindow(m_artist_dlg, CCommon::LoadText(IDS_ARTIST)); + m_tab_ctrl.AddWindow(m_artist_dlg, theApp.m_str_table.LoadText(L"TXT_ARTIST").c_str(), IconMgr::IconType::IT_Artist); } //唱片集 if ((theApp.m_media_lib_setting_data.display_item & MLDI_ALBUM) || (m_tab_show_force & MLDI_ALBUM)) { m_album_dlg->Create(IDD_MEDIA_CLASSIFY_DIALOG); - ImageList.Add(theApp.m_icon_set.album.GetIcon(true)); - m_tab_ctrl.AddWindow(m_album_dlg, CCommon::LoadText(IDS_ALBUM)); + m_tab_ctrl.AddWindow(m_album_dlg, theApp.m_str_table.LoadText(L"TXT_ALBUM").c_str(), IconMgr::IconType::IT_Album); } //流派 if (theApp.m_media_lib_setting_data.display_item & MLDI_GENRE) { m_genre_dlg->Create(IDD_MEDIA_CLASSIFY_DIALOG); - ImageList.Add(theApp.m_icon_set.genre.GetIcon(true)); - m_tab_ctrl.AddWindow(m_genre_dlg, CCommon::LoadText(IDS_GENRE)); + m_tab_ctrl.AddWindow(m_genre_dlg, theApp.m_str_table.LoadText(L"TXT_GENRE").c_str(), IconMgr::IconType::IT_Genre); } //年份 if (theApp.m_media_lib_setting_data.display_item & MLDI_YEAR) { m_year_dlg->Create(IDD_MEDIA_CLASSIFY_DIALOG); - ImageList.Add(theApp.m_icon_set.year.GetIcon(true)); - m_tab_ctrl.AddWindow(m_year_dlg, CCommon::LoadText(IDS_YEAR)); + m_tab_ctrl.AddWindow(m_year_dlg, theApp.m_str_table.LoadText(L"TXT_YEAR").c_str(), IconMgr::IconType::IT_Year); } //类型 if (theApp.m_media_lib_setting_data.display_item & MLDI_TYPE) { m_type_dlg->Create(IDD_MEDIA_CLASSIFY_DIALOG); - ImageList.Add(theApp.m_icon_set.file_relate); - m_tab_ctrl.AddWindow(m_type_dlg, CCommon::LoadText(IDS_FILE_TYPE)); + m_tab_ctrl.AddWindow(m_type_dlg, theApp.m_str_table.LoadText(L"TXT_FILE_TYPE").c_str(), IconMgr::IconType::IT_File_Relate); } //比特率 if (theApp.m_media_lib_setting_data.display_item & MLDI_BITRATE) { m_bitrate_dlg->Create(IDD_MEDIA_CLASSIFY_DIALOG); - ImageList.Add(theApp.m_icon_set.bitrate); - m_tab_ctrl.AddWindow(m_bitrate_dlg, CCommon::LoadText(IDS_BITRATE)); + m_tab_ctrl.AddWindow(m_bitrate_dlg, theApp.m_str_table.LoadText(L"TXT_BITRATE").c_str(), IconMgr::IconType::IT_Bitrate); } //分级 if (theApp.m_media_lib_setting_data.display_item & MLDI_RATING) { m_rating_dlg->Create(IDD_MEDIA_CLASSIFY_DIALOG); - ImageList.Add(theApp.m_icon_set.star); - m_tab_ctrl.AddWindow(m_rating_dlg, CCommon::LoadText(IDS_RATING)); + m_tab_ctrl.AddWindow(m_rating_dlg, theApp.m_str_table.LoadText(L"TXT_RATING").c_str(), IconMgr::IconType::IT_Star); } //所有曲目 if (theApp.m_media_lib_setting_data.display_item & MLDI_ALL) { m_all_media_dlg->Create(IDD_ALL_MEDIA_DIALOG); - ImageList.Add(theApp.m_icon_set.media_lib.GetIcon(true)); - m_tab_ctrl.AddWindow(m_all_media_dlg, CCommon::LoadText(IDS_ALL_TRACKS)); + m_tab_ctrl.AddWindow(m_all_media_dlg, theApp.m_str_table.LoadText(L"TXT_ALL_TRACKS").c_str(), IconMgr::IconType::IT_Media_Lib); } //最近播放 if (theApp.m_media_lib_setting_data.display_item & MLDI_RECENT) { m_recent_media_dlg->Create(IDD_ALL_MEDIA_DIALOG); - ImageList.Add(theApp.m_icon_set.recent_songs.GetIcon(true)); - m_tab_ctrl.AddWindow(m_recent_media_dlg, CCommon::LoadText(IDS_RECENT_PLAYED)); + m_tab_ctrl.AddWindow(m_recent_media_dlg, theApp.m_str_table.LoadText(L"TXT_RECENT_PLAYED").c_str(), IconMgr::IconType::IT_History); } //文件夹浏览 if (theApp.m_media_lib_setting_data.display_item & MLDI_FOLDER_EXPLORE) { m_folder_explore_dlg->Create(IDD_FOLDER_EXPLORE_DIALOG); - ImageList.Add(theApp.m_icon_set.folder_explore.GetIcon(true)); - m_tab_ctrl.AddWindow(m_folder_explore_dlg, CCommon::LoadText(IDS_FOLDER_EXPLORE)); + m_tab_ctrl.AddWindow(m_folder_explore_dlg, theApp.m_str_table.LoadText(L"TXT_FOLDER_EXPLORE").c_str(), IconMgr::IconType::IT_Folder_Explore); } m_tab_ctrl.SetItemSize(CSize(theApp.DPI(60), theApp.DPI(24))); m_tab_ctrl.AdjustTabWindowSize(); - m_tab_ctrl.SetImageList(&ImageList); - ImageList.Detach(); - m_tab_ctrl.SetCurTab(m_init_tab); - //获取初始时窗口的大小 - CRect rect; - GetWindowRect(rect); - m_min_size.cx = rect.Width(); - m_min_size.cy = rect.Height(); - OnPlaySelectedBtnEnable(0, 0); - LoadConfig(); - if (m_window_size.cx > 0 && m_window_size.cy > 0) - { - SetWindowPos(nullptr, 0, 0, m_window_size.cx, m_window_size.cy, SWP_NOMOVE | SWP_NOZORDER); - } - m_path_dlg->AdjustColumnWidth(); m_playlist_dlg->AdjustColumnWidth(); @@ -230,18 +199,7 @@ void CMediaLibDlg::OnBnClickedPlaySelected() // 调用子窗口的OnOK方法 CTabDlg* current_tab = dynamic_cast(m_tab_ctrl.GetCurrentTab()); if (current_tab != nullptr) - current_tab->OnOK(); -} - - -void CMediaLibDlg::OnGetMinMaxInfo(MINMAXINFO* lpMMI) -{ - // TODO: 在此添加消息处理程序代码和/或调用默认值 - //限制窗口最小大小 - lpMMI->ptMinTrackSize.x = m_min_size.cx; //设置最小宽度 - lpMMI->ptMinTrackSize.y = m_min_size.cy; //设置最小高度 - - CDialog::OnGetMinMaxInfo(lpMMI); + current_tab->OnOK(); // OnOK是虚方法,此处实际上执行的是CTabDlg的最终派生类的OnOK } @@ -256,27 +214,6 @@ afx_msg LRESULT CMediaLibDlg::OnPlaySelectedBtnEnable(WPARAM wParam, LPARAM lPar } -BOOL CMediaLibDlg::OnEraseBkgnd(CDC* pDC) -{ - // TODO: 在此添加消息处理程序代码和/或调用默认值 - - ////重绘背景时设置剪辑区域为窗口区域减去tab控件的区域 - //CRect rc_tab; - //m_tab_ctrl.GetWindowRect(rc_tab); - //ScreenToClient(rc_tab); - //CRgn tab_rgn; //tab控件区域 - //tab_rgn.CreateRectRgnIndirect(rc_tab); - //CRect rc_client; - //GetClientRect(rc_client); - //CRgn draw_rgn; //需要重绘的区域 - //draw_rgn.CreateRectRgnIndirect(rc_client); - //draw_rgn.CombineRgn(&draw_rgn, &tab_rgn, RGN_DIFF); - //pDC->SelectClipRgn(&draw_rgn); - return CDialog::OnEraseBkgnd(pDC); -} - - - void CMediaLibDlg::OnBnClickedMediaLibSettingsBtn() { // TODO: 在此添加控件通知处理程序代码 @@ -284,20 +221,6 @@ void CMediaLibDlg::OnBnClickedMediaLibSettingsBtn() } -void CMediaLibDlg::OnSize(UINT nType, int cx, int cy) -{ - CDialog::OnSize(nType, cx, cy); - - // TODO: 在此处添加消息处理程序代码 - if (nType != SIZE_MINIMIZED && nType != SIZE_MAXIMIZED) - { - CRect rect; - GetWindowRect(&rect); - m_window_size = rect.Size(); - } -} - - void CMediaLibDlg::OnBnClickedStatisticsInfoButton() { // TODO: 在此添加控件通知处理程序代码 @@ -308,10 +231,9 @@ void CMediaLibDlg::OnBnClickedStatisticsInfoButton() void CMediaLibDlg::OnDestroy() { - CDialog::OnDestroy(); + CBaseDialog::OnDestroy(); // TODO: 在此处添加消息处理程序代码 - SaveConfig(); // 销毁并释放子窗口内存 if (m_path_dlg != nullptr) { m_path_dlg->DestroyWindow(); delete m_path_dlg; m_path_dlg = nullptr; } diff --git a/MusicPlayer2/CMediaLibDlg.h b/MusicPlayer2/CMediaLibDlg.h index a1a62134c..16c7ed58e 100644 --- a/MusicPlayer2/CMediaLibDlg.h +++ b/MusicPlayer2/CMediaLibDlg.h @@ -1,5 +1,7 @@ #pragma once +#include "BaseDialog.h" #include "CTabCtrlEx.h" +#include "SetPathDlg.h" #include "CSelectPlaylist.h" #include "MediaClassifyDlg.h" #include "FolderExploreDlg.h" @@ -7,7 +9,7 @@ // CMediaLibDlg 对话框 -class CMediaLibDlg : public CDialog +class CMediaLibDlg : public CBaseDialog { DECLARE_DYNAMIC(CMediaLibDlg) @@ -44,30 +46,24 @@ class CMediaLibDlg : public CDialog bool NavigateToItem(const wstring& item); protected: - void SaveConfig() const; - void LoadConfig(); - + virtual CString GetDialogName() const override; + virtual bool InitializeControls() override; virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() private: CTabCtrlEx m_tab_ctrl; - CSize m_min_size{}; int m_init_tab{}; - CSize m_window_size{}; int m_tab_show_force{}; //要强制显示出来的标签 public: virtual BOOL OnInitDialog(); afx_msg void OnBnClickedPlaySelected(); - afx_msg void OnGetMinMaxInfo(MINMAXINFO* lpMMI); protected: afx_msg LRESULT OnPlaySelectedBtnEnable(WPARAM wParam, LPARAM lParam); public: - afx_msg BOOL OnEraseBkgnd(CDC* pDC); afx_msg void OnBnClickedMediaLibSettingsBtn(); - afx_msg void OnSize(UINT nType, int cx, int cy); afx_msg void OnBnClickedStatisticsInfoButton(); afx_msg void OnDestroy(); virtual void OnOK(); diff --git a/MusicPlayer2/CMiniModeUI.cpp b/MusicPlayer2/CMiniModeUI.cpp deleted file mode 100644 index 68d40d61b..000000000 --- a/MusicPlayer2/CMiniModeUI.cpp +++ /dev/null @@ -1,321 +0,0 @@ -#include "stdafx.h" -#include "CMiniModeUI.h" -#include "SongInfoHelper.h" - - -CMiniModeUI::CMiniModeUI(SMiniModeUIData& ui_data, CWnd* pMaineWnd) - : m_ui_data(ui_data), CPlayerUIBase(theApp.m_ui_data, pMaineWnd) -{ - m_font_time.CreatePointFont(80, CCommon::LoadText(IDS_DEFAULT_FONT)); -} - - -CMiniModeUI::~CMiniModeUI() -{ -} - -void CMiniModeUI::Init(CDC* pDC) -{ - CPlayerUIBase::Init(pDC); - m_first_draw = true; -} - -void CMiniModeUI::_DrawInfo(CRect draw_rect, bool reset) -{ - //绘制专辑封面 - int cover_side = m_ui_data.window_height - 2 * m_ui_data.margin; - CRect cover_rect{ CPoint(m_ui_data.margin, m_ui_data.margin), CSize(cover_side, cover_side) }; - if (theApp.m_app_setting_data.show_album_cover && CPlayer::GetInstance().AlbumCoverExist()) - { - if (theApp.m_app_setting_data.draw_album_high_quality) - m_draw.DrawImage(CPlayer::GetInstance().GetAlbumCover(), cover_rect.TopLeft(), cover_rect.Size(), theApp.m_app_setting_data.album_cover_fit); - else - m_draw.DrawBitmap(CPlayer::GetInstance().GetAlbumCover(), cover_rect.TopLeft(), cover_rect.Size(), theApp.m_app_setting_data.album_cover_fit); - } - else //专辑封面不存在时显示默认专辑封面图标 - { - if (IsDrawBackgroundAlpha()) - m_draw.FillAlphaRect(cover_rect, m_colors.color_spectrum_back, ALPHA_CHG(theApp.m_app_setting_data.background_transparency) * 2 / 3); - else - m_draw.FillRect(cover_rect, m_colors.color_spectrum_back); - - if (theApp.m_app_setting_data.draw_album_high_quality) - { - Gdiplus::Image* image{ CPlayer::GetInstance().IsPlaying() ? theApp.m_image_set.default_cover : theApp.m_image_set.default_cover_not_played }; - m_draw.DrawImage(image, cover_rect.TopLeft(), cover_rect.Size(), CDrawCommon::StretchMode::FIT); - } - else - { - //使图标在矩形框中居中 - CSize icon_size{ theApp.DPI(32), theApp.DPI(32) }; - CRect icon_rect; - icon_rect.left = cover_rect.left + (cover_rect.Width() - icon_size.cx) / 2; - icon_rect.right = icon_rect.left + icon_size.cx; - icon_rect.top = cover_rect.top + (cover_rect.Height() - icon_size.cy) / 2; - icon_rect.bottom = icon_rect.top + icon_size.cy; - - HICON& icon{ CPlayer::GetInstance().IsPlaying() ? theApp.m_icon_set.default_cover_small : theApp.m_icon_set.default_cover_small_not_played }; - m_draw.DrawIcon(icon, icon_rect.TopLeft(), icon_rect.Size()); - } - } - m_buttons[BTN_COVER].rect = cover_rect; - - //绘制播放控制按钮 - CRect rc_tmp; - rc_tmp.MoveToXY(m_ui_data.window_height, m_ui_data.margin); - rc_tmp.right = rc_tmp.left + theApp.DPI(27); - rc_tmp.bottom = rc_tmp.top + theApp.DPI(22); - DrawUIButton(rc_tmp, m_buttons[BTN_PREVIOUS], theApp.m_icon_set.previous_new); - - rc_tmp.MoveToX(rc_tmp.right + m_ui_data.margin); - if (CPlayer::GetInstance().IsPlaying()) - DrawUIButton(rc_tmp, m_buttons[BTN_PLAY_PAUSE], theApp.m_icon_set.pause_new); - else - DrawUIButton(rc_tmp, m_buttons[BTN_PLAY_PAUSE], theApp.m_icon_set.play_new); - - rc_tmp.MoveToX(rc_tmp.right + m_ui_data.margin); - DrawUIButton(rc_tmp, m_buttons[BTN_NEXT], theApp.m_icon_set.next_new); - - - //绘制频谱分析 - rc_tmp.MoveToX(rc_tmp.right + m_ui_data.margin); - rc_tmp.right = rc_tmp.left + theApp.DPI(30); - - //if (IsDrawBackgroundAlpha()) - // m_draw.FillAlphaRect(rc_tmp, m_colors.color_spectrum_back, ALPHA_CHG(theApp.m_app_setting_data.background_transparency) * 2 / 3); - //else - // m_draw.FillRect(rc_tmp, m_colors.color_spectrum_back); - m_draw.SetDrawArea(rc_tmp); - - int width{ rc_tmp.Width() / 9 }; //每个柱形的宽度 - int gap{ rc_tmp.Width() / 22 }; //柱形的间隔 - m_draw.DrawSpectrum(rc_tmp, width - gap, gap, 16, m_colors.color_spectrum, false); - - //绘制播放时间 - rc_tmp.MoveToX(rc_tmp.right + m_ui_data.margin); - rc_tmp.right = m_ui_data.widnow_width - 3 * theApp.DPI(20) - 4 * m_ui_data.margin; - rc_tmp.bottom = rc_tmp.top + theApp.DPI(16); - CString str; - if (m_ui_data.m_show_volume) - str.Format(CCommon::LoadText(IDS_VOLUME, _T(": %d%%")), CPlayer::GetInstance().GetVolume()); - else if (CPlayer::GetInstance().IsError()) - str = CCommon::LoadText(IDS_PLAY_ERROR); - else - str = CPlayer::GetInstance().GetTimeString().c_str(); - m_draw.SetFont(&m_font_time); - m_draw.DrawWindowText(rc_tmp, str, m_colors.color_text, Alignment::CENTER); - m_draw.SetFont(theApp.m_pMainWnd->GetFont()); - - //绘制进度条 - rc_tmp.MoveToY(rc_tmp.bottom); - rc_tmp.bottom = rc_tmp.top + theApp.DPI(6); - CRect progress_rect = rc_tmp; - int progress_height = theApp.DPI(2); - progress_rect.top = progress_rect.top + (rc_tmp.Height() - progress_height) / 2; - progress_rect.bottom = progress_rect.top + progress_height; - - if (IsDrawBackgroundAlpha()) - m_draw.FillAlphaRect(progress_rect, m_colors.color_spectrum_back, ALPHA_CHG(theApp.m_app_setting_data.background_transparency) * 2 / 3); - else - m_draw.FillRect(progress_rect, m_colors.color_spectrum_back); - - m_buttons[BTN_PROGRESS].rect = progress_rect; - m_buttons[BTN_PROGRESS].rect.InflateRect(0, theApp.DPI(2)); - - double progress = static_cast(CPlayer::GetInstance().GetCurrentPosition()) / CPlayer::GetInstance().GetSongLength(); - if (progress > 1) - progress = 1; - double progress_width_double{ progress * progress_rect.Width() }; - int progress_width{ static_cast(progress_width_double) }; - progress_rect.right = progress_rect.left + progress_width; - if (progress_rect.right > progress_rect.left) - m_draw.FillRect(progress_rect, m_colors.color_spectrum); - //绘制进度条最右侧一像素 - //进度条最右侧一像素根据当前进度计算出透明度,以使得进度条的变化更加平滑 - BYTE alpha{ static_cast((progress_width_double - progress_width) * 256) }; - progress_rect.left = progress_rect.right; - progress_rect.right = progress_rect.left + 1; - m_draw.FillAlphaRect(progress_rect, m_colors.color_spectrum, alpha); - - //绘制右上角按钮 - rc_tmp.right = m_ui_data.widnow_width - m_ui_data.margin; - rc_tmp.left = rc_tmp.right - theApp.DPI(20); - rc_tmp.top = m_ui_data.margin; - rc_tmp.bottom = rc_tmp.top + theApp.DPI(20); - DrawTextButton(rc_tmp, m_buttons[BTN_CLOSE], _T("×")); - - rc_tmp.MoveToX(rc_tmp.left - rc_tmp.Width() - m_ui_data.margin); - DrawUIButton(rc_tmp, m_buttons[BTN_MINI], theApp.m_icon_set.mini_restore); - - rc_tmp.MoveToX(rc_tmp.left - rc_tmp.Width() - m_ui_data.margin); - DrawTextButton(rc_tmp, m_buttons[BTN_SHOW_PLAYLIST], _T("≡")); - - //绘制右下角按钮 - rc_tmp.MoveToXY(m_ui_data.widnow_width - theApp.DPI(20) - m_ui_data.margin, m_ui_data.margin + theApp.DPI(20)); - DrawUIButton(rc_tmp, m_buttons[BTN_SELECT_FOLDER], theApp.m_icon_set.media_lib); - rc_tmp.MoveToX(rc_tmp.left - rc_tmp.Width() - m_ui_data.margin); - if (CPlayer::GetInstance().IsFavourite()) - DrawUIButton(rc_tmp, m_buttons[BTN_FAVOURITE], theApp.m_icon_set.heart); - else - DrawUIButton(rc_tmp, m_buttons[BTN_FAVOURITE], theApp.m_icon_set.favourite); - - //绘制显示文本信息 - //rc_tmp.MoveToXY(m_ui_data.window_height, m_ui_data.margin + theApp.DPI(22)); - rc_tmp.top = m_ui_data.margin + theApp.DPI(22); - rc_tmp.right = rc_tmp.left - m_ui_data.margin; - rc_tmp.left = m_ui_data.window_height; - rc_tmp.bottom = m_ui_data.window_height; - if (CPlayer::GetInstance().IsMidi() && theApp.m_general_setting_data.midi_use_inner_lyric && !CPlayer::GetInstance().MidiNoLyric()) - { - wstring current_lyric{ CPlayer::GetInstance().GetMidiLyric() }; - m_draw.DrawWindowText(rc_tmp, current_lyric.c_str(), m_colors.color_text, Alignment::CENTER); - } - else - { - const bool karaoke{ theApp.m_lyric_setting_data.lyric_karaoke_disp }; - const bool ignore_blank{ theApp.m_lyric_setting_data.donot_show_blank_lines }; - Time time{ CPlayer::GetInstance().GetCurrentPosition() }; - CLyrics::Lyric current_lyric{ CPlayer::GetInstance().m_Lyrics.GetLyric(time, false, ignore_blank, karaoke) }; // 获取当歌词 - int progress{ CPlayer::GetInstance().m_Lyrics.GetLyricProgress(time, ignore_blank, karaoke, [this](const wstring& str) { return m_draw.GetTextExtent(str.c_str()).cx; }) }; // 获取当前歌词进度(范围为0~1000) - bool no_lyric{ false }; - //如果当前一句歌词为空,且持续了超过了20秒,则不显示歌词 - no_lyric = (current_lyric.text.empty() && CPlayer::GetInstance().GetCurrentPosition() - current_lyric.time_start > 20000) || progress >= 1000; - - if (CPlayer::GetInstance().m_Lyrics.IsEmpty() || no_lyric) //没有歌词时显示播放的文件名 - { - //正在播放的文件名以滚动的样式显示。如果参数要求强制刷新,则重置滚动位置 - static CDrawCommon::ScrollInfo scroll_info; - m_draw.DrawScrollText(rc_tmp, CSongInfoHelper::GetDisplayStr(CPlayer::GetInstance().GetCurrentSongInfo(), theApp.m_media_lib_setting_data.display_format).c_str(), - m_colors.color_text, GetScrollTextPixel(true), true, scroll_info, reset); - } - else //显示歌词 - { - COLORREF color2 = (theApp.m_lyric_setting_data.lyric_karaoke_disp ? m_colors.color_text_2 : m_colors.color_text); - if (current_lyric.text.empty()) //如果当前歌词为空白,就显示为省略号 - current_lyric.text = CCommon::LoadText(IDS_DEFAULT_LYRIC_TEXT); - m_draw.DrawWindowText(rc_tmp, current_lyric.text.c_str(), m_colors.color_text, color2, progress, Alignment::CENTER); - } - } -} - -void CMiniModeUI::RButtonUp(CPoint point) -{ -} - -bool CMiniModeUI::LButtonUp(CPoint point) -{ - for (auto& btn : m_buttons) - { - btn.second.hover = false; - btn.second.pressed = false; - - if (btn.second.rect.PtInRect(point)) - { - switch (btn.first) - { - case BTN_PREVIOUS: - theApp.m_pMainWnd->SendMessage(WM_COMMAND, ID_PREVIOUS); - break; - case BTN_PLAY_PAUSE: - theApp.m_pMainWnd->SendMessage(WM_COMMAND, ID_PLAY_PAUSE); - break; - case BTN_NEXT: - theApp.m_pMainWnd->SendMessage(WM_COMMAND, ID_NEXT); - break; - case BTN_SHOW_PLAYLIST: - m_pMainWnd->SendMessage(WM_COMMAND, ID_SHOW_PLAY_LIST); - break; - case BTN_MINI: - //m_buttons[BTN_RETURN].hover = false; - m_pMainWnd->SendMessage(WM_COMMAND, IDOK); - break; - case BTN_CLOSE: - if (theApp.m_general_setting_data.minimize_to_notify_icon) - m_pMainWnd->ShowWindow(HIDE_WINDOW); - else - m_pMainWnd->SendMessage(WM_COMMAND, ID_MINI_MODE_EXIT); - break; - case BTN_SELECT_FOLDER: - m_pMainWnd->SendMessage(WM_COMMAND, ID_SET_PATH); - break; - case BTN_FAVOURITE: - m_pMainWnd->SendMessage(WM_COMMAND, ID_ADD_REMOVE_FROM_FAVOURITE); - break; - default: - break; - case BTN_COVER: - break; - case BTN_PROGRESS: - { - int ckick_pos = point.x - btn.second.rect.left; - double progress = static_cast(ckick_pos) / btn.second.rect.Width(); - if (CPlayer::GetInstance().GetPlayStatusMutex().try_lock_for(std::chrono::milliseconds(1000))) - { - CPlayer::GetInstance().SeekTo(progress); - CPlayer::GetInstance().GetPlayStatusMutex().unlock(); - } - } - break; - } - - } - } - return true; -} - -CRect CMiniModeUI::GetThumbnailClipArea() -{ - return CRect(); -} - -void CMiniModeUI::UpdateSongInfoTip(LPCTSTR str_tip) -{ - UpdateMouseToolTip(BTN_COVER, str_tip); -} - -void CMiniModeUI::UpdatePlayPauseButtonTip() -{ - if (CPlayer::GetInstance().IsPlaying() && !CPlayer::GetInstance().IsError()) - UpdateMouseToolTip(BTN_PLAY_PAUSE, CCommon::LoadText(IDS_PAUSE)); - else - UpdateMouseToolTip(BTN_PLAY_PAUSE, CCommon::LoadText(IDS_PLAY)); -} - -void CMiniModeUI::PreDrawInfo() -{ - //设置颜色 - m_colors = CPlayerUIHelper::GetUIColors(theApp.m_app_setting_data.theme_color, theApp.m_app_setting_data.dark_mode); - //设置绘图区域 - m_draw_rect = CRect(CPoint(0, 0), CSize(m_ui_data.widnow_width, m_ui_data.window_height)); -} - -void CMiniModeUI::AddMouseToolTip(BtnKey btn, LPCTSTR str) -{ - m_tool_tip.AddTool(m_pMainWnd, str, m_buttons[btn].rect, btn + 1); -} - -void CMiniModeUI::UpdateMouseToolTip(BtnKey btn, LPCTSTR str) -{ - //if (m_buttons[btn].hover) - //{ - m_tool_tip.UpdateTipText(str, m_pMainWnd, btn + 1); - //} -} - -void CMiniModeUI::UpdateToolTipPosition() -{ -} - -void CMiniModeUI::AddToolTips() -{ - AddMouseToolTip(BTN_PREVIOUS, CCommon::LoadText(IDS_PREVIOUS)); - AddMouseToolTip(BTN_PLAY_PAUSE, CPlayer::GetInstance().IsPlaying() ? CCommon::LoadText(IDS_PAUSE) : CCommon::LoadText(IDS_PLAY)); - AddMouseToolTip(BTN_NEXT, CCommon::LoadText(IDS_NEXT)); - AddMouseToolTip(BTN_SHOW_PLAYLIST, CCommon::LoadText(IDS_SHOW_HIDE_PLAYLIST)); - AddMouseToolTip(BTN_MINI, CCommon::LoadText(IDS_BACK_TO_NARMAL)); - AddMouseToolTip(BTN_CLOSE, CCommon::LoadText(IDS_CLOSE)); - AddMouseToolTip(BTN_COVER, _T("")); - AddMouseToolTip(BTN_PROGRESS, CCommon::LoadText(IDS_SEEK_TO)); - AddMouseToolTip(BTN_SELECT_FOLDER, CCommon::LoadText(IDS_MEDIA_LIB, CPlayerUIBase::GetCmdShortcutKeyForTooltips(ID_SET_PATH))); - AddMouseToolTip(BTN_FAVOURITE, CCommon::LoadText(IDS_ADD_TO_MA_FAVOURITE)); -} diff --git a/MusicPlayer2/CMiniModeUI.h b/MusicPlayer2/CMiniModeUI.h deleted file mode 100644 index 5be514219..000000000 --- a/MusicPlayer2/CMiniModeUI.h +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once -#include "IPlayerUI.h" -#include "MusicPlayer2.h" -#include "CPlayerUIHelper.h" -#include "CPlayerUIBase.h" - - -class CMiniModeUI : public CPlayerUIBase -{ -public: - - struct SMiniModeUIData - { - int widnow_width = theApp.DPI(304); - int window_height = theApp.DPI(44); - int window_height2 = theApp.DPI(336); - int margin = theApp.DPI(3); - bool m_show_volume{ false }; // 用于指示是否在显示时间的控件显示音量,当滚动鼠标滚轮时的1.5秒内,此变量的值为true - }; - -public: - CMiniModeUI(SMiniModeUIData& ui_data, CWnd* pMainWnd); - ~CMiniModeUI(); - - virtual void Init(CDC* pDC) override; - - virtual void RButtonUp(CPoint point) override; - virtual bool LButtonUp(CPoint point) override; - - virtual CRect GetThumbnailClipArea() override; - - void UpdateSongInfoTip(LPCTSTR str_tip); - void UpdatePlayPauseButtonTip(); - -private: - virtual void _DrawInfo(CRect draw_rect, bool reset = false) override; - virtual void PreDrawInfo() override; - void AddMouseToolTip(BtnKey btn, LPCTSTR str) override; //为一个按钮添加鼠标提示 - void UpdateMouseToolTip(BtnKey btn, LPCTSTR str) override; - virtual void UpdateToolTipPosition() override; - - virtual void AddToolTips() override; - - virtual bool IsDrawLargeIcon() const override { return false; } - virtual bool IsDrawStatusBar() const override { return false; } - virtual bool IsDrawTitleBar() const override { return false; } - virtual bool IsDrawMenuBar() const override { return false; } - -private: - SMiniModeUIData& m_ui_data; - CFont m_font_time; -}; diff --git a/MusicPlayer2/CNotifyIcon.cpp b/MusicPlayer2/CNotifyIcon.cpp index 49f36f68a..4a3fbb2d5 100644 --- a/MusicPlayer2/CNotifyIcon.cpp +++ b/MusicPlayer2/CNotifyIcon.cpp @@ -69,7 +69,7 @@ void CNotifyIcon::OnNotifyIcon(UINT msgId, HWND hMiniMode) //在通知区点击右键弹出右键菜单 CPoint point; GetCursorPos(&point); //获取当前光标的位置 - theApp.m_menu_set.m_notify_menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, theApp.m_pMainWnd); //在指定位置显示弹出菜单 + theApp.m_menu_mgr.GetMenu(MenuMgr::NotifyMenu)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, theApp.m_pMainWnd); //在指定位置显示弹出菜单 } if (msgId == WM_LBUTTONDBLCLK) { diff --git a/MusicPlayer2/COSUPlayerHelper.cpp b/MusicPlayer2/COSUPlayerHelper.cpp index 73b5f52d0..c1f4ecb07 100644 --- a/MusicPlayer2/COSUPlayerHelper.cpp +++ b/MusicPlayer2/COSUPlayerHelper.cpp @@ -2,6 +2,7 @@ #include "COSUPlayerHelper.h" #include "FilePathHelper.h" #include "AudioCommon.h" +#include "Common.h" COSUPlayerHelper::COSUPlayerHelper() @@ -26,7 +27,7 @@ bool COSUPlayerHelper::IsOsuFolder(const std::wstring & strPath) wstring parent_dir = path_helper.GetParentDir(); //判断一个文件是否为osu的Songs目录:它的父级目录有osu!.exe文件且文件夹是Songs - return CCommon::FileExist(parent_dir + L"osu!.exe") && folder_path.substr(folder_path.size() - 6, 5) == L"Songs"; + return folder_path.size() > 7 && folder_path.substr(folder_path.size() - 6, 5) == L"Songs" && CCommon::FileExist(parent_dir + L"osu!.exe"); } bool COSUPlayerHelper::IsOsuFile(const std::wstring& strPath) @@ -62,22 +63,15 @@ void COSUPlayerHelper::GetOSUAudioFiles(wstring path, vector& files) if(folder_name == L"." || folder_name == L"..") continue; - std::vector osu_list, song_list; + std::vector osu_list; CCommon::GetFiles(path + folder_name + L"\\*.osu", osu_list); - CAudioCommon::GetAudioFiles(path + folder_name, song_list); if(!osu_list.empty()) { - COSUFile osu_file{ (path + folder_name + L"\\" + osu_list.front()).c_str() }; - wstring file_name = osu_file.GetAudioFile(); - // 这里的file_name大小写可能与实际文件不同会导致自动更新/播放时媒体库出现大小写各一份,这里统一以音频文件为准(windows的文件存在api不区分大小写,两个都判存在 - auto it = std::find_if(song_list.begin(), song_list.end(), [&file_name](const std::wstring& str) - { - return CCommon::StringFindNoCase(str, file_name) != wstring::npos; - }); - if (it != song_list.end()) - { - files.push_back(*it); - } + COSUFile osu_file{ (path + folder_name + L'\\' + osu_list.front()).c_str() }; + wstring file_name = path + folder_name + L'\\' + osu_file.GetAudioFileName(); + // 这里的file_name大小写可能与实际文件不同会导致自动更新/播放时媒体库出现大小写各一份,这里统一以音频文件为准 + if (CCommon::CheckAndFixFile(file_name)) + files.push_back(file_name); } } } @@ -199,7 +193,7 @@ COSUFile::COSUFile(const wchar_t * file_path) GetTag("[Events]", m_events_seg); } -wstring COSUFile::GetAudioFile() +wstring COSUFile::GetAudioFileName() { return GetTagItem("AudioFilename:", m_general_seg); } diff --git a/MusicPlayer2/COSUPlayerHelper.h b/MusicPlayer2/COSUPlayerHelper.h index e607ecd91..d77f0fa36 100644 --- a/MusicPlayer2/COSUPlayerHelper.h +++ b/MusicPlayer2/COSUPlayerHelper.h @@ -23,7 +23,7 @@ class COSUFile { public: COSUFile(const wchar_t* file_path); - wstring GetAudioFile(); + wstring GetAudioFileName(); wstring GetArtist(); wstring GetTitle(); wstring GetAlbum(); diff --git a/MusicPlayer2/CPlayerUIBase.cpp b/MusicPlayer2/CPlayerUIBase.cpp index 700d26ca6..d4cc20850 100644 --- a/MusicPlayer2/CPlayerUIBase.cpp +++ b/MusicPlayer2/CPlayerUIBase.cpp @@ -9,7 +9,6 @@ CPlayerUIBase::CPlayerUIBase(UIData& ui_data, CWnd* pMainWnd) : m_ui_data(ui_data), m_pMainWnd(pMainWnd) { - //m_font_time.CreatePointFont(80, CCommon::LoadText(IDS_DEFAULT_FONT)); } @@ -21,7 +20,8 @@ CPlayerUIBase::~CPlayerUIBase() void CPlayerUIBase::Init(CDC* pDC) { m_pDC = pDC; - m_draw.Create(m_pDC, m_pMainWnd); + //m_draw.Create(m_pDC, m_pMainWnd); + m_draw.Create(m_pDC, &theApp.m_font_set.dlg.GetFont()); // m_draw的字体直接从m_font_set取得,CWnd->GetFont在不保留多语言窗口资源后不再准确 m_tool_tip.Create(m_pMainWnd, TTS_ALWAYSTIP); m_tool_tip.SetMaxTipWidth(theApp.DPI(400)); @@ -154,7 +154,7 @@ void CPlayerUIBase::DrawInfo(bool reset) CMusicPlayerDlg* pMainWindow = CMusicPlayerDlg::GetInstance(); if (pMainWindow != nullptr) { - pMainWindow->SetThumbnailClipArea(thumbnail_rect); + pMainWindow->TaskBarSetClipArea(thumbnail_rect); } last_width = m_draw_rect.Width(); @@ -202,7 +202,7 @@ void CPlayerUIBase::RButtonUp(CPoint point) GetCursorPos(&point1); //获取当前光标的位置,以便使得菜单可以跟随光标,该位置以屏幕左上角点为原点,point则以客户区左上角为原点 if (m_buttons[BTN_REPETEMODE].rect.PtInRect(point)) //如果在“循环模式”的矩形区域内点击鼠标右键,则弹出“循环模式”的子菜单 { - CMenu* pMenu = theApp.m_menu_set.m_main_popup_menu.GetSubMenu(0)->GetSubMenu(1); + CMenu* pMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::MainPlayCtrlRepeatModeMenu); ASSERT(pMenu != nullptr); if (pMenu != NULL) pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point1.x, point1.y, theApp.m_pMainWnd); @@ -211,7 +211,7 @@ void CPlayerUIBase::RButtonUp(CPoint point) if (m_buttons[BTN_SHOW_PLAYLIST].rect.PtInRect(point)) { - CMenu* pMenu = theApp.m_menu_set.m_playlist_btn_menu.GetSubMenu(0); + CMenu* pMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::MainAreaPlaylistBtnMenu); ASSERT(pMenu != nullptr); if (pMenu != NULL) pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point1.x, point1.y, theApp.m_pMainWnd); @@ -220,7 +220,7 @@ void CPlayerUIBase::RButtonUp(CPoint point) if (m_buttons[BTN_AB_REPEAT].rect.PtInRect(point)) { - CMenu* pMenu = theApp.m_menu_set.m_main_menu.GetSubMenu(1)->GetSubMenu(13); + CMenu* pMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::MainPlayCtrlAbRepeatMenu); ASSERT(pMenu != nullptr); if (pMenu != nullptr) pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point1.x, point1.y, theApp.m_pMainWnd); @@ -229,7 +229,7 @@ void CPlayerUIBase::RButtonUp(CPoint point) if (m_buttons[BTN_SKIN].rect.PtInRect(point)) { - CMenu* pMenu = theApp.m_menu_set.m_main_menu.GetSubMenu(4)->GetSubMenu(11); + CMenu* pMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::MainViewSwitchUiMenu); ASSERT(pMenu != nullptr); if (pMenu != nullptr) pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point1.x, point1.y, theApp.m_pMainWnd); @@ -243,15 +243,13 @@ void CPlayerUIBase::RButtonUp(CPoint point) return; } - if (!m_draw_data.lyric_rect.PtInRect(point)) //如果在歌词区域点击了鼠标右键 + if (m_draw_data.lyric_rect.PtInRect(point)) //如果在歌词区域点击了鼠标右键 { - theApp.m_menu_set.m_main_popup_menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point1.x, point1.y, theApp.m_pMainWnd); - } - else - { - theApp.m_menu_set.m_popup_menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point1.x, point1.y, theApp.m_pMainWnd); + theApp.m_menu_mgr.GetMenu(MenuMgr::MainAreaLrcMenu)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point1.x, point1.y, theApp.m_pMainWnd); + return; } - + // 其他区域显示主界面区域右键菜单 + theApp.m_menu_mgr.GetMenu(MenuMgr::MainAreaMenu)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point1.x, point1.y, theApp.m_pMainWnd); } void CPlayerUIBase::MouseMove(CPoint point) @@ -271,12 +269,13 @@ void CPlayerUIBase::MouseMove(CPoint point) song_pos = static_cast<__int64>(point.x - m_buttons[BTN_PROGRESS].rect.left) * CPlayer::GetInstance().GetSongLength() / m_buttons[BTN_PROGRESS].rect.Width(); Time song_pos_time; song_pos_time.fromInt(static_cast(song_pos)); - CString str; static int last_sec{}; if (last_sec != song_pos_time.sec) //只有鼠标指向位置对应的秒数变化了才更新鼠标提示 { - str.Format(CCommon::LoadText(IDS_SEEK_TO_MINUTE_SECOND), song_pos_time.min, song_pos_time.sec); - UpdateMouseToolTip(BTN_PROGRESS, str); + wstring min = std::to_wstring(song_pos_time.min); + wstring sec = std::to_wstring(song_pos_time.sec); + wstring str = theApp.m_str_table.LoadTextFormat(L"UI_TIP_SEEK_TO_MINUTE_SECOND", { min, sec.size() <= 1 ? L'0' + sec : sec }); + UpdateMouseToolTip(BTN_PROGRESS, str.c_str()); last_sec = song_pos_time.sec; } } @@ -296,16 +295,14 @@ bool CPlayerUIBase::LButtonUp(CPoint point) else //如果已经显示了音量调整按钮,则点击音量调整时保持音量调整按钮的显示 m_show_volume_adj = (m_buttons[BTN_VOLUME_UP].rect.PtInRect(point) || m_buttons[BTN_VOLUME_DOWN].rect.PtInRect(point)); - auto showMenu = [](CRect rect, int index) + auto showMenu = [](const CRect& rect, CMenu* pMenu) { CPoint point; point.x = rect.left; point.y = rect.bottom; ClientToScreen(AfxGetMainWnd()->GetSafeHwnd(), &point); - CMenu* menu = theApp.m_menu_set.m_main_menu.GetSubMenu(index); - if (menu != nullptr) - menu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, AfxGetMainWnd()); - + if (pMenu) + pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, AfxGetMainWnd()); }; for (auto& btn : m_buttons) @@ -349,14 +346,15 @@ bool CPlayerUIBase::LButtonUp(CPoint point) theApp.m_lyric_setting_data.show_translate = !theApp.m_lyric_setting_data.show_translate; return true; - case BTN_SKIN: case BTN_SKIN_TITLEBAR: + case BTN_SKIN: + case BTN_SKIN_TITLEBAR: { m_buttons[BTN_SKIN].hover = false; m_buttons[BTN_SKIN_TITLEBAR].hover = false; //theApp.m_pMainWnd->SendMessage(WM_COMMAND, ID_SWITCH_UI); CPoint point1; GetCursorPos(&point1); - CMenu* pMenu = theApp.m_menu_set.m_main_menu.GetSubMenu(4)->GetSubMenu(11); + CMenu* pMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::MainViewSwitchUiMenu); ASSERT(pMenu != nullptr); if (pMenu != nullptr) pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point1.x, point1.y, theApp.m_pMainWnd); @@ -410,15 +408,15 @@ bool CPlayerUIBase::LButtonUp(CPoint point) case BTN_SHOW_PLAYLIST: m_buttons[BTN_SHOW_PLAYLIST].hover = false; - if (theApp.m_nc_setting_data.playlist_btn_for_float_playlist) + if (theApp.m_media_lib_setting_data.playlist_btn_for_float_playlist) theApp.m_pMainWnd->SendMessage(WM_COMMAND, ID_FLOAT_PLAYLIST); else theApp.m_pMainWnd->SendMessage(WM_COMMAND, ID_SHOW_PLAYLIST); return true; - case BTN_SELECT_FOLDER: - m_buttons[BTN_SELECT_FOLDER].hover = false; - theApp.m_pMainWnd->SendMessage(WM_COMMAND, ID_SET_PATH); + case BTN_MEDIA_LIB: + m_buttons[BTN_MEDIA_LIB].hover = false; + theApp.m_pMainWnd->SendMessage(WM_COMMAND, ID_MEDIA_LIB); return true; case BTN_FAVOURITE: @@ -441,7 +439,7 @@ bool CPlayerUIBase::LButtonUp(CPoint point) m_buttons[BTN_PLAYLIST_DROP_DOWN].hover = false; CRect btn_rect = btn.second.rect; AfxGetMainWnd()->ClientToScreen(&btn_rect); - theApp.m_menu_set.m_recent_folder_playlist_menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, btn_rect.left, btn_rect.bottom, AfxGetMainWnd()); + theApp.m_menu_mgr.GetMenu(MenuMgr::RecentFolderPlaylistMenu)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, btn_rect.left, btn_rect.bottom, AfxGetMainWnd()); return true; } case BTN_PLAYLIST_MENU: @@ -449,13 +447,13 @@ bool CPlayerUIBase::LButtonUp(CPoint point) m_buttons[BTN_PLAYLIST_MENU].hover = false; CRect btn_rect = btn.second.rect; AfxGetMainWnd()->ClientToScreen(&btn_rect); - theApp.m_menu_set.m_playlist_toolbar_popup_menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, btn_rect.left, btn_rect.bottom, AfxGetMainWnd()); + theApp.m_menu_mgr.GetMenu(MenuMgr::PlaylistToolBarMenu)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, btn_rect.left, btn_rect.bottom, AfxGetMainWnd()); return true; } case BTN_VOLUME_UP: if (m_show_volume_adj) { - CPlayer::GetInstance().MusicControl(Command::VOLUME_UP, theApp.m_nc_setting_data.volum_step); + CPlayer::GetInstance().MusicControl(Command::VOLUME_ADJ, theApp.m_nc_setting_data.volum_step); return true; } break; @@ -463,7 +461,7 @@ bool CPlayerUIBase::LButtonUp(CPoint point) case BTN_VOLUME_DOWN: if (m_show_volume_adj) { - CPlayer::GetInstance().MusicControl(Command::VOLUME_DOWN, theApp.m_nc_setting_data.volum_step); + CPlayer::GetInstance().MusicControl(Command::VOLUME_ADJ, -theApp.m_nc_setting_data.volum_step); return true; } break; @@ -513,7 +511,7 @@ bool CPlayerUIBase::LButtonUp(CPoint point) { CPoint point1; GetCursorPos(&point1); - CMenu* add_to_menu = theApp.m_menu_set.m_main_popup_menu.GetSubMenu(0)->GetSubMenu(2); + CMenu* add_to_menu = theApp.m_menu_mgr.GetMenu(MenuMgr::AddToPlaylistMenu); ASSERT(add_to_menu != nullptr); if (add_to_menu != nullptr) { @@ -528,25 +526,25 @@ bool CPlayerUIBase::LButtonUp(CPoint point) //菜单 case MENU_FILE: - showMenu(btn.second.rect, 0); + showMenu(btn.second.rect, theApp.m_menu_mgr.GetMenu(MenuMgr::MainFileMenu)); return true; case MENU_PLAY_CONTROL: - showMenu(btn.second.rect, 1); + showMenu(btn.second.rect, theApp.m_menu_mgr.GetMenu(MenuMgr::MainPlayCtrlMenu)); return true; case MENU_PLAYLIST: - showMenu(btn.second.rect, 2); + showMenu(btn.second.rect, theApp.m_menu_mgr.GetMenu(MenuMgr::MainPlaylistMenu)); return true; case MENU_LYRICS: - showMenu(btn.second.rect, 3); + showMenu(btn.second.rect, theApp.m_menu_mgr.GetMenu(MenuMgr::MainLyricMenu)); return true; case MENU_VIEW: - showMenu(btn.second.rect, 4); + showMenu(btn.second.rect, theApp.m_menu_mgr.GetMenu(MenuMgr::MainViewMenu)); return true; case MENU_TOOLS: - showMenu(btn.second.rect, 5); + showMenu(btn.second.rect, theApp.m_menu_mgr.GetMenu(MenuMgr::MainToolMenu)); return true; case MENU_HELP: - showMenu(btn.second.rect, 6); + showMenu(btn.second.rect, theApp.m_menu_mgr.GetMenu(MenuMgr::MainHelpMenu)); return true; default: break; @@ -592,46 +590,48 @@ CRect CPlayerUIBase::GetThumbnailClipArea() void CPlayerUIBase::UpdateRepeatModeToolTip() { SetRepeatModeToolTipText(); - UpdateMouseToolTip(BTN_REPETEMODE, m_repeat_mode_tip); + UpdateMouseToolTip(BTN_REPETEMODE, m_repeat_mode_tip.c_str()); } void CPlayerUIBase::UpdateSongInfoToolTip() { SetSongInfoToolTipText(); - UpdateMouseToolTip(BTN_INFO, m_info_tip); + UpdateMouseToolTip(BTN_INFO, m_info_tip.c_str()); SetCoverToolTipText(); - UpdateMouseToolTip(BTN_COVER, m_cover_tip); + UpdateMouseToolTip(BTN_COVER, m_cover_tip.c_str()); } void CPlayerUIBase::UpdatePlayPauseButtonTip() { if (CPlayer::GetInstance().IsPlaying() && !CPlayer::GetInstance().IsError()) - UpdateMouseToolTip(BTN_PLAY_PAUSE, CCommon::LoadText(IDS_PAUSE)); + UpdateMouseToolTip(BTN_PLAY_PAUSE, theApp.m_str_table.LoadText(L"UI_TIP_BTN_PAUSE").c_str()); else - UpdateMouseToolTip(BTN_PLAY_PAUSE, CCommon::LoadText(IDS_PLAY)); + UpdateMouseToolTip(BTN_PLAY_PAUSE, theApp.m_str_table.LoadText(L"UI_TIP_BTN_PLAY").c_str()); } void CPlayerUIBase::UpdateFullScreenTip() { if (m_ui_data.full_screen) { - UpdateMouseToolTip(BTN_FULL_SCREEN_TITLEBAR, CCommon::LoadText(IDS_EXIT_FULL_SCREEN, GetCmdShortcutKeyForTooltips(ID_FULL_SCREEN))); - UpdateMouseToolTip(BTN_FULL_SCREEN, CCommon::LoadText(IDS_EXIT_FULL_SCREEN, GetCmdShortcutKeyForTooltips(ID_FULL_SCREEN))); + wstring tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_FULL_SCREEN_EXIT") + GetCmdShortcutKeyForTooltips(ID_FULL_SCREEN).GetString(); + UpdateMouseToolTip(BTN_FULL_SCREEN_TITLEBAR, tip_str.c_str()); + UpdateMouseToolTip(BTN_FULL_SCREEN, tip_str.c_str()); } else { - UpdateMouseToolTip(BTN_FULL_SCREEN_TITLEBAR, CCommon::LoadText(IDS_FULL_SCREEN, GetCmdShortcutKeyForTooltips(ID_FULL_SCREEN))); - UpdateMouseToolTip(BTN_FULL_SCREEN, CCommon::LoadText(IDS_FULL_SCREEN, GetCmdShortcutKeyForTooltips(ID_FULL_SCREEN))); + wstring tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_FULL_SCREEN") + GetCmdShortcutKeyForTooltips(ID_FULL_SCREEN).GetString(); + UpdateMouseToolTip(BTN_FULL_SCREEN_TITLEBAR, tip_str.c_str()); + UpdateMouseToolTip(BTN_FULL_SCREEN, tip_str.c_str()); } } void CPlayerUIBase::UpdateTitlebarBtnToolTip() { if (theApp.m_pMainWnd->IsZoomed()) - UpdateMouseToolTip(BTN_MAXIMIZE, CCommon::LoadText(IDS_RESTORE)); + UpdateMouseToolTip(BTN_MAXIMIZE, theApp.m_str_table.LoadText(L"UI_TIP_BTN_RESTORE").c_str()); else - UpdateMouseToolTip(BTN_MAXIMIZE, CCommon::LoadText(IDS_MAXIMIZE)); + UpdateMouseToolTip(BTN_MAXIMIZE, theApp.m_str_table.LoadText(L"UI_TIP_BTN_MAXIMIZE").c_str()); } bool CPlayerUIBase::SetCursor() @@ -673,48 +673,127 @@ CPlayerUIBase::UiSize CPlayerUIBase::GetUiSize() const } -IconRes CPlayerUIBase::GetBtnIcon(BtnKey key, bool big_icon) +IconMgr::IconType CPlayerUIBase::GetBtnIconType(BtnKey key) { switch (key) { - case BTN_REPETEMODE: return *GetRepeatModeIcon(); - case BTN_VOLUME: return *GetVolumeIcon(); - case BTN_SKIN: case BTN_SKIN_TITLEBAR: return theApp.m_icon_set.skin; - case BTN_EQ: return theApp.m_icon_set.eq; - case BTN_SETTING: case BTN_SETTING_TITLEBAR: return theApp.m_icon_set.setting; + case BTN_REPETEMODE: + switch (CPlayer::GetInstance().GetRepeatMode()) + { + case RepeatMode::RM_PLAY_ORDER: + return IconMgr::IconType::IT_Play_Order; + case RepeatMode::RM_LOOP_PLAYLIST: + return IconMgr::IconType::IT_Loop_Playlist; + case RepeatMode::RM_LOOP_TRACK: + return IconMgr::IconType::IT_Loop_Track; + case RepeatMode::RM_PLAY_SHUFFLE: + return IconMgr::IconType::IT_Play_Shuffle; + case RepeatMode::RM_PLAY_RANDOM: + return IconMgr::IconType::IT_Play_Random; + case RepeatMode::RM_PLAY_TRACK: + return IconMgr::IconType::IT_Play_Track; + default: + return IconMgr::IconType::IT_NO_ICON; + } + case BTN_VOLUME: + if (CPlayer::GetInstance().GetVolume() <= 0) + return IconMgr::IconType::IT_Volume0; + else if (CPlayer::GetInstance().GetVolume() >= 66) + return IconMgr::IconType::IT_Volume3; + else if (CPlayer::GetInstance().GetVolume() >= 33) + return IconMgr::IconType::IT_Volume2; + else + return IconMgr::IconType::IT_Volume1; + case BTN_SKIN: + case BTN_SKIN_TITLEBAR: + return IconMgr::IconType::IT_Skin; + case BTN_EQ: + return IconMgr::IconType::IT_Equalizer; + case BTN_SETTING: + case BTN_SETTING_TITLEBAR: + return IconMgr::IconType::IT_Setting; case BTN_MINI: + case BTN_MINI_TITLEBAR: if (IsMiniMode()) - return theApp.m_icon_set.mini_restore; + return IconMgr::IconType::IT_Mini_Off; else - return theApp.m_icon_set.mini; - case BTN_MINI_TITLEBAR: return theApp.m_icon_set.mini; - case BTN_INFO: return theApp.m_icon_set.info; - case BTN_FIND: return theApp.m_icon_set.find_songs; - case BTN_STOP: return (big_icon ? theApp.m_icon_set.stop_l : theApp.m_icon_set.stop); - case BTN_PREVIOUS: return (big_icon ? theApp.m_icon_set.previous_l : theApp.m_icon_set.previous_new); + return IconMgr::IconType::IT_Mini_On; + case BTN_INFO: + return IconMgr::IconType::IT_Info; + case BTN_FIND: + return IconMgr::IconType::IT_Find; + case BTN_STOP: + return IconMgr::IconType::IT_Stop; + case BTN_PREVIOUS: + return IconMgr::IconType::IT_Previous; case BTN_PLAY_PAUSE: if (CPlayer::GetInstance().IsPlaying()) - return (big_icon ? theApp.m_icon_set.pause_l : theApp.m_icon_set.pause_new); + return IconMgr::IconType::IT_Pause; + else + return IconMgr::IconType::IT_Play; + case BTN_NEXT: + return IconMgr::IconType::IT_Next; + case BTN_SHOW_PLAYLIST: + return IconMgr::IconType::IT_Playlist; + case BTN_MEDIA_LIB: + return IconMgr::IconType::IT_Media_Lib; + case BTN_FULL_SCREEN: + case BTN_FULL_SCREEN_TITLEBAR: + if (m_ui_data.full_screen) + return IconMgr::IconType::IT_Full_Screen_Off; + else + return IconMgr::IconType::IT_Full_Screen_On; + case BTN_MENU: + case BTN_MENU_TITLEBAR: + return IconMgr::IconType::IT_Menu; + case BTN_FAVOURITE: + if (CPlayer::GetInstance().IsFavourite()) + return IconMgr::IconType::IT_Favorite_Off; else - return (big_icon ? theApp.m_icon_set.play_l : theApp.m_icon_set.play_new); - case BTN_NEXT: return (big_icon ? theApp.m_icon_set.next_l : theApp.m_icon_set.next_new); - case BTN_SHOW_PLAYLIST: return theApp.m_icon_set.show_playlist; - case BTN_SELECT_FOLDER: return theApp.m_icon_set.media_lib; - case BTN_FULL_SCREEN_TITLEBAR: case BTN_FULL_SCREEN: return (m_ui_data.full_screen ? theApp.m_icon_set.full_screen : theApp.m_icon_set.full_screen1); - case BTN_MENU_TITLEBAR: case BTN_MENU: return theApp.m_icon_set.menu; - case BTN_FAVOURITE: return (CPlayer::GetInstance().IsFavourite() ? theApp.m_icon_set.heart : theApp.m_icon_set.favourite); - case BTN_MINIMIZE: return theApp.m_icon_set.minimize; - case BTN_MAXIMIZE: return theApp.m_icon_set.maximize; - case BTN_APP_CLOSE: return theApp.m_icon_set.close; - case BTN_ADD_TO_PLAYLIST: return theApp.m_icon_set.add; - case BTN_SWITCH_DISPLAY: return theApp.m_icon_set.switch_display; - case BTN_DARK_LIGHT: return theApp.m_icon_set.dark_mode; - case BTN_LOCATE_TO_CURRENT: return theApp.m_icon_set.locate; - case BTN_PLAYLIST_DROP_DOWN: return theApp.m_icon_set.expand; - case BTN_PLAYLIST_MENU: return theApp.m_icon_set.menu; - default: break; - } - return IconRes(); + return IconMgr::IconType::IT_Favorite_On; + case BTN_MINIMIZE: + return IconMgr::IconType::IT_Minimize; + case BTN_MAXIMIZE: + if (theApp.m_pMainWnd->IsZoomed()) + return IconMgr::IconType::IT_Maxmize_Off; + else + return IconMgr::IconType::IT_Maxmize_On; + case BTN_CLOSE: + case BTN_APP_CLOSE: + return IconMgr::IconType::IT_Close; + case BTN_ADD_TO_PLAYLIST: + return IconMgr::IconType::IT_Add; + case BTN_SWITCH_DISPLAY: + return IconMgr::IconType::IT_Switch_Display; + case BTN_DARK_LIGHT: // 之前是一个IconRes的深浅色,现拆分为两个图标类型,将来如果换图标主题要轻松一些 + if (theApp.m_app_setting_data.dark_mode) + return IconMgr::IconType::IT_Dark_Mode_Off; + else + return IconMgr::IconType::IT_Dark_Mode_On; + case BTN_LOCATE_TO_CURRENT: + return IconMgr::IconType::IT_Locate; + case BTN_PLAYLIST_DROP_DOWN: + return IconMgr::IconType::IT_Triangle_Down; + case BTN_PLAYLIST_MENU: + return IconMgr::IconType::IT_Menu; + case MENU_FILE: + return IconMgr::IconType::IT_Folder; + case MENU_PLAY_CONTROL: + return IconMgr::IconType::IT_Play; + case MENU_PLAYLIST: + return IconMgr::IconType::IT_Playlist; + case MENU_LYRICS: + return IconMgr::IconType::IT_Lyric; + case MENU_VIEW: + return IconMgr::IconType::IT_Playlist_Dock; + case MENU_TOOLS: + return IconMgr::IconType::IT_Setting; + case MENU_HELP: + return IconMgr::IconType::IT_Help; + default: + ASSERT(FALSE); + return IconMgr::IconType::IT_NO_ICON; + } } void CPlayerUIBase::PreDrawInfo() @@ -775,7 +854,7 @@ void CPlayerUIBase::DrawSongInfo(CRect rect, bool reset) if (!theApp.m_app_setting_data.always_show_statusbar) { CString play_state_str = CPlayer::GetInstance().GetPlayingState().c_str(); - //m_draw.GetDC()->SelectObject(theApp.m_pMainWnd->GetFont()); + //m_draw.GetDC()->SelectObject(&theApp.m_font_set.dlg.GetFont()); rc_tmp.right = rc_tmp.left + m_draw.GetTextExtent(play_state_str).cx + DPI(4); m_draw.DrawWindowText(rc_tmp, play_state_str, m_colors.color_text_lable); } @@ -838,10 +917,10 @@ void CPlayerUIBase::DrawSongInfo(CRect rect, bool reset) } } -void CPlayerUIBase::DrawControlBarBtn(CRect rect, UIButton& btn, const IconRes& icon) +void CPlayerUIBase::DrawControlBarBtn(CRect rect, BtnKey btn_type) { rect.DeflateRect(DPI(2), DPI(2)); - DrawUIButton(rect, btn, icon); + DrawUIButton(rect, btn_type); } void CPlayerUIBase::ResetDrawArea() @@ -921,28 +1000,26 @@ void CPlayerUIBase::DrawToolBarWithoutBackground(CRect rect, bool draw_translate //绘制循环模式 rc_tmp.right = rect.left + rect.Height(); - IconRes* pIcon = GetRepeatModeIcon(); - if (pIcon != nullptr) - DrawControlBarBtn(rc_tmp, m_buttons[BTN_REPETEMODE], *pIcon); + DrawControlBarBtn(rc_tmp, BTN_REPETEMODE); //绘制设置按钮 rc_tmp.MoveToX(rc_tmp.right); - DrawControlBarBtn(rc_tmp, m_buttons[BTN_SETTING], theApp.m_icon_set.setting); + DrawControlBarBtn(rc_tmp, BTN_SETTING); //绘制均衡器按钮 rc_tmp.MoveToX(rc_tmp.right); - DrawControlBarBtn(rc_tmp, m_buttons[BTN_EQ], theApp.m_icon_set.eq); + DrawControlBarBtn(rc_tmp, BTN_EQ); //绘制切换界面按钮 rc_tmp.MoveToX(rc_tmp.right); - DrawControlBarBtn(rc_tmp, m_buttons[BTN_SKIN], theApp.m_icon_set.skin); + DrawControlBarBtn(rc_tmp, BTN_SKIN); //绘制迷你模式按钮 if (rect.Width() >= DPI(174)) { rc_tmp.MoveToX(rc_tmp.right); //m_buttons[BTN_MINI].enable = !theApp.m_ui_data.full_screen; - DrawControlBarBtn(rc_tmp, m_buttons[BTN_MINI], theApp.m_icon_set.mini); + DrawControlBarBtn(rc_tmp, BTN_MINI); } else { @@ -953,7 +1030,7 @@ void CPlayerUIBase::DrawToolBarWithoutBackground(CRect rect, bool draw_translate if (rect.Width() >= DPI(198)) { rc_tmp.MoveToX(rc_tmp.right); - DrawControlBarBtn(rc_tmp, m_buttons[BTN_INFO], theApp.m_icon_set.info); + DrawControlBarBtn(rc_tmp, BTN_INFO); } else { @@ -964,7 +1041,7 @@ void CPlayerUIBase::DrawToolBarWithoutBackground(CRect rect, bool draw_translate if (rect.Width() >= DPI(222)) { rc_tmp.MoveToX(rc_tmp.right); - DrawControlBarBtn(rc_tmp, m_buttons[BTN_FIND], theApp.m_icon_set.find_songs); + DrawControlBarBtn(rc_tmp, BTN_FIND); } else { @@ -975,7 +1052,7 @@ void CPlayerUIBase::DrawToolBarWithoutBackground(CRect rect, bool draw_translate if (rect.Width() >= DPI(294)) { rc_tmp.MoveToX(rc_tmp.right); - DrawControlBarBtn(rc_tmp, m_buttons[BTN_DARK_LIGHT], theApp.m_icon_set.dark_mode); + DrawControlBarBtn(rc_tmp, BTN_DARK_LIGHT); } else { @@ -1012,9 +1089,9 @@ void CPlayerUIBase::DrawToolBarWithoutBackground(CRect rect, bool draw_translate if (rect.Width() >= DPI(270)) { rc_tmp.MoveToX(rc_tmp.right); - CRect translate_rect = rc_tmp; - translate_rect.DeflateRect(DPI(2), DPI(2)); - DrawTextButton(translate_rect, m_buttons[BTN_LRYIC], CCommon::LoadText(IDS_LRC), theApp.m_lyric_setting_data.show_desktop_lyric); + CRect desktop_lyric_rect = rc_tmp; + desktop_lyric_rect.DeflateRect(DPI(2), DPI(2)); + DrawDesktopLyricButton(desktop_lyric_rect); } else { @@ -1072,14 +1149,15 @@ CRect CPlayerUIBase::ClientAreaToDraw(CRect rect, CRect draw_area) return rect; } -void CPlayerUIBase::DrawUIButton(CRect rect, UIButton& btn, const IconRes& icon) +void CPlayerUIBase::DrawUIButton(const CRect& rect, BtnKey key_type, bool big_icon) { + auto& btn = m_buttons[key_type]; btn.rect = DrawAreaToClient(rect, m_draw_rect); + CRect rc_tmp = rect; if (btn.pressed && btn.enable) - rect.MoveToXY(rect.left + theApp.DPI(1), rect.top + theApp.DPI(1)); + rc_tmp.MoveToXY(rect.left + theApp.DPI(1), rect.top + theApp.DPI(1)); - CRect rc_tmp = rect; //rc_tmp.DeflateRect(DPI(2), DPI(2)); m_draw.SetDrawArea(rc_tmp); @@ -1112,49 +1190,17 @@ void CPlayerUIBase::DrawUIButton(CRect rect, UIButton& btn, const IconRes& icon) if (!theApp.m_app_setting_data.button_round_corners) m_draw.FillAlphaRect(rc_tmp, back_color, alpha); else - m_draw.DrawRoundRect(rc_tmp, back_color, CalculateRoundRectRadius(rect), alpha); + m_draw.DrawRoundRect(rc_tmp, back_color, CalculateRoundRectRadius(rc_tmp), alpha); } - bool is_light_icon = (theApp.m_app_setting_data.dark_mode || (is_close_btn && (btn.pressed || btn.hover))); - DrawUiIcon(rect, icon, !is_light_icon); + IconMgr::IconStyle icon_style = (is_close_btn && (btn.pressed || btn.hover)) ? IconMgr::IconStyle::IS_OutlinedLight : IconMgr::IconStyle::IS_Auto; + IconMgr::IconSize icon_size = big_icon ? IconMgr::IconSize::IS_DPI_20 : IconMgr::IconSize::IS_DPI_16; + DrawUiIcon(rc_tmp, GetBtnIconType(key_type), icon_style, icon_size); } -void CPlayerUIBase::DrawControlButton(CRect rect, UIButton& btn, const IconRes& icon) -{ - if (btn.pressed) - rect.MoveToXY(rect.left + theApp.DPI(1), rect.top + theApp.DPI(1)); - - CRect rc_tmp = rect; - m_draw.SetDrawArea(rc_tmp); - - if (btn.pressed || btn.hover) - { - BYTE alpha; - if (IsDrawBackgroundAlpha()) - alpha = ALPHA_CHG(theApp.m_app_setting_data.background_transparency) * 2 / 3; - else - alpha = 255; - COLORREF back_color{}; - if (btn.pressed) - back_color = m_colors.color_button_pressed; - else - back_color = m_colors.color_button_hover; - if (!theApp.m_app_setting_data.button_round_corners) - m_draw.FillAlphaRect(rc_tmp, back_color, alpha); - else - m_draw.DrawRoundRect(rc_tmp, back_color, CalculateRoundRectRadius(rect), alpha); - } - - //else if (!theApp.m_app_setting_data.dark_mode) - // m_draw.FillAlphaRect(rc_tmp, m_colors.color_button_back, alpha); - - btn.rect = DrawAreaToClient(rc_tmp, m_draw_rect); - - DrawUiIcon(rect, icon, !theApp.m_app_setting_data.dark_mode); -} - -void CPlayerUIBase::DrawTextButton(CRect rect, UIButton& btn, LPCTSTR text, bool back_color) +void CPlayerUIBase::DrawTextButton(CRect rect, BtnKey btn_type, LPCTSTR text, bool back_color) { + auto& btn = m_buttons[btn_type]; if (btn.enable) { if (btn.pressed) @@ -1242,15 +1288,23 @@ void CPlayerUIBase::UpdateVolumeToolTip() void CPlayerUIBase::UpdatePlaylistBtnToolTip() { - if (theApp.m_nc_setting_data.playlist_btn_for_float_playlist) - UpdateMouseToolTip(BTN_SHOW_PLAYLIST, CCommon::LoadText(IDS_SHOW_HIDE_PLAYLIST, GetCmdShortcutKeyForTooltips(ID_FLOAT_PLAYLIST))); + wstring tool_tip = theApp.m_str_table.LoadText(L"UI_TIP_BTN_PLAYLIST_SHOW_HIDE"); + if (theApp.m_media_lib_setting_data.playlist_btn_for_float_playlist) + tool_tip += GetCmdShortcutKeyForTooltips(ID_FLOAT_PLAYLIST).GetString(); else - UpdateMouseToolTip(BTN_SHOW_PLAYLIST, CCommon::LoadText(IDS_SHOW_HIDE_PLAYLIST, GetCmdShortcutKeyForTooltips(ID_SHOW_PLAYLIST))); + tool_tip += GetCmdShortcutKeyForTooltips(ID_SHOW_PLAYLIST).GetString(); + UpdateMouseToolTip(BTN_SHOW_PLAYLIST, tool_tip.c_str()); } void CPlayerUIBase::UpdateDarkLightModeBtnToolTip() { - UpdateMouseToolTip(BTN_DARK_LIGHT, CCommon::LoadText(theApp.m_app_setting_data.dark_mode ? IDS_SWITCH_TO_LIGHT_MODE : IDS_SWITHC_TO_DARK_MODE, GetCmdShortcutKeyForTooltips(ID_DARK_MODE))); + wstring tip_str; + if(theApp.m_app_setting_data.dark_mode) + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_DARK_LIGHT_TO_LIGHT_MODE"); + else + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_DARK_LIGHT_TO_DARK_MODE"); + tip_str += GetCmdShortcutKeyForTooltips(ID_DARK_MODE).GetString(); + UpdateMouseToolTip(BTN_DARK_LIGHT, tip_str.c_str()); } void CPlayerUIBase::UpdateToolTipPositionLater() @@ -1268,87 +1322,42 @@ void CPlayerUIBase::UpdateToolTipPosition() void CPlayerUIBase::SetRepeatModeToolTipText() { - m_repeat_mode_tip = CCommon::LoadText(IDS_REPEAT_MODE, _T(" (M): ")); - switch (CPlayer::GetInstance().GetRepeatMode()) - { - case RepeatMode::RM_PLAY_ORDER: - m_repeat_mode_tip += CCommon::LoadText(IDS_PLAY_ODER); - break; - case RepeatMode::RM_LOOP_PLAYLIST: - m_repeat_mode_tip += CCommon::LoadText(IDS_LOOP_PLAYLIST); - break; - case RepeatMode::RM_LOOP_TRACK: - m_repeat_mode_tip += CCommon::LoadText(IDS_LOOP_TRACK); - break; - case RepeatMode::RM_PLAY_SHUFFLE: - m_repeat_mode_tip += CCommon::LoadText(IDS_PLAY_SHUFFLE); - break; - case RepeatMode::RM_PLAY_RANDOM: - m_repeat_mode_tip += CCommon::LoadText(IDS_PLAY_RANDOM); - break; - case RepeatMode::RM_PLAY_TRACK: - m_repeat_mode_tip += CCommon::LoadText(IDS_PLAY_TRACK); - break; + wstring mode_str; + auto repeat_mode = CPlayer::GetInstance().GetRepeatMode(); + switch (repeat_mode) + { + case RM_PLAY_ORDER: mode_str = theApp.m_str_table.LoadText(L"UI_TIP_REPEAT_OREDE");break; + case RM_PLAY_SHUFFLE: mode_str = theApp.m_str_table.LoadText(L"UI_TIP_REPEAT_SHUFFLE"); break; + case RM_PLAY_RANDOM: mode_str = theApp.m_str_table.LoadText(L"UI_TIP_REPEAT_RANDOM"); break; + case RM_LOOP_PLAYLIST: mode_str = theApp.m_str_table.LoadText(L"UI_TIP_REPEAT_PLAYLIST"); break; + case RM_LOOP_TRACK: mode_str = theApp.m_str_table.LoadText(L"UI_TIP_REPEAT_TRACK"); break; + case RM_PLAY_TRACK: mode_str = theApp.m_str_table.LoadText(L"UI_TIP_REPEAT_ONCE"); break; + default: mode_str = L""; } + m_repeat_mode_tip = theApp.m_str_table.LoadText(L"UI_TIP_REPEAT_MODE") + L" (M): " + mode_str; } void CPlayerUIBase::SetSongInfoToolTipText() { const SongInfo& songInfo = CPlayer::GetInstance().GetCurrentSongInfo(); - m_info_tip = CCommon::LoadText(IDS_SONG_INFO, GetCmdShortcutKeyForTooltips(ID_SONG_INFO)); - m_info_tip += _T("\r\n"); - - m_info_tip += CCommon::LoadText(IDS_TITLE, _T(": ")); - m_info_tip += songInfo.GetTitle().c_str(); - m_info_tip += _T("\r\n"); - - m_info_tip += CCommon::LoadText(IDS_ARTIST, _T(": ")); - m_info_tip += songInfo.GetArtist().c_str(); - m_info_tip += _T("\r\n"); - - m_info_tip += CCommon::LoadText(IDS_ALBUM, _T(": ")); - m_info_tip += songInfo.GetAlbum().c_str(); - //m_info_tip += _T("\r\n"); - - //m_info_tip += CCommon::LoadText(IDS_BITRATE, _T(": ")); - //CString strTmp; - //strTmp.Format(_T("%d kbps"), songInfo.bitrate); - //m_info_tip += strTmp; + m_info_tip = theApp.m_str_table.LoadText(L"UI_TIP_BTN_PROPETRY") + GetCmdShortcutKeyForTooltips(ID_SONG_INFO).GetString() + L"\r\n"; + m_info_tip += theApp.m_str_table.LoadText(L"TXT_TITLE") + L": " + songInfo.GetTitle() + L"\r\n"; + m_info_tip += theApp.m_str_table.LoadText(L"TXT_ARTIST") + L": " + songInfo.GetArtist() + L"\r\n"; + m_info_tip += theApp.m_str_table.LoadText(L"TXT_ALBUM") + L": " + songInfo.GetAlbum(); } void CPlayerUIBase::SetCoverToolTipText() { if (theApp.m_nc_setting_data.show_cover_tip && theApp.m_app_setting_data.show_album_cover && CPlayer::GetInstance().AlbumCoverExist()) { - m_cover_tip = CCommon::LoadText(IDS_ALBUM_COVER, _T(": ")); - if (CPlayer::GetInstance().IsInnerCover()) - { - m_cover_tip += CCommon::LoadText(IDS_INNER_ALBUM_COVER_TIP_INFO); - switch (CPlayer::GetInstance().GetAlbumCoverType()) - { - case 0: - m_cover_tip += _T("jpg"); - break; - case 1: - m_cover_tip += _T("png"); - break; - case 2: - m_cover_tip += _T("gif"); - break; - } - } + m_cover_tip = theApp.m_str_table.LoadTextFormat(L"UI_TIP_COVER_INNER", { CPlayer::GetInstance().GetAlbumCoverType() }); else - { - m_cover_tip += CCommon::LoadText(IDS_OUT_IMAGE, _T("\r\n")); - m_cover_tip += CPlayer::GetInstance().GetAlbumCoverPath().c_str(); - } + m_cover_tip = theApp.m_str_table.LoadTextFormat(L"UI_TIP_COVER_OUT", { CPlayer::GetInstance().GetAlbumCoverPath() }); } else - { - m_cover_tip.Empty(); - } + m_cover_tip.clear(); } int CPlayerUIBase::Margin() const @@ -1465,22 +1474,12 @@ wstring CPlayerUIBase::GetDisplayFormatString() wstring result; int chans = CPlayer::GetInstance().GetChannels(); int freq = CPlayer::GetInstance().GetFreq(); - CString chans_str; - if (chans == 1) - chans_str = CCommon::LoadText(IDS_MONO); - else if (chans == 2) - chans_str = CCommon::LoadText(IDS_STEREO); - else if (chans == 6) - chans_str = CCommon::LoadText(_T("5.1 "), IDS_CHANNEL); - else if (chans == 8) - chans_str = CCommon::LoadText(_T("7.1 "), IDS_CHANNEL); - else if (chans > 2) - chans_str.Format(CCommon::LoadText(_T("%d "), IDS_CHANNEL), chans); + wstring chans_str = CSongInfoHelper::GetChannelsString(static_cast(chans)); wchar_t buff[64]; if (!CPlayer::GetInstance().IsMidi()) - swprintf_s(buff, L"%s %.1fkHz %dkbps %s", CPlayer::GetInstance().GetCurrentFileType().c_str(), freq / 1000.0f, CPlayer::GetInstance().GetCurrentSongInfo().bitrate, chans_str.GetString()); + swprintf_s(buff, L"%s %.1fkHz %dkbps %s", CPlayer::GetInstance().GetCurrentFileType().c_str(), freq / 1000.0f, CPlayer::GetInstance().GetCurrentSongInfo().bitrate, chans_str.c_str()); else - swprintf_s(buff, L"%s %.1fkHz %s", CPlayer::GetInstance().GetCurrentFileType().c_str(), freq / 1000.0f, chans_str.GetString()); + swprintf_s(buff, L"%s %.1fkHz %s", CPlayer::GetInstance().GetCurrentFileType().c_str(), freq / 1000.0f, chans_str.c_str()); result = buff; if (CPlayer::GetInstance().IsMidi()) { @@ -1494,12 +1493,15 @@ wstring CPlayerUIBase::GetDisplayFormatString() CString CPlayerUIBase::GetVolumeTooltipString() { - CString tooltip; + static const wstring& mute_str = theApp.m_str_table.LoadText(L"UI_TXT_VOLUME_MUTE"); + static const wstring& volume_adjust = theApp.m_str_table.LoadText(L"UI_TIP_VOLUME_MOUSE_WHEEL_ADJUST"); + wstring tooltip; if (CPlayer::GetInstance().GetVolume() <= 0) - tooltip.Format(_T("%s: %s\r\n%s"), CCommon::LoadText(IDS_VOLUME).GetString(), CCommon::LoadText(IDS_MUTE).GetString(), CCommon::LoadText(IDS_MOUSE_WHEEL_ADJUST_VOLUME).GetString()); + tooltip = theApp.m_str_table.LoadTextFormat(L"UI_TXT_VOLUME", { mute_str, L"" }); else - tooltip.Format(_T("%s: %d%%\r\n%s"), CCommon::LoadText(IDS_VOLUME).GetString(), CPlayer::GetInstance().GetVolume(), CCommon::LoadText(IDS_MOUSE_WHEEL_ADJUST_VOLUME).GetString()); - return tooltip; + tooltip = theApp.m_str_table.LoadTextFormat(L"UI_TXT_VOLUME", { CPlayer::GetInstance().GetVolume(), L"%" }); + tooltip += L"\r\n" + volume_adjust; + return CString(tooltip.c_str()); } int CPlayerUIBase::DPI(int pixel) const @@ -1542,7 +1544,7 @@ double CPlayerUIBase::GetScrollTextPixel(bool slower) return pixel; } -int CPlayerUIBase::CalculateRoundRectRadius(CRect rect) +int CPlayerUIBase::CalculateRoundRectRadius(const CRect& rect) { int radius{ min(rect.Width(), rect.Height()) / 6 }; if (radius < DPI(3)) @@ -1559,7 +1561,7 @@ bool CPlayerUIBase::IsDrawLargeIcon() const bool CPlayerUIBase::IsMiniMode() const { - return (dynamic_cast(this) != nullptr); + return dynamic_cast(this) != nullptr; } bool CPlayerUIBase::IsDrawNarrowMode() const @@ -1586,7 +1588,7 @@ void CPlayerUIBase::DrawVolumnAdjBtn() //如果不显示音量文本,则在音量调整按钮旁边显示音量。在这里计算文本的位置 rect_text = m_buttons[BTN_VOLUME_UP].rect; if (CPlayer::GetInstance().GetVolume() <= 0) - volume_str = CCommon::LoadText(IDS_MUTE); + volume_str = theApp.m_str_table.LoadText(L"UI_TXT_VOLUME_MUTE").c_str(); else volume_str.Format(_T("%d%%"), CPlayer::GetInstance().GetVolume()); int width{ m_draw.GetTextExtent(volume_str).cx }; @@ -1697,17 +1699,16 @@ void CPlayerUIBase::DrawControlBar(CRect rect, bool draw_switch_display_btn) const int btn_height = min(rect.Height(), btn_width); CRect rc_btn{ CPoint(rect.left, rect.top + (rect.Height() - btn_height) / 2), CSize(btn_width, btn_height) }; - DrawControlButton(rc_btn, m_buttons[BTN_STOP], theApp.m_icon_set.stop_l); + DrawUIButton(rc_btn, BTN_STOP, true); rc_btn.MoveToX(rc_btn.right); - DrawControlButton(rc_btn, m_buttons[BTN_PREVIOUS], theApp.m_icon_set.previous_l); + DrawUIButton(rc_btn, BTN_PREVIOUS, true); rc_btn.MoveToX(rc_btn.right); - IconRes& paly_pause_icon = CPlayer::GetInstance().IsPlaying() ? theApp.m_icon_set.pause_l : theApp.m_icon_set.play_l; - DrawControlButton(rc_btn, m_buttons[BTN_PLAY_PAUSE], paly_pause_icon); + DrawUIButton(rc_btn, BTN_PLAY_PAUSE, true); rc_btn.MoveToX(rc_btn.right); - DrawControlButton(rc_btn, m_buttons[BTN_NEXT], theApp.m_icon_set.next_l); + DrawUIButton(rc_btn, BTN_NEXT, true); int progressbar_left = rc_btn.right + Margin(); @@ -1717,23 +1718,20 @@ void CPlayerUIBase::DrawControlBar(CRect rect, bool draw_switch_display_btn) rc_btn.left = rc_btn.right - btn_side; rc_btn.top = rect.top + (rect.Height() - btn_side) / 2; rc_btn.bottom = rc_btn.top + btn_side; - DrawControlBarBtn(rc_btn, m_buttons[BTN_SHOW_PLAYLIST], theApp.m_icon_set.show_playlist); + DrawControlBarBtn(rc_btn, BTN_SHOW_PLAYLIST); rc_btn.MoveToX(rc_btn.left - btn_side); - m_buttons[BTN_SELECT_FOLDER].enable = !CPlayer::GetInstance().m_loading; - DrawControlBarBtn(rc_btn, m_buttons[BTN_SELECT_FOLDER], theApp.m_icon_set.media_lib); + m_buttons[BTN_MEDIA_LIB].enable = !CPlayer::GetInstance().m_loading; + DrawControlBarBtn(rc_btn, BTN_MEDIA_LIB); if (draw_switch_display_btn) { rc_btn.MoveToX(rc_btn.left - btn_side); - DrawControlBarBtn(rc_btn, m_buttons[BTN_SWITCH_DISPLAY], theApp.m_icon_set.switch_display); + DrawControlBarBtn(rc_btn, BTN_SWITCH_DISPLAY); } rc_btn.MoveToX(rc_btn.left - btn_side); - if (CPlayer::GetInstance().IsFavourite()) - DrawControlBarBtn(rc_btn, m_buttons[BTN_FAVOURITE], theApp.m_icon_set.heart); - else - DrawControlBarBtn(rc_btn, m_buttons[BTN_FAVOURITE], theApp.m_icon_set.favourite); + DrawControlBarBtn(rc_btn, BTN_FAVOURITE); if (!progress_on_top) { @@ -1856,8 +1854,15 @@ void CPlayerUIBase::DrawProgess(CRect rect) void CPlayerUIBase::DrawTranslateButton(CRect rect) { + static const wstring& btn_str = theApp.m_str_table.LoadText(L"UI_TXT_BTN_TRANSLATE"); m_buttons[BTN_TRANSLATE].enable = !CPlayer::GetInstance().m_Lyrics.IsEmpty(); - DrawTextButton(rect, m_buttons[BTN_TRANSLATE], CCommon::LoadText(IDS_TRAS), theApp.m_lyric_setting_data.show_translate); + DrawTextButton(rect, BTN_TRANSLATE, btn_str.c_str(), theApp.m_lyric_setting_data.show_translate); +} + +void CPlayerUIBase::DrawDesktopLyricButton(CRect rect) +{ + static const wstring& btn_str = theApp.m_str_table.LoadText(L"UI_TXT_BTN_DESKTOP_LYRIC"); + DrawTextButton(rect, BTN_LRYIC, btn_str.c_str(), theApp.m_lyric_setting_data.show_desktop_lyric); } int CPlayerUIBase::DrawTopRightIcons(bool always_show_full_screen) @@ -1877,8 +1882,7 @@ int CPlayerUIBase::DrawTopRightIcons(bool always_show_full_screen) rc_tmp.top = EdgeMargin(false); rc_tmp.bottom = rc_tmp.top + icon_size; rc_tmp.left = rc_tmp.right - icon_size; - IconRes& icon{ m_ui_data.full_screen ? theApp.m_icon_set.full_screen : theApp.m_icon_set.full_screen1 }; - DrawControlButton(rc_tmp, m_buttons[BTN_FULL_SCREEN_TITLEBAR], icon); + DrawUIButton(rc_tmp, BTN_FULL_SCREEN_TITLEBAR); total_width += Margin(); } else @@ -1894,7 +1898,7 @@ int CPlayerUIBase::DrawTopRightIcons(bool always_show_full_screen) rc_tmp.top = EdgeMargin(false); rc_tmp.bottom = rc_tmp.top + icon_size; rc_tmp.left = rc_tmp.right - icon_size; - DrawControlButton(rc_tmp, m_buttons[BTN_MENU_TITLEBAR], theApp.m_icon_set.menu); + DrawUIButton(rc_tmp, BTN_MENU_TITLEBAR); total_width += icon_size; total_width += Margin(); } @@ -2001,44 +2005,35 @@ void CPlayerUIBase::DrawStatusBar(CRect rect, bool reset) rc_tmp.right = rc_tmp.left - DPI(4); rc_tmp.left = rect.left; static CDrawCommon::ScrollInfo scroll_info0; - CString info; - info = CCommon::LoadTextFormat(IDS_PLAYLIST_INIT_INFO, { CPlayer::GetInstance().GetSongNum() }); - m_draw.DrawScrollText(rc_tmp, info, m_colors.color_text, GetScrollTextPixel(), false, scroll_info0, reset); + wstring info = theApp.m_str_table.LoadTextFormat(L"UI_TXT_PLAYLIST_INIT_INFO", { CPlayer::GetInstance().GetSongNum() }); + m_draw.DrawScrollText(rc_tmp, info.c_str(), m_colors.color_text, GetScrollTextPixel(), false, scroll_info0, reset); } //显示AB重复状态 else if (CPlayer::GetInstance().GetABRepeatMode() != CPlayer::AM_NONE) { - CString info; + wstring info; if (CPlayer::GetInstance().GetABRepeatMode() == CPlayer::AM_A_SELECTED) - info = CCommon::LoadTextFormat(IDS_AB_REPEAT_A_SELECTED, { CPlayer::GetInstance().GetARepeatPosition().toString(false) }); + info = theApp.m_str_table.LoadTextFormat(L"UI_TXT_AB_REPEAT_A_SELECTED", { CPlayer::GetInstance().GetARepeatPosition().toString(false) }); else if (CPlayer::GetInstance().GetABRepeatMode() == CPlayer::AM_AB_REPEAT) - info = CCommon::LoadTextFormat(IDS_AB_REPEAT_ON_INFO, { CPlayer::GetInstance().GetARepeatPosition().toString(false), CPlayer::GetInstance().GetBRepeatPosition().toString(false) }); - m_draw.DrawWindowText(rect, info, m_colors.color_text); + info = theApp.m_str_table.LoadTextFormat(L"UI_TXT_AB_REPEAT_ON", { CPlayer::GetInstance().GetARepeatPosition().toString(false), CPlayer::GetInstance().GetBRepeatPosition().toString(false) }); + m_draw.DrawWindowText(rect, info.c_str(), m_colors.color_text); } //显示媒体库更新状态 else if (theApp.IsMeidaLibUpdating() && theApp.m_media_update_para.num_added > 0) { - CString info = CCommon::LoadTextFormat(IDS_UPDATING_MEDIA_LIB_INFO, { theApp.m_media_update_para.num_added }); - CString str; - str.Format(_T(" %d%%"), theApp.m_media_update_para.num_added * 100 / theApp.m_media_update_para.total_num); - info += str; + wstring info = theApp.m_str_table.LoadTextFormat(L"UI_TXT_MEDIA_LIB_UPDATING_INFO", + { theApp.m_media_update_para.num_added, theApp.m_media_update_para.process_percent }); static CDrawCommon::ScrollInfo scroll_info2; - m_draw.DrawScrollText(rect, info, m_colors.color_text, GetScrollTextPixel(), false, scroll_info2, reset); + m_draw.DrawScrollText(rect, info.c_str(), m_colors.color_text, GetScrollTextPixel(), false, scroll_info2, reset); } else { //显示播放信息 wstring str_info; if (CPlayer::GetInstance().IsError()) - { - str_info = CCommon::LoadText(IDS_PLAY_ERROR).GetString(); - str_info += L": "; - str_info += CPlayer::GetInstance().GetErrorInfo(); - } + str_info = CPlayer::GetInstance().GetErrorInfo(); else - { str_info = CPlayer::GetInstance().GetPlayingState(); - } int text_width = m_draw.GetTextExtent(str_info.c_str()).cx; CRect rect_play{ rect }; rect_play.right = rect_play.left + text_width + theApp.DPI(8); @@ -2047,11 +2042,11 @@ void CPlayerUIBase::DrawStatusBar(CRect rect, bool reset) //显示下一个播放曲目 if (theApp.m_app_setting_data.show_next_track) { - static CString str_next_track_label = CCommon::LoadText(IDS_NEXT_TRACK, _T(": ")); + static wstring str_next_track_label = theApp.m_str_table.LoadText(L"UI_TXT_NEXT_TRACK"); CRect rect_next_track{ rect }; rect_next_track.left = rect_play.right; - rect_next_track.right = rect_next_track.left + m_draw.GetTextExtent(str_next_track_label).cx; - m_draw.DrawWindowText(rect_next_track, str_next_track_label.GetString(), m_colors.color_text); + rect_next_track.right = rect_next_track.left + m_draw.GetTextExtent(str_next_track_label.c_str()).cx; + m_draw.DrawWindowText(rect_next_track, str_next_track_label.c_str(), m_colors.color_text); rect_next_track.left = rect_next_track.right; rect_next_track.right = rect.right; @@ -2060,9 +2055,9 @@ void CPlayerUIBase::DrawStatusBar(CRect rect, bool reset) if (next_song.IsEmpty()) { if (CPlayer::GetInstance().GetRepeatMode() == RM_PLAY_RANDOM || CPlayer::GetInstance().GetRepeatMode() == RM_PLAY_SHUFFLE) - str_next_song += CCommon::LoadText(IDS_RANDOM_TRACK).GetString(); + str_next_song += theApp.m_str_table.LoadText(L"UI_TXT_NEXT_TRACK_RANDOM"); else - str_next_song += CCommon::LoadText(IDS_NONE).GetString(); + str_next_song += theApp.m_str_table.LoadText(L"UI_TXT_NEXT_TRACK_NONE"); } else { @@ -2092,22 +2087,20 @@ void CPlayerUIBase::DrawTitleBar(CRect rect) m_draw.FillRect(rect, m_colors.color_control_bar_back); //绘制应用图标 - auto app_icon = theApp.m_icon_set.app; CRect rect_temp = rect; rect_temp.right = rect_temp.left + m_layout.titlabar_height; - DrawUiIcon(rect_temp, app_icon, false); + DrawUiIcon(rect_temp, IconMgr::IconType::IT_App); //绘制右侧图标 rect_temp = rect; rect_temp.left = rect_temp.right - theApp.DPI(30); //关闭图标 - DrawUIButton(rect_temp, m_buttons[BTN_APP_CLOSE], theApp.m_icon_set.app_close); + DrawUIButton(rect_temp, BTN_APP_CLOSE); //最大化/还原图标 if (theApp.m_app_setting_data.show_maximize_btn_in_titlebar) { rect_temp.MoveToX(rect_temp.left - rect_temp.Width()); - auto max_icon = (theApp.m_pMainWnd->IsZoomed() ? theApp.m_icon_set.restore : theApp.m_icon_set.maximize); - DrawUIButton(rect_temp, m_buttons[BTN_MAXIMIZE], max_icon); + DrawUIButton(rect_temp, BTN_MAXIMIZE); } else { @@ -2117,7 +2110,7 @@ void CPlayerUIBase::DrawTitleBar(CRect rect) if (theApp.m_app_setting_data.show_minimize_btn_in_titlebar) { rect_temp.MoveToX(rect_temp.left - rect_temp.Width()); - DrawUIButton(rect_temp, m_buttons[BTN_MINIMIZE], theApp.m_icon_set.minimize); + DrawUIButton(rect_temp, BTN_MINIMIZE); } else { @@ -2127,7 +2120,7 @@ void CPlayerUIBase::DrawTitleBar(CRect rect) if (theApp.m_app_setting_data.show_fullscreen_btn_in_titlebar) { rect_temp.MoveToX(rect_temp.left - rect_temp.Width()); - DrawUIButton(rect_temp, m_buttons[BTN_FULL_SCREEN_TITLEBAR], theApp.m_icon_set.full_screen1); + DrawUIButton(rect_temp, BTN_FULL_SCREEN_TITLEBAR); } else { @@ -2137,7 +2130,7 @@ void CPlayerUIBase::DrawTitleBar(CRect rect) if (theApp.m_app_setting_data.show_minimode_btn_in_titlebar) { rect_temp.MoveToX(rect_temp.left - rect_temp.Width()); - DrawUIButton(rect_temp, m_buttons[BTN_MINI_TITLEBAR], theApp.m_icon_set.mini); + DrawUIButton(rect_temp, BTN_MINI_TITLEBAR); } else { @@ -2147,7 +2140,7 @@ void CPlayerUIBase::DrawTitleBar(CRect rect) if (theApp.m_app_setting_data.show_skin_btn_in_titlebar) { rect_temp.MoveToX(rect_temp.left - rect_temp.Width()); - DrawUIButton(rect_temp, m_buttons[BTN_SKIN_TITLEBAR], theApp.m_icon_set.skin); + DrawUIButton(rect_temp, BTN_SKIN_TITLEBAR); } else { @@ -2157,7 +2150,7 @@ void CPlayerUIBase::DrawTitleBar(CRect rect) if (theApp.m_app_setting_data.show_settings_btn_in_titlebar) { rect_temp.MoveToX(rect_temp.left - rect_temp.Width()); - DrawUIButton(rect_temp, m_buttons[BTN_SETTING_TITLEBAR], theApp.m_icon_set.setting); + DrawUIButton(rect_temp, BTN_SETTING_TITLEBAR); } else { @@ -2167,7 +2160,7 @@ void CPlayerUIBase::DrawTitleBar(CRect rect) if (!m_ui_data.ShowUiMenuBar()) { rect_temp.MoveToX(rect_temp.left - rect_temp.Width()); - DrawUIButton(rect_temp, m_buttons[BTN_MENU_TITLEBAR], theApp.m_icon_set.menu); + DrawUIButton(rect_temp, BTN_MENU_TITLEBAR); } else { @@ -2178,7 +2171,7 @@ void CPlayerUIBase::DrawTitleBar(CRect rect) rect_temp.right = rect_temp.left; rect_temp.left = m_layout.titlabar_height; static CDrawCommon::ScrollInfo scroll_info{}; - m_draw.DrawScrollText(rect_temp, theApp.m_window_title.GetString(), m_colors.color_text, GetScrollTextPixel(), false, scroll_info); + m_draw.DrawScrollText(rect_temp, theApp.m_window_title.c_str(), m_colors.color_text, GetScrollTextPixel(), false, scroll_info); //m_draw.DrawWindowText(rect_temp, title.GetString(), m_colors.color_text); } @@ -2199,6 +2192,23 @@ CString CPlayerUIBase::GetCmdShortcutKeyForTooltips(UINT id) return CString(); } +void CPlayerUIBase::ReplaceUiStringRes(wstring& str) +{ + size_t index{}; + while ((index = str.find(L"%(", index)) != wstring::npos) + { + size_t right_bracket_index = str.find(L')', index + 2); + if (right_bracket_index == wstring::npos) + break; + wstring key_str{ str.begin() + index + 2 , str.begin() + right_bracket_index }; + const wstring& value_str = theApp.m_str_table.LoadText(key_str); + if (value_str == StrTable::error_str) // LoadText内部已记录错误日志 + break; + str.replace(index, right_bracket_index + 1, value_str); + index = right_bracket_index + 1; + } +} + void CPlayerUIBase::DrawAlbumCover(CRect rect) { m_draw.SetDrawArea(rect); @@ -2216,7 +2226,7 @@ void CPlayerUIBase::DrawAlbumCover(CRect rect) rc_temp.DeflateRect(cover_margin, cover_margin); if (theApp.m_app_setting_data.draw_album_high_quality) { - Gdiplus::Image* image{ CPlayer::GetInstance().IsPlaying() ? theApp.m_image_set.default_cover : theApp.m_image_set.default_cover_not_played }; + Gdiplus::Image* image{ CPlayer::GetInstance().IsPlaying() ? theApp.m_image_set.default_cover_img : theApp.m_image_set.default_cover_not_played_img }; m_draw.DrawImage(image, rc_temp.TopLeft(), rc_temp.Size(), CDrawCommon::StretchMode::FIT); } else @@ -2224,8 +2234,13 @@ void CPlayerUIBase::DrawAlbumCover(CRect rect) int cover_side = min(rc_temp.Width(), rc_temp.Height()); int x = rc_temp.left + (rc_temp.Width() - cover_side) / 2; int y = rc_temp.top + (rc_temp.Height() - cover_side) / 2; - HICON& icon{ CPlayer::GetInstance().IsPlaying() ? theApp.m_icon_set.default_cover : theApp.m_icon_set.default_cover_not_played }; - m_draw.DrawIcon(icon, CPoint(x, y), CSize(cover_side, cover_side)); + + IconMgr::IconType icon_type = IconMgr::IconType::IT_Default_Cover_Stopped; + if (CPlayer::GetInstance().IsPlaying()) + icon_type = IconMgr::IconType::IT_Default_Cover_Playing; + HICON hIcon = theApp.m_icon_mgr.GetHICON(icon_type, IconMgr::IconStyle::IS_Color, IconMgr::IconSize::IS_ORG_512); + + m_draw.DrawIcon(hIcon, CPoint(x, y), CSize(cover_side, cover_side)); } } ResetDrawArea(); @@ -2326,8 +2341,7 @@ void CPlayerUIBase::DrawVolumeButton(CRect rect, bool adj_btn_top, bool show_tex //绘制图标 CRect rect_icon{ rect }; rect_icon.right = rect_icon.left + rect_icon.Height(); - IconRes* icon{ GetVolumeIcon() }; - DrawUiIcon(rect_icon, *icon, !theApp.m_app_setting_data.dark_mode); + DrawUiIcon(rect_icon, GetBtnIconType(BTN_VOLUME)); //绘制文本 if (show_text && rect_icon.right < rect.right) @@ -2336,7 +2350,7 @@ void CPlayerUIBase::DrawVolumeButton(CRect rect, bool adj_btn_top, bool show_tex rect_text.left = rect_icon.right; CString str; if (CPlayer::GetInstance().GetVolume() <= 0) - str = CCommon::LoadText(IDS_MUTE).GetString(); + str = theApp.m_str_table.LoadText(L"UI_TXT_VOLUME_MUTE").c_str(); else str.Format(_T("%d%%"), CPlayer::GetInstance().GetVolume()); if (m_buttons[BTN_VOLUME].hover) //鼠标指向音量区域时,以另外一种颜色显示 @@ -2374,20 +2388,17 @@ void CPlayerUIBase::DrawABRepeatButton(CRect rect) info = _T("A-B"); CFont* pOldFont = m_draw.GetFont(); m_draw.SetFont(&theApp.m_font_set.font8.GetFont(theApp.m_ui_data.full_screen)); //AB重复使用小一号字体,即播放时间的字体 - DrawTextButton(rect, m_buttons[BTN_AB_REPEAT], info, ab_repeat_mode != CPlayer::AM_NONE); + DrawTextButton(rect, BTN_AB_REPEAT, info, ab_repeat_mode != CPlayer::AM_NONE); m_draw.SetFont(pOldFont); } -void CPlayerUIBase::DrawLyrics(CRect rect, int margin) +void CPlayerUIBase::DrawLyrics(CRect rect, CFont* lyric_font, CFont* lyric_tr_font, bool with_background) { if (rect.Height() < DPI(4)) return; - if (margin < 0) - margin = Margin(); - //填充歌词区域背景 - if (theApp.m_app_setting_data.lyric_background) + if (with_background && theApp.m_app_setting_data.lyric_background) { BYTE alpha = 255; if (IsDrawBackgroundAlpha()) @@ -2403,11 +2414,11 @@ void CPlayerUIBase::DrawLyrics(CRect rect, int margin) } } //设置歌词文字区域 - if (margin > 0) - rect.DeflateRect(margin, margin); - //CDrawCommon::SetDrawArea(pDC, lyric_area); + int margin = Margin(); + rect.DeflateRect(margin, margin); //绘制歌词文本 + m_draw.SetLyricFont(lyric_font, lyric_tr_font); m_draw.DrawLryicCommon(rect, theApp.m_lyric_setting_data.lyric_align); } @@ -2417,7 +2428,8 @@ void CPlayerUIBase::DrawPlaylist(CRect rect, UiElement::Playlist* playlist_eleme if (CPlayer::GetInstance().IsPlaylistEmpty()) { - m_draw.DrawWindowText(rect, CCommon::LoadText(IDS_PLAYLIST_EMPTY_INFO), m_colors.color_text); + const wstring& info = theApp.m_str_table.LoadText(L"UI_PLAYLIST_EMPTY_INFO"); + m_draw.DrawWindowText(rect, info.c_str(), m_colors.color_text); } else { @@ -2570,22 +2582,26 @@ void CPlayerUIBase::DrawPlaylist(CRect rect, UiElement::Playlist* playlist_eleme void CPlayerUIBase::DrawCurrentPlaylistIndicator(CRect rect) { //绘制图标 - const IconRes& icon{ CPlayer::GetInstance().IsPlaylistMode() ? theApp.m_icon_set.show_playlist : theApp.m_icon_set.select_folder }; + IconMgr::IconType icon_type = CPlayer::GetInstance().IsPlaylistMode() ? IconMgr::IconType::IT_Playlist : IconMgr::IconType::IT_Folder; CRect rect_icon{ rect }; rect_icon.right = rect_icon.left + DPI(26); - DrawUiIcon(rect_icon, icon, !theApp.m_app_setting_data.dark_mode); + DrawUiIcon(rect_icon, icon_type); //绘制文本 - CString str{ CCommon::LoadText(CPlayer::GetInstance().IsPlaylistMode() ? IDS_PLAYLIST : IDS_FOLDER, _T(":")) }; + wstring str; + if (CPlayer::GetInstance().IsPlaylistMode()) + str = theApp.m_str_table.LoadText(L"UI_TXT_PLAYLIST"); + else + str = theApp.m_str_table.LoadText(L"UI_TXT_FOLDER"); CRect rect_text{ rect }; rect_text.left = rect_icon.right; - rect_text.right = rect_text.left + m_draw.GetTextExtent(str).cx; - m_draw.DrawWindowText(rect_text, str, m_colors.color_text, Alignment::LEFT, true); + rect_text.right = rect_text.left + m_draw.GetTextExtent(str.c_str()).cx; + m_draw.DrawWindowText(rect_text, str.c_str(), m_colors.color_text, Alignment::LEFT, true); //绘制菜单按钮 CRect menu_btn_rect{ rect }; menu_btn_rect.left = rect.right - DPI(26); const int icon_size{ (std::min)(DPI(24), rect.Height()) }; CRect menu_btn_icon_rect = CDrawCommon::CalculateCenterIconRect(menu_btn_rect, icon_size); - DrawUIButton(menu_btn_icon_rect, m_buttons[BTN_PLAYLIST_MENU], GetBtnIcon(BTN_PLAYLIST_MENU, IsDrawLargeIcon())); + DrawUIButton(menu_btn_icon_rect, BTN_PLAYLIST_MENU); //绘制当前播放列表名称 CRect rect_name{ rect }; rect_name.left = rect_text.right + DPI(8); @@ -2608,7 +2624,7 @@ void CPlayerUIBase::DrawCurrentPlaylistIndicator(CRect rect) rect_drop_down.left = rect_name.right + DPI(2); rect_drop_down.right = menu_btn_rect.left - DPI(6); CRect rect_drop_down_btn = CDrawCommon::CalculateCenterIconRect(rect_drop_down, icon_size); - DrawUIButton(rect_drop_down_btn, m_buttons[BTN_PLAYLIST_DROP_DOWN], GetBtnIcon(BTN_PLAYLIST_DROP_DOWN, IsDrawLargeIcon())); + DrawUIButton(rect_drop_down_btn, BTN_PLAYLIST_DROP_DOWN); } void CPlayerUIBase::DrawStackIndicator(UIButton indicator, int num, int index) @@ -2677,12 +2693,11 @@ void CPlayerUIBase::DrawUiMenuBar(CRect rect) CRect rc_item{ rect }; rc_item.bottom = rc_item.top + DPI(20); rc_item.left += DPI(4); - auto drawMenuItem = [&](BtnKey key, IconRes icon, UINT str_id) + auto drawMenuItem = [&](BtnKey key, LPCTSTR menu_str) { - CString text = CCommon::LoadText(str_id); UIButton& btn{ m_buttons[key] }; btn.rect = rc_item; - btn.rect.right = btn.rect.left + btn.rect.Height() + m_draw.GetTextExtent(text).cx + DPI(6); + btn.rect.right = btn.rect.left + btn.rect.Height() + m_draw.GetTextExtent(menu_str).cx + DPI(6); CRect rc_cur_item{ btn.rect }; if (btn.pressed && btn.enable) @@ -2713,7 +2728,9 @@ void CPlayerUIBase::DrawUiMenuBar(CRect rect) CRect rc_icon{ rc_cur_item }; rc_icon.left += DPI(2); rc_icon.right = rc_icon.left + rc_icon.Height(); - const HICON& hIcon = icon.GetIcon(!theApp.m_app_setting_data.dark_mode, IsDrawLargeIcon()); + HICON hIcon = theApp.m_icon_mgr.GetHICON(GetBtnIconType(key), + theApp.m_app_setting_data.dark_mode ? IconMgr::IconStyle::IS_OutlinedLight : IconMgr::IconStyle::IS_OutlinedDark, + IsDrawLargeIcon() ? IconMgr::IconSize::IS_DPI_16_Full_Screen : IconMgr::IconSize::IS_DPI_16); m_draw.SetDrawArea(rc_icon); m_draw.DrawIcon(hIcon, rc_icon, DPI(16)); @@ -2721,76 +2738,47 @@ void CPlayerUIBase::DrawUiMenuBar(CRect rect) CRect rc_text{ rc_cur_item }; rc_text.left = rc_icon.right; rc_text.right = btn.rect.right; - m_draw.DrawWindowText(rc_text, text, m_colors.color_text); + m_draw.DrawWindowText(rc_text, menu_str, m_colors.color_text); //下一个矩形的位置 rc_item.left = rc_text.right + DPI(2); }; - - drawMenuItem(MENU_FILE, theApp.m_icon_set.select_folder, IDS_FILE); //文件 - drawMenuItem(MENU_PLAY_CONTROL, theApp.m_icon_set.play_new, IDS_PLAY_CONTROL); //播放控制 - drawMenuItem(MENU_PLAYLIST, theApp.m_icon_set.show_playlist, IDS_PLAYLIST); //播放列表 - drawMenuItem(MENU_LYRICS, theApp.m_icon_set.lyric, IDS_LYRICS); //歌词 - drawMenuItem(MENU_VIEW, theApp.m_icon_set.playlist_dock, IDS_VIEW); //视图 - drawMenuItem(MENU_TOOLS, theApp.m_icon_set.setting, IDS_TOOLS); //工具 - drawMenuItem(MENU_HELP, theApp.m_icon_set.help, IDS_HELP); //帮助 + // 自绘的菜单栏不支持助记键,显示的字符串与系统菜单栏不同,所以这里的字符串使用LoadText而不是LoadMenuText + static const wstring& menu_name_file = theApp.m_str_table.LoadText(L"UI_TXT_MENU_FILE"); + static const wstring& menu_name_play_control = theApp.m_str_table.LoadText(L"UI_TXT_MENU_PLAY_CONTROL"); + static const wstring& menu_name_playlist = theApp.m_str_table.LoadText(L"UI_TXT_MENU_PLAYLIST"); + static const wstring& menu_name_lyrics = theApp.m_str_table.LoadText(L"UI_TXT_MENU_LYRICS"); + static const wstring& menu_name_view = theApp.m_str_table.LoadText(L"UI_TXT_MENU_VIEW"); + static const wstring& menu_name_tools = theApp.m_str_table.LoadText(L"UI_TXT_MENU_TOOLS"); + static const wstring& menu_name_help = theApp.m_str_table.LoadText(L"UI_TXT_MENU_HELP"); + drawMenuItem(MENU_FILE, menu_name_file.c_str()); //文件 + drawMenuItem(MENU_PLAY_CONTROL, menu_name_play_control.c_str()); //播放控制 + drawMenuItem(MENU_PLAYLIST, menu_name_playlist.c_str()); //播放列表 + drawMenuItem(MENU_LYRICS, menu_name_lyrics.c_str()); //歌词 + drawMenuItem(MENU_VIEW, menu_name_view.c_str()); //视图 + drawMenuItem(MENU_TOOLS, menu_name_tools.c_str()); //工具 + drawMenuItem(MENU_HELP, menu_name_help.c_str()); //帮助 ResetDrawArea(); } -IconRes* CPlayerUIBase::GetRepeatModeIcon() +void CPlayerUIBase::DrawUiIcon(const CRect& rect, IconMgr::IconType icon_type, IconMgr::IconStyle icon_style, IconMgr::IconSize icon_size) { - IconRes* pIcon = nullptr; - switch (CPlayer::GetInstance().GetRepeatMode()) - { - case RepeatMode::RM_PLAY_ORDER: - pIcon = &theApp.m_icon_set.play_oder; - break; - case RepeatMode::RM_LOOP_PLAYLIST: - pIcon = &theApp.m_icon_set.loop_playlist; - break; - case RepeatMode::RM_LOOP_TRACK: - pIcon = &theApp.m_icon_set.loop_track; - break; - case RepeatMode::RM_PLAY_SHUFFLE: - pIcon = &theApp.m_icon_set.play_shuffle; - break; - case RepeatMode::RM_PLAY_RANDOM: - pIcon = &theApp.m_icon_set.play_random; - break; - case RepeatMode::RM_PLAY_TRACK: - pIcon = &theApp.m_icon_set.play_track; - break; - } - return pIcon; -} - -IconRes* CPlayerUIBase::GetVolumeIcon() -{ - IconRes* icon{}; - if (CPlayer::GetInstance().GetVolume() <= 0) - icon = &theApp.m_icon_set.volume0; - else if (CPlayer::GetInstance().GetVolume() >= 66) - icon = &theApp.m_icon_set.volume3; - else if (CPlayer::GetInstance().GetVolume() >= 33) - icon = &theApp.m_icon_set.volume2; - else - icon = &theApp.m_icon_set.volume1; - return icon; -} - -void CPlayerUIBase::DrawUiIcon(CRect rect, const IconRes & icon, bool dark) -{ - //使图标在矩形中居中 - CRect rc_icon; - CSize icon_size = icon.GetSize(IsDrawLargeIcon()); - rc_icon.left = rect.left + (rect.Width() - icon_size.cx) / 2; - rc_icon.top = rect.top + (rect.Height() - icon_size.cy) / 2; - rc_icon.right = rc_icon.left + icon_size.cx; - rc_icon.bottom = rc_icon.top + icon_size.cy; - - //绘制图标 - const HICON& hIcon = icon.GetIcon(dark, IsDrawLargeIcon()); - m_draw.DrawIcon(hIcon, rc_icon.TopLeft(), rc_icon.Size()); + // style为IS_Auto时根据深色模式设置向IconMgr要求深色/浅色图标,没有对应风格图标时IconMgr会自行fallback + if (icon_style == IconMgr::IconStyle::IS_Auto) + icon_style = theApp.m_app_setting_data.dark_mode ? IconMgr::IconStyle::IS_OutlinedLight : IconMgr::IconStyle::IS_OutlinedDark; + // 要求大图标时在icon_size基础上再进行放大(×全屏缩放系数) + if (IsDrawLargeIcon() && icon_size == IconMgr::IconSize::IS_DPI_16) + icon_size = IconMgr::IconSize::IS_DPI_16_Full_Screen; + if (IsDrawLargeIcon() && icon_size == IconMgr::IconSize::IS_DPI_20) + icon_size = IconMgr::IconSize::IS_DPI_20_Full_Screen; + if (IsDrawLargeIcon() && icon_size == IconMgr::IconSize::IS_DPI_32) + icon_size = IconMgr::IconSize::IS_DPI_32_Full_Screen; + // 使图标在矩形中居中 + CSize size_icon = IconMgr::GetIconSize(icon_size); + CPoint pos_icon{ rect.left + (rect.Width() - size_icon.cx) / 2 , rect.top + (rect.Height() - size_icon.cy) / 2 }; + // 绘制图标 + HICON hIcon = theApp.m_icon_mgr.GetHICON(icon_type, icon_style, icon_size); + m_draw.DrawIcon(hIcon, pos_icon, size_icon); } //void CPlayerUIBase::AddMouseToolTip(BtnKey btn, LPCTSTR str) @@ -2806,53 +2794,129 @@ void CPlayerUIBase::DrawUiIcon(CRect rect, const IconRes & icon, bool dark) void CPlayerUIBase::AddToolTips() { bool is_mini_mode{ IsMiniMode() }; - AddMouseToolTip(BTN_REPETEMODE, m_repeat_mode_tip); - AddMouseToolTip(BTN_TRANSLATE, CCommon::LoadText(IDS_SHOW_LYRIC_TRANSLATION)); + wstring tip_str; + // 翻译 + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_TRANSLATION"); + AddMouseToolTip(BTN_TRANSLATE, tip_str.c_str()); + // 音量 AddMouseToolTip(BTN_VOLUME, GetVolumeTooltipString()); + // 切换界面 + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_SWITCH_UI"); + if (!is_mini_mode) tip_str += GetCmdShortcutKeyForTooltips(ID_SWITCH_UI); + AddMouseToolTip(BTN_SKIN, tip_str.c_str()); + AddMouseToolTip(BTN_SKIN_TITLEBAR, tip_str.c_str()); + // 音效 + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_SOUND_EFFECT_SETTING"); + tip_str += GetCmdShortcutKeyForTooltips(ID_EQUALIZER); + AddMouseToolTip(BTN_EQ, tip_str.c_str()); + // 设置 + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_OPTION_SETTING"); + tip_str += GetCmdShortcutKeyForTooltips(ID_OPTION_SETTINGS); + AddMouseToolTip(BTN_SETTING, tip_str.c_str()); + AddMouseToolTip(BTN_SETTING_TITLEBAR, tip_str.c_str()); + // MINI模式 if (is_mini_mode) - AddMouseToolTip(BTN_SKIN, CCommon::LoadText(IDS_SWITCH_UI)); + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_MINIMODE_RTN"); else - AddMouseToolTip(BTN_SKIN, CCommon::LoadText(IDS_SWITCH_UI, GetCmdShortcutKeyForTooltips(ID_SWITCH_UI))); - AddMouseToolTip(BTN_SKIN_TITLEBAR, CCommon::LoadText(IDS_SWITCH_UI, GetCmdShortcutKeyForTooltips(ID_SWITCH_UI))); - AddMouseToolTip(BTN_EQ, CCommon::LoadText(IDS_SOUND_EFFECT_SETTING, GetCmdShortcutKeyForTooltips(ID_EQUALIZER))); - AddMouseToolTip(BTN_SETTING, CCommon::LoadText(IDS_SETTINGS, GetCmdShortcutKeyForTooltips(ID_OPTION_SETTINGS))); - AddMouseToolTip(BTN_SETTING_TITLEBAR, CCommon::LoadText(IDS_SETTINGS, GetCmdShortcutKeyForTooltips(ID_OPTION_SETTINGS))); - if (is_mini_mode) - AddMouseToolTip(BTN_MINI, CCommon::LoadText(IDS_BACK_TO_NARMAL)); + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_MINIMODE"); + tip_str += GetCmdShortcutKeyForTooltips(ID_MINI_MODE); + AddMouseToolTip(BTN_MINI, tip_str.c_str()); + AddMouseToolTip(BTN_MINI_TITLEBAR, tip_str.c_str()); + // 曲目信息(属性) + AddMouseToolTip(BTN_INFO, m_info_tip.c_str()); + // 停止 + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_STOP"); + AddMouseToolTip(BTN_STOP, tip_str.c_str()); + // 上一曲 + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_PREVIOUS"); + AddMouseToolTip(BTN_PREVIOUS, tip_str.c_str()); + // 播放/暂停 + if (CPlayer::GetInstance().IsPlaying()) + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_PAUSE"); else - AddMouseToolTip(BTN_MINI, CCommon::LoadText(IDS_MINI_MODE, GetCmdShortcutKeyForTooltips(ID_MINI_MODE))); - AddMouseToolTip(BTN_MINI_TITLEBAR, CCommon::LoadText(IDS_MINI_MODE, GetCmdShortcutKeyForTooltips(ID_MINI_MODE))); - AddMouseToolTip(BTN_INFO, m_info_tip); - AddMouseToolTip(BTN_STOP, CCommon::LoadText(IDS_STOP)); - AddMouseToolTip(BTN_PREVIOUS, CCommon::LoadText(IDS_PREVIOUS)); - AddMouseToolTip(BTN_PLAY_PAUSE, CPlayer::GetInstance().IsPlaying() ? CCommon::LoadText(IDS_PAUSE) : CCommon::LoadText(IDS_PLAY)); - AddMouseToolTip(BTN_NEXT, CCommon::LoadText(IDS_NEXT)); - AddMouseToolTip(BTN_PROGRESS, CCommon::LoadText(IDS_SEEK_TO)); - if (is_mini_mode) - AddMouseToolTip(BTN_SHOW_PLAYLIST, CCommon::LoadText(IDS_SHOW_HIDE_PLAYLIST)); + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_PLAY"); + AddMouseToolTip(BTN_PLAY_PAUSE, tip_str.c_str()); + // 下一曲 + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_NEXT"); + AddMouseToolTip(BTN_NEXT, tip_str.c_str()); + // 进度条 + tip_str = theApp.m_str_table.LoadTextFormat(L"UI_TIP_SEEK_TO_MINUTE_SECOND", { L"0", L"00" }); + AddMouseToolTip(BTN_PROGRESS, tip_str.c_str()); + // 显示/隐藏播放列表 + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_PLAYLIST_SHOW_HIDE"); + if (!is_mini_mode) + { + if (theApp.m_media_lib_setting_data.playlist_btn_for_float_playlist) + tip_str += GetCmdShortcutKeyForTooltips(ID_FLOAT_PLAYLIST); + else + tip_str += GetCmdShortcutKeyForTooltips(ID_SHOW_PLAYLIST); + } + AddMouseToolTip(BTN_SHOW_PLAYLIST, tip_str.c_str()); + // 媒体库 + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_MEDIA_LIB"); + tip_str += GetCmdShortcutKeyForTooltips(ID_MEDIA_LIB); + AddMouseToolTip(BTN_MEDIA_LIB, tip_str.c_str()); + // 查找歌曲 + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_FIND_SONGS"); + tip_str += GetCmdShortcutKeyForTooltips(ID_FIND); + AddMouseToolTip(BTN_FIND, tip_str.c_str()); + // 封面 + AddMouseToolTip(BTN_COVER, m_cover_tip.c_str()); + // 全屏 + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_FULL_SCREEN"); + tip_str += GetCmdShortcutKeyForTooltips(ID_FULL_SCREEN); + AddMouseToolTip(BTN_FULL_SCREEN_TITLEBAR, tip_str.c_str()); + AddMouseToolTip(BTN_FULL_SCREEN, tip_str.c_str()); + // 主菜单 + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_MAIN_MENU"); + AddMouseToolTip(BTN_MENU_TITLEBAR, tip_str.c_str()); + AddMouseToolTip(BTN_MENU, tip_str.c_str()); + // “我喜欢的音乐” + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_FAVOURITE"); + AddMouseToolTip(BTN_FAVOURITE, tip_str.c_str()); + // 桌面歌词 + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_DESKTOP_LYRIC"); + AddMouseToolTip(BTN_LRYIC, tip_str.c_str()); + // AB重复 + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_AB_REPEAT"); + tip_str = GetCmdShortcutKeyForTooltips(ID_AB_REPEAT); + AddMouseToolTip(BTN_AB_REPEAT, tip_str.c_str()); + // 关闭 + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_CLOSE"); + AddMouseToolTip(BTN_APP_CLOSE, tip_str.c_str()); + AddMouseToolTip(BTN_CLOSE, tip_str.c_str()); + // 最小化 + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_MINIMIZE"); + AddMouseToolTip(BTN_MINIMIZE, tip_str.c_str()); + // 最大化 + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_MAXIMIZE"); + AddMouseToolTip(BTN_MAXIMIZE, tip_str.c_str()); + // 添加到播放列表 + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_ADD_TO_PLAYLIST"); + AddMouseToolTip(BTN_ADD_TO_PLAYLIST, tip_str.c_str()); + // 切换界面 + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_SWITCH_DISPLAY"); + AddMouseToolTip(BTN_SWITCH_DISPLAY, tip_str.c_str()); + // 深色/浅色模式 + if(theApp.m_app_setting_data.dark_mode) + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_DARK_LIGHT_TO_LIGHT_MODE"); else - AddMouseToolTip(BTN_SHOW_PLAYLIST, CCommon::LoadText(IDS_SHOW_HIDE_PLAYLIST, theApp.m_nc_setting_data.playlist_btn_for_float_playlist ? GetCmdShortcutKeyForTooltips(ID_FLOAT_PLAYLIST) : GetCmdShortcutKeyForTooltips(ID_SHOW_PLAYLIST))); - AddMouseToolTip(BTN_SELECT_FOLDER, CCommon::LoadText(IDS_MEDIA_LIB, GetCmdShortcutKeyForTooltips(ID_SET_PATH))); - AddMouseToolTip(BTN_FIND, CCommon::LoadText(IDS_FIND_SONGS, GetCmdShortcutKeyForTooltips(ID_FIND))); - AddMouseToolTip(BTN_COVER, m_cover_tip); - AddMouseToolTip(BTN_FULL_SCREEN_TITLEBAR, CCommon::LoadText(IDS_FULL_SCREEN, GetCmdShortcutKeyForTooltips(ID_FULL_SCREEN))); - AddMouseToolTip(BTN_FULL_SCREEN, CCommon::LoadText(IDS_FULL_SCREEN, GetCmdShortcutKeyForTooltips(ID_FULL_SCREEN))); - AddMouseToolTip(BTN_MENU_TITLEBAR, CCommon::LoadText(IDS_MAIN_MENU)); - AddMouseToolTip(BTN_MENU, CCommon::LoadText(IDS_MAIN_MENU)); - AddMouseToolTip(BTN_FAVOURITE, CCommon::LoadText(IDS_ADD_TO_MA_FAVOURITE)); - AddMouseToolTip(BTN_LRYIC, CCommon::LoadText(IDS_SHOW_DESKTOP_LYRIC)); - AddMouseToolTip(BTN_AB_REPEAT, CCommon::LoadText(IDS_AB_REPEAT, GetCmdShortcutKeyForTooltips(ID_AB_REPEAT))); - AddMouseToolTip(BTN_APP_CLOSE, CCommon::LoadText(IDS_CLOSE)); - AddMouseToolTip(BTN_MINIMIZE, CCommon::LoadText(IDS_MINIMIZE)); - AddMouseToolTip(BTN_MAXIMIZE, CCommon::LoadText(IDS_MAXIMIZE)); - AddMouseToolTip(BTN_ADD_TO_PLAYLIST, CCommon::LoadText(IDS_ADD_TO_PLAYLIST)); - AddMouseToolTip(BTN_SWITCH_DISPLAY, CCommon::LoadText(IDS_SWITCH_DISPLAY)); - AddMouseToolTip(BTN_DARK_LIGHT, CCommon::LoadText(theApp.m_app_setting_data.dark_mode ? IDS_SWITCH_TO_LIGHT_MODE : IDS_SWITHC_TO_DARK_MODE, GetCmdShortcutKeyForTooltips(ID_DARK_MODE))); - AddMouseToolTip(BTN_CLOSE, CCommon::LoadText(IDS_CLOSE)); - AddMouseToolTip(BTN_LOCATE_TO_CURRENT, CCommon::LoadText(IDS_LOCATE_TO_CURRENT, GetCmdShortcutKeyForTooltips(ID_LOCATE_TO_CURRENT))); - AddMouseToolTip(BTN_PLAYLIST_MENU, CCommon::LoadText(IDS_PLAYLIST_MENU)); - AddMouseToolTip(BTN_PLAYLIST_DROP_DOWN, CCommon::LoadText(IDS_RECENT_FOLDER_OR_PLAYLIST)); - AddMouseToolTip(static_cast(UiElement::PLAYLIST_TOOLTIP_INDEX), _T("")); - + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_DARK_LIGHT_TO_DARK_MODE"); + tip_str += GetCmdShortcutKeyForTooltips(ID_DARK_MODE); + AddMouseToolTip(BTN_DARK_LIGHT, tip_str.c_str()); + // 播放列表定位到当前播放 + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_LOCATE_TO_CURRENT"); + tip_str += GetCmdShortcutKeyForTooltips(ID_LOCATE_TO_CURRENT); + AddMouseToolTip(BTN_LOCATE_TO_CURRENT, tip_str.c_str()); + // 播放列表 + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_PLAYLIST_MENU"); + AddMouseToolTip(BTN_PLAYLIST_MENU, tip_str.c_str()); + // 播放列表下拉菜单按钮 + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_RECENT_FOLDER_OR_PLAYLIST"); + AddMouseToolTip(BTN_PLAYLIST_DROP_DOWN, tip_str.c_str()); + // 循环模式 + AddMouseToolTip(BTN_REPETEMODE, m_repeat_mode_tip.c_str()); UpdateRepeatModeToolTip(); + // 播放列表工具提示 + AddMouseToolTip(static_cast(UiElement::PLAYLIST_TOOLTIP_INDEX), L""); } diff --git a/MusicPlayer2/CPlayerUIBase.h b/MusicPlayer2/CPlayerUIBase.h index 83a62ea2e..9d0867f0c 100644 --- a/MusicPlayer2/CPlayerUIBase.h +++ b/MusicPlayer2/CPlayerUIBase.h @@ -3,6 +3,7 @@ #include "IPlayerUI.h" #include "CPlayerUIHelper.h" #include "CUIDrawer.h" +#include "IconMgr.h" #define WM_MAIN_MENU_POPEDUP (WM_USER+117) //显示弹出式主菜单的消息,wPara为表示菜单显示位置的CPoint的指针 @@ -31,9 +32,8 @@ struct SLayoutData const int margin = theApp.DPI(4); //边缘的余量 const int width_threshold = theApp.DPI(600); //界面从普通界面模式切换到窄界面模式时界面宽度的阈值 const int info_height = theApp.DPI(216); //窄界面模式时显示信息区域的高度 - const int path_edit_height = theApp.DPI(32); //前路径Edit控件区域的高度 + const int path_edit_height = theApp.DPI(24); //当前路径Edit控件的高度 const int search_edit_height = theApp.DPI(26); //歌曲搜索框Edit控件区域的高度 - //const int select_folder_width = theApp.DPI(90); //“选择文件夹”按钮的宽度 const CSize spectral_size{ theApp.DPI(120), theApp.DPI(90) }; //频谱分析区域的大小 const int toolbar_height = theApp.DPI(24); //播放列表工具栏的高度 const int titlabar_height = theApp.DPI(28); //标题栏的高度 @@ -110,7 +110,7 @@ class CPlayerUIBase : public IPlayerUI bool PointInMenubarArea(CPoint point) const; //获取界面的名称 - virtual CString GetUIName() { return CString(); } + virtual wstring GetUIName() { return wstring(); } enum class UiSize { @@ -125,6 +125,10 @@ class CPlayerUIBase : public IPlayerUI static CString GetCmdShortcutKeyForTooltips(UINT id); //获取用于显示在鼠标提示中的键盘快捷键 +protected: + // 将字符串形如“%(KEY_STR)”格式的字符替换成当前.ini中对应id的字符串 + static void ReplaceUiStringRes(wstring& str); + public: enum BtnKey //标识按钮的类型 { @@ -149,7 +153,7 @@ class CPlayerUIBase : public IPlayerUI BTN_PLAY_PAUSE, //播放/暂停 BTN_NEXT, //下一曲 BTN_SHOW_PLAYLIST, //显示/隐藏播放列表 - BTN_SELECT_FOLDER, //媒体库 + BTN_MEDIA_LIB, //媒体库 BTN_PROGRESS, //进度条 BTN_COVER, //专辑封面 BTN_FULL_SCREEN_TITLEBAR, //标题栏上的全屏显示按钮 @@ -187,9 +191,9 @@ class CPlayerUIBase : public IPlayerUI RCM_LIGHT }; - //根据按钮的类型获取对应的图标 - //big_icon: 某些按钮提供了不同的尺寸,如果为false,则图标大小为16x16,否则为20x20 - IconRes GetBtnIcon(BtnKey key, bool big_icon = false); + // 获取参数按钮当前应当使用的图标类型 + // 将BtnKey枚举和当前状态组合映射为IconMgr::IconType枚举 + IconMgr::IconType GetBtnIconType(BtnKey key); protected: struct DrawData @@ -214,13 +218,14 @@ class CPlayerUIBase : public IPlayerUI void DrawProgressBar(CRect rect, bool play_time_both_side = false); //绘制进度条(包含时间)。play_time_both_side如果为true,则播放时间显示的进度条的两侧,否则显示在进度条的右侧 void DrawProgess(CRect rect); //绘制进度条 void DrawTranslateButton(CRect rect); + void DrawDesktopLyricButton(CRect rect); int DrawTopRightIcons(bool always_show_full_screen = false); //绘制右上角的图标。返回总宽度 void DrawCurrentTime(); //在右上角绘制当前系统时间 void DrawAlbumCover(CRect rect); //绘制专辑封面 void DrawAlbumCoverWithInfo(CRect rect); //绘制专辑封面,并在上面绘制歌曲的标题和艺术家 void DrawVolumeButton(CRect rect, bool adj_btn_top = false, bool show_text = true); //adj_btn_top:点击后弹出的音量调整按钮是否在上方;show_text:是否显示文本 void DrawABRepeatButton(CRect rect); - void DrawLyrics(CRect rect, int margin = -1); //绘制歌词 rect:歌曲区域;margin歌词文本到歌词区域边框的边距 + void DrawLyrics(CRect rect, CFont* lyric_font, CFont* lyric_tr_font, bool with_background); //绘制歌词 rect:歌曲区域;with_background是否绘制背景 void DrawPlaylist(CRect rect, UiElement::Playlist* playlist_element, int item_height); //绘制播放列表 void DrawCurrentPlaylistIndicator(CRect rect); //绘制当前播放列表指示 /** @@ -232,13 +237,14 @@ class CPlayerUIBase : public IPlayerUI void DrawStackIndicator(UIButton indicator, int num, int index); void DrawUiMenuBar(CRect rect); - IconRes* GetRepeatModeIcon(); //获取当前循环模式的图标 - IconRes* GetVolumeIcon(); //获取当前音量的图标 - void DrawUiIcon(CRect rect, const IconRes& icon, bool dark); - void DrawUIButton(CRect rect, UIButton& btn, const IconRes& icon); - void DrawControlButton(CRect rect, UIButton& btn, const IconRes& icon); - void DrawTextButton(CRect rect, UIButton& btn, LPCTSTR text, bool back_color = false); - void DrawControlBarBtn(CRect rect, UIButton& btn, const IconRes& icon); + // 实际绘制一个图标 + void DrawUiIcon(const CRect& rect, IconMgr::IconType icon_type, IconMgr::IconStyle icon_style = IconMgr::IconStyle::IS_Auto, IconMgr::IconSize icon_size = IconMgr::IconSize::IS_DPI_16); + // 绘制一个UI按钮 (使用GetBtnIconType取得的图标) + void DrawUIButton(const CRect& rect, BtnKey key_type, bool big_icon = false); + // 绘制一个工具条按钮(将rect四面缩小 DPI(2) 后调用DrawUIButton) + void DrawControlBarBtn(CRect rect, BtnKey btn_type); + // 绘制一个UI按钮,以text文本作为图标 + void DrawTextButton(CRect rect, BtnKey btn_type, LPCTSTR text, bool back_color = false); void ResetDrawArea(); @@ -269,7 +275,7 @@ class CPlayerUIBase : public IPlayerUI int DPI(double pixel) const; double DPIDouble(double pixel); double GetScrollTextPixel(bool slower = false); //计算滚动文本一次滚动的像素值,如果slower为true,则滚动得稍微慢一点 - int CalculateRoundRectRadius(CRect rect); //计算绘制圆角矩形的半径 + int CalculateRoundRectRadius(const CRect& rect); //计算绘制圆角矩形的半径 virtual bool IsDrawLargeIcon() const; //是否绘制大图标 @@ -303,9 +309,9 @@ class CPlayerUIBase : public IPlayerUI CToolTipCtrl m_tool_tip; - CString m_repeat_mode_tip; - CString m_info_tip; - CString m_cover_tip; + wstring m_repeat_mode_tip; + wstring m_info_tip; + wstring m_cover_tip; UIData& m_ui_data; diff --git a/MusicPlayer2/CPlayerUIHelper.cpp b/MusicPlayer2/CPlayerUIHelper.cpp index 1c014e59a..bb112a067 100644 --- a/MusicPlayer2/CPlayerUIHelper.cpp +++ b/MusicPlayer2/CPlayerUIHelper.cpp @@ -1,6 +1,7 @@ #include "stdafx.h" #include "CPlayerUIHelper.h" #include "MusicPlayer2.h" +#include "Player.h" CPlayerUIHelper::CPlayerUIHelper() diff --git a/MusicPlayer2/CSelectPlaylist.cpp b/MusicPlayer2/CSelectPlaylist.cpp index 652bb285e..671d2cf4e 100644 --- a/MusicPlayer2/CSelectPlaylist.cpp +++ b/MusicPlayer2/CSelectPlaylist.cpp @@ -3,13 +3,15 @@ #include "stdafx.h" #include "MusicPlayer2.h" +#include "Player.h" #include "CSelectPlaylist.h" -#include "afxdialogex.h" #include "InputDlg.h" #include "Playlist.h" #include "SongDataManager.h" #include "RecentFolderAndPlaylist.h" #include "MusicPlayerCmdHelper.h" +#include "CommonDialogMgr.h" +#include "FilterHelper.h" // CSelectPlaylist 对话框 @@ -81,13 +83,6 @@ int CSelectPlaylistDlg::GetPlayingItem() return playing_item; } -void CSelectPlaylistDlg::OnTabEntered() -{ - if (m_playlist_ctrl.GetCurSel() != -1) - m_left_selected_item = m_playlist_ctrl.GetCurSel(); // m_left_selected_item直接存储m_playlist_ctrl的索引 - SetButtonsEnable(); -} - void CSelectPlaylistDlg::ShowSongList() { CWaitCursor wait_cursor; @@ -187,6 +182,30 @@ wstring CSelectPlaylistDlg::GetSelectedString() const return m_selected_string; } +void CSelectPlaylistDlg::OnTabEntered() +{ + if (m_playlist_ctrl.GetCurSel() != -1) + m_left_selected_item = m_playlist_ctrl.GetCurSel(); // m_left_selected_item直接存储m_playlist_ctrl的索引 + SetButtonsEnable(); +} + +bool CSelectPlaylistDlg::InitializeControls() +{ + wstring temp; + temp = theApp.m_str_table.LoadText(L"TXT_LIB_PLAYLIST_NEW_PLAYLIST"); + SetDlgItemTextW(IDC_NEW_PLAYLIST, temp.c_str()); + // IDC_SEARCH_EDIT + // IDC_LIST1 + // IDC_HSPLITER_STATIC + // IDC_SONG_LIST + + RepositionTextBasedControls({ + { CtrlTextInfo::L1, IDC_NEW_PLAYLIST, CtrlTextInfo::W32 }, + { CtrlTextInfo::R1, IDC_SEARCH_EDIT } + }); + return true; +} + BEGIN_MESSAGE_MAP(CSelectPlaylistDlg, CMediaLibTabDlg) ON_NOTIFY(NM_DBLCLK, IDC_LIST1, &CSelectPlaylistDlg::OnNMDblclkList1) ON_BN_CLICKED(IDC_NEW_PLAYLIST, &CSelectPlaylistDlg::OnBnClickedNewPlaylist) @@ -219,25 +238,17 @@ BOOL CSelectPlaylistDlg::OnInitDialog() // TODO: 在此添加额外的初始化 - CButton* new_btn = (CButton*)(GetDlgItem(IDC_NEW_PLAYLIST)); - if (new_btn != nullptr) - new_btn->SetIcon(theApp.m_icon_set.add.GetIcon(true)); - + SetButtonIcon(IDC_NEW_PLAYLIST, IconMgr::IconType::IT_Add); //初始化播放列表控件 vector width; CalculateColumeWidth(width); m_playlist_ctrl.SetExtendedStyle(m_playlist_ctrl.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_LABELTIP); - m_playlist_ctrl.InsertColumn(0, CCommon::LoadText(IDS_NUMBER), LVCFMT_LEFT, width[0]); - m_playlist_ctrl.InsertColumn(1, CCommon::LoadText(IDS_PLAYLIST), LVCFMT_LEFT, width[1]); - m_playlist_ctrl.InsertColumn(2, CCommon::LoadText(IDS_TRACK_PLAYED), LVCFMT_LEFT, width[2]); - m_playlist_ctrl.InsertColumn(3, CCommon::LoadText(IDS_TRACK_TOTAL_NUM), LVCFMT_LEFT, width[3]); - m_playlist_ctrl.InsertColumn(4, CCommon::LoadText(IDS_TOTAL_LENGTH), LVCFMT_LEFT, width[4]); - - ////初始化提示信息 - //m_Mytip.Create(this, TTS_ALWAYSTIP); - //m_Mytip.AddTool(GetDlgItem(IDC_CLEAR_BUTTON), CCommon::LoadText(IDS_CLEAR_SEARCH_RESULT)); - //m_Mytip.AddTool(&m_search_edit, CCommon::LoadText(IDS_INPUT_KEY_WORD)); + m_playlist_ctrl.InsertColumn(0, theApp.m_str_table.LoadText(L"TXT_SERIAL_NUMBER").c_str(), LVCFMT_LEFT, width[0]); + m_playlist_ctrl.InsertColumn(1, theApp.m_str_table.LoadText(L"TXT_PLAYLIST").c_str(), LVCFMT_LEFT, width[1]); + m_playlist_ctrl.InsertColumn(2, theApp.m_str_table.LoadText(L"TXT_LAST_PLAYED_TRACK").c_str(), LVCFMT_LEFT, width[2]); + m_playlist_ctrl.InsertColumn(3, theApp.m_str_table.LoadText(L"TXT_NUM_OF_TRACK").c_str(), LVCFMT_LEFT, width[3]); + m_playlist_ctrl.InsertColumn(4, theApp.m_str_table.LoadText(L"TXT_TOTAL_LENGTH").c_str(), LVCFMT_LEFT, width[4]); ////设置列表控件的提示总是置顶,用于解决如果弹出此窗口的父窗口具有置顶属性时,提示信息在窗口下面的问题 //m_playlist_ctrl.GetToolTips()->SetWindowPos(&CWnd::wndTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); @@ -245,14 +256,14 @@ BOOL CSelectPlaylistDlg::OnInitDialog() //初始化右侧列表 m_song_list_ctrl.SetExtendedStyle(m_song_list_ctrl.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_LABELTIP); - m_song_list_ctrl.InsertColumn(COL_INDEX, CCommon::LoadText(IDS_NUMBER), LVCFMT_LEFT, theApp.DPI(40)); - m_song_list_ctrl.InsertColumn(COL_TITLE, CCommon::LoadText(IDS_TITLE), LVCFMT_LEFT, theApp.DPI(150)); - m_song_list_ctrl.InsertColumn(COL_ARTIST, CCommon::LoadText(IDS_ARTIST), LVCFMT_LEFT, theApp.DPI(100)); - m_song_list_ctrl.InsertColumn(COL_ALBUM, CCommon::LoadText(IDS_ALBUM), LVCFMT_LEFT, theApp.DPI(150)); - m_song_list_ctrl.InsertColumn(COL_TRACK, CCommon::LoadText(IDS_TRACK_NUM), LVCFMT_LEFT, theApp.DPI(60)); - m_song_list_ctrl.InsertColumn(COL_GENRE, CCommon::LoadText(IDS_GENRE), LVCFMT_LEFT, theApp.DPI(100)); - m_song_list_ctrl.InsertColumn(COL_BITRATE, CCommon::LoadText(IDS_BITRATE), LVCFMT_LEFT, theApp.DPI(60)); - m_song_list_ctrl.InsertColumn(COL_PATH, CCommon::LoadText(IDS_FILE_PATH), LVCFMT_LEFT, theApp.DPI(600)); + m_song_list_ctrl.InsertColumn(COL_INDEX, theApp.m_str_table.LoadText(L"TXT_SERIAL_NUMBER").c_str(), LVCFMT_LEFT, theApp.DPI(40)); + m_song_list_ctrl.InsertColumn(COL_TITLE, theApp.m_str_table.LoadText(L"TXT_TITLE").c_str(), LVCFMT_LEFT, theApp.DPI(150)); + m_song_list_ctrl.InsertColumn(COL_ARTIST, theApp.m_str_table.LoadText(L"TXT_ARTIST").c_str(), LVCFMT_LEFT, theApp.DPI(100)); + m_song_list_ctrl.InsertColumn(COL_ALBUM, theApp.m_str_table.LoadText(L"TXT_ALBUM").c_str(), LVCFMT_LEFT, theApp.DPI(150)); + m_song_list_ctrl.InsertColumn(COL_TRACK, theApp.m_str_table.LoadText(L"TXT_TRACK_NUM").c_str(), LVCFMT_LEFT, theApp.DPI(60)); + m_song_list_ctrl.InsertColumn(COL_GENRE, theApp.m_str_table.LoadText(L"TXT_GENRE").c_str(), LVCFMT_LEFT, theApp.DPI(100)); + m_song_list_ctrl.InsertColumn(COL_BITRATE, theApp.m_str_table.LoadText(L"TXT_BITRATE").c_str(), LVCFMT_LEFT, theApp.DPI(60)); + m_song_list_ctrl.InsertColumn(COL_PATH, theApp.m_str_table.LoadText(L"TXT_FILE_PATH").c_str(), LVCFMT_LEFT, theApp.DPI(600)); m_song_list_ctrl.SetCtrlAEnable(true); // ShowPathList初始化m_playlist_ctrl_data,需要在其他方法之前 @@ -260,7 +271,8 @@ BOOL CSelectPlaylistDlg::OnInitDialog() SetLeftListSelected(GetPlayingItem()); // 初始化时选中正在播放的播放列表 ShowSongList(); m_search_edit.SetFocus(); //初始时将焦点设置到搜索框 - m_search_edit.SetCueBanner(CCommon::LoadText(IDS_SEARCH_HERE), TRUE); + wstring prompt_str = theApp.m_str_table.LoadText(L"TXT_SEARCH_PROMPT") + L"(F)"; + m_search_edit.SetCueBanner(prompt_str.c_str(), TRUE); //初始化分隔条 m_splitter_ctrl.AttachCtrlAsLeftPane(IDC_LIST1); @@ -305,7 +317,7 @@ void CSelectPlaylistDlg::ShowPathList() if (m_search_result.empty()) { m_playlist_ctrl.InsertItem(0, _T("")); - m_playlist_ctrl.SetItemText(0, 1, CCommon::LoadText(IDS_NO_RESULT_TO_SHOW)); + m_playlist_ctrl.SetItemText(0, 1, theApp.m_str_table.LoadText(L"TXT_PLAYLIST_CTRL_NO_RESULT_TO_SHOW").c_str()); m_playlist_ctrl.EnableWindow(FALSE); return; } @@ -325,11 +337,11 @@ void CSelectPlaylistDlg::SetListRowData(int index, const PlaylistInfo& playlist_ CFilePathHelper path_helper{ playlist_info.path }; wstring playlist_name = path_helper.GetFileName(); if (playlist_name == DEFAULT_PLAYLIST_NAME) - playlist_name = CCommon::LoadText(_T("["), IDS_DEFAULT, _T("]")); + playlist_name = theApp.m_str_table.LoadText(L"TXT_PLAYLIST_NAME_DEFAULT"); else if (playlist_name == FAVOURITE_PLAYLIST_NAME) - playlist_name = CCommon::LoadText(_T("["), IDS_MY_FAVURITE, _T("]")); + playlist_name = theApp.m_str_table.LoadText(L"TXT_PLAYLIST_NAME_FAVOURITE"); else if (playlist_name == TEMP_PLAYLIST_NAME) - playlist_name = CCommon::LoadText(_T("["), IDS_TEMP_PLAYLIST, _T("]")); + playlist_name = theApp.m_str_table.LoadText(L"TXT_PLAYLIST_NAME_TEMP"); else playlist_name = path_helper.GetFileNameWithoutExtension(); @@ -410,7 +422,10 @@ void CSelectPlaylistDlg::OnOK() else // 否则播放m_right_selected_item指定曲目,设置play为true,force为true ok = CPlayer::GetInstance().SetPlaylist(sel_playlist.path, m_right_selected_item, 0, true, true); if (!ok) - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } else { CTabDlg::OnOK(); @@ -432,25 +447,28 @@ void CSelectPlaylistDlg::OnBnClickedNewPlaylist() wstring CSelectPlaylistDlg::DoNewPlaylist() { CInputDlg imput_dlg(this); - imput_dlg.SetTitle(CCommon::LoadText(IDS_NEW_PLAYLIST)); - imput_dlg.SetInfoText(CCommon::LoadText(IDS_INPUT_PLAYLIST_NAME)); + imput_dlg.SetTitle(theApp.m_str_table.LoadText(L"TITLE_NEW_PLAYLIST").c_str()); + imput_dlg.SetInfoText(theApp.m_str_table.LoadText(L"TXT_NEW_PLAYLIST_INPUT_PLAYLIST_NAME").c_str()); if (imput_dlg.DoModal() == IDOK) { CString playlist_name = imput_dlg.GetEditText(); if (playlist_name.IsEmpty()) { - MessageBox(CCommon::LoadText(IDS_PLAYLIST_NAME_EMPTY_WARNING), NULL, MB_ICONWARNING | MB_OK); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_PLAYLIST_NAME_EMPTY_WARNING"); + MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK); return wstring(); } if (!CCommon::IsFileNameValid(wstring(playlist_name.GetString()))) { - MessageBox(CCommon::LoadText(IDS_FILE_NAME_INVALID_WARNING), NULL, MB_ICONWARNING | MB_OK); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_FILE_NAME_INVALID_WARNING"); + MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK); return wstring(); } wstring playlist_path = theApp.m_playlist_dir + playlist_name.GetString() + PLAYLIST_EXTENSION; if (CCommon::FileExist(playlist_path)) { - MessageBox(CCommon::LoadTextFormat(IDS_PLAYLIST_EXIST_WARNING, { playlist_name }), NULL, MB_ICONWARNING | MB_OK); + wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_PLAYLIST_EXIST_WARNING", { playlist_name }); + MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK); return wstring(); } @@ -481,8 +499,8 @@ void CSelectPlaylistDlg::OnRenamePlaylist() old_playlist_name = old_path.GetFileNameWithoutExtension(); // 获取播放列表名 CInputDlg imput_dlg; - imput_dlg.SetTitle(CCommon::LoadText(IDS_RENAME_PLAYLIST)); - imput_dlg.SetInfoText(CCommon::LoadText(IDS_INPUT_PLAYLIST_NAME)); + imput_dlg.SetTitle(theApp.m_str_table.LoadText(L"TITLE_RENAME_PLAYLIST").c_str()); + imput_dlg.SetInfoText(theApp.m_str_table.LoadText(L"TXT_RENAME_PLAYLIST_INPUT_PLAYLIST_NAME").c_str()); imput_dlg.SetEditText(old_playlist_name.c_str()); if (imput_dlg.DoModal() == IDOK) @@ -490,24 +508,28 @@ void CSelectPlaylistDlg::OnRenamePlaylist() wstring new_playlist_name{ imput_dlg.GetEditText() }; if (new_playlist_name.empty()) { - MessageBox(CCommon::LoadText(IDS_PLAYLIST_NAME_EMPTY_WARNING), NULL, MB_ICONWARNING | MB_OK); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_PLAYLIST_NAME_EMPTY_WARNING"); + MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK); return; } if (!CCommon::IsFileNameValid(new_playlist_name)) { - MessageBox(CCommon::LoadText(IDS_FILE_NAME_INVALID_WARNING), NULL, MB_ICONWARNING | MB_OK); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_FILE_NAME_INVALID_WARNING"); + MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK); return; } if (CCommon::FileExist(theApp.m_playlist_dir + new_playlist_name + PLAYLIST_EXTENSION)) { - MessageBox(CCommon::LoadTextFormat(IDS_PLAYLIST_EXIST_WARNING, { new_playlist_name }), NULL, MB_ICONWARNING | MB_OK); + wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_PLAYLIST_EXIST_WARNING", { new_playlist_name }); + MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK); return; } wstring new_path = CCommon::FileRename(sel_playlist_path, new_playlist_name); //播放列表后命名后的路径 if (new_path.empty()) { - MessageBox(CCommon::LoadText(IDS_REMANE_FAILED), NULL, MB_ICONWARNING | MB_OK); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_PLAYLIST_REMANE_FAILED"); + MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK); return; } if (sel_playlist_path == new_path) @@ -538,12 +560,15 @@ void CSelectPlaylistDlg::OnDeletePlaylist() if (CPlayer::GetInstance().IsPlaylistMode() && CPlayer::GetInstance().GetPlaylistPath() == del_path) { if (!CPlayer::GetInstance().RemoveCurPlaylistOrFolder()) - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } } else { CPlaylistMgr::Instance().DeletePlaylist(del_path); - CCommon::DeleteAFile(this->GetSafeHwnd(), del_path); + CommonDialogMgr::DeleteAFile(this->GetSafeHwnd(), del_path); CRecentFolderAndPlaylist::Instance().Init(); ShowPathList(); SetLeftListSelected(GetPlayingItem()); @@ -570,7 +595,7 @@ void CSelectPlaylistDlg::OnNMRClickList1(NMHDR* pNMHDR, LRESULT* pResult) m_selected_string = m_playlist_ctrl.GetItemText(pNMItemActivate->iItem, pNMItemActivate->iSubItem); //弹出右键菜单 - CMenu* pContextMenu = theApp.m_menu_set.m_media_lib_playlist_menu.GetSubMenu(0); + CMenu* pContextMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::LibPlaylistMenu); m_playlist_ctrl.ShowPopupMenu(pContextMenu, pNMItemActivate->iItem, this); *pResult = 0; @@ -684,7 +709,7 @@ void CSelectPlaylistDlg::OnNMRClickSongList(NMHDR* pNMHDR, LRESULT* pResult) if (!m_right_selected_items.empty()) { //弹出右键菜单 - CMenu* pMenu = theApp.m_menu_set.m_media_lib_popup_menu.GetSubMenu(1); + CMenu* pMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::LibRightMenu); ASSERT(pMenu != nullptr); if (pMenu != nullptr) { @@ -727,7 +752,8 @@ void CSelectPlaylistDlg::OnPlaylistSaveAs() { // TODO: 在此添加命令处理程序代码 PlaylistInfo playlist_info{ GetSelectedPlaylist() }; - CFileDialog fileDlg(FALSE, _T("m3u"), CFilePathHelper(playlist_info.path).GetFileNameWithoutExtension().c_str(), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, CCommon::LoadText(IDS_SAVE_PLAYLIST_FILTER), this); + wstring filter = FilterHelper::GetPlaylistSaveAsFilter(); + CFileDialog fileDlg(FALSE, _T("m3u"), CFilePathHelper(playlist_info.path).GetFileNameWithoutExtension().c_str(), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, filter.c_str(), this); if (IDOK == fileDlg.DoModal()) { CPlaylistFile playlist; @@ -753,13 +779,15 @@ void CSelectPlaylistDlg::OnPlaylistFixPathError() { if (LeftSelectValid()) { - if (MessageBox(CCommon::LoadText(IDS_PLAYLIST_FIX_PATH_ERROR_INFO), NULL, MB_ICONQUESTION | MB_YESNO) == IDYES) + const wstring& inquary_info = theApp.m_str_table.LoadText(L"MSG_PLAYLIST_FIX_ERROR_PATH_INQUARY"); + if (MessageBox(inquary_info.c_str(), NULL, MB_ICONQUESTION | MB_YESNO) == IDYES) { PlaylistInfo playlist_info{ GetSelectedPlaylist() }; CMusicPlayerCmdHelper helper; int fixed_count = helper.FixPlaylistPathError(playlist_info.path); ShowSongList(); - MessageBox(CCommon::LoadTextFormat(IDS_PLAYLIST_FIX_PATH_ERROR_COMPLETE, { fixed_count }), NULL, MB_ICONINFORMATION | MB_OK); + wstring complete_info = theApp.m_str_table.LoadTextFormat(L"MSG_PLAYLIST_FIX_ERROR_PATH_COMPLETE", { fixed_count }); + MessageBox(complete_info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); } } } diff --git a/MusicPlayer2/CSelectPlaylist.h b/MusicPlayer2/CSelectPlaylist.h index aa18b7395..0c9b172ca 100644 --- a/MusicPlayer2/CSelectPlaylist.h +++ b/MusicPlayer2/CSelectPlaylist.h @@ -1,5 +1,6 @@ #pragma once #include "TabDlg.h" +#include "PlaylistMgr.h" #include "ListCtrlEx.h" #include "SearchEditCtrl.h" #include "MediaLibTabDlg.h" @@ -65,9 +66,6 @@ class CSelectPlaylistDlg : public CMediaLibTabDlg CHorizontalSplitter m_splitter_ctrl; protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 - - virtual void OnTabEntered() override; virtual const vector& GetSongList() const override; virtual int GetItemSelected() const override; @@ -76,8 +74,11 @@ class CSelectPlaylistDlg : public CMediaLibTabDlg virtual void AfterDeleteFromDisk(const std::vector& files) override; virtual wstring GetSelectedString() const override; - DECLARE_MESSAGE_MAP() + virtual void OnTabEntered() override; + virtual bool InitializeControls() override; + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 + DECLARE_MESSAGE_MAP() private: // 根据关键字执行快速查找(更新m_search_result) void QuickSearch(const wstring& key_words); diff --git a/MusicPlayer2/CTabCtrlEx.cpp b/MusicPlayer2/CTabCtrlEx.cpp index 74c867da1..69fc73d1b 100644 --- a/MusicPlayer2/CTabCtrlEx.cpp +++ b/MusicPlayer2/CTabCtrlEx.cpp @@ -4,6 +4,7 @@ #include "stdafx.h" #include "MusicPlayer2.h" #include "CTabCtrlEx.h" +#include "TabDlg.h" // CTabCtrlEx @@ -19,7 +20,7 @@ CTabCtrlEx::~CTabCtrlEx() { } -void CTabCtrlEx::AddWindow(CWnd* pWnd, LPCTSTR lable_text) +void CTabCtrlEx::AddWindow(CWnd* pWnd, LPCTSTR lable_text, IconMgr::IconType icon_type) { if (pWnd == nullptr || pWnd->GetSafeHwnd() == NULL) return; @@ -30,6 +31,8 @@ void CTabCtrlEx::AddWindow(CWnd* pWnd, LPCTSTR lable_text) pWnd->MoveWindow(m_tab_rect); m_tab_list.push_back(pWnd); + if (icon_type != IconMgr::IconType::IT_NO_ICON) + m_icon_list.push_back(icon_type); } void CTabCtrlEx::SetCurTab(int index) @@ -74,6 +77,19 @@ void CTabCtrlEx::AdjustTabWindowSize() { m_tab_list[i]->MoveWindow(m_tab_rect); } + //为每个标签添加图标 + if (m_icon_list.empty()) + return; + CSize icon_size = IconMgr::GetIconSize(IconMgr::IconSize::IS_DPI_16); + CImageList ImageList; + ImageList.Create(icon_size.cx, icon_size.cy, ILC_COLOR32 | ILC_MASK, 2, 2); + for (auto icon_type : m_icon_list) + { + HICON hIcon = theApp.m_icon_mgr.GetHICON(icon_type, IconMgr::IconStyle::IS_OutlinedDark, IconMgr::IconSize::IS_DPI_16); + ImageList.Add(hIcon); + } + SetImageList(&ImageList); + ImageList.Detach(); } void CTabCtrlEx::CalSubWindowSize() diff --git a/MusicPlayer2/CTabCtrlEx.h b/MusicPlayer2/CTabCtrlEx.h index 2e0f3aa3b..6be29e9c4 100644 --- a/MusicPlayer2/CTabCtrlEx.h +++ b/MusicPlayer2/CTabCtrlEx.h @@ -1,5 +1,5 @@ #pragma once - +#include "IconMgr.h" // CTabCtrlEx @@ -11,9 +11,10 @@ class CTabCtrlEx : public CTabCtrl CTabCtrlEx(); virtual ~CTabCtrlEx(); - void AddWindow(CWnd* pWnd, LPCTSTR lable_text); //向当前tab控件添加一个子窗口 + void AddWindow(CWnd* pWnd, LPCTSTR lable_text, IconMgr::IconType icon_type); //向当前tab控件添加一个子窗口 void SetCurTab(int index); CWnd* GetCurrentTab(); + // 调整所有标签页大小兼执行设置图标 void AdjustTabWindowSize(); protected: @@ -23,6 +24,7 @@ class CTabCtrlEx : public CTabCtrl protected: vector m_tab_list; //保存tab控件每个子窗口的指针 + vector m_icon_list; public: afx_msg void OnTcnSelchange(NMHDR *pNMHDR, LRESULT *pResult); virtual void PreSubclassWindow(); diff --git a/MusicPlayer2/CTest.cpp b/MusicPlayer2/CTest.cpp index 0a235d8a7..940b3fd55 100644 --- a/MusicPlayer2/CTest.cpp +++ b/MusicPlayer2/CTest.cpp @@ -7,7 +7,7 @@ #include "IniHelper.h" #include "MusicPlayerCmdHelper.h" #include "MessageDlg.h" -#include "PropertyDlgHelper.h" +#include "TagSelBaseDlg.h" #include "TagLibHelper.h" #include "Player.h" #include "CueFile.h" @@ -52,8 +52,6 @@ void CTest::Test() //TestCueSave(); TestFilePathHelper(); - TestReplaceStringRes(); - SaveAllStringRes(101, 600); } void CTest::TestStringMatch() @@ -151,7 +149,7 @@ void CTest::TestCommon() void CTest::TestOSUFile() { COSUFile osu_file{ L"D:\\Program Files\\osu!\\Songs\\66385 u's - Snow halation\\u's - Snow halation (blissfulyoshi) [Insane].osu" }; - wstring file_name = osu_file.GetAudioFile(); + wstring file_name = osu_file.GetAudioFileName(); int a = 0; } @@ -203,28 +201,13 @@ void CTest::TestImageResize() void CTest::TestCrashDlg() { //显示错误信息对话框 - CMessageDlg dlg; - dlg.SetWindowTitle(CCommon::LoadText(IDS_ERROR1)); - dlg.SetInfoText(CCommon::LoadText(IDS_ERROR_MESSAGE)); - - CString info = CCommon::LoadTextFormat(IDS_CRASH_INFO, {}); - info += _T("\r\n"); - info += theApp.GetSystemInfoString(); - dlg.SetMessageText(info); - - //设置图标 - HICON hIcon; - HRESULT hr = LoadIconMetric(NULL, IDI_ERROR, LIM_LARGE, &hIcon); - if (SUCCEEDED(hr)) - dlg.SetMessageIcon(hIcon); - - dlg.DoModal(); + // 待重写(做独立的crash对话框) } void CTest::TestTagParse() { SongInfo song; - CPropertyDlgHelper::GetTagFromFileName(L"666-744FFFF23", FORMULAR_YEAR L"-" FORMULAR_ARTIST L"FFFF" FORMULAR_TITLE, song); + CTagSelBaseDlg::GetTagFromFileName(CTagSelBaseDlg::FORMULAR_YEAR + L"-" + CTagSelBaseDlg::FORMULAR_ARTIST + L"FFFF" + CTagSelBaseDlg::FORMULAR_TITLE, L"666-744FFFF23", song); int a = 0; } @@ -263,21 +246,3 @@ void CTest::TestFilePathHelper() ASSERT(file_dir == L"C:\\abc.d\\"); ASSERT(folder_name == L"abc.d"); } - -void CTest::TestReplaceStringRes() -{ - wstring str{ L"abc%(118)eee%(263)" }; - CCommon::ReplaceUiStringRes(str); - ASSERT(str == L"abc播放eee自动重命名"); -} - -void CTest::SaveAllStringRes(int min_id, int max_id) -{ - std::ofstream stream(L"string_res.csv"); - for (int i = min_id; i <= max_id; i++) - { - CString str = CCommon::LoadText(i); - CCommon::StringCsvNormalize(str); - stream << i << ',' << CCommon::UnicodeToStr(str.GetString(), CodeType::ANSI) << std::endl; - } -} diff --git a/MusicPlayer2/CTest.h b/MusicPlayer2/CTest.h index 55a50367d..5fef065c6 100644 --- a/MusicPlayer2/CTest.h +++ b/MusicPlayer2/CTest.h @@ -25,7 +25,5 @@ class CTest static void TestRating(); static void TestCueSave(); static void TestFilePathHelper(); - static void TestReplaceStringRes(); - static void SaveAllStringRes(int min_id, int max_id); }; diff --git a/MusicPlayer2/CUIDrawer.cpp b/MusicPlayer2/CUIDrawer.cpp index 21676ca99..52ca52c09 100644 --- a/MusicPlayer2/CUIDrawer.cpp +++ b/MusicPlayer2/CUIDrawer.cpp @@ -1,6 +1,7 @@ #include "stdafx.h" #include "CUIDrawer.h" #include "MusicPlayer2.h" +#include "Player.h" CUIDrawer::CUIDrawer(UIColors& colors) : m_colors(colors) @@ -12,6 +13,12 @@ CUIDrawer::~CUIDrawer() { } +void CUIDrawer::SetLyricFont(CFont* lyric_font, CFont* lyric_tr_font) +{ + m_lyric_font = lyric_font; + m_lyric_tr_font = lyric_tr_font; +} + void CUIDrawer::DrawLryicCommon(CRect rect, Alignment align) { SetDrawArea(rect); @@ -25,16 +32,15 @@ void CUIDrawer::DrawLryicCommon(CRect rect, Alignment align) int CUIDrawer::GetLyricTextHeight() const { //计算文本高度 - if (!m_for_cortana_lyric) - m_pDC->SelectObject(&theApp.m_font_set.lyric.GetFont(theApp.m_ui_data.full_screen)); - else - m_pDC->SelectObject(&theApp.m_font_set.cortana.GetFont()); - return m_pDC->GetTextExtent(L"文").cy; //根据当前的字体设置计算文本的高度 + CFont* pOldFont = m_pDC->SelectObject(m_lyric_font); + int height = m_pDC->GetTextExtent(L"文").cy; + m_pDC->SelectObject(pOldFont); + return height; //根据当前的字体设置计算文本的高度 } -void CUIDrawer::Create(CDC* pDC, CWnd* pMainWnd) +void CUIDrawer::Create(CDC* pDC, CFont* pFont) { - CDrawCommon::Create(pDC, pMainWnd); + CDrawCommon::Create(pDC, pFont); } bool CUIDrawer::IsDrawMultiLine(int height) const @@ -67,16 +73,16 @@ void CUIDrawer::DrawLyricTextMultiLine(CRect lyric_area, Alignment align) int lyric_height = GetLyricTextHeight() + line_space; //文本高度加上行间距 int lyric_height2 = lyric_height * 2 + line_space; //包含翻译的歌词高度 - CFont* pOldFont = SetLyricFont(); + CFont* pOldFont = SetFont(m_lyric_font); if (CPlayer::GetInstance().IsPlaylistEmpty()) //当前播放为空时在歌词区域显示播放提示 { CFont* font = SetFont(&theApp.m_font_set.font10.GetFont()); - CString no_track_tip_str{ CCommon::LoadTextFormat(IDS_NO_TRACKS_TIP_INFO, { + wstring no_track_tip_str = theApp.m_str_table.LoadTextFormat(L"UI_LYRIC_NO_TRACKS_TIP", { theApp.m_accelerator_res.GetShortcutDescriptionById(ID_SHOW_PLAYLIST), theApp.m_accelerator_res.GetShortcutDescriptionById(ID_FILE_OPEN), theApp.m_accelerator_res.GetShortcutDescriptionById(ID_FILE_OPEN_FOLDER), - theApp.m_accelerator_res.GetShortcutDescriptionById(ID_SET_PATH)})}; - DrawWindowText(lyric_area, no_track_tip_str, m_colors.color_text_2, Alignment::LEFT, false, true); + theApp.m_accelerator_res.GetShortcutDescriptionById(ID_MEDIA_LIB)}); + DrawWindowText(lyric_area, no_track_tip_str.c_str(), m_colors.color_text_2, Alignment::LEFT, false, true); SetFont(font); } else if (CPlayerUIHelper::IsMidiLyric()) @@ -100,7 +106,8 @@ void CUIDrawer::DrawLyricTextMultiLine(CRect lyric_area, Alignment align) //显示“当前歌曲没有歌词” else { - DrawWindowText(lyric_area, CCommon::LoadText(IDS_NO_LYRIC_INFO), m_colors.color_text_2, Alignment::CENTER); + static const wstring& no_lyric_info = theApp.m_str_table.LoadText(L"UI_LYRIC_NONE"); + DrawWindowText(lyric_area, no_lyric_info.c_str(), m_colors.color_text_2, Alignment::CENTER); } } else @@ -173,7 +180,7 @@ void CUIDrawer::DrawLyricTextMultiLine(CRect lyric_area, Alignment align) int fade_percent = last_time_span / 8; //计算颜色高亮变化的百分比,除数越大则持续时间越长,10则为1秒 COLORREF text_color = CColorConvert::GetGradientColor(m_colors.color_text_2, m_colors.color_text, fade_percent); //绘制歌词文本 - SetLyricFont(); + SetFont(m_lyric_font); if (theApp.m_lyric_setting_data.lyric_karaoke_disp) DrawWindowText(rect_text, lyric_i.text.c_str(), m_colors.color_text, m_colors.color_text_2, progress, align, true); else @@ -181,13 +188,13 @@ void CUIDrawer::DrawLyricTextMultiLine(CRect lyric_area, Alignment align) //绘制翻译文本 if (!lyric_i.translate.empty() && theApp.m_lyric_setting_data.show_translate) { - SetLyricFontTranslated(); + SetFont(m_lyric_tr_font); DrawWindowText(rect_translate, lyric_i.translate.c_str(), text_color, text_color, progress, align, true); } } else //绘制非正在播放的歌词 { - SetLyricFont(); + SetFont(m_lyric_font); COLORREF text_color; if (i == lyric_index - 1 || (i == lyric_index && progress == 1000)) // 绘制正在取消高亮的歌词(这里实现一句歌词颜色从高亮缓慢变化到非高亮效果),逐字歌词最后一句在此处取消高亮 { @@ -204,7 +211,7 @@ void CUIDrawer::DrawLyricTextMultiLine(CRect lyric_area, Alignment align) //绘制翻译文本 if (!lyric_i.translate.empty() && theApp.m_lyric_setting_data.show_translate) { - SetLyricFontTranslated(); + SetFont(m_lyric_tr_font); DrawWindowText(rect_translate, lyric_i.translate.c_str(), text_color, align, true); } } @@ -216,7 +223,7 @@ void CUIDrawer::DrawLyricTextMultiLine(CRect lyric_area, Alignment align) void CUIDrawer::DrawLyricTextSingleLine(CRect rect, int& flag, bool double_line, Alignment align) { - CFont* pOldFont = SetLyricFont(); + CFont* pOldFont = SetFont(m_lyric_font); if (CPlayerUIHelper::IsMidiLyric()) { @@ -237,7 +244,8 @@ void CUIDrawer::DrawLyricTextSingleLine(CRect rect, int& flag, bool double_line, //显示“当前歌曲没有歌词” else { - DrawWindowText(rect, CCommon::LoadText(IDS_NO_LYRIC_INFO), m_colors.color_text_2, Alignment::CENTER); + static const wstring& no_lyric_info = theApp.m_str_table.LoadText(L"UI_LYRIC_NONE"); + DrawWindowText(rect, no_lyric_info.c_str(), m_colors.color_text_2, Alignment::CENTER); } } else @@ -245,6 +253,7 @@ void CUIDrawer::DrawLyricTextSingleLine(CRect rect, int& flag, bool double_line, SetDrawArea(rect); CRect lyric_rect = rect; + static const wstring& empty_lyric = theApp.m_str_table.LoadText(L"UI_LYRIC_EMPTY_LINE"); const bool karaoke{ theApp.m_lyric_setting_data.lyric_karaoke_disp }; const bool ignore_blank{ theApp.m_lyric_setting_data.donot_show_blank_lines}; auto& now_lyrics{ CPlayer::GetInstance().m_Lyrics }; @@ -256,14 +265,14 @@ void CUIDrawer::DrawLyricTextSingleLine(CRect rect, int& flag, bool double_line, flag = switch_flag ? 10000 + progress : progress; if (current_lyric.text.empty()) - current_lyric.text = CCommon::LoadText(IDS_DEFAULT_LYRIC_TEXT); + current_lyric.text = empty_lyric; //双行显示歌词 if (double_line && (current_lyric.translate.empty() || !theApp.m_lyric_setting_data.show_translate) && rect.Height() > static_cast(GetLyricTextHeight() * 1.73)) { wstring next_lyric_text; next_lyric_text = now_lyrics.GetLyric(time, true, ignore_blank, karaoke).text; if (next_lyric_text.empty()) - next_lyric_text = CCommon::LoadText(IDS_DEFAULT_LYRIC_TEXT); + next_lyric_text = empty_lyric; //这里实现文本从非高亮缓慢变化到高亮效果 int last_time_span = time - current_lyric.time_start; //当前播放的歌词已持续的时间 int fade_percent = last_time_span / 8; //计算颜色高亮变化的百分比,除数越大则持续时间越长,10则为1秒 @@ -282,11 +291,11 @@ void CUIDrawer::DrawLyricTextSingleLine(CRect rect, int& flag, bool double_line, CRect translate_rect = lyric_rect; translate_rect.MoveToY(lyric_rect.bottom); - SetLyricFontTranslated(); + SetFont(m_lyric_tr_font); DrawWindowText(translate_rect, current_lyric.translate.c_str(), m_colors.color_text, m_colors.color_text, progress, align, true); } // 绘制单行歌词 - SetLyricFont(); + SetFont(m_lyric_font); if (theApp.m_lyric_setting_data.lyric_karaoke_disp) DrawWindowText(lyric_rect, current_lyric.text.c_str(), m_colors.color_text, m_colors.color_text_2, progress, align, true); else if (0 < progress && progress < 1000) // 仅高亮“正在进行”的歌词 @@ -432,7 +441,7 @@ int CUIDrawer::DPI(int pixel) void CUIDrawer::DrawLyricDoubleLine(CRect rect, LPCTSTR lyric, LPCTSTR next_lyric, Alignment align, int progress, bool switch_flag, int fade_percent) { - CFont* pOldFont = SetLyricFont(); + CFont* pOldFont = SetFont(m_lyric_font); CRect up_rect{ rect }, down_rect{ rect }; //上半部分和下半部分歌词的矩形区域 up_rect.bottom = up_rect.top + (up_rect.Height() / 2); @@ -467,19 +476,3 @@ void CUIDrawer::DrawLyricDoubleLine(CRect rect, LPCTSTR lyric, LPCTSTR next_lyri } SetFont(pOldFont); } - -CFont* CUIDrawer::SetLyricFont() -{ - if (!m_for_cortana_lyric) - return SetFont(&theApp.m_font_set.lyric.GetFont(theApp.m_ui_data.full_screen)); - else - return SetFont(&theApp.m_font_set.cortana.GetFont()); -} - -CFont* CUIDrawer::SetLyricFontTranslated() -{ - if (!m_for_cortana_lyric) - return SetFont(&theApp.m_font_set.lyric_translate.GetFont(theApp.m_ui_data.full_screen)); - else - return SetFont(&theApp.m_font_set.cortana_translate.GetFont()); -} diff --git a/MusicPlayer2/CUIDrawer.h b/MusicPlayer2/CUIDrawer.h index 2f2f98fdf..610512288 100644 --- a/MusicPlayer2/CUIDrawer.h +++ b/MusicPlayer2/CUIDrawer.h @@ -18,10 +18,13 @@ class CUIDrawer : CUIDrawer(UIColors& colors); ~CUIDrawer(); + // 设置歌词&翻译字体 + void SetLyricFont(CFont* lyric_font, CFont* lyric_tr_font); + void DrawLryicCommon(CRect rect, Alignment align = Alignment::AUTO); int GetLyricTextHeight() const; - virtual void Create(CDC* pDC, CWnd* pMainWnd /* = nullptr */) override; + virtual void Create(CDC* pDC, CFont* pFont/* = nullptr */) override; bool IsDrawMultiLine(int height) const; //根据一个高度判断是否绘制多行歌词 void SetForCortanaLyric(bool for_cortana_lyric = true); @@ -48,13 +51,13 @@ class CUIDrawer : int DPI(int pixel); private: - CFont* SetLyricFont(); - CFont* SetLyricFontTranslated(); // 实际绘制双行歌词 void DrawLyricDoubleLine(CRect rect, LPCTSTR lyric, LPCTSTR next_lyric, Alignment align, int progress, bool switch_flag, int fade_percent = 100); private: UIColors& m_colors; + CFont* m_lyric_font = nullptr; + CFont* m_lyric_tr_font = nullptr; bool m_for_cortana_lyric{ false }; //是否用于显示搜索框歌词 }; diff --git a/MusicPlayer2/CleanupRangeDlg.cpp b/MusicPlayer2/CleanupRangeDlg.cpp index 031a5b775..1acaac97d 100644 --- a/MusicPlayer2/CleanupRangeDlg.cpp +++ b/MusicPlayer2/CleanupRangeDlg.cpp @@ -26,6 +26,21 @@ CString CCleanupRangeDlg::GetDialogName() const return _T("CleanupRangeDlg"); } +bool CCleanupRangeDlg::InitializeControls() +{ + wstring temp; + temp = theApp.m_str_table.LoadText(L"TITLE_CLEAN_UP_RANGE"); + SetWindowTextW(temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_CLEAN_UP_RANGE_SEL"); + SetDlgItemTextW(IDC_TXT_CLEAN_UP_RANGE_SEL_STATIC, temp.c_str()); + + RepositionTextBasedControls({ + { CtrlTextInfo::R1, IDOK, CtrlTextInfo::W32 }, + { CtrlTextInfo::R2, IDCANCEL, CtrlTextInfo::W32 } + }); + return true; +} + void CCleanupRangeDlg::DoDataExchange(CDataExchange* pDX) { CBaseDialog::DoDataExchange(pDX); @@ -46,19 +61,19 @@ BOOL CCleanupRangeDlg::OnInitDialog() CBaseDialog::OnInitDialog(); // TODO: 在此添加额外的初始化 - SetIcon(theApp.m_icon_set.app.GetIcon(), FALSE); + SetIcon(IconMgr::IconType::IT_App, FALSE); m_list_ctrl.SetExtendedStyle(m_list_ctrl.GetExtendedStyle() | LVS_EX_CHECKBOXES); m_list_ctrl.SetRowHeight(theApp.DPI(24)); m_list_ctrl.FillLeftSpaceAfterPaint(false); - m_list_ctrl.AddString(CCommon::LoadText(IDS_FILES_THAT_NOT_EXIST)); - m_list_ctrl.AddString(CCommon::LoadText(IDS_FILES_NOT_IN_MEDIA_LIB_DIR)); - m_list_ctrl.AddString(CCommon::LoadText(IDS_FILES_THAT_ERROR)); - m_list_ctrl.AddString(CCommon::LoadText(IDS_FILES_TOO_SHORT)); + m_list_ctrl.AddString(theApp.m_str_table.LoadText(L"TXT_CLEAN_UP_RANGE_FILES_THAT_NOT_EXIST").c_str()); + m_list_ctrl.AddString(theApp.m_str_table.LoadText(L"TXT_CLEAN_UP_RANGE_FILES_NOT_IN_MEDIA_LIB_DIR").c_str()); + m_list_ctrl.AddString(theApp.m_str_table.LoadText(L"TXT_CLEAN_UP_RANGE_FILES_THAT_ERROR").c_str()); + m_list_ctrl.AddString(theApp.m_str_table.LoadText(L"TXT_CLEAN_UP_RANGE_FILES_TOO_SHORT").c_str()); // 媒体库目录存在Songs文件夹的话再显示这个清理选项 if (m_clean_file_non_main_in_osu_enable) - m_list_ctrl.AddString(CCommon::LoadText(IDS_FILES_NON_MAIN_IN_OSU)); + m_list_ctrl.AddString(theApp.m_str_table.LoadText(L"TXT_CLEAN_UP_RANGE_FILES_NON_MAIN_IN_OSU").c_str()); return TRUE; // return TRUE unless you set the focus to a control // 异常: OCX 属性页应返回 FALSE @@ -77,7 +92,8 @@ void CCleanupRangeDlg::OnOK() if (!m_clean_file_not_exist && !m_clean_file_not_in_media_lib_dir && !m_clean_file_wrong && !m_clean_file_too_short && !m_clean_file_non_main_in_osu) { - MessageBox(CCommon::LoadText(IDS_CLEAN_UP_MEDIA_WARNING), NULL, MB_OK | MB_ICONWARNING); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_CLEAN_UP_RANGE_NOT_SELECT_WARNING"); + MessageBox(info.c_str(), NULL, MB_OK | MB_ICONWARNING); return; } diff --git a/MusicPlayer2/CleanupRangeDlg.h b/MusicPlayer2/CleanupRangeDlg.h index 87119b8c8..8bb18e170 100644 --- a/MusicPlayer2/CleanupRangeDlg.h +++ b/MusicPlayer2/CleanupRangeDlg.h @@ -36,6 +36,7 @@ class CCleanupRangeDlg : public CBaseDialog protected: virtual CString GetDialogName() const override; + virtual bool InitializeControls() override; virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() diff --git a/MusicPlayer2/ColorConvert.cpp b/MusicPlayer2/ColorConvert.cpp index 5a7a608b0..a5f4a4dec 100644 --- a/MusicPlayer2/ColorConvert.cpp +++ b/MusicPlayer2/ColorConvert.cpp @@ -224,6 +224,8 @@ void CColorConvert::ReduceLuminance(COLORREF & color) } } +// 考虑改用CDrawingManager::SmartMixColors,CDrawingManager中也有各种HSL/HSV/RGB互转的静态方法 +// https://learn.microsoft.com/zh-cn/cpp/mfc/reference/cdrawingmanager-class?view=msvc-170 COLORREF CColorConvert::GetGradientColor(COLORREF color1, COLORREF color2, int percent) { if (percent > 100) diff --git a/MusicPlayer2/Common.cpp b/MusicPlayer2/Common.cpp index b40e8c9cc..fd444a6ce 100644 --- a/MusicPlayer2/Common.cpp +++ b/MusicPlayer2/Common.cpp @@ -3,7 +3,6 @@ #include "resource.h" #include "FilePathHelper.h" #include -#include #include // #include @@ -39,11 +38,16 @@ CCommon::~CCommon() // std::sort(files.begin(), files.end()); //对容器里的文件按名称排序 //} -bool CCommon::FileExist(const wstring& file) +bool CCommon::FileExist(const wstring& file, bool is_case_sensitive) { - if (file == L"." || file == L"..") + WIN32_FIND_DATA findFileData; + HANDLE hFind = FindFirstFileW(file.c_str(), &findFileData); + if (hFind == INVALID_HANDLE_VALUE) // 没有找到说明不区分大小写也没有匹配文件 return false; - return (PathFileExists(file.c_str()) != 0); + FindClose(hFind); + if (is_case_sensitive) // 如果需要区分大小写那么重新严格比较 + return CFilePathHelper(file).GetFileName() == findFileData.cFileName; + return true; } bool CCommon::FolderExist(const wstring& file) @@ -58,16 +62,31 @@ bool CCommon::IsFolder(const wstring& path) return (dwAttrib & FILE_ATTRIBUTE_DIRECTORY) != 0; } -unsigned __int64 CCommon::GetFileLastModified(const wstring& file_path) +bool CCommon::CheckAndFixFile(wstring& file) { - WIN32_FIND_DATA ffd; - HANDLE hFind = FindFirstFile(file_path.c_str(), &ffd); + WIN32_FIND_DATA findFileData; + HANDLE hFind = FindFirstFileW(file.c_str(), &findFileData); + if (hFind == INVALID_HANDLE_VALUE) + return false; FindClose(hFind); - unsigned __int64 last_modified_time{}; - last_modified_time = ffd.ftLastWriteTime.dwLowDateTime; - unsigned __int64 hight_date_time = ffd.ftLastWriteTime.dwHighDateTime; - last_modified_time |= (hight_date_time << 32); - return last_modified_time; + CFilePathHelper file_path(file); + file = file_path.GetDir() + findFileData.cFileName; // 修正file的文件名大小写到与文件一致 + return true; +} + +bool CCommon::GetFileLastModified(const wstring& file_path, unsigned __int64& modified_time) +{ + // 使用GetFileAttributesEx,耗时大约为FindFirstFile的2/3 + WIN32_FILE_ATTRIBUTE_DATA file_attributes; + if (GetFileAttributesEx(file_path.c_str(), GetFileExInfoStandard, &file_attributes)) + { + ULARGE_INTEGER last_modified_time{}; + last_modified_time.HighPart = file_attributes.ftLastWriteTime.dwHighDateTime; + last_modified_time.LowPart = file_attributes.ftLastWriteTime.dwLowDateTime; + modified_time = last_modified_time.QuadPart; + return true; + } + return false; } bool CCommon::IsFileHidden(const wstring& file_path) @@ -172,6 +191,40 @@ bool CCommon::CharIsNumber(wchar_t ch) return (ch >= L'0' && ch <= L'9'); } +void CCommon::StringSplitLine(const wstring& source_str, vector& results, bool skip_empty, bool trim) +{ + results.clear(); + if (source_str.empty()) + return; + + auto push_back_str = [&](const wchar_t* start, const wchar_t* end) + { + wstring tmp(start, end); + if (trim) + StringNormalize(tmp); + if (!skip_empty || !tmp.empty()) + results.push_back(std::move(tmp)); + }; + + const wchar_t* line_start_pos = source_str.data(); + const wchar_t* cur_pos = line_start_pos; + const wchar_t* end_pos = line_start_pos + source_str.size(); + while (cur_pos < end_pos) + { + if (*cur_pos == L'\r' || *cur_pos == L'\n') + { + push_back_str(line_start_pos, cur_pos); + ++cur_pos; // 指针移动到下一个字符 + if (*cur_pos == L'\n' && *(cur_pos - 1) == L'\r') // 如果下一个字符是LF且位于CR后面那么跳过 + ++cur_pos; + line_start_pos = cur_pos; + } + else + ++cur_pos; + } + push_back_str(line_start_pos, cur_pos); +} + void CCommon::StringSplit(const wstring& str, wchar_t div_ch, vector& results, bool skip_empty, bool trim) { results.clear(); @@ -707,117 +760,18 @@ wstring CCommon::GetAppDataConfigDir() wstring CCommon::GetSpecialDir(int csidl) { + bool rtn{}; LPITEMIDLIST ppidl; - TCHAR folder_dir[MAX_PATH]; + wchar_t folder_dir[MAX_PATH]; if (SHGetSpecialFolderLocation(NULL, csidl, &ppidl) == S_OK) { - SHGetPathFromIDList(ppidl, folder_dir); + rtn = SHGetPathFromIDListW(ppidl, folder_dir); CoTaskMemFree(ppidl); } - return wstring(folder_dir); -} - -//int CCommon::GetListWidth(CListBox & list) -//{ -// CDC *pDC = list.GetDC(); -// if (NULL == pDC) -// { -// return 0; -// } -// int nCount = list.GetCount(); -// if (nCount < 1) -// return 0; -// int nMaxExtent = 0; -// CString szText; -// for (int i = 0; i < nCount; ++i) -// { -// list.GetText(i, szText); -// CSize &cs = pDC->GetTextExtent(szText); -// if (cs.cx > nMaxExtent) -// { -// nMaxExtent = cs.cx; -// } -// } -// return nMaxExtent; -//} - - -int CCommon::DeleteAFile(HWND hwnd, _tstring file) -{ - file.push_back(_T('\0')); //pFrom必须以两个\0结尾 - LPCTSTR strTitle = CCommon::LoadText(IDS_DELETE); //文件删除进度对话框标题 - SHFILEOPSTRUCT FileOp{}; //定义SHFILEOPSTRUCT结构对象 - FileOp.hwnd = hwnd; - FileOp.wFunc = FO_DELETE; //执行文件删除操作; - FileOp.pFrom = file.c_str(); - FileOp.fFlags = FOF_ALLOWUNDO; //此标志使删除文件备份到Windows回收站 - FileOp.hNameMappings = NULL; - FileOp.lpszProgressTitle = strTitle; - return SHFileOperation(&FileOp); //删除文件 -} - -int CCommon::DeleteFiles(HWND hwnd, const vector<_tstring>& files) -{ - _tstring file_list; - for (const auto& file : files) - { - file_list += file; - file_list.push_back(_T('\0')); - } - return DeleteAFile(hwnd, file_list); -} - -int CCommon::CopyAFile(HWND hwnd, _tstring file_from, _tstring file_to) -{ - file_from.push_back(_T('\0')); //pFrom必须以两个\0结尾 - file_to.push_back(_T('\0')); //pTo必须以两个\0结尾 - SHFILEOPSTRUCT FileOp{}; - FileOp.hwnd = hwnd; - FileOp.wFunc = FO_COPY; - FileOp.pFrom = file_from.c_str(); - FileOp.pTo = file_to.c_str(); - FileOp.fFlags = FOF_ALLOWUNDO; - FileOp.hNameMappings = NULL; - static CString str_title = LoadText(IDS_COPY); - FileOp.lpszProgressTitle = str_title; - return SHFileOperation(&FileOp); -} - -int CCommon::CopyFiles(HWND hwnd, const vector<_tstring>& files, _tstring file_to) -{ - _tstring file_list; - for (const auto& file : files) - { - file_list += file; - file_list.push_back(_T('\0')); - } - return CopyAFile(hwnd, file_list, file_to); -} - -int CCommon::MoveAFile(HWND hwnd, _tstring file_from, _tstring file_to) -{ - file_from.push_back(_T('\0')); //pFrom必须以两个\0结尾 - file_to.push_back(_T('\0')); //pTo必须以两个\0结尾 - SHFILEOPSTRUCT FileOp{}; - FileOp.hwnd = hwnd; - FileOp.wFunc = FO_MOVE; - FileOp.pFrom = file_from.c_str(); - FileOp.pTo = file_to.c_str(); - FileOp.fFlags = FOF_ALLOWUNDO; - FileOp.hNameMappings = NULL; - FileOp.lpszProgressTitle = LoadText(IDS_MOVE); - return SHFileOperation(&FileOp); -} - -int CCommon::MoveFiles(HWND hwnd, const vector<_tstring>& files, _tstring file_to) -{ - _tstring file_list; - for (const auto& file : files) - { - file_list += file; - file_list.push_back(_T('\0')); - } - return MoveAFile(hwnd, file_list, file_to); + ASSERT(rtn); + if (rtn) + return wstring(folder_dir); + return wstring(); } bool CCommon::CreateDir(const _tstring& path) @@ -1387,42 +1341,6 @@ void CCommon::IterateMenuItem(CMenu* pMenu, std::function fu } } -CString CCommon::LoadText(UINT id, LPCTSTR back_str) -{ - CString str; - str.LoadString(id); - if (back_str != nullptr) - str += back_str; - return str; -} - -CString CCommon::LoadText(LPCTSTR front_str, UINT id, LPCTSTR back_str) -{ - CString str; - str.LoadString(id); - if (back_str != nullptr) - str += back_str; - if (front_str != nullptr) - str = front_str + str; - return str; -} - -CString CCommon::StringFormat(LPCTSTR format_str, const std::initializer_list& paras) -{ - CString str_rtn = format_str; - int index = 1; - for (const auto& para : paras) - { - CString para_str = para.ToString(); - CString format_para; - format_para.Format(_T("<%%%d%%>"), index); - str_rtn.Replace(format_para, para_str); - - index++; - } - return str_rtn; -} - bool CCommon::StringLeftMatch(const std::wstring& str, const std::wstring& matched_str) { if (str.size() < matched_str.size()) @@ -1430,48 +1348,55 @@ bool CCommon::StringLeftMatch(const std::wstring& str, const std::wstring& match return str.substr(0, matched_str.size()) == matched_str; } -CString CCommon::LoadTextFormat(UINT id, const std::initializer_list& paras) +bool CCommon::GetThreadLanguageList(vector& language_tag) { - CString str; - str.LoadString(id); - return StringFormat(str.GetString(), paras); + language_tag.clear(); + ULONG num{}; + vector buffer(LOCALE_NAME_MAX_LENGTH, L'\0'); + ULONG buffer_size{ static_cast(buffer.size()) }; + bool rtn = GetThreadPreferredUILanguages(MUI_LANGUAGE_NAME, &num, buffer.data(), &buffer_size); // >=Windows Vista + if (!rtn) return false; + ASSERT(buffer_size <= LOCALE_NAME_MAX_LENGTH); + size_t pos{}; + for (size_t i{}; i < buffer_size; ++i) + { + if (buffer[i] != L'\0' || pos == i) + continue; + wstring tmp(buffer.begin() + pos, buffer.begin() + i); + language_tag.push_back(tmp); + pos = i + 1; + } + ASSERT(language_tag.size() == num); + return true; } -void CCommon::ReplaceUiStringRes(std::wstring& str) +bool CCommon::SetThreadLanguageList(const vector& language_tag) { - size_t index{}; - while (true) + vector buffer; + size_t buffer_size{ 1 }; + for (const wstring& tag : language_tag) { - index = str.find(L"%(", index); - if (index == std::wstring::npos) + if (tag.empty()) continue; + buffer_size += tag.size() + 1; + if (buffer_size > LOCALE_NAME_MAX_LENGTH) break; - size_t right_bracket_index = str.find(L')', index + 2); - if (right_bracket_index == std::wstring::npos) - break; - int res_id = _wtoi(str.substr(index + 2, right_bracket_index - index - 2).c_str()); - std::wstring res_str = LoadText(static_cast(res_id)).GetString(); - if (!res_str.empty()) - { - str.replace(index, right_bracket_index - index + 1, res_str); - index += res_str.size(); - } - else - { - index = right_bracket_index + 1; - } + buffer.insert(buffer.end(), tag.begin(), tag.end()); + buffer.push_back(L'\0'); } + if (buffer.empty()) // buffer为空时多插入一个\0确保双\0结尾(空buffer会重置之前设置的线程首选UI语言列表) + buffer.push_back(L'\0'); + buffer.push_back(L'\0'); + bool rtn = SetThreadPreferredUILanguages(MUI_LANGUAGE_NAME, buffer.data(), nullptr); // >=Windows Vista + return rtn; } - -void CCommon::SetThreadLanguage(Language language) +wstring CCommon::GetSystemDefaultUIFont() { - switch (language) - { - case Language::ENGLISH: SetThreadUILanguage(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)); break; - case Language::SIMPLIFIED_CHINESE: SetThreadUILanguage(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED)); break; - //case Language::TRADITIONAL_CHINESE: SetThreadUILanguage(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL)); break; - default: break; - } + NONCLIENTMETRICS metrics; + metrics.cbSize = sizeof(NONCLIENTMETRICS); + SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &metrics, 0); + wstring font_name = metrics.lfMessageFont.lfFaceName; + return font_name; } void CCommon::WStringCopy(wchar_t* str_dest, int dest_size, const wchar_t* str_source, int source_size) @@ -1759,77 +1684,84 @@ bool CCommon::GetNumberBit(unsigned short num, int bit) std::string CCommon::GetTextResourceRawData(UINT id) { std::string res_data; - HRSRC hRes = FindResource(NULL, MAKEINTRESOURCE(id), _T("TEXT")); - if (hRes != NULL) + HINSTANCE hInstance = AfxGetResourceHandle(); + HRSRC hRsrc = FindResource(NULL, MAKEINTRESOURCE(id), _T("TEXT")); + if (hRsrc != NULL) { - HGLOBAL hglobal = LoadResource(NULL, hRes); - if (hglobal != NULL) + HGLOBAL hGlobal = LoadResource(NULL, hRsrc); + if (hGlobal != NULL) { - res_data = (const char*)hglobal; + const char* pResource = static_cast(LockResource(hGlobal)); + if (pResource != NULL) + { + // 获取资源大小 + DWORD dwSize = SizeofResource(hInstance, hRsrc); + // 将资源数据存储到std::string + return std::string(pResource, dwSize); + } + UnlockResource(hGlobal); } } return res_data; } -CString CCommon::GetTextResource(UINT id, CodeType code_type) +wstring CCommon::GetTextResource(UINT id, CodeType code_type) { - std::string res_data = GetTextResourceRawData(id); - res_data.push_back('\0'); - CString res_str; - if (!res_data.empty()) - { - if (code_type == CodeType::UTF16LE) - { - res_str = (const wchar_t*)res_data.c_str(); - } - else - { - res_str = CCommon::StrToUnicode(res_data, code_type).c_str(); - } - } + string res_data = GetTextResourceRawData(id); + wstring res_str = CCommon::StrToUnicode(res_data, code_type); return res_str; } Gdiplus::Image* CCommon::GetPngImageResource(UINT id) { - HINSTANCE hIns = AfxGetInstanceHandle(); - HRSRC hRsrc = ::FindResource(hIns, MAKEINTRESOURCE(id), _T("PNG")); // type - if (!hRsrc) - return nullptr; - // load resource into memory - DWORD len = SizeofResource(hIns, hRsrc); - BYTE* lpRsrc = (BYTE*)LoadResource(hIns, hRsrc); - if (!lpRsrc) - return nullptr; - // Allocate global memory on which to create stream - HGLOBAL m_hMem = GlobalAlloc(GMEM_FIXED, len); - BYTE* pmem = (BYTE*)GlobalLock(m_hMem); - memcpy(pmem, lpRsrc, len); - IStream* pstm; - CreateStreamOnHGlobal(m_hMem, FALSE, &pstm); - // load from stream - Gdiplus::Image* lpImage = Gdiplus::Image::FromStream(pstm); - // free/release stuff - GlobalUnlock(m_hMem); - pstm->Release(); - FreeResource(lpRsrc); - return lpImage; + Gdiplus::Image* pImage = nullptr; + HINSTANCE hInst = AfxGetResourceHandle(); + if (HRSRC hRes = ::FindResource(hInst, MAKEINTRESOURCE(id), _T("PNG"))) + { + DWORD imageSize = ::SizeofResource(hInst, hRes); + if (HGLOBAL hResData = ::LoadResource(hInst, hRes)) + { + LPVOID pResourceData = ::LockResource(hResData); +#ifdef COMPILE_IN_WIN_XP + if (HGLOBAL hBuffer = ::GlobalAlloc(GMEM_FIXED, imageSize)) + { + ::CopyMemory(hBuffer, pResourceData, imageSize); + IStream* pStream = nullptr; + if (SUCCEEDED(::CreateStreamOnHGlobal(hBuffer, TRUE, &pStream))) + { + pImage = Gdiplus::Image::FromStream(pStream); + pStream->Release(); + } + ::GlobalFree(hBuffer); // 释放内存句柄 + } +#else // 在缓冲区上创建内存流 + if (IStream* pStream = SHCreateMemStream(static_cast(pResourceData), imageSize)) + { + pImage = Gdiplus::Image::FromStream(pStream); + pStream->Release(); + } +#endif // COMPILE_IN_WIN_XP + ::FreeResource(hResData); + } + } + return pImage; } string CCommon::GetPngImageResourceData(UINT id) { - HINSTANCE hIns = AfxGetInstanceHandle(); - HRSRC hRsrc = ::FindResource(hIns, MAKEINTRESOURCE(id), _T("PNG")); // type - if (!hRsrc) - return nullptr; - // load resource into memory - DWORD len = SizeofResource(hIns, hRsrc); - BYTE* lpRsrc = (BYTE*)LoadResource(hIns, hRsrc); - if (!lpRsrc) - return nullptr; - string data((const char*)lpRsrc, len); - FreeResource(lpRsrc); + string data; + HINSTANCE hInst = AfxGetResourceHandle(); + if (HRSRC hRes = ::FindResource(hInst, MAKEINTRESOURCE(id), _T("PNG"))) + { + DWORD imageSize = ::SizeofResource(hInst, hRes); + if (HGLOBAL hResData = ::LoadResource(hInst, hRes)) + { + LPVOID pResourceData = ::LockResource(hResData); + data = string(static_cast(pResourceData), imageSize); + ::FreeResource(hResData); + } + } return data; } @@ -1888,11 +1820,17 @@ POINT CCommon::CalculateWindowMoveOffset(CRect& check_rect, vector& scree return mov; } -CString CCommon::GetLastCompileTime() +wstring CCommon::GetLastCompileTime() { - CString compile_time = GetTextResource(IDR_COMPILE_TIME, CodeType::ANSI); - compile_time.Replace(_T("\r\n"), _T("")); - compile_time.Delete(compile_time.GetLength() - 1, 1); + wstring compile_time = GetTextResource(IDR_COMPILE_TIME, CodeType::ANSI); + size_t pos = compile_time.find(L"\r\n"); + while (pos != wstring::npos) + { + compile_time.replace(pos, 2, L""); + pos = compile_time.find(L"\r\n"); + } + if (!compile_time.empty()) + compile_time.pop_back(); return compile_time; } @@ -1903,6 +1841,7 @@ unsigned __int64 CCommon::GetCurTimeElapse() CTime cur_time(sys_time); unsigned __int64 c_time = cur_time.GetTime(); static unsigned __int64 last_time{}; + // 此处用作排序时间戳,需要避免重复 last_time = (last_time < c_time) ? c_time : (last_time + 1); return last_time; } diff --git a/MusicPlayer2/Common.h b/MusicPlayer2/Common.h index 30535f5f7..9f43f056e 100644 --- a/MusicPlayer2/Common.h +++ b/MusicPlayer2/Common.h @@ -2,7 +2,6 @@ #pragma once #include "CVariant.h" #include -#include #include #include @@ -16,8 +15,7 @@ enum class Command PLAY_PAUSE, FF, //快进 REW, //快倒 - VOLUME_UP, - VOLUME_DOWN, + VOLUME_ADJ, SEEK }; @@ -45,22 +43,14 @@ enum class CodeType AUTO }; -//语言 -enum class Language -{ - FOLLOWING_SYSTEM, //跟随系统 - ENGLISH, //英语 - SIMPLIFIED_CHINESE //简体中文 -}; - class CCommon { public: CCommon(); ~CCommon(); - //判断文件是否存在 - static bool FileExist(const wstring& file); + // 判断文件是否存在,file为文件绝对路径,is_case_sensitive为true时对文件名区分大小写(路径仍然不区分) + static bool FileExist(const wstring& file, bool is_case_sensitive = false); //判断文件夹是否存在 static bool FolderExist(const wstring& file); @@ -68,7 +58,10 @@ class CCommon //判断是否是文件夹 static bool IsFolder(const wstring& path); - static unsigned __int64 GetFileLastModified(const wstring& file_path); + // 判断文件是否存在,file为文件绝对路径,如果存在会更正文件名大小写到与实际文件一致 + static bool CheckAndFixFile(wstring& file); + + static bool GetFileLastModified(const wstring& file_path, unsigned __int64& modified_time); //判断文件是否隐藏 static bool IsFileHidden(const wstring& file_path); @@ -117,6 +110,9 @@ class CCommon static bool CharIsNumber(wchar_t ch); + // 按换行分割字符串,自适应CR/LF/CRLF换行 + static void StringSplitLine(const wstring& source_str, vector& results, bool skip_empty = true, bool trim = true); + //将一个字符串分割成若干个字符串 //str: 原始字符串 //div_ch: 用于分割的字符 @@ -196,7 +192,7 @@ class CCommon //判断一个字符串是否符合绝对路径的格式(而不是判断路径是否有效) static bool IsPath(const wstring& str); - //删除一个字符串中指定的字符 + //替换一个字符串中指定的字符 static bool StringCharacterReplace(wstring& str, wchar_t ch, wchar_t ch_replaced); static void StringReplace(wstring& str, const wstring& str_old, const wstring& str_new); @@ -219,27 +215,6 @@ class CCommon //csidl: 含义同SHGetSpecialFolderLocation函数的参数 static wstring GetSpecialDir(int csidl); - ////获取一个列表控件最大长度项目宽度的像素值 - //static int GetListWidth(CListBox& list); - - //删除一个文件 - static int DeleteAFile(HWND hwnd, _tstring file); - //删除多个文件 - static int DeleteFiles(HWND hwnd, const vector<_tstring>& files); - - //复制一个文件 - static int CopyAFile(HWND hwnd, _tstring file_from, _tstring file_to); - //复制多个文件 - static int CopyFiles(HWND hwnd, const vector<_tstring>& files, _tstring file_to); - - //移动一个文件 - //file_from:要移动的文件的路径 - //file_to:移动目标的目录的位置 - static int MoveAFile(HWND hwnd, _tstring file_from, _tstring file_to); - - //移动多个文件 - static int MoveFiles(HWND hwnd, const vector<_tstring>& files, _tstring file_to); - static bool CreateDir(const _tstring& path); //文件/文件夹重命名 @@ -260,7 +235,7 @@ class CCommon //从剪贴板获取字符串 static wstring GetStringFromClipboard(); - //写入日志 + // 写入日志(对同一日志文件并发写入会丢失,请确保参数path指定的文件同一时刻只有一个线程能够写入) static void WriteLog(const wchar_t* path, const wstring& content); // 将通过命令行参数传递过来的多个文件路径拆分,并保存到file容器里 @@ -310,10 +285,6 @@ class CCommon template static bool IsItemInVector(const vector& items, Func func); - // 累加vector内元素 - template - static T SumVector(vector& vec); - //判断文件名是末尾是否符合“(数字)”的形式 //file_name: 要判断的文件名,不包含扩展名 //number: 接收括号中的数字 @@ -332,7 +303,7 @@ class CCommon //将hSrc中的所有菜单项添加到菜单hDst中(来自 https://blog.csdn.net/zgl7903/article/details/71077441) static int AppendMenuOp(HMENU hDst, HMENU hSrc); - //判断一个菜单项是否在菜单中(不检查子菜单) + //判断一个菜单项是否在菜单中(检查子菜单) static bool IsMenuItemInMenu(CMenu* pMenu, UINT id); //获取一个菜单项的序号 @@ -345,24 +316,17 @@ class CCommon */ static void IterateMenuItem(CMenu* pMenu, std::function func); - //从资源文件载入字符串。其中,front_str、back_str为载入字符串时需要在前面或后面添加的字符串 - static CString LoadText(UINT id, LPCTSTR back_str = nullptr); - static CString LoadText(LPCTSTR front_str, UINT id, LPCTSTR back_str = nullptr); - - //安全的格式化字符串,将format_str中形如<%序号%>的字符串替换成初始化列表paras中的元素,元素支持int/double/LPCTSTR/CString格式,序号从1开始 - static CString StringFormat(LPCTSTR format_str, const std::initializer_list& paras); - //判断str的左侧是否匹配matched_str static bool StringLeftMatch(const std::wstring& str, const std::wstring& matched_str); - //从资源文件中载入字符串,并将资源字符串中形如<%序号%>的字符串替换成可变参数列表中的参数 - static CString LoadTextFormat(UINT id, const std::initializer_list& paras); + // 获取当前线程首选 UI 语言列表 + static bool GetThreadLanguageList(vector& language_tag); - //将字符串形如“%(数字)”格式的字符替换成字符串资源中对应id的字符串 - static void ReplaceUiStringRes(std::wstring& str); + // 设置当前线程的线程首选 UI 语言 + static bool SetThreadLanguageList(const vector& language_tag); - //设置线程语言 - static void SetThreadLanguage(Language language); + // 获取当前系统的默认UI字体 + static wstring GetSystemDefaultUIFont(); //安全的字符串复制函数 static void WStringCopy(wchar_t* str_dest, int dest_size, const wchar_t* str_source, int source_size = INT_MAX); @@ -450,7 +414,7 @@ class CCommon static std::string GetTextResourceRawData(UINT id); //从资源加载自定义文本资源。id:资源的ID,code_type:文本的编码格式 - static CString GetTextResource(UINT id, CodeType code_type); + static wstring GetTextResource(UINT id, CodeType code_type); //从资源加载png图片资源 //https://www.cnblogs.com/a-live/p/3222567.html @@ -467,7 +431,7 @@ class CCommon static POINT CalculateWindowMoveOffset(CRect& check_rect, vector& screen_rects); //从资源文件读取上次编译时间 - static CString GetLastCompileTime(); + static wstring GetLastCompileTime(); static unsigned __int64 GetCurTimeElapse(); @@ -610,17 +574,6 @@ inline bool CCommon::IsItemInVector(const vector& items, Func func) return false; } -template -inline T CCommon::SumVector(vector& vec) -{ - T sum{}; - for (size_t i{}; i < vec.size(); ++i) - { - sum += vec[i]; - } - return sum; -} - template inline bool CCommon::IsItemInVector(const vector& items, const T& item) { diff --git a/MusicPlayer2/CommonData.h b/MusicPlayer2/CommonData.h index 5e0031755..93ed97d76 100644 --- a/MusicPlayer2/CommonData.h +++ b/MusicPlayer2/CommonData.h @@ -1,9 +1,7 @@ #pragma once -#include "stdafx.h" #include "ColorConvert.h" #include "DrawCommon.h" #include "Common.h" -#include "resource.h" namespace CONSTVAL { @@ -127,19 +125,21 @@ struct FontSet UIFont font11; UIFont font12; //界面4的歌曲标题 + UIFont dlg; // 窗口控件字体 UIFont lyric; //歌词字体 UIFont lyric_translate; //歌词翻译的字体 UIFont cortana; //搜索框字体 UIFont cortana_translate; //搜索框翻译字体 - void Init() + void Init(LPCTSTR font_name) { - font9.SetFont(9, CCommon::LoadText(IDS_DEFAULT_FONT)); - font8.SetFont(8, CCommon::LoadText(IDS_DEFAULT_FONT)); - font10.SetFont(10, CCommon::LoadText(IDS_DEFAULT_FONT)); - font11.SetFont(11, CCommon::LoadText(IDS_DEFAULT_FONT)); - font12.SetFont(12, CCommon::LoadText(IDS_DEFAULT_FONT)); + font9.SetFont(9, font_name); + font8.SetFont(8, font_name); + font10.SetFont(10, font_name); + font11.SetFont(11, font_name); + font12.SetFont(12, font_name); + dlg.SetFont(9, font_name); } }; @@ -297,7 +297,7 @@ struct GeneralSettingData bool midi_use_inner_lyric{ false }; //播放MIDI音乐时显示内嵌歌词 bool minimize_to_notify_icon{ false }; //是否最小到通知区图标 - Language language; + wstring language_; // 这个是设置状态(空字符串为跟随系统) bool portable_mode{ false }; //如果为true,则程序所有数据都保存到exe所在目录下,否则保存到Appdata\Romaing目录下 }; @@ -367,6 +367,7 @@ struct MediaLibSettingData bool insert_begin_of_playlist{ false }; // 向播放列表添加歌曲时插入开头而不是追加到末尾 bool show_playlist_tooltip{}; //显示播放列表工具提示 bool float_playlist_follow_main_wnd{}; //浮动播放列表跟随主窗口 + bool playlist_btn_for_float_playlist{ false }; // 指定主界面中进度条右侧的“显示/隐藏播放列表”按钮的功能是否为显示浮动播放列表 int playlist_item_height{ 24 }; RecentPlayedRange recent_played_range{}; //最近播放曲目列表的显示范围 int display_item{}; //媒体库显示的项目 @@ -394,7 +395,6 @@ struct NonCategorizedSettingData bool float_playlist{ false }; //浮动播放列表(不应该用此变量来判断浮动播放列表是否存在) CSize playlist_size{ 320, 530 }; //浮动播放列表的大小 - bool playlist_btn_for_float_playlist{ false }; //指定主界面中进度条右侧的“显示/隐藏播放列表”按钮的功能是否为显示浮动播放列表 int max_album_cover_size{ 800 }; bool show_debug_info{ false }; @@ -415,175 +415,6 @@ struct NonCategorizedSettingData int debug_log{ 0 }; //是否写入日志信息 }; -struct IconRes -{ -private: - HICON hIcon{}; - HICON hIconDark{}; - HICON hIconLarge{}; - HICON hIconDarkLarge{}; - CSize iconSize{}; - CSize iconSizeLarge{}; - -public: - const HICON& GetIcon(bool dark = false, bool large = false) const - { - if (large) - return (dark && hIconDarkLarge != NULL ? hIconDarkLarge : hIconLarge); - else - return (dark && hIconDark != NULL ? hIconDark : hIcon); - } - - void Load(UINT id, UINT id_dark, int size) - { - int size_large = static_cast(size * CONSTVAL::FULL_SCREEN_ZOOM_FACTOR); - - if (size < 32) - size = CCommon::IconSizeNormalize(size); - if (size_large < 32) - size_large = CCommon::IconSizeNormalize(size_large); - - if (id != 0) - { - hIcon = CDrawCommon::LoadIconResource(id, size, size); - hIconLarge = CDrawCommon::LoadIconResource(id, size_large, size_large); - } - if (id_dark != 0) - { - hIconDark = CDrawCommon::LoadIconResource(id_dark, size, size); - hIconDarkLarge = CDrawCommon::LoadIconResource(id_dark, size_large, size_large); - } - iconSize.cx = iconSize.cy = size; - iconSizeLarge.cx = iconSizeLarge.cy = size_large; - } - - const CSize& GetSize(bool large = false) const - { - return (large ? iconSizeLarge : iconSize); - } -}; - -struct IconSet -{ - //界面图标 - IconRes app; - HICON default_cover; - HICON default_cover_small; - HICON default_cover_not_played; - HICON default_cover_small_not_played; - IconRes default_cover_toolbar; - IconRes default_cover_toolbar_not_played; - IconRes skin; - IconRes eq; - IconRes setting; - IconRes mini; - IconRes play_oder; - IconRes play_shuffle; - IconRes play_random; - IconRes loop_playlist; - IconRes loop_track; - IconRes play_track; - IconRes previous; - IconRes play; - IconRes pause; - IconRes next; - IconRes stop; - IconRes info; - IconRes select_folder; - IconRes media_lib; - IconRes show_playlist; - IconRes find_songs; - IconRes full_screen; - IconRes full_screen1; - IconRes menu; - IconRes favourite; - IconRes heart; - IconRes double_line; - IconRes lock; - IconRes close; - IconRes edit; - IconRes add; - IconRes artist; - IconRes album; - IconRes genre; - IconRes year; - IconRes folder_explore; - IconRes lyric_forward; - IconRes lyric_delay; - IconRes recent_songs; - IconRes volume1; - IconRes volume2; - IconRes volume3; - IconRes volume0; - - IconRes stop_l; - IconRes previous_l; - IconRes play_l; - IconRes pause_l; - IconRes next_l; - - IconRes play_new; - IconRes pause_new; - IconRes previous_new; - IconRes next_new; - - IconRes app_close; - IconRes maximize; - IconRes minimize; - IconRes restore; - IconRes sort; - IconRes display_mode; - IconRes link; - IconRes unlink; - IconRes switch_display; - IconRes lyric; - IconRes playlist_dock; - IconRes help; - IconRes dark_mode; - IconRes mini_restore; - - //菜单图标(仅16x16) - HICON stop_new; - HICON save_new; - HICON save_as; - HICON music; - HICON file_relate; - HICON online; - HICON play_pause; - HICON convert; - HICON download; - HICON download1; - HICON ff_new; - HICON rew_new; - HICON playlist_float; - HICON statistics; - HICON pin; - HICON exit; - HICON album_cover; - HICON rename; - HICON tag; - HICON star; - HICON internal_lyric; - HICON speed_up; - HICON slow_down; - HICON shortcut; - HICON play_as_next; - HICON play_in_playlist; - HICON copy; - HICON play_in_folder; - HICON bitrate; - HICON reverb; - HICON hot_key; - HICON fix; - - HICON ok; - IconRes locate; - IconRes expand; - - //通知区图标 - HICON notify_icons[MAX_NOTIFY_ICON]; -}; - //界面相关的一些选项 struct UIData @@ -603,38 +434,17 @@ struct UIData }; -struct MenuSet -{ - CMenu m_main_menu; //菜单栏上的菜单 - CMenu m_list_popup_menu; //播放列表右键菜单 - CMenu m_main_menu_popup; //按住Shift键时弹出的右键菜单 - CMenu m_popup_menu; //歌词右键菜单 - CMenu m_main_popup_menu; - CMenu m_playlist_btn_menu; //播放列表按钮上的右键菜单 - CMenu m_playlist_toolbar_menu; //播放列表工具栏菜单 - CMenu m_playlist_toolbar_popup_menu; //播放列表工具栏弹出菜单 - CMenu m_lyric_default_style; //桌面歌词预设方案菜单 - CMenu m_media_lib_popup_menu; - CMenu m_media_lib_folder_menu; //媒体库-文件夹的右键菜单 - CMenu m_media_lib_playlist_menu; //媒体库-播放列表的右键菜单 - CMenu m_notify_menu; //通知区图标右键菜单 - CMenu m_mini_mode_menu; //迷你模式右键菜单 - CMenu m_property_cover_menu; //属性——专辑封面中的右键菜单 - CMenu m_property_menu; - CMenu m_recent_folder_playlist_menu; -}; - struct ImageSet { - Gdiplus::Image* default_cover{}; - Gdiplus::Image* default_cover_not_played{}; - string default_cover_data; - string default_cover_not_played_data; + Gdiplus::Image* default_cover_img{}; + Gdiplus::Image* default_cover_not_played_img{}; + string default_cover_img_data; + string default_cover_not_played_img_data; ~ImageSet() { - SAFE_DELETE(default_cover); - SAFE_DELETE(default_cover_not_played); + SAFE_DELETE(default_cover_img); + SAFE_DELETE(default_cover_not_played_img); } }; @@ -661,6 +471,7 @@ class CFlagLocker struct MediaUpdateThreadPara { int num_added{}; //更新媒体库时新增(包括更新)的音频文件数量 - int total_num{}; + int process_percent{}; // 更新媒体库进度% bool thread_exit{}; //如果为true,则线程应该退出 + bool force; // 为true时无视修改时间强制刷新 }; diff --git a/MusicPlayer2/CommonDialogMgr.cpp b/MusicPlayer2/CommonDialogMgr.cpp new file mode 100644 index 000000000..bf4b1b607 --- /dev/null +++ b/MusicPlayer2/CommonDialogMgr.cpp @@ -0,0 +1,90 @@ +#include "stdafx.h" +#include "CommonDialogMgr.h" +#include "MusicPlayer2.h" + +CommonDialogMgr::CommonDialogMgr() +{ +} + +CommonDialogMgr::~CommonDialogMgr() +{ +} + +int CommonDialogMgr::DeleteAFile(HWND hwnd, wstring file) +{ + file.push_back(L'\0'); // pFrom必须以两个\0结尾 + static wstring title_delete = theApp.m_str_table.LoadText(L"TITLE_FILE_DELETE"); + SHFILEOPSTRUCT FileOp{}; // 定义SHFILEOPSTRUCT结构对象 + FileOp.hwnd = hwnd; + FileOp.wFunc = FO_DELETE; // 执行文件删除操作; + FileOp.pFrom = file.c_str(); + FileOp.fFlags = FOF_ALLOWUNDO; // 此标志使删除文件备份到Windows回收站 + FileOp.hNameMappings = NULL; + FileOp.lpszProgressTitle = title_delete.c_str(); + return SHFileOperation(&FileOp); // 删除文件 +} + +int CommonDialogMgr::DeleteFiles(HWND hwnd, const vector& files) +{ + wstring file_list; + for (const auto& file : files) + { + file_list += file; + file_list.push_back(L'\0'); + } + return DeleteAFile(hwnd, file_list); +} + +int CommonDialogMgr::CopyAFile(HWND hwnd, wstring file_from, wstring file_to) +{ + file_from.push_back(L'\0'); // pFrom必须以两个\0结尾 + file_to.push_back(L'\0'); // pTo必须以两个\0结尾 + static wstring title_copy = theApp.m_str_table.LoadText(L"TITLE_FILE_COPY"); + SHFILEOPSTRUCT FileOp{}; + FileOp.hwnd = hwnd; + FileOp.wFunc = FO_COPY; + FileOp.pFrom = file_from.c_str(); + FileOp.pTo = file_to.c_str(); + FileOp.fFlags = FOF_ALLOWUNDO; + FileOp.hNameMappings = NULL; + FileOp.lpszProgressTitle = title_copy.c_str(); + return SHFileOperation(&FileOp); +} + +int CommonDialogMgr::CopyFiles(HWND hwnd, const vector& files, wstring file_to) +{ + wstring file_list; + for (const auto& file : files) + { + file_list += file; + file_list.push_back(L'\0'); + } + return CopyAFile(hwnd, file_list, file_to); +} + +int CommonDialogMgr::MoveAFile(HWND hwnd, wstring file_from, wstring file_to) +{ + file_from.push_back(L'\0'); // pFrom必须以两个\0结尾 + file_to.push_back(L'\0'); // pTo必须以两个\0结尾 + static wstring title_move = theApp.m_str_table.LoadText(L"TITLE_FILE_MOVE"); + SHFILEOPSTRUCT FileOp{}; + FileOp.hwnd = hwnd; + FileOp.wFunc = FO_MOVE; + FileOp.pFrom = file_from.c_str(); + FileOp.pTo = file_to.c_str(); + FileOp.fFlags = FOF_ALLOWUNDO; + FileOp.hNameMappings = NULL; + FileOp.lpszProgressTitle = title_move.c_str(); + return SHFileOperation(&FileOp); +} + +int CommonDialogMgr::MoveFiles(HWND hwnd, const vector& files, wstring file_to) +{ + wstring file_list; + for (const auto& file : files) + { + file_list += file; + file_list.push_back(L'\0'); + } + return MoveAFile(hwnd, file_list, file_to); +} diff --git a/MusicPlayer2/CommonDialogMgr.h b/MusicPlayer2/CommonDialogMgr.h new file mode 100644 index 000000000..fc4c7ec60 --- /dev/null +++ b/MusicPlayer2/CommonDialogMgr.h @@ -0,0 +1,27 @@ +#pragma once +class CommonDialogMgr +{ +public: + CommonDialogMgr(); + ~CommonDialogMgr(); + + // 删除一个文件 + static int DeleteAFile(HWND hwnd, wstring file); + // 删除多个文件 + static int DeleteFiles(HWND hwnd, const vector& files); + + // 复制一个文件 + static int CopyAFile(HWND hwnd, wstring file_from, wstring file_to); + // 复制多个文件 + static int CopyFiles(HWND hwnd, const vector& files, wstring file_to); + + // 移动一个文件 + // file_from:要移动的文件的路径 + // file_to:移动目标的目录的位置 + static int MoveAFile(HWND hwnd, wstring file_from, wstring file_to); + // 移动多个文件 + static int MoveFiles(HWND hwnd, const vector& files, wstring file_to); + + // TODO: MessageBox +}; + diff --git a/MusicPlayer2/CortanaLyric.cpp b/MusicPlayer2/CortanaLyric.cpp index 0e3961be5..7a53ba166 100644 --- a/MusicPlayer2/CortanaLyric.cpp +++ b/MusicPlayer2/CortanaLyric.cpp @@ -1,10 +1,10 @@ -m_cortana_hwnd = m_hCortanaBar; -m_hCortanaStatic = m_hCortanaBar; -#include "stdafx.h" +#include "stdafx.h" #include "CortanaLyric.h" #include "SongInfoHelper.h" #include "CPlayerUIBase.h" #include "CPlayerUIHelper.h" +#include "Player.h" +#include "WinVersionHelper.h" CCriticalSection CCortanaLyric::m_critical; @@ -92,7 +92,7 @@ void CCortanaLyric::Init() m_cover_width = min_conver_width; m_pDC = m_cortana_wnd->GetDC(); - m_draw.Create(m_pDC, m_cortana_wnd); + m_draw.Create(m_pDC, m_cortana_wnd->GetFont()); //获取用来检查小娜是否为深色模式的采样点的坐标 @@ -144,12 +144,16 @@ void CCortanaLyric::DrawInfo() CSingleLock sync(&m_critical, TRUE); bool is_midi_lyric = CPlayerUIHelper::IsMidiLyric(); + static wstring str_now_playing{ theApp.m_str_table.LoadText(L"UI_TXT_PLAYSTATUS_PLAYING") + L": " }; + //不使用兼容模式显示歌词,直接在小娜搜索框内绘图 if(!theApp.m_lyric_setting_data.cortana_lyric_compatible_mode || CWinVersionHelper::IsWindows11OrLater()) //Windows11无法使用兼容模式显示歌词 { if (m_pDC != nullptr) { m_draw.SetFont(&theApp.m_font_set.cortana.GetFont()); + // 设置m_draw的歌词字体,DrawLyricTextMultiLine / DrawLyricTextSingleLine依赖此状态 + m_draw.SetLyricFont(&theApp.m_font_set.cortana.GetFont(), &theApp.m_font_set.cortana_translate.GetFont()); //双缓冲绘图 CDrawDoubleBuffer drawDoubleBuffer(m_pDC, m_cortana_rect); //使用m_draw绘图 @@ -185,19 +189,17 @@ void CCortanaLyric::DrawInfo() } else //没有歌词时在Cortana搜索框上以滚动的方式显示当前播放歌曲的文件名 { - static int index{}; - static wstring song_name{}; + static SongInfo last_song_info; + const SongInfo& song_info = CPlayer::GetInstance().GetCurrentSongInfo(); //如果当前播放的歌曲发生变化,DrawCortanaText函数的第2参数为true,即重置滚动位置 - static CString str_now_playing{ CCommon::LoadText(IDS_NOW_PLAYING, _T(": ")) }; - if (index != CPlayer::GetInstance().GetIndex() || song_name != CPlayer::GetInstance().GetFileName()) + if (!song_info.IsSameSong(last_song_info)) { - DrawCortanaText((str_now_playing + CSongInfoHelper::GetDisplayStr(CPlayer::GetInstance().GetCurrentSongInfo(), theApp.m_media_lib_setting_data.display_format).c_str()), true, CPlayerUIHelper::GetScrollTextPixel()); - index = CPlayer::GetInstance().GetIndex(); - song_name = CPlayer::GetInstance().GetFileName(); + DrawCortanaText((str_now_playing + CSongInfoHelper::GetDisplayStr(song_info, theApp.m_media_lib_setting_data.display_format)).c_str(), true, CPlayerUIHelper::GetScrollTextPixel()); + last_song_info = song_info; } else { - DrawCortanaText((str_now_playing + CSongInfoHelper::GetDisplayStr(CPlayer::GetInstance().GetCurrentSongInfo(), theApp.m_media_lib_setting_data.display_format).c_str()), false, CPlayerUIHelper::GetScrollTextPixel()); + DrawCortanaText((str_now_playing + CSongInfoHelper::GetDisplayStr(song_info, theApp.m_media_lib_setting_data.display_format)).c_str(), false, CPlayerUIHelper::GetScrollTextPixel()); } } } @@ -239,15 +241,16 @@ void CCortanaLyric::DrawInfo() } else if (!CPlayer::GetInstance().m_Lyrics.IsEmpty()) //有歌词时显示歌词 { + static const wstring& empty_lyric = theApp.m_str_table.LoadText(L"UI_LYRIC_EMPTY_LINE"); Time time{ CPlayer::GetInstance().GetCurrentPosition() }; str_disp = CPlayer::GetInstance().m_Lyrics.GetLyric(time, false, false, false).text; if (str_disp.empty()) - str_disp = CCommon::LoadText(IDS_DEFAULT_LYRIC_TEXT); + str_disp = empty_lyric; } else { //没有歌词时显示当前播放歌曲的名称 - str_disp = CCommon::LoadText(IDS_NOW_PLAYING, _T(": ")).GetString() + CSongInfoHelper::GetDisplayStr(CPlayer::GetInstance().GetCurrentSongInfo(), theApp.m_media_lib_setting_data.display_format); + str_disp = str_now_playing + CSongInfoHelper::GetDisplayStr(CPlayer::GetInstance().GetCurrentSongInfo(), theApp.m_media_lib_setting_data.display_format); } if(str_disp != str_disp_last) @@ -326,8 +329,13 @@ void CCortanaLyric::DrawAlbumCover(const CImage & album_cover) rc_icon.right = rc_icon.bottom = icon_side; rc_icon.MoveToX(cover_rect.left + (cover_rect.Width() - icon_side) / 2); rc_icon.MoveToY(cover_rect.top + (cover_rect.Height() - icon_side) / 2); - HICON icon{ CPlayer::GetInstance().IsPlaying() ? theApp.m_icon_set.default_cover_small : theApp.m_icon_set.default_cover_small_not_played }; - m_draw.DrawIcon(icon, rc_icon.TopLeft(), rc_icon.Size()); + + IconMgr::IconType icon_type = IconMgr::IconType::IT_Default_Cover_Stopped; + if (CPlayer::GetInstance().IsPlaying()) + icon_type = IconMgr::IconType::IT_Default_Cover_Playing; + HICON hIcon = theApp.m_icon_mgr.GetHICON(icon_type, IconMgr::IconStyle::IS_Color, IconMgr::IconSize::IS_DPI_32); + + m_draw.DrawIcon(hIcon, rc_icon.TopLeft(), rc_icon.Size()); } else { diff --git a/MusicPlayer2/CoverDownloadDlg.cpp b/MusicPlayer2/CoverDownloadDlg.cpp index dc206a8a1..fd579bb17 100644 --- a/MusicPlayer2/CoverDownloadDlg.cpp +++ b/MusicPlayer2/CoverDownloadDlg.cpp @@ -3,9 +3,10 @@ #include "stdafx.h" #include "MusicPlayer2.h" +#include "Player.h" #include "CoverDownloadDlg.h" -#include "afxdialogex.h" #include "SongDataManager.h" +#include "IniHelper.h" // CCoverDownloadDlg 对话框 @@ -24,12 +25,14 @@ CCoverDownloadDlg::~CCoverDownloadDlg() UINT CCoverDownloadDlg::SongSearchThreadFunc(LPVOID lpParam) { - CCommon::SetThreadLanguage(theApp.m_general_setting_data.language); + CCommon::SetThreadLanguageList(theApp.m_str_table.GetLanguageTag()); CCoverDownloadDlg* pThis = (CCoverDownloadDlg*)lpParam; wstring search_result; - pThis->m_search_rtn = CInternetCommon::HttpPost(pThis->m_search_url, search_result); //向网易云音乐的歌曲搜索API发送http的POST请求 + wstring m_search_url = pThis->m_search_url; + bool m_search_rtn = CInternetCommon::HttpPost(m_search_url, search_result); //向网易云音乐的歌曲搜索API发送http的POST请求 if (theApp.m_cover_download_dialog_exit) return 0; + pThis->m_search_rtn = m_search_rtn; pThis->m_search_result = search_result; ::PostMessage(pThis->m_hWnd, WM_SEARCH_COMPLATE, 0, 0); //搜索完成后发送一个搜索完成的消息 return 0; @@ -37,7 +40,7 @@ UINT CCoverDownloadDlg::SongSearchThreadFunc(LPVOID lpParam) UINT CCoverDownloadDlg::CoverDownloadThreadFunc(LPVOID lpParam) { - CCommon::SetThreadLanguage(theApp.m_general_setting_data.language); + CCommon::SetThreadLanguageList(theApp.m_str_table.GetLanguageTag()); CCoverDownloadDlg* pThis = (CCoverDownloadDlg*)lpParam; CInternetCommon::ItemInfo match_item = pThis->m_down_list[pThis->m_item_selected]; wstring song_id = match_item.id; @@ -46,7 +49,8 @@ UINT CCoverDownloadDlg::CoverDownloadThreadFunc(LPVOID lpParam) wstring cover_url = CCoverDownloadCommon::GetAlbumCoverURL(song_id); if (cover_url.empty()) { - AfxMessageBox(CCommon::LoadText(IDS_ALBUM_COVER_DOWNLOAD_FAILED_WARNING), MB_ICONWARNING | MB_OK); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_NETWORK_COVER_DOWNLOAD_FAILED"); + AfxMessageBox(info.c_str(), MB_ICONWARNING | MB_OK); } //获取要保存的专辑封面的文件路径 @@ -114,6 +118,57 @@ CString CCoverDownloadDlg::GetDialogName() const return _T("CoverDownloadDlg"); } +bool CCoverDownloadDlg::InitializeControls() +{ + SetIcon(IconMgr::IconType::IT_Album_Cover, FALSE); + wstring temp; + temp = theApp.m_str_table.LoadText(L"TITLE_COVER_DL"); + SetWindowTextW(temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_TITLE"); + SetDlgItemTextW(IDC_TXT_COVER_DL_TITLE_STATIC, temp.c_str()); + // IDC_TITLE_EDIT + temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_SEARCH"); + SetDlgItemTextW(IDC_SEARCH_BUTTON, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_ARTIST"); + SetDlgItemTextW(IDC_TXT_COVER_DL_ARTIST_STATIC, temp.c_str()); + // IDC_ARTIST_EDIT + temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_INFO"); + SetDlgItemTextW(IDC_STATIC_INFO, temp.c_str()); + temp = L"" + theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_UNLINK") + L""; + SetDlgItemTextW(IDC_UNASSOCIATE_LINK, temp.c_str()); + // IDC_COVER_DOWN_LIST + temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_OPT"); + SetDlgItemTextW(IDC_DOWNLOAD_OPTION_GROUPBOX, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_COVER_DL_LOCATION_SEL"); + SetDlgItemTextW(IDC_COVER_LOCATION_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_COVER_DL_LOCATION_FOLDER_SONG"); + SetDlgItemTextW(IDC_SAVE_TO_SONG_FOLDER2, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_COVER_DL_LOCATION_FOLDER_COVER"); + SetDlgItemTextW(IDC_SAVE_TO_ALBUM_FOLDER2, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_SEL_DL"); + SetDlgItemTextW(IDC_DOWNLOAD_SELECTED, temp.c_str()); + + SetButtonIcon(IDC_SEARCH_BUTTON, IconMgr::IconType::IT_Find); + SetButtonIcon(IDC_DOWNLOAD_SELECTED, IconMgr::IconType::IT_Download); + + RepositionTextBasedControls({ + { CtrlTextInfo::L1, IDC_TXT_COVER_DL_TITLE_STATIC }, + { CtrlTextInfo::C0, IDC_TITLE_EDIT }, + { CtrlTextInfo::R1, IDC_SEARCH_BUTTON, CtrlTextInfo::W32 }, + { CtrlTextInfo::L1, IDC_TXT_COVER_DL_ARTIST_STATIC }, + { CtrlTextInfo::C0, IDC_ARTIST_EDIT } + }, CtrlTextInfo::W64); + RepositionTextBasedControls({ + { CtrlTextInfo::C0, IDC_STATIC_INFO }, + { CtrlTextInfo::R1, IDC_UNASSOCIATE_LINK } + }, CtrlTextInfo::W128); + RepositionTextBasedControls({ + { CtrlTextInfo::R1, IDC_DOWNLOAD_SELECTED, CtrlTextInfo::W32 }, + { CtrlTextInfo::R2, IDCANCEL, CtrlTextInfo::W32 } + }); + return true; +} + void CCoverDownloadDlg::DoDataExchange(CDataExchange* pDX) { CBaseDialog::DoDataExchange(pDX); @@ -163,10 +218,6 @@ BOOL CCoverDownloadDlg::OnInitDialog() // TODO: 在此添加额外的初始化 LoadConfig(); - SetIcon(theApp.m_icon_set.album_cover, FALSE); - SetButtonIcon(IDC_SEARCH_BUTTON, theApp.m_icon_set.find_songs.GetIcon(true)); - SetButtonIcon(IDC_DOWNLOAD_SELECTED, theApp.m_icon_set.download); - m_song = GetSongInfo(); // 初始化复制Songinfo使用,防止随着播放GetSongInfo获取到另一首 m_org_album_cover_path = CPlayer::GetInstance().GetAlbumCoverPath(); @@ -206,10 +257,10 @@ BOOL CCoverDownloadDlg::OnInitDialog() width3 = rect.Width() - theApp.DPI(20) - 1 - width0 - width1 - width2; m_down_list_ctrl.SetExtendedStyle(m_down_list_ctrl.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_LABELTIP); - m_down_list_ctrl.InsertColumn(0, CCommon::LoadText(IDS_NUMBER), LVCFMT_LEFT, width0); //插入第1列 - m_down_list_ctrl.InsertColumn(1, CCommon::LoadText(IDS_TITLE), LVCFMT_LEFT, width1); //插入第2列 - m_down_list_ctrl.InsertColumn(2, CCommon::LoadText(IDS_ARTIST), LVCFMT_LEFT, width2); //插入第3列 - m_down_list_ctrl.InsertColumn(3, CCommon::LoadText(IDS_ALBUM), LVCFMT_LEFT, width3); //插入第3列 + m_down_list_ctrl.InsertColumn(0, theApp.m_str_table.LoadText(L"TXT_SERIAL_NUMBER").c_str(), LVCFMT_LEFT, width0); + m_down_list_ctrl.InsertColumn(1, theApp.m_str_table.LoadText(L"TXT_TITLE").c_str(), LVCFMT_LEFT, width1); + m_down_list_ctrl.InsertColumn(2, theApp.m_str_table.LoadText(L"TXT_ARTIST").c_str(), LVCFMT_LEFT, width2); + m_down_list_ctrl.InsertColumn(3, theApp.m_str_table.LoadText(L"TXT_ALBUM").c_str(), LVCFMT_LEFT, width3); m_unassciate_lnk.ShowWindow(SW_HIDE); @@ -236,7 +287,7 @@ BOOL CCoverDownloadDlg::OnInitDialog() void CCoverDownloadDlg::OnBnClickedSearchButton() { // TODO: 在此添加控件通知处理程序代码 - SetDlgItemText(IDC_STATIC_INFO, CCommon::LoadText(IDS_SEARCHING)); + SetDlgItemText(IDC_STATIC_INFO, theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_INFO_SEARCHING").c_str()); // 这里使用的是歌词下载对话框的字符串 GetDlgItem(IDC_SEARCH_BUTTON)->EnableWindow(FALSE); //点击“搜索”后禁用该按钮 wstring keyword = CInternetCommon::URLEncode(m_artist + L' ' + m_title); //搜索关键字为“艺术家 标题”,并将其转换成URL编码 CString url; @@ -254,8 +305,18 @@ afx_msg LRESULT CCoverDownloadDlg::OnSearchComplate(WPARAM wParam, LPARAM lParam GetDlgItem(IDC_SEARCH_BUTTON)->EnableWindow(TRUE); //搜索完成之后启用该按钮 switch (m_search_rtn) { - case 1: MessageBox(CCommon::LoadText(IDS_SEARCH_FAILED_INFO), NULL, MB_ICONWARNING); return 0; - case 2: MessageBox(CCommon::LoadText(IDS_SEARCH_TIME_OUT), NULL, MB_ICONWARNING); return 0; + case CInternetCommon::FAILURE: + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_NETWORK_SEARCH_FAILED"); + MessageBox(info.c_str(), NULL, MB_ICONWARNING); + return 0; + } + case CInternetCommon::OUTTIME: + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_NETWORK_SEARCH_TIME_OUT"); + MessageBox(info.c_str(), NULL, MB_ICONWARNING); + return 0; + } default: break; } @@ -265,7 +326,8 @@ afx_msg LRESULT CCoverDownloadDlg::OnSearchComplate(WPARAM wParam, LPARAM lParam //计算搜索结果中最佳匹配项目 int best_matched; bool id_releated{ false }; - if (!m_song.song_id == 0) // 如果当前歌曲已经有关联的ID,则根据该ID在搜索结果列表中查找对应的项目 + CSongDataManager::GetInstance().GetSongID(m_song, m_song.song_id); // 从媒体库读取id + if (m_song.song_id != 0) // 如果当前歌曲已经有关联的ID,则根据该ID在搜索结果列表中查找对应的项目 { for (size_t i{}; i < m_down_list.size(); i++) { @@ -279,20 +341,20 @@ afx_msg LRESULT CCoverDownloadDlg::OnSearchComplate(WPARAM wParam, LPARAM lParam } if (!id_releated) best_matched = CInternetCommon::SelectMatchedItem(m_down_list, m_title, m_artist, m_album, m_file_name, true); - CString info; + wstring info; m_unassciate_lnk.ShowWindow(SW_HIDE); if (m_down_list.empty()) - info = CCommon::LoadText(IDS_SEARCH_NO_SONG); + info = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_INFO_SEARCH_NO_SONG"); else if (best_matched == -1) - info = CCommon::LoadText(IDS_SEARCH_NO_MATCHED); + info = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_INFO_SEARCH_NO_MATCHED"); else if (id_releated) { - info = CCommon::LoadTextFormat(IDS_SEARCH_RELATED, { best_matched + 1 }); + info = theApp.m_str_table.LoadTextFormat(L"TXT_LYRIC_DL_INFO_SEARCH_RELATED", { best_matched + 1 }); m_unassciate_lnk.ShowWindow(SW_SHOW); } else - info = CCommon::LoadTextFormat(IDS_SEARCH_BEST_MATCHED, { best_matched + 1 }); - SetDlgItemText(IDC_STATIC_INFO, info); + info = theApp.m_str_table.LoadTextFormat(L"TXT_LYRIC_DL_INFO_SEARCH_BEST_MATCHED", { best_matched + 1 }); + SetDlgItemText(IDC_STATIC_INFO, info.c_str()); //自动选中列表中最佳匹配的项目 m_down_list_ctrl.SetFocus(); m_down_list_ctrl.SetItemState(best_matched, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); //选中行 @@ -387,7 +449,8 @@ afx_msg LRESULT CCoverDownloadDlg::OnDownloadComplate(WPARAM wParam, LPARAM lPar CPlayer::GetInstance().AlbumCoverGaussBlur(); } GetDlgItem(IDC_DOWNLOAD_SELECTED)->EnableWindow(TRUE); //下载完成后启用该按钮 - MessageBox(CCommon::LoadText(IDS_DOWNLOAD_COMPLETE), NULL, MB_ICONINFORMATION | MB_OK); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_NETWORK_DOWNLOAD_COMPLETE"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); return 0; } diff --git a/MusicPlayer2/CoverDownloadDlg.h b/MusicPlayer2/CoverDownloadDlg.h index 1bab7611c..2043b4e0e 100644 --- a/MusicPlayer2/CoverDownloadDlg.h +++ b/MusicPlayer2/CoverDownloadDlg.h @@ -60,6 +60,7 @@ class CCoverDownloadDlg : public CBaseDialog virtual SongInfo GetSongInfo() const; virtual CString GetDialogName() const override; + virtual bool InitializeControls() override; virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 void ShowDownloadList(); //将搜索结果显示出来 diff --git a/MusicPlayer2/CueFile.cpp b/MusicPlayer2/CueFile.cpp index f8d1db6fc..48ee0a363 100644 --- a/MusicPlayer2/CueFile.cpp +++ b/MusicPlayer2/CueFile.cpp @@ -25,21 +25,6 @@ CCueFile::~CCueFile() { } -void CCueFile::LoadContentsDirect(const std::wstring& cue_contets) -{ - m_file_content_wcs = cue_contets; - DoAnalysis(); -} - -// void CCueFile::SetTotalLength(Time length) -// { -// if (!m_result.empty()) -// { -// m_result.back().end_pos = length; -// m_result.back().lengh = Time(length - m_result.back().start_pos); -// } -// } - std::vector& CCueFile::GetAnalysisResult() { return m_result; @@ -191,7 +176,6 @@ void CCueFile::DoAnalysis() song_info_common.disc_num = static_cast(_wtoi(GetCommand(cue_head_contents, L"REM DISCNUMBER").c_str())); song_info_common.total_discs = static_cast(_wtoi(GetCommand(cue_head_contents, L"REM TOTALDISCS").c_str())); song_info_common.is_cue = true; - song_info_common.info_acquired = true; //查找所有属性 FindAllProperty(cue_head_contents, m_cue_property_map); diff --git a/MusicPlayer2/CueFile.h b/MusicPlayer2/CueFile.h index fd741555a..3284c828d 100644 --- a/MusicPlayer2/CueFile.h +++ b/MusicPlayer2/CueFile.h @@ -1,6 +1,4 @@ #pragma once -#include -#include "Time.h" #include "SongInfo.h" #include "Common.h" @@ -10,10 +8,8 @@ class CCueFile CCueFile(const std::wstring& file_path); CCueFile(); ~CCueFile(); - void LoadContentsDirect(const std::wstring& cue_contets); - // void SetTotalLength(Time length); //设置cue对应音频文件的总长度(需要在解析完成后调用GetAudioFileName获取解析到的音频文件路径,再获取该音频文件的长度) + std::vector& GetAnalysisResult(); - // std::wstring GetAudioFileName() const; //将所有cue音轨保存到cue文件 //如果file_path为空,则保存到m_file_path @@ -36,7 +32,6 @@ class CCueFile private: std::wstring m_file_path; - //std::string m_file_content; std::wstring m_file_content_wcs; CodeType m_code_type{ CodeType::AUTO }; std::vector m_result; diff --git a/MusicPlayer2/DataSettingsDlg.cpp b/MusicPlayer2/DataSettingsDlg.cpp index 739a86781..8407d00dc 100644 --- a/MusicPlayer2/DataSettingsDlg.cpp +++ b/MusicPlayer2/DataSettingsDlg.cpp @@ -4,8 +4,8 @@ #include "stdafx.h" #include "MusicPlayer2.h" #include "DataSettingsDlg.h" -#include "afxdialogex.h" #include "UpdateHelper.h" +#include "FilterHelper.h" // CDataSettingsDlg 对话框 @@ -27,6 +27,69 @@ bool CDataSettingsDlg::IsAutoRunModified() const return m_auto_run_modified; } +bool CDataSettingsDlg::InitializeControls() +{ + wstring temp; + temp = theApp.m_str_table.LoadText(L"TXT_OPT_DATA_APP_SETTING"); + SetDlgItemTextW(IDC_TXT_OPT_DATA_APP_SETTING_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_DATA_UPDATE_AUTO_CHECK"); + SetDlgItemTextW(IDC_CHECK_UPDATE_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_DATA_UPDATE_SOURCE_SEL"); + SetDlgItemTextW(IDC_TXT_OPT_DATA_UPDATE_SOURCE_SEL_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_DATA_UPDATE_SOURCE_GITHUB"); + SetDlgItemTextW(IDC_GITHUB_RADIO, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_DATA_UPDATE_SOURCE_GITEE"); + SetDlgItemTextW(IDC_GITEE_RADIO, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_DATA_AUTO_RUN"); + SetDlgItemTextW(IDC_AUTO_RUN_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_DATA_LANGUAGE_SEL"); + SetDlgItemTextW(IDC_TXT_OPT_DATA_LANGUAGE_SEL_STATIC, temp.c_str()); + // IDC_COMBO1 + temp = theApp.m_str_table.LoadText(L"TXT_OPT_DATA_DATA_FILE_CFG"); + SetDlgItemTextW(IDC_TXT_OPT_DATA_DATA_FILE_CFG_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_DATA_DATA_FILE_SAVE_DIR_APPDATA"); + SetDlgItemTextW(IDC_SAVE_TO_APPDATA_RADIO, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_DATA_DATA_FILE_SAVE_DIR_PROGRAM"); + SetDlgItemTextW(IDC_SAVE_TO_PROGRAM_DIR_RADIO, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_DATA_DATA_FILE_DIR_OPEN"); + SetDlgItemTextW(IDC_OPEN_CONFIG_PATH_BUTTON, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_DATA_CLOSE_MAIN_WINDOW"); + SetDlgItemTextW(IDC_TXT_OPT_DATA_CLOSE_MAIN_WINDOW_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_DATA_CLOSE_MAIN_WINDOW_MINIMIZE_NOTIFY_AREA"); + SetDlgItemTextW(IDC_MINIMIZE_TO_NOTIFY_RADIO, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_DATA_CLOSE_MAIN_WINDOW_EXIT"); + SetDlgItemTextW(IDC_EXIT_PROGRAM_RADIO, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_DATA_AUTO_DL_SETTING"); + SetDlgItemTextW(IDC_TXT_OPT_DATA_AUTO_DL_SETTING_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_DATA_AUTO_DL_LYRIC"); + SetDlgItemTextW(IDC_LYRIC_AUTO_DOWNLOAD_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_DATA_AUTO_DL_LYRIC_SAVE_SEL"); + SetDlgItemTextW(IDC_TXT_OPT_DATA_AUTO_DL_LYRIC_SAVE_SEL_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_DATA_AUTO_DL_LYRIC_SAVE_SONG_DIR"); + SetDlgItemTextW(IDC_SAVE_TO_SONG_FOLDER, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_DATA_AUTO_DL_LYRIC_SAVE_LYRIC_DIR"); + SetDlgItemTextW(IDC_SAVE_TO_LYRIC_FOLDER, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_DATA_AUTO_DL_COVER"); + SetDlgItemTextW(IDC_COVER_AUTO_DOWNLOAD_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_DATA_AUTO_DL_COVER_SAVE_SEL"); + SetDlgItemTextW(IDC_TXT_OPT_DATA_AUTO_DL_COVER_SAVE_SEL_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_DATA_AUTO_DL_COVER_SAVE_SONG_DIR"); + SetDlgItemTextW(IDC_SAVE_TO_SONG_FOLDER3, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_DATA_AUTO_DL_COVER_SAVE_COVER_DIR"); + SetDlgItemTextW(IDC_SAVE_TO_ALBUM_FOLDER3, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_DATA_AUTO_DL_ONLY_WHEN_TAG_FULL"); + SetDlgItemTextW(IDC_DOWNLOAD_WHEN_TAG_FULL_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_DATA_MIDI_SETTING"); + SetDlgItemTextW(IDC_TXT_OPT_DATA_MIDI_SETTING_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_DATA_MIDI_INNER_LYRIC_FIRST"); + SetDlgItemTextW(IDC_MIDI_USE_INNER_LYRIC_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_DATA_MIDI_SF2_PATH"); + SetDlgItemTextW(IDC_TXT_OPT_DATA_MIDI_SF2_PATH_STATIC, temp.c_str()); + // IDC_SF2_PATH_EDIT + + return false; +} + void CDataSettingsDlg::DoDataExchange(CDataExchange* pDX) { CTabDlg::DoDataExchange(pDX); @@ -41,17 +104,28 @@ void CDataSettingsDlg::GetDataFromUi() m_data.save_album_to_song_folder = (((CButton*)GetDlgItem(IDC_SAVE_TO_SONG_FOLDER3))->GetCheck() != 0); //获取语言的设置 - m_data.language = static_cast(m_language_combo.GetCurSel()); - if (m_data.language != theApp.m_general_setting_data.language) + int sel_language = m_language_combo.GetCurSel(); + if (sel_language == 0) + m_data.language_.clear(); + else + { + sel_language -= 1; + const auto& language_list = theApp.m_str_table.GetLanguageList(); + if (sel_language >= 0 && sel_language < static_cast(language_list.size())) + m_data.language_ = language_list[sel_language].bcp_47; + } + if (m_data.language_ != theApp.m_general_setting_data.language_) { - MessageBox(CCommon::LoadText(IDS_LANGUAGE_CHANGE_INFO), NULL, MB_ICONINFORMATION | MB_OK); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_OPT_DATA_LANGUAGE_CHANGE_INFO"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); } //获取数据文件保存位置的设置 m_data.portable_mode = (IsDlgButtonChecked(IDC_SAVE_TO_PROGRAM_DIR_RADIO) != 0); if (m_data.portable_mode != theApp.m_general_setting_data.portable_mode) { - MessageBox(CCommon::LoadText(IDS_CFG_DIR_CHANGED_INFO), NULL, MB_ICONINFORMATION | MB_OK); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_OPT_DATA_CFG_DIR_CHANGED_INFO"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); } } @@ -62,11 +136,9 @@ void CDataSettingsDlg::ApplyDataToUi() BEGIN_MESSAGE_MAP(CDataSettingsDlg, CTabDlg) - //ON_BN_CLICKED(IDC_ID3V2_FIRST_CHECK, &CDataSettingsDlg::OnBnClickedId3v2FirstCheck) ON_BN_CLICKED(IDC_COVER_AUTO_DOWNLOAD_CHECK, &CDataSettingsDlg::OnBnClickedCoverAutoDownloadCheck) ON_BN_CLICKED(IDC_LYRIC_AUTO_DOWNLOAD_CHECK, &CDataSettingsDlg::OnBnClickedLyricAutoDownloadCheck) ON_BN_CLICKED(IDC_CHECK_UPDATE_CHECK, &CDataSettingsDlg::OnBnClickedCheckUpdateCheck) - //ON_BN_CLICKED(IDC_BROWSE_BUTTON, &CDataSettingsDlg::OnBnClickedBrowseButton) ON_BN_CLICKED(IDC_MIDI_USE_INNER_LYRIC_CHECK, &CDataSettingsDlg::OnBnClickedMidiUseInnerLyricCheck) ON_BN_CLICKED(IDC_DOWNLOAD_WHEN_TAG_FULL_CHECK, &CDataSettingsDlg::OnBnClickedDownloadWhenTagFullCheck) ON_EN_CHANGE(IDC_SF2_PATH_EDIT, &CDataSettingsDlg::OnEnChangeSf2PathEdit) @@ -86,12 +158,18 @@ BOOL CDataSettingsDlg::OnInitDialog() CTabDlg::OnInitDialog(); // TODO: 在此添加额外的初始化 - //SetBackgroundColor(RGB(255, 255, 255)); - m_language_combo.AddString(CCommon::LoadText(IDS_FOLLOWING_SYSTEM)); - m_language_combo.AddString(_T("English")); - m_language_combo.AddString(_T("简体中文")); - m_language_combo.SetCurSel(static_cast(m_data.language)); + m_language_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_DATA_LANGUAGE_FOLLOWING_SYSTEM").c_str()); + const auto& language_list = theApp.m_str_table.GetLanguageList(); + int language_sel{}; + for (size_t i{}; i < language_list.size(); ++i) + { + m_language_combo.AddString(language_list[i].display_name.c_str()); + if (language_list[i].bcp_47 == m_data.language_) + language_sel = i + 1; + } + ASSERT(language_sel != 0 || m_data.language_.empty()); // 仅当设置为“跟随系统(空)”时索引才可能为0 + m_language_combo.SetCurSel(language_sel); m_auto_run = theApp.GetAutoRun(); CheckDlgButton(IDC_AUTO_RUN_CHECK, m_auto_run); @@ -104,14 +182,13 @@ BOOL CDataSettingsDlg::OnInitDialog() CheckDlgButton(IDC_SAVE_TO_PROGRAM_DIR_RADIO, m_data.portable_mode); EnableDlgCtrl(IDC_SAVE_TO_PROGRAM_DIR_RADIO, theApp.m_module_dir_writable); - //((CButton*)GetDlgItem(IDC_ID3V2_FIRST_CHECK))->SetCheck(m_data.id3v2_first); ((CButton*)GetDlgItem(IDC_COVER_AUTO_DOWNLOAD_CHECK))->SetCheck(m_data.auto_download_album_cover); ((CButton*)GetDlgItem(IDC_LYRIC_AUTO_DOWNLOAD_CHECK))->SetCheck(m_data.auto_download_lyric); ((CButton*)GetDlgItem(IDC_DOWNLOAD_WHEN_TAG_FULL_CHECK))->SetCheck(m_data.auto_download_only_tag_full); ((CButton*)GetDlgItem(IDC_CHECK_UPDATE_CHECK))->SetCheck(m_data.check_update_when_start); m_sf2_path_edit.SetWindowText(m_data.sf2_path.c_str()); - CString szFilter = CCommon::LoadText(IDS_SOUND_FONT_FILTER); - m_sf2_path_edit.EnableFileBrowseButton(_T("SF2"), szFilter); + wstring sf2_filter = FilterHelper::GetSF2FileFilter(); + m_sf2_path_edit.EnableFileBrowseButton(L"SF2", sf2_filter.c_str()); ((CButton*)GetDlgItem(IDC_MIDI_USE_INNER_LYRIC_CHECK))->SetCheck(m_data.midi_use_inner_lyric); if (m_data.minimize_to_notify_icon) ((CButton*)GetDlgItem(IDC_MINIMIZE_TO_NOTIFY_RADIO))->SetCheck(TRUE); @@ -151,9 +228,9 @@ BOOL CDataSettingsDlg::OnInitDialog() m_toolTip.Create(this); m_toolTip.SetMaxTipWidth(theApp.DPI(300)); - m_toolTip.AddTool(GetDlgItem(IDC_DOWNLOAD_WHEN_TAG_FULL_CHECK), CCommon::LoadText(IDS_AUTO_DOWNLOAD_LYRIC_TIP_INFO)); + m_toolTip.AddTool(GetDlgItem(IDC_DOWNLOAD_WHEN_TAG_FULL_CHECK), theApp.m_str_table.LoadText(L"TIP_OPT_DATA_AUTO_DL_ONLY_WHEN_TAG_FULL").c_str()); //m_toolTip.AddTool(GetDlgItem(IDC_SF2_PATH_EDIT), _T("需要额外的音色库才能播放 MIDI 音乐。")); - m_toolTip.AddTool(GetDlgItem(IDC_MIDI_USE_INNER_LYRIC_CHECK), CCommon::LoadText(IDS_MIDI_INNER_LYRIC_TIP_INFO)); + m_toolTip.AddTool(GetDlgItem(IDC_MIDI_USE_INNER_LYRIC_CHECK), theApp.m_str_table.LoadText(L"TIP_OPT_DATA_MIDI_INNER_LYRIC_FIRSR").c_str()); m_toolTip.AddTool(GetDlgItem(IDC_SAVE_TO_APPDATA_RADIO), theApp.m_appdata_dir.c_str()); m_toolTip.AddTool(GetDlgItem(IDC_SAVE_TO_PROGRAM_DIR_RADIO), theApp.m_module_dir.c_str()); @@ -171,7 +248,8 @@ BOOL CDataSettingsDlg::OnInitDialog() void CDataSettingsDlg::EnableControl() { - bool enable = CPlayer::GetInstance().IsBassCore(); + // bool enable = CPlayer::GetInstance().IsBassCore(); + bool enable = !theApp.m_play_setting_data.use_ffmpeg && !theApp.m_play_setting_data.use_mci; m_sf2_path_edit.EnableWindow(enable && theApp.m_format_convert_dialog_exit); //正在进行格式转换时不允许更改音色库 CWnd* pWnd = GetDlgItem(IDC_BROWSE_BUTTON); if (pWnd != nullptr) @@ -188,13 +266,6 @@ void CDataSettingsDlg::EnableControl() } -//void CDataSettingsDlg::OnBnClickedId3v2FirstCheck() -//{ -// // TODO: 在此添加控件通知处理程序代码 -// m_data.id3v2_first = (((CButton*)GetDlgItem(IDC_ID3V2_FIRST_CHECK))->GetCheck() != 0); -//} - - void CDataSettingsDlg::OnBnClickedCoverAutoDownloadCheck() { // TODO: 在此添加控件通知处理程序代码 diff --git a/MusicPlayer2/DataSettingsDlg.h b/MusicPlayer2/DataSettingsDlg.h index ab1142b97..8d762da1d 100644 --- a/MusicPlayer2/DataSettingsDlg.h +++ b/MusicPlayer2/DataSettingsDlg.h @@ -1,5 +1,4 @@ #pragma once -#include"Common.h" #include "TabDlg.h" #include "BrowseEdit.h" #include "MyComboBox.h" @@ -33,6 +32,7 @@ class CDataSettingsDlg : public CTabDlg void EnableControl(); protected: + virtual bool InitializeControls() override; virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 virtual void GetDataFromUi() override; virtual void ApplyDataToUi() override; @@ -40,7 +40,6 @@ class CDataSettingsDlg : public CTabDlg DECLARE_MESSAGE_MAP() public: virtual BOOL OnInitDialog(); - //afx_msg void OnBnClickedId3v2FirstCheck(); afx_msg void OnBnClickedCoverAutoDownloadCheck(); afx_msg void OnBnClickedLyricAutoDownloadCheck(); afx_msg void OnBnClickedCheckUpdateCheck(); diff --git a/MusicPlayer2/Define.h b/MusicPlayer2/Define.h index bb32a85b5..55637461f 100644 --- a/MusicPlayer2/Define.h +++ b/MusicPlayer2/Define.h @@ -1,21 +1,24 @@ #pragma once //自定义包含文件 -//#include #include #include #include -//#include -#include -#include -#include -#include -#include #include +#include +#include #include #include -#include +#include #include +#include +#include +#include +#include +#include +#include #include +#include +#include using std::ofstream; using std::ifstream; using std::string; @@ -23,6 +26,7 @@ using std::wstring; using std::vector; using std::deque; using std::map; +using std::pair; //用于BASS音频库的支持 #include"bass.h" @@ -108,9 +112,6 @@ using _tstring = std::string; #define IDC_SAVE_COMBO_BOX 1990 //定义添加到“另存为”对话框中的组合框的ID #define IDC_OPEN_CHECKBOX 1991 //定义添加到“添加文件夹”对话框中的复选框的ID -//添加到系统菜单中的“迷你模式”菜单项的ID -#define IDM_MINIMODE 112 - //均衡器 #define EQU_CH_NUM 10 //均衡器通道的数量 const int EQU_STYLE_TABLE[9][EQU_CH_NUM] //均衡器预设 @@ -142,6 +143,7 @@ const int EQU_STYLE_TABLE[9][EQU_CH_NUM] //均衡器预设 #define FAVOURITE_PLAYLIST_NAME L"favourite.playlist" #define TEMP_PLAYLIST_NAME L"temp.playlist" #define PLAYLIST_EXTENSION L".playlist" +#define PLAYLIST_EXTENSION_2 L"playlist" #define APP_NAME L"MusicPlayer2" #define NO_LYRIC_STR L"NoLyric" #define DEFAULT_BACKGROUND_NAME L"default_background.jpg" diff --git a/MusicPlayer2/DesktopLyric.cpp b/MusicPlayer2/DesktopLyric.cpp index 53ebbd6b3..95a33270c 100644 --- a/MusicPlayer2/DesktopLyric.cpp +++ b/MusicPlayer2/DesktopLyric.cpp @@ -3,10 +3,8 @@ #include "MusicPlayer2.h" #include "SongInfoHelper.h" #include "GdiPlusTool.h" -#include "Define.h" #include "CPlayerUIHelper.h" #include "MusicPlayerDlg.h" -#include "WIC.h" CDesktopLyric::CDesktopLyric() { @@ -27,14 +25,12 @@ BEGIN_MESSAGE_MAP(CDesktopLyric, CLyricsWindow) ON_WM_SIZING() ON_WM_RBUTTONUP() ON_WM_GETMINMAXINFO() - // ON_MESSAGE(WM_INITMENU, &CDesktopLyric::OnInitmenu) ON_WM_TIMER() ON_COMMAND(ID_LYRIC_DEFAULT_STYLE1, &CDesktopLyric::OnLyricDefaultStyle1) ON_COMMAND(ID_LYRIC_DEFAULT_STYLE2, &CDesktopLyric::OnLyricDefaultStyle2) ON_COMMAND(ID_LYRIC_DEFAULT_STYLE3, &CDesktopLyric::OnLyricDefaultStyle3) ON_WM_LBUTTONDBLCLK() - ON_WM_MOUSEWHEEL() ON_WM_INITMENU() END_MESSAGE_MAP() @@ -42,26 +38,6 @@ void CDesktopLyric::Create() { CLyricsWindow::Create(theApp.DPI(150)); - m_popupMenu.LoadMenu(IDR_DESKTOP_LYRIC_POPUP_MENU); - - //为右键添加图标 - CMenuIcon::AddIconToMenuItem(m_popupMenu.GetSafeHmenu(), ID_PLAY_PAUSE, FALSE, theApp.m_icon_set.play_pause); - CMenuIcon::AddIconToMenuItem(m_popupMenu.GetSafeHmenu(), ID_STOP, FALSE, theApp.m_icon_set.stop_new); - CMenuIcon::AddIconToMenuItem(m_popupMenu.GetSafeHmenu(), ID_PREVIOUS, FALSE, theApp.m_icon_set.previous_new.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_popupMenu.GetSafeHmenu(), ID_NEXT, FALSE, theApp.m_icon_set.next_new.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_popupMenu.GetSafeHmenu(), ID_PLAY_ORDER, FALSE, theApp.m_icon_set.play_oder.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_popupMenu.GetSafeHmenu(), ID_PLAY_SHUFFLE, FALSE, theApp.m_icon_set.play_shuffle.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_popupMenu.GetSafeHmenu(), ID_PLAY_RANDOM, FALSE, theApp.m_icon_set.play_random.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_popupMenu.GetSafeHmenu(), ID_LOOP_PLAYLIST, FALSE, theApp.m_icon_set.loop_playlist.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_popupMenu.GetSafeHmenu(), ID_LOOP_TRACK, FALSE, theApp.m_icon_set.loop_track.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_popupMenu.GetSafeHmenu(), ID_PLAY_TRACK, FALSE, theApp.m_icon_set.play_track.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_popupMenu.GetSafeHmenu(), ID_LYRIC_DISPLAYED_DOUBLE_LINE, FALSE, theApp.m_icon_set.double_line.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_popupMenu.GetSafeHmenu(), ID_LYRIC_BACKGROUND_PENETRATE, FALSE, theApp.m_icon_set.skin.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_popupMenu.GetSafeHmenu(), ID_LOCK_DESKTOP_LRYIC, FALSE, theApp.m_icon_set.lock.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_popupMenu.GetSubMenu(0)->GetSafeHmenu(), 10, TRUE, theApp.m_icon_set.media_lib.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_popupMenu.GetSafeHmenu(), ID_OPTION_SETTINGS, FALSE, theApp.m_icon_set.setting.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_popupMenu.GetSafeHmenu(), ID_CLOSE_DESKTOP_LYRIC, FALSE, theApp.m_icon_set.close.GetIcon(true)); - //初始化提示信息 m_tool_tip.Create(this, TTS_ALWAYSTIP); m_tool_tip.SetMaxTipWidth(theApp.DPI(400)); @@ -116,14 +92,15 @@ void CDesktopLyric::UpdateLyric(Gdiplus::Graphics* pGraphics, Gdiplus::Font* pFo } ) }; // TRACE("progress %d\n", progress); + static const wstring& empty_lyric = theApp.m_str_table.LoadText(L"UI_LYRIC_EMPTY_LINE_2"); if (is_lyric_empty) - lyric.text = CCommon::LoadText(IDS_DEFAULT_LYRIC_TEXT_CORTANA); + lyric.text = empty_lyric; if (theApp.m_lyric_setting_data.desktop_lyric_data.lyric_double_line) { CLyrics::Lyric next_lyric{ now_lyrics.GetLyric(time, true, ignore_blank, karaoke) }; if (next_lyric.text.empty()) - next_lyric.text = CCommon::LoadText(IDS_DEFAULT_LYRIC_TEXT_CORTANA); + next_lyric.text = empty_lyric; SetNextLyric(next_lyric.text.c_str()); } @@ -331,32 +308,31 @@ void CDesktopLyric::DrawToolbar(Gdiplus::Graphics* pGraphics) if (!bLocked) { - DrawToolIcon(pGraphics, theApp.m_icon_set.app, rcIcon, BTN_APP); + DrawToolIcon(pGraphics, IconMgr::IconType::IT_App, rcIcon, BTN_APP); rcIcon.MoveToX(rcIcon.right); - DrawToolIcon(pGraphics, theApp.m_icon_set.stop, rcIcon, BTN_STOP); + DrawToolIcon(pGraphics, IconMgr::IconType::IT_Stop, rcIcon, BTN_STOP); rcIcon.MoveToX(rcIcon.right); - DrawToolIcon(pGraphics, theApp.m_icon_set.previous, rcIcon, BTN_PREVIOUS); + DrawToolIcon(pGraphics, IconMgr::IconType::IT_Previous, rcIcon, BTN_PREVIOUS); rcIcon.MoveToX(rcIcon.right); - IconRes hPlayPauseIcon = (CPlayer::GetInstance().IsPlaying() ? theApp.m_icon_set.pause : theApp.m_icon_set.play); - DrawToolIcon(pGraphics, hPlayPauseIcon, rcIcon, BTN_PLAY_PAUSE); + DrawToolIcon(pGraphics, CPlayer::GetInstance().IsPlaying() ? IconMgr::IconType::IT_Pause : IconMgr::IconType::IT_Play, rcIcon, BTN_PLAY_PAUSE); rcIcon.MoveToX(rcIcon.right); - DrawToolIcon(pGraphics, theApp.m_icon_set.next, rcIcon, BTN_NEXT); + DrawToolIcon(pGraphics, IconMgr::IconType::IT_Next, rcIcon, BTN_NEXT); rcIcon.MoveToX(rcIcon.right); - DrawToolIcon(pGraphics, theApp.m_icon_set.setting, rcIcon, BTN_SETTING); + DrawToolIcon(pGraphics, IconMgr::IconType::IT_Setting, rcIcon, BTN_SETTING); rcIcon.MoveToX(rcIcon.right); - DrawToolIcon(pGraphics, theApp.m_icon_set.media_lib, rcIcon, BTN_DEFAULT_STYLE); + DrawToolIcon(pGraphics, IconMgr::IconType::IT_Media_Lib, rcIcon, BTN_DEFAULT_STYLE); rcIcon.MoveToX(rcIcon.right); - DrawToolIcon(pGraphics, theApp.m_icon_set.lyric_delay, rcIcon, BTN_LYRIC_DELAY); + DrawToolIcon(pGraphics, IconMgr::IconType::IT_Triangle_Left, rcIcon, BTN_LYRIC_DELAY); rcIcon.MoveToX(rcIcon.right); - DrawToolIcon(pGraphics, theApp.m_icon_set.lyric_forward, rcIcon, BTN_LYRIC_FORWARD); + DrawToolIcon(pGraphics, IconMgr::IconType::IT_Triangle_Right, rcIcon, BTN_LYRIC_FORWARD); rcIcon.MoveToX(rcIcon.right); - DrawToolIcon(pGraphics, theApp.m_icon_set.double_line, rcIcon, BTN_DOUBLE_LINE, theApp.m_lyric_setting_data.desktop_lyric_data.lyric_double_line); + DrawToolIcon(pGraphics, IconMgr::IconType::IT_Double_Line, rcIcon, BTN_DOUBLE_LINE, theApp.m_lyric_setting_data.desktop_lyric_data.lyric_double_line); rcIcon.MoveToX(rcIcon.right); - DrawToolIcon(pGraphics, theApp.m_icon_set.skin, rcIcon, BTN_BACKGROUND_PENETRATE, theApp.m_lyric_setting_data.desktop_lyric_data.lyric_background_penetrate); + DrawToolIcon(pGraphics, IconMgr::IconType::IT_Skin, rcIcon, BTN_BACKGROUND_PENETRATE, theApp.m_lyric_setting_data.desktop_lyric_data.lyric_background_penetrate); rcIcon.MoveToX(rcIcon.right); - DrawToolIcon(pGraphics, theApp.m_icon_set.lock, rcIcon, BTN_LOCK); + DrawToolIcon(pGraphics, IconMgr::IconType::IT_Lock, rcIcon, BTN_LOCK); rcIcon.MoveToX(rcIcon.right); - DrawToolIcon(pGraphics, theApp.m_icon_set.close, rcIcon, BTN_CLOSE); + DrawToolIcon(pGraphics, IconMgr::IconType::IT_Cancel, rcIcon, BTN_CLOSE); bool lyric_disable{ CPlayer::GetInstance().m_Lyrics.IsEmpty() || CPlayerUIHelper::IsMidiLyric() }; m_buttons[BTN_LYRIC_FORWARD].enable = !lyric_disable; @@ -368,7 +344,7 @@ void CDesktopLyric::DrawToolbar(Gdiplus::Graphics* pGraphics) for (auto& btn : m_buttons) { if (btn.first == BTN_LOCK) - DrawToolIcon(pGraphics, theApp.m_icon_set.lock, rcIcon, BTN_LOCK); + DrawToolIcon(pGraphics, IconMgr::IconType::IT_Lock, rcIcon, BTN_LOCK); else btn.second = UIButton(); } @@ -381,7 +357,7 @@ void CDesktopLyric::DrawToolbar(Gdiplus::Graphics* pGraphics) } } -void CDesktopLyric::DrawToolIcon(Gdiplus::Graphics* pGraphics, IconRes icon, CRect rect, BtnKey btn_key, bool checked) +void CDesktopLyric::DrawToolIcon(Gdiplus::Graphics* pGraphics, IconMgr::IconType icon_type, CRect rect, BtnKey btn_key, bool checked) { rect.DeflateRect(theApp.DPI(2), theApp.DPI(2)); auto& btn = m_buttons[btn_key]; @@ -422,9 +398,11 @@ void CDesktopLyric::DrawToolIcon(Gdiplus::Graphics* pGraphics, IconRes icon, CRe } } + HICON hIcon = theApp.m_icon_mgr.GetHICON(icon_type, IconMgr::IconStyle::IS_Filled, IconMgr::IconSize::IS_DPI_16); + CSize icon_size = IconMgr::GetIconSize(IconMgr::IconSize::IS_DPI_16); + CRect rc_tmp = rect; //使图标在矩形中居中 - CSize icon_size = icon.GetSize(); rc_tmp.left = rect.left + (rect.Width() - icon_size.cx) / 2; rc_tmp.top = rect.top + (rect.Height() - icon_size.cy) / 2; rc_tmp.right = rc_tmp.left + icon_size.cx; @@ -433,28 +411,36 @@ void CDesktopLyric::DrawToolIcon(Gdiplus::Graphics* pGraphics, IconRes icon, CRe HDC hDC = pGraphics->GetHDC(); CDrawCommon drawer; drawer.Create(CDC::FromHandle(hDC)); - drawer.DrawIcon(icon.GetIcon(true), rc_tmp.TopLeft(), rc_tmp.Size()); + drawer.DrawIcon(hIcon, rc_tmp.TopLeft(), rc_tmp.Size()); pGraphics->ReleaseHDC(hDC); } void CDesktopLyric::AddToolTips() { - AddMouseToolTip(BTN_APP, CCommon::LoadText(IDS_MAIN_MENU)); - AddMouseToolTip(BTN_STOP, CCommon::LoadText(IDS_STOP)); - AddMouseToolTip(BTN_PREVIOUS, CCommon::LoadText(IDS_PREVIOUS)); - AddMouseToolTip(BTN_PLAY_PAUSE, CCommon::LoadText(IDS_PLAY_PAUSE)); - AddMouseToolTip(BTN_NEXT, CCommon::LoadText(IDS_NEXT)); - AddMouseToolTip(BTN_SETTING, CCommon::LoadText(IDS_SETTINGS)); - AddMouseToolTip(BTN_LYRIC_FORWARD, CCommon::LoadText(IDS_LYRIC_FORWARD)); - AddMouseToolTip(BTN_LYRIC_DELAY, CCommon::LoadText(IDS_LYRIC_DELAY)); - AddMouseToolTip(BTN_DEFAULT_STYLE, CCommon::LoadText(IDS_DEFAULT_STYLE)); - AddMouseToolTip(BTN_DOUBLE_LINE, CCommon::LoadText(IDS_LYRIC_DOUBLE_LINE)); - AddMouseToolTip(BTN_BACKGROUND_PENETRATE, CCommon::LoadText(IDS_LYRIC_BACKGROUND_PENETRATE)); + wstring tip_str; + AddMouseToolTip(BTN_APP, theApp.m_str_table.LoadText(L"UI_TIP_BTN_MAIN_MENU").c_str()); + AddMouseToolTip(BTN_STOP, theApp.m_str_table.LoadText(L"UI_TIP_BTN_STOP").c_str()); + AddMouseToolTip(BTN_PREVIOUS, theApp.m_str_table.LoadText(L"UI_TIP_BTN_PREVIOUS").c_str()); + AddMouseToolTip(BTN_PLAY_PAUSE, theApp.m_str_table.LoadText(L"UI_TIP_BTN_PLAY_PAUSE").c_str()); + AddMouseToolTip(BTN_NEXT, theApp.m_str_table.LoadText(L"UI_TIP_BTN_NEXT").c_str()); + AddMouseToolTip(BTN_SETTING, theApp.m_str_table.LoadText(L"UI_TIP_BTN_OPTION_SETTING").c_str()); + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_DESKTOP_LYRIC_FORWARD"); + AddMouseToolTip(BTN_LYRIC_FORWARD, tip_str.c_str()); + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_DESKTOP_LYRIC_DELAY"); + AddMouseToolTip(BTN_LYRIC_DELAY, tip_str.c_str()); + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_DESKTOP_LYRIC_DEFAULT_STYLE"); + AddMouseToolTip(BTN_DEFAULT_STYLE, tip_str.c_str()); + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_DESKTOP_LYRIC_DOUBLE_LINE"); + AddMouseToolTip(BTN_DOUBLE_LINE, tip_str.c_str()); + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_DESKTOP_LYRIC_BACKGROUND_PENETRATE"); + AddMouseToolTip(BTN_BACKGROUND_PENETRATE, tip_str.c_str()); if (theApp.m_lyric_setting_data.desktop_lyric_data.lock_desktop_lyric) - AddMouseToolTip(BTN_LOCK, CCommon::LoadText(IDS_ULOCK_DESKTOP_LYRIC)); + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_DESKTOP_LYRIC_UNLOCK"); else - AddMouseToolTip(BTN_LOCK, CCommon::LoadText(IDS_LOCK_DESKTOP_LYRIC)); - AddMouseToolTip(BTN_CLOSE, CCommon::LoadText(IDS_CLOSE_DESKTOP_LYRIC)); + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_DESKTOP_LYRIC_LOCK"); + AddMouseToolTip(BTN_LOCK, tip_str.c_str()); + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_DESKTOP_LYRIC_CLOSE"); + AddMouseToolTip(BTN_CLOSE, tip_str.c_str()); m_tool_tip.SetWindowPos(&CWnd::wndTopMost, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); } @@ -570,7 +556,7 @@ void CDesktopLyric::OnLButtonUp(UINT nFlags, CPoint point) CPoint cur_point; GetCursorPos(&cur_point); m_bMenuPopedUp = true; - theApp.m_menu_set.m_main_menu_popup.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, cur_point.x, cur_point.y, this); + theApp.m_menu_mgr.GetMenu(MenuMgr::MainPopupMenu)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, cur_point.x, cur_point.y, this); m_bMenuPopedUp = false; } return; @@ -609,7 +595,7 @@ void CDesktopLyric::OnLButtonUp(UINT nFlags, CPoint point) cur_point.y = m_buttons[BTN_DEFAULT_STYLE].rect.bottom - m_frameSize.cy; ClientToScreen(&cur_point); m_bMenuPopedUp = true; - CMenu* pMenu = theApp.m_menu_set.m_lyric_default_style.GetSubMenu(0); + CMenu* pMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::DlrcDefMenu); if (pMenu != nullptr) pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, cur_point.x, cur_point.y, this); m_bMenuPopedUp = false; @@ -715,7 +701,7 @@ void CDesktopLyric::OnRButtonUp(UINT nFlags, CPoint point) m_bMenuPopedUp = true; CPoint point1; //定义一个用于确定光标位置的位置 GetCursorPos(&point1); //获取当前光标的位置,以便使得菜单可以跟随光标,该位置以屏幕左上角点为原点,point则以客户区左上角为原点 - CMenu* pMenu = m_popupMenu.GetSubMenu(0); + CMenu* pMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::DlrcMenu); if (pMenu != NULL) pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point1.x, point1.y, this); m_bMenuPopedUp = false; @@ -727,8 +713,9 @@ BOOL CDesktopLyric::OnCommand(WPARAM wParam, LPARAM lParam) { // TODO: 在此添加专用代码和/或调用基类 WORD command = LOWORD(wParam); - if (CCommon::IsMenuItemInMenu(m_popupMenu.GetSubMenu(0), command) || CCommon::IsMenuItemInMenu(&theApp.m_menu_set.m_main_menu, command)) - AfxGetMainWnd()->SendMessage(WM_COMMAND, wParam, lParam); //将菜单命令转发到主窗口 + if (CCommon::IsMenuItemInMenu(theApp.m_menu_mgr.GetMenu(MenuMgr::DlrcMenu), command) + || CCommon::IsMenuItemInMenu(theApp.m_menu_mgr.GetMenu(MenuMgr::MainPopupMenu), command)) + AfxGetMainWnd()->SendMessage(WM_COMMAND, wParam, lParam); //将未处理的菜单命令转发到主窗口 return CLyricsWindow::OnCommand(wParam, lParam); } @@ -744,19 +731,24 @@ void CDesktopLyric::OnGetMinMaxInfo(MINMAXINFO* lpMMI) } -//afx_msg LRESULT CDesktopLyric::OnInitmenu(WPARAM wParam, LPARAM lParam) -//{ -// AfxGetMainWnd()->SendMessage(WM_INITMENU, wParam, lParam); //将WM_INITMENU消息转发到主窗口 -// return 0; -//} - - BOOL CDesktopLyric::PreTranslateMessage(MSG* pMsg) { // TODO: 在此添加专用代码和/或调用基类 if (pMsg->message == WM_MOUSEMOVE) m_tool_tip.RelayEvent(pMsg); + if (pMsg->message == WM_MOUSEWHEEL) // 将滚轮消息转发给主窗口处理音量调整 + { + CWnd* pMainWnd = AfxGetMainWnd(); + if (pMainWnd) + { + POINT pt = { INT16_MAX, INT16_MAX }; // 修改pt参数为一个特殊值 + LPARAM lParam = MAKELPARAM(pt.x, pt.y); + pMainWnd->SendMessage(WM_MOUSEWHEEL, pMsg->wParam, lParam); + return TRUE; + } + } + return CLyricsWindow::PreTranslateMessage(pMsg); } @@ -834,22 +826,6 @@ void CDesktopLyric::OnLButtonDblClk(UINT nFlags, CPoint point) } -BOOL CDesktopLyric::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) -{ - // TODO: 在此添加消息处理程序代码和/或调用默认值 - if (zDelta > 0) - { - AfxGetMainWnd()->SendMessage(WM_COMMAND, ID_VOLUME_UP); - } - if (zDelta < 0) - { - AfxGetMainWnd()->SendMessage(WM_COMMAND, ID_VOLUME_DOWN); - } - - return CLyricsWindow::OnMouseWheel(nFlags, zDelta, pt); -} - - void CDesktopLyric::OnInitMenu(CMenu* pMenu) { CLyricsWindow::OnInitMenu(pMenu); diff --git a/MusicPlayer2/DesktopLyric.h b/MusicPlayer2/DesktopLyric.h index 92e5b0ef5..ad9421f5f 100644 --- a/MusicPlayer2/DesktopLyric.h +++ b/MusicPlayer2/DesktopLyric.h @@ -2,6 +2,7 @@ #include "LyricsWindow.h" #include "CommonData.h" #include "IniHelper.h" +#include "IconMgr.h" struct LyricStyle { @@ -82,7 +83,7 @@ class CDesktopLyric : public CLyricsWindow //绘制工具条 void DrawToolbar(Gdiplus::Graphics* pGraphics); //绘制工具条上的图标 - void DrawToolIcon(Gdiplus::Graphics* pGraphics, IconRes icon, CRect rect, BtnKey btn, bool checked = false); + void DrawToolIcon(Gdiplus::Graphics* pGraphics, IconMgr::IconType icon_type, CRect rect, BtnKey btn, bool checked = false); virtual void PreDrawLyric(Gdiplus::Graphics* pGraphics, Gdiplus::Font* pFont) override; virtual void AfterDrawLyric(Gdiplus::Graphics* pGraphics) override; @@ -94,7 +95,6 @@ class CDesktopLyric : public CLyricsWindow //CLyricsWindow m_lyric_window; LyricStyleDefaultData m_default_style[LYRIC_DEFAULT_STYLE_NUM]; - CMenu m_popupMenu; CToolTipCtrl m_tool_tip; std::map m_buttons; bool m_first_draw = true; //第一次绘制工具条时,则为true @@ -125,6 +125,5 @@ class CDesktopLyric : public CLyricsWindow afx_msg void OnLyricDefaultStyle2(); afx_msg void OnLyricDefaultStyle3(); afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); - afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt); afx_msg void OnInitMenu(CMenu* pMenu); }; diff --git a/MusicPlayer2/DrawCommon.cpp b/MusicPlayer2/DrawCommon.cpp index fdc30e134..19393ac0c 100644 --- a/MusicPlayer2/DrawCommon.cpp +++ b/MusicPlayer2/DrawCommon.cpp @@ -23,12 +23,10 @@ CDrawCommon::~CDrawCommon() SAFE_DELETE(m_pGraphics); } -void CDrawCommon::Create(CDC* pDC, CWnd* pMainWnd) +void CDrawCommon::Create(CDC* pDC, CFont* pFont) { m_pDC = pDC; - m_pMainWnd = pMainWnd; - if (m_pMainWnd != nullptr) - m_pfont = m_pMainWnd->GetFont(); + m_pfont = pFont; if (pDC != nullptr) { m_pGraphics = new Gdiplus::Graphics(pDC->GetSafeHdc()); @@ -36,12 +34,10 @@ void CDrawCommon::Create(CDC* pDC, CWnd* pMainWnd) } } -void CDrawCommon::Create(CDC* pDC, Gdiplus::Graphics* pGraphics, CWnd* pMainWnd) +void CDrawCommon::Create(CDC* pDC, Gdiplus::Graphics* pGraphics, CFont* pFont) { m_pDC = pDC; - m_pMainWnd = pMainWnd; - if (m_pMainWnd != nullptr) - m_pfont = m_pMainWnd->GetFont(); + m_pfont = pFont; m_pGraphics = pGraphics; m_auto_destory_graphics = false; } @@ -51,10 +47,10 @@ void CDrawCommon::Create(CDC* pDC, Gdiplus::Graphics* pGraphics, CWnd* pMainWnd) // m_backColor = back_color; //} -CFont* CDrawCommon::SetFont(CFont* pfont) +CFont* CDrawCommon::SetFont(CFont* pFont) { CFont* pOldFont = m_pfont; - m_pfont = pfont; + m_pfont = pFont; return pOldFont; } @@ -74,6 +70,7 @@ void CDrawCommon::DrawWindowText(CRect rect, LPCTSTR lpszString, COLORREF color, ASSERT(align != Alignment::AUTO); m_pDC->SetTextColor(color); m_pDC->SetBkMode(TRANSPARENT); + ASSERT(m_pfont != nullptr); // 请先设置字体 if (m_pfont != nullptr) m_pDC->SelectObject(m_pfont); //设置绘图的剪辑区域 @@ -117,6 +114,7 @@ void CDrawCommon::DrawWindowText(CRect rect, LPCTSTR lpszString, COLORREF color1 if (split < 0) split = 0; if (split > 1000) split = 1000; m_pDC->SetBkMode(TRANSPARENT); + ASSERT(m_pfont != nullptr); // 请先设置字体 if (m_pfont != nullptr) m_pDC->SelectObject(m_pfont); CSize text_size; //文本的大小 @@ -195,6 +193,7 @@ void CDrawCommon::DrawScrollText(CRect rect, LPCTSTR lpszString, COLORREF color, } m_pDC->SetTextColor(color); m_pDC->SetBkMode(TRANSPARENT); + ASSERT(m_pfont != nullptr); // 请先设置字体 if (m_pfont != nullptr) m_pDC->SelectObject(m_pfont); CSize text_size; //文本的大小 @@ -272,6 +271,7 @@ void CDrawCommon::DrawScrollText2(CRect rect, LPCTSTR lpszString, COLORREF color } m_pDC->SetTextColor(color); m_pDC->SetBkMode(TRANSPARENT); + ASSERT(m_pfont != nullptr); // 请先设置字体 if (m_pfont != nullptr) m_pDC->SelectObject(m_pfont); CSize text_size; //文本的大小 @@ -614,6 +614,7 @@ CSize CDrawCommon::GetTextExtent(LPCTSTR str) { if (m_pDC->GetSafeHdc() == NULL) return CSize(); + ASSERT(m_pfont != nullptr); // 请先设置字体 if (m_pfont != nullptr) m_pDC->SelectObject(m_pfont); return m_pDC->GetTextExtent(str); @@ -700,11 +701,6 @@ void CDrawCommon::ImageResize(const wstring& path_src, const wstring& path_dest, ImageResize(imSrc, path_dest, size, type); } -HICON CDrawCommon::LoadIconResource(UINT id, int width, int height) -{ - return (HICON)LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(id), IMAGE_ICON, width, height, 0); -} - HBITMAP CDrawCommon::CopyBitmap(HBITMAP hSourceHbitmap) { CDC sourceDC; diff --git a/MusicPlayer2/DrawCommon.h b/MusicPlayer2/DrawCommon.h index 7c0143379..a71aef2c6 100644 --- a/MusicPlayer2/DrawCommon.h +++ b/MusicPlayer2/DrawCommon.h @@ -43,14 +43,12 @@ class CDrawCommon }; CDrawCommon(); - ~CDrawCommon(); - - virtual void Create(CDC* pDC, CWnd* pMainWnd = nullptr); - void Create(CDC* pDC, Gdiplus::Graphics* pGraphics, CWnd* pMainWnd = nullptr); - //void SetBackColor(COLORREF back_color); //设置绘制文本时填充的背景颜色 - //COLORREF GetBackColor() const { return m_backColor; } - CFont* SetFont(CFont* pfont); //设置绘制文本的字体(返回原来的字体) - CFont* GetFont() { return m_pfont; } + virtual ~CDrawCommon(); // 基类析构方法需要是虚方法 + + virtual void Create(CDC* pDC, CFont* pFont = nullptr); + void Create(CDC* pDC, Gdiplus::Graphics* pGraphics, CFont* pFont = nullptr); + CFont* SetFont(CFont* pFont); // 设置绘制文本的字体(返回原来的字体) + CFont* GetFont() { return m_pfont; } void SetDC(CDC* pDC); //设置绘图的DC CDC* GetDC() { @@ -137,8 +135,6 @@ class CDrawCommon static void ImageResize(const CImage& img_src, const wstring& path_dest, int size, ImageType type); static void ImageResize(const wstring& path_src, const wstring& path_dest, int size, ImageType type); - static HICON LoadIconResource(UINT id, int width, int height); - //复制一个bitmap (http://wupei.j2megame.org/archives/86) //(这两个函数未测试成功,复制的图片为全黑色,原因暂时未知,后面再调查) static HBITMAP CopyBitmap(HBITMAP hSourceHbitmap); @@ -154,8 +150,6 @@ class CDrawCommon protected: CDC* m_pDC{}; //用于绘图的CDC类的指针 - CWnd* m_pMainWnd{}; //绘图窗口的句柄 - //COLORREF m_backColor{ RGB(255,255,255) }; CFont* m_pfont{}; Gdiplus::Graphics* m_pGraphics{}; bool m_auto_destory_graphics{}; //是否自动析构Graphics对象,如果Graphics对象是内部创建的,则为true,如果是从外面传过来的,则为false diff --git a/MusicPlayer2/EditStringListDlg.cpp b/MusicPlayer2/EditStringListDlg.cpp index a47b8d120..605ec33e5 100644 --- a/MusicPlayer2/EditStringListDlg.cpp +++ b/MusicPlayer2/EditStringListDlg.cpp @@ -4,17 +4,14 @@ #include "stdafx.h" #include "MusicPlayer2.h" #include "EditStringListDlg.h" -#include "afxdialogex.h" // CEditStringListDlg 对话框 -#define IDC_ITEM_EDITBOX 1991 - IMPLEMENT_DYNAMIC(CEditStringListDlg, CBaseDialog) CEditStringListDlg::CEditStringListDlg(vector& items, CWnd* pParent /*=nullptr*/) - : CBaseDialog(IDD_SELECT_ITEM_DIALOG, pParent), m_items(items) + : CBaseDialog(IDD_SELECT_ITEM_DIALOG, pParent), m_items(items) { } @@ -28,9 +25,9 @@ void CEditStringListDlg::SetTitle(LPCTSTR title) m_title = title; } -void CEditStringListDlg::SetDlgIcon(HICON icon) +void CEditStringListDlg::SetDlgIcon(IconMgr::IconType icon_type) { - m_icon = icon; + m_icon_type = icon_type; } @@ -46,6 +43,20 @@ CString CEditStringListDlg::GetDialogName() const return _T("SelectItemDlg"); } +bool CEditStringListDlg::InitializeControls() +{ + SetWindowTextW(m_title); + // IDC_LIST1 + // IDOK + // IDCANCEL + + RepositionTextBasedControls({ + { CtrlTextInfo::R1, IDOK, CtrlTextInfo::W32 }, + { CtrlTextInfo::R2, IDCANCEL, CtrlTextInfo::W32 } + }); + return true; +} + BEGIN_MESSAGE_MAP(CEditStringListDlg, CBaseDialog) END_MESSAGE_MAP() @@ -59,11 +70,10 @@ BOOL CEditStringListDlg::OnInitDialog() CBaseDialog::OnInitDialog(); // TODO: 在此添加额外的初始化 - SetWindowText(m_title); - if (m_icon == NULL) - SetIcon(theApp.m_icon_set.app.GetIcon(), FALSE); + if (m_icon_type == IconMgr::IconType::IT_NO_ICON) + SetIcon(IconMgr::IconType::IT_App, FALSE); else - SetIcon(m_icon, FALSE); + SetIcon(m_icon_type, FALSE); for (const auto& str : m_items) m_list_ctrl.AddString(str.c_str()); diff --git a/MusicPlayer2/EditStringListDlg.h b/MusicPlayer2/EditStringListDlg.h index 428f93c10..c27b6ed97 100644 --- a/MusicPlayer2/EditStringListDlg.h +++ b/MusicPlayer2/EditStringListDlg.h @@ -1,38 +1,37 @@ #pragma once -#include "EditableListBox.h" #include "BaseDialog.h" +#include "EditableListBox.h" // CEditStringListDlg 对话框 class CEditStringListDlg : public CBaseDialog { - DECLARE_DYNAMIC(CEditStringListDlg) + DECLARE_DYNAMIC(CEditStringListDlg) public: - CEditStringListDlg(vector& items, CWnd* pParent = nullptr); // 标准构造函数 - virtual ~CEditStringListDlg(); + CEditStringListDlg(vector& items, CWnd* pParent = nullptr); // 标准构造函数 + virtual ~CEditStringListDlg(); void SetTitle(LPCTSTR title); - void SetDlgIcon(HICON icon); + void SetDlgIcon(IconMgr::IconType icon_type); // 对话框数据 #ifdef AFX_DESIGN_TIME - enum { IDD = IDD_SELECT_ITEM_DIALOG }; + enum { IDD = IDD_SELECT_ITEM_DIALOG }; #endif private: CEditableListBox m_list_ctrl; CString m_title; vector& m_items; - HICON m_icon{}; + IconMgr::IconType m_icon_type{ IconMgr::IconType::IT_NO_ICON }; protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 - - DECLARE_MESSAGE_MAP() - virtual CString GetDialogName() const override; + virtual bool InitializeControls() override; + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 + DECLARE_MESSAGE_MAP() public: virtual BOOL OnInitDialog(); virtual void OnOK(); diff --git a/MusicPlayer2/EqualizerDlg.cpp b/MusicPlayer2/EqualizerDlg.cpp index 67e193c68..8de961e83 100644 --- a/MusicPlayer2/EqualizerDlg.cpp +++ b/MusicPlayer2/EqualizerDlg.cpp @@ -3,16 +3,17 @@ #include "stdafx.h" #include "MusicPlayer2.h" +#include "Player.h" #include "EqualizerDlg.h" -#include "afxdialogex.h" +#include "IniHelper.h" // CEqualizerDlg 对话框 -IMPLEMENT_DYNAMIC(CEqualizerDlg, CDialogEx) +IMPLEMENT_DYNAMIC(CEqualizerDlg, CTabDlg) CEqualizerDlg::CEqualizerDlg(CWnd* pParent /*=NULL*/) - : CDialogEx(IDD_EQUALIZER_DIALOG, pParent) + : CTabDlg(IDD_EQUALIZER_DIALOG, pParent) { } @@ -23,75 +24,85 @@ CEqualizerDlg::~CEqualizerDlg() void CEqualizerDlg::EnableControls(bool enable) { - m_equ_style_list.EnableWindow(enable); - for (int i{}; i < EQU_CH_NUM; i++) - { - m_sliders[i].EnableWindow(enable); - } + m_equ_style_list.EnableWindow(enable); + for (int i{}; i < EQU_CH_NUM; i++) + { + m_sliders[i].EnableWindow(enable); + } } void CEqualizerDlg::SaveConfig() const { - CIniHelper ini(theApp.m_config_path); - - ini.WriteInt(L"equalizer", L"equalizer_style", m_equ_style_selected); - //保存自定义的每个均衡器通道的增益 - wchar_t buff[16]; - for (int i{}; i < EQU_CH_NUM; i++) - { - swprintf_s(buff, L"channel%d", i + 1); - ini.WriteInt(L"equalizer", buff, m_user_defined_gain[i]); - } - ini.Save(); + CIniHelper ini(theApp.m_config_path); + + ini.WriteInt(L"equalizer", L"equalizer_style", m_equ_style_selected); + //保存自定义的每个均衡器通道的增益 + wchar_t buff[16]; + for (int i{}; i < EQU_CH_NUM; i++) + { + swprintf_s(buff, L"channel%d", i + 1); + ini.WriteInt(L"equalizer", buff, m_user_defined_gain[i]); + } + ini.Save(); } void CEqualizerDlg::LoadConfig() { - CIniHelper ini(theApp.m_config_path); - - m_equ_style_selected = ini.GetInt(L"equalizer", L"equalizer_style", 0); - //读取自定义的每个均衡器通道的增益 - wchar_t buff[16]; - for (int i{}; i < EQU_CH_NUM; i++) - { - swprintf_s(buff, L"channel%d", i + 1); - m_user_defined_gain[i] = ini.GetInt(L"equalizer", buff, 0); - } + CIniHelper ini(theApp.m_config_path); + + m_equ_style_selected = ini.GetInt(L"equalizer", L"equalizer_style", 0); + //读取自定义的每个均衡器通道的增益 + wchar_t buff[16]; + for (int i{}; i < EQU_CH_NUM; i++) + { + swprintf_s(buff, L"channel%d", i + 1); + m_user_defined_gain[i] = ini.GetInt(L"equalizer", buff, 0); + } } void CEqualizerDlg::UpdateChannelTip(int channel, int gain) { - if (channel < 0 || channel >= EQU_CH_NUM) return; - wchar_t buff[8]; - swprintf_s(buff, L"%ddB", gain); - m_Mytip.UpdateTipText(buff, &m_sliders[channel]); //更新鼠标提示 + if (channel < 0 || channel >= EQU_CH_NUM) return; + wchar_t buff[8]; + swprintf_s(buff, L"%ddB", gain); + m_Mytip.UpdateTipText(buff, &m_sliders[channel]); //更新鼠标提示 +} + +bool CEqualizerDlg::InitializeControls() +{ + wstring temp; + temp = theApp.m_str_table.LoadText(L"TXT_EQ_ENABLE"); + SetDlgItemTextW(IDC_ENABLE_EQU_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_EQ_PRESET"); + SetDlgItemTextW(IDC_TXT_EQ_PRESET_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_EQ_CHANNEL_SETTING"); + SetDlgItemTextW(IDC_TXT_EQ_CHANNEL_SETTING_STATIC, temp.c_str()); + + return false; } void CEqualizerDlg::DoDataExchange(CDataExchange* pDX) { - CDialogEx::DoDataExchange(pDX); - DDX_Control(pDX, IDC_SLIDER1, m_sliders[0]); - DDX_Control(pDX, IDC_SLIDER2, m_sliders[1]); - DDX_Control(pDX, IDC_SLIDER3, m_sliders[2]); - DDX_Control(pDX, IDC_SLIDER4, m_sliders[3]); - DDX_Control(pDX, IDC_SLIDER5, m_sliders[4]); - DDX_Control(pDX, IDC_SLIDER6, m_sliders[5]); - DDX_Control(pDX, IDC_SLIDER7, m_sliders[6]); - DDX_Control(pDX, IDC_SLIDER8, m_sliders[7]); - DDX_Control(pDX, IDC_SLIDER9, m_sliders[8]); - DDX_Control(pDX, IDC_SLIDER10, m_sliders[9]); - DDX_Control(pDX, IDC_EQU_STYLES_LIST, m_equ_style_list); - DDX_Control(pDX, IDC_ENABLE_EQU_CHECK, m_enable_equ_check); + CTabDlg::DoDataExchange(pDX); + DDX_Control(pDX, IDC_SLIDER1, m_sliders[0]); + DDX_Control(pDX, IDC_SLIDER2, m_sliders[1]); + DDX_Control(pDX, IDC_SLIDER3, m_sliders[2]); + DDX_Control(pDX, IDC_SLIDER4, m_sliders[3]); + DDX_Control(pDX, IDC_SLIDER5, m_sliders[4]); + DDX_Control(pDX, IDC_SLIDER6, m_sliders[5]); + DDX_Control(pDX, IDC_SLIDER7, m_sliders[6]); + DDX_Control(pDX, IDC_SLIDER8, m_sliders[7]); + DDX_Control(pDX, IDC_SLIDER9, m_sliders[8]); + DDX_Control(pDX, IDC_SLIDER10, m_sliders[9]); + DDX_Control(pDX, IDC_EQU_STYLES_LIST, m_equ_style_list); } -BEGIN_MESSAGE_MAP(CEqualizerDlg, CDialogEx) -// ON_WM_TIMER() - ON_WM_VSCROLL() - ON_BN_CLICKED(IDC_ENABLE_EQU_CHECK, &CEqualizerDlg::OnBnClickedEnableEquCheck) - ON_WM_DESTROY() - ON_WM_CTLCOLOR() - ON_MESSAGE(WM_LISTBOX_SEL_CHANGED, &CEqualizerDlg::OnListboxSelChanged) +BEGIN_MESSAGE_MAP(CEqualizerDlg, CTabDlg) + ON_WM_VSCROLL() + ON_BN_CLICKED(IDC_ENABLE_EQU_CHECK, &CEqualizerDlg::OnBnClickedEnableEquCheck) + ON_WM_DESTROY() + ON_MESSAGE(WM_LISTBOX_SEL_CHANGED, &CEqualizerDlg::OnListboxSelChanged) END_MESSAGE_MAP() @@ -100,159 +111,139 @@ END_MESSAGE_MAP() BOOL CEqualizerDlg::OnInitDialog() { - CDialogEx::OnInitDialog(); - - // TODO: 在此添加额外的初始化 - LoadConfig(); - //初始化滑动条的位置 - for (int i{}; i < EQU_CH_NUM; i++) - { - m_sliders[i].SetRange(-15, 15, TRUE); - m_sliders[i].SetPos(-CPlayer::GetInstance().GeEqualizer(i)); - } - - //初始化均衡器开关复选框 - m_enable_equ_check.SetCheck(CPlayer::GetInstance().GetEqualizerEnable()); - - //初始化“均衡器预设”列表 - m_equ_style_list.AddString(CCommon::LoadText(IDS_NONE)); - m_equ_style_list.AddString(CCommon::LoadText(IDS_CLASSICAL)); - m_equ_style_list.AddString(CCommon::LoadText(IDS_POP)); - m_equ_style_list.AddString(CCommon::LoadText(IDS_JAZZ)); - m_equ_style_list.AddString(CCommon::LoadText(IDS_ROCK)); - m_equ_style_list.AddString(CCommon::LoadText(IDS_SOFT)); - m_equ_style_list.AddString(CCommon::LoadText(IDS_BASS)); - m_equ_style_list.AddString(CCommon::LoadText(IDS_ELIMINATE_BASS)); - m_equ_style_list.AddString(CCommon::LoadText(IDS_WEAKENING_TREBLE)); - m_equ_style_list.AddString(CCommon::LoadText(IDS_USER_DEFINE)); - m_equ_style_list.SetCurSel(m_equ_style_selected); - - //初始化控件的启用禁用状态 - EnableControls(CPlayer::GetInstance().GetEqualizerEnable()); - - //初始化提示信息 - m_Mytip.Create(this, TTS_ALWAYSTIP); - wchar_t buff[8]; - for (int i{}; i < EQU_CH_NUM; i++) - { - swprintf_s(buff, L"%ddB", -m_sliders[i].GetPos()); - m_Mytip.AddTool(&m_sliders[i], buff); - } - - SetBackgroundColor(RGB(255, 255, 255)); - - return TRUE; // return TRUE unless you set the focus to a control - // 异常: OCX 属性页应返回 FALSE + CTabDlg::OnInitDialog(); + + // TODO: 在此添加额外的初始化 + LoadConfig(); + + //初始化滑动条的位置 + for (int i{}; i < EQU_CH_NUM; i++) + { + m_sliders[i].SetRange(-15, 15, TRUE); + m_sliders[i].SetPos(-CPlayer::GetInstance().GeEqualizer(i)); + } + + //初始化均衡器开关复选框 + CheckDlgButton(IDC_ENABLE_EQU_CHECK, CPlayer::GetInstance().GetEqualizerEnable()); + + //初始化“均衡器预设”列表 + m_equ_style_list.AddString(theApp.m_str_table.LoadText(L"TXT_EQ_NONE").c_str()); + m_equ_style_list.AddString(theApp.m_str_table.LoadText(L"TXT_EQ_CLASSICAL").c_str()); + m_equ_style_list.AddString(theApp.m_str_table.LoadText(L"TXT_EQ_POP").c_str()); + m_equ_style_list.AddString(theApp.m_str_table.LoadText(L"TXT_EQ_JAZZ").c_str()); + m_equ_style_list.AddString(theApp.m_str_table.LoadText(L"TXT_EQ_ROCK").c_str()); + m_equ_style_list.AddString(theApp.m_str_table.LoadText(L"TXT_EQ_SOFT").c_str()); + m_equ_style_list.AddString(theApp.m_str_table.LoadText(L"TXT_EQ_BASS").c_str()); + m_equ_style_list.AddString(theApp.m_str_table.LoadText(L"TXT_EQ_ELIMINATE_BASS").c_str()); + m_equ_style_list.AddString(theApp.m_str_table.LoadText(L"TXT_EQ_WEAKENING_TREBLE").c_str()); + m_equ_style_list.AddString(theApp.m_str_table.LoadText(L"TXT_EQ_USER_DEFINE").c_str()); + m_equ_style_list.SetCurSel(m_equ_style_selected); + + //初始化控件的启用禁用状态 + EnableControls(CPlayer::GetInstance().GetEqualizerEnable()); + + //初始化提示信息 + m_Mytip.Create(this, TTS_ALWAYSTIP); + wchar_t buff[8]; + for (int i{}; i < EQU_CH_NUM; i++) + { + swprintf_s(buff, L"%ddB", -m_sliders[i].GetPos()); + m_Mytip.AddTool(&m_sliders[i], buff); + } + + return TRUE; // return TRUE unless you set the focus to a control + // 异常: OCX 属性页应返回 FALSE } void CEqualizerDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { - // TODO: 在此添加消息处理程序代码和/或调用默认值 - for (int i{}; i < EQU_CH_NUM; i++) - { - if (pScrollBar->GetSafeHwnd() == m_sliders[i].GetSafeHwnd()) - { - int gain{ -m_sliders[i].GetPos() }; //由于滑动条的值越往上越小,所以这里取负数 - CPlayer::GetInstance().SetEqualizer(i, gain); //设置通道i的增益 - UpdateChannelTip(i, gain); //更新鼠标提示 - - if (m_equ_style_list.GetCurSel() == 9) //如果“均衡器预设”中选中的是自定义 - { - m_user_defined_gain[i] = gain; //将增益值保存到用户自定义增益里 - } - else - { - //否则,将当前每个滑动条上的增益设置保存到m_user_defined_gain里 - for (int j{}; j < EQU_CH_NUM; j++) - { - m_user_defined_gain[j] = -m_sliders[j].GetPos(); - } - m_equ_style_list.SetCurSel(9); //更改了均衡器的设定,“均衡器预设”中自动选中“自定义” - m_equ_style_selected = 9; - } - break; - } - } - - CDialogEx::OnVScroll(nSBCode, nPos, pScrollBar); + // TODO: 在此添加消息处理程序代码和/或调用默认值 + for (int i{}; i < EQU_CH_NUM; i++) + { + if (pScrollBar->GetSafeHwnd() == m_sliders[i].GetSafeHwnd()) + { + int gain{ -m_sliders[i].GetPos() }; //由于滑动条的值越往上越小,所以这里取负数 + CPlayer::GetInstance().SetEqualizer(i, gain); //设置通道i的增益 + UpdateChannelTip(i, gain); //更新鼠标提示 + + if (m_equ_style_list.GetCurSel() == 9) //如果“均衡器预设”中选中的是自定义 + { + m_user_defined_gain[i] = gain; //将增益值保存到用户自定义增益里 + } + else + { + //否则,将当前每个滑动条上的增益设置保存到m_user_defined_gain里 + for (int j{}; j < EQU_CH_NUM; j++) + { + m_user_defined_gain[j] = -m_sliders[j].GetPos(); + } + m_equ_style_list.SetCurSel(9); //更改了均衡器的设定,“均衡器预设”中自动选中“自定义” + m_equ_style_selected = 9; + } + break; + } + } + + CTabDlg::OnVScroll(nSBCode, nPos, pScrollBar); } BOOL CEqualizerDlg::PreTranslateMessage(MSG* pMsg) { - // TODO: 在此添加专用代码和/或调用基类 - if (pMsg->message == WM_MOUSEMOVE) - m_Mytip.RelayEvent(pMsg); + // TODO: 在此添加专用代码和/或调用基类 + if (pMsg->message == WM_MOUSEMOVE) + m_Mytip.RelayEvent(pMsg); - return CDialogEx::PreTranslateMessage(pMsg); + return CTabDlg::PreTranslateMessage(pMsg); } void CEqualizerDlg::OnBnClickedEnableEquCheck() { - // TODO: 在此添加控件通知处理程序代码 - bool enable = (m_enable_equ_check.GetCheck() != 0); - CPlayer::GetInstance().EnableEqualizer(enable); - EnableControls(enable); + // TODO: 在此添加控件通知处理程序代码 + bool enable = (IsDlgButtonChecked(IDC_ENABLE_EQU_CHECK) != FALSE); + CPlayer::GetInstance().EnableEqualizer(enable); + EnableControls(enable); } afx_msg LRESULT CEqualizerDlg::OnListboxSelChanged(WPARAM wParam, LPARAM lParam) { - if ((CWnd*)wParam == &m_equ_style_list) - { - m_equ_style_selected = (int)lParam; - if (m_equ_style_selected >= 0 && m_equ_style_selected < 9) - { - //根据选中的均衡器风格设置每个通道的增益 - for (int i{}; i < EQU_CH_NUM; i++) - { - int gain = EQU_STYLE_TABLE[m_equ_style_selected][i]; - CPlayer::GetInstance().SetEqualizer(i, gain); - m_sliders[i].SetPos(-gain); - UpdateChannelTip(i, gain); //更新鼠标提示 - } - } - else if (m_equ_style_selected == 9) //如果选择了“自定义” - { - for (int i{}; i < EQU_CH_NUM; i++) - { - int gain = m_user_defined_gain[i]; - CPlayer::GetInstance().SetEqualizer(i, gain); - m_sliders[i].SetPos(-gain); - UpdateChannelTip(i, gain); //更新鼠标提示 - } - } - - } - return 0; + if ((CWnd*)wParam == &m_equ_style_list) + { + m_equ_style_selected = (int)lParam; + if (m_equ_style_selected >= 0 && m_equ_style_selected < 9) + { + //根据选中的均衡器风格设置每个通道的增益 + for (int i{}; i < EQU_CH_NUM; i++) + { + int gain = EQU_STYLE_TABLE[m_equ_style_selected][i]; + CPlayer::GetInstance().SetEqualizer(i, gain); + m_sliders[i].SetPos(-gain); + UpdateChannelTip(i, gain); //更新鼠标提示 + } + } + else if (m_equ_style_selected == 9) //如果选择了“自定义” + { + for (int i{}; i < EQU_CH_NUM; i++) + { + int gain = m_user_defined_gain[i]; + CPlayer::GetInstance().SetEqualizer(i, gain); + m_sliders[i].SetPos(-gain); + UpdateChannelTip(i, gain); //更新鼠标提示 + } + } + + } + return 0; } void CEqualizerDlg::OnDestroy() { - CDialogEx::OnDestroy(); + CTabDlg::OnDestroy(); - // TODO: 在此处添加消息处理程序代码 - SaveConfig(); -} - - -HBRUSH CEqualizerDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) -{ - HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor); - - // TODO: 在此更改 DC 的任何特性 - //设置均衡器通道滑动条的背景色为白色 - for (int i{}; i < EQU_CH_NUM; i++) - { - if (pWnd == &m_sliders[i]) - { - return (HBRUSH)::GetStockObject(WHITE_BRUSH); - } - } - - // TODO: 如果默认的不是所需画笔,则返回另一个画笔 - return hbr; + // TODO: 在此处添加消息处理程序代码 + SaveConfig(); } diff --git a/MusicPlayer2/EqualizerDlg.h b/MusicPlayer2/EqualizerDlg.h index b9a2ae945..8da358546 100644 --- a/MusicPlayer2/EqualizerDlg.h +++ b/MusicPlayer2/EqualizerDlg.h @@ -1,47 +1,45 @@ #pragma once -#include "afxcmn.h" -#include "afxwin.h" +#include "TabDlg.h" #include "CListBoxEnhanced.h" // CEqualizerDlg 对话框 -class CEqualizerDlg : public CDialogEx +class CEqualizerDlg : public CTabDlg { - DECLARE_DYNAMIC(CEqualizerDlg) + DECLARE_DYNAMIC(CEqualizerDlg) public: - CEqualizerDlg(CWnd* pParent = NULL); // 标准构造函数 - virtual ~CEqualizerDlg(); + CEqualizerDlg(CWnd* pParent = NULL); // 标准构造函数 + virtual ~CEqualizerDlg(); // 对话框数据 #ifdef AFX_DESIGN_TIME - enum { IDD = IDD_EQUALIZER_DIALOG }; + enum { IDD = IDD_EQUALIZER_DIALOG }; #endif protected: - int m_user_defined_gain[EQU_CH_NUM]{}; //用户自定义的均衡器设置 + int m_user_defined_gain[EQU_CH_NUM]{}; //用户自定义的均衡器设置 - CSliderCtrl m_sliders[EQU_CH_NUM]; - CListBoxEnhanced m_equ_style_list; - CButton m_enable_equ_check; - CToolTipCtrl m_Mytip; //鼠标提示 - int m_equ_style_selected{}; //选中的均衡器预设 + CSliderCtrl m_sliders[EQU_CH_NUM]; + CListBoxEnhanced m_equ_style_list; + CToolTipCtrl m_Mytip; //鼠标提示 + int m_equ_style_selected{}; //选中的均衡器预设 - void EnableControls(bool enable); //启用或禁用控件 - void SaveConfig() const; - void LoadConfig(); - void UpdateChannelTip(int channel, int gain); //更新通道滑动条的鼠标提示 + void EnableControls(bool enable); //启用或禁用控件 + void SaveConfig() const; + void LoadConfig(); + void UpdateChannelTip(int channel, int gain); //更新通道滑动条的鼠标提示 - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 + virtual bool InitializeControls() override; + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 - DECLARE_MESSAGE_MAP() + DECLARE_MESSAGE_MAP() protected: - virtual BOOL OnInitDialog(); - afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); - virtual BOOL PreTranslateMessage(MSG* pMsg); - afx_msg void OnBnClickedEnableEquCheck(); - afx_msg LRESULT OnListboxSelChanged(WPARAM wParam, LPARAM lParam); - afx_msg void OnDestroy(); - afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); + virtual BOOL OnInitDialog(); + afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); + virtual BOOL PreTranslateMessage(MSG* pMsg); + afx_msg void OnBnClickedEnableEquCheck(); + afx_msg LRESULT OnListboxSelChanged(WPARAM wParam, LPARAM lParam); + afx_msg void OnDestroy(); }; diff --git a/MusicPlayer2/FfmpegCore.cpp b/MusicPlayer2/FfmpegCore.cpp index 419729b04..1b104a0d6 100644 --- a/MusicPlayer2/FfmpegCore.cpp +++ b/MusicPlayer2/FfmpegCore.cpp @@ -4,6 +4,7 @@ #include "AudioCommon.h" #include "Common.h" #include "MusicPlayer2.h" +#include "Player.h" #define ft2ts(t) (((size_t)t.dwHighDateTime << 32) | (size_t)t.dwLowDateTime) @@ -14,8 +15,8 @@ CFfmpegCore::CFfmpegCore() { err = 0; Init(L"ffmpeg_core.dll"); if (!IsSucceed()) { - CString strInfo = CCommon::LoadText(IDS_FFMPEG_INIT_FAILED); - theApp.WriteLog(wstring(strInfo)); + const wstring& info = theApp.m_str_table.LoadText(L"LOG_FFMPEG_INIT_FAILED"); + theApp.WriteLog(info); } } @@ -28,7 +29,7 @@ void CFfmpegCore::InitCore() { if (IsSucceed()) { CAudioCommon::m_surpported_format.clear(); CAudioCommon::m_all_surpported_extensions.clear(); - CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"mp3 wma wav m4a ogg oga flac ape mp2 mp1 opus ape cda aif aiff cue mp4 mkv mka m2ts", CCommon::LoadText(IDS_BASIC_AUDIO_FORMAT))); + CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"mp3 wma wav m4a ogg oga flac ape mp2 mp1 opus ape cda aif aiff cue mp4 mkv mka m2ts", theApp.m_str_table.LoadText(L"TXT_FILE_TYPE_BASE").c_str())); CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"3gp 3g2 mj2 psp m4b ism ismv isma f4v", L"3gp")); CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"aa", L"Audible Format 2, 3, and 4")); CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(L"aac", L"AAC (Advanced Audio Coding)")); @@ -62,7 +63,7 @@ void CFfmpegCore::InitCore() { if (!theApp.m_nc_setting_data.user_defined_type_ffmpeg.empty()) { - CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(theApp.m_nc_setting_data.user_defined_type_ffmpeg, CCommon::LoadText(IDS_OTHER_FORMATS))); + CAudioCommon::m_surpported_format.push_back(CAudioCommon::CreateSupportedFormat(theApp.m_nc_setting_data.user_defined_type_ffmpeg, theApp.m_str_table.LoadText(L"TXT_FILE_TYPE_FFMPEG_USER_DEFINE").c_str())); } for (const auto& item : CAudioCommon::m_surpported_format) @@ -81,7 +82,7 @@ void CFfmpegCore::InitCore() { auto devices = GetAudioDevices(); DeviceInfo d; d.index = -1; - d.name = CCommon::LoadText(IDS_SDL_DEFAULT_DEVICE); + d.name = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_DEVICE_NAME_SDL_DEFAULT"); d.driver = L""; d.flags = 0; theApp.m_output_devices.clear(); @@ -217,12 +218,16 @@ int CFfmpegCore::GetCurPosition() { int CFfmpegCore::GetSongLength() { if (IsSucceed() && handle) { - return static_cast(ffmpeg_core_get_song_length(handle) / 1000); + int64_t length = ffmpeg_core_get_song_length(handle); + if (length != INT64_MIN) + return static_cast(length / 1000); + else + return 0; } else return 0; } void CFfmpegCore::SetCurPosition(int position) { - if (IsSucceed() && handle) { + if (IsSucceed() && handle && GetSongLength() != 0) { // 时长为0(获取失败)时seek(0)会卡死 int re = ffmpeg_core_seek(handle, (int64_t)position * 1000); if (re) { err = re; @@ -232,7 +237,7 @@ void CFfmpegCore::SetCurPosition(int position) { void CFfmpegCore::GetAudioInfo(SongInfo& song_info, int flag) { if (!handle || !IsSucceed()) return; - if (flag & AF_LENGTH) song_info.setLength(GetSongLength()); + if (flag & AF_LENGTH) song_info.end_pos.fromInt(GetSongLength()); if (flag & AF_CHANNEL_INFO) { song_info.freq = ffmpeg_core_get_freq(handle); song_info.bits = ffmpeg_core_get_bits(handle); @@ -243,6 +248,7 @@ void CFfmpegCore::GetAudioInfo(SongInfo& song_info, int flag) { } if (flag & AF_TAG_INFO) { CAudioTag audio_tag(song_info); + audio_tag.GetAudioRating(); if (!audio_tag.GetAudioTag()) //如果taglib获取信息失败,则使用ffmpeg获取标签信息 { song_info.title = GetTitle(); @@ -261,7 +267,13 @@ void CFfmpegCore::GetAudioInfo(const wchar_t* file_path, SongInfo& song_info, in MusicInfoHandle* h = nullptr; int re = ffmpeg_core_info_open(file_path, &h); if (re || !h) return; - if (flag & AF_LENGTH) song_info.setLength(static_cast(ffmpeg_core_info_get_song_length(h) / 1000)); + if (flag & AF_LENGTH) { + int64_t length = ffmpeg_core_info_get_song_length(h); + if (length != INT64_MIN) + song_info.end_pos.fromInt(static_cast(length / 1000)); + else + song_info.end_pos.fromInt(0); + } if (flag & AF_CHANNEL_INFO) { song_info.freq = ffmpeg_core_info_get_freq(h); song_info.bits = ffmpeg_core_info_get_bits(h); @@ -274,6 +286,7 @@ void CFfmpegCore::GetAudioInfo(const wchar_t* file_path, SongInfo& song_info, in if (song_info.file_path.empty()) song_info.file_path = file_path; CAudioTag audio_tag(song_info); + audio_tag.GetAudioRating(); if (!audio_tag.GetAudioTag()) //如果taglib获取信息失败,则使用ffmpeg获取标签信息 { song_info.title = GetTitle(h); diff --git a/MusicPlayer2/FileNameFormDlg.cpp b/MusicPlayer2/FileNameFormDlg.cpp new file mode 100644 index 000000000..f0bb1a43c --- /dev/null +++ b/MusicPlayer2/FileNameFormDlg.cpp @@ -0,0 +1,56 @@ +// FileNameFormDlg.cpp: 实现文件 +// + +#include "stdafx.h" +#include "MusicPlayer2.h" +#include "FileNameFormDlg.h" + + +// CFileNameFormDlg 对话框 + +IMPLEMENT_DYNAMIC(CFileNameFormDlg, CTagSelBaseDlg) + +CFileNameFormDlg::CFileNameFormDlg(CWnd* pParent) + : CTagSelBaseDlg(false, pParent) +{ +} + +CFileNameFormDlg::~CFileNameFormDlg() +{ +} + +CString CFileNameFormDlg::GetDialogName() const +{ + return L"FileNameFormDlg"; +} + +bool CFileNameFormDlg::InitializeControls() +{ + wstring temp; + temp = theApp.m_str_table.LoadText(L"TITLE_FILE_NAME_FORM"); + SetWindowTextW(temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_FILE_NAME_FORM_INFO"); + SetDlgItemTextW(IDC_INFO_STATIC, temp.c_str()); + + return CTagSelBaseDlg::InitializeControls(); +} + +void CFileNameFormDlg::DoDataExchange(CDataExchange* pDX) +{ + CTagSelBaseDlg::DoDataExchange(pDX); +} + +BEGIN_MESSAGE_MAP(CFileNameFormDlg, CTagSelBaseDlg) +END_MESSAGE_MAP() + + +BOOL CFileNameFormDlg::OnInitDialog() +{ + CTagSelBaseDlg::OnInitDialog(); + + // TODO: 在此添加额外的初始化 + SetIcon(IconMgr::IconType::IT_Tag, FALSE); + + return TRUE; // return TRUE unless you set the focus to a control + // 异常: OCX 属性页应返回 FALSE +} diff --git a/MusicPlayer2/FileNameFormDlg.h b/MusicPlayer2/FileNameFormDlg.h new file mode 100644 index 000000000..1ce1d48cd --- /dev/null +++ b/MusicPlayer2/FileNameFormDlg.h @@ -0,0 +1,23 @@ +#pragma once +#include "TagSelBaseDlg.h" + +// CFileNameFormDlg 对话框 + +class CFileNameFormDlg : public CTagSelBaseDlg +{ + DECLARE_DYNAMIC(CFileNameFormDlg) +public: + CFileNameFormDlg(CWnd* pParent = nullptr); // 标准构造函数 + virtual ~CFileNameFormDlg(); + +protected: + virtual CString GetDialogName() const; + virtual bool InitializeControls() override; + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 + + DECLARE_MESSAGE_MAP() +public: + virtual BOOL OnInitDialog(); +}; + + diff --git a/MusicPlayer2/FileRelateDlg.cpp b/MusicPlayer2/FileRelateDlg.cpp index 708d82d11..ff8e8236a 100644 --- a/MusicPlayer2/FileRelateDlg.cpp +++ b/MusicPlayer2/FileRelateDlg.cpp @@ -4,10 +4,8 @@ #include "stdafx.h" #include "MusicPlayer2.h" #include "FileRelateDlg.h" -#include "afxdialogex.h" #include "AudioCommon.h" #include "RegFileRelate.h" -#include #include "Playlist.h" @@ -30,6 +28,25 @@ CString CFileRelateDlg::GetDialogName() const return _T("FileRelateDlg"); } +bool CFileRelateDlg::InitializeControls() +{ + wstring temp; + temp = theApp.m_str_table.LoadText(L"TITLE_FILE_RELATE"); + SetWindowTextW(temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_FILE_RELATE_SEL_DEFAULT"); + SetDlgItemTextW(IDC_DEFAULT_BUTTON, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_FILE_RELATE_SEL_ALL"); + SetDlgItemTextW(IDC_SELECT_ALL_CHECK, temp.c_str()); + + RepositionTextBasedControls({ + { CtrlTextInfo::L2, IDC_DEFAULT_BUTTON, CtrlTextInfo::W32 }, + { CtrlTextInfo::L1, IDC_SELECT_ALL_CHECK, CtrlTextInfo::W16 }, + { CtrlTextInfo::R1, IDOK, CtrlTextInfo::W32 }, + { CtrlTextInfo::R2, IDCANCEL, CtrlTextInfo::W32 } + }); + return true; +} + void CFileRelateDlg::DoDataExchange(CDataExchange* pDX) { CBaseDialog::DoDataExchange(pDX); @@ -104,16 +121,16 @@ BOOL CFileRelateDlg::OnInitDialog() CBaseDialog::OnInitDialog(); // TODO: 在此添加额外的初始化 - SetIcon(theApp.m_icon_set.file_relate, FALSE); - + SetIcon(IconMgr::IconType::IT_File_Relate, FALSE); + CRect rect; m_list_ctrl.GetWindowRect(rect); m_list_ctrl.SetExtendedStyle(m_list_ctrl.GetExtendedStyle() | LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT | LVS_EX_CHECKBOXES); int width0 = theApp.DPI(120); int width1 = rect.Width() - width0 - theApp.DPI(20) - 1; - m_list_ctrl.InsertColumn(0, CCommon::LoadText(IDS_FORMAT), LVCFMT_LEFT, width0); - m_list_ctrl.InsertColumn(1,CCommon::LoadText(IDS_DESCRIPTION), LVCFMT_LEFT, width1); + m_list_ctrl.InsertColumn(0, theApp.m_str_table.LoadText(L"TXT_FILE_RELATE_FORMAT").c_str(), LVCFMT_LEFT, width0); + m_list_ctrl.InsertColumn(1, theApp.m_str_table.LoadText(L"TXT_FILE_RELATE_DESCRIPTION").c_str(), LVCFMT_LEFT, width1); RefreshList(); diff --git a/MusicPlayer2/FileRelateDlg.h b/MusicPlayer2/FileRelateDlg.h index dd1b8a03a..01e39b1d3 100644 --- a/MusicPlayer2/FileRelateDlg.h +++ b/MusicPlayer2/FileRelateDlg.h @@ -1,5 +1,6 @@ #pragma once #include "BaseDialog.h" +#include "ListCtrlEx.h" // CFileRelateDlg 对话框 @@ -19,6 +20,7 @@ class CFileRelateDlg : public CBaseDialog protected: virtual CString GetDialogName() const override; + virtual bool InitializeControls() override; virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 void RefreshList(); diff --git a/MusicPlayer2/FilterHelper.cpp b/MusicPlayer2/FilterHelper.cpp new file mode 100644 index 000000000..3e7226778 --- /dev/null +++ b/MusicPlayer2/FilterHelper.cpp @@ -0,0 +1,83 @@ +#include "stdafx.h" +#include "FilterHelper.h" +#include "MusicPlayer2.h" +#include "Playlist.h" +#include "Lyric.h" +#include "AudioCommon.h" + +wstring FilterHelper::GetAudioFileFilter() +{ + wstring filter = theApp.m_str_table.LoadText(L"TXT_FILTER_ALL_SUPPORTED_AUDIO_FORMAT") + BulidExtFilter(CAudioCommon::m_all_surpported_extensions); + for (const auto& format : CAudioCommon::m_surpported_format) + { + filter += format.description; + filter.push_back(L'|'); + filter += format.extensions_list; + filter.push_back(L'|'); + } + filter += theApp.m_str_table.LoadText(L"TXT_FILTER_ALL_FILES") + L"|*.*||"; + return filter; +} + +wstring FilterHelper::GetLyricFileFilter() +{ + wstring filter = theApp.m_str_table.LoadText(L"TXT_FILTER_LYRIC_FILE") + BulidExtFilter(CLyrics::m_surpported_lyric); + filter += theApp.m_str_table.LoadText(L"TXT_FILTER_TXT_FILE") + L"|*.txt|"; + filter += theApp.m_str_table.LoadText(L"TXT_FILTER_ALL_FILES") + L"|*.*||"; + return filter; +} + +wstring FilterHelper::GetSF2FileFilter() +{ + wstring filter = theApp.m_str_table.LoadText(L"TXT_FILTER_SF2_FILE") + L"|*.SF2|"; + filter += theApp.m_str_table.LoadText(L"TXT_FILTER_ALL_FILES") + L"|*.*||"; + return filter; +} + +wstring FilterHelper::GetListenTimeFilter() +{ + wstring filter = theApp.m_str_table.LoadText(L"TXT_FILTER_CSV_FILE") + L"|*.csv|"; + filter += theApp.m_str_table.LoadText(L"TXT_FILTER_ALL_FILES") + L"|*.*||"; + return filter; +} + +wstring FilterHelper::GetPlaylistSelectFilter() +{ + wstring filter = theApp.m_str_table.LoadText(L"TXT_FILTER_ALL_SUPPORTED_PLAYLIST_FILE") + BulidExtFilter(CPlaylistFile::m_surpported_playlist); + filter += theApp.m_str_table.LoadText(L"TXT_FILTER_PLAYLIST_FILE") + L"|*" + PLAYLIST_EXTENSION + L"|"; + filter += theApp.m_str_table.LoadText(L"TXT_FILTER_M3U_FILE") + L"|*.m3u|"; + filter += theApp.m_str_table.LoadText(L"TXT_FILTER_M3U8_FILE") + L"|*.m3u8|"; + filter += theApp.m_str_table.LoadText(L"TXT_FILTER_ALL_FILES") + L"|*.*||"; + return filter; +} + +wstring FilterHelper::GetPlaylistSaveAsFilter() +{ + wstring filter = theApp.m_str_table.LoadText(L"TXT_FILTER_M3U_FILE") + L"|*.m3u|"; + filter += theApp.m_str_table.LoadText(L"TXT_FILTER_M3U8_FILE") + L"|*.m3u8|"; + filter += theApp.m_str_table.LoadText(L"TXT_FILTER_PLAYLIST_FILE") + L"|*" + PLAYLIST_EXTENSION + L"|"; + filter += theApp.m_str_table.LoadText(L"TXT_FILTER_ALL_FILES") + L"|*.*||"; + return filter; +} + +wstring FilterHelper::GetImageFileFilter() +{ + const vector surpported_image = { L"jpg", L"jpeg", L"png", L"bmp", L"gif" }; + wstring filter = theApp.m_str_table.LoadText(L"TXT_FILTER_IMAGE_FILE") + BulidExtFilter(surpported_image); + filter += theApp.m_str_table.LoadText(L"TXT_FILTER_ALL_FILES") + L"|*.*||"; + return filter; +} + +wstring FilterHelper::BulidExtFilter(const vector& ext_list) +{ + ASSERT(!ext_list.empty()); + wstring str{ L"|" }; + for (const wstring& ext : ext_list) + { + ASSERT(!ext.empty()); + str += L"*." + ext + L';'; + } + str.back() = L'|'; + return str; +} + diff --git a/MusicPlayer2/FilterHelper.h b/MusicPlayer2/FilterHelper.h new file mode 100644 index 000000000..49fa9af70 --- /dev/null +++ b/MusicPlayer2/FilterHelper.h @@ -0,0 +1,20 @@ +#pragma once + +class FilterHelper +{ +public: + static wstring GetAudioFileFilter(); + static wstring GetLyricFileFilter(); + static wstring GetSF2FileFilter(); + static wstring GetListenTimeFilter(); + // 获取打开播放列表对话框的filier + static wstring GetPlaylistSelectFilter(); + // 获取播放列表另存为的filier + static wstring GetPlaylistSaveAsFilter(); + static wstring GetImageFileFilter(); + +private: + static wstring BulidExtFilter(const vector& ext_list); + +}; + diff --git a/MusicPlayer2/FindDlg.cpp b/MusicPlayer2/FindDlg.cpp index fb03bc6b2..28b681a86 100644 --- a/MusicPlayer2/FindDlg.cpp +++ b/MusicPlayer2/FindDlg.cpp @@ -3,14 +3,15 @@ #include "stdafx.h" #include "MusicPlayer2.h" +#include "Player.h" #include "FindDlg.h" -#include "afxdialogex.h" #include "MusicPlayerCmdHelper.h" #include "PropertyDlg.h" #include "Playlist.h" #include "AddToPlaylistDlg.h" #include "SongDataManager.h" #include "COSUPlayerHelper.h" +#include "IniHelper.h" // CFindDlg 对话框 @@ -32,6 +33,52 @@ CString CFindDlg::GetDialogName() const return _T("FindDlg"); } +bool CFindDlg::InitializeControls() +{ + wstring temp; + temp = theApp.m_str_table.LoadText(L"TITLE_FIND"); + SetWindowTextW(temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_FIND_KEY_WORD_INPUT"); + SetDlgItemTextW(IDC_TXT_FIND_KEY_WORD_INPUT_STATIC, temp.c_str()); + // IDC_FIND_EDIT + temp = theApp.m_str_table.LoadText(L"TXT_FIND_FIND"); + SetDlgItemTextW(IDC_FIND_BUTTON, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_FIND_FIND_RANGE"); + SetDlgItemTextW(IDC_TXT_FIND_FIND_RANGE_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_FIND_CURRENT_PLAYLIST"); + SetDlgItemTextW(IDC_FIND_CURRENT_PLAYLIST_RADIO, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_FIND_MEDIA_LIB"); + SetDlgItemTextW(IDC_FIND_ALL_PLAYLIST_RADIO, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_FIND_OPT"); + SetDlgItemTextW(IDC_TXT_FIND_OPT_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_FIND_OPT_FILE_NAME"); + SetDlgItemTextW(IDC_FIND_FILE_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_FIND_OPT_TITLE"); + SetDlgItemTextW(IDC_FIND_TITLE_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_FIND_OPT_ARTIST"); + SetDlgItemTextW(IDC_FIND_ARTIST_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_FIND_OPT_ALBUM"); + SetDlgItemTextW(IDC_FIND_ALBUM_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_FIND_RESULT_LAST"); + SetDlgItemTextW(IDC_FIND_RESULT_STATIC, temp.c_str()); + temp = L""; + SetDlgItemTextW(IDC_FIND_INFO_STATIC, temp.c_str()); + // IDC_FIND_LIST + temp = theApp.m_str_table.LoadText(L"TXT_FIND_PLAY_SELECTED"); + SetDlgItemTextW(IDOK, temp.c_str()); + + RepositionTextBasedControls({ + { CtrlTextInfo::L1, IDC_TXT_FIND_KEY_WORD_INPUT_STATIC }, + { CtrlTextInfo::C0, IDC_FIND_EDIT }, + { CtrlTextInfo::R1, IDC_FIND_BUTTON, CtrlTextInfo::W32 } + }, CtrlTextInfo::W128); + RepositionTextBasedControls({ + { CtrlTextInfo::R1, IDOK, CtrlTextInfo::W32 }, + { CtrlTextInfo::R2, IDCANCEL, CtrlTextInfo::W32 } + }); + return true; +} + void CFindDlg::DoDataExchange(CDataExchange* pDX) { CBaseDialog::DoDataExchange(pDX); @@ -60,9 +107,8 @@ void CFindDlg::ShowFindResult() void CFindDlg::ShowFindInfo() { - CString str; - str = CCommon::LoadTextFormat(IDS_FIND_DLG_INFO, { m_key_word, m_find_result.size() }); - SetDlgItemText(IDC_FIND_INFO_STATIC, str); + wstring str = theApp.m_str_table.LoadTextFormat(L"TXT_FIND_RESULT_INFO", { m_key_word, m_find_result.size() }); + SetDlgItemText(IDC_FIND_INFO_STATIC, str.c_str()); ShowDlgCtrl(IDC_FIND_INFO_STATIC, !m_key_word.empty()); } @@ -81,7 +127,7 @@ UINT CFindDlg::ViewOnlineThreadFunc(LPVOID lpParam) CFindDlg* pThis = (CFindDlg*)(lpParam); if (pThis == nullptr) return 0; - CCommon::SetThreadLanguage(theApp.m_general_setting_data.language); + CCommon::SetThreadLanguageList(theApp.m_str_table.GetLanguageTag()); //此命令用于跳转到歌曲对应的网易云音乐的在线页面 SongInfo song{ pThis->m_find_result[pThis->m_item_selected] }; if (CCommon::FileExist(song.file_path)) @@ -157,7 +203,7 @@ BEGIN_MESSAGE_MAP(CFindDlg, CBaseDialog) ON_COMMAND(ID_EXPLORE_ONLINE, &CFindDlg::OnExploreOnline) ON_COMMAND(ID_FORMAT_CONVERT, &CFindDlg::OnFormatConvert) ON_COMMAND(ID_ITEM_PROPERTY, &CFindDlg::OnItemProperty) - ON_COMMAND(ID_ADD_TO_NEW_PALYLIST_AND_PLAY, &CFindDlg::OnAddToNewPalylistAndPlay) + ON_COMMAND(ID_ADD_TO_NEW_PLAYLIST_AND_PLAY, &CFindDlg::OnAddToNewPlaylistAndPlay) ON_WM_INITMENU() ON_COMMAND(ID_DELETE_FROM_DISK, &CFindDlg::OnDeleteFromDisk) ON_COMMAND(ID_PLAY_AS_NEXT, &CFindDlg::OnPlayAsNext) @@ -271,9 +317,9 @@ void CFindDlg::OnBnClickedFindButton() // 显示查找结果 ShowFindResult(); if (!m_find_result.empty()) - SetDlgItemText(IDC_FIND_RESULT_STATIC, CCommon::LoadText(IDS_FIND_RESULT, _T(": "))); + SetDlgItemText(IDC_FIND_RESULT_STATIC, theApp.m_str_table.LoadText(L"TXT_FIND_RESULT_CURRENT").c_str()); else - SetDlgItemText(IDC_FIND_RESULT_STATIC, CCommon::LoadText(IDS_NO_RESULT)); + SetDlgItemText(IDC_FIND_RESULT_STATIC, theApp.m_str_table.LoadText(L"TXT_FIND_RESULT_NONE").c_str()); ShowFindInfo(); } } @@ -285,10 +331,10 @@ BOOL CFindDlg::OnInitDialog() // TODO: 在此添加额外的初始化 - SetIcon(theApp.m_icon_set.find_songs.GetIcon(true), FALSE); - SetIcon(AfxGetApp()->LoadIcon(IDI_FIND_SONGS_D), TRUE); - SetButtonIcon(IDOK, theApp.m_icon_set.play_new.GetIcon(true)); - SetButtonIcon(IDC_FIND_BUTTON, theApp.m_icon_set.find_songs.GetIcon(true)); + SetIcon(IconMgr::IconType::IT_Find, FALSE); + SetIcon(IconMgr::IconType::IT_Find, TRUE); + SetButtonIcon(IDOK, IconMgr::IconType::IT_Play); + SetButtonIcon(IDC_FIND_BUTTON, IconMgr::IconType::IT_Find); //设置查找选项复选按钮的状态 m_find_file_check.SetCheck(m_find_file); @@ -310,12 +356,12 @@ BOOL CFindDlg::OnInitDialog() width0 = theApp.DPI(40); width2 = (list_width - width0) / 5; width1 = list_width - width0 - width2 * 4; - m_find_result_list.InsertColumn(0, CCommon::LoadText(IDS_NUMBER), LVCFMT_LEFT, width0); //插入第0列 - m_find_result_list.InsertColumn(1, CCommon::LoadText(IDS_FILE_NAME), LVCFMT_LEFT, width1); //插入第1列 - m_find_result_list.InsertColumn(2, CCommon::LoadText(IDS_TITLE), LVCFMT_LEFT, width2); //插入第2列 - m_find_result_list.InsertColumn(3, CCommon::LoadText(IDS_ARTIST), LVCFMT_LEFT, width2); //插入第3列 - m_find_result_list.InsertColumn(4, CCommon::LoadText(IDS_ALBUM), LVCFMT_LEFT, width2); //插入第4列 - m_find_result_list.InsertColumn(5, CCommon::LoadText(IDS_FILE_PATH), LVCFMT_LEFT, width2); //插入第5列 + m_find_result_list.InsertColumn(0, theApp.m_str_table.LoadText(L"TXT_SERIAL_NUMBER").c_str(), LVCFMT_LEFT, width0); + m_find_result_list.InsertColumn(1, theApp.m_str_table.LoadText(L"TXT_FILE_NAME").c_str(), LVCFMT_LEFT, width1); + m_find_result_list.InsertColumn(2, theApp.m_str_table.LoadText(L"TXT_TITLE").c_str(), LVCFMT_LEFT, width2); + m_find_result_list.InsertColumn(3, theApp.m_str_table.LoadText(L"TXT_ARTIST").c_str(), LVCFMT_LEFT, width2); + m_find_result_list.InsertColumn(4, theApp.m_str_table.LoadText(L"TXT_ALBUM").c_str(), LVCFMT_LEFT, width2); + m_find_result_list.InsertColumn(5, theApp.m_str_table.LoadText(L"TXT_FILE_PATH").c_str(), LVCFMT_LEFT, width2); ShowFindResult(); //显示(上一次的)查找结果 ShowFindInfo(); @@ -329,11 +375,6 @@ BOOL CFindDlg::OnInitDialog() //设置列表控件的提示总是置顶,用于解决如果弹出此窗口的父窗口具有置顶属性时,提示信息在窗口下面的问题 m_find_result_list.GetToolTips()->SetWindowPos(&CWnd::wndTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - //初始化右键菜单 - //if (m_menu.m_hMenu == NULL) - // m_menu.LoadMenu(IDR_FIND_POPUP_MENU); - //m_menu.GetSubMenu(0)->SetDefaultItem(ID_FD_PLAY); - GetDlgItem(IDOK)->EnableWindow(FALSE); //禁用“播放选中曲目”按钮,除非选中了一个项目 return FALSE; // return TRUE unless you set the focus to a control @@ -475,7 +516,7 @@ void CFindDlg::OnNMRClickFindList(NMHDR* pNMHDR, LRESULT* pResult) sub_item = pNMItemActivate->iSubItem; m_selected_string = m_find_result_list.GetItemText(m_item_selected, sub_item); //弹出右键菜单 - CMenu* pContextMenu = theApp.m_menu_set.m_media_lib_popup_menu.GetSubMenu(1); + CMenu* pContextMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::LibRightMenu); m_find_result_list.ShowPopupMenu(pContextMenu, pNMItemActivate->iItem, this); } @@ -487,7 +528,7 @@ void CFindDlg::OnCopyText() { // TODO: 在此添加命令处理程序代码 if (!CCommon::CopyStringToClipboard(wstring(m_selected_string))) - MessageBox(CCommon::LoadText(IDS_COPY_CLIPBOARD_FAILED), NULL, MB_ICONWARNING); + MessageBox(theApp.m_str_table.LoadText(L"MSG_COPY_CLIPBOARD_FAILED").c_str(), NULL, MB_ICONWARNING); } @@ -497,7 +538,10 @@ void CFindDlg::OnPlayItemInFolderMode() if (m_item_selected >= 0 && m_item_selected < static_cast(m_find_result.size())) { if (!CPlayer::GetInstance().OpenASongInFolderMode(m_find_result[m_item_selected], true)) - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } else OnCancel(); } @@ -550,7 +594,10 @@ void CFindDlg::OnOK() if (selected_track != -1) //如果查找结果是当前播放列表中的曲目,则在当前播放列表中查找选中的曲目,并播放 { if (!CPlayer::GetInstance().PlayTrack(selected_track)) - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } } else { @@ -564,7 +611,10 @@ void CFindDlg::OnOK() else ok = CPlayer::GetInstance().OpenSongsInTempPlaylist(songs); if (!ok) - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } } } @@ -572,14 +622,17 @@ void CFindDlg::OnOK() } -void CFindDlg::OnAddToNewPalylistAndPlay() +void CFindDlg::OnAddToNewPlaylistAndPlay() { // TODO: 在此添加命令处理程序代码 wstring playlist_path; if (_OnAddToNewPlaylist(playlist_path)) { if (!CPlayer::GetInstance().SetPlaylist(playlist_path, 0, 0, true)) - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } else OnCancel(); } @@ -598,7 +651,6 @@ void CFindDlg::OnInitMenu(CMenu* pMenu) bool can_del = !theApp.m_media_lib_setting_data.disable_delete_from_disk && std::find_if(songs.begin(), songs.end(), [&](const SongInfo& song_info) { return song_info.is_cue || COSUPlayerHelper::IsOsuFile(song_info.file_path); }) != songs.end(); - pMenu->SetDefaultItem(ID_PLAY_ITEM); pMenu->EnableMenuItem(ID_PLAY_AS_NEXT, MF_BYCOMMAND | (select_all_in_playing_list ? MF_ENABLED : MF_GRAYED)); pMenu->EnableMenuItem(ID_DELETE_FROM_DISK, MF_BYCOMMAND | (can_del ? MF_ENABLED : MF_GRAYED)); } diff --git a/MusicPlayer2/FindDlg.h b/MusicPlayer2/FindDlg.h index 4138a0a0b..8e3383f61 100644 --- a/MusicPlayer2/FindDlg.h +++ b/MusicPlayer2/FindDlg.h @@ -1,7 +1,5 @@ #pragma once -#include "afxcmn.h" #include "AudioCommon.h" -#include "afxwin.h" #include "ListCtrlEx.h" #include "Common.h" #include "BaseDialog.h" @@ -63,6 +61,7 @@ class CFindDlg : public CBaseDialog CString m_selected_string; virtual CString GetDialogName() const override; + virtual bool InitializeControls() override; virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 void ShowFindResult(); void ShowFindInfo(); @@ -98,7 +97,7 @@ class CFindDlg : public CBaseDialog afx_msg void OnFormatConvert(); afx_msg void OnItemProperty(); virtual void OnOK(); - afx_msg void OnAddToNewPalylistAndPlay(); + afx_msg void OnAddToNewPlaylistAndPlay(); private: public: afx_msg void OnInitMenu(CMenu* pMenu); diff --git a/MusicPlayer2/FlacEncodeCfgDlg.cpp b/MusicPlayer2/FlacEncodeCfgDlg.cpp index 4294d964a..08c161277 100644 --- a/MusicPlayer2/FlacEncodeCfgDlg.cpp +++ b/MusicPlayer2/FlacEncodeCfgDlg.cpp @@ -3,7 +3,6 @@ #include "stdafx.h" #include "MusicPlayer2.h" -#include "afxdialogex.h" #include "FlacEncodeCfgDlg.h" @@ -12,7 +11,7 @@ IMPLEMENT_DYNAMIC(CFlacEncodeCfgDlg, CDialog) CFlacEncodeCfgDlg::CFlacEncodeCfgDlg(CWnd* pParent /*=nullptr*/) - : CDialog(IDD_FLAC_ENCODE_CFG_DIALOG, pParent) + : CBaseDialog(IDD_FLAC_ENCODE_CFG_DIALOG, pParent) { } @@ -21,34 +20,66 @@ CFlacEncodeCfgDlg::~CFlacEncodeCfgDlg() { } +CString CFlacEncodeCfgDlg::GetDialogName() const +{ + return CString(); +} + +bool CFlacEncodeCfgDlg::InitializeControls() +{ + wstring temp; + temp = theApp.m_str_table.LoadText(L"TITLE_ENCODE_OPT_FLAC"); + SetWindowTextW(temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_ENCODE_OPT_FLAC_CMP_LEVEL"); + SetDlgItemTextW(IDC_TXT_ENCODE_OPT_FLAC_CMP_LEVEL_STATIC, temp.c_str()); + // IDC_SLIDER1 + // IDC_COMP_LEVEL_STATIC + temp = theApp.m_str_table.LoadText(L"TXT_ENCODE_OPT_FLAC_CMP_LEVEL_LOW"); + SetDlgItemTextW(IDC_TXT_ENCODE_OPT_FLAC_CMP_LEVEL_LOW_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_ENCODE_OPT_FLAC_CMP_LEVEL_HIGH"); + SetDlgItemTextW(IDC_TXT_ENCODE_OPT_FLAC_CMP_LEVEL_HIGH_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_ENCODE_OPT_FLAC_SPECIFY_PARA"); + SetDlgItemTextW(IDC_SPECIFY_PARA_CHECK, temp.c_str()); + // IDC_EDIT1 + // IDOK + // IDCANCEL + + RepositionTextBasedControls({ + { CtrlTextInfo::L1, IDC_SPECIFY_PARA_CHECK, CtrlTextInfo::W16 }, + { CtrlTextInfo::C0, IDC_EDIT1 } + }, CtrlTextInfo::W128); + RepositionTextBasedControls({ + { CtrlTextInfo::R1, IDOK, CtrlTextInfo::W32 }, + { CtrlTextInfo::R2, IDCANCEL, CtrlTextInfo::W32 } + }); + return true; +} + void CFlacEncodeCfgDlg::DoDataExchange(CDataExchange* pDX) { - CDialog::DoDataExchange(pDX); + CBaseDialog::DoDataExchange(pDX); DDX_Control(pDX, IDC_SLIDER1, m_comp_level_slider); } void CFlacEncodeCfgDlg::SetInfoText() { - CString comp_level; - comp_level.Format(_T("%d"), m_encode_para.compression_level); - SetDlgItemText(IDC_COMP_LEVEL_STATIC, comp_level); + wstring comp_level = std::to_wstring(m_encode_para.compression_level); + SetDlgItemTextW(IDC_COMP_LEVEL_STATIC, comp_level.c_str()); //设置编码参数 - CString str_cmd_para = _T("-") + comp_level; - m_encode_para.cmd_para = str_cmd_para.GetString(); - - SetDlgItemText(IDC_EDIT1, str_cmd_para); + if (!m_encode_para.user_define_para) + m_encode_para.cmd_para = L"-" + comp_level; + SetDlgItemTextW(IDC_EDIT1, m_encode_para.cmd_para.c_str()); } void CFlacEncodeCfgDlg::EnableControl() { - CWnd* edit_control{ GetDlgItem(IDC_EDIT1) }; - if (edit_control != nullptr) - edit_control->EnableWindow(m_encode_para.user_define_para); + EnableDlgCtrl(IDC_SLIDER1, !m_encode_para.user_define_para); + EnableDlgCtrl(IDC_EDIT1, m_encode_para.user_define_para); } -BEGIN_MESSAGE_MAP(CFlacEncodeCfgDlg, CDialog) +BEGIN_MESSAGE_MAP(CFlacEncodeCfgDlg, CBaseDialog) ON_NOTIFY(NM_CUSTOMDRAW, IDC_SLIDER1, &CFlacEncodeCfgDlg::OnNMCustomdrawSlider1) ON_BN_CLICKED(IDC_SPECIFY_PARA_CHECK, &CFlacEncodeCfgDlg::OnBnClickedSpecifyParaCheck) END_MESSAGE_MAP() @@ -59,7 +90,7 @@ END_MESSAGE_MAP() BOOL CFlacEncodeCfgDlg::OnInitDialog() { - CDialog::OnInitDialog(); + CBaseDialog::OnInitDialog(); // TODO: 在此添加额外的初始化 m_comp_level_slider.SetRange(0, 8); @@ -87,6 +118,7 @@ void CFlacEncodeCfgDlg::OnBnClickedSpecifyParaCheck() { // TODO: 在此添加控件通知处理程序代码 m_encode_para.user_define_para = (IsDlgButtonChecked(IDC_SPECIFY_PARA_CHECK) != 0); + SetInfoText(); EnableControl(); } @@ -98,5 +130,5 @@ void CFlacEncodeCfgDlg::OnOK() GetDlgItemText(IDC_EDIT1, str); m_encode_para.cmd_para = str; - CDialog::OnOK(); + CBaseDialog::OnOK(); } diff --git a/MusicPlayer2/FlacEncodeCfgDlg.h b/MusicPlayer2/FlacEncodeCfgDlg.h index b702e34d9..5ee3d740a 100644 --- a/MusicPlayer2/FlacEncodeCfgDlg.h +++ b/MusicPlayer2/FlacEncodeCfgDlg.h @@ -1,11 +1,11 @@ #pragma once -#include "afxdialogex.h" +#include "BaseDialog.h" #include "IPlayerCore.h" // CFlacEncodeCfgDlg 对话框 -class CFlacEncodeCfgDlg : public CDialog +class CFlacEncodeCfgDlg : public CBaseDialog { DECLARE_DYNAMIC(CFlacEncodeCfgDlg) @@ -24,6 +24,10 @@ class CFlacEncodeCfgDlg : public CDialog CSliderCtrl m_comp_level_slider; protected: + virtual CString GetDialogName() const override; + virtual bool IsRememberDialogSizeEnable() const { return false; }; + virtual bool InitializeControls() override; + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 void SetInfoText(); void EnableControl(); diff --git a/MusicPlayer2/FolderBrowserDlg.cpp b/MusicPlayer2/FolderBrowserDlg.cpp index ed9ac6a43..53bd41ba3 100644 --- a/MusicPlayer2/FolderBrowserDlg.cpp +++ b/MusicPlayer2/FolderBrowserDlg.cpp @@ -1,7 +1,6 @@ #include "stdafx.h" #include "FolderBrowserDlg.h" -#include "Common.h" -#include "resource.h" +#include "MusicPlayer2.h" CFolderBrowserDlg::CFolderBrowserDlg(HWND hParent) @@ -36,7 +35,8 @@ int CFolderBrowserDlg::DoModal() { if (!SHGetPathFromIDList(lp, szPath)) { - AfxMessageBox(CCommon::LoadText(IDS_INVALID_DIR_WARNING), MB_ICONWARNING | MB_OK); + static const wstring& info = theApp.m_str_table.LoadText(L"MSG_FOLDER_BROWSER_INVALID_DIR_WARNING"); + AfxMessageBox(info.c_str(), MB_ICONWARNING | MB_OK); goto browse; } m_path = szPath; diff --git a/MusicPlayer2/FolderExploreDlg.cpp b/MusicPlayer2/FolderExploreDlg.cpp index c599afc9b..c470fe50a 100644 --- a/MusicPlayer2/FolderExploreDlg.cpp +++ b/MusicPlayer2/FolderExploreDlg.cpp @@ -3,14 +3,15 @@ #include "stdafx.h" #include "MusicPlayer2.h" +#include "Player.h" #include "FolderExploreDlg.h" -#include "afxdialogex.h" #include "AudioCommon.h" #include "MusicPlayerCmdHelper.h" #include "PropertyDlg.h" #include "Playlist.h" #include "AddToPlaylistDlg.h" #include "SongDataManager.h" +#include "COSUPlayerHelper.h" // CFolderExploreDlg 对话框 @@ -84,16 +85,21 @@ void CFolderExploreDlg::ShowSongList() SetDlgItemText(IDC_PATH_STATIC, m_folder_path_selected.c_str()); //获取歌曲列表 - std::vector files; - CAudioCommon::GetAudioFiles(m_folder_path_selected, files, 20000, false); - int index{}; - CAudioCommon::GetCueTracks(files, CPlayer::GetInstance().GetPlayerCore(), index, false); m_right_items.clear(); - for (const auto& file : files) - { - const SongInfo& song{ CSongDataManager::GetInstance().GetSongInfo3(file) }; - m_right_items.push_back(song); - } + + // 此处在主线程更新cue条目到媒体库并加载歌曲信息,如果有大量cue且没有提前“更新媒体库”第一次进行耗时可能很长 + if (COSUPlayerHelper::IsOsuFolder(m_folder_path_selected)) + COSUPlayerHelper::GetOSUAudioFiles(m_folder_path_selected, m_right_items); + else // 播放左侧目录的OpenFolder包含子文件夹所以这里也包含子文件夹 + CAudioCommon::GetAudioFiles(m_folder_path_selected, m_right_items, MAX_SONG_NUM, true); + + bool exit_flag{}; + int update_cnt{}; + // 这里仍然使用GetCueTracks而不是GetAudioInfo是因为后者涉及忽略短文件设置,实际执行的OpenFolder无视设置加入短文件 + // 我希望此处预览(至少数量上)与OpenFolder结果一致,但不希望只为看一下(预览)就把无关(短)文件加入媒体库 + CAudioCommon::GetCueTracks(m_right_items, update_cnt, exit_flag, MR_MIN_REQUIRED); + // 加载歌曲信息 + CSongDataManager::GetInstance().LoadSongsInfo(m_right_items); //显示到列表控件中 m_list_data.clear(); @@ -221,14 +227,14 @@ BOOL CFolderExploreDlg::OnInitDialog() CMediaLibTabDlg::OnInitDialog(); // TODO: 在此添加额外的初始化 - CCommon::SetDialogFont(this, theApp.m_pMainWnd->GetFont()); //由于此对话框资源由不同语言共用,所以这里要设置一下字体 //为树控件设置图标 - CImageList image_list; - image_list.Create(theApp.DPI(16), theApp.DPI(16), ILC_COLOR32 | ILC_MASK, 2, 2); - image_list.Add(CDrawCommon::LoadIconResource(IDI_EXPLORE_FOLDER, theApp.DPI(16), theApp.DPI(16))); - m_folder_explore_tree.SetImageList(&image_list, TVSIL_NORMAL); - image_list.Detach(); + CSize icon_size = IconMgr::GetIconSize(IconMgr::IconSize::IS_DPI_16); + CImageList ImageList; + ImageList.Create(icon_size.cx, icon_size.cy, ILC_COLOR32 | ILC_MASK, 2, 2); + ImageList.Add(theApp.m_icon_mgr.GetHICON(IconMgr::IconType::IT_Folder, IconMgr::IconStyle::IS_Color, IconMgr::IconSize::IS_DPI_16)); + m_folder_explore_tree.SetImageList(&ImageList, TVSIL_NORMAL); + ImageList.Detach(); //设置行高 m_folder_explore_tree.SetItemHeight(theApp.DPI(22)); @@ -241,25 +247,18 @@ BOOL CFolderExploreDlg::OnInitDialog() //即只有当标签切换到“文件夹浏览”时才填充数据,以加载“媒体库”对话框的打开速度 //ShowFolderTree(); - //// - //CImageList image_list1; - //image_list1.Create(theApp.DPI(16), theApp.DPI(16), ILC_COLOR32 | ILC_MASK, 2, 2); - //image_list1.Add(theApp.LoadIcon(IDI_FILE_ICON)); - //m_song_list_ctrl.SetImageList(&image_list1, LVSIL_SMALL); - //初始化右侧列表 m_song_list_ctrl.SetExtendedStyle(m_song_list_ctrl.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_LABELTIP); //CRect rc_song_list; //m_song_list_ctrl.GetWindowRect(rc_song_list); - m_song_list_ctrl.InsertColumn(0, CCommon::LoadText(IDS_FILE_NAME), LVCFMT_LEFT, theApp.DPI(200)); - m_song_list_ctrl.InsertColumn(1, CCommon::LoadText(IDS_TITLE), LVCFMT_LEFT, theApp.DPI(180)); - m_song_list_ctrl.InsertColumn(2, CCommon::LoadText(IDS_ARTIST), LVCFMT_LEFT, theApp.DPI(100)); - m_song_list_ctrl.InsertColumn(3, CCommon::LoadText(IDS_ALBUM), LVCFMT_LEFT, theApp.DPI(100)); - m_song_list_ctrl.InsertColumn(4, CCommon::LoadText(IDS_FILE_PATH), LVCFMT_LEFT, theApp.DPI(600)); + m_song_list_ctrl.InsertColumn(0, theApp.m_str_table.LoadText(L"TXT_FILE_NAME").c_str(), LVCFMT_LEFT, theApp.DPI(200)); + m_song_list_ctrl.InsertColumn(1, theApp.m_str_table.LoadText(L"TXT_TITLE").c_str(), LVCFMT_LEFT, theApp.DPI(180)); + m_song_list_ctrl.InsertColumn(2, theApp.m_str_table.LoadText(L"TXT_ARTIST").c_str(), LVCFMT_LEFT, theApp.DPI(100)); + m_song_list_ctrl.InsertColumn(3, theApp.m_str_table.LoadText(L"TXT_ALBUM").c_str(), LVCFMT_LEFT, theApp.DPI(100)); + m_song_list_ctrl.InsertColumn(4, theApp.m_str_table.LoadText(L"TXT_FILE_PATH").c_str(), LVCFMT_LEFT, theApp.DPI(600)); m_song_list_ctrl.SetCtrlAEnable(true); - m_search_edit.SetCueBanner(CCommon::LoadText(IDS_SEARCH_FORDER), TRUE); - //SetDlgItemText(IDC_SETTINGS_BUTTON, CCommon::LoadText(IDS_BTN_SETTINGS)); + m_search_edit.SetCueBanner(theApp.m_str_table.LoadText(L"TXT_SEARCH_PROMPT_FORDER").c_str(), TRUE); //初始化分隔条 m_splitter_ctrl.AttachCtrlAsLeftPane(IDC_FOLDER_EXPLORE_TREE); @@ -298,7 +297,7 @@ void CFolderExploreDlg::OnNMRClickFolderExploreTree(NMHDR *pNMHDR, LRESULT *pRes m_folder_explore_tree.GetWindowRect(window_rect); //获取列表控件的矩形区域(以屏幕左上角为原点) point.y = window_rect.top + item_rect.bottom; //设置鼠标要弹出的y坐标为选中项目的下边框位置,防止右键菜单挡住选中的项目 } - CMenu* pMenu = theApp.m_menu_set.m_media_lib_popup_menu.GetSubMenu(0); + CMenu* pMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::LibLeftMenu); pMenu->TrackPopupMenu(TPM_LEFTBUTTON | TPM_LEFTALIGN, point.x, point.y, this); } } @@ -356,7 +355,7 @@ void CFolderExploreDlg::OnNMRClickSongList(NMHDR *pNMHDR, LRESULT *pResult) if(!m_right_selected_items.empty()) { //弹出右键菜单 - CMenu* pMenu = theApp.m_menu_set.m_media_lib_popup_menu.GetSubMenu(1); + CMenu* pMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::LibRightMenu); ASSERT(pMenu != nullptr); if (pMenu != nullptr) { @@ -421,7 +420,11 @@ void CFolderExploreDlg::OnOK() { wstring folder_path{ m_folder_explore_tree.GetItemPath(m_tree_item_selected) }; if (!CPlayer::GetInstance().OpenFolder(folder_path, true, true)) - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } + else { CTabDlg::OnOK(); CWnd* pParent = GetParentWindow(); diff --git a/MusicPlayer2/FormatConvertDlg.cpp b/MusicPlayer2/FormatConvertDlg.cpp index 64166f312..e37912945 100644 --- a/MusicPlayer2/FormatConvertDlg.cpp +++ b/MusicPlayer2/FormatConvertDlg.cpp @@ -3,16 +3,19 @@ #include "stdafx.h" #include "MusicPlayer2.h" +#include "Player.h" #include "FormatConvertDlg.h" -#include "afxdialogex.h" #include "BassCore.h" -#include "COSUPlayerHelper.h" -#include "WIC.h" -#include "TagLibHelper.h" #include "MusicPlayerCmdHelper.h" #include "SongDataManager.h" -#include "PropertyDlgHelper.h" +#include "FileNameFormDlg.h" +#include "MP3EncodeCfgDlg.h" +#include "WmaEncodeCfgDlg.h" +#include "OggEncodeCfgDlg.h" #include "FlacEncodeCfgDlg.h" +#include "FilterHelper.h" +#include "IniHelper.h" +#include "TagEditDlg.h" #define MAX_ALBUM_COVER_SIZE (128 * 1024) //编码器支持的最大专辑封面大小 #define CONVERT_TEMP_ALBUM_COVER_NAME L"cover_R1hdyFy6CoEK7Gu8" //临时的专辑封面文件名 @@ -44,33 +47,39 @@ CFormatConvertDlg::CFormatConvertDlg(const vector& items, CWnd* pParen : CBaseDialog(IDD_FORMAT_CONVERT_DIALOG, pParent) { //获取文件列表 - for (auto item : items) + for (SongInfo item : items) { - CAudioCommon::ClearDefaultTagStr(item); - if (CAudioCommon::GetAudioTypeByFileName(item.file_path) == AU_MIDI) - { - //如果文件是 MIDI 音乐,则把SF2音色库信息添加到注释信息 - CString comment; - comment.Format(_T("Converted from MIDI by MusicPlayer2. SF2: %s"), CPlayer::GetInstance().GetSoundFontName().c_str()); - item.comment = comment; - } - if (!CCommon::IsItemInVector(m_file_list, [&](const SongInfo& song) - { - if (!song.is_cue) - return item.file_path == song.file_path; - else - return (item.file_path == song.file_path && item.track == song.track); - })) - m_file_list.push_back(item); + item.Normalize(); + m_file_list.push_back(std::move(item)); + } + // 确保音频文件信息更新到媒体库,并解析cue,(对于大量不存在于媒体库的新文件此方法很慢) + int cnt{}, percent{}; + bool exit_flag{ false }; + CAudioCommon::GetAudioInfo(m_file_list, cnt, exit_flag, percent, MR_MIN_REQUIRED, false); + // 去重 + std::unordered_set song_key; + song_key.reserve(m_file_list.size()); + auto new_end = std::remove_if(m_file_list.begin(), m_file_list.end(), + [&](const SongInfo& song) { return !song_key.emplace(song).second; }); // emplace失败说明此项目已存在,返回true移除当前项目 + m_file_list.erase(new_end, m_file_list.end()); + // 加载歌曲信息(与播放列表一致) + CSongDataManager::GetInstance().LoadSongsInfo(m_file_list); + + //如果文件是 MIDI 音乐,则把SF2音色库信息添加到注释信息 + wstring midi_comment = L"Converted from MIDI by MusicPlayer2. SF2: " + CPlayer::GetInstance().GetSoundFontName(); + for (auto& song : m_file_list) + { + if (CAudioCommon::GetAudioTypeByFileName(song.file_path) == AU_MIDI) + song.comment = midi_comment; } - m_freq_map[L"8 kHz"] = 8000; - m_freq_map[L"16 kHz"] = 16000; - m_freq_map[L"22 kHz"] = 22050; - m_freq_map[L"24 kHz"] = 24000; - m_freq_map[L"32 kHz"] = 32000; - m_freq_map[L"44.1 kHz"] = 44100; - m_freq_map[L"48 kHz"] = 48000; + m_freq_map.emplace_back(L"8 kHz", 8000); + m_freq_map.emplace_back(L"16 kHz", 16000); + m_freq_map.emplace_back(L"22 kHz", 22050); + m_freq_map.emplace_back(L"24 kHz", 24000); + m_freq_map.emplace_back(L"32 kHz", 32000); + m_freq_map.emplace_back(L"44.1 kHz", 44100); + m_freq_map.emplace_back(L"48 kHz", 48000); } CFormatConvertDlg::~CFormatConvertDlg() @@ -84,6 +93,72 @@ CString CFormatConvertDlg::GetDialogName() const } +bool CFormatConvertDlg::InitializeControls() +{ + wstring temp; + temp = theApp.m_str_table.LoadText(L"TITLE_FORMAT_CONVERT"); + SetWindowTextW(temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_OUT_FORMAT_SEL"); + SetDlgItemTextW(IDC_TXT_FORMAT_CONVERT_OUT_FORMAT_SEL_STATIC, temp.c_str()); + // IDC_OUT_FORMAT_COMBO + temp = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_SETTING"); + SetDlgItemTextW(IDC_ENCODER_CONFIG_BUTTON, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_FILE_LIST"); + SetDlgItemTextW(IDC_TXT_FORMAT_CONVERT_FILE_LIST_STATIC, temp.c_str()); + // IDC_SONG_LIST1 + temp = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_OPT"); + SetDlgItemTextW(IDC_TXT_FORMAT_CONVERT_OPT_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_CHANGE_FREQ"); + SetDlgItemTextW(IDC_CHANGE_FREQ_CHECK, temp.c_str()); + // IDC_FREQ_COMBO + temp = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_COPY_TAG"); + SetDlgItemTextW(IDC_COPY_TAG_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_COPY_COVER"); + SetDlgItemTextW(IDC_COPY_ALBUM_COVER_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_OUT_FILE_NAME"); + SetDlgItemTextW(IDC_TXT_FORMAT_CONVERT_OUT_FILE_NAME_STATIC, temp.c_str()); + // IDC_OUT_NAME_EDIT + temp = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_ADD_SERIAL_NUMBER"); + SetDlgItemTextW(IDC_ADD_NUMBER_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_FILE_EXIST_SEL"); + SetDlgItemTextW(IDC_TXT_FORMAT_CONVERT_FILE_EXIST_SEL_STATIC, temp.c_str()); + // IDC_TARGET_FILE_EXIST_COMBO + temp = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_OUT_DIR"); + SetDlgItemTextW(IDC_TXT_FORMAT_CONVERT_OUT_DIR_STATIC, temp.c_str()); + // IDC_OUT_DIR_EDIT + temp = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_OUT_DIR_OPEN_WHEN_COMPLETE"); + SetDlgItemTextW(IDC_OPEN_TARGET_DIR_CHECK, temp.c_str()); + temp = L""; + SetDlgItemTextW(IDC_PROGRESS_BAR, temp.c_str()); // 此控件持有的文本会影响接下来的重排,需要先清空 + SetDlgItemTextW(IDC_PROGRESS_TEXT, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_START_CONVERT"); + SetDlgItemTextW(IDC_START_CONVERT_BUTTON, temp.c_str()); + // IDCANCEL + + RepositionTextBasedControls({ + { CtrlTextInfo::L1, IDC_TXT_FORMAT_CONVERT_OUT_FORMAT_SEL_STATIC }, + { CtrlTextInfo::C0, IDC_OUT_FORMAT_COMBO }, + { CtrlTextInfo::R1, IDC_ENCODER_CONFIG_BUTTON, CtrlTextInfo::W32 } + }, CtrlTextInfo::W128); + RepositionTextBasedControls({ + { CtrlTextInfo::L2, IDC_CHANGE_FREQ_CHECK, CtrlTextInfo::W32 }, + { CtrlTextInfo::L1, IDC_FREQ_COMBO } + }); + RepositionTextBasedControls({ + { CtrlTextInfo::L1, IDC_TXT_FORMAT_CONVERT_OUT_FILE_NAME_STATIC }, + { CtrlTextInfo::C0, IDC_OUT_NAME_EDIT }, + { CtrlTextInfo::L1, IDC_TXT_FORMAT_CONVERT_OUT_DIR_STATIC }, + { CtrlTextInfo::C0, IDC_OUT_DIR_EDIT } + }, CtrlTextInfo::W128); + RepositionTextBasedControls({ + { CtrlTextInfo::L1, IDC_PROGRESS_BAR }, + { CtrlTextInfo::C0, IDC_PROGRESS_TEXT }, + { CtrlTextInfo::R1, IDC_START_CONVERT_BUTTON, CtrlTextInfo::W32 }, + { CtrlTextInfo::R2, IDCANCEL, CtrlTextInfo::W32 } + }, CtrlTextInfo::W128); + return true; +} + void CFormatConvertDlg::DoDataExchange(CDataExchange* pDX) { CBaseDialog::DoDataExchange(pDX); @@ -108,7 +183,7 @@ void CFormatConvertDlg::LoadConfig() { m_out_dir = CCommon::GetSpecialDir(CSIDL_MYDOCUMENTS); } - m_out_name = ini.GetString(L"format_convert", L"out_name_formular", FORMULAR_ORIGINAL); + m_out_name = ini.GetString(L"format_convert", L"out_name_formular", CFileNameFormDlg::FORMULAR_ORIGINAL.c_str()); m_convert_freq = ini.GetBool(L"format_convert", L"convert_freq", false); m_freq_sel = ini.GetString(L"format_convert", L"freq_sel", L""); m_open_output_dir = ini.GetBool(L"format_convert", L"open_output_dir", false); @@ -135,11 +210,21 @@ void CFormatConvertDlg::LoadEncoderConfig() CIniHelper ini(theApp.m_config_dir + L"Encoder\\encoder.ini"); m_mp3_encode_para.encode_type = ini.GetInt(L"mp3_encoder", L"encode_type", 0); - m_mp3_encode_para.cbr_bitrate = ini.GetString(L"mp3_encoder", L"cbr_bitrate", L"128"); - m_mp3_encode_para.abr_bitrate = ini.GetString(L"mp3_encoder", L"abr_bitrate", L"128"); + m_mp3_encode_para.cbr_bitrate = ini.GetInt(L"mp3_encoder", L"cbr_bitrate", 128); + m_mp3_encode_para.abr_bitrate = ini.GetInt(L"mp3_encoder", L"abr_bitrate", 128); m_mp3_encode_para.vbr_quality = ini.GetInt(L"mp3_encoder", L"vbr_quality", 4); m_mp3_encode_para.cmd_para = ini.GetString(L"mp3_encoder", L"cmd_para", L""); m_mp3_encode_para.joint_stereo = ini.GetBool(L"mp3_encoder", L"joint_stereo", true); + if (m_mp3_encode_para.encode_type == 3) // 旧版兼容 + { + m_mp3_encode_para.encode_type = 0; + m_mp3_encode_para.cmd_para.clear(); + } + if (!m_mp3_encode_para.cmd_para.empty()) + { + m_mp3_encode_para.user_define_para = true; + } + CMP3EncodeCfgDlg::EncodeParaToCmdline(m_mp3_encode_para); m_wma_encode_para.cbr = ini.GetBool(L"wma_encoder", L"cbr", true); m_wma_encode_para.cbr_bitrate = ini.GetInt(L"wma_encoder", L"cbr_bitrate", 64); @@ -159,10 +244,10 @@ void CFormatConvertDlg::SaveEncoderConfig() const CIniHelper ini(encoder_dir + L"encoder.ini"); ini.WriteInt(L"mp3_encoder", L"encode_type", m_mp3_encode_para.encode_type); - ini.WriteString(L"mp3_encoder", L"cbr_bitrate", m_mp3_encode_para.cbr_bitrate); - ini.WriteString(L"mp3_encoder", L"abr_bitrate", m_mp3_encode_para.abr_bitrate); + ini.WriteInt(L"mp3_encoder", L"cbr_bitrate", m_mp3_encode_para.cbr_bitrate); + ini.WriteInt(L"mp3_encoder", L"abr_bitrate", m_mp3_encode_para.abr_bitrate); ini.WriteInt(L"mp3_encoder", L"vbr_quality", m_mp3_encode_para.vbr_quality); - ini.WriteString(L"mp3_encoder", L"cmd_para", m_mp3_encode_para.cmd_para); + ini.WriteString(L"mp3_encoder", L"cmd_para", m_mp3_encode_para.user_define_para ? m_mp3_encode_para.cmd_para : L""); ini.WriteBool(L"mp3_encoder", L"joint_stereo", m_mp3_encode_para.joint_stereo); ini.WriteBool(L"wma_encoder", L"cbr", m_wma_encode_para.cbr); @@ -218,10 +303,10 @@ BOOL CFormatConvertDlg::OnInitDialog() // TODO: 在此添加额外的初始化 CenterWindow(); - SetIcon(theApp.m_icon_set.convert, FALSE); - SetIcon(AfxGetApp()->LoadIcon(IDI_CONVERT_D), true); - SetButtonIcon(IDC_ENCODER_CONFIG_BUTTON, theApp.m_icon_set.setting.GetIcon(true)); - SetButtonIcon(IDC_START_CONVERT_BUTTON, theApp.m_icon_set.convert); + SetIcon(IconMgr::IconType::IT_Convert, FALSE); + SetIcon(IconMgr::IconType::IT_Convert, TRUE); + SetButtonIcon(IDC_ENCODER_CONFIG_BUTTON, IconMgr::IconType::IT_Setting); + SetButtonIcon(IDC_START_CONVERT_BUTTON, IconMgr::IconType::IT_Convert); LoadConfig(); LoadEncoderConfig(); @@ -230,13 +315,6 @@ BOOL CFormatConvertDlg::OnInitDialog() if (!CPlayer::GetInstance().GetPlayerCore()->IsFreqConvertAvailable()) m_convert_freq = false; - //初始化菜单 - m_list_popup_menu.LoadMenu(IDR_FORMAT_CONVERT_POPUP_MENU); - CMenuIcon::AddIconToMenuItem(m_list_popup_menu.GetSafeHmenu(), ID_ADD_FILE, FALSE, theApp.m_icon_set.add.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_list_popup_menu.GetSafeHmenu(), ID_EDIT_TAG_INFO, FALSE, theApp.m_icon_set.edit.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_list_popup_menu.GetSafeHmenu(), ID_DELETE_SELECT, FALSE, theApp.m_icon_set.close.GetIcon(true)); - - //初始化文件列表 CRect rect; m_file_list_ctrl.GetWindowRect(rect); @@ -244,9 +322,9 @@ BOOL CFormatConvertDlg::OnInitDialog() width1 = rect.Width() - width0 - width2 - theApp.DPI(20) - 1; //插入列 m_file_list_ctrl.SetExtendedStyle(m_file_list_ctrl.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_LABELTIP); - m_file_list_ctrl.InsertColumn(0, CCommon::LoadText(IDS_NUMBER), LVCFMT_LEFT, width0); //插入第1列 - m_file_list_ctrl.InsertColumn(1, CCommon::LoadText(IDS_FILE_NAME), LVCFMT_LEFT, width1); //插入第2列 - m_file_list_ctrl.InsertColumn(2, CCommon::LoadText(IDS_CONVERTING_STATE), LVCFMT_LEFT, width2); //插入第3列 + m_file_list_ctrl.InsertColumn(0, theApp.m_str_table.LoadText(L"TXT_SERIAL_NUMBER").c_str(), LVCFMT_LEFT, width0); + m_file_list_ctrl.InsertColumn(1, theApp.m_str_table.LoadText(L"TXT_FILE_NAME").c_str(), LVCFMT_LEFT, width1); + m_file_list_ctrl.InsertColumn(2, theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_STAUS").c_str(), LVCFMT_LEFT, width2); //插入项目 ShowFileList(); //设置主题颜色 @@ -254,7 +332,7 @@ BOOL CFormatConvertDlg::OnInitDialog() //初始化转换格式的下拉列表 m_encode_format_combo.AddString(_T("WAV")); - m_encode_format_combo.AddString(CCommon::LoadText(IDS_MP3_LAME_ENCODER)); + m_encode_format_combo.AddString(theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_ENCODER_NAME_MP3_LAME").c_str()); m_encode_format_combo.AddString(_T("WMA")); m_encode_format_combo.AddString(_T("OGG")); m_encode_format_combo.AddString(_T("FLAC")); @@ -265,19 +343,23 @@ BOOL CFormatConvertDlg::OnInitDialog() ((CButton*)GetDlgItem(IDC_COPY_ALBUM_COVER_CHECK))->SetCheck(m_write_album_cover); ((CButton*)GetDlgItem(IDC_ADD_NUMBER_CHECK))->SetCheck(m_add_file_serial_num); CComboBox* file_exist_combo = (CComboBox*)GetDlgItem(IDC_TARGET_FILE_EXIST_COMBO); - file_exist_combo->AddString(CCommon::LoadText(IDS_AUTO_RENAME)); - file_exist_combo->AddString(CCommon::LoadText(IDS_IGNORE)); - file_exist_combo->AddString(CCommon::LoadText(IDS_OVERWRITE)); + file_exist_combo->AddString(theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_FILE_EXIST_AUTO_RENAME").c_str()); + file_exist_combo->AddString(theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_FILE_EXIST_IGNORE").c_str()); + file_exist_combo->AddString(theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_FILE_EXIST_OVERWRITE").c_str()); file_exist_combo->SetCurSel(m_file_exist_action); ((CButton*)GetDlgItem(IDC_OPEN_TARGET_DIR_CHECK))->SetCheck(m_open_output_dir); - - for (const auto& item : m_freq_map) - m_freq_comb.AddString(item.first.c_str()); - if (m_freq_sel.empty()) - m_freq_comb.SelectString(0, _T("44.1 kHz")); - else - m_freq_comb.SelectString(0, m_freq_sel.c_str()); + int freq_comb_sel{ -1 }; + for (size_t i{}; i < m_freq_map.size(); ++i) + { + m_freq_comb.AddString(m_freq_map[i].first.c_str()); + if (m_freq_map[i].first == m_freq_sel) + freq_comb_sel = i; + if (m_freq_map[i].second == 44100) // 默认值 + m_freq_comb.SetCurSel(i); + } + if (freq_comb_sel != -1) + m_freq_comb.SetCurSel(freq_comb_sel); m_freq_comb.EnableWindow(m_convert_freq); ((CButton*)GetDlgItem(IDC_CHANGE_FREQ_CHECK))->SetCheck(m_convert_freq); @@ -287,8 +369,7 @@ BOOL CFormatConvertDlg::OnInitDialog() if (!m_out_dir.empty() && m_out_dir.back() != L'\\') m_out_dir.push_back(L'\\'); m_out_dir_edit.SetWindowText(m_out_dir.c_str()); - m_out_dir_edit.EnableFolderBrowseButton(CCommon::LoadText(IDS_SELECT_OUTPUT_FOLDER)); - SetDlgItemText(IDC_PROGRESS_TEXT, _T("")); + m_out_dir_edit.EnableFolderBrowseButton(theApp.m_str_table.LoadText(L"TITLE_FOLDER_BROWSER_OUTPUT_FOLDER").c_str()); m_progress_bar.SetBackgroundColor(GetSysColor(COLOR_BTNFACE)); m_progress_bar.ShowWindow(SW_HIDE); @@ -307,14 +388,8 @@ BOOL CFormatConvertDlg::OnInitDialog() void CFormatConvertDlg::EnableControls(bool enable) { GetDlgItem(IDC_OUT_FORMAT_COMBO)->EnableWindow(enable); - //GetDlgItem(IDC_BROWSE_BUTTON)->EnableWindow(enable); GetDlgItem(IDC_START_CONVERT_BUTTON)->EnableWindow(enable); GetDlgItem(IDC_ENCODER_CONFIG_BUTTON)->EnableWindow(enable); - //GetDlgItem(IDC_ADD_BUTTON)->EnableWindow(enable); - //GetDlgItem(IDC_DELETE_BUTTON)->EnableWindow(enable); - //GetDlgItem(IDC_CLEAR_BUTTON)->EnableWindow(enable); - //GetDlgItem(IDC_MOVE_UP_BUTTON)->EnableWindow(enable); - //GetDlgItem(IDC_MOVE_DOWN_BUTTON)->EnableWindow(enable); GetDlgItem(IDC_COPY_TAG_CHECK)->EnableWindow(enable); GetDlgItem(IDC_TARGET_FILE_EXIST_COMBO)->EnableWindow(enable); GetDlgItem(IDC_COPY_ALBUM_COVER_CHECK)->EnableWindow(enable); @@ -376,8 +451,8 @@ bool CFormatConvertDlg::EncodeSingleFile(CFormatConvertDlg* pthis, int file_inde out_file_path += index_str; } - // 按照格式字符串生成输出文件名 - out_file_path += CPropertyDlgHelper::FileNameFromTag(pthis->m_out_name, song_info); + // 按照格式字符串生成输出文件名(这里缺少长度检查) + out_file_path += CFileNameFormDlg::FileNameFromTag(pthis->m_out_name, song_info); // 按照输出格式添加后缀 switch (pthis->m_encode_format) @@ -489,25 +564,23 @@ bool CFormatConvertDlg::EncodeSingleFile(CFormatConvertDlg* pthis, int file_inde void CFormatConvertDlg::SetProgressInfo(int progress) { - CString info; + wstring info; if (progress >= 100) - info = CCommon::LoadText(IDS_COMPLEATE); + info = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_PROGRESS_INFO_COMPLEATE"); else - info = CCommon::LoadTextFormat(IDS_PROGRESS_INFO, { progress }); - SetDlgItemText(IDC_PROGRESS_TEXT, info); + info = theApp.m_str_table.LoadTextFormat(L"TXT_FORMAT_CONVERT_PROGRESS_INFO", { progress }); + SetDlgItemText(IDC_PROGRESS_TEXT, info.c_str()); } int CFormatConvertDlg::GetFreq() { - CString str; - m_freq_comb.GetWindowText(str); - - return m_freq_map[str.GetString()]; + int sel_index = m_freq_comb.GetCurSel(); + return m_freq_map[sel_index].second; } UINT CFormatConvertDlg::ThreadFunc(LPVOID lpParam) { - CCommon::SetThreadLanguage(theApp.m_general_setting_data.language); + CCommon::SetThreadLanguageList(theApp.m_str_table.GetLanguageTag()); CFormatConvertDlg* pThis{ (CFormatConvertDlg*)lpParam }; for (size_t i{}; i < pThis->m_file_list.size(); i++) { @@ -521,11 +594,6 @@ UINT CFormatConvertDlg::ThreadFunc(LPVOID lpParam) return 0; } -bool CFormatConvertDlg::IsTaskbarListEnable() const -{ - return CWinVersionHelper::IsWindows7OrLater() && m_pTaskbar != nullptr; -} - void CFormatConvertDlg::OnCbnSelchangeOutFormatCombo() { @@ -544,25 +612,25 @@ void CFormatConvertDlg::OnBnClickedStartConvertButton() if (!m_encoder_succeed) { CBassCore* bass_core = dynamic_cast(CPlayer::GetInstance().GetPlayerCore()); - CString info; + wstring info; if (bass_core != nullptr) - info = CCommon::LoadTextFormat(IDS_BASS_ENCODER_LOAD_ERROR, { bass_core->GetEncoderDir() + L"bassenc.dll" }); + info = theApp.m_str_table.LoadTextFormat(L"MSG_FORMAT_CONVERT_BASS_LOAD_ERROR", { bass_core->GetEncoderDir() + L"bassenc.dll" }); else - info = CCommon::LoadText(IDS_IDS_ENCODER_INIT_ERROR); - MessageBox(info, NULL, MB_ICONERROR | MB_OK); + info = theApp.m_str_table.LoadText(L"MSG_FORMAT_CONVERT_INIT_ERROR"); + MessageBox(info.c_str(), NULL, MB_ICONERROR | MB_OK); return; } if (m_out_dir.empty()) { - MessageBox(CCommon::LoadText(IDS_SET_OUTPUT_DIR_INFO), NULL, MB_ICONWARNING | MB_OK); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_FORMAT_CONVERT_SET_OUTPUT_DIR"); + MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK); return; } else if (!CCommon::FolderExist(m_out_dir)) { - CString info; - info = CCommon::LoadTextFormat(IDS_OUTPUT_DIR_NOT_EXIST, { m_out_dir }); - MessageBox(info, NULL, MB_ICONWARNING | MB_OK); + wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_FORMAT_CONVERT_OUTPUT_DIR_NOT_EXIST", { m_out_dir }); + MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK); } //先清除“状态”一列的内容 @@ -576,91 +644,55 @@ void CFormatConvertDlg::OnBnClickedStartConvertButton() //创建格式转换的工作线程 m_pThread = AfxBeginThread(ThreadFunc, this); m_thread_runing = true; -#ifndef COMPILE_IN_WIN_XP - if (IsTaskbarListEnable()) - m_pTaskbar->SetProgressState(this->GetSafeHwnd(), TBPF_INDETERMINATE); -#endif + if (theApp.IsTaskbarInteractionEnabled()) + theApp.GetITaskbarList3()->SetProgressState(this->GetSafeHwnd(), TBPF_INDETERMINATE); } -//void CFormatConvertDlg::OnBnClickedBrowseButton() -//{ -// // TODO: 在此添加控件通知处理程序代码 -//#ifdef COMPILE_IN_WIN_XP -// CFolderBrowserDlg folderPickerDlg(this->GetSafeHwnd()); -// folderPickerDlg.SetInfo(CCommon::LoadText(IDS_SELECT_OUTPUT_FOLDER)); -//#else -// CFolderPickerDialog folderPickerDlg(m_out_dir.c_str()); -// folderPickerDlg.m_ofn.lpstrTitle = CCommon::LoadText(IDS_SELECT_OUTPUT_FOLDER); //设置对话框标题 -//#endif // COMPILE_IN_WIN_XP -// if (folderPickerDlg.DoModal() == IDOK) -// { -// m_out_dir = folderPickerDlg.GetPathName(); -// if (m_out_dir.back() != L'\\') m_out_dir.push_back(L'\\'); //确保路径末尾有反斜杠 -// SetDlgItemText(IDC_OUT_DIR_EDIT, m_out_dir.c_str()); -// } -// -//} - - afx_msg LRESULT CFormatConvertDlg::OnConvertProgress(WPARAM wParam, LPARAM lParam) { - CString percent_str; + wstring status_str; int percent = (int)lParam; if (percent == 0) m_file_list_ctrl.EnsureVisible(wParam, FALSE); //转换开始时,确保当前列表项可见 if (percent < 0) { //显示错误信息 - percent_str += CCommon::LoadText(IDS_ERROR); - percent_str += L": "; - if (percent == CONVERT_ERROR_FILE_CONNOT_OPEN) - percent_str += CCommon::LoadText(IDS_CONVERT_ERROR_FILE_CONNOT_OPEN); + if (percent == CONVERT_ERROR_FILE_CANNOT_OPEN) + status_str = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_STAUS_ERROR_FILE_CANNOT_OPEN"); else if (percent == CONVERT_ERROR_ENCODE_CHANNEL_FAILED) - percent_str += CCommon::LoadText(IDS_CONVERT_ERROR_ENCODE_CHANNEL_FAILED); + status_str = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_STAUS_ERROR_ENCODE_CHANNEL_FAILED"); else if (percent == CONVERT_ERROR_ENCODE_PARA_ERROR) - percent_str += CCommon::LoadText(IDS_CONVERT_ERROR_ENCODE_PARA_ERROR); + status_str = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_STAUS_ERROR_ENCODE_PARA_ERROR"); else if (percent == CONVERT_ERROR_MIDI_NO_SF2) - percent_str += CCommon::LoadText(IDS_CONVERT_ERROR_MIDI_NO_SF2); + status_str = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_STAUS_ERROR_MIDI_NO_SF2"); else if (percent == CONVERT_ERROR_WMA_NO_WMP9_OR_LATER) - { - percent_str += CCommon::LoadText(IDS_CONVERT_ERROR_ENCODE_CHANNEL_FAILED); - percent_str += _T(": "); - percent_str += CCommon::LoadText(IDS_NO_WMP9_OR_LATER); - } + status_str = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_STAUS_ERROR_NO_WMP9_OR_LATER"); else if (percent == CONVERT_ERROR_WMA_NO_SUPPORTED_ENCODER) - { - percent_str += CCommon::LoadText(IDS_CONVERT_ERROR_ENCODE_CHANNEL_FAILED); - percent_str += _T(": "); - percent_str += CCommon::LoadText(IDS_NO_SUPPORTED_ENCODER_WARNING); - } + status_str = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_STAUS_ERROR_NO_SUPPORTED_ENCODER"); else - percent_str += std::to_wstring(percent).c_str(); + status_str = theApp.m_str_table.LoadTextFormat(L"TXT_FORMAT_CONVERT_STAUS_ERROR_OTHER", { percent }); } else if (percent == 101) { - percent_str = CCommon::LoadText(IDS_COMPLEATE); + status_str = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_STAUS_COMPLEATE"); } else if (percent == 102) { - percent_str = CCommon::LoadText(IDS_SKIPED1); + status_str = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_STAUS_SKIPED"); } else { - percent_str.Format(_T("%d%%"), (int)lParam); + status_str = std::to_wstring(static_cast(lParam)) + L'%'; } - m_file_list_ctrl.SetItemText(wParam, 2, percent_str); + m_file_list_ctrl.SetItemText(wParam, 2, status_str.c_str()); //总体的进度 int position, length; length = m_file_list.size() * 100; position = wParam * 100 + percent; -#ifndef COMPILE_IN_WIN_XP - if (IsTaskbarListEnable()) - { - m_pTaskbar->SetProgressValue(this->GetSafeHwnd(), position, length); - } -#endif + if (theApp.IsTaskbarInteractionEnabled()) + theApp.GetITaskbarList3()->SetProgressValue(this->GetSafeHwnd(), position, length); int total_percent = position * 100 / length; static int last_percent = -1; if (last_percent != total_percent) @@ -803,7 +835,7 @@ void CFormatConvertDlg::OnNMRClickSongList1(NMHDR* pNMHDR, LRESULT* pResult) LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast(pNMHDR); // TODO: 在此添加控件通知处理程序代码 m_item_selected = pNMItemActivate->iItem; //获取鼠标选中的项目 - CMenu* pContextMenu = m_list_popup_menu.GetSubMenu(0); //获取第一个弹出菜单 + CMenu* pContextMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::FcListMenu); m_file_list_ctrl.ShowPopupMenu(pContextMenu, pNMItemActivate->iItem, this); *pResult = 0; @@ -816,74 +848,47 @@ void CFormatConvertDlg::OnAddFile() if (m_thread_runing) return; //设置过滤器 - wstring filter(CCommon::LoadText(IDS_ALL_SUPPORTED_FORMAT, _T("|"))); - for (const auto& ext : CAudioCommon::m_all_surpported_extensions) - { - filter += L"*."; - filter += ext; - filter.push_back(L';'); - } - filter.pop_back(); - filter.push_back(L'|'); - for (const auto& format : CAudioCommon::m_surpported_format) - { - filter += format.description; - filter.push_back(L'|'); - filter += format.extensions_list; - filter.push_back(L'|'); - } - filter += CCommon::LoadText(IDS_ALL_FILES, _T("|*.*||")); + wstring filter = FilterHelper::GetAudioFileFilter(); //构造打开文件对话框 CFileDialog fileDlg(TRUE, NULL, NULL, OFN_ALLOWMULTISELECT, filter.c_str(), this); //设置保存文件名的字符缓冲的大小为128kB(如果以平均一个文件名长度为32字节计算,最多可以打开大约4096个文件) fileDlg.m_ofn.nMaxFile = 128 * 1024; - LPTSTR ch = new TCHAR[fileDlg.m_ofn.nMaxFile]; - fileDlg.m_ofn.lpstrFile = ch; - //对内存块清零 - ZeroMemory(fileDlg.m_ofn.lpstrFile, sizeof(TCHAR) * fileDlg.m_ofn.nMaxFile); + std::vector buffer(fileDlg.m_ofn.nMaxFile); + fileDlg.m_ofn.lpstrFile = buffer.data(); //显示打开文件对话框 if (IDOK == fileDlg.DoModal()) { - POSITION posFile = fileDlg.GetStartPosition(); - while (posFile != NULL) + wchar_t* pos = buffer.data(); + wchar_t* end = pos + buffer.size(); + while (pos < end && *pos != L'\0') { - SongInfo item; - CString file_path = fileDlg.GetNextPathName(posFile); - item = CSongDataManager::GetInstance().GetSongInfo(wstring(file_path)); - if (!item.info_acquired) //如果歌曲没有获取过信息,则重新获取 - { - HSTREAM hStream; - hStream = BASS_StreamCreateFile(FALSE, item.file_path.c_str(), 0, 0, BASS_SAMPLE_FLOAT); - BASS_CHANNELINFO channel_info; - BASS_ChannelGetInfo(hStream, &channel_info); - if (CAudioCommon::GetAudioTypeByBassChannel(channel_info.ctype) != AU_MIDI) - { - bool is_osu = COSUPlayerHelper::IsOsuFile(item.file_path); - if (is_osu) - { - item.file_path = item.file_path; - COSUPlayerHelper::GetOSUAudioTitleArtist(item); - } - else - { - CBassCore::GetBASSAudioInfo(hStream, item); - } - //CPlayer::AcquireSongInfo(hStream, item.file_path, item); - } - BASS_StreamFree(hStream); - } - if (!CCommon::IsItemInVector(m_file_list, [&](const SongInfo song) - { - if (!song.is_cue) - return item.file_path == song.file_path; - else - return (item.file_path == song.file_path && item.track == song.track); - })) - m_file_list.push_back(item); + wstring file_name(pos); + // 将指针移动到下一个文件名的起始位置 + pos += file_name.size() + 1; + m_file_list.push_back(SongInfo(file_name)); + } + // 音频文件信息更新到媒体库,并解析cue,(对于大量不存在于媒体库的新文件此方法很慢) + int cnt{}, percent{}; + bool exit_flag{ false }; + CAudioCommon::GetAudioInfo(m_file_list, cnt, exit_flag, percent, MR_MIN_REQUIRED, false); + // 去重 + std::unordered_set song_key; + song_key.reserve(m_file_list.size()); + auto new_end = std::remove_if(m_file_list.begin(), m_file_list.end(), + [&](const SongInfo& song) { return !song_key.emplace(song).second; }); // emplace失败说明此项目已存在,返回true移除当前项目 + m_file_list.erase(new_end, m_file_list.end()); + // 加载歌曲信息(与播放列表一致) + CSongDataManager::GetInstance().LoadSongsInfo(m_file_list); + //如果文件是 MIDI 音乐,则把SF2音色库信息添加到注释信息 + wstring midi_comment = L"Converted from MIDI by MusicPlayer2. SF2: " + CPlayer::GetInstance().GetSoundFontName(); + for (auto& song : m_file_list) + { + if (CAudioCommon::GetAudioTypeByFileName(song.file_path) == AU_MIDI) + song.comment = midi_comment; } + // 刷新显示 ShowFileList(); } - delete[] ch; } @@ -1032,7 +1037,10 @@ void CFormatConvertDlg::OnBnClickedChangeFreqCheck() m_convert_freq = false; CBassCore* bass_core = dynamic_cast(CPlayer::GetInstance().GetPlayerCore()); if (bass_core != nullptr) - MessageBox(CCommon::LoadTextFormat(IDS_BASS_MIX_LOAD_ERROR, { bass_core->GetEncoderDir() + L"bassmix.dll" }), NULL, MB_ICONWARNING | MB_OK); + { + wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_FORMAT_CONVERT_BASS_MIX_LOAD_ERROR", { bass_core->GetEncoderDir() + L"bassmix.dll" }); + MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK); + } pBtn->SetCheck(FALSE); } diff --git a/MusicPlayer2/FormatConvertDlg.h b/MusicPlayer2/FormatConvertDlg.h index e9ddd77e0..8dedaf2b1 100644 --- a/MusicPlayer2/FormatConvertDlg.h +++ b/MusicPlayer2/FormatConvertDlg.h @@ -1,16 +1,9 @@ #pragma once +#include "BaseDialog.h" +#include "IPlayerCore.h" #include "ListCtrlEx.h" -#include "AudioTag.h" -#include "MP3EncodeCfgDlg.h" -#include "OggEncodeCfgDlg.h" -#include "WmaEncodeCfgDlg.h" -#include "TagEditDlg.h" -#include "FolderBrowserDlg.h" #include "PlayerProgressBar.h" -#include #include "BrowseEdit.h" -#include "MusicPlayer2.h" -#include "BaseDialog.h" //单个文件转换进度的消息 @@ -36,8 +29,6 @@ class CFormatConvertDlg : public CBaseDialog //工作线程函数 static UINT ThreadFunc(LPVOID lpParam); - bool IsTaskbarListEnable() const; - // 对话框数据 #ifdef AFX_DESIGN_TIME enum { IDD = IDD_FORMAT_CONVERT_DIALOG }; @@ -48,15 +39,10 @@ class CFormatConvertDlg : public CBaseDialog CListCtrlEx m_file_list_ctrl; CComboBox m_encode_format_combo; CPlayerProgressBar m_progress_bar; - CMenu m_list_popup_menu; CComboBox m_freq_comb; CBrowseEdit m_out_dir_edit; CBrowseEdit m_out_name_edit; -//#ifndef COMPILE_IN_WIN_XP - ITaskbarList3* m_pTaskbar{ theApp.GetITaskbarList3() }; //用于支持任务栏显示播放进度 -//#endif - vector m_file_list; // 要转换格式的文件列表 wstring m_out_dir; // 输出目录 wstring m_out_name; // 输出文件名格式字符串 @@ -82,9 +68,10 @@ class CFormatConvertDlg : public CBaseDialog wstring m_freq_sel{}; //采样频率下拉列表中的选中项 bool m_open_output_dir{ false }; //转换完成后打开输出目录 - std::map m_freq_map; + vector> m_freq_map; virtual CString GetDialogName() const override; + virtual bool InitializeControls() override; virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 void LoadConfig(); diff --git a/MusicPlayer2/GetTagOnlineDlg.cpp b/MusicPlayer2/GetTagOnlineDlg.cpp index 0150fb5a1..b319f5e06 100644 --- a/MusicPlayer2/GetTagOnlineDlg.cpp +++ b/MusicPlayer2/GetTagOnlineDlg.cpp @@ -1,8 +1,6 @@ -#include "stdafx.h" -#include "GetTagOnlineDlg.h" -#include "Resource.h" -#include "Player.h" +#include "stdafx.h" #include "MusicPlayer2.h" +#include "GetTagOnlineDlg.h" CGetTagOnlineDlg::CGetTagOnlineDlg(const SongInfo& song, CWnd * pParent) : CCoverDownloadDlg(pParent), m_song_info(song) @@ -24,7 +22,6 @@ void CGetTagOnlineDlg::OnBnClickedDownloadSelected() if (m_item_selected < 0 || m_item_selected >= static_cast(m_down_list.size())) return; m_item_info = m_down_list[m_item_selected]; - CPlayer::GetInstance().SetRelatedSongID(m_item_info.id); //ѡĿĸID if (m_pParentWnd != nullptr) { @@ -43,14 +40,12 @@ BOOL CGetTagOnlineDlg::OnInitDialog() { CCoverDownloadDlg::OnInitDialog(); - // TODO: ڴӶijʼ - SetIcon(theApp.m_icon_set.info.GetIcon(true), FALSE); - - SetWindowText(CCommon::LoadText(IDS_GET_TAG_ONLINE_TITLE)); + // TODO: 在此添加额外的初始化 + SetIcon(IconMgr::IconType::IT_Info, FALSE); + + SetWindowText(theApp.m_str_table.LoadText(L"TITLE_GET_TAG_ONLINE").c_str()); - CWnd* pGetInfoBtn = GetDlgItem(IDC_DOWNLOAD_SELECTED); - if (pGetInfoBtn != nullptr) - pGetInfoBtn->SetWindowText(CCommon::LoadText(IDS_GET_THIS)); + SetDlgItemTextW(IDC_DOWNLOAD_SELECTED, theApp.m_str_table.LoadText(L"TXT_GET_TAG_ONLINE_GET_THIS").c_str()); ShowDlgCtrl(IDC_DOWNLOAD_OPTION_GROUPBOX, false); ShowDlgCtrl(IDC_COVER_LOCATION_STATIC, false); @@ -58,5 +53,5 @@ BOOL CGetTagOnlineDlg::OnInitDialog() ShowDlgCtrl(IDC_SAVE_TO_ALBUM_FOLDER2, false); return TRUE; // return TRUE unless you set the focus to a control - // 쳣: OCX ҳӦ FALSE + // 异常: OCX 属性页应返回 FALSE } diff --git a/MusicPlayer2/GetTagOnlineDlg.h b/MusicPlayer2/GetTagOnlineDlg.h index 6cdb7b3c2..419ffb00c 100644 --- a/MusicPlayer2/GetTagOnlineDlg.h +++ b/MusicPlayer2/GetTagOnlineDlg.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include "CoverDownloadDlg.h" #include "InternetCommon.h" class CGetTagOnlineDlg : public CCoverDownloadDlg diff --git a/MusicPlayer2/Help.txt b/MusicPlayer2/Help.txt deleted file mode 100644 index 1bb52db1a..000000000 Binary files a/MusicPlayer2/Help.txt and /dev/null differ diff --git a/MusicPlayer2/Help_en_us.txt b/MusicPlayer2/Help_en_us.txt deleted file mode 100644 index 112f09701..000000000 Binary files a/MusicPlayer2/Help_en_us.txt and /dev/null differ diff --git a/MusicPlayer2/IPlayerCore.h b/MusicPlayer2/IPlayerCore.h index 5c40276e3..953e88b16 100644 --- a/MusicPlayer2/IPlayerCore.h +++ b/MusicPlayer2/IPlayerCore.h @@ -40,12 +40,13 @@ enum PlayingState //正在播放标志 //MP3编码参数 struct MP3EncodePara { - int encode_type{ 0 }; //0:CBR, 1:ABR, 2:VBR, 3:自定义参数 - wstring cbr_bitrate{ L"128" }; //CBR比特率 - wstring abr_bitrate{ L"128" }; //ABR比特率 - int vbr_quality{ 4 }; //VBR质量(0~9) + int encode_type{ 0 }; // 0:CBR, 1:ABR, 2:VBR, (更改:<3:自定义参数>不再使用,但加载配置时保持兼容) + int cbr_bitrate{ 128 }; // CBR比特率 + int abr_bitrate{ 128 }; // ABR比特率 + int vbr_quality{ 4 }; // VBR质量(0~9) bool joint_stereo{ true }; - wstring cmd_para; //命令行参数 + bool user_define_para{ false }; // 使用用户自定义参数(此项不保存,当ini中cmd_para非空时加载为true) + wstring cmd_para; // 命令行参数 }; //wma 编码参数 @@ -74,7 +75,7 @@ struct FlacEncodePara enum class EncodeFormat { WAV, MP3, WMA, OGG, FLAC }; //格式转换错误代码 -#define CONVERT_ERROR_FILE_CONNOT_OPEN (-1) //源文件无法读取 +#define CONVERT_ERROR_FILE_CANNOT_OPEN (-1) //源文件无法读取 #define CONVERT_ERROR_ENCODE_CHANNEL_FAILED (-2) //编码通道创建失败 #define CONVERT_ERROR_ENCODE_PARA_ERROR (-3) //找不到编码器或编码器参数错误 #define CONVERT_ERROR_MIDI_NO_SF2 (-4) //没有MIDI音色库 @@ -109,8 +110,11 @@ class IPlayerCore virtual int GetCurPosition() = 0; //获取当前播放进度,单位为毫秒 virtual int GetSongLength() = 0; //获取歌曲长度,单位为毫秒 virtual void SetCurPosition(int position) = 0; //设置播放进度,单位为毫秒 - virtual void GetAudioInfo(SongInfo& song_info, int flag = AF_LENGTH | AF_BITRATE | AF_TAG_INFO) = 0; //获取打开的音频的长度、比特率和标签信息,flag用于指定获取哪些信息 - virtual void GetAudioInfo(const wchar_t* file_path, SongInfo& song_info, int flag = AF_LENGTH | AF_BITRATE | AF_TAG_INFO) = 0; //获取指定音频文件的长度、比特率和标签信息 + // 获取打开的音频的长度、比特率和标签信息,flag用于指定获取哪些信息 + virtual void GetAudioInfo(SongInfo& song_info, int flag = AF_LENGTH | AF_BITRATE | AF_TAG_INFO | AF_CHANNEL_INFO) = 0; + // 获取file_path属性写入song_info,flag用于指定获取哪些信息(需要支持并发且不影响当前播放) + // AF_LENGTH读取文件时长直接写入end_pos,AF_BITRATE读取比特率,AF_TAG_INFO读取标签/分级,AF_CHANNEL_INFO读取采样率/位深度/通道数 + virtual void GetAudioInfo(const wchar_t* file_path, SongInfo& song_info, int flag = AF_LENGTH | AF_BITRATE | AF_TAG_INFO | AF_CHANNEL_INFO) = 0; /** * @brief 音频编码的回调函数 diff --git a/MusicPlayer2/IPropertyTabDlg.h b/MusicPlayer2/IPropertyTabDlg.h index f8b519433..701b1876c 100644 --- a/MusicPlayer2/IPropertyTabDlg.h +++ b/MusicPlayer2/IPropertyTabDlg.h @@ -1,4 +1,6 @@ #pragma once +#include "TabDlg.h" + class IPropertyTabDlg { public: diff --git a/MusicPlayer2/IconMgr.cpp b/MusicPlayer2/IconMgr.cpp new file mode 100644 index 000000000..d70a36ad7 --- /dev/null +++ b/MusicPlayer2/IconMgr.cpp @@ -0,0 +1,292 @@ +#include "stdafx.h" +#include "IconMgr.h" +#include "MusicPlayer2.h" + +IconMgr::IconMgr() {} + +IconMgr::~IconMgr() {} + +HICON IconMgr::GetHICON(IconType type, IconStyle style, IconSize size) +{ + if (type == IT_NO_ICON) + return NULL; + int key = MakeKey(type, style, size); + { // 加读锁查找缓存的HICON + std::shared_lock readLock(m_shared_mutex); + auto iter = m_icon_map.find(key); + if (iter != m_icon_map.end()) + return iter->second; + } + { // 缓存中不存在时加写锁加载HICON + std::unique_lock writeLock(m_shared_mutex); + auto iter = m_icon_map.find(key); // 避免并发问题此处需要先再次检查 + if (iter != m_icon_map.end()) + return iter->second; + + auto [id_dark, id_light, id_filled, id_color] = GetIconID(type); + UINT id{}; + switch (style) + { + case IconMgr::IS_OutlinedDark: id = id_dark; break; + case IconMgr::IS_OutlinedLight: id = id_light; break; + case IconMgr::IS_Filled: id = id_filled; break; + case IconMgr::IS_Color: id = id_color; break; + default: break; + } + // 没有要求的风格时fallback到其他风格 + if (!id) id = id_color; + if (!id) id = id_dark; + if (!id) id = id_light; + if (!id) id = id_filled; + + HICON hIcon = NULL; + if (id) + { + int width = GetIconWidth(size); + if (width) + hIcon = (HICON)LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(id), IMAGE_ICON, width, width, 0); + else + hIcon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(id)); // 全量加载所有分辨率 + } + m_icon_map.emplace(key, hIcon); // 即使hIcon为NULL也保存, 这表示当前的图标不存在 + return hIcon; + } +} + +int IconMgr::GetIconWidth(IconSize size) +{ + if (size == IS_ALL) + return 0; + int width; + switch (size) + { + case IS_DPI_16: case IS_DPI_16_Full_Screen: width = theApp.DPI(16); break; + case IS_DPI_20: case IS_DPI_20_Full_Screen: width = theApp.DPI(20); break; + case IS_DPI_32: case IS_DPI_32_Full_Screen: width = theApp.DPI(32); break; + case IS_ORG_512: width = 512; break; + default: width = theApp.DPI(16); break; // 系统默认小图标大小 SM_CXICON * SM_CYICON + } + if (size == IS_DPI_16_Full_Screen || size == IS_DPI_20_Full_Screen || size == IS_DPI_32_Full_Screen) + width = static_cast(width * CONSTVAL::FULL_SCREEN_ZOOM_FACTOR); + if (width < 32) + width = CCommon::IconSizeNormalize(width); + return width; +} + +std::tuple IconMgr::GetIconID(IconType type) +{ + switch (type) + { // return { 深色的图标, 浅色的图标, 填充风格图标, 彩色图标 }; + case IconMgr::IconType::IT_App: +#ifdef _DEBUG + return { NULL, NULL, NULL, IDI_APP_DEBUG }; +#else + return { NULL, NULL, NULL, IDR_MAINFRAME }; +#endif + case IconMgr::IconType::IT_App_Monochrome: + return { IDI_APP_DARK, IDI_APP_LIGHT, NULL, NULL }; + case IconMgr::IconType::IT_Stop: + return { IDI_STOP_NEW_D, IDI_STOP_NEW, IDI_STOP, NULL }; + case IconMgr::IconType::IT_Play: + return { IDI_PLAY_NEW_D, IDI_PLAY_NEW, IDI_PLAY, NULL }; + case IconMgr::IconType::IT_Pause: + return { IDI_PAUSE_NEW_D, IDI_PAUSE_NEW, IDI_PAUSE, NULL }; + case IconMgr::IconType::IT_Play_Pause: + return { IDI_PLAY_PAUSE_D, NULL, IDI_PLAY_PAUSE, NULL }; + case IconMgr::IconType::IT_Previous: + return { IDI_PREVIOUS_NEW_D, IDI_PREVIOUS_NEW, IDI_PREVIOUS, NULL }; + case IconMgr::IconType::IT_Next: + return { IDI_NEXT_NEW_D, IDI_NEXT_NEW, IDI_NEXT1, NULL }; + case IconMgr::IconType::IT_Favorite_On: + return { IDI_FAVOURITE_D, IDI_FAVOURITE, NULL, NULL }; + case IconMgr::IconType::IT_Favorite_Off: + return { NULL, NULL, NULL, IDI_HEART }; + case IconMgr::IconType::IT_Media_Lib: + return { IDI_MEDIA_LIB_D, IDI_MEDIA_LIB, NULL, NULL }; + case IconMgr::IconType::IT_Playlist: + return { IDI_PLAYLIST_D, IDI_PLAYLIST, NULL, NULL }; + case IconMgr::IconType::IT_Menu: + return { IDI_MENU_D, IDI_MENU, NULL, NULL }; + case IconMgr::IconType::IT_Full_Screen_On: + return { IDI_FULL_SCREEN1_D, IDI_FULL_SCREEN1, NULL, NULL }; + case IconMgr::IconType::IT_Full_Screen_Off: + return { IDI_FULL_SCREEN_D, IDI_FULL_SCREEN, NULL, NULL }; + case IconMgr::IconType::IT_Minimize: + return { IDI_MINIMIZE_D, IDI_MINIMIZE, NULL, NULL }; + case IconMgr::IconType::IT_Maxmize_On: + return { IDI_MAXIMIZE_D, IDI_MAXIMIZE, NULL, NULL }; + case IconMgr::IconType::IT_Maxmize_Off: + return { IDI_RESTORE_D, IDI_RESTORE, NULL, NULL }; + case IconMgr::IconType::IT_Close: + return { IDI_CLOSE_D, IDI_CLOSE, NULL, NULL }; + case IconMgr::IconType::IT_Play_Order: + return { IDI_PLAY_ORDER_D, IDI_PLAY_ORDER, NULL, NULL }; + case IconMgr::IconType::IT_Loop_Playlist: + return { IDI_LOOP_PLAYLIST_D, IDI_LOOP_PLAYLIST, NULL, NULL }; + case IconMgr::IconType::IT_Loop_Track: + return { IDI_LOOP_TRACK_D, IDI_LOOP_TRACK, NULL, NULL }; + case IconMgr::IconType::IT_Play_Shuffle: + return { IDI_PLAY_SHUFFLE_D, IDI_PLAY_SHUFFLE, NULL, NULL }; + case IconMgr::IconType::IT_Play_Random: + return { IDI_PLAY_RANDOM_D, IDI_PLAY_RANDOM, NULL, NULL }; + case IconMgr::IconType::IT_Play_Track: + return { IDI_PLAY_TRACK_D, IDI_PLAY_TRACK, NULL, NULL }; + case IconMgr::IconType::IT_Setting: + return { IDI_SETTING_D, IDI_SETTING, NULL, NULL }; + case IconMgr::IconType::IT_Equalizer: + return { IDI_EQ_D, IDI_EQ, NULL, NULL }; + case IconMgr::IconType::IT_Skin: + return { IDI_SKIN_D, IDI_SKIN, NULL, NULL }; + case IconMgr::IconType::IT_Mini_On: + return { IDI_MINI_D, IDI_MINI, NULL, NULL }; + case IconMgr::IconType::IT_Mini_Off: + return { IDI_MINI_RESTORE_D, IDI_MINI_RESTORE, NULL, NULL }; + case IconMgr::IconType::IT_Info: + return { IDI_SONG_INFO_D, IDI_SONG_INFO, NULL, NULL }; + case IconMgr::IconType::IT_Find: + return { IDI_FIND_SONGS_D, IDI_FIND_SONGS, NULL, NULL }; + case IconMgr::IconType::IT_Dark_Mode_On: + return { IDI_DARK_MODE_D, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Dark_Mode_Off: + return { NULL, IDI_LIGHT_MODE, NULL, NULL }; + case IconMgr::IconType::IT_Volume0: + return { IDI_VOLUME0_D, IDI_VOLUME0, NULL, NULL }; + case IconMgr::IconType::IT_Volume1: + return { IDI_VOLUME1_D, IDI_VOLUME1, NULL, NULL }; + case IconMgr::IconType::IT_Volume2: + return { IDI_VOLUME2_D, IDI_VOLUME2, NULL, NULL }; + case IconMgr::IconType::IT_Volume3: + return { IDI_VOLUME3_D, IDI_VOLUME3, NULL, NULL }; + case IconMgr::IconType::IT_Switch_Display: + return { IDI_SWITCH_D, IDI_SWITCH, NULL, NULL }; + case IconMgr::IconType::IT_Folder: + return { IDI_SELECT_FOLDER_D, IDI_SELECT_FOLDER, NULL, IDI_EXPLORE_FOLDER }; + case IconMgr::IconType::IT_Music: + return { IDI_MUSIC_D, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Link: + return { IDI_LINK_D, IDI_LINK, NULL, NULL }; + case IconMgr::IconType::IT_Exit: + return { IDI_EXIT_D, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Rewind: + return { IDI_REW_NEW_D, NULL, IDI_REW, NULL }; + case IconMgr::IconType::IT_Fast_Forward: + return { IDI_FF_NEW_D, NULL, IDI_FF, NULL }; + case IconMgr::IconType::IT_Speed_Up: + return { IDI_SPEED_UP_D, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Slow_Down: + return { IDI_SLOW_DOWN_D, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Add: + return { IDI_ADD_D, IDI_ADD, NULL, NULL }; + case IconMgr::IconType::IT_Save: + return { IDI_SAVE_NEW_D, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Save_As: + return { IDI_SAVE_AS_D, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Sort_Mode: + return { IDI_SORT_D, IDI_SORT, NULL, NULL }; + case IconMgr::IconType::IT_Playlist_Display_Mode: + return { IDI_DISPLAY_MODE_D, IDI_DISPLAY_MODE, NULL, NULL }; + case IconMgr::IconType::IT_Locate: + return { IDI_LOCATE_D, IDI_LOCATE, NULL, NULL }; + case IconMgr::IconType::IT_Lyric: + return { IDI_LYRIC_D, IDI_LYRIC, NULL, NULL }; + case IconMgr::IconType::IT_Copy: + return { IDI_COPY, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Edit: + return { IDI_EDIT_D, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Unlink: + return { IDI_UNLINK_D, IDI_UNLINK, NULL, NULL }; + case IconMgr::IconType::IT_Folder_Explore: + return { IDI_FOLDER_EXPLORE_D, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Internal_Lyric: + return { IDI_INTERNAL_LYRIC_D, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Download: + return { IDI_DOWNLOAD_D, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Download_Batch: + return { IDI_DOWNLOAD1_D, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Playlist_Dock: + return { IDI_PLAYLIST_DOCK_D, IDI_PLAYLIST_DOCK, NULL, NULL }; + case IconMgr::IconType::IT_Playlist_Float: + return { IDI_PLAYLIST_FLOAT_D, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Pin: + return { IDI_PIN_D, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Convert: + return { IDI_CONVERT_D, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Online: + return { IDI_ONLINE_D, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Shortcut: + return { IDI_SHORTCUT_D, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Album_Cover: + return { IDI_ALBUM_COVER_D, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Statistics: + return { IDI_STATISTICS_D, NULL, NULL, NULL }; + case IconMgr::IconType::IT_File_Relate: + return { IDI_FILE_RELATE_D, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Help: + return { IDI_HELP_D, IDI_HELP, NULL, NULL }; + case IconMgr::IconType::IT_Fix: + return { IDI_FIX_D, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Star: + return { IDI_STAR, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Artist: + return { IDI_ARTIST_D, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Album: + return { IDI_ALBUM_D, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Genre: + return { IDI_GENRE_D, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Year: + return { IDI_YEAR_D, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Bitrate: + return { IDI_BITRATE, NULL, NULL, NULL }; + case IconMgr::IconType::IT_History: + return { IDI_RECENT_SONG_D, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Key_Board: + return { IDI_HOT_KEY, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Reverb: + return { IDI_REVERB, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Double_Line: + return { IDI_DOUBLE_LINE_D, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Lock: + return { IDI_LOCK_D, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Play_As_Next: + return { IDI_PLAY_AS_NEXT, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Rename: + return { IDI_RENAME_D, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Play_In_Playlist: + return { IDI_PLAY_IN_PLAYLIST, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Play_In_Folder: + return { IDI_PLAY_IN_FOLDER, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Tag: + return { IDI_TAG, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Le_Tag_Insert: + return { NULL, NULL, NULL, IDI_ADD_TAG }; + case IconMgr::IconType::IT_Le_Tag_Replace: + return { NULL, NULL, NULL, IDI_REPLACE_TAG }; + case IconMgr::IconType::IT_Le_Tag_Delete: + return { NULL, NULL, NULL, IDI_DELETE_TAG }; + case IconMgr::IconType::IT_Le_Save: + return { NULL, NULL, NULL, IDI_SAVE }; + case IconMgr::IconType::IT_Le_Find: + return { NULL, NULL, NULL, IDI_FIND }; + case IconMgr::IconType::IT_Le_Replace: + return { NULL, NULL, NULL, IDI_REPLACE }; + case IconMgr::IconType::IT_Triangle_Left: + return { IDI_LYRIC_DELAY_D, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Triangle_Up: + return { IDI_UP_D, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Triangle_Right: + return { IDI_LYRIC_FORWARD_D, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Triangle_Down: + return { IDI_EXPAND_D, IDI_EXPAND, NULL, NULL }; + case IconMgr::IconType::IT_Ok: + return { IDI_OK_D, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Cancel: + return { IDI_CLOSE_D, NULL, NULL, NULL }; + case IconMgr::IconType::IT_Default_Cover_Playing: + return { NULL, NULL, NULL, IDI_DEFAULT_COVER }; + case IconMgr::IconType::IT_Default_Cover_Stopped: + return { NULL, NULL, NULL, IDI_DEFAULT_COVER_NOT_PLAYED }; + default: + return { NULL, NULL, NULL, NULL }; + } +} + diff --git a/MusicPlayer2/IconMgr.h b/MusicPlayer2/IconMgr.h new file mode 100644 index 000000000..8edecb101 --- /dev/null +++ b/MusicPlayer2/IconMgr.h @@ -0,0 +1,167 @@ +#pragma once +class IconMgr +{ +public: + IconMgr(); + virtual ~IconMgr(); + + enum IconType + { // 命名以其(点击时的)功能为准 + IT_App, // 应用图标 + IT_App_Monochrome, // 应用图标(单色) + IT_Stop, // 停止 + IT_Play, // 播放 + IT_Pause, // 暂停 + IT_Play_Pause, // 播放/暂停 + IT_Previous, // 上一曲 + IT_Next, // 下一曲 + IT_Favorite_On, // 添加到我喜欢的音乐(空心♥) + IT_Favorite_Off, // 从我喜欢的音乐移除(实心♥) + IT_Media_Lib, // 媒体库 + IT_Playlist, // 播放列表 + + IT_Menu, // 菜单 + IT_Full_Screen_On, // 进入全屏 + IT_Full_Screen_Off, // 退出全屏 + IT_Minimize, // 最小化 + IT_Maxmize_On, // 进入最大化 + IT_Maxmize_Off, // 退出最大化 + IT_Close, // 关闭 + + IT_Play_Order, // 顺序播放 + IT_Loop_Playlist, // 列表循环 + IT_Loop_Track, // 单曲循环 + IT_Play_Shuffle, // 无序播放 + IT_Play_Random, // 随机播放 + IT_Play_Track, // 单曲播放 + IT_Setting, // 设置 + IT_Equalizer, // 均衡器 + IT_Skin, // 切换界面(皮肤) + IT_Mini_On, // 进入迷你模式 + IT_Mini_Off, // 退出迷你模式 + IT_Info, // 曲目信息 + IT_Find, // 查找歌曲 + IT_Dark_Mode_On, // 进入深色模式(月亮) + IT_Dark_Mode_Off, // 退出深色模式(太阳) + IT_Volume0, // 音量: 静音 + IT_Volume1, // 音量: ) + IT_Volume2, // 音量: )) + IT_Volume3, // 音量: ))) + IT_Switch_Display, // 切换显示(xml界面堆栈元素) + + IT_Folder, // 文件夹 + IT_Music, // 音符/打开文件 + IT_Link, // 曲别针/链接 + IT_Exit, // 退出 + IT_Rewind, // 快退 + IT_Fast_Forward, // 快进 + IT_Speed_Up, // 加速播放 + IT_Slow_Down, // 减速播放 + IT_Add, // 添加 + IT_Save, // 保存 + IT_Save_As, // 另存为 + IT_Sort_Mode, // 排序模式 + IT_Playlist_Display_Mode, // 播放列表显示方式 + IT_Locate, // 定位 + IT_Lyric, // 歌词 + IT_Copy, // 复制 + IT_Edit, // 编辑 + IT_Unlink, // 取消关联 + IT_Folder_Explore, // 文件夹浏览/搜索 + IT_Internal_Lyric, // 内嵌歌词 + IT_Download, // 下载 + IT_Download_Batch, // 批量下载 + IT_Playlist_Dock, // 停靠播放列表/视图 + IT_Playlist_Float, // 浮动播放列表 + IT_Pin, // 图钉/置顶 + IT_Convert, // 格式转换 + IT_Online, // 在线查看 + IT_Shortcut, // 快捷方式 + IT_Album_Cover, // 专辑封面 + IT_Statistics, // 统计 + IT_File_Relate, // 文件关联 + IT_Help, // 帮助 + IT_Fix, // 扳手/修复 + IT_Star, // 星星/分级 + IT_Artist, // 艺术家 + IT_Album, // 专辑 + IT_Genre, // 流派 + IT_Year, // 年份 + IT_Bitrate, // 比特率 + IT_History, // 最近播放 + IT_Key_Board, // 快捷键 + IT_Reverb, // 混响 + IT_Double_Line, // 双行 + IT_Lock, // 锁/桌面歌词锁定 + IT_Play_As_Next, // 下一首播放 + IT_Rename, // 重命名 + IT_Play_In_Playlist, // 添加到新播放列表并播放 + IT_Play_In_Folder, // 在文件夹模式中播放 + IT_Tag, // 标签 + + IT_Le_Tag_Insert, // Le 插入时间标签 + IT_Le_Tag_Replace, // Le 替换时间标签 + IT_Le_Tag_Delete, // Le 删除时间标签 + IT_Le_Save, // Le 保存 + IT_Le_Find, // Le 文本查找 + IT_Le_Replace, // Le 文本替换 + + IT_Triangle_Left, // 向左三角形 + IT_Triangle_Up, // 向上三角形 + IT_Triangle_Right, // 向右三角形 + IT_Triangle_Down, // 向下三角形 + + IT_Ok, // 圆/确认 + IT_Cancel, // 叉/取消 + + IT_Default_Cover_Playing, // 默认封面(播放中) + IT_Default_Cover_Stopped, // 默认封面(已停止) + + IT_NO_ICON, + }; + + enum IconStyle + { + IS_Auto, + IS_OutlinedDark, // 深色的图标(浅色模式用) + IS_OutlinedLight, // 浅色的图标(深色模式用) + IS_Filled, + IS_Color, + }; + + enum IconSize + { + IS_DPI_16, + IS_DPI_16_Full_Screen, + IS_DPI_20, + IS_DPI_20_Full_Screen, + IS_DPI_32, + IS_DPI_32_Full_Screen, + IS_ORG_512, + IS_ALL, + }; + + // 获取需要的图标,不要在代码中大量直接调用 + // 请为同类调用提供一层包装以免之后修改困难 + HICON GetHICON(IconType type, IconStyle style = IS_Auto, IconSize size = IS_DPI_16); + + static CSize GetIconSize(IconSize size) + { + int width = GetIconWidth(size); + return CSize(width, width); + } + static int GetIconWidth(IconSize size); + +private: + + int MakeKey(IconType type, IconStyle style, IconSize size) + { + ASSERT(style < 10 && size < 10); + return type * 100 + style * 10 + size; + } + std::tuple GetIconID(IconType type); + + std::map m_icon_map; + std::shared_mutex m_shared_mutex; // 线程同步对象 +}; + diff --git a/MusicPlayer2/IniHelper.cpp b/MusicPlayer2/IniHelper.cpp index d6364cb22..a200b2da8 100644 --- a/MusicPlayer2/IniHelper.cpp +++ b/MusicPlayer2/IniHelper.cpp @@ -6,22 +6,26 @@ CIniHelper::CIniHelper(const wstring& file_path) { m_file_path = file_path; ifstream file_stream{ file_path }; - if (file_stream.fail()) - { + if (!file_stream.is_open()) return; - } - //读取文件内容 + // 获取文件大小 + file_stream.seekg(0, std::ios::end); + size_t file_size = static_cast(file_stream.tellg()); + file_stream.seekg(0, std::ios::beg); + // 读取文件内容 string ini_str; - while (!file_stream.eof()) - { - ini_str.push_back(file_stream.get()); - } - ini_str.pop_back(); - if (!ini_str.empty() && ini_str.back() != L'\n') //确保文件末尾有回车符 + ini_str.resize(file_size + 1); + file_stream.read(&ini_str[0], file_size); + // 检查并添加末尾的空行 + if (!ini_str.empty() && ini_str.back() != L'\n') ini_str.push_back(L'\n'); + // 转换成Unicode + m_ini_str = CCommon::StrToUnicode(ini_str, CodeType::AUTO); +} - //转换成Unicode - m_ini_str = CCommon::StrToUnicode(ini_str.c_str(), CodeType::AUTO); +CIniHelper::CIniHelper(UINT id, CodeType code_type) +{ + m_ini_str = CCommon::GetTextResource(id, code_type); } @@ -190,25 +194,103 @@ void CIniHelper::WriteValue(const wchar_t* AppName, const wchar_t* KeyName, CVar } +vector CIniHelper::GetAllAppName(const wstring& prefix) const +{ + vector list; + size_t pos{}; + while ((pos = m_ini_str.find(L"\n[" + prefix, pos)) != wstring::npos) + { + size_t end = m_ini_str.find(L']', pos + 1); + if (end != wstring::npos) + { + wstring tmp(m_ini_str.begin() + pos + prefix.size() + 2, m_ini_str.begin() + end); + list.push_back(std::move(tmp)); + pos = end + 1; + } + } + return list; +} + +void CIniHelper::GetAllKeyValues(const wstring& AppName, std::map& map) const +{ + wstring app_str{ L"[" }; + app_str.append(AppName).append(L"]"); + size_t app_pos{}, app_end_pos{}; + app_pos = m_ini_str.find(app_str); + if (app_pos == wstring::npos) + return; + app_end_pos = m_ini_str.find(L"\n[", app_pos + 2); + if (app_end_pos != wstring::npos) + app_end_pos++; + app_str = m_ini_str.substr(app_pos, app_end_pos - app_pos); + vector line; + CCommon::StringSplit(app_str, L'\n', line); + for (wstring str : line) + { + // CCommon::StringSplit会跳过空字符串,str一定非空 + if (str[0] == L';' || str[0] == L'#') // 跳过注释行(只支持行首注释) + continue; + size_t pos = str.find_first_of(L'='); + if (pos == wstring::npos) + continue; + wstring key{ str.substr(0, pos) }; + wstring value{ str.substr(pos + 1) }; + CCommon::StringNormalize(key); + CCommon::StringNormalize(value); + if (!key.empty() && !value.empty()) + { + if (value.front() == L'\"' && value.back() == L'\"') + value = value.substr(1, value.size() - 2); + UnEscapeString(value); + map[key] = value; + } + } +} + bool CIniHelper::Save() { + if (m_file_path.empty()) + return false; ofstream file_stream{ m_file_path }; if (file_stream.fail()) return false; - string ini_str{ CCommon::UnicodeToStr(m_ini_str.c_str(), m_save_as_utf8 ? CodeType::UTF8_NO_BOM : CodeType::ANSI) }; - if (m_save_as_utf8) //如果以UTF8编码保存,先插入BOM - { - string utf8_bom; - utf8_bom.push_back(-17); - utf8_bom.push_back(-69); - utf8_bom.push_back(-65); - file_stream << utf8_bom; - } - + string ini_str{ CCommon::UnicodeToStr(m_ini_str, m_save_as_utf8 ? CodeType::UTF8 : CodeType::ANSI) }; file_stream << ini_str; return true; } +void CIniHelper::UnEscapeString(wstring& str) +{ + if (str.find(L'\\') == wstring::npos) // 仅含有‘\’时需要处理转义字符 + return; + bool escape{ false }; + wstring result; + result.reserve(str.size()); + for (const wchar_t ch : str) + { + if (escape) + { + switch (ch) + { + case L'n': result += L'\n'; break; + case L'r': result += L'\r'; break; + case L't': result += L'\t'; break; + case L'"': result += L'"'; break; + case L';': result += L';'; break; + case L'#': result += L'#'; break; + case L'\\': result += L'\\'; break; + default:result += '\\'; result += ch; break; + } + escape = false; + } + else if (ch == L'\\') + escape = true; + else + result += ch; + } + str.swap(result); +} + void CIniHelper::_WriteString(const wchar_t* AppName, const wchar_t* KeyName, const wstring& str) { wstring app_str{ L"[" }; diff --git a/MusicPlayer2/IniHelper.h b/MusicPlayer2/IniHelper.h index 953263eb8..2aa282477 100644 --- a/MusicPlayer2/IniHelper.h +++ b/MusicPlayer2/IniHelper.h @@ -9,6 +9,8 @@ class CIniHelper { public: CIniHelper(const wstring& file_path); + // 从资源文件加载ini (只能读取) + CIniHelper(UINT id, CodeType code_type = CodeType::UTF8); ~CIniHelper(); void SetSaveAsUTF8(bool utf8); @@ -31,6 +33,11 @@ class CIniHelper CVariant GetValue(const wchar_t * AppName, const wchar_t * KeyName, CVariant default_values) const; void WriteValue(const wchar_t * AppName, const wchar_t * KeyName, CVariant value); + // 获取带有指定前缀的所有AppName(不含前缀) + vector GetAllAppName(const wstring& prefix) const; + // 获取一个AppName下所有键值对 + void GetAllKeyValues(const wstring& AppName, std::map& map) const; + bool Save(); //将ini文件保存到文件,成功返回true protected: @@ -38,6 +45,7 @@ class CIniHelper wstring m_ini_str; bool m_save_as_utf8{ true }; //是否以UTF8编码保存 + static void UnEscapeString(wstring& str); void _WriteString(const wchar_t* AppName, const wchar_t* KeyName, const wstring& str); wstring _GetString(const wchar_t* AppName, const wchar_t* KeyName, const wchar_t* default_str) const; }; diff --git a/MusicPlayer2/InputDlg.cpp b/MusicPlayer2/InputDlg.cpp index f88f5c130..c24f9bb17 100644 --- a/MusicPlayer2/InputDlg.cpp +++ b/MusicPlayer2/InputDlg.cpp @@ -4,15 +4,14 @@ #include "stdafx.h" #include "MusicPlayer2.h" #include "InputDlg.h" -#include "afxdialogex.h" // CInputDlg 对话框 -IMPLEMENT_DYNAMIC(CInputDlg, CDialog) +IMPLEMENT_DYNAMIC(CInputDlg, CBaseDialog) CInputDlg::CInputDlg(CWnd* pParent /*=nullptr*/) - : CDialog(IDD_INPUT_DLG, pParent) + : CBaseDialog(IDD_INPUT_DLG, pParent) { } @@ -41,13 +40,31 @@ CString CInputDlg::GetEditText() const return m_strEdit; } +CString CInputDlg::GetDialogName() const +{ + return CString(); +} + +bool CInputDlg::InitializeControls() +{ + SetWindowTextW(m_strTitle); + SetDlgItemTextW(IDC_INFO_STATIC, m_strInfo); + SetDlgItemTextW(IDC_INPUT_EDIT, m_strEdit); + + RepositionTextBasedControls({ + { CtrlTextInfo::R1, IDOK, CtrlTextInfo::W32 }, + { CtrlTextInfo::R2, IDCANCEL, CtrlTextInfo::W32 } + }); + return true; +} + void CInputDlg::DoDataExchange(CDataExchange* pDX) { - CDialog::DoDataExchange(pDX); + CBaseDialog::DoDataExchange(pDX); } -BEGIN_MESSAGE_MAP(CInputDlg, CDialog) +BEGIN_MESSAGE_MAP(CInputDlg, CBaseDialog) END_MESSAGE_MAP() @@ -56,16 +73,13 @@ END_MESSAGE_MAP() BOOL CInputDlg::OnInitDialog() { - CDialog::OnInitDialog(); + CBaseDialog::OnInitDialog(); // TODO: 在此添加额外的初始化 - SetWindowText(m_strTitle); - SetDlgItemText(IDC_INFO_STATIC, m_strInfo); CEdit* pEdit = (CEdit*)GetDlgItem(IDC_INPUT_EDIT); if(pEdit!=nullptr) { - pEdit->SetWindowText(m_strEdit); pEdit->SetFocus(); //初始时将焦点设置到输入框 pEdit->SetSel(0, -1); } @@ -80,5 +94,5 @@ void CInputDlg::OnOK() // TODO: 在此添加专用代码和/或调用基类 GetDlgItemText(IDC_INPUT_EDIT, m_strEdit); - CDialog::OnOK(); + CBaseDialog::OnOK(); } diff --git a/MusicPlayer2/InputDlg.h b/MusicPlayer2/InputDlg.h index b0b60cd93..b0021ea48 100644 --- a/MusicPlayer2/InputDlg.h +++ b/MusicPlayer2/InputDlg.h @@ -1,9 +1,9 @@ #pragma once - +#include "BaseDialog.h" // CInputDlg 对话框 -class CInputDlg : public CDialog +class CInputDlg : public CBaseDialog { DECLARE_DYNAMIC(CInputDlg) @@ -22,6 +22,8 @@ class CInputDlg : public CDialog CString GetEditText() const; protected: + virtual CString GetDialogName() const override; + virtual bool InitializeControls() override; virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 private: diff --git a/MusicPlayer2/InternetCommon.cpp b/MusicPlayer2/InternetCommon.cpp index 7a4f68b33..f36f14b04 100644 --- a/MusicPlayer2/InternetCommon.cpp +++ b/MusicPlayer2/InternetCommon.cpp @@ -473,13 +473,13 @@ CInternetCommon::ItemInfo CInternetCommon::SearchSongAndGetMatched(const wstring //设置搜索关键字 wstring search_result; //查找歌曲返回的结果 wstring keyword; //查找的关键字 - if (title == CCommon::LoadText(IDS_DEFAULT_TITLE).GetString() || title.empty()) //如果没有标题信息,就把文件名设为搜索关键字 + if (title.empty() || theApp.m_str_table.LoadText(L"TXT_EMPTY_TITLE") == title) // 如果没有标题信息,就把文件名设为搜索关键字 { keyword = file_name; size_t index = keyword.rfind(L'.'); //查找最后一个点 keyword = keyword.substr(0, index); //去掉扩展名 } - else if (artist == CCommon::LoadText(IDS_DEFAULT_ARTIST).GetString() || artist.empty()) //如果有标题信息但是没有艺术家信息,就把标题设为搜索关键字 + else if (artist.empty() || theApp.m_str_table.LoadText(L"TXT_EMPTY_ARTIST") == artist) //如果有标题信息但是没有艺术家信息,就把标题设为搜索关键字 { keyword = title; } @@ -496,7 +496,10 @@ CInternetCommon::ItemInfo CInternetCommon::SearchSongAndGetMatched(const wstring if (rtn != 0) { if(message) - AfxMessageBox(CCommon::LoadText(IDS_NETWORK_CONNECTION_FAILED), NULL, MB_ICONWARNING); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_NETWORK_CONNECTION_FAILED"); + AfxMessageBox(info.c_str(), NULL, MB_ICONWARNING); + } if (result != nullptr) *result = DR_NETWORK_ERROR; @@ -509,7 +512,10 @@ CInternetCommon::ItemInfo CInternetCommon::SearchSongAndGetMatched(const wstring if (down_list.empty()) { if (message) - AfxMessageBox(CCommon::LoadText(IDS_CANNOT_FIND_THIS_SONG), NULL, MB_ICONWARNING); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_NETWORK_CANNOT_FIND_THIS_SONG"); + AfxMessageBox(info.c_str(), NULL, MB_ICONWARNING); + } if (result != nullptr) *result = DR_DOWNLOAD_ERROR; return CInternetCommon::ItemInfo(); @@ -519,16 +525,19 @@ CInternetCommon::ItemInfo CInternetCommon::SearchSongAndGetMatched(const wstring wstring _title = title; wstring _artist = artist; wstring _album = album; - if (title == CCommon::LoadText(IDS_DEFAULT_TITLE).GetString()) _title.clear(); - if (artist == CCommon::LoadText(IDS_DEFAULT_ARTIST).GetString()) _artist.clear(); - if (album == CCommon::LoadText(IDS_DEFAULT_ALBUM).GetString()) _album.clear(); + if (theApp.m_str_table.LoadText(L"TXT_EMPTY_TITLE") == title) _title.clear(); + if (theApp.m_str_table.LoadText(L"TXT_EMPTY_ARTIST") == artist) _artist.clear(); + if (theApp.m_str_table.LoadText(L"TXT_EMPTY_ALBUM") == album) _album.clear(); if (_title.empty()) _title = keyword; int best_matched = CInternetCommon::SelectMatchedItem(down_list, _title, _artist, _album, file_name, true); if (best_matched < 0) { if (message) - AfxMessageBox(CCommon::LoadText(IDS_CANNOT_FIND_THIS_SONG), NULL, MB_ICONWARNING); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_NETWORK_CANNOT_FIND_THIS_SONG"); + AfxMessageBox(info.c_str(), NULL, MB_ICONWARNING); + } if (result != nullptr) *result = DR_DOWNLOAD_ERROR; return CInternetCommon::ItemInfo(); diff --git a/MusicPlayer2/LastFM.cpp b/MusicPlayer2/LastFM.cpp index cb335a8bf..bc0fb1ace 100644 --- a/MusicPlayer2/LastFM.cpp +++ b/MusicPlayer2/LastFM.cpp @@ -361,7 +361,7 @@ bool LastFM::Unlove() { #define RETURN_AND_RELEASE_MUTEX(value) return ReleaseMutex(mutex), value; -bool LastFM::Scrobble(list& tracks) { +bool LastFM::Scrobble(std::list& tracks) { DWORD dw = WaitForSingleObject(mutex, 1000); if (dw != WAIT_OBJECT_0) { return false; diff --git a/MusicPlayer2/LastFM.h b/MusicPlayer2/LastFM.h index fcf6bf029..826007062 100644 --- a/MusicPlayer2/LastFM.h +++ b/MusicPlayer2/LastFM.h @@ -1,6 +1,5 @@ #pragma once #include "LastFMDataArchive.h" -#include /// Can be obtained from https://www.last.fm/api/accounts/create #define LASTFM_API_KEY L"f2e8f3d36d2de514acc2b072762bb732" #define LASTFM_SHARED_SECRET L"a6b6804e2bc3a60732ac9c5719c52494" @@ -31,7 +30,7 @@ class LastFM { bool Love(); bool Unlove(wstring track, wstring artist); bool Unlove(); - bool Scrobble(list& tracks); + bool Scrobble(std::list& tracks); bool Scrobble(); bool PushCurrentTrackToCache(); void AddCurrentPlayedTime(int millisec); diff --git a/MusicPlayer2/LastFMDataArchive.cpp b/MusicPlayer2/LastFMDataArchive.cpp index 9de2a6b38..da983ff9c 100644 --- a/MusicPlayer2/LastFMDataArchive.cpp +++ b/MusicPlayer2/LastFMDataArchive.cpp @@ -2,7 +2,6 @@ #include "LastFMDataArchive.h" #include "MusicPlayer2.h" #include -#include "AudioTag.h" void LastFMTrack::Clear() { artist = L""; @@ -52,7 +51,7 @@ void LastFMTrack::ReadDataFrom(CArchive& ar) { duration.fromInt((int)d); } -void LastFMTrack::ReadDataFrom(SongInfo info) { +void LastFMTrack::ReadDataFrom(const SongInfo& info) { Clear(); if (!info.artist.empty()) { artist = info.artist; @@ -68,14 +67,7 @@ void LastFMTrack::ReadDataFrom(SongInfo info) { } trackNumber = info.track; duration = info.length(); - CAudioTag tag(info); - std::map property_map; - tag.GetAudioTagPropertyMap(property_map); - for (const auto& prop : property_map) { - if (prop.first == L"ALBUMARTIST") { - albumArtist = prop.second; - } - } + albumArtist = info.album_artist; } bool LastFMTrack::operator==(const LastFMTrack& track) { @@ -158,9 +150,8 @@ void LastFMDataArchive::LoadData(wstring path) { cached_tracks.push_back(track); } } catch (CArchiveException* exception) { - CString info; - info = CCommon::LoadTextFormat(IDS_SERIALIZE_ERROR, { path, exception->m_cause }); - theApp.WriteLog(wstring{ info }); + wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_SERIALIZE_ERROR", { path, exception->m_cause }); + theApp.WriteLog(info); } ar.Close(); file.Close(); diff --git a/MusicPlayer2/LastFMDataArchive.h b/MusicPlayer2/LastFMDataArchive.h index e1d215da9..faf8aa7b8 100644 --- a/MusicPlayer2/LastFMDataArchive.h +++ b/MusicPlayer2/LastFMDataArchive.h @@ -1,11 +1,6 @@ #pragma once -#include -#include -#include "Time.h" #include "SongInfo.h" -using namespace std; - class LastFMTrack { public: /// The artist name. @@ -31,7 +26,7 @@ class LastFMTrack { void Clear(); void SaveDataTo(CArchive &archive); void ReadDataFrom(CArchive &archive); - void ReadDataFrom(SongInfo info); + void ReadDataFrom(const SongInfo& info); bool operator==(const LastFMTrack& track); bool operator==(const SongInfo& info); }; @@ -43,7 +38,7 @@ class LastFMDataArchive { /// The track information of current track after corrected. LastFMTrack corrected_current_track; /// The list of tracks are not scrobbed. - list cached_tracks; + std::list cached_tracks; /// A session key generated by authenticating a user via the authentication protocol. wstring session_key; /// User name diff --git a/MusicPlayer2/ListCtrlEx.cpp b/MusicPlayer2/ListCtrlEx.cpp index bb1e31a0f..24feb4b19 100644 --- a/MusicPlayer2/ListCtrlEx.cpp +++ b/MusicPlayer2/ListCtrlEx.cpp @@ -1,7 +1,6 @@ #include "stdafx.h" #include "ListCtrlEx.h" #include "MusicPlayer2.h" -#include IMPLEMENT_DYNAMIC(CListCtrlEx, CListCtrl) diff --git a/MusicPlayer2/ListCtrlEx.h b/MusicPlayer2/ListCtrlEx.h index 9c39648b8..ef7f97f5e 100644 --- a/MusicPlayer2/ListCtrlEx.h +++ b/MusicPlayer2/ListCtrlEx.h @@ -1,5 +1,4 @@ #pragma once -#include "afxcmn.h" #include "ColorConvert.h" //鼠标拖动完成向父窗口发送此消息,通过wPara传递拖放结束的位置 diff --git a/MusicPlayer2/Lyric.cpp b/MusicPlayer2/Lyric.cpp index 88212447e..2f5bec94d 100644 --- a/MusicPlayer2/Lyric.cpp +++ b/MusicPlayer2/Lyric.cpp @@ -1,6 +1,7 @@ #include "stdafx.h" #include "Lyric.h" #include "FilePathHelper.h" +#include "MusicPlayer2.h" const vector CLyrics::m_surpported_lyric{ L"lrc", L"ksc" }; @@ -29,13 +30,8 @@ CLyrics::CLyrics(const wstring& file_name, const LyricType& lyric_type) : m_file void CLyrics::LyricsFromRowString(const wstring& lyric_str, const LyricType& lyric_type) { - vector results; - CCommon::StringSplit(lyric_str, L'\n', results, false); - for (auto& str : results) - { - CCommon::StringNormalize(str); - m_lyrics_str.push_back(str); - } + CCommon::StringSplitLine(lyric_str, m_lyrics_str, false, true); + ASSERT(lyric_type != LyricType::LY_AUTO); // 按歌词类型调用解析方法 if (lyric_type == LyricType::LY_LRC) @@ -226,6 +222,12 @@ void CLyrics::DisposeLrc() last_pos_end = index2; time_w_ = time_w; } + if (index2 < static_cast(text_str.size())) // 如果最后的时间标签并非结尾,那么将text_str剩下的字符作为没有显式提供时长的一个匀速段加入 + { + lyric.text += text_str.substr(index2); + lyric.split.push_back(lyric.text.size()); + lyric.word_time.push_back(-1); + } } else lyric.text = text_str; @@ -254,8 +256,13 @@ void CLyrics::DisposeLrcNetease() size_t index1{ m_lyrics_str[i].find(L"[", index) }; // 网易的歌词非扩展lrc,如果出现第二段时间标签则放入下一行 if (index1 != wstring::npos) { - m_lyrics_str.emplace(m_lyrics_str.begin() + i, m_lyrics_str[i].substr(0, index1)); - m_lyrics_str[i + 1] = m_lyrics_str[i + 1].substr(index1); + // 判断是否为时间标签,避免误分割 + size_t index2{ m_lyrics_str[i].find_first_not_of(L"[:.]0123456789-", index1) }; + if (index2 != wstring::npos && index2 != index1 + 1) + { + m_lyrics_str.emplace(m_lyrics_str.begin() + i, m_lyrics_str[i].substr(0, index1)); + m_lyrics_str[i + 1] = m_lyrics_str[i + 1].substr(index1); + } } // 有重复时间标签的(第一个内容空白,歌词在第二个里),此处将其内容合并。 index = m_lyrics_str[i].rfind(L"]", index) + 1; // 避免截取到歌词开头的数字,同时也避开非时间标签的[id:xxx],[ti:xxx]等 @@ -383,10 +390,16 @@ void CLyrics::NormalizeLyric() { auto& now{ m_lyrics[i] }; auto& next{ m_lyrics[i + 1] }; + if (!now.word_time.empty() && now.word_time.back() < 0) // 若是逐字歌词且没有显式提供最后匀速段的持续时长 + { // 这里认为其持续到下一行歌词开始 + now.word_time.back() = next.time_start - now.time_start - std::accumulate(now.word_time.begin(), now.word_time.end() - 1, 0); + if (now.word_time.back() < 0) + now.word_time.back() = 0; + } if (now.time_span_raw != 0) // 原始歌词有行持续时间 now.time_span = now.time_span_raw; else if (!now.word_time.empty()) // 否则累加字时间作为行持续时间 - now.time_span = CCommon::SumVector(now.word_time); + now.time_span = std::accumulate(now.word_time.begin(), now.word_time.end(), 0); // time_span为0说明不是逐字歌词,使用下一行开始时间作为本行结束时间; 对逐字歌词检查并阻止time_start + time_span超过下一句的time_start,防止出现时轴重叠 if (now.time_span == 0 || next.time_start - now.time_start < now.time_span) now.time_span = next.time_start - now.time_start; @@ -394,10 +407,19 @@ void CLyrics::NormalizeLyric() if (m_lyrics.size() > 0) // 填充最后一句 { Lyric& now = m_lyrics[m_lyrics.size() - 1]; + if (!now.word_time.empty() && now.word_time.back() < 0) // 若是逐字歌词且没有显式提供最后匀速段的持续时长 + { + if (now.word_time.size() >= 2) + now.word_time.back() = *(now.word_time.end() - 2); // 使用前一个匀速段的持续时长 + else + now.word_time.back() = 20000; // 20秒 + if (now.word_time.back() < 0) + now.word_time.back() = 0; + } if (now.time_span_raw != 0) now.time_span = now.time_span_raw; else if (!now.word_time.empty()) - now.time_span = CCommon::SumVector(now.word_time); + now.time_span = std::accumulate(now.word_time.begin(), now.word_time.end(), 0); } } @@ -504,15 +526,16 @@ CLyrics::Lyric CLyrics::GetLyric(Time time, bool is_next, bool ignore_blank, boo if (!blank2mark || blank_time < LYRIC_BLANK_IGNORE_TIME) // 不添加进度符号 return GetLyric(now_index); CLyrics::Lyric lyric = GetLyric(now_index); + const static wstring mark = theApp.m_str_table.LoadText(L"UI_LYRIC_MUSIC_SYMBOL") + L' '; if(!lyric.text.empty()) // 只对非空歌词添加,应对以多行空行结尾的歌词 - lyric.text = L"♪♪♪ " + lyric.text; + lyric.text = mark + lyric.text; return lyric; } int CLyrics::GetLyricProgress(Time time, bool ignore_blank, bool blank2mark, std::function measure) const { if (m_lyrics.empty()) return 0; - const wstring mark{ L"♪♪♪" }; + const static wstring mark = theApp.m_str_table.LoadText(L"UI_LYRIC_MUSIC_SYMBOL"); int lyric_current_time{}; // 当前所处匀速段已进行时间 int lyric_last_time{}; // 当前所处匀速段总时常 diff --git a/MusicPlayer2/Lyric.h b/MusicPlayer2/Lyric.h index 508a997f2..8846e3e47 100644 --- a/MusicPlayer2/Lyric.h +++ b/MusicPlayer2/Lyric.h @@ -1,6 +1,6 @@ #pragma once -#include"Common.h" #include"Time.h" +#include "Common.h" class CLyrics { diff --git a/MusicPlayer2/LyricBatchDownloadDlg.cpp b/MusicPlayer2/LyricBatchDownloadDlg.cpp index f9e0d14d0..34da4fade 100644 --- a/MusicPlayer2/LyricBatchDownloadDlg.cpp +++ b/MusicPlayer2/LyricBatchDownloadDlg.cpp @@ -4,9 +4,9 @@ #include "stdafx.h" #include "MusicPlayer2.h" #include "LyricBatchDownloadDlg.h" -#include "afxdialogex.h" #include "SongDataManager.h" #include "COSUPlayerHelper.h" +#include "IniHelper.h" // CLyricBatchDownloadDlg 对话框 @@ -28,6 +28,45 @@ CString CLyricBatchDownloadDlg::GetDialogName() const return _T("LyricBatchDownloadDlg"); } +bool CLyricBatchDownloadDlg::InitializeControls() +{ + wstring temp; + temp = theApp.m_str_table.LoadText(L"TITLE_LYRIC_BDL"); + SetWindowTextW(temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_BDL_DL_OPT"); + SetDlgItemTextW(IDC_TXT_LYRIC_BDL_DL_OPT_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_BDL_SKIP_ALREADY"); + SetDlgItemTextW(IDC_SKIP_EXIST_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_BDL_SAVE_ENCODE_SEL"); + SetDlgItemTextW(IDC_TXT_LYRIC_BDL_SAVE_ENCODE_SEL_STATIC, temp.c_str()); + // IDC_COMBO1 + temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_BDL_WITH_TRANSLATION"); + SetDlgItemTextW(IDC_DOWNLOAD_TRASNLATE_CHECK2, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_BDL_SAVE_DIR_SEL"); + SetDlgItemTextW(IDC_TXT_LYRIC_BDL_SAVE_DIR_SEL_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_BDL_SAVE_DIR_LYRIC"); + SetDlgItemTextW(IDC_SAVE_TO_LYRIC_FOLDER, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_BDL_SAVE_DIR_SONG"); + SetDlgItemTextW(IDC_SAVE_TO_SONG_FOLDER, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_BDL_SONG_LIST"); + SetDlgItemTextW(IDC_TXT_LYRIC_BDL_SONG_LIST_STATIC, temp.c_str()); + // IDC_SONG_LIST1 + temp = L""; + SetDlgItemTextW(IDC_PROGRESS_BAR, temp.c_str()); + SetDlgItemTextW(IDC_INFO_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_BDL_DL_START"); + SetDlgItemTextW(IDC_START_DOWNLOAD, temp.c_str()); + // IDCANCEL + + RepositionTextBasedControls({ + { CtrlTextInfo::L1, IDC_PROGRESS_BAR }, + { CtrlTextInfo::C0, IDC_INFO_STATIC }, + { CtrlTextInfo::R1, IDC_START_DOWNLOAD, CtrlTextInfo::W32 }, + { CtrlTextInfo::R2, IDCANCEL, CtrlTextInfo::W32 } + }); + return true; +} + void CLyricBatchDownloadDlg::SaveConfig() const { CIniHelper ini(theApp.m_config_path); @@ -101,9 +140,9 @@ BOOL CLyricBatchDownloadDlg::OnInitDialog() CBaseDialog::OnInitDialog(); // TODO: 在此添加额外的初始化 - SetIcon(theApp.m_icon_set.download1, FALSE); - SetIcon(AfxGetApp()->LoadIcon(IDI_DOWNLOAD1_D), FALSE); - SetButtonIcon(IDC_START_DOWNLOAD, theApp.m_icon_set.download1); + SetIcon(IconMgr::IconType::IT_Download_Batch, FALSE); + SetIcon(IconMgr::IconType::IT_Download_Batch, TRUE); + SetButtonIcon(IDC_START_DOWNLOAD, IconMgr::IconType::IT_Download_Batch); CenterWindow(); @@ -145,11 +184,11 @@ BOOL CLyricBatchDownloadDlg::OnInitDialog() width4 = rect.Width() - width0 - width1 - width2 - width3 - theApp.DPI(20) - 1; //插入列 m_song_list_ctrl.SetExtendedStyle(m_song_list_ctrl.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_LABELTIP); - m_song_list_ctrl.InsertColumn(0, CCommon::LoadText(IDS_NUMBER), LVCFMT_LEFT, width0); //插入第1列 - m_song_list_ctrl.InsertColumn(1, CCommon::LoadText(IDS_TITLE), LVCFMT_LEFT, width1); //插入第2列 - m_song_list_ctrl.InsertColumn(2, CCommon::LoadText(IDS_ARTIST), LVCFMT_LEFT, width2); //插入第3列 - m_song_list_ctrl.InsertColumn(3, CCommon::LoadText(IDS_FILE_NAME), LVCFMT_LEFT, width3); //插入第3列 - m_song_list_ctrl.InsertColumn(4, CCommon::LoadText(IDS_STATE), LVCFMT_LEFT, width4); //插入第4列 + m_song_list_ctrl.InsertColumn(0, theApp.m_str_table.LoadText(L"TXT_SERIAL_NUMBER").c_str(), LVCFMT_LEFT, width0); //插入第1列 + m_song_list_ctrl.InsertColumn(1, theApp.m_str_table.LoadText(L"TXT_TITLE").c_str(), LVCFMT_LEFT, width1); //插入第2列 + m_song_list_ctrl.InsertColumn(2, theApp.m_str_table.LoadText(L"TXT_ARTIST").c_str(), LVCFMT_LEFT, width2); //插入第3列 + m_song_list_ctrl.InsertColumn(3, theApp.m_str_table.LoadText(L"TXT_FILE_NAME").c_str(), LVCFMT_LEFT, width3); //插入第3列 + m_song_list_ctrl.InsertColumn(4, theApp.m_str_table.LoadText(L"TXT_LYRIC_BDL_STATUS").c_str(), LVCFMT_LEFT, width4); //插入第4列 //插入项目 for (size_t i{}; i < m_playlist.size(); i++) { @@ -237,7 +276,7 @@ void CLyricBatchDownloadDlg::OnBnClickedDownloadTrasnlateCheck2() //工作线程函数 UINT CLyricBatchDownloadDlg::ThreadFunc(LPVOID lpParam) { - CCommon::SetThreadLanguage(theApp.m_general_setting_data.language); + CCommon::SetThreadLanguageList(theApp.m_str_table.GetLanguageTag()); ThreadInfo* pInfo = (ThreadInfo*)lpParam; //依次下载列表中每一首歌曲的歌词 @@ -245,14 +284,12 @@ UINT CLyricBatchDownloadDlg::ThreadFunc(LPVOID lpParam) { if (theApp.m_batch_download_dialog_exit) return 0; - CString info; int percent = i * 100 / pInfo->playlist->size(); - info = CCommon::LoadTextFormat(IDS_LYRIC_BATCH_DOWNLOADING_INFO, { percent }); - pInfo->static_ctrl->SetWindowText(info); + wstring info = theApp.m_str_table.LoadTextFormat(L"TXT_LYRIC_BDL_INFO_DOWNLOADING_INFO", { percent }); + pInfo->static_ctrl->SetWindowText(info.c_str()); pInfo->progress_bar->SetProgress(percent); - //SetDlgItemText(IDC_INFO_STATIC, info); - pInfo->list_ctrl->SetItemText(i, 4, CCommon::LoadText(IDS_DOWNLOADING)); + pInfo->list_ctrl->SetItemText(i, 4, theApp.m_str_table.LoadText(L"TXT_LYRIC_BDL_STATUS_DOWNLOADING").c_str()); pInfo->list_ctrl->EnsureVisible(i, FALSE); //设置要保存的歌词的路径 @@ -278,7 +315,7 @@ UINT CLyricBatchDownloadDlg::ThreadFunc(LPVOID lpParam) bool lyric_exist = CCommon::FileExist(lyric_path) || (!pInfo->playlist->at(i).lyric_file.empty()); if (pInfo->skip_exist && lyric_exist) //如果设置了跳过已存在歌词的曲目,并且歌词已经存在,则跳过它 { - pInfo->list_ctrl->SetItemText(i, 4, CCommon::LoadText(IDS_SKIPED)); + pInfo->list_ctrl->SetItemText(i, 4, theApp.m_str_table.LoadText(L"TXT_LYRIC_BDL_STATUS_SKIPED").c_str()); continue; } @@ -310,7 +347,7 @@ UINT CLyricBatchDownloadDlg::ThreadFunc(LPVOID lpParam) return 0; if (rtn != 0) { - pInfo->list_ctrl->SetItemText(i, 4, CCommon::LoadText(IDS_NETWORK_CONNECTION_FAILED)); + pInfo->list_ctrl->SetItemText(i, 4, theApp.m_str_table.LoadText(L"TXT_LYRIC_BDL_STATUS_NETWORK_FAILED").c_str()); continue; } @@ -320,7 +357,7 @@ UINT CLyricBatchDownloadDlg::ThreadFunc(LPVOID lpParam) CInternetCommon::DisposeSearchResult(down_list, search_result); //处理返回的查找结果,并将结果保存在down_list容器里 if (down_list.empty()) { - pInfo->list_ctrl->SetItemText(i, 4, CCommon::LoadText(IDS_CANNOT_FIND_THIS_SONG)); + pInfo->list_ctrl->SetItemText(i, 4, theApp.m_str_table.LoadText(L"TXT_LYRIC_BDL_STATUS_CANNOT_FIND_THIS_SONG").c_str()); song_info_ori.SetNoOnlineLyric(true); CSongDataManager::GetInstance().AddItem(song_info_ori); continue; @@ -330,15 +367,15 @@ UINT CLyricBatchDownloadDlg::ThreadFunc(LPVOID lpParam) wstring title = pInfo->playlist->at(i).title; wstring artist = pInfo->playlist->at(i).artist; wstring album = pInfo->playlist->at(i).album; - if (title == CCommon::LoadText(IDS_DEFAULT_TITLE).GetString()) title.clear(); - if (artist == CCommon::LoadText(IDS_DEFAULT_ARTIST).GetString()) artist.clear(); - if (album == CCommon::LoadText(IDS_DEFAULT_ALBUM).GetString()) album.clear(); + if (theApp.m_str_table.LoadText(L"TXT_EMPTY_TITLE") == title) title.clear(); + if (theApp.m_str_table.LoadText(L"TXT_EMPTY_ARTIST") == artist) artist.clear(); + if (theApp.m_str_table.LoadText(L"TXT_EMPTY_ALBUM") == album) album.clear(); int best_matched = CInternetCommon::SelectMatchedItem(down_list, title, artist, album, pInfo->playlist->at(i).GetFileName(), true); if (best_matched < 0) { song_info_ori.SetNoOnlineLyric(true); CSongDataManager::GetInstance().AddItem(song_info_ori); - pInfo->list_ctrl->SetItemText(i, 4, CCommon::LoadText(IDS_NO_MATCHED_LYRIC)); + pInfo->list_ctrl->SetItemText(i, 4, theApp.m_str_table.LoadText(L"TXT_LYRIC_BDL_STATUS_NO_MATCHED_LYRIC").c_str()); continue; } @@ -346,14 +383,14 @@ UINT CLyricBatchDownloadDlg::ThreadFunc(LPVOID lpParam) CLyricDownloadCommon::DownloadLyric(down_list[best_matched].id, lyric_str, pInfo->download_translate); if (lyric_str.empty()) { - pInfo->list_ctrl->SetItemText(i, 4, CCommon::LoadText(IDS_LYRIC_DOWNLOAD_FAILED)); + pInfo->list_ctrl->SetItemText(i, 4, theApp.m_str_table.LoadText(L"TXT_LYRIC_BDL_STATUS_DOWNLOAD_FAILED").c_str()); continue; } //处理歌词文本 if (!CLyricDownloadCommon::DisposeLryic(lyric_str)) { - pInfo->list_ctrl->SetItemText(i, 4, CCommon::LoadText(IDS_SONG_NO_LYRIC)); + pInfo->list_ctrl->SetItemText(i, 4, theApp.m_str_table.LoadText(L"TXT_LYRIC_BDL_STATUS_SONG_NO_LYRIC").c_str()); continue; } @@ -368,13 +405,13 @@ UINT CLyricBatchDownloadDlg::ThreadFunc(LPVOID lpParam) if (CLyricBatchDownloadDlg::SaveLyric(lyric_path.c_str(), lyric_str, pInfo->save_code, &char_cannot_convert)) { if (char_cannot_convert) - pInfo->list_ctrl->SetItemText(i, 4, CCommon::LoadText(IDS_DOWNLOAD_ENCODE_WARNING)); //char_cannot_convert为true,则说明有无法转换的Unicode字符 + pInfo->list_ctrl->SetItemText(i, 4, theApp.m_str_table.LoadText(L"TXT_LYRIC_BDL_STATUS_ENCODE_WARNING").c_str()); //char_cannot_convert为true,则说明有无法转换的Unicode字符 else - pInfo->list_ctrl->SetItemText(i, 4, CCommon::LoadText(IDS_SUCCESSED)); + pInfo->list_ctrl->SetItemText(i, 4, theApp.m_str_table.LoadText(L"TXT_LYRIC_BDL_STATUS_SUCCESSED").c_str()); } else { - pInfo->list_ctrl->SetItemText(i, 4, CCommon::LoadText(IDS_CANNOT_WRITE_TO_FILE)); + pInfo->list_ctrl->SetItemText(i, 4, theApp.m_str_table.LoadText(L"TXT_LYRIC_BDL_STATUS_SUCCESSED").c_str()); } if (pInfo->download_translate) @@ -391,7 +428,7 @@ UINT CLyricBatchDownloadDlg::ThreadFunc(LPVOID lpParam) afx_msg LRESULT CLyricBatchDownloadDlg::OnBatchDownloadComplate(WPARAM wParam, LPARAM lParam) { - SetDlgItemText(IDC_INFO_STATIC, CCommon::LoadText(IDS_DOWNLOAD_COMPLETE)); + SetDlgItemText(IDC_INFO_STATIC, theApp.m_str_table.LoadText(L"TXT_LYRIC_BDL_INFO_COMPLETE").c_str()); //下载完成后重新载入歌词 CPlayer::GetInstance().SearchLyrics(true); CPlayer::GetInstance().IniLyrics(); @@ -414,15 +451,12 @@ void CLyricBatchDownloadDlg::OnCancel() // TODO: 在此添加专用代码和/或调用基类 //对话框将要关闭时,将退出标志置为true theApp.m_batch_download_dialog_exit = true; - int rtn; if (m_pThread != nullptr) { - rtn = WaitForSingleObject(m_pThread->m_hThread, 2000); //等待线程退出 -#ifdef DEBUG - CString info; - info.Format(CCommon::LoadText(IDS_RETURN_VALUE_OF_WAIT_FOR_SINGLE_OBJECT), rtn); - MessageBox(info, NULL, MB_ICONINFORMATION); -#endif // DEBUG + int rtn = WaitForSingleObject(m_pThread->m_hThread, 2000); //等待线程退出 + // std::wstringstream wss; + // wss << std::hex << std::uppercase << L"0x" << rtn; + // MessageBox(wss.str().c_str(), NULL, MB_ICONINFORMATION); } DestroyWindow(); diff --git a/MusicPlayer2/LyricBatchDownloadDlg.h b/MusicPlayer2/LyricBatchDownloadDlg.h index bcdc05a04..8c8bc2ed0 100644 --- a/MusicPlayer2/LyricBatchDownloadDlg.h +++ b/MusicPlayer2/LyricBatchDownloadDlg.h @@ -1,7 +1,6 @@ #pragma once -#include "afxwin.h" #include "Common.h" -#include "afxcmn.h" +#include "Player.h" #include "LyricDownloadCommon.h" #include "LyricDownloadDlg.h" #include "ListCtrlEx.h" @@ -66,14 +65,14 @@ class CLyricBatchDownloadDlg : public CBaseDialog CWinThread* m_pThread{}; //下载歌词的线程 virtual CString GetDialogName() const override; - + virtual bool InitializeControls() override; + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 + void SaveConfig() const; void LoadConfig(); void EnableControls(bool enable); //启用或禁用控件 - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 - DECLARE_MESSAGE_MAP() public: virtual BOOL OnInitDialog(); diff --git a/MusicPlayer2/LyricDownloadDlg.cpp b/MusicPlayer2/LyricDownloadDlg.cpp index 832eb94b7..45a17ea27 100644 --- a/MusicPlayer2/LyricDownloadDlg.cpp +++ b/MusicPlayer2/LyricDownloadDlg.cpp @@ -3,12 +3,13 @@ #include "stdafx.h" #include "MusicPlayer2.h" +#include "Player.h" #include "LyricDownloadDlg.h" -#include "afxdialogex.h" #include "MessageDlg.h" -#include "WIC.h" #include "SongInfoHelper.h" #include "SongDataManager.h" +#include "FilterHelper.h" +#include "IniHelper.h" // CLyricDownloadDlg 对话框 @@ -47,27 +48,28 @@ bool CLyricDownloadDlg::SaveLyric(const wchar_t * path, CodeType code_type) string lyric_str = CCommon::UnicodeToStr(m_lyric_str, code_type, &char_connot_convert); if (char_connot_convert) //当文件中包含Unicode字符时,询问用户是否要选择一个Unicode编码格式再保存 { - CString info; - info.LoadString(IDS_STRING103); //从string table载入字符串 - if (MessageBox(info, NULL, MB_OKCANCEL | MB_ICONWARNING) != IDOK) - return false; //如果用户点击了取消按钮,则返回false + const wstring& info = theApp.m_str_table.LoadText(L"MSG_UNICODE_WARNING"); // 从string table载入字符串 + if (MessageBox(info.c_str(), NULL, MB_OKCANCEL | MB_ICONWARNING) != IDOK) + return false; // 如果用户点击了取消按钮,则返回false } ofstream out_put{ path, std::ios::binary }; - if (out_put.fail()) - { - MessageBox(CCommon::LoadText(IDS_LYRIC_SAVE_FAILED), NULL, MB_ICONWARNING | MB_OK); - return false; + if (!out_put.is_open()) + { + out_put.close(); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_LYRIC_SAVE_FAILED"); + MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK); + return false; } out_put << lyric_str; + out_put.close(); return true; } void CLyricDownloadDlg::SetID(wstring id) { - SongInfo song_info{ CSongDataManager::GetInstance().GetSongInfo3(m_song) }; - song_info.SetSongId(id); - CSongDataManager::GetInstance().AddItem(song_info); + m_song.SetSongId(id); + CSongDataManager::GetInstance().SetSongID(m_song, m_song.song_id); } void CLyricDownloadDlg::SaveConfig() const @@ -107,6 +109,59 @@ CString CLyricDownloadDlg::GetDialogName() const return _T("LyricDownloadDlg"); } +bool CLyricDownloadDlg::InitializeControls() +{ + wstring temp; + temp = theApp.m_str_table.LoadText(L"TITLE_LYRIC_DL"); + SetWindowTextW(temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_TITLE"); + SetDlgItemTextW(IDC_TXT_LYRIC_DL_TITLE_STATIC, temp.c_str()); + // IDC_TITLE_EDIT1 + temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_SEARCH"); + SetDlgItemTextW(IDC_SEARCH_BUTTON2, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_ARTIST"); + SetDlgItemTextW(IDC_TXT_LYRIC_DL_ARTIST_STATIC, temp.c_str()); + // IDC_ARTIST_EDIT1 + temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_INFO"); + SetDlgItemTextW(IDC_STATIC_INFO, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_UNLINK"); + SetDlgItemTextW(IDC_UNASSOCIATE_LINK, temp.c_str()); + // IDC_LYRIC_DOWN_LIST1 + temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_OPT"); + SetDlgItemTextW(IDC_TXT_LYRIC_DL_OPT_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_WITH_TRANSLATION"); + SetDlgItemTextW(IDC_DOWNLOAD_TRANSLATE_CHECK1, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_SAVE_ENCODE_SEL"); + SetDlgItemTextW(IDC_TXT_LYRIC_DL_SAVE_ENCODE_SEL_STATIC, temp.c_str()); + // IDC_COMBO2 + temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_SAVE_DIR_SEL"); + SetDlgItemTextW(IDC_TXT_LYRIC_DL_SAVE_DIR_SEL_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_SAVE_DIR_LYRIC"); + SetDlgItemTextW(IDC_SAVE_TO_LYRIC_FOLDER1, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_SAVE_DIR_SONG"); + SetDlgItemTextW(IDC_SAVE_TO_SONG_FOLDER1, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_SEL_DL"); + SetDlgItemTextW(IDC_DOWNLOAD_SELECTED, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_SEL_SAVE_AS"); + SetDlgItemTextW(IDC_SELECTED_SAVE_AS, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_CLOSE"); + SetDlgItemTextW(IDCANCEL, temp.c_str()); + + RepositionTextBasedControls({ + { CtrlTextInfo::L1, IDC_TXT_LYRIC_DL_TITLE_STATIC }, + { CtrlTextInfo::C0, IDC_TITLE_EDIT1 }, + { CtrlTextInfo::R1, IDC_SEARCH_BUTTON2, CtrlTextInfo::W32 }, + { CtrlTextInfo::L1, IDC_TXT_LYRIC_DL_ARTIST_STATIC }, + { CtrlTextInfo::C0, IDC_ARTIST_EDIT1 } + }, CtrlTextInfo::W64); + RepositionTextBasedControls({ + { CtrlTextInfo::R1, IDC_DOWNLOAD_SELECTED, CtrlTextInfo::W32 }, + { CtrlTextInfo::R2, IDC_SELECTED_SAVE_AS, CtrlTextInfo::W32 }, + { CtrlTextInfo::R3, IDCANCEL, CtrlTextInfo::W32 } + }); + return true; +} + void CLyricDownloadDlg::DoDataExchange(CDataExchange* pDX) { CBaseDialog::DoDataExchange(pDX); @@ -161,16 +216,16 @@ BOOL CLyricDownloadDlg::OnInitDialog() // TODO: 在此添加额外的初始化 LoadConfig(); - SetIcon(theApp.m_icon_set.download, FALSE); - SetButtonIcon(IDC_SEARCH_BUTTON2, theApp.m_icon_set.find_songs.GetIcon(true)); - SetButtonIcon(IDC_DOWNLOAD_SELECTED, theApp.m_icon_set.download); - SetButtonIcon(IDC_SELECTED_SAVE_AS, theApp.m_icon_set.save_as); + SetIcon(IconMgr::IconType::IT_Download, FALSE); + SetButtonIcon(IDC_SEARCH_BUTTON2, IconMgr::IconType::IT_Find); + SetButtonIcon(IDC_DOWNLOAD_SELECTED, IconMgr::IconType::IT_Download); + SetButtonIcon(IDC_SELECTED_SAVE_AS, IconMgr::IconType::IT_Save_As); m_song = CPlayer::GetInstance().GetCurrentSongInfo(); if (m_song.IsTitleEmpty()) //如果没有标题信息,就把文件名设为标题 { - m_song.title = CPlayer::GetInstance().GetFileName(); + m_song.title = m_song.GetFileName(); size_t index = m_song.title.rfind(L'.'); m_song.title = m_song.title.substr(0, index); } @@ -190,7 +245,7 @@ BOOL CLyricDownloadDlg::OnInitDialog() } else { - m_lyric_name = CPlayer::GetInstance().GetFileName(); + m_lyric_name = m_song.GetFileName(); m_lyric_name = CFilePathHelper(m_lyric_name).ReplaceFileExtension(nullptr); //清除文件名的扩展名 } //if (!song.is_cue) @@ -218,11 +273,11 @@ BOOL CLyricDownloadDlg::OnInitDialog() width3 = rect.Width() - theApp.DPI(20) - 1 - width0 - width1 - width2 - width4; m_down_list_ctrl.SetExtendedStyle(m_down_list_ctrl.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_LABELTIP); - m_down_list_ctrl.InsertColumn(0, CCommon::LoadText(IDS_NUMBER), LVCFMT_LEFT, width0); - m_down_list_ctrl.InsertColumn(1, CCommon::LoadText(IDS_TITLE), LVCFMT_LEFT, width1); - m_down_list_ctrl.InsertColumn(2, CCommon::LoadText(IDS_ARTIST), LVCFMT_LEFT, width2); - m_down_list_ctrl.InsertColumn(3, CCommon::LoadText(IDS_ALBUM), LVCFMT_LEFT, width3); - m_down_list_ctrl.InsertColumn(4, CCommon::LoadText(IDS_LENGTH), LVCFMT_LEFT, width4); + m_down_list_ctrl.InsertColumn(0, theApp.m_str_table.LoadText(L"TXT_SERIAL_NUMBER").c_str(), LVCFMT_LEFT, width0); + m_down_list_ctrl.InsertColumn(1, theApp.m_str_table.LoadText(L"TXT_TITLE").c_str(), LVCFMT_LEFT, width1); + m_down_list_ctrl.InsertColumn(2, theApp.m_str_table.LoadText(L"TXT_ARTIST").c_str(), LVCFMT_LEFT, width2); + m_down_list_ctrl.InsertColumn(3, theApp.m_str_table.LoadText(L"TXT_ALBUM").c_str(), LVCFMT_LEFT, width3); + m_down_list_ctrl.InsertColumn(4, theApp.m_str_table.LoadText(L"TXT_LENGTH").c_str(), LVCFMT_LEFT, width4); //设置列表控件的提示总是置顶,用于解决如果弹出此窗口的父窗口具有置顶属性时,提示信息在窗口下面的问题 m_down_list_ctrl.GetToolTips()->SetWindowPos(&CWnd::wndTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); @@ -247,18 +302,8 @@ BOOL CLyricDownloadDlg::OnInitDialog() ((CButton*)GetDlgItem(IDC_SAVE_TO_LYRIC_FOLDER1))->SetCheck(FALSE); ((CButton*)GetDlgItem(IDC_SAVE_TO_SONG_FOLDER1))->SetCheck(TRUE); m_save_to_song_folder = true; - //CString info; - //info.LoadString(IDS_LYRIC_FOLDER_NOT_EXIST); - //m_tool_tip.AddTool(GetDlgItem(IDC_SAVE_TO_LYRIC_FOLDER1), info); } - //初始化右键菜单 - m_menu.LoadMenu(IDR_LYRIC_DOWNLOAD_MENU); - m_menu.GetSubMenu(0)->SetDefaultItem(ID_LD_LYRIC_DOWNLOAD); - CMenuIcon::AddIconToMenuItem(m_menu.GetSafeHmenu(), ID_LD_LYRIC_DOWNLOAD, FALSE, theApp.m_icon_set.download); - CMenuIcon::AddIconToMenuItem(m_menu.GetSafeHmenu(), ID_LD_LYRIC_SAVEAS, FALSE, theApp.m_icon_set.save_as); - CMenuIcon::AddIconToMenuItem(m_menu.GetSafeHmenu(), ID_LD_VIEW_ONLINE, FALSE, theApp.m_icon_set.online); - m_unassciate_lnk.ShowWindow(SW_HIDE); return TRUE; // return TRUE unless you set the focus to a control @@ -269,7 +314,7 @@ BOOL CLyricDownloadDlg::OnInitDialog() void CLyricDownloadDlg::OnBnClickedSearchButton2() { // TODO: 在此添加控件通知处理程序代码 - SetDlgItemText(IDC_STATIC_INFO, CCommon::LoadText(IDS_SEARCHING)); + SetDlgItemText(IDC_STATIC_INFO, theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_INFO_SEARCHING").c_str()); GetDlgItem(IDC_SEARCH_BUTTON2)->EnableWindow(FALSE); //点击“搜索”后禁用该按钮 wstring keyword = CInternetCommon::URLEncode(m_song.artist + L' ' + m_song.title); //搜索关键字为“艺术家 标题”,并将其转换成URL编码 CString url; @@ -328,7 +373,7 @@ void CLyricDownloadDlg::OnNMRClickLyricDownList1(NMHDR *pNMHDR, LRESULT *pResult if (IsItemSelectedValid()) { //弹出右键菜单 - CMenu* pContextMenu = m_menu.GetSubMenu(0); //获取第一个弹出菜单 + CMenu* pContextMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::LdListMenu); m_down_list_ctrl.ShowPopupMenu(pContextMenu, pNMItemActivate->iItem, this); } @@ -386,11 +431,15 @@ void CLyricDownloadDlg::OnDestroy() UINT CLyricDownloadDlg::LyricSearchThreadFunc(LPVOID lpParam) { - CCommon::SetThreadLanguage(theApp.m_general_setting_data.language); + CCommon::SetThreadLanguageList(theApp.m_str_table.GetLanguageTag()); SearchThreadInfo* pInfo = (SearchThreadInfo*)lpParam; - wstring result; - pInfo->rtn = CInternetCommon::HttpPost(pInfo->url, result); //向网易云音乐的歌曲搜索API发送http的POST请求 - if (theApp.m_lyric_download_dialog_exit) return 0; + wstring url = pInfo->url; + wstring result; + bool rtn = CInternetCommon::HttpPost(url, result); //向网易云音乐的歌曲搜索API发送http的POST请求 + if (theApp.m_lyric_download_dialog_exit) return 0; + // 此处(以及大部分网络相关)有线程安全问题,HttpPost可能卡30s网络超时,要解决此问题CInternetSession的封装应当提供退出flag参数 + // 此时如果歌词下载窗口关闭则pInfo会是野指针(比如关闭再打开此对话框会使得上面的检查无效) + pInfo->rtn = rtn; pInfo->result = result; ::PostMessage(pInfo->hwnd, WM_SEARCH_COMPLATE, 0, 0); //搜索完成后发送一个搜索完成的消息 @@ -399,11 +448,14 @@ UINT CLyricDownloadDlg::LyricSearchThreadFunc(LPVOID lpParam) UINT CLyricDownloadDlg::LyricDownloadThreadFunc(LPVOID lpParam) { - CCommon::SetThreadLanguage(theApp.m_general_setting_data.language); + CCommon::SetThreadLanguageList(theApp.m_str_table.GetLanguageTag()); DownloadThreadInfo* pInfo = (DownloadThreadInfo*)lpParam; - wstring result; - pInfo->success = CLyricDownloadCommon::DownloadLyric(pInfo->song_id, result, pInfo->download_translate); //下载歌词 - if (theApp.m_lyric_download_dialog_exit) return 0; + wstring song_id = pInfo->song_id; + bool download_translate = pInfo->download_translate; + wstring result; + bool rtn = CLyricDownloadCommon::DownloadLyric(song_id, result, download_translate); //下载歌词 + if (theApp.m_lyric_download_dialog_exit) return 0; + pInfo->success = rtn; pInfo->result = result; ::PostMessage(pInfo->hwnd, WM_DOWNLOAD_COMPLATE, (WPARAM)pInfo->save_as, 0); //下载完成后发送一个下载完成消息(wParam用于传递是否弹出“另存为”对话框) return 0; @@ -416,14 +468,24 @@ afx_msg LRESULT CLyricDownloadDlg::OnSearchComplate(WPARAM wParam, LPARAM lParam GetDlgItem(IDC_SEARCH_BUTTON2)->EnableWindow(TRUE); //搜索完成之后启用该按钮 m_search_result = m_search_thread_info.result; if(m_search_thread_info.rtn != CInternetCommon::SUCCESS) - SetDlgItemText(IDC_STATIC_INFO, CCommon::LoadText(IDS_SEARCH_RESULT)); + SetDlgItemText(IDC_STATIC_INFO, theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_INFO").c_str()); - switch (m_search_thread_info.rtn) - { - case CInternetCommon::FAILURE: MessageBox(CCommon::LoadText(IDS_SEARCH_FAILED_INFO), NULL, MB_ICONWARNING); return 0; - case CInternetCommon::OUTTIME: MessageBox(CCommon::LoadText(IDS_SEARCH_TIME_OUT), NULL, MB_ICONWARNING); return 0; - default: break; - } + switch (m_search_thread_info.rtn) + { + case CInternetCommon::FAILURE: + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_NETWORK_SEARCH_FAILED"); + MessageBox(info.c_str(), NULL, MB_ICONWARNING); + return 0; + } + case CInternetCommon::OUTTIME: + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_NETWORK_SEARCH_TIME_OUT"); + MessageBox(info.c_str(), NULL, MB_ICONWARNING); + return 0; + } + default: break; + } //DEBUG模式下,将查找返回的结果保存到文件 #ifdef DEBUG ofstream out_put{ L".\\down.log", std::ios::binary }; @@ -436,7 +498,8 @@ afx_msg LRESULT CLyricDownloadDlg::OnSearchComplate(WPARAM wParam, LPARAM lParam //计算搜索结果中最佳匹配项目 int best_matched; bool id_releated{ false }; - if (!m_song.song_id == 0) //如果当前歌曲已经有关联的ID,则根据该ID在搜索结果列表中查找对应的项目 + CSongDataManager::GetInstance().GetSongID(m_song, m_song.song_id); // 从媒体库读取id + if (m_song.song_id != 0) //如果当前歌曲已经有关联的ID,则根据该ID在搜索结果列表中查找对应的项目 { for (size_t i{}; iEnableWindow(TRUE); //下载完成后启用该按钮 if (!m_download_thread_info.success || m_lyric_str.empty()) { - MessageBox(CCommon::LoadText(IDS_LYRIC_DOWNLOAD_FAILED, _T("!")), NULL, MB_ICONWARNING); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_NETWORK_LYRIC_DOWNLOAD_FAILED"); + MessageBox(info.c_str(), NULL, MB_ICONWARNING); return 0; } if (!CLyricDownloadCommon::DisposeLryic(m_lyric_str)) { - MessageBox(CCommon::LoadText(IDS_SONG_NO_LYRIC, _T("!")), NULL, MB_ICONWARNING); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_NETWORK_SONG_NO_LYRIC"); + MessageBox(info.c_str(), NULL, MB_ICONWARNING); return 0; } @@ -530,15 +595,15 @@ afx_msg LRESULT CLyricDownloadDlg::OnDownloadComplate(WPARAM wParam, LPARAM lPar { if (!m_save_to_song_folder && !CCommon::FolderExist(theApp.m_lyric_setting_data.lyric_path)) { - CString info; - info.LoadString(IDS_LYRIC_FOLDER_NOT_EXIST); - MessageBox(info, NULL, MB_ICONWARNING | MB_OK); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_LYRIC_FOLDER_NOT_EXIST"); + MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK); return 0; } wstring saved_path = GetSavedPath(); if (CCommon::FileExist(saved_path)) { - if (MessageBox(CCommon::LoadText(IDS_LYRIC_OVERWRITE_INQUARY), NULL, MB_ICONWARNING | MB_OKCANCEL) == IDCANCEL) + const wstring& info = theApp.m_str_table.LoadText(L"MSG_LYRIC_OVERWRITE_INQUARY"); + if (MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OKCANCEL) == IDCANCEL) return 0; } if (!SaveLyric(saved_path.c_str(), m_save_code)) //保存歌词 @@ -551,21 +616,20 @@ afx_msg LRESULT CLyricDownloadDlg::OnDownloadComplate(WPARAM wParam, LPARAM lPar if (m_song.IsSameSong(CPlayer::GetInstance().GetCurrentSongInfo())) //如果正在播放的歌曲还是当前下载歌词的歌曲,才更新歌词显示 CPlayer::GetInstance().IniLyrics(saved_path); - CString info; - info = CCommon::LoadTextFormat(IDS_DOWNLOAD_COMPLETE_SAVED, { saved_path }); - MessageBox(info, NULL, MB_ICONINFORMATION); + wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_LYRIC_DOWNLOAD_COMPLETE_SAVED", { saved_path }); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION); } else { //设置过滤器 - CString szFilter = CCommon::LoadText(IDS_LYRIC_FILE_FILTER); + wstring filter = FilterHelper::GetLyricFileFilter(); //构造保存文件对话框 - CFileDialog fileDlg(FALSE, _T("lrc"), GetSavedPath().c_str(), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter, this); + CFileDialog fileDlg(FALSE, _T("lrc"), GetSavedPath().c_str(), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, filter.c_str(), this); //为“另存为”对话框添加一个组合选择框 fileDlg.AddComboBox(IDC_SAVE_COMBO_BOX); //为组合选择框添加项目 - fileDlg.AddControlItem(IDC_SAVE_COMBO_BOX, 0, CCommon::LoadText(IDS_SAVE_AS_ANSI)); - fileDlg.AddControlItem(IDC_SAVE_COMBO_BOX, 1, CCommon::LoadText(IDS_SAVE_AS_UTF8)); + fileDlg.AddControlItem(IDC_SAVE_COMBO_BOX, 0, theApp.m_str_table.LoadText(L"TXT_SAVE_AS_ANSI").c_str()); + fileDlg.AddControlItem(IDC_SAVE_COMBO_BOX, 1, theApp.m_str_table.LoadText(L"TXT_SAVE_AS_UTF8").c_str()); //为组合选择框设置默认选中的项目 fileDlg.SetSelectedControlItem(IDC_SAVE_COMBO_BOX, static_cast(m_save_code)); @@ -645,7 +709,7 @@ void CLyricDownloadDlg::OnLdCopyTitle() if (IsItemSelectedValid()) { if(!CCommon::CopyStringToClipboard(m_down_list[m_item_selected].title)) - MessageBox(CCommon::LoadText(IDS_COPY_CLIPBOARD_FAILED), NULL, MB_ICONWARNING); + MessageBox(theApp.m_str_table.LoadText(L"MSG_COPY_CLIPBOARD_FAILED").c_str(), NULL, MB_ICONWARNING); } } @@ -656,7 +720,7 @@ void CLyricDownloadDlg::OnLdCopyArtist() if (IsItemSelectedValid()) { if (!CCommon::CopyStringToClipboard(m_down_list[m_item_selected].artist)) - MessageBox(CCommon::LoadText(IDS_COPY_CLIPBOARD_FAILED), NULL, MB_ICONWARNING); + MessageBox(theApp.m_str_table.LoadText(L"MSG_COPY_CLIPBOARD_FAILED").c_str(), NULL, MB_ICONWARNING); } } @@ -667,7 +731,7 @@ void CLyricDownloadDlg::OnLdCopyAlbum() if (IsItemSelectedValid()) { if (!CCommon::CopyStringToClipboard(m_down_list[m_item_selected].album)) - MessageBox(CCommon::LoadText(IDS_COPY_CLIPBOARD_FAILED), NULL, MB_ICONWARNING); + MessageBox(theApp.m_str_table.LoadText(L"MSG_COPY_CLIPBOARD_FAILED").c_str(), NULL, MB_ICONWARNING); } } @@ -678,7 +742,7 @@ void CLyricDownloadDlg::OnLdCopyId() if (IsItemSelectedValid()) { if (!CCommon::CopyStringToClipboard(m_down_list[m_item_selected].id)) - MessageBox(CCommon::LoadText(IDS_COPY_CLIPBOARD_FAILED), NULL, MB_ICONWARNING); + MessageBox(theApp.m_str_table.LoadText(L"MSG_COPY_CLIPBOARD_FAILED").c_str(), NULL, MB_ICONWARNING); } } @@ -745,12 +809,14 @@ void CLyricDownloadDlg::OnLdPreview() //如果不成功弹出消息对话框 if (!success || result.empty()) { - MessageBox(CCommon::LoadText(IDS_LYRIC_DOWNLOAD_FAILED, _T("!")), NULL, MB_ICONWARNING); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_NETWORK_LYRIC_DOWNLOAD_FAILED"); + MessageBox(info.c_str(), NULL, MB_ICONWARNING); return; } if (!CLyricDownloadCommon::DisposeLryic(result)) { - MessageBox(CCommon::LoadText(IDS_SONG_NO_LYRIC, _T("!")), NULL, MB_ICONWARNING); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_NETWORK_SONG_NO_LYRIC"); + MessageBox(info.c_str(), NULL, MB_ICONWARNING); return; } @@ -761,18 +827,13 @@ void CLyricDownloadDlg::OnLdPreview() lyrics.LyricsFromRowString(result, CLyrics::LyricType::LY_LRC_NETEASE); result = lyrics.GetLyricsString2(); - //显示预览窗口 - CString dlg_title = CCommon::LoadText(IDS_LYRIC_PREVIEW); - CMessageDlg dlg; - dlg.SetWindowTitle(dlg_title); - CString info; - info += item.artist.c_str(); - info += _T(" - "); - info += item.title.c_str(); - dlg.SetInfoText(info); - dlg.SetMessageText(result.c_str()); - - dlg.DoModal(); + // 显示预览窗口 + CMessageDlg dlg(L"LrcPreviewDlg"); + dlg.SetWindowTitle(theApp.m_str_table.LoadText(L"TITLE_LYRIC_PREVIEW")); + wstring info = item.artist + L" - " + item.title; + dlg.SetInfoText(info); + dlg.SetMessageText(result); + dlg.DoModal(); } diff --git a/MusicPlayer2/LyricDownloadDlg.h b/MusicPlayer2/LyricDownloadDlg.h index 643de475d..340045937 100644 --- a/MusicPlayer2/LyricDownloadDlg.h +++ b/MusicPlayer2/LyricDownloadDlg.h @@ -1,8 +1,6 @@ #pragma once #include "LyricDownloadCommon.h" -#include "afxcmn.h" #include "Lyric.h" -#include "afxwin.h" #include "ListCtrlEx.h" #include "SongInfo.h" #include "BaseDialog.h" @@ -69,7 +67,6 @@ class CLyricDownloadDlg : public CBaseDialog CodeType m_save_code{}; //保存的编码格式 int m_search_max_item{ 30 }; //查找歌曲时返回的最大数量 - CMenu m_menu; CListCtrlEx m_down_list_ctrl; CButton m_download_translate_chk; CComboBox m_save_code_combo; @@ -90,6 +87,7 @@ class CLyricDownloadDlg : public CBaseDialog wstring GetSavedPath(); virtual CString GetDialogName() const override; + virtual bool InitializeControls() override; virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 diff --git a/MusicPlayer2/LyricEditDlg.cpp b/MusicPlayer2/LyricEditDlg.cpp index 1aa40dc53..5334f26bb 100644 --- a/MusicPlayer2/LyricEditDlg.cpp +++ b/MusicPlayer2/LyricEditDlg.cpp @@ -3,10 +3,10 @@ #include "stdafx.h" #include "MusicPlayer2.h" +#include "Player.h" #include "LyricEditDlg.h" -#include "afxdialogex.h" -#include "WIC.h" - +#include "FilterHelper.h" +#include "COSUPlayerHelper.h" // CLyricEditDlg 对话框 @@ -90,22 +90,24 @@ void CLyricEditDlg::OpreateTag(TagOpreation operation) bool CLyricEditDlg::SaveLyric(wstring path, CodeType code_type) { - bool is_osu{ CPlayer::GetInstance().IsOsuFile() }; - const SongInfo& song{ CPlayer::GetInstance().GetCurrentSongInfo() }; - bool lyric_write_support = CAudioTag::IsFileTypeLyricWriteSupport(CFilePathHelper(song.file_path).GetFileExtension()); + // 这里不应当依赖播放实例,因为当前播放与启动歌词编辑的SongInfo不一定是同一个 + CFilePathHelper song_path(m_current_edit_song.file_path); + bool lyric_write_support = CAudioTag::IsFileTypeLyricWriteSupport(song_path.GetFileExtension()); if (m_inner_lyric && lyric_write_support) { //写入内嵌歌词 bool saved{ false }; - SongInfo song_info{ song }; CPlayer::ReOpen reopen(true); if (reopen.IsLockSuccess()) { - CAudioTag audio_tag(song_info); + CAudioTag audio_tag(m_current_edit_song); saved = audio_tag.WriteAudioLyric(m_lyric_string); } else - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } if (saved) { m_modified = false; @@ -114,7 +116,8 @@ bool CLyricEditDlg::SaveLyric(wstring path, CodeType code_type) } else { - MessageBox(CCommon::LoadText(IDS_LYRIC_SAVE_FAILED), NULL, MB_ICONWARNING | MB_OK); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_LYRIC_SAVE_FAILED"); + MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK); } return saved; } @@ -123,17 +126,15 @@ bool CLyricEditDlg::SaveLyric(wstring path, CodeType code_type) //写入歌词文件 if (path.empty()) //如果保存时传递的路径的空字符串,则将保存路径设置为当前歌曲所在路径 { - if (!song.is_cue && !is_osu) + if (!m_current_edit_song.is_cue && !COSUPlayerHelper::IsOsuFile(m_current_edit_song.file_path)) { - m_lyric_path = CPlayer::GetInstance().GetCurrentDir() + CPlayer::GetInstance().GetFileName(); - int index = m_lyric_path.rfind(L'.'); - m_lyric_path = m_lyric_path.substr(0, index); + m_lyric_path = song_path.ReplaceFileExtension(L"lrc"); } else { - m_lyric_path = CPlayer::GetInstance().GetCurrentDir() + song.artist + L" - " + song.title; + m_lyric_path = song_path.GetDir() + m_current_edit_song.artist + L" - " + m_current_edit_song.title + L".lrc"; + CCommon::FileNameNormalize(m_lyric_path); } - m_lyric_path += L".lrc"; m_original_lyric_path = m_lyric_path; SetLyricPathEditText(); path = m_lyric_path; @@ -142,8 +143,9 @@ bool CLyricEditDlg::SaveLyric(wstring path, CodeType code_type) string lyric_str = CCommon::UnicodeToStr(m_lyric_string, code_type, &char_connot_convert); if (char_connot_convert) //当文件中包含Unicode字符时,询问用户是否要选择一个Unicode编码格式再保存 { - CString info{ CCommon::LoadText(IDS_STRING103) }; //从string table载入字符串 - if (MessageBox(info, NULL, MB_OKCANCEL | MB_ICONWARNING) != IDOK) return false; //如果用户点击了取消按钮,则返回false + const wstring& info = theApp.m_str_table.LoadText(L"MSG_UNICODE_WARNING"); + if (MessageBox(info.c_str(), NULL, MB_OKCANCEL | MB_ICONWARNING) != IDOK) + return false; //如果用户点击了取消按钮,则返回false } ofstream out_put{ path, std::ios::binary }; bool failed = out_put.fail(); @@ -157,7 +159,8 @@ bool CLyricEditDlg::SaveLyric(wstring path, CodeType code_type) } else { - MessageBox(CCommon::LoadText(IDS_LYRIC_SAVE_FAILED), NULL, MB_ICONWARNING | MB_OK); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_LYRIC_SAVE_FAILED"); + MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK); } return !failed; } @@ -165,25 +168,26 @@ bool CLyricEditDlg::SaveLyric(wstring path, CodeType code_type) void CLyricEditDlg::UpdateStatusbarInfo() { - CString str; //显示字符数 - str = CCommon::LoadTextFormat(IDS_CHARACTER_TOTAL, { m_lyric_string.size() }); - m_status_bar.SetText(str, 0, 0); - + wstring total_char = theApp.m_str_table.LoadTextFormat(L"TXT_LYRIC_EDIT_TOTAL_CHARACTER", { m_lyric_string.size() }); //显示是否修改 - m_status_bar.SetText(m_modified ? CCommon::LoadText(IDS_MODIFIED) : CCommon::LoadText(IDS_UNMODIFIED), 1, 0); - + wstring modified_info = m_modified ? theApp.m_str_table.LoadText(L"TXT_LYRIC_EDIT_MODIFIED") : theApp.m_str_table.LoadText(L"TXT_LYRIC_EDIT_UNMODIFIED"); //显示编码格式 - str = CCommon::LoadText(IDS_ENCODE_FORMAT, _T(": ")); + wstring str; switch (m_code_type) { - case CodeType::ANSI: str += _T("ANSI"); break; - case CodeType::UTF8: str += _T("UTF8"); break; - case CodeType::UTF8_NO_BOM: str += CCommon::LoadText(IDS_UTF8_NO_BOM); break; - case CodeType::UTF16LE: str += _T("UTF16LE"); break; - case CodeType::UTF16BE: str += _T("UTF16BE"); break; + case CodeType::ANSI: str = L"ANSI"; break; + case CodeType::UTF8: str = L"UTF8"; break; + case CodeType::UTF8_NO_BOM: str = theApp.m_str_table.LoadText(L"TXT_LYRIC_EDIT_UTF8NOBOM"); break; + case CodeType::UTF16LE: str = L"UTF16LE"; break; + case CodeType::UTF16BE: str = L"UTF16BE"; break; + default: str = L""; } - m_status_bar.SetText(str, 2, 0); + wstring encode_info = theApp.m_str_table.LoadTextFormat(L"TXT_LYRIC_EDIT_ENCODE_FORMAT", { str }); + + m_status_bar.SetText(total_char.c_str(), 0, 0); + m_status_bar.SetText(modified_info.c_str(), 1, 0); + m_status_bar.SetText(encode_info.c_str(), 2, 0); } void CLyricEditDlg::StatusBarSetParts(int width) @@ -207,7 +211,8 @@ bool CLyricEditDlg::SaveInquiry() { if (m_modified) { - int rtn = MessageBox(CCommon::LoadText(IDS_LYRIC_SAVE_INRUARY), NULL, MB_YESNOCANCEL | MB_ICONQUESTION); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_LYRIC_SAVE_INRUARY"); + int rtn = MessageBox(info.c_str(), NULL, MB_YESNOCANCEL | MB_ICONQUESTION); switch (rtn) { case IDYES: if (!SaveLyric(m_lyric_path.c_str(), m_code_type)) return false; @@ -221,7 +226,7 @@ bool CLyricEditDlg::SaveInquiry() void CLyricEditDlg::SetLyricPathEditText() { if (m_inner_lyric) - SetDlgItemText(IDC_LYRIC_PATH_EDIT2, CCommon::LoadText(IDS_INNER_LYRIC)); + SetDlgItemText(IDC_LYRIC_PATH_EDIT2, theApp.m_str_table.LoadText(L"TXT_INNER_LYRIC").c_str()); else SetDlgItemText(IDC_LYRIC_PATH_EDIT2, m_lyric_path.c_str()); } @@ -247,6 +252,23 @@ CString CLyricEditDlg::GetDialogName() const return _T("LyricEditDlg"); } +bool CLyricEditDlg::InitializeControls() +{ + CBaseDialog::SetMinSize(theApp.DPI(300), theApp.DPI(300)); + wstring temp; + temp = theApp.m_str_table.LoadText(L"TITLE_LYRIC_EDIT"); + SetWindowTextW(temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_EDIT_LYRIC_PATH"); + SetDlgItemTextW(IDC_STATIC1, temp.c_str()); + // IDC_LYRIC_PATH_EDIT2 + + RepositionTextBasedControls({ + { CtrlTextInfo::L1, IDC_STATIC1 }, + { CtrlTextInfo::C0, IDC_LYRIC_PATH_EDIT2 } + }, CtrlTextInfo::W128); + return true; +} + void CLyricEditDlg::DoDataExchange(CDataExchange* pDX) { CBaseDialog::DoDataExchange(pDX); @@ -254,14 +276,8 @@ void CLyricEditDlg::DoDataExchange(CDataExchange* pDX) BEGIN_MESSAGE_MAP(CLyricEditDlg, CBaseDialog) - //ON_BN_CLICKED(IDC_INSERT_TAG_BUTTON, &CLyricEditDlg::OnBnClickedInsertTagButton) - //ON_BN_CLICKED(IDC_REPLACE_TAG_BUTTON, &CLyricEditDlg::OnBnClickedReplaceTagButton) - //ON_BN_CLICKED(IDC_DELETE_TAG__BUTTON, &CLyricEditDlg::OnBnClickedDeleteTag) - //ON_BN_CLICKED(IDC_SAVE_LYRIC_BUTTON, &CLyricEditDlg::OnBnClickedSaveLyricButton) - //ON_BN_CLICKED(IDC_SAVE_AS_BUTTON5, &CLyricEditDlg::OnBnClickedSaveAsButton5) ON_WM_DESTROY() ON_WM_CLOSE() - //ON_BN_CLICKED(IDC_OPEN_LYRIC_BUTTON, &CLyricEditDlg::OnBnClickedOpenLyricButton) ON_COMMAND(ID_LYRIC_OPEN, &CLyricEditDlg::OnLyricOpen) ON_COMMAND(ID_LYRIC_SAVE, &CLyricEditDlg::OnLyricSave) ON_COMMAND(ID_LYRIC_SAVE_AS, &CLyricEditDlg::OnLyricSaveAs) @@ -291,14 +307,13 @@ END_MESSAGE_MAP() BOOL CLyricEditDlg::OnInitDialog() { - CBaseDialog::SetMinSize(theApp.DPI(300), theApp.DPI(300)); CBaseDialog::OnInitDialog(); // TODO: 在此添加额外的初始化 CenterWindow(); - SetIcon(theApp.m_icon_set.edit.GetIcon(true), FALSE); - SetIcon(AfxGetApp()->LoadIcon(IDI_EDIT_D), TRUE); + SetIcon(IconMgr::IconType::IT_Edit, FALSE); + SetIcon(IconMgr::IconType::IT_Edit, TRUE); m_view = (CScintillaEditView*)RUNTIME_CLASS(CScintillaEditView)->CreateObject(); m_view->Create(NULL, NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL, CalculateEditCtrlRect(), this, 3000); @@ -323,10 +338,10 @@ BOOL CLyricEditDlg::OnInitDialog() } m_original_lyric_path = m_lyric_path; //m_code_type = CPlayer::GetInstance().m_Lyrics.GetCodeType(); - m_current_song_name = CPlayer::GetInstance().GetFileName(); + m_current_edit_song = CPlayer::GetInstance().GetCurrentSongInfo(); //初始化编辑区字体 - m_view->SetFontFace(CCommon::LoadText(IDS_DEFAULT_FONT)); + m_view->SetFontFace(theApp.m_str_table.GetDefaultFontName().c_str()); m_view->SetFontSize(10); m_view->SetTextW(m_lyric_string); @@ -336,53 +351,8 @@ BOOL CLyricEditDlg::OnInitDialog() SetLyricPathEditText(); - ////初始化提示信息 - //m_Mytip.Create(this, TTS_ALWAYSTIP); - //m_Mytip.AddTool(GetDlgItem(IDC_INSERT_TAG_BUTTON), _T("在光标所在行的最左边插入一个时间标签,快捷键:F8")); - //m_Mytip.AddTool(GetDlgItem(IDC_REPLACE_TAG_BUTTON), _T("替换光标所在行最左边的时间标签,快捷键:F9")); - //m_Mytip.AddTool(GetDlgItem(IDC_DELETE_TAG__BUTTON), _T("删除光标处的时间标签,快捷键:Ctrl+Del")); - //m_Mytip.AddTool(GetDlgItem(IDC_SAVE_LYRIC_BUTTON), _T("快捷键:Ctrl+S")); - //m_Mytip.AddTool(GetDlgItem(ID_PLAY_PAUSE), _T("快捷键:Ctrl+P")); - //m_Mytip.AddTool(GetDlgItem(ID_REW), _T("快捷键:Ctrl+←")); - //m_Mytip.AddTool(GetDlgItem(ID_FF), _T("快捷键:Ctrl+→")); - - ////获取初始时窗口的大小 - //CRect rect; - //GetWindowRect(rect); - //m_min_size.cx = rect.Width(); - //m_min_size.cy = rect.Height(); - - //为菜单添加图标 - CMenu* pMenu = GetMenu(); - if (pMenu != nullptr) - { - CMenuIcon::AddIconToMenuItem(pMenu->GetSafeHmenu(), ID_LYRIC_OPEN, FALSE, theApp.m_icon_set.music); - CMenuIcon::AddIconToMenuItem(pMenu->GetSafeHmenu(), ID_LYRIC_SAVE, FALSE, theApp.m_icon_set.save_new); - CMenuIcon::AddIconToMenuItem(pMenu->GetSafeHmenu(), ID_LYRIC_SAVE_AS, FALSE, theApp.m_icon_set.save_as); - CMenuIcon::AddIconToMenuItem(pMenu->GetSafeHmenu(), IDCANCEL, FALSE, theApp.m_icon_set.exit); - CMenuIcon::AddIconToMenuItem(pMenu->GetSafeHmenu(), ID_LYRIC_INSERT_TAG, FALSE, theApp.m_icon_set.exit); - - HICON icon_add_tag = CDrawCommon::LoadIconResource(IDI_ADD_TAG, theApp.DPI(16), theApp.DPI(16)); - HICON icon_replace_tag = CDrawCommon::LoadIconResource(IDI_REPLACE_TAG, theApp.DPI(16), theApp.DPI(16)); - HICON icon_delete_tag = CDrawCommon::LoadIconResource(IDI_DELETE_TAG, theApp.DPI(16), theApp.DPI(16)); - HICON icon_find = CDrawCommon::LoadIconResource(IDI_FIND, theApp.DPI(16), theApp.DPI(16)); - HICON icon_replace = CDrawCommon::LoadIconResource(IDI_REPLACE, theApp.DPI(16), theApp.DPI(16)); - CMenuIcon::AddIconToMenuItem(pMenu->GetSafeHmenu(), ID_LYRIC_INSERT_TAG, FALSE, icon_add_tag); - CMenuIcon::AddIconToMenuItem(pMenu->GetSafeHmenu(), ID_LYRIC_REPLACE_TAG, FALSE, icon_replace_tag); - CMenuIcon::AddIconToMenuItem(pMenu->GetSafeHmenu(), ID_LYRIC_DELETE_TAG, FALSE, icon_delete_tag); - CMenuIcon::AddIconToMenuItem(pMenu->GetSafeHmenu(), ID_LYRIC_FIND, FALSE, icon_find); - CMenuIcon::AddIconToMenuItem(pMenu->GetSafeHmenu(), ID_LYRIC_REPLACE, FALSE, icon_replace); - DestroyIcon(icon_add_tag); - DestroyIcon(icon_replace_tag); - DestroyIcon(icon_delete_tag); - DestroyIcon(icon_find); - DestroyIcon(icon_replace); - - CMenuIcon::AddIconToMenuItem(pMenu->GetSafeHmenu(), ID_PLAY_PAUSE, FALSE, theApp.m_icon_set.play_pause); - CMenuIcon::AddIconToMenuItem(pMenu->GetSafeHmenu(), ID_REW, FALSE, theApp.m_icon_set.rew_new); - CMenuIcon::AddIconToMenuItem(pMenu->GetSafeHmenu(), ID_FF, FALSE, theApp.m_icon_set.ff_new); - CMenuIcon::AddIconToMenuItem(pMenu->GetSafeHmenu(), ID_SEEK_TO_CUR_LINE, FALSE, theApp.m_icon_set.locate.GetIcon(true)); - } + // 设置窗口菜单 (窗口销毁前记得先分离菜单句柄) + ::SetMenu(m_hWnd, theApp.m_menu_mgr.GetSafeHmenu(MenuMgr::LeMenu)); //初始化工具栏 if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE/* | CBRS_TOP*/ | CBRS_ALIGN_TOP | CBRS_BORDER_BOTTOM | CBRS_BORDER_TOP @@ -393,24 +363,23 @@ BOOL CLyricEditDlg::OnInitDialog() return -1; // fail to create } RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0); - int icon_size = theApp.DPI(20); - if (icon_size < 32) - icon_size = CCommon::IconSizeNormalize(icon_size); + + CSize icon_size = IconMgr::GetIconSize(IconMgr::IconSize::IS_DPI_20); CImageList ImageList; - ImageList.Create(icon_size, icon_size, ILC_COLOR32 | ILC_MASK, 2, 2); + ImageList.Create(icon_size.cx, icon_size.cy, ILC_COLOR32 | ILC_MASK, 2, 2); //通过ImageList对象加载图标作为工具栏的图标 //添加图标 - ImageList.Add(CDrawCommon::LoadIconResource(IDI_ADD_TAG, icon_size, icon_size)); - ImageList.Add(CDrawCommon::LoadIconResource(IDI_REPLACE_TAG, icon_size, icon_size)); - ImageList.Add(CDrawCommon::LoadIconResource(IDI_DELETE_TAG, icon_size, icon_size)); - ImageList.Add(CDrawCommon::LoadIconResource(IDI_SAVE, icon_size, icon_size)); - ImageList.Add(CDrawCommon::LoadIconResource(IDI_PLAY_PAUSE, icon_size, icon_size)); - ImageList.Add(CDrawCommon::LoadIconResource(IDI_REW, icon_size, icon_size)); - ImageList.Add(CDrawCommon::LoadIconResource(IDI_FF, icon_size, icon_size)); - ImageList.Add(CDrawCommon::LoadIconResource(IDI_LOCATE_D, icon_size, icon_size)); - ImageList.Add(CDrawCommon::LoadIconResource(IDI_FIND, icon_size, icon_size)); - ImageList.Add(CDrawCommon::LoadIconResource(IDI_REPLACE, icon_size, icon_size)); + ImageList.Add(theApp.m_icon_mgr.GetHICON(IconMgr::IconType::IT_Le_Tag_Insert, IconMgr::IconStyle::IS_Color, IconMgr::IconSize::IS_DPI_20)); + ImageList.Add(theApp.m_icon_mgr.GetHICON(IconMgr::IconType::IT_Le_Tag_Replace, IconMgr::IconStyle::IS_Color, IconMgr::IconSize::IS_DPI_20)); + ImageList.Add(theApp.m_icon_mgr.GetHICON(IconMgr::IconType::IT_Le_Tag_Delete, IconMgr::IconStyle::IS_Color, IconMgr::IconSize::IS_DPI_20)); + ImageList.Add(theApp.m_icon_mgr.GetHICON(IconMgr::IconType::IT_Le_Save, IconMgr::IconStyle::IS_Color, IconMgr::IconSize::IS_DPI_20)); + ImageList.Add(theApp.m_icon_mgr.GetHICON(IconMgr::IconType::IT_Play_Pause, IconMgr::IconStyle::IS_Filled, IconMgr::IconSize::IS_DPI_20)); + ImageList.Add(theApp.m_icon_mgr.GetHICON(IconMgr::IconType::IT_Rewind, IconMgr::IconStyle::IS_Filled, IconMgr::IconSize::IS_DPI_20)); + ImageList.Add(theApp.m_icon_mgr.GetHICON(IconMgr::IconType::IT_Fast_Forward, IconMgr::IconStyle::IS_Filled, IconMgr::IconSize::IS_DPI_20)); + ImageList.Add(theApp.m_icon_mgr.GetHICON(IconMgr::IconType::IT_Locate, IconMgr::IconStyle::IS_OutlinedDark, IconMgr::IconSize::IS_DPI_20)); + ImageList.Add(theApp.m_icon_mgr.GetHICON(IconMgr::IconType::IT_Le_Find, IconMgr::IconStyle::IS_Color, IconMgr::IconSize::IS_DPI_20)); + ImageList.Add(theApp.m_icon_mgr.GetHICON(IconMgr::IconType::IT_Le_Replace, IconMgr::IconStyle::IS_Color, IconMgr::IconSize::IS_DPI_20)); m_wndToolBar.GetToolBarCtrl().SetImageList(&ImageList); ImageList.Detach(); SetToolbarCmdEnable(); @@ -487,9 +456,12 @@ void CLyricEditDlg::OnCancel() void CLyricEditDlg::OnDestroy() { // TODO: 在此处添加消息处理程序代码 + ::SetMenu(m_hWnd, NULL); // 菜单对象/句柄由MenuMgr管理,这里分离菜单以免句柄被销毁 + CBaseDialog::OnDestroy(); + m_dlg_exist = false; - if (m_current_song_name == CPlayer::GetInstance().GetFileName() && m_lyric_saved) //关闭歌词编辑窗口时如果正在播放的歌曲没有变,且执行过保存操作,就重新初始化歌词 + if (m_current_edit_song.IsSameSong(CPlayer::GetInstance().GetCurrentSongInfo()) && m_lyric_saved) // 关闭歌词编辑窗口时如果正在播放的歌曲没有变,且执行过保存操作,就重新初始化歌词 { if (CPlayer::GetInstance().IsInnerLyric()) { @@ -613,7 +585,8 @@ void CLyricEditDlg::OnLyricOpen() // TODO: 在此添加命令处理程序代码 if (m_modified) { - int rtn = MessageBox(CCommon::LoadText(IDS_LYRIC_SAVE_INRUARY), NULL, MB_YESNOCANCEL | MB_ICONQUESTION); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_LYRIC_SAVE_INRUARY"); + int rtn = MessageBox(info.c_str(), NULL, MB_YESNOCANCEL | MB_ICONQUESTION); switch (rtn) { case IDYES: @@ -629,9 +602,9 @@ void CLyricEditDlg::OnLyricOpen() } //设置过滤器 - CString szFilter = CCommon::LoadText(IDS_LYRIC_FILE_FILTER); + wstring filter = FilterHelper::GetLyricFileFilter(); //构造打开文件对话框 - CFileDialog fileDlg(TRUE, _T("txt"), NULL, 0, szFilter, this); + CFileDialog fileDlg(TRUE, _T("txt"), NULL, 0, filter.c_str(), this); //显示打开文件对话框 if (IDOK == fileDlg.DoModal()) { @@ -656,15 +629,16 @@ void CLyricEditDlg::OnLyricSaveAs() { // TODO: 在此添加命令处理程序代码 //构造保存文件对话框 - CString default_path = m_lyric_path.c_str(); + wstring default_path = m_lyric_path; if (m_inner_lyric) default_path = CFilePathHelper(CPlayer::GetInstance().GetCurrentFilePath()).ReplaceFileExtension(L"lrc").c_str(); - CFileDialog fileDlg(FALSE, _T("txt"), default_path, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, CCommon::LoadText(IDS_LYRIC_FILE_FILTER), this); + wstring filter = FilterHelper::GetLyricFileFilter(); + CFileDialog fileDlg(FALSE, _T("txt"), default_path.c_str(), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, filter.c_str(), this); //为“另存为”对话框添加一个组合选择框 fileDlg.AddComboBox(IDC_SAVE_COMBO_BOX); //为组合选择框添加项目 - fileDlg.AddControlItem(IDC_SAVE_COMBO_BOX, 0, CCommon::LoadText(IDS_SAVE_AS_ANSI)); - fileDlg.AddControlItem(IDC_SAVE_COMBO_BOX, 1, CCommon::LoadText(IDS_SAVE_AS_UTF8)); + fileDlg.AddControlItem(IDC_SAVE_COMBO_BOX, 0, theApp.m_str_table.LoadText(L"TXT_SAVE_AS_ANSI").c_str()); + fileDlg.AddControlItem(IDC_SAVE_COMBO_BOX, 1, theApp.m_str_table.LoadText(L"TXT_SAVE_AS_UTF8").c_str()); //为组合选择框设置默认选中的项目 DWORD default_selected{ 0 }; if (m_code_type == CodeType::UTF8 || m_code_type == CodeType::UTF8_NO_BOM) @@ -782,9 +756,8 @@ afx_msg LRESULT CLyricEditDlg::OnFindReplace(WPARAM wParam, LPARAM lParam) UpdateStatusbarInfo(); if (replace_count != 0) { - CString info; - info = CCommon::LoadTextFormat(IDS_REPLACE_COMPLETE_INFO, { replace_count }); - MessageBox(info, NULL, MB_ICONINFORMATION); + wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_LYRIC_EDIT_STRING_REPLACE_COMPLETE", { replace_count }); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION); } } if (m_pReplaceDlg->IsTerminating()) @@ -805,9 +778,8 @@ void CLyricEditDlg::OnFindNext() m_find_index = m_lyric_string.rfind(m_find_str, m_find_index - 1); //向前查找 if (m_find_index == string::npos) { - CString info; - info = CCommon::LoadTextFormat(IDS_CONNOT_FIND_STRING, { m_find_str }); - MessageBox(info, NULL, MB_OK | MB_ICONINFORMATION); + wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_LYRIC_EDIT_STRING_CANNOT_FIND", { m_find_str }); + MessageBox(info.c_str(), NULL, MB_OK | MB_ICONINFORMATION); m_find_flag = false; } else @@ -850,16 +822,6 @@ void CLyricEditDlg::OnSize(UINT nType, int cx, int cy) //调整窗口的大小和位置 if (nType != SIZE_MINIMIZED) { - CRect rect; - CWnd* plyric_path_wnd{ GetDlgItem(IDC_LYRIC_PATH_EDIT2) }; - if (plyric_path_wnd != nullptr) - { - plyric_path_wnd->GetWindowRect(rect); - ScreenToClient(&rect); - rect.right = cx - MARGIN; - plyric_path_wnd->MoveWindow(rect); - } - if (m_view->GetSafeHwnd() != NULL) { m_view->MoveWindow(CalculateEditCtrlRect()); @@ -867,6 +829,7 @@ void CLyricEditDlg::OnSize(UINT nType, int cx, int cy) if (m_wndToolBar.m_hWnd != NULL) { + CRect rect; rect.left = 0; rect.top = 0; rect.right = cx; @@ -927,42 +890,42 @@ BOOL CLyricEditDlg::OnToolTipText(UINT, NMHDR* pNMHDR, LRESULT* pResult) { TOOLTIPTEXT* pT = (TOOLTIPTEXT*)pNMHDR; //将pNMHDR转换成TOOLTIPTEXT指针类型数据 UINT nID = pNMHDR->idFrom; //获取工具条上按钮的ID - CString tipInfo; + wstring tipInfo; switch (nID) { case ID_LYRIC_INSERT_TAG: - tipInfo = CCommon::LoadText(IDS_INSERT_TIME_TAG_TIP); + tipInfo = theApp.m_str_table.LoadText(L"TIP_LYRIC_EDIT_INSERT_TIME_TAG") + L" (F8)"; break; case ID_LYRIC_REPLACE_TAG: - tipInfo = CCommon::LoadText(IDS_REPLACE_TIME_TAG_TIP); + tipInfo = theApp.m_str_table.LoadText(L"TIP_LYRIC_EDIT_REPLACE_TIME_TAG") + L" (F9)"; break; case ID_LYRIC_DELETE_TAG: - tipInfo = CCommon::LoadText(IDS_DELETE_TIME_TAG_TIP); + tipInfo = theApp.m_str_table.LoadText(L"TIP_LYRIC_EDIT_DELETE_TIME_TAG") + L" (Ctrl+Del)"; break; case ID_LYRIC_SAVE: - tipInfo = CCommon::LoadText(IDS_SAVE_TIP); + tipInfo = theApp.m_str_table.LoadText(L"TIP_LYRIC_EDIT_SAVE") + L" (Ctrl+S)"; break; case ID_PLAY_PAUSE: - tipInfo = CCommon::LoadText(IDS_PLAY_PAUSE_TIP); + tipInfo = theApp.m_str_table.LoadText(L"TIP_LYRIC_EDIT_PLAY_PAUSE") + L" (Ctrl+P)"; break; case ID_REW: - tipInfo = CCommon::LoadText(IDS_REWIND_TIP); + tipInfo = theApp.m_str_table.LoadText(L"TIP_LYRIC_EDIT_REWIND") + L" (Ctrl+←)"; break; case ID_FF: - tipInfo = CCommon::LoadText(IDS_FAST_FOWARD_TIP); + tipInfo = theApp.m_str_table.LoadText(L"TIP_LYRIC_EDIT_FAST_FOWARD") + L" (Ctrl+→)"; break; case ID_LYRIC_FIND: - tipInfo = CCommon::LoadText(IDS_FIND_TIP); + tipInfo = theApp.m_str_table.LoadText(L"TIP_LYRIC_EDIT_FIND") + L" (Ctrl+F)"; break; case ID_LYRIC_REPLACE: - tipInfo = CCommon::LoadText(IDS_REPLACE_TIP); + tipInfo = theApp.m_str_table.LoadText(L"TIP_LYRIC_EDIT_REPLACE") + L" (Ctrl+H)"; break; case ID_SEEK_TO_CUR_LINE: - tipInfo = CCommon::LoadText(IDS_SEEK_TO_LINE_TIP); + tipInfo = theApp.m_str_table.LoadText(L"TIP_LYRIC_EDIT_INSERT_TIME_TAG") + L" (Ctrl+G)"; break; } - CCommon::WStringCopy(pT->szText, 80, tipInfo.GetString()); + CCommon::WStringCopy(pT->szText, 80, tipInfo.c_str()); return 0; } diff --git a/MusicPlayer2/LyricEditDlg.h b/MusicPlayer2/LyricEditDlg.h index 5b671bc77..ec7ab0e66 100644 --- a/MusicPlayer2/LyricEditDlg.h +++ b/MusicPlayer2/LyricEditDlg.h @@ -1,9 +1,9 @@ #pragma once -#include "afxwin.h" #include "Time.h" #include "EditEx.h" #include "BaseDialog.h" #include "ScintillaEditView.h" +#include "Lyric.h" const int WM_FINDREPLACE = ::RegisterWindowMessage(FINDMSGSTRING); //将FINDMSGSTRING注册为WM_FINDREPLACE消息 @@ -37,7 +37,7 @@ class CLyricEditDlg : public CBaseDialog wstring m_lyric_path; //歌词路径 wstring m_original_lyric_path; //原来的歌词(当前播放歌曲对应的歌词)的路径 CodeType m_code_type; //歌词编码 - wstring m_current_song_name; //正在播放的歌曲名 + SongInfo m_current_edit_song; // 启动歌词编辑的SongInfo CLyrics::LyricType m_lyric_type{}; bool m_modified{ false }; //如果歌词已更改,则为true bool m_lyric_saved{ false }; //如果执行过保存操作,则为true @@ -71,6 +71,7 @@ class CLyricEditDlg : public CBaseDialog void SetToolbarCmdEnable(); virtual CString GetDialogName() const override; + virtual bool InitializeControls() override; virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() diff --git a/MusicPlayer2/LyricRelateDlg.cpp b/MusicPlayer2/LyricRelateDlg.cpp index bb0def3a8..2776f8fa1 100644 --- a/MusicPlayer2/LyricRelateDlg.cpp +++ b/MusicPlayer2/LyricRelateDlg.cpp @@ -3,10 +3,13 @@ #include "stdafx.h" #include "MusicPlayer2.h" +#include "Player.h" #include "LyricRelateDlg.h" #include "SongInfoHelper.h" #include "MusicPlayerCmdHelper.h" #include "SongDataManager.h" +#include "FilterHelper.h" +#include "CommonDialogMgr.h" // CLyricRelateDlg 对话框 @@ -49,7 +52,7 @@ void CLyricRelateDlg::AddListRow(const wstring& lyric_path) bool is_related{ lyric_path == CPlayer::GetInstance().GetCurrentSongInfo().lyric_file }; if(is_related) { - m_result_list.SetItemText(index, 3, CCommon::LoadText(IDS_YES)); + m_result_list.SetItemText(index, 3, theApp.m_str_table.LoadText(L"TXT_LRC_RELATE_IS_RELATED_YES").c_str()); m_result_list.SetHightItem(index); } } @@ -93,6 +96,50 @@ CString CLyricRelateDlg::GetDialogName() const return _T("LyricRelateDlg"); } +bool CLyricRelateDlg::InitializeControls() +{ + wstring temp; + temp = theApp.m_str_table.LoadText(L"TITLE_LRC_RELATE"); + SetWindowTextW(temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_LRC_RELATE_LRC_TITLE"); + SetDlgItemTextW(IDC_TXT_LRC_RELATE_LRC_TITLE_STATIC, temp.c_str()); + // IDC_LYRIC_NAME_EDIT + temp = theApp.m_str_table.LoadText(L"TXT_LRC_RELATE_FUZZY_MATCH"); + SetDlgItemTextW(IDC_FUZZY_MATCH_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_LRC_RELATE_SEARCH_LOCAL"); + SetDlgItemTextW(IDC_LOCAL_SEARCH_BUTTON, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_LRC_RELATE_SEARCH_RESULT"); + SetDlgItemTextW(IDC_TXT_LRC_RELATE_SEARCH_RESULT_STATIC, temp.c_str()); + // IDC_SEARCH_RESULT_LIST + temp = theApp.m_str_table.LoadText(L"TXT_LRC_RELATE_BROWSE"); + SetDlgItemTextW(IDC_BROWSE_BUTTON1, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_LRC_RELATE_DEL_FILE"); + SetDlgItemTextW(IDC_DELETE_FILE_BUTTON, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_LRC_RELATE_UNLINK"); + SetDlgItemTextW(IDC_DONOT_RELATE_BUTTON, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_LRC_RELATE_SEL_LINK"); + SetDlgItemTextW(IDOK, temp.c_str()); + // IDCANCEL + + RepositionTextBasedControls({ + { CtrlTextInfo::L1, IDC_TXT_LRC_RELATE_LRC_TITLE_STATIC }, + { CtrlTextInfo::C0, IDC_LYRIC_NAME_EDIT }, + { CtrlTextInfo::R1, IDC_FUZZY_MATCH_CHECK, CtrlTextInfo::W16 }, + { CtrlTextInfo::R2, IDC_LOCAL_SEARCH_BUTTON, CtrlTextInfo::W32 } + }, CtrlTextInfo::W128); + RepositionTextBasedControls({ + { CtrlTextInfo::C0, IDC_SEARCH_RESULT_LIST }, + { CtrlTextInfo::R1, IDC_BROWSE_BUTTON1, CtrlTextInfo::W32 }, + { CtrlTextInfo::R1, IDC_DELETE_FILE_BUTTON, CtrlTextInfo::W32 } + }, CtrlTextInfo::W256); + RepositionTextBasedControls({ + { CtrlTextInfo::L1, IDC_DONOT_RELATE_BUTTON, CtrlTextInfo::W32 }, + { CtrlTextInfo::R1, IDOK, CtrlTextInfo::W32 }, + { CtrlTextInfo::R2, IDCANCEL, CtrlTextInfo::W32 } + }); + return true; +} + void CLyricRelateDlg::DoDataExchange(CDataExchange* pDX) { CBaseDialog::DoDataExchange(pDX); @@ -119,11 +166,11 @@ BOOL CLyricRelateDlg::OnInitDialog() CBaseDialog::OnInitDialog(); // TODO: 在此添加额外的初始化 - SetIcon(theApp.m_icon_set.lyric.GetIcon(true), FALSE); - SetButtonIcon(IDC_LOCAL_SEARCH_BUTTON, theApp.m_icon_set.find_songs.GetIcon(true)); - SetButtonIcon(IDC_BROWSE_BUTTON1, theApp.m_icon_set.folder_explore.GetIcon(true)); - SetButtonIcon(IDC_DELETE_FILE_BUTTON, theApp.m_icon_set.close.GetIcon(true)); - SetButtonIcon(IDC_DONOT_RELATE_BUTTON, theApp.m_icon_set.unlink.GetIcon(true)); + SetIcon(IconMgr::IconType::IT_Lyric, FALSE); + SetButtonIcon(IDC_LOCAL_SEARCH_BUTTON, IconMgr::IconType::IT_Find); + SetButtonIcon(IDC_BROWSE_BUTTON1, IconMgr::IconType::IT_Folder_Explore); + SetButtonIcon(IDC_DELETE_FILE_BUTTON, IconMgr::IconType::IT_Cancel); + SetButtonIcon(IDC_DONOT_RELATE_BUTTON, IconMgr::IconType::IT_Unlink); wstring lyric_name; if (CPlayer::GetInstance().GetCurrentSongInfo().is_cue || CPlayer::GetInstance().IsOsuFile()) @@ -142,10 +189,10 @@ BOOL CLyricRelateDlg::OnInitDialog() width[1] = rect.Width() * 3 / 10; width[2] = rect.Width() * 2 / 5; width[3] = rect.Width() - width[0] - width[1] - width[2] - theApp.DPI(20) - 1; - m_result_list.InsertColumn(0, CCommon::LoadText(IDS_NUMBER), LVCFMT_LEFT, width[0]); - m_result_list.InsertColumn(1, CCommon::LoadText(IDS_FILE_NAME), LVCFMT_LEFT, width[1]); - m_result_list.InsertColumn(2, CCommon::LoadText(IDS_FILE_PATH), LVCFMT_LEFT, width[2]); - m_result_list.InsertColumn(3, CCommon::LoadText(IDS_IS_RELATED), LVCFMT_LEFT, width[3]); + m_result_list.InsertColumn(0, theApp.m_str_table.LoadText(L"TXT_SERIAL_NUMBER").c_str(), LVCFMT_LEFT, width[0]); + m_result_list.InsertColumn(1, theApp.m_str_table.LoadText(L"TXT_FILE_NAME").c_str(), LVCFMT_LEFT, width[1]); + m_result_list.InsertColumn(2, theApp.m_str_table.LoadText(L"TXT_FILE_PATH").c_str(), LVCFMT_LEFT, width[2]); + m_result_list.InsertColumn(3, theApp.m_str_table.LoadText(L"TXT_LRC_RELATE_IS_RELATED").c_str(), LVCFMT_LEFT, width[3]); SearchLyrics(); ShowSearchResult(); @@ -166,9 +213,9 @@ void CLyricRelateDlg::OnBnClickedLocalSearchButton() void CLyricRelateDlg::OnBnClickedBrowseButton1() { // TODO: 在此添加控件通知处理程序代码 - CString szFilter = CCommon::LoadText(IDS_LYRIC_FILE_FILTER); + wstring filter = FilterHelper::GetLyricFileFilter(); //构造打开文件对话框 - CFileDialog fileDlg(TRUE, NULL, NULL, 0, szFilter, this); + CFileDialog fileDlg(TRUE, NULL, NULL, 0, filter.c_str(), this); //显示打开文件对话框 if (IDOK == fileDlg.DoModal()) { @@ -183,7 +230,7 @@ void CLyricRelateDlg::OnBnClickedDeleteFileButton() // TODO: 在此添加控件通知处理程序代码 int index_selected = m_result_list.GetCurSel(); wstring lyric_file = GetListRow(index_selected); - CCommon::DeleteAFile(m_hWnd, lyric_file); + CommonDialogMgr::DeleteAFile(m_hWnd, lyric_file); if (lyric_file == CPlayer::GetInstance().GetCurrentSongInfo().lyric_file) { //如果删除的是正在显示的歌词,则将其清除 diff --git a/MusicPlayer2/LyricRelateDlg.h b/MusicPlayer2/LyricRelateDlg.h index 5c8cf1e24..dd1638b78 100644 --- a/MusicPlayer2/LyricRelateDlg.h +++ b/MusicPlayer2/LyricRelateDlg.h @@ -36,6 +36,7 @@ class CLyricRelateDlg : public CBaseDialog protected: virtual CString GetDialogName() const override; + virtual bool InitializeControls() override; virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() diff --git a/MusicPlayer2/LyricSettingsDlg.cpp b/MusicPlayer2/LyricSettingsDlg.cpp index 29ab2ca45..b07de78db 100644 --- a/MusicPlayer2/LyricSettingsDlg.cpp +++ b/MusicPlayer2/LyricSettingsDlg.cpp @@ -4,9 +4,9 @@ #include "stdafx.h" #include "MusicPlayer2.h" #include "LyricSettingsDlg.h" -#include "afxdialogex.h" #include "CortanaLyric.h" #include "MusicPlayerDlg.h" +#include "WinVersionHelper.h" // CLyricSettingsDlg 对话框 @@ -22,6 +22,113 @@ CLyricSettingsDlg::~CLyricSettingsDlg() { } +bool CLyricSettingsDlg::InitializeControls() +{ + wstring temp; + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_OPT"); + SetDlgItemTextW(IDC_TXT_OPT_LRC_OPT_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_USE_INNER_FIRST"); + SetDlgItemTextW(IDC_USE_INNER_LYRIC_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_FUZZY_MATCH"); + SetDlgItemTextW(IDC_LYRIC_FUZZY_MATCH, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_SHOW_TRANSLATION"); + SetDlgItemTextW(IDC_SHOW_LYRIC_TRANSLATE_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_SONG_INFO_IF_NO_LRC"); + SetDlgItemTextW(IDC_SHOW_SONG_INFO_IF_LYRIC_NOT_EXIST_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_LRC_FOLDER"); + SetDlgItemTextW(IDC_TXT_OPT_LRC_LRC_FOLDER_STATIC, temp.c_str()); + // IDC_LYRIC_PATH_EDIT + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_SAVE_POLICY_SEL"); + SetDlgItemTextW(IDC_TXT_OPT_LRC_SAVE_POLICY_SEL_STATIC, temp.c_str()); + // IDC_LYRIC_SAVE_COMBO + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_KARAOKE_DISP"); + SetDlgItemTextW(IDC_KARAOKE_DISP, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_USE_MUSIC_SYMBOL"); + SetDlgItemTextW(IDC_LYRIC_HIDE_BLANK_LINE_CHECK, temp.c_str()); + + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_WINDOW_LRC"); + SetDlgItemTextW(IDC_TXT_OPT_LRC_WINDOW_LRC_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_WINDOW_LRC_LINE_SPACING"); + SetDlgItemTextW(IDC_TXT_OPT_LRC_WINDOW_LRC_LINE_SPACING_STATIC, temp.c_str()); + // IDC_FONT_SIZE_EDIT2 + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_ALIGN_SEL"); + SetDlgItemTextW(IDC_TXT_OPT_LRC_WINDOW_LRC_ALIGN_SEL_STATIC, temp.c_str()); + // IDC_ALIGNMENT_COMBO2 + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_FONT_SEL"); + SetDlgItemTextW(IDC_SET_FONT_BUTTON, temp.c_str()); + + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_DESKTOP_LRC"); + SetDlgItemTextW(IDC_TXT_OPT_LRC_DESKTOP_LRC_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_DESKTOP_LRC_ENABLE"); + SetDlgItemTextW(IDC_SHOW_DESKTOP_LYRIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_DESKTOP_LRC_BG_PENETRATE"); + SetDlgItemTextW(IDC_HIDE_LYRIC_WITHOUT_LYRIC_CHECK3, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_DESKTOP_LRC_HIDE_NO_LRC"); + SetDlgItemTextW(IDC_HIDE_LYRIC_WITHOUT_LYRIC_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_DESKTOP_LRC_HIDE_PAUSE"); + SetDlgItemTextW(IDC_HIDE_LYRIC_PAUSE_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_DESKTOP_LRC_LOCK"); + SetDlgItemTextW(IDC_LOCK_DESKTOP_LYRIC_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_DESKTOP_LRC_SHOW_UNLOCK_WHEN_LOCK"); + SetDlgItemTextW(IDC_SHOW_UNLOCK_WHEN_LOCKED, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_DOUBLE_LINE"); + SetDlgItemTextW(IDC_LYRIC_DOUBLE_LINE_CHECK2, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_DESKTOP_LRC_COLOR_TEXT"); + SetDlgItemTextW(IDC_TXT_OPT_LRC_DESKTOP_LRC_COLOR_TEXT_STATIC, temp.c_str()); + // IDC_TEXT_COLOR1_STATIC + // IDC_TEXT_COLOR2_STATIC + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_DESKTOP_LRC_COLOR_HIGHLIGHT"); + SetDlgItemTextW(IDC_TXT_OPT_LRC_DESKTOP_LRC_COLOR_HIGHLIGHT_STATIC, temp.c_str()); + // IDC_HIGHLIGHT_COLOR1_STATIC + // IDC_HIGHLIGHT_COLOR2_STATIC + // IDC_TEXT_GRADIENT_COMBO + // IDC_HIGHLIGHT_GRADIENT_COMBO + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_DESKTOP_LRC_DEFAULT_STYLE"); + SetDlgItemTextW(IDC_DEFAULT_STYLE, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_DESKTOP_LRC_TRANSPARENCY"); + SetDlgItemTextW(IDC_TXT_OPT_LRC_DESKTOP_LRC_TRANSPARENCY_STATIC, temp.c_str()); + // IDC_LYRIC_OPACITY_SLIDER + // IDC_LYRIC_OPACITY_STATIC + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_ALIGN_SEL"); + SetDlgItemTextW(IDC_TXT_OPT_LRC_DESKTOP_LRC_ALIGN_SEL_STATIC, temp.c_str()); + // IDC_DESKTOP_LYRIC_ALIGNMENT_COMBO + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_FONT_SEL"); + SetDlgItemTextW(IDC_SET_FONT2, temp.c_str()); + + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_SEARCH_BOX_FUNCTION"); + SetDlgItemTextW(IDC_TXT_OPT_LRC_SEARCH_BOX_FUNCTION_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_SEARCH_BOX_FUNCTION_ENABLE"); + SetDlgItemTextW(IDC_SHOW_LYRIC_IN_CORTANA, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_SEARCH_BOX_COMPATIBLE_MODE"); + SetDlgItemTextW(IDC_LYRIC_COMPATIBLE_MODE, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_SEARCH_BOX_SHOW_WHEN_PAUSE"); + SetDlgItemTextW(IDC_KEEP_DISPLAY_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_SEARCH_BOX_BG_COLOR_SEL"); + SetDlgItemTextW(IDC_TXT_OPT_LRC_SEARCH_BOX_BG_COLOR_SEL_STATIC, temp.c_str()); + // IDC_CORTANA_COLOR_COMBO + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_SEARCH_BOX_BG_TRANSPARENCY_IN_WHITE_MODE"); + SetDlgItemTextW(IDC_SEARCH_BOX_TRANSPARENT_IN_WHITE_MODE, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_SEARCH_BOX_SHOW_COVER"); + SetDlgItemTextW(IDC_SHOW_ALBUM_COVER_IN_CORTANA, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_SEARCH_BOX_NO_COVER_SHOW_DEFAULT_COVER"); + SetDlgItemTextW(IDC_SHOW_DEFAULT_ALBUM_ICON_CHK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_SEARCH_BOX_NO_COVER_BEATS_CORTANA_ICON"); + SetDlgItemTextW(IDC_CORTANA_ICON_DEAT_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_SEARCH_BOX_SHOW_SPECTRUM"); + SetDlgItemTextW(IDC_SHOW_SPECTRUM_IN_CORTANA, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_SEARCH_BOX_SHOW_LRC"); + SetDlgItemTextW(IDC_SHOW_LYRIC_IN_CORTANA2, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_DOUBLE_LINE"); + SetDlgItemTextW(IDC_LYRIC_DOUBLE_LINE_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_ALIGN_SEL"); + SetDlgItemTextW(IDC_TXT_OPT_LRC_SEARCH_BOX_ALIGN_SEL_STATIC, temp.c_str()); + // IDC_ALIGNMENT_COMBO + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LRC_FONT_SEL"); + SetDlgItemTextW(IDC_SET_FONT, temp.c_str()); + + return false; +} + void CLyricSettingsDlg::DoDataExchange(CDataExchange* pDX) { CTabDlg::DoDataExchange(pDX); @@ -36,7 +143,6 @@ void CLyricSettingsDlg::DoDataExchange(CDataExchange* pDX) DDX_Control(pDX, IDC_KEEP_DISPLAY_CHECK, m_keep_display_chk); DDX_Control(pDX, IDC_SHOW_SPECTRUM_IN_CORTANA, m_show_spectrum_chk); DDX_Control(pDX, IDC_SHOW_LYRIC_IN_CORTANA2, m_show_lyric_in_cortana_chk); - //DDX_Control(pDX, IDC_SEARCH_BOX_OPAQUE_CHECK, m_search_box_opaque_chk); DDX_Control(pDX, IDC_SHOW_DESKTOP_LYRIC, m_show_desktop_lyric_chk); DDX_Control(pDX, IDC_LYRIC_DOUBLE_LINE_CHECK2, m_desktop_lyric_double_line_chk); DDX_Control(pDX, IDC_TEXT_COLOR1_STATIC, m_text_color1_static); @@ -64,7 +170,6 @@ void CLyricSettingsDlg::DoDataExchange(CDataExchange* pDX) BEGIN_MESSAGE_MAP(CLyricSettingsDlg, CTabDlg) ON_BN_CLICKED(IDC_KARAOKE_DISP, &CLyricSettingsDlg::OnBnClickedKaraokeDisp) - //ON_BN_CLICKED(IDC_EXPLORE_LYRIC_BUTTON, &CLyricSettingsDlg::OnBnClickedExploreLyricButton) ON_BN_CLICKED(IDC_LYRIC_FUZZY_MATCH, &CLyricSettingsDlg::OnBnClickedLyricFuzzyMatch) ON_BN_CLICKED(IDC_SHOW_LYRIC_IN_CORTANA, &CLyricSettingsDlg::OnBnClickedShowLyricInCortana) ON_BN_CLICKED(IDC_LYRIC_DOUBLE_LINE_CHECK, &CLyricSettingsDlg::OnBnClickedLyricDoubleLineCheck) @@ -76,13 +181,11 @@ BEGIN_MESSAGE_MAP(CLyricSettingsDlg, CTabDlg) ON_BN_CLICKED(IDC_KEEP_DISPLAY_CHECK, &CLyricSettingsDlg::OnBnClickedKeepDisplayCheck) ON_BN_CLICKED(IDC_SHOW_SPECTRUM_IN_CORTANA, &CLyricSettingsDlg::OnBnClickedShowSpectrumInCortana) ON_BN_CLICKED(IDC_SHOW_LYRIC_IN_CORTANA2, &CLyricSettingsDlg::OnBnClickedShowLyricInCortana2) - //ON_BN_CLICKED(IDC_SEARCH_BOX_OPAQUE_CHECK, &CLyricSettingsDlg::OnBnClickedSearchBoxOpaqueCheck) ON_BN_CLICKED(IDC_SHOW_DESKTOP_LYRIC, &CLyricSettingsDlg::OnBnClickedShowDesktopLyric) ON_BN_CLICKED(IDC_SET_FONT2, &CLyricSettingsDlg::OnBnClickedSetFont2) ON_CBN_SELCHANGE(IDC_TEXT_GRADIENT_COMBO, &CLyricSettingsDlg::OnCbnSelchangeTextGradientCombo) ON_CBN_SELCHANGE(IDC_HIGHLIGHT_GRADIENT_COMBO, &CLyricSettingsDlg::OnCbnSelchangeHighlightGradientCombo) ON_BN_CLICKED(IDC_LOCK_DESKTOP_LYRIC_CHECK, &CLyricSettingsDlg::OnBnClickedLockDesktopLyricCheck) - ON_WM_CTLCOLOR() ON_WM_HSCROLL() ON_BN_CLICKED(IDC_HIDE_LYRIC_WITHOUT_LYRIC_CHECK, &CLyricSettingsDlg::OnBnClickedHideLyricWithoutLyricCheck) ON_BN_CLICKED(IDC_HIDE_LYRIC_PAUSE_CHECK, &CLyricSettingsDlg::OnBnClickedHideLyricPauseCheck) @@ -120,16 +223,15 @@ END_MESSAGE_MAP() BOOL CLyricSettingsDlg::OnInitDialog() { CTabDlg::OnInitDialog(); - // TODO: 在此添加额外的初始化 //初始化各控件的状态 m_karaoke_disp_check.SetCheck(m_data.lyric_karaoke_disp); m_lyric_fuzzy_match_check.SetCheck(m_data.lyric_fuzzy_match); m_use_inner_lyric_chk.SetCheck(m_data.use_inner_lyric_first); - m_lyric_save_policy_combo.AddString(CCommon::LoadText(IDS_DO_NOT_SAVE)); - m_lyric_save_policy_combo.AddString(CCommon::LoadText(IDS_AUTO_SAVE)); - m_lyric_save_policy_combo.AddString(CCommon::LoadText(IDS_INQUIRY)); + m_lyric_save_policy_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_LRC_SAVE_POLICY_DO_NOT_SAVE").c_str()); + m_lyric_save_policy_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_LRC_SAVE_POLICY_AUTO_SAVE").c_str()); + m_lyric_save_policy_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_LRC_SAVE_POLICY_INQUIRY").c_str()); m_lyric_save_policy_combo.SetCurSel(static_cast(m_data.lyric_save_policy)); CheckDlgButton(IDC_SHOW_LYRIC_TRANSLATE_CHECK, m_data.show_translate); CheckDlgButton(IDC_LYRIC_HIDE_BLANK_LINE_CHECK, m_data.donot_show_blank_lines); @@ -138,10 +240,10 @@ BOOL CLyricSettingsDlg::OnInitDialog() m_lyric_line_space_edit.SetRange(MIM_LINE_SPACE, MAX_LINE_SPACE); m_lyric_line_space_edit.SetValue(m_data.lyric_line_space); - m_lyric_alignment_combo.AddString(CCommon::LoadText(IDS_ALIGN_LEFT)); - m_lyric_alignment_combo.AddString(CCommon::LoadText(IDS_ALIGN_RIGHT)); - m_lyric_alignment_combo.AddString(CCommon::LoadText(IDS_ALIGN_AUTO)); - m_lyric_alignment_combo.AddString(CCommon::LoadText(IDS_CENTER)); + m_lyric_alignment_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_LRC_ALIGN_LEFT").c_str()); + m_lyric_alignment_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_LRC_ALIGN_RIGHT").c_str()); + m_lyric_alignment_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_LRC_ALIGN_AUTO").c_str()); + m_lyric_alignment_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_LRC_ALIGN_CENTER").c_str()); m_lyric_alignment_combo.SetCurSel(static_cast(m_data.lyric_align)); m_lyric_double_line_chk.SetCheck(m_data.cortana_lyric_double_line); @@ -168,22 +270,22 @@ BOOL CLyricSettingsDlg::OnInitDialog() m_lyric_background_penetrate_chk.SetCheck(m_data.desktop_lyric_data.lyric_background_penetrate); m_show_unlock_when_locked_chk.SetCheck(m_data.desktop_lyric_data.show_unlock_when_locked); - m_text_gradient_combo.AddString(CCommon::LoadText(IDS_NO_GRADIENT)); - m_text_gradient_combo.AddString(CCommon::LoadText(IDS_TOW_COLOR_GRADIENT)); - m_text_gradient_combo.AddString(CCommon::LoadText(IDS_THREE_COLOR_GRADIENT)); + m_text_gradient_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_LRC_DESKTOP_LRC_COLOR_GRADIENT_NONE").c_str()); + m_text_gradient_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_LRC_DESKTOP_LRC_COLOR_GRADIENT_TWO").c_str()); + m_text_gradient_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_LRC_DESKTOP_LRC_COLOR_GRADIENT_THREE").c_str()); m_text_gradient_combo.SetCurSel(m_data.desktop_lyric_data.text_gradient); - m_highlight_gradient_combo.AddString(CCommon::LoadText(IDS_NO_GRADIENT)); - m_highlight_gradient_combo.AddString(CCommon::LoadText(IDS_TOW_COLOR_GRADIENT)); - m_highlight_gradient_combo.AddString(CCommon::LoadText(IDS_THREE_COLOR_GRADIENT)); + m_highlight_gradient_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_LRC_DESKTOP_LRC_COLOR_GRADIENT_NONE").c_str()); + m_highlight_gradient_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_LRC_DESKTOP_LRC_COLOR_GRADIENT_TWO").c_str()); + m_highlight_gradient_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_LRC_DESKTOP_LRC_COLOR_GRADIENT_THREE").c_str()); m_highlight_gradient_combo.SetCurSel(m_data.desktop_lyric_data.highlight_gradient); m_desktop_lyric_opacity_sld.SetRange(20, 100); m_desktop_lyric_opacity_sld.SetPos(m_data.desktop_lyric_data.opacity); - m_desktop_lyric_alignment_combo.AddString(CCommon::LoadText(IDS_ALIGN_LEFT)); - m_desktop_lyric_alignment_combo.AddString(CCommon::LoadText(IDS_ALIGN_RIGHT)); - m_desktop_lyric_alignment_combo.AddString(CCommon::LoadText(IDS_ALIGN_AUTO)); - m_desktop_lyric_alignment_combo.AddString(CCommon::LoadText(IDS_CENTER)); + m_desktop_lyric_alignment_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_LRC_ALIGN_LEFT").c_str()); + m_desktop_lyric_alignment_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_LRC_ALIGN_RIGHT").c_str()); + m_desktop_lyric_alignment_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_LRC_ALIGN_AUTO").c_str()); + m_desktop_lyric_alignment_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_LRC_ALIGN_CENTER").c_str()); m_desktop_lyric_alignment_combo.SetCurSel(static_cast(m_data.desktop_lyric_data.lyric_align)); CString str; @@ -206,29 +308,36 @@ BOOL CLyricSettingsDlg::OnInitDialog() m_lyric_dir_edit.SetWindowText(m_data.lyric_path.c_str()); m_lyric_dir_edit.EnableFolderBrowseButton(); + wstring tip_str; m_tool_tip.Create(this); m_tool_tip.SetMaxTipWidth(300); - m_tool_tip.AddTool(&m_lyric_fuzzy_match_check, CCommon::LoadText(IDS_LYRIC_FUZZY_MATHC_TIP_INFO)); - m_tool_tip.AddTool(&m_lyric_dir_edit, CCommon::LoadText(IDS_LYRIC_PATH_TIP_INFO)); - m_tool_tip.AddTool(GetDlgItem(IDC_SHOW_LYRIC_IN_CORTANA), CCommon::LoadText(IDS_CORTANA_SHOW_LYRIC_TIP_INFO)); - //m_tool_tip.AddTool(&m_search_box_opaque_chk, CCommon::LoadText(IDS_SEARCH_BOX_OPAQUE_TIP)); - m_tool_tip.AddTool(GetDlgItem(IDC_LYRIC_HIDE_BLANK_LINE_CHECK), CCommon::LoadText(IDS_LYRICS_HIDE_BLANK_LINES_TIP)); - m_tool_tip.AddTool(GetDlgItem(IDC_SET_FONT_BUTTON), GetFontInfoString(m_data.lyric_font)); - m_tool_tip.AddTool(GetDlgItem(IDC_SET_FONT2), GetFontInfoString(m_data.desktop_lyric_data.lyric_font)); - m_tool_tip.AddTool(GetDlgItem(IDC_SET_FONT), GetFontInfoString(m_data.cortana_font)); - m_tool_tip.AddTool(GetDlgItem(IDC_SHOW_SONG_INFO_IF_LYRIC_NOT_EXIST_CHECK), CCommon::LoadText(IDS_SHOW_SONG_INFO_WHEN_LYRICS_NOT_EXIST_TIP)); + m_tool_tip.AddTool(&m_lyric_fuzzy_match_check, theApp.m_str_table.LoadText(L"TIP_OPT_LRC_FUZZY_MATCH").c_str()); + m_tool_tip.AddTool(&m_lyric_dir_edit, theApp.m_str_table.LoadText(L"TIP_OPT_LRC_LRC_FOLDER_PATH").c_str()); + m_tool_tip.AddTool(GetDlgItem(IDC_SHOW_LYRIC_IN_CORTANA), theApp.m_str_table.LoadText(L"TIP_OPT_LRC_SEARCH_BOX_FUNCTION_ENABLE").c_str()); + tip_str = theApp.m_str_table.LoadTextFormat(L"TIP_OPT_LRC_USE_MUSIC_SYMBOL", { + theApp.m_str_table.LoadText(L"UI_LYRIC_EMPTY_LINE"), + theApp.m_str_table.LoadText(L"UI_LYRIC_EMPTY_LINE_2"), + theApp.m_str_table.LoadText(L"UI_LYRIC_MUSIC_SYMBOL") + }); + m_tool_tip.AddTool(GetDlgItem(IDC_LYRIC_HIDE_BLANK_LINE_CHECK), tip_str.c_str()); + m_tool_tip.AddTool(GetDlgItem(IDC_SET_FONT_BUTTON), GetFontInfoString(m_data.lyric_font).c_str()); + m_tool_tip.AddTool(GetDlgItem(IDC_SET_FONT2), GetFontInfoString(m_data.desktop_lyric_data.lyric_font).c_str()); + m_tool_tip.AddTool(GetDlgItem(IDC_SET_FONT), GetFontInfoString(m_data.cortana_font).c_str()); + tip_str = theApp.m_str_table.LoadTextFormat(L"TIP_OPT_LRC_SONG_INFO_IF_NO_LRC", + { theApp.m_str_table.LoadText(L"UI_LYRIC_NONE") }); + m_tool_tip.AddTool(GetDlgItem(IDC_SHOW_SONG_INFO_IF_LYRIC_NOT_EXIST_CHECK), tip_str.c_str()); m_tool_tip.SetWindowPos(&CWnd::wndTopMost, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); - m_cortana_color_combo.AddString(CCommon::LoadText(IDS_FOLLOWING_SYSTEM)); - m_cortana_color_combo.AddString(CCommon::LoadText(IDS_DARK)); - m_cortana_color_combo.AddString(CCommon::LoadText(IDS_LIGHT)); + m_cortana_color_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_LRC_SEARCH_BOX_BG_COLOR_FOLLOWING_SYSTEM").c_str()); + m_cortana_color_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_LRC_SEARCH_BOX_BG_COLOR_DARK").c_str()); + m_cortana_color_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_LRC_SEARCH_BOX_BG_COLOR_LIGHT").c_str()); m_cortana_color_combo.SetCurSel(m_data.cortana_color); - m_alignment_combo.AddString(CCommon::LoadText(IDS_ALIGN_LEFT)); - m_alignment_combo.AddString(CCommon::LoadText(IDS_ALIGN_RIGHT)); - m_alignment_combo.AddString(CCommon::LoadText(IDS_ALIGN_AUTO)); - m_alignment_combo.AddString(CCommon::LoadText(IDS_CENTER)); + m_alignment_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_LRC_ALIGN_LEFT").c_str()); + m_alignment_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_LRC_ALIGN_RIGHT").c_str()); + m_alignment_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_LRC_ALIGN_AUTO").c_str()); + m_alignment_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_LRC_ALIGN_CENTER").c_str()); m_alignment_combo.SetCurSel(static_cast(m_data.cortana_lyric_align)); //设置控件不响应鼠标滚轮消息 @@ -317,22 +426,16 @@ bool CLyricSettingsDlg::IsSearchBoxTransparentInWhiteTheme() const return (m_data.cortana_transparent_color == LIGHT_MODE_SEARCH_BOX_BACKGROUND_COLOR); } -CString CLyricSettingsDlg::GetFontInfoString(const FontInfo& font_info) +wstring CLyricSettingsDlg::GetFontInfoString(const FontInfo& font_info) { - CString str; - str.Format(_T("%s, %dpt"), font_info.name.c_str(), font_info.size); - - CString font_style; + wstring str = font_info.name + L", " + std::to_wstring(font_info.size) + L"pt"; + wstring font_style; + if (font_info.style.bold || font_info.style.italic) + str.push_back(L','); if (font_info.style.bold) - font_style += CCommon::LoadText(IDS_BOLD); + str += L' ' + theApp.m_str_table.LoadText(L"TIP_OPT_LRC_FONT_INFO_BOLD"); if (font_info.style.italic) - font_style += CCommon::LoadText(_T(" "), IDS_ITALIC); - - if (!font_style.IsEmpty()) - { - str += _T(", "); - str += font_style; - } + str += L' ' + theApp.m_str_table.LoadText(L"TIP_OPT_LRC_FONT_INFO_ITALIC"); return str; } @@ -450,7 +553,7 @@ void CLyricSettingsDlg::OnBnClickedSetFont() m_data.cortana_font.style.underline = (fontDlg.IsUnderline() != FALSE); m_data.cortana_font.style.strike_out = (fontDlg.IsStrikeOut() != FALSE); m_search_box_font_changed = true; - m_tool_tip.UpdateTipText(GetFontInfoString(m_data.cortana_font), GetDlgItem(IDC_SET_FONT)); + m_tool_tip.UpdateTipText(GetFontInfoString(m_data.cortana_font).c_str(), GetDlgItem(IDC_SET_FONT)); } } @@ -511,7 +614,7 @@ void CLyricSettingsDlg::OnBnClickedSetFont2() m_data.desktop_lyric_data.lyric_font.style.italic = (fontDlg.IsItalic() != FALSE); m_data.desktop_lyric_data.lyric_font.style.underline = (fontDlg.IsUnderline() != FALSE); m_data.desktop_lyric_data.lyric_font.style.strike_out = (fontDlg.IsStrikeOut() != FALSE); - m_tool_tip.UpdateTipText(GetFontInfoString(m_data.desktop_lyric_data.lyric_font), GetDlgItem(IDC_SET_FONT2)); + m_tool_tip.UpdateTipText(GetFontInfoString(m_data.desktop_lyric_data.lyric_font).c_str(), GetDlgItem(IDC_SET_FONT2)); } } @@ -537,24 +640,6 @@ void CLyricSettingsDlg::OnBnClickedLockDesktopLyricCheck() } -HBRUSH CLyricSettingsDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) -{ - HBRUSH hbr = CTabDlg::OnCtlColor(pDC, pWnd, nCtlColor); - - // TODO: 在此更改 DC 的任何特性 - if (pWnd == &m_desktop_lyric_opacity_sld) //设置滑动条控件的背景色为白色 - { - static HBRUSH brush{}; - if (brush == NULL) - brush = CreateSolidBrush(m_background_color); - return brush; - } - - // TODO: 如果默认的不是所需画笔,则返回另一个画笔 - return hbr; -} - - void CLyricSettingsDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { // TODO: 在此添加消息处理程序代码和/或调用默认值 @@ -606,7 +691,7 @@ void CLyricSettingsDlg::OnBnClickedDefaultStyle() pBtn->GetWindowRect(rect); point.x = rect.left; point.y = rect.bottom; - CMenu* pMenu = theApp.m_menu_set.m_lyric_default_style.GetSubMenu(1); + CMenu* pMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::OptDlrcDefStyleMenu); if (pMenu != NULL) pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this); } @@ -671,7 +756,8 @@ afx_msg LRESULT CLyricSettingsDlg::OnColorSelected(WPARAM wParam, LPARAM lParam) void CLyricSettingsDlg::OnLyricDefaultStyle1Modify() { // TODO: 在此添加命令处理程序代码 - if (MessageBox(CCommon::LoadTextFormat(IDS_MODIFY_DEFAULT_STYLE_WARNING, { 1 }), NULL, MB_ICONWARNING | MB_YESNO) == IDYES) + wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_OPT_LRC_DESKTOP_LRC_DEFAULT_STYLE_MODIFY_WARNING", { 1 }); + if (MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_YESNO) == IDYES) { LyricStyleDefaultData style_data; CDesktopLyric::LyricSettingDatatOLyricStyleDefaultData(m_data.desktop_lyric_data, style_data); @@ -683,7 +769,8 @@ void CLyricSettingsDlg::OnLyricDefaultStyle1Modify() void CLyricSettingsDlg::OnLyricDefaultStyle2Modify() { // TODO: 在此添加命令处理程序代码 - if (MessageBox(CCommon::LoadTextFormat(IDS_MODIFY_DEFAULT_STYLE_WARNING, { 2 }), NULL, MB_ICONWARNING | MB_YESNO) == IDYES) + wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_OPT_LRC_DESKTOP_LRC_DEFAULT_STYLE_MODIFY_WARNING", { 2 }); + if (MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_YESNO) == IDYES) { LyricStyleDefaultData style_data; CDesktopLyric::LyricSettingDatatOLyricStyleDefaultData(m_data.desktop_lyric_data, style_data); @@ -695,7 +782,8 @@ void CLyricSettingsDlg::OnLyricDefaultStyle2Modify() void CLyricSettingsDlg::OnLyricDefaultStyle3Modify() { // TODO: 在此添加命令处理程序代码 - if (MessageBox(CCommon::LoadTextFormat(IDS_MODIFY_DEFAULT_STYLE_WARNING, { 3 }), NULL, MB_ICONWARNING | MB_YESNO) == IDYES) + wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_OPT_LRC_DESKTOP_LRC_DEFAULT_STYLE_MODIFY_WARNING", { 3 }); + if (MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_YESNO) == IDYES) { LyricStyleDefaultData style_data; CDesktopLyric::LyricSettingDatatOLyricStyleDefaultData(m_data.desktop_lyric_data, style_data); @@ -707,7 +795,8 @@ void CLyricSettingsDlg::OnLyricDefaultStyle3Modify() void CLyricSettingsDlg::OnRestoreDefaultStyle() { // TODO: 在此添加命令处理程序代码 - if (MessageBox(CCommon::LoadText(IDS_RESTORE_DEFAULT_STYTLE_WARNING), NULL, MB_ICONWARNING | MB_YESNO) == IDYES) + const wstring& info = theApp.m_str_table.LoadText(L"MSG_OPT_LRC_DESKTOP_LRC_DEFAULT_STYLE_RESTORE_WARNING"); + if (MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_YESNO) == IDYES) { m_pDesktopLyric->RestoreDefaultStyle(); } @@ -786,7 +875,7 @@ void CLyricSettingsDlg::OnBnClickedSetFontButton() m_data.lyric_font.style.strike_out = (fontDlg.IsStrikeOut() != FALSE); //将字体已更改flag置为true m_font_changed = true; - m_tool_tip.UpdateTipText(GetFontInfoString(m_data.lyric_font), GetDlgItem(IDC_SET_FONT_BUTTON)); + m_tool_tip.UpdateTipText(GetFontInfoString(m_data.lyric_font).c_str(), GetDlgItem(IDC_SET_FONT_BUTTON)); } } diff --git a/MusicPlayer2/LyricSettingsDlg.h b/MusicPlayer2/LyricSettingsDlg.h index f1820539b..11a31d52a 100644 --- a/MusicPlayer2/LyricSettingsDlg.h +++ b/MusicPlayer2/LyricSettingsDlg.h @@ -1,5 +1,4 @@ #pragma once -#include "afxwin.h" #include "FolderBrowserDlg.h" #include "TabDlg.h" #include "ColorStaticEx.h" @@ -75,8 +74,6 @@ class CLyricSettingsDlg : public CTabDlg bool m_search_box_font_changed{ false }; bool m_font_changed{ false }; - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 - virtual BOOL OnInitDialog(); void EnableControl(); void EnableControlForDesktopLyric(); void ApplyDefaultLyricStyle(const LyricStyleDefaultData& style); @@ -84,12 +81,16 @@ class CLyricSettingsDlg : public CTabDlg void SetSearchBoxTransparentInWhiteTheme(bool transparent); bool IsSearchBoxTransparentInWhiteTheme() const; - static CString GetFontInfoString(const FontInfo& font_info); + static wstring GetFontInfoString(const FontInfo& font_info); virtual void GetDataFromUi() override; + virtual bool InitializeControls() override; + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 + DECLARE_MESSAGE_MAP() public: + virtual BOOL OnInitDialog(); afx_msg void OnBnClickedKaraokeDisp(); //afx_msg void OnBnClickedExploreLyricButton(); virtual void OnCancel(); @@ -112,7 +113,6 @@ class CLyricSettingsDlg : public CTabDlg afx_msg void OnCbnSelchangeTextGradientCombo(); afx_msg void OnCbnSelchangeHighlightGradientCombo(); afx_msg void OnBnClickedLockDesktopLyricCheck(); - afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); afx_msg void OnBnClickedHideLyricWithoutLyricCheck(); afx_msg void OnBnClickedHideLyricPauseCheck(); diff --git a/MusicPlayer2/LyricsWindow.cpp b/MusicPlayer2/LyricsWindow.cpp index 432f735b7..93fa74887 100644 --- a/MusicPlayer2/LyricsWindow.cpp +++ b/MusicPlayer2/LyricsWindow.cpp @@ -90,7 +90,7 @@ BOOL CLyricsWindow::Create(LPCTSTR lpszClassName,int nWidth,int nHeight) { if(!RegisterWndClass(lpszClassName)) { - TRACE("Class Registration Failedn"); + TRACE(L"Class Registration Failedn"); } //-------------------------------------------- @@ -430,36 +430,36 @@ void CLyricsWindow::DrawHighlightLyrics(Gdiplus::Graphics* pGraphics,Gdiplus::Gr //创建渐变画刷 Gdiplus::Brush* CLyricsWindow::CreateGradientBrush(LyricsGradientMode TextGradientMode,Gdiplus::Color& Color1,Gdiplus::Color& Color2, Gdiplus::RectF& dstRect) { - Gdiplus::PointF pt1; - Gdiplus::PointF pt2; - Gdiplus::Brush* pBrush=NULL; - switch (TextGradientMode) - { - case LyricsGradientMode_Two://两色渐变 - { - Gdiplus::PointF point1(dstRect.X,dstRect.Y); - Gdiplus::PointF point2(dstRect.X,dstRect.Y+dstRect.Height); - pBrush=new Gdiplus::LinearGradientBrush(point1,point2,Color1,Color2); - ((Gdiplus::LinearGradientBrush*)pBrush)->SetWrapMode(Gdiplus::WrapModeTileFlipXY); - break; - } - - case LyricsGradientMode_Three://三色渐变 - { - Gdiplus::PointF point1(dstRect.X,dstRect.Y); - Gdiplus::PointF point2(dstRect.X,dstRect.Y+dstRect.Height/2); - pBrush=new Gdiplus::LinearGradientBrush(point1,point2,Color1,Color2); - ((Gdiplus::LinearGradientBrush*)pBrush)->SetWrapMode(Gdiplus::WrapModeTileFlipXY); - break; - } - - default://无渐变 - { - pBrush=new Gdiplus::SolidBrush(Color1); - break; - } - } - return pBrush; + // 单色画刷 + if (TextGradientMode != LyricsGradientMode_Two && TextGradientMode != LyricsGradientMode_Three) + { + Gdiplus::SolidBrush* pSolidBrush = new Gdiplus::SolidBrush(Color1); + return static_cast(pSolidBrush); + } + + Gdiplus::PointF point1(dstRect.X, dstRect.Y); + Gdiplus::PointF point2(dstRect.X, dstRect.Y); + if (TextGradientMode == LyricsGradientMode_Two) + point2.Y += dstRect.Height; + else + point2.Y += dstRect.Height / 2; // 这里的三色渐变是靠环绕模式对映 + + // 创建线性渐变画刷 + Gdiplus::LinearGradientBrush* pLinearGradientBrush = new Gdiplus::LinearGradientBrush(point1, point2, Gdiplus::Color(), Gdiplus::Color()); + // 定义插值点的数量, 创建颜色和位置的向量 + const int colorCount = 10; + std::array colors{}; + std::array positions{}; + for (int i = 0; i < colorCount; ++i) + { // CDrawingManager::SmartMixColors产生的渐变色更好,GDI+默认的渐变色有很多灰色 + COLORREF interpolatedColor = CDrawingManager::SmartMixColors(Color1.ToCOLORREF(), Color2.ToCOLORREF(), 1.0, colorCount - i, i); + colors[i].SetFromCOLORREF(interpolatedColor); + positions[i] = static_cast(i) / (colorCount - 1); + } + // 设置插值颜色 + pLinearGradientBrush->SetInterpolationColors(colors.data(), positions.data(), colorCount); + pLinearGradientBrush->SetWrapMode(Gdiplus::WrapModeTileFlipXY);// 设置环绕模式 + return static_cast(pLinearGradientBrush); } //设置歌词颜色 diff --git a/MusicPlayer2/MP3EncodeCfgDlg.cpp b/MusicPlayer2/MP3EncodeCfgDlg.cpp index 39f7c48b9..f7f8c80f5 100644 --- a/MusicPlayer2/MP3EncodeCfgDlg.cpp +++ b/MusicPlayer2/MP3EncodeCfgDlg.cpp @@ -4,15 +4,14 @@ #include "stdafx.h" #include "MusicPlayer2.h" #include "MP3EncodeCfgDlg.h" -#include "afxdialogex.h" // CMP3EncodeCfgDlg 对话框 -IMPLEMENT_DYNAMIC(CMP3EncodeCfgDlg, CDialog) +IMPLEMENT_DYNAMIC(CMP3EncodeCfgDlg, CBaseDialog) CMP3EncodeCfgDlg::CMP3EncodeCfgDlg(CWnd* pParent /*=nullptr*/) - : CDialog(IDD_MP3_ENCODE_CFG_DIALOG, pParent) + : CBaseDialog(IDD_MP3_ENCODE_CFG_DIALOG, pParent) { } @@ -21,78 +20,105 @@ CMP3EncodeCfgDlg::~CMP3EncodeCfgDlg() { } -void CMP3EncodeCfgDlg::InitBitrateCombobox(CComboBox & combo) +void CMP3EncodeCfgDlg::EncodeParaToCmdline(MP3EncodePara& para) { - combo.AddString(_T("32")); - combo.AddString(_T("40")); - combo.AddString(_T("64")); - combo.AddString(_T("80")); - combo.AddString(_T("96")); - combo.AddString(_T("112")); - combo.AddString(_T("128")); - combo.AddString(_T("160")); - combo.AddString(_T("192")); - combo.AddString(_T("224")); - combo.AddString(_T("256")); - combo.AddString(_T("320")); + if (para.user_define_para) + return; + wchar_t buff[32]; + switch (para.encode_type) + { + case 0: + swprintf_s(buff, L"-b %d -h", para.cbr_bitrate); + para.cmd_para = buff; + break; + case 1: + swprintf_s(buff, L"--abr %d -h", para.abr_bitrate); + para.cmd_para = buff; + break; + case 2: + swprintf_s(buff, L"-V %d -h", para.vbr_quality); + para.cmd_para = buff; + break; + default: + break; + } + if (para.joint_stereo) + para.cmd_para += L" -m j"; } void CMP3EncodeCfgDlg::SetControlState() { - m_encode_cmdline_edit.SetWindowText(m_encode_para.cmd_para.c_str()); - m_encode_cmdline_edit.SetReadOnly(m_encode_para.encode_type != 3); - m_cbr_rate_combo.EnableWindow(m_encode_para.encode_type == 0); - m_abr_rate_combo.EnableWindow(m_encode_para.encode_type == 1); - m_vbr_qua_sld.EnableWindow(m_encode_para.encode_type == 2); - m_joint_stereo_btn.EnableWindow(m_encode_para.encode_type != 3); + EnableDlgCtrl(IDC_CBR_RADIO, !m_encode_para.user_define_para); + EnableDlgCtrl(IDC_ABR_RADIO, !m_encode_para.user_define_para); + EnableDlgCtrl(IDC_VBR_RADIO, !m_encode_para.user_define_para); + EnableDlgCtrl(IDC_CBR_RATE_COMBO, !m_encode_para.user_define_para && m_encode_para.encode_type == 0); + EnableDlgCtrl(IDC_ABR_RATE_COMBO, !m_encode_para.user_define_para && m_encode_para.encode_type == 1); + EnableDlgCtrl(IDC_SLIDER1, !m_encode_para.user_define_para && m_encode_para.encode_type == 2); + EnableDlgCtrl(IDC_JOINT_STEREO_CHECK, !m_encode_para.user_define_para); + m_encode_cmdline_edit.SetReadOnly(!m_encode_para.user_define_para); + SetDlgItemTextW(IDC_ENCODE_CMDLINE_EDIT, m_encode_para.cmd_para.c_str()); } -void CMP3EncodeCfgDlg::EncodeParaToCmdline(MP3EncodePara& para) +CString CMP3EncodeCfgDlg::GetDialogName() const +{ + return L"Mp3EncodeOptDlg"; +} + +bool CMP3EncodeCfgDlg::InitializeControls() { - wchar_t buff[32]; - switch (para.encode_type) - { - case 0: - swprintf_s(buff, L"-b %s -h", para.cbr_bitrate.c_str()); - para.cmd_para = buff; - break; - case 1: - swprintf_s(buff, L"--abr %s -h", para.abr_bitrate.c_str()); - para.cmd_para = buff; - break; - case 2: - swprintf_s(buff, L"-V %d -h", para.vbr_quality); - para.cmd_para = buff; - break; - } - if (para.joint_stereo && para.encode_type != 3) - para.cmd_para += L" -m j"; + wstring temp; + temp = theApp.m_str_table.LoadText(L"TITLE_ENCODE_OPT_MP3"); + SetWindowTextW(temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_ENCODE_OPT_MP3_CBR"); + SetDlgItemTextW(IDC_CBR_RADIO, temp.c_str()); + // IDC_CBR_RATE_COMBO + temp = theApp.m_str_table.LoadText(L"TXT_ENCODE_OPT_MP3_ABR"); + SetDlgItemTextW(IDC_ABR_RADIO, temp.c_str()); + // IDC_ABR_RATE_COMBO + temp = theApp.m_str_table.LoadText(L"TXT_ENCODE_OPT_MP3_VBR"); + SetDlgItemTextW(IDC_VBR_RADIO, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_ENCODE_OPT_MP3_VBR_QUALITY_SEL"); + SetDlgItemTextW(IDC_TXT_ENCODE_OPT_MP3_VBR_QUALITY_SEL_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_ENCODE_OPT_MP3_VBR_QUALITY_LOW"); + SetDlgItemTextW(IDC_TXT_ENCODE_OPT_MP3_VBR_QUALITY_LOW_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_ENCODE_OPT_MP3_VBR_QUALITY_HIGH"); + SetDlgItemTextW(IDC_TXT_ENCODE_OPT_MP3_VBR_QUALITY_HIGH_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_ENCODE_OPT_MP3_JOINT_STEREO"); + SetDlgItemTextW(IDC_JOINT_STEREO_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_ENCODE_OPT_MP3_SPECIFY_PARA"); + SetDlgItemTextW(IDC_USER_CHECK, temp.c_str()); + // IDC_ENCODE_CMDLINE_EDIT + + RepositionTextBasedControls({ + { CtrlTextInfo::L1, IDC_USER_CHECK, CtrlTextInfo::W16 }, + { CtrlTextInfo::C0, IDC_ENCODE_CMDLINE_EDIT } + }); + RepositionTextBasedControls({ + { CtrlTextInfo::R1, IDOK, CtrlTextInfo::W32 }, + { CtrlTextInfo::R2, IDCANCEL, CtrlTextInfo::W32 } + }); + return true; } void CMP3EncodeCfgDlg::DoDataExchange(CDataExchange* pDX) { - CDialog::DoDataExchange(pDX); - DDX_Control(pDX, IDC_CBR_RADIO, m_cbr_radio); - DDX_Control(pDX, IDC_ABR_RADIO, m_abr_radio); - DDX_Control(pDX, IDC_VBR_RADIO, m_vbr_radio); - DDX_Control(pDX, IDC_USER_RADIO, m_user_radio); - DDX_Control(pDX, IDC_CBR_RATE_COMBO, m_cbr_rate_combo); - DDX_Control(pDX, IDC_ABR_RATE_COMBO, m_abr_rate_combo); - DDX_Control(pDX, IDC_SLIDER1, m_vbr_qua_sld); - DDX_Control(pDX, IDC_ENCODE_CMDLINE_EDIT, m_encode_cmdline_edit); - DDX_Control(pDX, IDC_JOINT_STEREO_CHECK, m_joint_stereo_btn); -} - - -BEGIN_MESSAGE_MAP(CMP3EncodeCfgDlg, CDialog) - ON_CBN_SELCHANGE(IDC_CBR_RATE_COMBO, &CMP3EncodeCfgDlg::OnCbnSelchangeCbrRateCombo) - ON_CBN_SELCHANGE(IDC_ABR_RATE_COMBO, &CMP3EncodeCfgDlg::OnCbnSelchangeAbrRateCombo) - ON_BN_CLICKED(IDC_CBR_RADIO, &CMP3EncodeCfgDlg::OnBnClickedCbrRadio) - ON_BN_CLICKED(IDC_ABR_RADIO, &CMP3EncodeCfgDlg::OnBnClickedAbrRadio) - ON_BN_CLICKED(IDC_VBR_RADIO, &CMP3EncodeCfgDlg::OnBnClickedVbrRadio) - ON_NOTIFY(NM_CUSTOMDRAW, IDC_SLIDER1, &CMP3EncodeCfgDlg::OnNMCustomdrawSlider1) - ON_BN_CLICKED(IDC_USER_RADIO, &CMP3EncodeCfgDlg::OnBnClickedUserRadio) - ON_BN_CLICKED(IDC_JOINT_STEREO_CHECK, &CMP3EncodeCfgDlg::OnBnClickedJointStereoCheck) + CBaseDialog::DoDataExchange(pDX); + DDX_Control(pDX, IDC_CBR_RATE_COMBO, m_cbr_rate_combo); + DDX_Control(pDX, IDC_ABR_RATE_COMBO, m_abr_rate_combo); + DDX_Control(pDX, IDC_SLIDER1, m_vbr_qua_sld); + DDX_Control(pDX, IDC_ENCODE_CMDLINE_EDIT, m_encode_cmdline_edit); +} + + +BEGIN_MESSAGE_MAP(CMP3EncodeCfgDlg, CBaseDialog) + ON_CBN_SELCHANGE(IDC_CBR_RATE_COMBO, &CMP3EncodeCfgDlg::OnCbnSelchangeCbrRateCombo) + ON_CBN_SELCHANGE(IDC_ABR_RATE_COMBO, &CMP3EncodeCfgDlg::OnCbnSelchangeAbrRateCombo) + ON_BN_CLICKED(IDC_CBR_RADIO, &CMP3EncodeCfgDlg::OnBnClickedCbrRadio) + ON_BN_CLICKED(IDC_ABR_RADIO, &CMP3EncodeCfgDlg::OnBnClickedAbrRadio) + ON_BN_CLICKED(IDC_VBR_RADIO, &CMP3EncodeCfgDlg::OnBnClickedVbrRadio) + ON_NOTIFY(NM_CUSTOMDRAW, IDC_SLIDER1, &CMP3EncodeCfgDlg::OnNMCustomdrawSlider1) + ON_BN_CLICKED(IDC_JOINT_STEREO_CHECK, &CMP3EncodeCfgDlg::OnBnClickedJointStereoCheck) + ON_BN_CLICKED(IDC_USER_CHECK, &CMP3EncodeCfgDlg::OnBnClickedUserRadio) END_MESSAGE_MAP() @@ -101,127 +127,141 @@ END_MESSAGE_MAP() BOOL CMP3EncodeCfgDlg::OnInitDialog() { - CDialog::OnInitDialog(); - - // TODO: 在此添加额外的初始化 - InitBitrateCombobox(m_cbr_rate_combo); - InitBitrateCombobox(m_abr_rate_combo); - int index; - index = m_cbr_rate_combo.FindStringExact(0, m_encode_para.cbr_bitrate.c_str()); - m_cbr_rate_combo.SetCurSel(index); - index = m_abr_rate_combo.FindStringExact(0, m_encode_para.abr_bitrate.c_str()); - m_abr_rate_combo.SetCurSel(index); - switch (m_encode_para.encode_type) - { - case 0: - m_cbr_radio.SetCheck(TRUE); - break; - case 1: - m_abr_radio.SetCheck(TRUE); - break; - case 2: - m_vbr_radio.SetCheck(TRUE); - break; - case 3: - m_user_radio.SetCheck(TRUE); - break; - } - - m_vbr_qua_sld.SetRange(0, 9); - m_vbr_qua_sld.SetPos(9 - m_encode_para.vbr_quality); - - m_joint_stereo_btn.SetCheck(m_encode_para.joint_stereo); - - EncodeParaToCmdline(m_encode_para); - SetControlState(); - return TRUE; // return TRUE unless you set the focus to a control - // 异常: OCX 属性页应返回 FALSE + CBaseDialog::OnInitDialog(); + + // TODO: 在此添加额外的初始化 + m_bitrate_list.emplace_back(L"32 kbps", 32); + m_bitrate_list.emplace_back(L"40 kbps", 40); + m_bitrate_list.emplace_back(L"64 kbps", 64); + m_bitrate_list.emplace_back(L"80 kbps", 80); + m_bitrate_list.emplace_back(L"96 kbps", 96); + m_bitrate_list.emplace_back(L"112 kbps", 112); + m_bitrate_list.emplace_back(L"128 kbps", 128); + m_bitrate_list.emplace_back(L"160 kbps", 160); + m_bitrate_list.emplace_back(L"192 kbps", 192); + m_bitrate_list.emplace_back(L"224 kbps", 224); + m_bitrate_list.emplace_back(L"256 kbps", 256); + m_bitrate_list.emplace_back(L"320 kbps", 320); + + int index_cbr{}, index_abr{}; + for (size_t i{}; i < m_bitrate_list.size(); ++i) + { + const auto& item = m_bitrate_list[i]; + if (item.second == m_encode_para.cbr_bitrate) + index_cbr = i; + if (item.second == m_encode_para.abr_bitrate) + index_abr = i; + m_cbr_rate_combo.AddString(item.first.c_str()); + m_abr_rate_combo.AddString(item.first.c_str()); + } + m_cbr_rate_combo.SetCurSel(index_cbr); + m_abr_rate_combo.SetCurSel(index_abr); + + switch (m_encode_para.encode_type) + { + case 0: CheckDlgButton(IDC_CBR_RADIO, TRUE); break; + case 1: CheckDlgButton(IDC_ABR_RADIO, TRUE); break; + case 2: CheckDlgButton(IDC_VBR_RADIO, TRUE); break; + default: break; + } + + m_vbr_qua_sld.SetRange(0, 9); + m_vbr_qua_sld.SetPos(9 - m_encode_para.vbr_quality); + + CheckDlgButton(IDC_JOINT_STEREO_CHECK, m_encode_para.joint_stereo); + CheckDlgButton(IDC_USER_CHECK, m_encode_para.user_define_para); + + EncodeParaToCmdline(m_encode_para); + SetControlState(); + return TRUE; // return TRUE unless you set the focus to a control + // 异常: OCX 属性页应返回 FALSE } void CMP3EncodeCfgDlg::OnCbnSelchangeCbrRateCombo() { - // TODO: 在此添加控件通知处理程序代码 - CString str; - m_cbr_rate_combo.GetLBText(m_cbr_rate_combo.GetCurSel(), str); - m_encode_para.cbr_bitrate = str; - EncodeParaToCmdline(m_encode_para); - SetControlState(); + // TODO: 在此添加控件通知处理程序代码 + int sel = m_cbr_rate_combo.GetCurSel(); + if (sel >= 0 && sel < static_cast(m_bitrate_list.size())) + m_encode_para.cbr_bitrate = m_bitrate_list[sel].second; + EncodeParaToCmdline(m_encode_para); + SetControlState(); } void CMP3EncodeCfgDlg::OnCbnSelchangeAbrRateCombo() { - // TODO: 在此添加控件通知处理程序代码 - CString str; - m_abr_rate_combo.GetLBText(m_abr_rate_combo.GetCurSel(), str); - m_encode_para.abr_bitrate = str; - EncodeParaToCmdline(m_encode_para); - SetControlState(); + // TODO: 在此添加控件通知处理程序代码 + int sel = m_abr_rate_combo.GetCurSel(); + if (sel >= 0 && sel < static_cast(m_bitrate_list.size())) + m_encode_para.abr_bitrate = m_bitrate_list[sel].second; + EncodeParaToCmdline(m_encode_para); + SetControlState(); } void CMP3EncodeCfgDlg::OnBnClickedCbrRadio() { - // TODO: 在此添加控件通知处理程序代码 - m_encode_para.encode_type = 0; - EncodeParaToCmdline(m_encode_para); - SetControlState(); + // TODO: 在此添加控件通知处理程序代码 + m_encode_para.encode_type = 0; + EncodeParaToCmdline(m_encode_para); + SetControlState(); } void CMP3EncodeCfgDlg::OnBnClickedAbrRadio() { - // TODO: 在此添加控件通知处理程序代码 - m_encode_para.encode_type = 1; - EncodeParaToCmdline(m_encode_para); - SetControlState(); + // TODO: 在此添加控件通知处理程序代码 + m_encode_para.encode_type = 1; + EncodeParaToCmdline(m_encode_para); + SetControlState(); } void CMP3EncodeCfgDlg::OnBnClickedVbrRadio() { - // TODO: 在此添加控件通知处理程序代码 - m_encode_para.encode_type = 2; - EncodeParaToCmdline(m_encode_para); - SetControlState(); + // TODO: 在此添加控件通知处理程序代码 + m_encode_para.encode_type = 2; + EncodeParaToCmdline(m_encode_para); + SetControlState(); } void CMP3EncodeCfgDlg::OnNMCustomdrawSlider1(NMHDR *pNMHDR, LRESULT *pResult) { - LPNMCUSTOMDRAW pNMCD = reinterpret_cast(pNMHDR); - // TODO: 在此添加控件通知处理程序代码 - m_encode_para.vbr_quality = 9 - m_vbr_qua_sld.GetPos(); - EncodeParaToCmdline(m_encode_para); - SetControlState(); - *pResult = 0; + LPNMCUSTOMDRAW pNMCD = reinterpret_cast(pNMHDR); + // TODO: 在此添加控件通知处理程序代码 + m_encode_para.vbr_quality = 9 - m_vbr_qua_sld.GetPos(); + EncodeParaToCmdline(m_encode_para); + SetControlState(); + *pResult = 0; } -void CMP3EncodeCfgDlg::OnBnClickedUserRadio() +void CMP3EncodeCfgDlg::OnBnClickedJointStereoCheck() { - // TODO: 在此添加控件通知处理程序代码 - m_encode_para.encode_type = 3; - SetControlState(); + // TODO: 在此添加控件通知处理程序代码 + m_encode_para.joint_stereo = (IsDlgButtonChecked(IDC_JOINT_STEREO_CHECK) != 0); + EncodeParaToCmdline(m_encode_para); + SetControlState(); } -void CMP3EncodeCfgDlg::OnOK() +void CMP3EncodeCfgDlg::OnBnClickedUserRadio() { - // TODO: 在此添加专用代码和/或调用基类 - CString str; - m_encode_cmdline_edit.GetWindowText(str); - m_encode_para.cmd_para = str; - - CDialog::OnOK(); + // TODO: 在此添加控件通知处理程序代码 + m_encode_para.user_define_para = (IsDlgButtonChecked(IDC_USER_CHECK) != 0); + EncodeParaToCmdline(m_encode_para); + SetControlState(); } -void CMP3EncodeCfgDlg::OnBnClickedJointStereoCheck() +void CMP3EncodeCfgDlg::OnOK() { - // TODO: 在此添加控件通知处理程序代码 - m_encode_para.joint_stereo = (m_joint_stereo_btn.GetCheck() != 0); - EncodeParaToCmdline(m_encode_para); - SetControlState(); + // TODO: 在此添加专用代码和/或调用基类 + CString str; + m_encode_cmdline_edit.GetWindowTextW(str); + m_encode_para.cmd_para = str; + + CBaseDialog::OnOK(); } diff --git a/MusicPlayer2/MP3EncodeCfgDlg.h b/MusicPlayer2/MP3EncodeCfgDlg.h index 11860a089..e918e53da 100644 --- a/MusicPlayer2/MP3EncodeCfgDlg.h +++ b/MusicPlayer2/MP3EncodeCfgDlg.h @@ -1,52 +1,53 @@ #pragma once +#include "BaseDialog.h" #include "IPlayerCore.h" // CMP3EncodeCfgDlg 对话框 -class CMP3EncodeCfgDlg : public CDialog +class CMP3EncodeCfgDlg : public CBaseDialog { - DECLARE_DYNAMIC(CMP3EncodeCfgDlg) + DECLARE_DYNAMIC(CMP3EncodeCfgDlg) public: - CMP3EncodeCfgDlg(CWnd* pParent = nullptr); // 标准构造函数 - virtual ~CMP3EncodeCfgDlg(); + CMP3EncodeCfgDlg(CWnd* pParent = nullptr); // 标准构造函数 + virtual ~CMP3EncodeCfgDlg(); // 对话框数据 #ifdef AFX_DESIGN_TIME - enum { IDD = IDD_MP3_ENCODE_CFG_DIALOG }; + enum { IDD = IDD_MP3_ENCODE_CFG_DIALOG }; #endif - MP3EncodePara m_encode_para; + MP3EncodePara m_encode_para; - void InitBitrateCombobox(CComboBox& combo); - void SetControlState(); + static void EncodeParaToCmdline(MP3EncodePara& para); - static void EncodeParaToCmdline(MP3EncodePara& para); +protected: + void SetControlState(); + + //控制变量 + CComboBox m_cbr_rate_combo; + CComboBox m_abr_rate_combo; + CSliderCtrl m_vbr_qua_sld; + CEdit m_encode_cmdline_edit; + + vector> m_bitrate_list; protected: - //控制变量 - CButton m_cbr_radio; - CButton m_abr_radio; - CButton m_vbr_radio; - CButton m_user_radio; - CComboBox m_cbr_rate_combo; - CComboBox m_abr_rate_combo; - CSliderCtrl m_vbr_qua_sld; - CEdit m_encode_cmdline_edit; - CButton m_joint_stereo_btn; - - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 - - DECLARE_MESSAGE_MAP() + virtual CString GetDialogName() const override; + virtual bool IsRememberDialogSizeEnable() const override { return false; }; + virtual bool InitializeControls() override; + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 + + DECLARE_MESSAGE_MAP() public: - virtual BOOL OnInitDialog(); - afx_msg void OnCbnSelchangeCbrRateCombo(); - afx_msg void OnCbnSelchangeAbrRateCombo(); - afx_msg void OnBnClickedCbrRadio(); - afx_msg void OnBnClickedAbrRadio(); - afx_msg void OnBnClickedVbrRadio(); - afx_msg void OnNMCustomdrawSlider1(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnBnClickedUserRadio(); - virtual void OnOK(); - afx_msg void OnBnClickedJointStereoCheck(); + virtual BOOL OnInitDialog(); + afx_msg void OnCbnSelchangeCbrRateCombo(); + afx_msg void OnCbnSelchangeAbrRateCombo(); + afx_msg void OnBnClickedCbrRadio(); + afx_msg void OnBnClickedAbrRadio(); + afx_msg void OnBnClickedVbrRadio(); + afx_msg void OnNMCustomdrawSlider1(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnBnClickedJointStereoCheck(); + afx_msg void OnBnClickedUserRadio(); + virtual void OnOK(); }; diff --git a/MusicPlayer2/MciCore.cpp b/MusicPlayer2/MciCore.cpp index 00adf0cb5..ddb90a97d 100644 --- a/MusicPlayer2/MciCore.cpp +++ b/MusicPlayer2/MciCore.cpp @@ -2,6 +2,8 @@ #include "MciCore.h" #include "AudioCommon.h" #include "MusicPlayer2.h" +#include "AudioTag.h" +#include "FilePathHelper.h" CMciCore::CMciCore() @@ -10,8 +12,8 @@ CMciCore::CMciCore() if (!IsSucceed()) { - CString strInfo = CCommon::LoadText(IDS_MCI_INIT_FAILED); - theApp.WriteLog(wstring(strInfo)); + const wstring& info = theApp.m_str_table.LoadText(L"LOG_MCI_INIT_FAILED"); + theApp.WriteLog(info); } } @@ -43,7 +45,7 @@ void CMciCore::InitCore() //向支持的文件列表插入原生支持的文件格式 CAudioCommon::m_surpported_format.clear(); SupportedFormat format; - format.description = CCommon::LoadText(IDS_BASIC_AUDIO_FORMAT); + format.description = theApp.m_str_table.LoadText(L"TXT_FILE_TYPE_BASE"); format.extensions.push_back(L"mp3"); format.extensions.push_back(L"wma"); format.extensions.push_back(L"wav"); @@ -210,13 +212,14 @@ void CMciCore::GetAudioInfo(SongInfo & song_info, int flag) if (m_success) { if (flag&AF_LENGTH) - song_info.setLength(GetMciSongLength(song_info.file_path)); + song_info.end_pos.fromInt(GetMciSongLength(song_info.file_path)); if (flag&AF_BITRATE) song_info.bitrate = GetMciBitrate(song_info.file_path); if (flag&AF_TAG_INFO) { CAudioTag audio_tag(song_info); audio_tag.GetAudioTag(); + audio_tag.GetAudioRating(); } } @@ -231,7 +234,7 @@ void CMciCore::GetAudioInfo(const wchar_t * file_path, SongInfo & song_info, int { wchar_t buff[16]; m_error_code = mciSendStringW((L"status \"" + wstring(file_path) + L"\" length").c_str(), buff, 15, 0); //获取当前歌曲的长度,并储存在buff数组里 - song_info.setLength(_wtoi(buff)); + song_info.end_pos.fromInt(_wtoi(buff)); } if (flag&AF_BITRATE) song_info.bitrate = GetMciBitrate(file_path); @@ -239,6 +242,7 @@ void CMciCore::GetAudioInfo(const wchar_t * file_path, SongInfo & song_info, int { CAudioTag audio_tag(song_info); audio_tag.GetAudioTag(); + audio_tag.GetAudioRating(); } m_error_code = mciSendStringW((L"close \"" + wstring(file_path) + L"\"").c_str(), NULL, 0, 0); diff --git a/MusicPlayer2/MediaClassifyDlg.cpp b/MusicPlayer2/MediaClassifyDlg.cpp index 8226b89e6..a1119d38e 100644 --- a/MusicPlayer2/MediaClassifyDlg.cpp +++ b/MusicPlayer2/MediaClassifyDlg.cpp @@ -4,7 +4,6 @@ #include "stdafx.h" #include "MusicPlayer2.h" #include "MediaClassifyDlg.h" -#include "afxdialogex.h" #include "Playlist.h" #include "InputDlg.h" #include "MusicPlayerCmdHelper.h" @@ -22,13 +21,13 @@ CMediaClassifyDlg::CMediaClassifyDlg(CMediaClassifier::ClassificationType type, m_classifer(type, theApp.m_media_lib_setting_data.hide_only_one_classification) { if (m_type == CMediaClassifier::CT_ARTIST) - m_default_str = CCommon::LoadText(IDS_DEFAULT_ARTIST); + m_default_str = theApp.m_str_table.LoadText(L"TXT_EMPTY_ARTIST"); else if (m_type == CMediaClassifier::CT_ALBUM) - m_default_str = CCommon::LoadText(IDS_DEFAULT_ALBUM); + m_default_str = theApp.m_str_table.LoadText(L"TXT_EMPTY_ALBUM"); else if (m_type == CMediaClassifier::CT_GENRE) - m_default_str = CCommon::LoadText(IDS_DEFAULT_GENRE); + m_default_str = theApp.m_str_table.LoadText(L"TXT_EMPTY_GENRE"); else if (m_type == CMediaClassifier::CT_YEAR) - m_default_str = CCommon::LoadText(IDS_DEFAULT_YEAR); + m_default_str = theApp.m_str_table.LoadText(L"TXT_EMPTY_YEAR"); } CMediaClassifyDlg::~CMediaClassifyDlg() @@ -71,7 +70,7 @@ bool CMediaClassifyDlg::SetLeftListSel(const wstring& item) if (m_type == CMediaClassifier::CT_ARTIST) { vector artist_list; - song.GetArtistList(artist_list, theApp.m_media_lib_setting_data.artist_split_ext); + song.GetArtistList(artist_list); if (CCommon::IsItemInVector(artist_list, item)) { other_index = i; @@ -153,9 +152,8 @@ void CMediaClassifyDlg::ShowClassifyList() auto iter = media_list.find(STR_OTHER_CLASSIFY_TYPE); if (iter != media_list.end()) { - CString item_name = CCommon::LoadText(_T("<"), IDS_OTHER, _T(">")); CListCtrlEx::RowData row_data; - row_data[0] = wstring(item_name); + row_data[0] = theApp.m_str_table.LoadText(L"TXT_CLASSIFY_OTHER"); row_data[1] = std::to_wstring(iter->second.size()); m_list_data_left.push_back(std::move(row_data)); } @@ -204,7 +202,7 @@ CString CMediaClassifyDlg::GetClassifyListSelectedString(int index) const CString str_selected = m_classify_list_ctrl.GetItemText(index, 0); if (str_selected == m_default_str.c_str()) str_selected.Empty(); - if (str_selected == CCommon::LoadText(_T("<"), IDS_OTHER, _T(">"))) + if (str_selected == theApp.m_str_table.LoadText(L"TXT_CLASSIFY_OTHER").c_str()) str_selected = STR_OTHER_CLASSIFY_TYPE; return str_selected; } @@ -421,62 +419,60 @@ BOOL CMediaClassifyDlg::OnInitDialog() // TODO: 在此添加额外的初始化 - CCommon::SetDialogFont(this, theApp.m_pMainWnd->GetFont()); //由于此对话框资源由不同语言共用,所以这里要设置一下字体 - //初始化左侧列表 m_classify_list_ctrl.SetExtendedStyle(m_classify_list_ctrl.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_LABELTIP); - CString title_name; + wstring title_name; if (m_type == CMediaClassifier::CT_ARTIST) - title_name = CCommon::LoadText(IDS_ARTIST); + title_name = theApp.m_str_table.LoadText(L"TXT_ARTIST"); else if (m_type == CMediaClassifier::CT_ALBUM) - title_name = CCommon::LoadText(IDS_ALBUM); + title_name = theApp.m_str_table.LoadText(L"TXT_ALBUM"); else if (m_type == CMediaClassifier::CT_GENRE) - title_name = CCommon::LoadText(IDS_GENRE); + title_name = theApp.m_str_table.LoadText(L"TXT_GENRE"); else if (m_type == CMediaClassifier::CT_YEAR) - title_name = CCommon::LoadText(IDS_YEAR); + title_name = theApp.m_str_table.LoadText(L"TXT_YEAR"); else if (m_type == CMediaClassifier::CT_TYPE) - title_name = CCommon::LoadText(IDS_FILE_TYPE); + title_name = theApp.m_str_table.LoadText(L"TXT_FILE_TYPE"); else if (m_type == CMediaClassifier::CT_BITRATE) - title_name = CCommon::LoadText(IDS_BITRATE); + title_name = theApp.m_str_table.LoadText(L"TXT_BITRATE"); else if (m_type == CMediaClassifier::CT_RATING) - title_name = CCommon::LoadText(IDS_RATING); + title_name = theApp.m_str_table.LoadText(L"TXT_RATING"); CRect rc_classify_list; m_classify_list_ctrl.GetWindowRect(rc_classify_list); std::vector width; CalculateClassifyListColumeWidth(width); - m_classify_list_ctrl.InsertColumn(0, title_name, LVCFMT_LEFT, width[0]); - m_classify_list_ctrl.InsertColumn(1, CCommon::LoadText(IDS_TRACK_TOTAL_NUM), LVCFMT_LEFT, width[1]); + m_classify_list_ctrl.InsertColumn(0, title_name.c_str(), LVCFMT_LEFT, width[0]); + m_classify_list_ctrl.InsertColumn(1, theApp.m_str_table.LoadText(L"TXT_NUM_OF_TRACK").c_str(), LVCFMT_LEFT, width[1]); //ShowClassifyList(); //初始化右侧列表 m_song_list_ctrl.SetExtendedStyle(m_song_list_ctrl.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_LABELTIP); //CRect rc_song_list; //m_song_list_ctrl.GetWindowRect(rc_song_list); - m_song_list_ctrl.InsertColumn(0, CCommon::LoadText(IDS_TITLE), LVCFMT_LEFT, theApp.DPI(150)); - m_song_list_ctrl.InsertColumn(1, CCommon::LoadText(IDS_ARTIST), LVCFMT_LEFT, theApp.DPI(100)); - m_song_list_ctrl.InsertColumn(2, CCommon::LoadText(IDS_ALBUM), LVCFMT_LEFT, theApp.DPI(150)); - m_song_list_ctrl.InsertColumn(3, CCommon::LoadText(IDS_TRACK_NUM), LVCFMT_LEFT, theApp.DPI(60)); - m_song_list_ctrl.InsertColumn(4, CCommon::LoadText(IDS_GENRE), LVCFMT_LEFT, theApp.DPI(100)); - m_song_list_ctrl.InsertColumn(5, CCommon::LoadText(IDS_BITRATE), LVCFMT_LEFT, theApp.DPI(60)); - m_song_list_ctrl.InsertColumn(6, CCommon::LoadText(IDS_FILE_PATH), LVCFMT_LEFT, theApp.DPI(600)); + m_song_list_ctrl.InsertColumn(0, theApp.m_str_table.LoadText(L"TXT_TITLE").c_str(), LVCFMT_LEFT, theApp.DPI(150)); + m_song_list_ctrl.InsertColumn(1, theApp.m_str_table.LoadText(L"TXT_ARTIST").c_str(), LVCFMT_LEFT, theApp.DPI(100)); + m_song_list_ctrl.InsertColumn(2, theApp.m_str_table.LoadText(L"TXT_ALBUM").c_str(), LVCFMT_LEFT, theApp.DPI(150)); + m_song_list_ctrl.InsertColumn(3, theApp.m_str_table.LoadText(L"TXT_TRACK_NUM").c_str(), LVCFMT_LEFT, theApp.DPI(60)); + m_song_list_ctrl.InsertColumn(4, theApp.m_str_table.LoadText(L"TXT_GENRE").c_str(), LVCFMT_LEFT, theApp.DPI(100)); + m_song_list_ctrl.InsertColumn(5, theApp.m_str_table.LoadText(L"TXT_BITRATE").c_str(), LVCFMT_LEFT, theApp.DPI(60)); + m_song_list_ctrl.InsertColumn(6, theApp.m_str_table.LoadText(L"TXT_FILE_PATH").c_str(), LVCFMT_LEFT, theApp.DPI(600)); m_song_list_ctrl.SetCtrlAEnable(true); if (m_type == CMediaClassifier::CT_ARTIST) - m_search_edit.SetCueBanner(CCommon::LoadText(IDS_SEARCH_ARTIST), TRUE); + m_search_edit.SetCueBanner(theApp.m_str_table.LoadText(L"TXT_SEARCH_PROMPT_ARTIST").c_str(), TRUE); else if (m_type == CMediaClassifier::CT_ALBUM) - m_search_edit.SetCueBanner(CCommon::LoadText(IDS_SEARCH_ALBUM), TRUE); + m_search_edit.SetCueBanner(theApp.m_str_table.LoadText(L"TXT_SEARCH_PROMPT_ALBUM").c_str(), TRUE); else if (m_type == CMediaClassifier::CT_GENRE) - m_search_edit.SetCueBanner(CCommon::LoadText(IDS_SEARCH_GENRE), TRUE); + m_search_edit.SetCueBanner(theApp.m_str_table.LoadText(L"TXT_SEARCH_PROMPT_GENRE").c_str(), TRUE); else if (m_type == CMediaClassifier::CT_YEAR) - m_search_edit.SetCueBanner(CCommon::LoadText(IDS_SEARCH_YEAR), TRUE); + m_search_edit.SetCueBanner(theApp.m_str_table.LoadText(L"TXT_SEARCH_PROMPT_YEAR").c_str(), TRUE); else if (m_type == CMediaClassifier::CT_TYPE) - m_search_edit.SetCueBanner(CCommon::LoadText(IDS_SEARCH_FILE_TYPE), TRUE); + m_search_edit.SetCueBanner(theApp.m_str_table.LoadText(L"TXT_SEARCH_PROMPT_FILE_TYPE").c_str(), TRUE); else if (m_type == CMediaClassifier::CT_BITRATE) - m_search_edit.SetCueBanner(CCommon::LoadText(IDS_SEARCH_BITRATE), TRUE); + m_search_edit.SetCueBanner(theApp.m_str_table.LoadText(L"TXT_SEARCH_PROMPT_BITRATE").c_str(), TRUE); else if (m_type == CMediaClassifier::CT_RATING) m_search_edit.EnableWindow(FALSE); else - m_search_edit.SetCueBanner(CCommon::LoadText(IDS_SEARCH_HERE), TRUE); + m_search_edit.SetCueBanner(theApp.m_str_table.LoadText(L"TXT_SEARCH_PROMPT").c_str(), TRUE); //初始化分隔条 m_splitter_ctrl.AttachCtrlAsLeftPane(IDC_CLASSIFY_LIST); @@ -506,7 +502,7 @@ void CMediaClassifyDlg::OnNMRClickClassifyList(NMHDR* pNMHDR, LRESULT* pResult) if (!m_left_selected_items.empty()) { //弹出右键菜单 - CMenu* pMenu = theApp.m_menu_set.m_media_lib_popup_menu.GetSubMenu(0); + CMenu* pMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::LibLeftMenu); ASSERT(pMenu != nullptr); if (pMenu != nullptr) { @@ -570,7 +566,7 @@ void CMediaClassifyDlg::OnNMRClickSongList(NMHDR* pNMHDR, LRESULT* pResult) if (!m_right_selected_items.empty()) { //弹出右键菜单 - CMenu* pMenu = theApp.m_menu_set.m_media_lib_popup_menu.GetSubMenu(1); + CMenu* pMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::LibRightMenu); ASSERT(pMenu != nullptr); if (pMenu != nullptr) { @@ -582,39 +578,6 @@ void CMediaClassifyDlg::OnNMRClickSongList(NMHDR* pNMHDR, LRESULT* pResult) } -//void CMediaClassifyDlg::OnInitMenu(CMenu* pMenu) -//{ -// CMediaLibTabDlg::OnInitMenu(pMenu); -// -// //bool select_valid; -// //if (m_left_selected) -// // select_valid = !m_left_selected_items.empty(); -// //else -// // select_valid = !m_right_selected_items.empty(); -// -// //pMenu->EnableMenuItem(ID_PLAY_ITEM, MF_BYCOMMAND | (select_valid ? MF_ENABLED : MF_GRAYED)); -// //pMenu->EnableMenuItem(ID_PLAY_ITEM_IN_FOLDER_MODE, MF_BYCOMMAND | (select_valid ? MF_ENABLED : MF_GRAYED)); -// //pMenu->EnableMenuItem(ID_ADD_TO_DEFAULT_PLAYLIST, MF_BYCOMMAND | (select_valid ? MF_ENABLED : MF_GRAYED)); -// //pMenu->EnableMenuItem(ID_ADD_TO_MY_FAVOURITE, MF_BYCOMMAND | (select_valid ? MF_ENABLED : MF_GRAYED)); -// //for (UINT id = ID_ADD_TO_MY_FAVOURITE + 1; id < ID_ADD_TO_MY_FAVOURITE + ADD_TO_PLAYLIST_MAX_SIZE; id++) -// //{ -// // pMenu->EnableMenuItem(id, MF_BYCOMMAND | (select_valid ? MF_ENABLED : MF_GRAYED)); -// //} -// //pMenu->EnableMenuItem(ID_ADD_TO_NEW_PLAYLIST, MF_BYCOMMAND | (select_valid ? MF_ENABLED : MF_GRAYED)); -// //pMenu->EnableMenuItem(ID_ADD_TO_NEW_PALYLIST_AND_PLAY, MF_BYCOMMAND | (select_valid ? MF_ENABLED : MF_GRAYED)); -// //pMenu->EnableMenuItem(ID_EXPLORE_ONLINE, MF_BYCOMMAND | (select_valid ? MF_ENABLED : MF_GRAYED)); -// //pMenu->EnableMenuItem(ID_FORMAT_CONVERT, MF_BYCOMMAND | (select_valid ? MF_ENABLED : MF_GRAYED)); -// //pMenu->EnableMenuItem(ID_EXPLORE_TRACK, MF_BYCOMMAND | (select_valid ? MF_ENABLED : MF_GRAYED)); -// //pMenu->EnableMenuItem(ID_ITEM_PROPERTY, MF_BYCOMMAND | (select_valid ? MF_ENABLED : MF_GRAYED)); -// -// pMenu->SetDefaultItem(ID_PLAY_ITEM); -// -// // TODO: 在此处添加消息处理程序代码 -//} - - - - void CMediaClassifyDlg::OnNMDblclkClassifyList(NMHDR* pNMHDR, LRESULT* pResult) { LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast(pNMHDR); diff --git a/MusicPlayer2/MediaLibHelper.cpp b/MusicPlayer2/MediaLibHelper.cpp index 8786a677b..5da050cf3 100644 --- a/MusicPlayer2/MediaLibHelper.cpp +++ b/MusicPlayer2/MediaLibHelper.cpp @@ -1,8 +1,8 @@ #include "stdafx.h" #include "MediaLibHelper.h" #include "MusicPlayer2.h" -#include #include "SongDataManager.h" +#include "FilePathHelper.h" CMediaClassifier::CMediaClassifier(ClassificationType type, bool hide_only_one_classification) : m_type(type), m_hide_only_one_classification(hide_only_one_classification) @@ -35,35 +35,41 @@ void CMediaClassifier::ClassifyMedia() switch (m_type) { case CMediaClassifier::CT_ARTIST: - song_info.second.GetArtistList(item_names, theApp.m_media_lib_setting_data.artist_split_ext); // 有的歌曲可能有多个艺术家,将解析到的艺术家保存到vector里 + { + static const wstring& default_artist = theApp.m_str_table.LoadText(L"TXT_EMPTY_ARTIST"); + song_info.second.GetArtistList(item_names); // 有的歌曲可能有多个艺术家,将解析到的艺术家保存到vector里 for (auto& item_name : item_names) CCommon::StringNormalize(item_name); - if (item_names.empty() || (item_names.size() == 1 && item_names[0] == CCommon::LoadText(IDS_DEFAULT_ARTIST).GetString())) + if (item_names.empty() || (item_names.size() == 1 && default_artist == item_names[0])) { item_names.clear(); item_names.push_back(std::wstring()); } - break; + } + break; case CMediaClassifier::CT_ALBUM: { + static const wstring& default_album = theApp.m_str_table.LoadText(L"TXT_EMPTY_ALBUM"); wstring str_album = song_info.second.album; - if (str_album == CCommon::LoadText(IDS_DEFAULT_ALBUM).GetString()) + if (default_album == str_album) str_album.clear(); item_names.push_back(str_album); } break; case CMediaClassifier::CT_GENRE: { + static const wstring& default_genre = theApp.m_str_table.LoadText(L"TXT_EMPTY_GENRE"); wstring str_genre = song_info.second.genre; - if (str_genre == CCommon::LoadText(IDS_DEFAULT_GENRE).GetString()) + if (default_genre == str_genre) str_genre.clear(); item_names.push_back(str_genre); } break; case CMediaClassifier::CT_YEAR: { + static const wstring& default_year = theApp.m_str_table.LoadText(L"TXT_EMPTY_YEAR"); wstring str_year = song_info.second.get_year(); - if (str_year == CCommon::LoadText(IDS_DEFAULT_YEAR).GetString()) + if (default_year == str_year) str_year.clear(); if (str_year.size() > 4) str_year.resize(4); @@ -106,7 +112,7 @@ void CMediaClassifier::ClassifyMedia() if (song_info.second.rating >= 1 && song_info.second.rating <= 5) str_type = std::to_wstring(song_info.second.rating); else - str_type = CCommon::LoadText(IDS_UNRATED).GetString(); + str_type = theApp.m_str_table.LoadText(L"TXT_EMPTY_RATED"); item_names.push_back(str_type); break; } diff --git a/MusicPlayer2/MediaLibHelper.h b/MusicPlayer2/MediaLibHelper.h index b47e6f5ed..752f95f15 100644 --- a/MusicPlayer2/MediaLibHelper.h +++ b/MusicPlayer2/MediaLibHelper.h @@ -1,6 +1,6 @@ #pragma once -#include #include "SongInfo.h" +#include "Common.h" #define STR_OTHER_CLASSIFY_TYPE L"eRk0Q6ov" diff --git a/MusicPlayer2/MediaLibSettingDlg.cpp b/MusicPlayer2/MediaLibSettingDlg.cpp index c04d70526..eca4524ff 100644 --- a/MusicPlayer2/MediaLibSettingDlg.cpp +++ b/MusicPlayer2/MediaLibSettingDlg.cpp @@ -4,11 +4,11 @@ #include "stdafx.h" #include "MusicPlayer2.h" #include "MediaLibSettingDlg.h" -#include "afxdialogex.h" #include "MusicPlayerCmdHelper.h" #include "CleanupRangeDlg.h" #include "SongDataManager.h" #include "COSUPlayerHelper.h" +#include "FilePathHelper.h" // CMediaLibSettingDlg 对话框 @@ -27,29 +27,175 @@ CMediaLibSettingDlg::~CMediaLibSettingDlg() void CMediaLibSettingDlg::ShowDataSizeInfo() { - CString info; + wstring info; if (m_data_size < 1024) - info.Format(_T("%s: %d %s"), CCommon::LoadText(IDS_CURRENT_DATA_FILE_SIZE), m_data_size, CCommon::LoadText(IDS_BYTE)); + info = theApp.m_str_table.LoadTextFormat(L"TXT_OPT_MEDIA_LIB_CURRENT_DATA_FILE_SIZE_BYTE", { m_data_size }); else if (m_data_size < 1024 * 1024) - info.Format(_T("%s: %.2f KB (%d %s)"), CCommon::LoadText(IDS_CURRENT_DATA_FILE_SIZE), static_cast(m_data_size) / 1024.0f, m_data_size, CCommon::LoadText(IDS_BYTE)); + { + std::wstringstream wss; + wss << std::fixed << std::setprecision(2) << static_cast(m_data_size) / 1024.0f; + info = theApp.m_str_table.LoadTextFormat(L"TXT_OPT_MEDIA_LIB_CURRENT_DATA_FILE_SIZE_KB", { m_data_size, wss.str() }); + } else - info.Format(_T("%s: %.2f MB (%d %s)"), CCommon::LoadText(IDS_CURRENT_DATA_FILE_SIZE), static_cast(m_data_size) / 1024.0f / 1024.0f, m_data_size, CCommon::LoadText(IDS_BYTE)); //注:此处曾经由于“%.2fMB”漏掉了“f”导致出现了一打开这个对话框程序就停止工作的严重问题。 - SetDlgItemText(IDC_SIZE_STATIC, info); + { + std::wstringstream wss; + wss << std::fixed << std::setprecision(2) << static_cast(m_data_size) / 1024.0f / 1024.0f; + info = theApp.m_str_table.LoadTextFormat(L"TXT_OPT_MEDIA_LIB_CURRENT_DATA_FILE_SIZE_MB", { m_data_size, wss.str() }); + } + SetDlgItemText(IDC_SIZE_STATIC, info.c_str()); +} + +bool CMediaLibSettingDlg::InitializeControls() +{ + wstring temp; + temp = theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_MEDIA_LIB_OPT"); + SetDlgItemTextW(IDC_TXT_OPT_MEDIA_LIB_MEDIA_LIB_OPT_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_DISABLE_DEL"); + SetDlgItemTextW(IDC_DISABLE_DELETE_FROM_DISK_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_USE_CLASSIFY_OTHER"); + SetDlgItemTextW(IDC_CLASSIFY_OTHER_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_TOO_SHORT_SEC"); + SetDlgItemTextW(IDC_TXT_OPT_MEDIA_LIB_TOO_SHORT_SEC_STATIC, temp.c_str()); + // IDC_FILE_TOO_SHORT_SEC_EDIT + temp = theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_ARTIST_SPLIT_EXT_SEL"); + SetDlgItemTextW(IDC_TXT_OPT_MEDIA_LIB_ARTIST_SPLIT_EXT_SEL_STATIC, temp.c_str()); + // IDC_ARTIST_SPLIT_EXT_EDIT + temp = theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_MEDIA_LIB_UPDATE_OPT"); + SetDlgItemTextW(IDC_TXT_OPT_MEDIA_LIB_MEDIA_LIB_UPDATE_OPT_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_REMOVE_FILE_NOT_EXIST"); + SetDlgItemTextW(IDC_REMOVE_FILE_NOT_EXIST_WHEN_UPDATE_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_IGNORE_TOO_SHORT"); + SetDlgItemTextW(IDC_IGNORE_TOO_SHORT_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_AUTO_UPDATE_WHEN_STARTUP"); + SetDlgItemTextW(IDC_UPDATE_MEDIA_LIB_CHK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_FORCE_RELOAD"); + SetDlgItemTextW(IDC_REFRESH_MEDIA_LIB_BUTTON, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_MEDIA_LIB_DIR"); + SetDlgItemTextW(IDC_TXT_OPT_MEDIA_LIB_MEDIA_LIB_DIR_STATIC, temp.c_str()); + // IDC_DIR_LIST + temp = theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_MEDIA_LIB_DIR_ADD"); + SetDlgItemTextW(IDC_ADD_BUTTON, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_MEDIA_LIB_DIR_DEL"); + SetDlgItemTextW(IDC_DELETE_BUTTON, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_MEDIA_LIB_DISP_TAB"); + SetDlgItemTextW(IDC_TXT_OPT_MEDIA_LIB_MEDIA_LIB_DISP_TAB_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_ARTIST"); + SetDlgItemTextW(IDC_ARTIST_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_ALBUM"); + SetDlgItemTextW(IDC_ALBUM_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_GENRE"); + SetDlgItemTextW(IDC_GENRE_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_YEAR"); + SetDlgItemTextW(IDC_YEAR_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_FILE_TYPE"); + SetDlgItemTextW(IDC_FILE_TYPE_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_BITRATE"); + SetDlgItemTextW(IDC_BITRATE_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_RATING"); + SetDlgItemTextW(IDC_RATING_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_ALL_TRACKS"); + SetDlgItemTextW(IDC_ALL_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_RECENT_PLAYED"); + SetDlgItemTextW(IDC_RECENT_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_FOLDER_EXPLORE"); + SetDlgItemTextW(IDC_FOLDER_EXPLORE_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_PLAYLIST_OPT"); + SetDlgItemTextW(IDC_TXT_OPT_MEDIA_LIB_PLAYLIST_OPT_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_DISABLE_DRAGE_SORT"); + SetDlgItemTextW(IDC_DISABLE_DRAGE_SORT_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_INS_BEGIN"); + SetDlgItemTextW(IDC_INSERT_BEGIN_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_FLOAT_PLAYLIST_BY_DEFAULT"); + SetDlgItemTextW(IDC_FLOAT_PLAYLIST_BY_DEFAULT_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_FLOAT_PLAYLIST_FOLLOW_MAIN_WND"); + SetDlgItemTextW(IDC_FLOAT_PLAYLIST_FOLLOW_MAIN_WND_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_SHOW_TOOLTIP"); + SetDlgItemTextW(IDC_SHOW_PLAYLIST_TOOLTIP_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_PLAYLIST_DISPLAY_MODE"); + SetDlgItemTextW(IDC_TXT_OPT_MEDIA_LIB_PLAYLIST_DISPLAY_MODE_STATIC, temp.c_str()); + // IDC_PLAYLIST_DISPLAY_MODE_OMBO + temp = theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_PLAYLIST_ITEM_HEIGHT"); + SetDlgItemTextW(IDC_TXT_OPT_MEDIA_LIB_PLAYLIST_ITEM_HEIGHT_STATIC, temp.c_str()); + // IDC_PLAYLIST_ITEM_HEIGHT_EDIT + temp = theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_RECENT_PLAY"); + SetDlgItemTextW(IDC_TXT_OPT_MEDIA_LIB_RECENT_PLAY_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_RECENT_PLAY_RANGE_SEL"); + SetDlgItemTextW(IDC_TXT_OPT_MEDIA_LIB_RECENT_PLAY_RANGE_SEL_STATIC, temp.c_str()); + // IDC_RECENT_PLAYED_RANGE_OMBO + temp = theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_RECENT_PLAY_CLEAR"); + SetDlgItemTextW(IDC_CLEAR_RECENT_PLAYED_LIST_BTN, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_CLEAN_MEDIA_LIB"); + SetDlgItemTextW(IDC_TXT_OPT_MEDIA_LIB_CLEAN_MEDIA_LIB_STATIC, temp.c_str()); + // IDC_SIZE_STATIC + temp = theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_DATA_FILE_CLEAN"); + SetDlgItemTextW(IDC_CLEAN_DATA_FILE_BUTTON, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_TAG_EDIT"); + SetDlgItemTextW(IDC_TXT_OPT_MEDIA_LIB_TAG_EDIT_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_TAG_ID3V2_WRITE_TYPE"); + SetDlgItemTextW(IDC_TXT_OPT_MEDIA_LIB_TAG_ID3V2_WRITE_TYPE_STATIC, temp.c_str()); + // IDC_ID3V2_TYPE_COMBO + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LAST_FM"); + SetDlgItemTextW(IDC_TXT_OPT_LAST_FM_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LAST_FM_ENABLE"); + SetDlgItemTextW(IDC_ENABLE_LASTFM, temp.c_str()); + // IDC_LASTFM_STATUS + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LAST_FM_USE_HTTPS"); + SetDlgItemTextW(IDC_LASTFM_ENABLE_HTTPS, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LAST_FM_LOGIN"); + SetDlgItemTextW(IDC_LASTFM_LOGIN, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LAST_FM_UPLOAD_NOW_PLAYING"); + SetDlgItemTextW(IDC_LASTFM_ENABLE_NOWPLAYING, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LAST_FM_CACHE_CONDITION"); + SetDlgItemTextW(IDC_TXT_OPT_LAST_FM_CACHE_CONDITION_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LAST_FM_CACHE_CONDITION_PERCENT"); + SetDlgItemTextW(IDC_TXT_OPT_LAST_FM_CACHE_CONDITION_PERCENT_STATIC, temp.c_str()); + // IDC_LASTFM_LEAST_PERDUR + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LAST_FM_CACHE_CONDITION_DURATION"); + SetDlgItemTextW(IDC_TXT_OPT_LAST_FM_CACHE_CONDITION_DURATION_STATIC, temp.c_str()); + // IDC_LASTFM_LEAST_DUR + // IDC_LASTFM_CACHE_STATUS + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LAST_FM_CACHE_UPLOAD"); + SetDlgItemTextW(IDC_LASTFM_UPLOAD_CACHE, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LAST_FM_UPLOAD_WHEN_REACH_THRESHOLD"); + SetDlgItemTextW(IDC_LASTFM_AUTO_SCROBBLE, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_LAST_FM_AUTO_UPLOAD_THRESHOLD"); + SetDlgItemTextW(IDC_TXT_OPT_LAST_FM_AUTO_UPLOAD_THRESHOLD_STATIC, temp.c_str()); + // IDC_LASTFM_AUTO_SCROBBLE_MIN + + RepositionTextBasedControls({ + { CtrlTextInfo::C0, IDC_UPDATE_MEDIA_LIB_CHK }, + { CtrlTextInfo::R1, IDC_REFRESH_MEDIA_LIB_BUTTON, CtrlTextInfo::W32 } + }); + RepositionTextBasedControls({ + { CtrlTextInfo::C0, IDC_DIR_LIST }, + { CtrlTextInfo::R1, IDC_ADD_BUTTON, CtrlTextInfo::W32 }, + { CtrlTextInfo::R1, IDC_DELETE_BUTTON, CtrlTextInfo::W32 } + }); + RepositionTextBasedControls({ + { CtrlTextInfo::R1, IDC_CLEAR_RECENT_PLAYED_LIST_BTN, CtrlTextInfo::W32 } + }); + RepositionTextBasedControls({ + { CtrlTextInfo::C0, IDC_SIZE_STATIC }, + { CtrlTextInfo::R1, IDC_CLEAN_DATA_FILE_BUTTON, CtrlTextInfo::W32 } + }); + RepositionTextBasedControls({ + { CtrlTextInfo::C0, IDC_LASTFM_ENABLE_HTTPS }, + { CtrlTextInfo::C0, IDC_LASTFM_ENABLE_NOWPLAYING }, + { CtrlTextInfo::R1, IDC_LASTFM_LOGIN, CtrlTextInfo::W32 } + }); + RepositionTextBasedControls({ + { CtrlTextInfo::R1, IDC_LASTFM_UPLOAD_CACHE, CtrlTextInfo::W32 } + }); + return true; } void CMediaLibSettingDlg::DoDataExchange(CDataExchange* pDX) { CTabDlg::DoDataExchange(pDX); - DDX_Control(pDX, IDC_CLASSIFY_OTHER_CHECK, m_classify_other_chk); - //DDX_Control(pDX, IDC_SHOW_TREE_TOOL_TIPS_CHECK, m_show_tree_tool_tips_chk); DDX_Control(pDX, IDC_DIR_LIST, m_dir_list_ctrl); - DDX_Control(pDX, IDC_UPDATE_MEDIA_LIB_CHK, m_update_media_lib_chk); - DDX_Control(pDX, IDC_DISABLE_DRAGE_SORT_CHECK, m_disable_drag_sort_chk); DDX_Control(pDX, IDC_PLAYLIST_DISPLAY_MODE_OMBO, m_playlist_display_mode_combo); DDX_Control(pDX, IDC_RECENT_PLAYED_RANGE_OMBO, m_recent_played_range_combo); - DDX_Control(pDX, IDC_IGNORE_TOO_SHORT_CHECK, m_ignore_too_short_chk); DDX_Control(pDX, IDC_FILE_TOO_SHORT_SEC_EDIT, m_file_too_short_sec_edit); - DDX_Control(pDX, IDC_INSERT_BEGIN_CHECK, m_insert_begin_chk); DDX_Control(pDX, IDC_ID3V2_TYPE_COMBO, m_id3v2_type_combo); DDX_Control(pDX, IDC_ENABLE_LASTFM, m_enable_lastfm); DDX_Control(pDX, IDC_LASTFM_STATUS, m_lastfm_status); @@ -68,6 +214,14 @@ void CMediaLibSettingDlg::DoDataExchange(CDataExchange* pDX) void CMediaLibSettingDlg::GetDataFromUi() { + m_data.disable_delete_from_disk = (IsDlgButtonChecked(IDC_DISABLE_DELETE_FROM_DISK_CHECK) != 0); + m_data.hide_only_one_classification = (IsDlgButtonChecked(IDC_CLASSIFY_OTHER_CHECK) != 0); + m_data.file_too_short_sec = m_file_too_short_sec_edit.GetValue(); + + m_data.remove_file_not_exist_when_update = (IsDlgButtonChecked(IDC_REMOVE_FILE_NOT_EXIST_WHEN_UPDATE_CHECK) != 0); + m_data.ignore_too_short_when_update = (IsDlgButtonChecked(IDC_IGNORE_TOO_SHORT_CHECK) != 0); + m_data.update_media_lib_when_start_up = (IsDlgButtonChecked(IDC_UPDATE_MEDIA_LIB_CHK) != 0); + m_data.display_item = 0; if (IsDlgButtonChecked(IDC_ARTIST_CHECK)) m_data.display_item |= MLDI_ARTIST; @@ -89,12 +243,22 @@ void CMediaLibSettingDlg::GetDataFromUi() m_data.display_item |= MLDI_RECENT; if (IsDlgButtonChecked(IDC_FOLDER_EXPLORE_CHECK)) m_data.display_item |= MLDI_FOLDER_EXPLORE; + + m_data.disable_drag_sort = (IsDlgButtonChecked(IDC_DISABLE_DRAGE_SORT_CHECK) != 0); + m_data.insert_begin_of_playlist = (IsDlgButtonChecked(IDC_INSERT_BEGIN_CHECK) != 0); + m_data.playlist_btn_for_float_playlist = (IsDlgButtonChecked(IDC_FLOAT_PLAYLIST_BY_DEFAULT_CHECK) != 0); + m_data.float_playlist_follow_main_wnd = (IsDlgButtonChecked(IDC_FLOAT_PLAYLIST_FOLLOW_MAIN_WND_CHECK) != 0); + m_data.show_playlist_tooltip = (IsDlgButtonChecked(IDC_SHOW_PLAYLIST_TOOLTIP_CHECK) != 0); + m_data.display_format = static_cast(m_playlist_display_mode_combo.GetCurSel()); + m_data.playlist_item_height = m_playlist_item_height_edit.GetValue(); + m_data.recent_played_range = static_cast(m_recent_played_range_combo.GetCurSel()); + + int cur_index = m_id3v2_type_combo.GetCurSel(); + m_data.write_id3_v2_3 = (cur_index == 0); + m_data.lastfm_least_perdur = m_lastfm_least_perdur.GetValue(); m_data.lastfm_least_dur = m_lastfm_least_dur.GetValue(); m_data.lastfm_auto_scrobble_min = m_lastfm_auto_scrobble_min.GetValue(); - m_data.playlist_item_height = m_playlist_item_height_edit.GetValue(); - m_data.file_too_short_sec = m_file_too_short_sec_edit.GetValue(); - m_data.remove_file_not_exist_when_update = (IsDlgButtonChecked(IDC_REMOVE_FILE_NOT_EXIST_WHEN_UPDATE_CHECK)); } // void CMediaLibSettingDlg::ApplyDataToUi() @@ -103,22 +267,11 @@ void CMediaLibSettingDlg::GetDataFromUi() BEGIN_MESSAGE_MAP(CMediaLibSettingDlg, CTabDlg) ON_WM_TIMER() - ON_BN_CLICKED(IDC_CLASSIFY_OTHER_CHECK, &CMediaLibSettingDlg::OnBnClickedClassifyOtherCheck) - //ON_BN_CLICKED(IDC_SHOW_TREE_TOOL_TIPS_CHECK, &CMediaLibSettingDlg::OnBnClickedShowTreeToolTipsCheck) ON_BN_CLICKED(IDC_ADD_BUTTON, &CMediaLibSettingDlg::OnBnClickedAddButton) ON_BN_CLICKED(IDC_DELETE_BUTTON, &CMediaLibSettingDlg::OnBnClickedDeleteButton) - ON_BN_CLICKED(IDC_UPDATE_MEDIA_LIB_CHK, &CMediaLibSettingDlg::OnBnClickedUpdateMediaLibChk) ON_BN_CLICKED(IDC_CLEAN_DATA_FILE_BUTTON, &CMediaLibSettingDlg::OnBnClickedCleanDataFileButton) ON_BN_CLICKED(IDC_CLEAR_RECENT_PLAYED_LIST_BTN, &CMediaLibSettingDlg::OnBnClickedClearRecentPlayedListBtn) - ON_BN_CLICKED(IDC_DISABLE_DRAGE_SORT_CHECK, &CMediaLibSettingDlg::OnBnClickedDisableDrageSortCheck) - ON_CBN_SELCHANGE(IDC_PLAYLIST_DISPLAY_MODE_OMBO, &CMediaLibSettingDlg::OnCbnSelchangePlaylistDisplayModeOmbo) - ON_CBN_SELCHANGE(IDC_RECENT_PLAYED_RANGE_OMBO, &CMediaLibSettingDlg::OnCbnSelchangeRecentPlayedRangeOmbo) - ON_BN_CLICKED(IDC_INSERT_BEGIN_CHECK, &CMediaLibSettingDlg::OnBnClickedInsertBeginCheck) - ON_CBN_SELCHANGE(IDC_ID3V2_TYPE_COMBO, &CMediaLibSettingDlg::OnCbnSelchangeId3v2TypeCombo) ON_BN_CLICKED(IDC_REFRESH_MEDIA_LIB_BUTTON, &CMediaLibSettingDlg::OnBnClickedRefreshMediaLibButton) - ON_BN_CLICKED(IDC_DISABLE_DELETE_FROM_DISK_CHECK, &CMediaLibSettingDlg::OnBnClickedDisableDeleteFromDiskCheck) - ON_BN_CLICKED(IDC_SHOW_PLAYLIST_TOOLTIP_CHECK, &CMediaLibSettingDlg::OnBnClickedShowPlaylistTooltipCheck) - ON_BN_CLICKED(IDC_FLOAT_PLAYLIST_FOLLOW_MAIN_WND_CHECK, &CMediaLibSettingDlg::OnBnClickedFloatPlaylistFollowMainWndCheck) ON_BN_CLICKED(IDC_ENABLE_LASTFM, &CMediaLibSettingDlg::OnBnClickedEnableLastfm) ON_BN_CLICKED(IDC_LASTFM_LOGIN, &CMediaLibSettingDlg::OnBnClickedLastfmLogin) ON_BN_CLICKED(IDC_LASTFM_AUTO_SCROBBLE, &CMediaLibSettingDlg::OnBnClickedLastfmAutoScrobble) @@ -126,7 +279,6 @@ BEGIN_MESSAGE_MAP(CMediaLibSettingDlg, CTabDlg) ON_BN_CLICKED(IDC_LASTFM_ENABLE_HTTPS, &CMediaLibSettingDlg::OnBnClickedLastfmEnableHttps) ON_BN_CLICKED(IDC_LASTFM_ENABLE_NOWPLAYING, &CMediaLibSettingDlg::OnBnClickedLastfmEnableNowplaying) ON_MESSAGE(WM_EDIT_BROWSE_CHANGED, &CMediaLibSettingDlg::OnEditBrowseChanged) - ON_BN_CLICKED(IDC_IGNORE_TOO_SHORT_CHECK, &CMediaLibSettingDlg::OnBnClickedIgnoreTooShortCheck) END_MESSAGE_MAP() @@ -141,47 +293,51 @@ BOOL CMediaLibSettingDlg::OnInitDialog() m_data_size = CCommon::GetFileSize(theApp.m_song_data_path); ShowDataSizeInfo(); - m_classify_other_chk.SetCheck(m_data.hide_only_one_classification); - //m_show_tree_tool_tips_chk.SetCheck(m_data.show_tree_tool_tips); - m_update_media_lib_chk.SetCheck(m_data.update_media_lib_when_start_up); - m_disable_drag_sort_chk.SetCheck(m_data.disable_drag_sort); + CheckDlgButton(IDC_CLASSIFY_OTHER_CHECK, m_data.hide_only_one_classification); + CheckDlgButton(IDC_UPDATE_MEDIA_LIB_CHK, m_data.update_media_lib_when_start_up); + CheckDlgButton(IDC_DISABLE_DRAGE_SORT_CHECK, m_data.disable_drag_sort); CheckDlgButton(IDC_DISABLE_DELETE_FROM_DISK_CHECK, m_data.disable_delete_from_disk); CheckDlgButton(IDC_REMOVE_FILE_NOT_EXIST_WHEN_UPDATE_CHECK, m_data.remove_file_not_exist_when_update); m_artist_split_ext_edit.SetWindowTextW(CCommon::MergeStringList(m_data.artist_split_ext).c_str()); m_artist_split_ext_edit.SetEditBrowseMode(CBrowseEdit::EditBrowseMode::LIST2); - m_artist_split_ext_edit.SetPopupDlgTitle(CCommon::LoadText(IDS_SET_MULTI_ARTIST_SPLIT_EXT)); + m_artist_split_ext_edit.SetPopupDlgTitle(theApp.m_str_table.LoadText(L"TITLE_BROWSE_EDIT_SET_MULTI_ARTIST_SPLIT_EXT")); m_artist_split_ext_edit.SetReadOnly(true); // 没有异常处理故禁用手动编辑(应当使用弹出窗口) for (const auto& str : m_data.media_folders) m_dir_list_ctrl.AddString(str.c_str()); m_dir_list_ctrl.SetMouseWheelEnable(false); + wstring tip_str; m_toolTip.Create(this); m_toolTip.SetMaxTipWidth(theApp.DPI(300)); - m_toolTip.AddTool(GetDlgItem(IDC_CLEAN_DATA_FILE_BUTTON), CCommon::LoadText(IDS_CLEAR_DATA_FILE_TIP_INFO)); - m_toolTip.AddTool(&m_update_media_lib_chk, CCommon::LoadText(IDS_UPDATE_MEDIA_LIB_TIP)); - m_toolTip.AddTool(&m_artist_split_ext_edit, CCommon::LoadText(IDS_ARTIST_SPLIT_EXT_TIP_INFO)); - - m_playlist_display_mode_combo.AddString(CCommon::LoadText(IDS_FILE_NAME)); - m_playlist_display_mode_combo.AddString(CCommon::LoadText(IDS_TITLE)); - m_playlist_display_mode_combo.AddString(CCommon::LoadText(IDS_ARTIST) + _T(" - ") + CCommon::LoadText(IDS_TITLE)); - m_playlist_display_mode_combo.AddString(CCommon::LoadText(IDS_TITLE) + _T(" - ") + CCommon::LoadText(IDS_ARTIST)); + tip_str = theApp.m_str_table.LoadText(L"TIP_OPT_MEDIA_LIB_DATA_FILE_CLEAN"); + m_toolTip.AddTool(GetDlgItem(IDC_CLEAN_DATA_FILE_BUTTON), tip_str.c_str()); + tip_str = theApp.m_str_table.LoadText(L"TIP_OPT_MEDIA_LIB_AUTO_UPDATE_WHEN_STARTUP"); + m_toolTip.AddTool(GetDlgItem(IDC_UPDATE_MEDIA_LIB_CHK), tip_str.c_str()); + tip_str = theApp.m_str_table.LoadText(L"TIP_OPT_MEDIA_LIB_ARTIST_SPLIT_EXT"); + m_toolTip.AddTool(&m_artist_split_ext_edit, tip_str.c_str()); + + m_playlist_display_mode_combo.AddString(theApp.m_str_table.LoadText(L"TXT_FILE_NAME").c_str()); + m_playlist_display_mode_combo.AddString(theApp.m_str_table.LoadText(L"TXT_TITLE").c_str()); + m_playlist_display_mode_combo.AddString((theApp.m_str_table.LoadText(L"TXT_ARTIST") + L" - " + theApp.m_str_table.LoadText(L"TXT_TITLE")).c_str()); + m_playlist_display_mode_combo.AddString((theApp.m_str_table.LoadText(L"TXT_TITLE") + L" - " + theApp.m_str_table.LoadText(L"TXT_ARTIST")).c_str()); m_playlist_display_mode_combo.SetCurSel(static_cast(m_data.display_format)); - m_recent_played_range_combo.AddString(CCommon::LoadText(IDS_ALL)); - m_recent_played_range_combo.AddString(CCommon::LoadText(IDS_TODAY)); - m_recent_played_range_combo.AddString(CCommon::LoadText(IDS_LAST_THREE_DAYS)); - m_recent_played_range_combo.AddString(CCommon::LoadText(IDS_LAST_WEEK)); - m_recent_played_range_combo.AddString(CCommon::LoadText(IDS_LAST_MONTH)); - m_recent_played_range_combo.AddString(CCommon::LoadText(IDS_LAST_HALF_YEAR)); - m_recent_played_range_combo.AddString(CCommon::LoadText(IDS_LAST_YEAR)); + m_recent_played_range_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_RECENT_PLAY_RANGE_ALL").c_str()); + m_recent_played_range_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_RECENT_PLAY_RANGE_TODAY").c_str()); + m_recent_played_range_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_RECENT_PLAY_RANGE_LAST_THREE_DAYS").c_str()); + m_recent_played_range_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_RECENT_PLAY_RANGE_LAST_WEEK").c_str()); + m_recent_played_range_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_RECENT_PLAY_RANGE_LAST_MONTH").c_str()); + m_recent_played_range_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_RECENT_PLAY_RANGE_LAST_HALF_YEAR").c_str()); + m_recent_played_range_combo.AddString(theApp.m_str_table.LoadText(L"TXT_OPT_MEDIA_LIB_RECENT_PLAY_RANGE_LAST_YEAR").c_str()); m_recent_played_range_combo.SetCurSel(static_cast(m_data.recent_played_range)); - m_insert_begin_chk.SetCheck(m_data.insert_begin_of_playlist); - m_ignore_too_short_chk.SetCheck(m_data.ignore_too_short_when_update); - CheckDlgButton(IDC_SHOW_PLAYLIST_TOOLTIP_CHECK, m_data.show_playlist_tooltip); + CheckDlgButton(IDC_INSERT_BEGIN_CHECK, m_data.insert_begin_of_playlist); + CheckDlgButton(IDC_IGNORE_TOO_SHORT_CHECK, m_data.ignore_too_short_when_update); + CheckDlgButton(IDC_FLOAT_PLAYLIST_BY_DEFAULT_CHECK, m_data.playlist_btn_for_float_playlist); CheckDlgButton(IDC_FLOAT_PLAYLIST_FOLLOW_MAIN_WND_CHECK, m_data.float_playlist_follow_main_wnd); + CheckDlgButton(IDC_SHOW_PLAYLIST_TOOLTIP_CHECK, m_data.show_playlist_tooltip); CheckDlgButton(IDC_ARTIST_CHECK, m_data.display_item & MLDI_ARTIST); CheckDlgButton(IDC_ALBUM_CHECK, m_data.display_item & MLDI_ALBUM); @@ -199,19 +355,18 @@ BOOL CMediaLibSettingDlg::OnInitDialog() int cur_index = m_data.write_id3_v2_3 ? 0 : 1; m_id3v2_type_combo.SetCurSel(cur_index); - CButton* setting_btn = (CButton*)(GetDlgItem(IDC_REFRESH_MEDIA_LIB_BUTTON)); - if (setting_btn != nullptr) - setting_btn->SetIcon(theApp.m_icon_set.loop_playlist.GetIcon(true)); - m_lastfm_least_perdur.SetRange(10, 90); + SetButtonIcon(IDC_REFRESH_MEDIA_LIB_BUTTON, IconMgr::IconType::IT_Loop_Playlist); + + m_lastfm_least_perdur.SetRange(10, 90, 10); m_lastfm_least_perdur.SetValue(m_data.lastfm_least_perdur); - m_lastfm_least_dur.SetRange(10, 240); + m_lastfm_least_dur.SetRange(10, 240, 10); m_lastfm_least_dur.SetValue(m_data.lastfm_least_dur); m_lastfm_auto_scrobble_min.SetRange(1, 50); m_lastfm_auto_scrobble_min.SetValue(m_data.lastfm_auto_scrobble_min); m_playlist_item_height_edit.SetRange(MIN_PLAYLIST_ITEM_HEIGHT, MAX_PLAYLIST_ITEM_HEIGHT); m_playlist_item_height_edit.SetValue(m_data.playlist_item_height); - m_file_too_short_sec_edit.SetRange(1, 60); + m_file_too_short_sec_edit.SetRange(1, 60, 10); m_file_too_short_sec_edit.SetValue(m_data.file_too_short_sec); //设置控件不响应鼠标滚轮消息 @@ -232,20 +387,6 @@ BOOL CMediaLibSettingDlg::OnInitDialog() } -void CMediaLibSettingDlg::OnBnClickedClassifyOtherCheck() -{ - // TODO: 在此添加控件通知处理程序代码 - m_data.hide_only_one_classification = (m_classify_other_chk.GetCheck() != 0); -} - - -//void CMediaLibSettingDlg::OnBnClickedShowTreeToolTipsCheck() -//{ -// // TODO: 在此添加控件通知处理程序代码 -// m_data.show_tree_tool_tips = (m_show_tree_tool_tips_chk.GetCheck() != 0); -//} - - void CMediaLibSettingDlg::OnBnClickedAddButton() { // TODO: 在此添加控件通知处理程序代码 @@ -274,13 +415,6 @@ void CMediaLibSettingDlg::OnBnClickedDeleteButton() } -void CMediaLibSettingDlg::OnBnClickedUpdateMediaLibChk() -{ - // TODO: 在此添加控件通知处理程序代码 - m_data.update_media_lib_when_start_up = (m_update_media_lib_chk.GetCheck() != 0); -} - - void CMediaLibSettingDlg::OnBnClickedCleanDataFileButton() { // TODO: 在此添加控件通知处理程序代码 @@ -346,9 +480,8 @@ void CMediaLibSettingDlg::OnBnClickedCleanDataFileButton() size_t data_size = CCommon::GetFileSize(theApp.m_song_data_path); //清理后数据文件的大小 int size_reduced = m_data_size - data_size; //清理后数据文件减少的字节数 if (size_reduced < 0) size_reduced = 0; - CString info; - info = CCommon::LoadTextFormat(IDS_CLEAR_COMPLETE_INFO, { clear_cnt, size_reduced }); - MessageBox(info, NULL, MB_ICONINFORMATION); + wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_OPT_MEDIA_LIB_DATA_FILE_CLEAR_COMPLETE", { clear_cnt, size_reduced }); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION); m_data_size = data_size; ShowDataSizeInfo(); } @@ -370,7 +503,8 @@ void CMediaLibSettingDlg::OnBnClickedClearRecentPlayedListBtn() // TODO: 在此添加控件通知处理程序代码 //清除歌曲的上次播放时间 - if (MessageBox(CCommon::LoadText(IDS_CLEAR_RECENT_PLAYLIST_INFO), NULL, MB_ICONINFORMATION | MB_YESNO) == IDYES) + const wstring& info = theApp.m_str_table.LoadText(L"MSG_OPT_MEDIA_LIB_RECENT_PLAY_CLEAR_INQUARY"); + if (MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_YESNO) == IDYES) { CSongDataManager::GetInstance().ClearLastPlayedTime(); ::SendMessage(AfxGetMainWnd()->GetSafeHwnd(), WM_RECENT_PLAYED_LIST_CLEARED, 0, 0); @@ -378,34 +512,6 @@ void CMediaLibSettingDlg::OnBnClickedClearRecentPlayedListBtn() } -void CMediaLibSettingDlg::OnBnClickedDisableDrageSortCheck() -{ - // TODO: Add your control notification handler code here - m_data.disable_drag_sort = (m_disable_drag_sort_chk.GetCheck() != 0); -} - - -void CMediaLibSettingDlg::OnCbnSelchangePlaylistDisplayModeOmbo() -{ - // TODO: Add your control notification handler code here - m_data.display_format = static_cast(m_playlist_display_mode_combo.GetCurSel()); -} - - -void CMediaLibSettingDlg::OnCbnSelchangeRecentPlayedRangeOmbo() -{ - // TODO: Add your control notification handler code here - m_data.recent_played_range = static_cast(m_recent_played_range_combo.GetCurSel()); -} - - -void CMediaLibSettingDlg::OnBnClickedInsertBeginCheck() -{ - // TODO: 在此添加控件通知处理程序代码 - m_data.insert_begin_of_playlist = (m_insert_begin_chk.GetCheck() != 0); -} - - void CMediaLibSettingDlg::OnOK() { // TODO: 在此添加专用代码和/或调用基类 @@ -414,48 +520,21 @@ void CMediaLibSettingDlg::OnOK() } -void CMediaLibSettingDlg::OnCbnSelchangeId3v2TypeCombo() -{ - // TODO: 在此添加控件通知处理程序代码 - int cur_index = m_id3v2_type_combo.GetCurSel(); - m_data.write_id3_v2_3 = (cur_index == 0); -} - - void CMediaLibSettingDlg::OnBnClickedRefreshMediaLibButton() { // TODO: 在此添加控件通知处理程序代码 if (theApp.IsMeidaLibUpdating()) { - MessageBox(CCommon::LoadText(IDS_MEDIA_LIB_UPDATING_INFO), nullptr, MB_ICONINFORMATION | MB_OK); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_OPT_MEDIA_LIB_UPDATING_INFO"); + MessageBox(info.c_str(), nullptr, MB_ICONINFORMATION | MB_OK); } else { - theApp.StartUpdateMediaLib(true); + theApp.StartUpdateMediaLib(true); // 刷新媒体库按钮强制重新获取所有元数据 } } -void CMediaLibSettingDlg::OnBnClickedDisableDeleteFromDiskCheck() -{ - // TODO: 在此添加控件通知处理程序代码 - m_data.disable_delete_from_disk = (IsDlgButtonChecked(IDC_DISABLE_DELETE_FROM_DISK_CHECK) != 0); -} - - -void CMediaLibSettingDlg::OnBnClickedShowPlaylistTooltipCheck() -{ - // TODO: 在此添加控件通知处理程序代码 - m_data.show_playlist_tooltip = (IsDlgButtonChecked(IDC_SHOW_PLAYLIST_TOOLTIP_CHECK) != 0); -} - - -void CMediaLibSettingDlg::OnBnClickedFloatPlaylistFollowMainWndCheck() -{ - m_data.float_playlist_follow_main_wnd = (IsDlgButtonChecked(IDC_FLOAT_PLAYLIST_FOLLOW_MAIN_WND_CHECK) != 0); -} - - void CMediaLibSettingDlg::OnBnClickedEnableLastfm() { m_data.enable_lastfm = (m_enable_lastfm.GetCheck() != 0); UpdateLastFMStatus(); @@ -463,30 +542,36 @@ void CMediaLibSettingDlg::OnBnClickedEnableLastfm() { void CMediaLibSettingDlg::OnBnClickedLastfmLogin() { - auto token = theApp.m_lastfm.GetToken(); - std::wstring url; - int button; - if (token.empty()) goto failed; - url = theApp.m_lastfm.GetRequestAuthorizationUrl(token); - if (url.empty()) goto failed; - ShellExecuteW(nullptr, L"open", url.c_str(), nullptr, nullptr, SW_SHOW); - button = GetOwner()->MessageBoxW(CCommon::LoadText(IDS_LASTFM_LOGIN), NULL, MB_ICONINFORMATION | MB_OKCANCEL); - if (button == IDOK) { - if (!theApp.m_lastfm.GetSession(token)) goto failed; - UpdateLastFMStatus(); - theApp.SaveLastFMData(); + wstring token = theApp.m_lastfm.GetToken(); + wstring url = theApp.m_lastfm.GetRequestAuthorizationUrl(token); + if (!token.empty() && !url.empty()) + { + ShellExecuteW(nullptr, L"open", url.c_str(), nullptr, nullptr, SW_SHOW); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_OPT_LAST_FM_LOGIN"); + if (MessageBoxW(info.c_str(), NULL, MB_ICONINFORMATION | MB_OKCANCEL) == IDOK) + { + if (theApp.m_lastfm.GetSession(token)) + { + UpdateLastFMStatus(); + theApp.SaveLastFMData(); + return; + } + } } + const wstring& info = theApp.m_str_table.LoadText(L"MSG_OPT_LAST_FM_LOGIN"); + MessageBoxW(info.c_str(), NULL, MB_ICONERROR | MB_OK); return; -failed: - GetOwner()->MessageBoxW(CCommon::LoadText(IDS_LOGIN_FAILED), NULL, MB_ICONERROR | MB_OK); } void CMediaLibSettingDlg::UpdateLastFMStatus() { m_enable_lastfm.SetCheck(m_data.enable_lastfm); - auto has_key = theApp.m_lastfm.HasSessionKey(); - const auto& basic = has_key ? CCommon::LoadText(IDS_LOGGED) : CCommon::LoadText(IDS_LOGIN_REQUIRED); - const auto& s = has_key ? std::wstring(basic.GetString()) + L" (" + theApp.m_lastfm.UserName() + L")" : std::wstring(basic.GetString()); - m_lastfm_status.SetWindowTextW(CString(s.c_str())); + bool has_key = theApp.m_lastfm.HasSessionKey(); + wstring status_str; + if (has_key) + status_str = theApp.m_str_table.LoadTextFormat(L"TXT_OPT_LAST_FM_STATUS_LOGIN_LOGGED", { theApp.m_lastfm.UserName() }); + else + status_str = theApp.m_str_table.LoadText(L"TXT_OPT_LAST_FM_STATUS_LOGIN_REQUIRED"); + m_lastfm_status.SetWindowTextW(status_str.c_str()); bool login_enabled = m_data.enable_lastfm && !has_key; m_lastfm_login.EnableWindow(login_enabled); m_lastfm_least_perdur.EnableWindow(m_data.enable_lastfm); @@ -514,12 +599,9 @@ void CMediaLibSettingDlg::OnTimer(UINT_PTR nIDEvent) { } void CMediaLibSettingDlg::UpdateLastFMCacheStatus() { - CString status = CCommon::LoadText(IDS_LASTFM_CACHE_STATUS); - wchar_t tmp[32]; - auto count = theApp.m_lastfm.CachedCount(); - wsprintf(tmp, L"%i", (int)count); - status.Replace(L"%i", tmp); - m_lastfm_cache_status.SetWindowTextW(status); + size_t count = theApp.m_lastfm.CachedCount(); + wstring status_str = theApp.m_str_table.LoadTextFormat(L"TXT_OPT_LAST_FM_CACHE_STATUS", { count }); + m_lastfm_cache_status.SetWindowTextW(status_str.c_str()); m_lastfm_upload_cache.EnableWindow(m_data.enable_lastfm && count > 0); } @@ -551,9 +633,3 @@ afx_msg LRESULT CMediaLibSettingDlg::OnEditBrowseChanged(WPARAM wParam, LPARAM l return 0; } - -void CMediaLibSettingDlg::OnBnClickedIgnoreTooShortCheck() -{ - // TODO: 在此添加控件通知处理程序代码 - m_data.ignore_too_short_when_update = (m_ignore_too_short_chk.GetCheck() != 0); -} diff --git a/MusicPlayer2/MediaLibSettingDlg.h b/MusicPlayer2/MediaLibSettingDlg.h index 68dd1d287..9d4d653e5 100644 --- a/MusicPlayer2/MediaLibSettingDlg.h +++ b/MusicPlayer2/MediaLibSettingDlg.h @@ -1,7 +1,6 @@ #pragma once #include "TabDlg.h" #include "CListBoxEnhanced.h" -#include "afxwin.h" #include "MyComboBox.h" #include "SpinEdit.h" #include "BrowseEdit.h" @@ -10,36 +9,30 @@ class CMediaLibSettingDlg : public CTabDlg { - DECLARE_DYNAMIC(CMediaLibSettingDlg) + DECLARE_DYNAMIC(CMediaLibSettingDlg) public: - CMediaLibSettingDlg(CWnd* pParent = nullptr); // 标准构造函数 - virtual ~CMediaLibSettingDlg(); + CMediaLibSettingDlg(CWnd* pParent = nullptr); // 标准构造函数 + virtual ~CMediaLibSettingDlg(); // 对话框数据 #ifdef AFX_DESIGN_TIME - enum { IDD = IDD_MEDIA_LIB_SETTING_DIALOG }; + enum { IDD = IDD_MEDIA_LIB_SETTING_DIALOG }; #endif MediaLibSettingData m_data; private: - CButton m_classify_other_chk; - //CButton m_show_tree_tool_tips_chk; CListBoxEnhanced m_dir_list_ctrl; - CButton m_update_media_lib_chk; - CButton m_disable_drag_sort_chk; - CMyComboBox m_playlist_display_mode_combo; - CMyComboBox m_recent_played_range_combo; - CButton m_ignore_too_short_chk; + CMyComboBox m_playlist_display_mode_combo; + CMyComboBox m_recent_played_range_combo; CSpinEdit m_file_too_short_sec_edit; - CButton m_insert_begin_chk; CMyComboBox m_id3v2_type_combo; CButton m_enable_lastfm; CSpinEdit m_playlist_item_height_edit; CToolTipCtrl m_toolTip; - size_t m_data_size; //数据文件的大小 + size_t m_data_size{}; // 数据文件的大小 CStatic m_lastfm_status; CButton m_lastfm_login; CSpinEdit m_lastfm_least_perdur; @@ -55,7 +48,8 @@ class CMediaLibSettingDlg : public CTabDlg protected: void ShowDataSizeInfo(); - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 + virtual bool InitializeControls() override; + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 // 在点击选项设置对话框的“应用”或“确定”时CMusicPlayerDlg::ApplySettings()将所有m_data写入theApp前被调用 // 这里是设置应用前最后的更新ui到m_data的机会,不需要实时更新到m_data的ui也可以只在这里获取 virtual void GetDataFromUi() override; @@ -66,27 +60,16 @@ class CMediaLibSettingDlg : public CTabDlg void UpdateLastFMCacheStatus(); afx_msg void OnTimer(UINT_PTR nIDEvent); - DECLARE_MESSAGE_MAP() + DECLARE_MESSAGE_MAP() public: virtual BOOL OnInitDialog(); - afx_msg void OnBnClickedClassifyOtherCheck(); - //afx_msg void OnBnClickedShowTreeToolTipsCheck(); afx_msg void OnBnClickedAddButton(); afx_msg void OnBnClickedDeleteButton(); - afx_msg void OnBnClickedUpdateMediaLibChk(); afx_msg void OnBnClickedCleanDataFileButton(); virtual BOOL PreTranslateMessage(MSG* pMsg); - afx_msg void OnBnClickedClearRecentPlayedListBtn(); - afx_msg void OnBnClickedDisableDrageSortCheck(); - afx_msg void OnCbnSelchangePlaylistDisplayModeOmbo(); - afx_msg void OnCbnSelchangeRecentPlayedRangeOmbo(); - afx_msg void OnBnClickedInsertBeginCheck(); + afx_msg void OnBnClickedClearRecentPlayedListBtn(); virtual void OnOK(); - afx_msg void OnCbnSelchangeId3v2TypeCombo(); afx_msg void OnBnClickedRefreshMediaLibButton(); - afx_msg void OnBnClickedDisableDeleteFromDiskCheck(); - afx_msg void OnBnClickedShowPlaylistTooltipCheck(); - afx_msg void OnBnClickedFloatPlaylistFollowMainWndCheck(); afx_msg void OnBnClickedEnableLastfm(); afx_msg void OnBnClickedLastfmLogin(); afx_msg void OnBnClickedLastfmAutoScrobble(); @@ -95,6 +78,4 @@ class CMediaLibSettingDlg : public CTabDlg afx_msg void OnBnClickedLastfmEnableNowplaying(); protected: afx_msg LRESULT OnEditBrowseChanged(WPARAM wParam, LPARAM lParam); -public: - afx_msg void OnBnClickedIgnoreTooShortCheck(); }; diff --git a/MusicPlayer2/MediaLibStatisticsDlg.cpp b/MusicPlayer2/MediaLibStatisticsDlg.cpp index b2643673e..2bbaa7a94 100644 --- a/MusicPlayer2/MediaLibStatisticsDlg.cpp +++ b/MusicPlayer2/MediaLibStatisticsDlg.cpp @@ -4,7 +4,6 @@ #include "stdafx.h" #include "MusicPlayer2.h" #include "MediaLibStatisticsDlg.h" -#include "afxdialogex.h" #include "SongDataManager.h" #include "MediaLibHelper.h" @@ -22,16 +21,32 @@ CMediaLibStatisticsDlg::~CMediaLibStatisticsDlg() { } -void CMediaLibStatisticsDlg::DoDataExchange(CDataExchange* pDX) +CString CMediaLibStatisticsDlg::GetDialogName() const { - CBaseDialog::DoDataExchange(pDX); - DDX_Control(pDX, IDC_LIST1, m_list_ctrl); + return _T("MediaLibStatisticsDlg"); } +bool CMediaLibStatisticsDlg::InitializeControls() +{ + wstring temp; + temp = theApp.m_str_table.LoadText(L"TITLE_LIB_STATISTICS"); + SetWindowTextW(temp.c_str()); + // IDC_LIST1 + // IDOK + temp = theApp.m_str_table.LoadText(L"TXT_CLOSE"); + SetDlgItemTextW(IDCANCEL, temp.c_str()); + + RepositionTextBasedControls({ + { CtrlTextInfo::R1, IDOK, CtrlTextInfo::W32 }, + { CtrlTextInfo::R2, IDCANCEL, CtrlTextInfo::W32 } + }); + return true; +} -CString CMediaLibStatisticsDlg::GetDialogName() const +void CMediaLibStatisticsDlg::DoDataExchange(CDataExchange* pDX) { - return _T("MediaLibStatisticsDlg"); + CBaseDialog::DoDataExchange(pDX); + DDX_Control(pDX, IDC_LIST1, m_list_ctrl); } BEGIN_MESSAGE_MAP(CMediaLibStatisticsDlg, CBaseDialog) @@ -47,14 +62,12 @@ BOOL CMediaLibStatisticsDlg::OnInitDialog() // TODO: 在此添加额外的初始化 - SetWindowText(CCommon::LoadText(IDS_MEDIALIB_STATISTICS)); - SetIcon(theApp.m_icon_set.info.GetIcon(true), FALSE); + SetIcon(IconMgr::IconType::IT_Info, FALSE); //初始化控件 - CWnd* ok_btn{ GetDlgItem(IDOK) }; - if (ok_btn != nullptr) - ok_btn->ShowWindow(SW_HIDE); - SetDlgItemText(IDCANCEL, CCommon::LoadText(IDS_CLOSE)); + ShowDlgCtrl(IDOK, false); + if (auto pWnd = GetDlgItem(IDCANCEL)) + pWnd->SetFocus(); //初始化列表 CRect rect; @@ -62,15 +75,15 @@ BOOL CMediaLibStatisticsDlg::OnInitDialog() m_list_ctrl.SetExtendedStyle(m_list_ctrl.GetExtendedStyle() | LVS_EX_GRIDLINES); int width0 = rect.Width() / 2; int width1 = rect.Width() - width0 - theApp.DPI(20) - 1; - m_list_ctrl.InsertColumn(0, CCommon::LoadText(IDS_ITEM), LVCFMT_LEFT, width0); - m_list_ctrl.InsertColumn(1, CCommon::LoadText(IDS_VLAUE), LVCFMT_LEFT, width1); + m_list_ctrl.InsertColumn(0, theApp.m_str_table.LoadText(L"TXT_ITEM").c_str(), LVCFMT_LEFT, width0); + m_list_ctrl.InsertColumn(1, theApp.m_str_table.LoadText(L"TXT_VALUE").c_str(), LVCFMT_LEFT, width1); //插入列 - m_list_ctrl.InsertItem(RI_ARTIST, CCommon::LoadText(IDS_ARTIST)); //艺术家 - m_list_ctrl.InsertItem(RI_ALBUM, CCommon::LoadText(IDS_ALBUM)); //唱片 - m_list_ctrl.InsertItem(RI_GENRE, CCommon::LoadText(IDS_GENRE)); //流派 - m_list_ctrl.InsertItem(RI_TOTAL, CCommon::LoadText(IDS_TOTAL_TRACKS)); //曲目总数 - m_list_ctrl.InsertItem(RI_PLAYED, CCommon::LoadText(IDS_TRACKS_PLAYED)); //播放过的曲目数 + m_list_ctrl.InsertItem(RI_ARTIST, theApp.m_str_table.LoadText(L"TXT_ARTIST").c_str()); //艺术家 + m_list_ctrl.InsertItem(RI_ALBUM, theApp.m_str_table.LoadText(L"TXT_ALBUM").c_str()); //唱片 + m_list_ctrl.InsertItem(RI_GENRE, theApp.m_str_table.LoadText(L"TXT_GENRE").c_str()); //流派 + m_list_ctrl.InsertItem(RI_TOTAL, theApp.m_str_table.LoadText(L"TXT_LIB_STATISTICS_TOTAL_NUM_OF_TRACK").c_str()); //曲目总数 + m_list_ctrl.InsertItem(RI_PLAYED, theApp.m_str_table.LoadText(L"TXT_LIB_STATISTICS_NUM_OF_TRACK_PLAYED").c_str()); //播放过的曲目数 //设置数值 std::set artist_set; @@ -84,7 +97,7 @@ BOOL CMediaLibStatisticsDlg::OnInitDialog() { //处理多个艺术家情况 std::vector artist_list; - item.second.GetArtistList(artist_list, theApp.m_media_lib_setting_data.artist_split_ext); + item.second.GetArtistList(artist_list); for (const auto& artist : artist_list) artist_set.emplace(artist); diff --git a/MusicPlayer2/MediaLibStatisticsDlg.h b/MusicPlayer2/MediaLibStatisticsDlg.h index 62a723c93..0c0924c30 100644 --- a/MusicPlayer2/MediaLibStatisticsDlg.h +++ b/MusicPlayer2/MediaLibStatisticsDlg.h @@ -1,6 +1,6 @@ #pragma once -#include "ListCtrlEx.h" #include "BaseDialog.h" +#include "ListCtrlEx.h" // CMediaLibStatisticsDlg 对话框 @@ -32,12 +32,11 @@ class CMediaLibStatisticsDlg : public CBaseDialog RI_MAX }; + virtual CString GetDialogName() const override; + virtual bool InitializeControls() override; virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() - - virtual CString GetDialogName() const override; - public: virtual BOOL OnInitDialog(); }; diff --git a/MusicPlayer2/MediaLibTabDlg.cpp b/MusicPlayer2/MediaLibTabDlg.cpp index 46c53fc1f..8463520f0 100644 --- a/MusicPlayer2/MediaLibTabDlg.cpp +++ b/MusicPlayer2/MediaLibTabDlg.cpp @@ -1,6 +1,7 @@ #include "stdafx.h" #include "MediaLibTabDlg.h" #include "MusicPlayer2.h" +#include "Player.h" #include "MusicPlayerCmdHelper.h" #include "PropertyDlg.h" #include "SongDataManager.h" @@ -24,7 +25,7 @@ BEGIN_MESSAGE_MAP(CMediaLibTabDlg, CTabDlg) ON_COMMAND(ID_PLAY_ITEM, &CMediaLibTabDlg::OnPlayItem) ON_COMMAND(ID_PLAY_ITEM_IN_FOLDER_MODE, &CMediaLibTabDlg::OnPlayItemInFolderMode) ON_COMMAND(ID_ADD_TO_NEW_PLAYLIST, &CMediaLibTabDlg::OnAddToNewPlaylist) - ON_COMMAND(ID_ADD_TO_NEW_PALYLIST_AND_PLAY, &CMediaLibTabDlg::OnAddToNewPalylistAndPlay) + ON_COMMAND(ID_ADD_TO_NEW_PLAYLIST_AND_PLAY, &CMediaLibTabDlg::OnAddToNewPlaylistAndPlay) ON_COMMAND(ID_EXPLORE_ONLINE, &CMediaLibTabDlg::OnExploreOnline) ON_COMMAND(ID_EXPLORE_TRACK, &CMediaLibTabDlg::OnExploreTrack) ON_COMMAND(ID_FORMAT_CONVERT, &CMediaLibTabDlg::OnFormatConvert) @@ -62,7 +63,7 @@ UINT CMediaLibTabDlg::ViewOnlineThreadFunc(LPVOID lpParam) CMediaLibTabDlg* pThis = (CMediaLibTabDlg*)(lpParam); if (pThis == nullptr) return 0; - CCommon::SetThreadLanguage(theApp.m_general_setting_data.language); + CCommon::SetThreadLanguageList(theApp.m_str_table.GetLanguageTag()); //此命令用于跳转到歌曲对应的网易云音乐的在线页面 if (pThis->GetItemSelected() >= 0) { @@ -90,7 +91,10 @@ void CMediaLibTabDlg::OnOK() else ok = CPlayer::GetInstance().OpenSongsInTempPlaylist(GetSongList(), GetItemSelected()); if (!ok) - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } else { CTabDlg::OnOK(); @@ -143,7 +147,6 @@ void CMediaLibTabDlg::OnInitMenu(CMenu* pMenu) bool can_del = !theApp.m_media_lib_setting_data.disable_delete_from_disk && std::find_if(songs.begin(), songs.end(), [&](const SongInfo& song_info) { return song_info.is_cue || COSUPlayerHelper::IsOsuFile(song_info.file_path); }) != songs.end(); - pMenu->SetDefaultItem(ID_PLAY_ITEM); // 左右菜单都有这一项 pMenu->EnableMenuItem(ID_PLAY_AS_NEXT, MF_BYCOMMAND | (select_all_in_playing_list ? MF_ENABLED : MF_GRAYED)); pMenu->EnableMenuItem(ID_DELETE_FROM_DISK, MF_BYCOMMAND | (can_del ? MF_ENABLED : MF_GRAYED)); } @@ -173,7 +176,10 @@ void CMediaLibTabDlg::OnPlayItemInFolderMode() if (sel_item >= 0 && sel_item < static_cast(GetSongList().size())) { if (!CPlayer::GetInstance().OpenASongInFolderMode(GetSongList()[sel_item], true)) - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } else OnCancel(); } @@ -188,14 +194,17 @@ void CMediaLibTabDlg::OnAddToNewPlaylist() } -void CMediaLibTabDlg::OnAddToNewPalylistAndPlay() +void CMediaLibTabDlg::OnAddToNewPlaylistAndPlay() { // TODO: 在此添加命令处理程序代码 wstring playlist_path; if (_OnAddToNewPlaylist(playlist_path)) { if (!CPlayer::GetInstance().SetPlaylist(playlist_path, 0, 0, true)) - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } else OnCancel(); } @@ -273,5 +282,5 @@ void CMediaLibTabDlg::OnCopyText() { // TODO: 在此添加命令处理程序代码 if (!CCommon::CopyStringToClipboard(GetSelectedString())) - MessageBox(CCommon::LoadText(IDS_COPY_CLIPBOARD_FAILED), NULL, MB_ICONWARNING); + MessageBox(theApp.m_str_table.LoadText(L"MSG_COPY_CLIPBOARD_FAILED").c_str(), NULL, MB_ICONWARNING); } diff --git a/MusicPlayer2/MediaLibTabDlg.h b/MusicPlayer2/MediaLibTabDlg.h index 80dcfec6e..365f338af 100644 --- a/MusicPlayer2/MediaLibTabDlg.h +++ b/MusicPlayer2/MediaLibTabDlg.h @@ -52,7 +52,7 @@ class CMediaLibTabDlg : public CTabDlg afx_msg void OnPlayAsNext(); afx_msg void OnPlayItemInFolderMode(); afx_msg void OnAddToNewPlaylist(); - afx_msg void OnAddToNewPalylistAndPlay(); + afx_msg void OnAddToNewPlaylistAndPlay(); afx_msg void OnExploreOnline(); afx_msg void OnExploreTrack(); afx_msg void OnFormatConvert(); diff --git a/MusicPlayer2/MediaTransControls.cpp b/MusicPlayer2/MediaTransControls.cpp index 4dd09ad30..e8624c35d 100644 --- a/MusicPlayer2/MediaTransControls.cpp +++ b/MusicPlayer2/MediaTransControls.cpp @@ -1,482 +1,159 @@ #include "stdafx.h" #include "MediaTransControls.h" - #ifndef DISABLE_MEDIA_TRANS_CONTROLS -#include "Resource.h" -#include "shcore.h" -#include "WinVersionHelper.h" -#include "player.h" -#include "AudioTag.h" - -#pragma comment(lib, "RuntimeObject.lib") -#pragma comment(lib, "ShCore.lib") - -#include -/// The file content of SystemMediaTransportControlsInterop.h -/// SystemMediaTransportControlsInterop.h can not be found in Win 8.1 SDK -#ifndef ISystemMediaTransportControlsInterop -EXTERN_C const IID IID_ISystemMediaTransportControlsInterop; -MIDL_INTERFACE("ddb0472d-c911-4a1f-86d9-dc3d71a95f5a") -ISystemMediaTransportControlsInterop : public IInspectable{ - public: - virtual HRESULT STDMETHODCALLTYPE GetForWindow( - /* [in] */ __RPC__in HWND appWindow, - /* [in] */ __RPC__in REFIID riid, - /* [iid_is][retval][out] */ - __RPC__deref_out_opt void** mediaTransportControl) = 0; -}; -# endif - -using namespace Windows::Foundation; -using namespace ABI::Windows::Storage; -using namespace Microsoft::WRL; -using namespace Microsoft::WRL::Wrappers; - -void MediaTransControls::SetEnabled(bool enable) -{ - m_enabled = enable; -} - -bool MediaTransControls::Init() { - if (!m_enabled || m_initailzed) return true; - /// Windows 8.1 or later is required - if (!CWinVersionHelper::IsWindows81OrLater()) return false; - CComPtr op; - HRESULT ret; - if ((ret = GetActivationFactory(HStringReference(L"Windows.Media.SystemMediaTransportControls").Get(), &op)) != S_OK) { - controls = nullptr; - return false; - } - if ((ret = op->GetForWindow(AfxGetMainWnd()->GetSafeHwnd(), IID_PPV_ARGS(&controls))) != S_OK) { - controls = nullptr; - return false; - } - controls->put_PlaybackStatus(MediaPlaybackStatus::MediaPlaybackStatus_Closed); - ret = controls->get_DisplayUpdater(&this->updater); - ASSERT(ret == S_OK); - if (ret != S_OK) { - controls = nullptr; - return false; - } - ret = updater->put_Type(MediaPlaybackType::MediaPlaybackType_Music); - ASSERT(ret == S_OK); - if (ret != S_OK) { - controls = nullptr; - updater = nullptr; - return false; - } - ret = updater->get_MusicProperties(&music); - ASSERT(ret == S_OK); - if (ret != S_OK) { - controls = nullptr; - updater = nullptr; - return false; - } - auto callbackButtonPressed = Callback>( - [this](ISystemMediaTransportControls*, ISystemMediaTransportControlsButtonPressedEventArgs* pArgs) { - HRESULT ret; - SystemMediaTransportControlsButton button; - if ((ret = pArgs->get_Button(&button)) != S_OK) { - return ret; - } - OnButtonPressed(button); - return S_OK; - }); - ret = controls->add_ButtonPressed(callbackButtonPressed.Get(), &m_EventRegistrationToken); - ASSERT(ret == S_OK); - if (ret != S_OK) { - controls = nullptr; - updater = nullptr; - music = nullptr; - return false; - } - controls->put_IsPlayEnabled(true); - controls->put_IsPauseEnabled(true); - controls->put_IsStopEnabled(true); - controls->put_IsPreviousEnabled(true); - controls->put_IsNextEnabled(true); - ret = controls->put_IsEnabled(true); - ASSERT(ret == S_OK); - m_initailzed = true; - ret = ActivateInstance(HStringReference(RuntimeClass_Windows_Media_SystemMediaTransportControlsTimelineProperties).Get(), &timeline); - if (timeline && ret == S_OK) { - timeline->put_StartTime(ABI::Windows::Foundation::TimeSpan { 0 }); - timeline->put_Position(ABI::Windows::Foundation::TimeSpan{ 0 }); - timeline->put_MinSeekTime(ABI::Windows::Foundation::TimeSpan{ 0 }); - timeline->put_EndTime(ABI::Windows::Foundation::TimeSpan{ 0 }); - timeline->put_MaxSeekTime(ABI::Windows::Foundation::TimeSpan{ 0 }); - } - controls.As(&controls2); - if (controls2) { - controls2->UpdateTimelineProperties(timeline); - auto callbackPlaybackPositionChangeRequested = Callback>( - [this](ISystemMediaTransportControls*, IPlaybackPositionChangeRequestedEventArgs* pArgs) { - HRESULT ret; - ABI::Windows::Foundation::TimeSpan time; - if ((ret = pArgs->get_RequestedPlaybackPosition(&time)) == S_OK) { - if (CPlayer::GetInstance().GetPlayStatusMutex().try_lock_for(std::chrono::milliseconds(1000))) { - CPlayer::GetInstance().SeekTo(static_cast(time.Duration / 10000)); - CPlayer::GetInstance().GetPlayStatusMutex().unlock(); - } - } - return S_OK; - }); - controls2->add_PlaybackPositionChangeRequested(callbackPlaybackPositionChangeRequested.Get(), &m_EventRegistrationToken2); - auto callbackPlaybackRateChangeRequested = Callback>( - [this](ISystemMediaTransportControls*, IPlaybackRateChangeRequestedEventArgs* pArgs) { - HRESULT ret; - double rate = 1.0; - ret = pArgs->get_RequestedPlaybackRate(&rate); - if (ret == S_OK) { - CPlayer::GetInstance().SetSpeed((float)rate); - } - return S_OK; - }); - controls2->add_PlaybackRateChangeRequested(callbackPlaybackRateChangeRequested.Get(), &m_EventRegistrationToken3); - } - return true; -} - -template -bool AwaitForIAsyncOperation(CComPtr> io) { - CComPtr info; - ABI::Windows::Foundation::AsyncStatus status; - HRESULT ret; - info = io; - while (true) { - if ((ret = info->get_Status(&status)) != S_OK) { - return false; - } - if (status != ABI::Windows::Foundation::AsyncStatus::Started) { - if (status == ABI::Windows::Foundation::AsyncStatus::Completed) return true; - return false; - } - Sleep(10); - } -} - -void MediaTransControls::loadThumbnail(wstring fn) { - if (!m_enabled || !fn.length() || !updater) return; - if (IsURL(fn)) return loadThumbnailFromUrl(fn); - HRESULT ret; - CComPtr sfs; - if ((ret = GetActivationFactory(HStringReference(RuntimeClass_Windows_Storage_StorageFile).Get(), &sfs)) != S_OK) { - return; - } - CComPtr> af; - if ((ret = sfs->GetFileFromPathAsync(HStringReference(fn.c_str()).Get(), &af)) != S_OK) { - return; - } - /// Present file - CComPtr f; - if (!AwaitForIAsyncOperation(af)) { - return; - } - if ((ret = af->GetResults(&f)) != S_OK) { - return; - } - CComPtr rasrs; - if ((ret = GetActivationFactory(HStringReference(RuntimeClass_Windows_Storage_Streams_RandomAccessStreamReference).Get(), &rasrs)) != S_OK) { - return; - } - CComPtr stream; - if ((ret = rasrs->CreateFromFile(f, &stream)) != S_OK) { - return; - } - updater->put_Thumbnail(stream); - updater->Update(); -} - -void MediaTransControls::loadThumbnail(const BYTE* content, size_t size) { - if (!m_enabled || !content || !size || !updater) return; - ComPtr s; - HRESULT ret; - if ((ret = ActivateInstance(HStringReference(RuntimeClass_Windows_Storage_Streams_InMemoryRandomAccessStream).Get(), s.GetAddressOf())) != S_OK) { - return; - } - ComPtr writer; - CreateStreamOverRandomAccessStream(s.Get(), IID_PPV_ARGS(writer.GetAddressOf())); - writer->Write(content, (ULONG)size, nullptr); - CComPtr rasrs; - if ((ret = GetActivationFactory(HStringReference(RuntimeClass_Windows_Storage_Streams_RandomAccessStreamReference).Get(), &rasrs)) != S_OK) { - return; - } - CComPtr stream; - if ((ret = rasrs->CreateFromStream(s.Get(), &stream)) != S_OK) { - return; - } - updater->put_Thumbnail(stream); - updater->Update(); -} - -void MediaTransControls::loadThumbnailFromUrl(wstring url) { - if (!m_enabled || !url.length() || !updater) return; - HRESULT ret; - CComPtr u; - if ((ret = Windows::Foundation::GetActivationFactory(HStringReference(RuntimeClass_Windows_Foundation_Uri).Get(), &u)) != S_OK) { - return; - } - CComPtr uri; - if ((ret = u->CreateUri(HStringReference(url.c_str()).Get(), &uri)) != S_OK) { - return; - } - CComPtr rasrs; - if ((ret = GetActivationFactory(HStringReference(RuntimeClass_Windows_Storage_Streams_RandomAccessStreamReference).Get(), &rasrs)) != S_OK) { - return; - } - CComPtr stream; - if ((ret = rasrs->CreateFromUri(uri, &stream)) != S_OK) { - return; - } - ret = updater->put_Thumbnail(stream); - ASSERT(ret == S_OK); - updater->Update(); -} - -bool MediaTransControls::IsActive() { - if (!m_enabled) - return false; - if (controls) { - boolean enabled; - HRESULT hr; - if ((hr = controls->get_IsEnabled(&enabled)) == S_OK) { - return enabled; - } - } - return false; -} +#include "MediaTransControlsImpl.h" -void MediaTransControls::UpdateTitle(wstring title) { - if (music) { - music->put_Title(HStringReference(title.c_str()).Get()); - } -} - -void MediaTransControls::UpdateArtist(wstring artist) { - if (music) { - auto ret = music->put_Artist(HStringReference(artist.c_str()).Get()); - ASSERT(ret == S_OK); - } -} +#include "player.h" +#include "WinVersionHelper.h" +#include "resource.h" -void MediaTransControls::ClearAll() +MediaTransControls::MediaTransControls() { - if (m_enabled && updater) - updater->ClearAll(); } -void MediaTransControls::UpdateControls(Command cmd) +MediaTransControls::~MediaTransControls() { - if (m_enabled && controls) - { - switch (cmd) { - case Command::PLAY: - controls->put_PlaybackStatus(MediaPlaybackStatus_Playing); - break; - case Command::PAUSE: - controls->put_PlaybackStatus(MediaPlaybackStatus_Paused); - break; - case Command::STOP: - controls->put_PlaybackStatus(MediaPlaybackStatus_Stopped); - break; - default: - ASSERT(FALSE); - break; - } - } } -void MediaTransControls::UpdateControlsMetadata(const SongInfo song) +bool MediaTransControls::InitSMTC(bool enable) { - if (m_enabled && updater && music) { - updater->put_Type(MediaPlaybackType_Music); - UpdateTitle((!song.IsTitleEmpty() || song.file_path.empty()) ? song.GetTitle() : song.GetFileName()); - UpdateArtist(song.GetArtist()); - UpdateAlbumTitle(song.GetAlbum()); - UpdateTrackNumber(song.track); - if (!song.IsGenreEmpty()) - UpdateGenre(song.GetGenre()); - if (song.total_tracks != 0) - UpdateAlbumTrackCount(song.total_tracks); - if (!song.album_artist.empty()) - UpdateAlbumArtist(song.album_artist); - updater->Update(); - } -} - -void MediaTransControls::OnButtonPressed(SystemMediaTransportControlsButton button) { - switch (button) { - case SystemMediaTransportControlsButton_Play: - SendMessage(AfxGetMainWnd()->GetSafeHwnd(), WM_COMMAND, ID_PLAY, 0); - break; - case SystemMediaTransportControlsButton_Pause: - SendMessage(AfxGetMainWnd()->GetSafeHwnd(), WM_COMMAND, ID_PAUSE, 0); - break; - case SystemMediaTransportControlsButton_Stop: - SendMessage(AfxGetMainWnd()->GetSafeHwnd(), WM_COMMAND, ID_STOP, 0); - break; - case SystemMediaTransportControlsButton_Previous: - SendMessage(AfxGetMainWnd()->GetSafeHwnd(), WM_COMMAND, ID_PREVIOUS, 0); - break; - case SystemMediaTransportControlsButton_Next: - SendMessage(AfxGetMainWnd()->GetSafeHwnd(), WM_COMMAND, ID_NEXT, 0); - break; - } -} - -bool MediaTransControls::IsURL(wstring s) { - auto i = s.find(L"://"); - return i != std::wstring::npos && i > 1; -} - -void MediaTransControls::UpdateDuration(int64_t duration) { - if (!m_enabled) - return; - HRESULT hr; - if (timeline) { - hr = timeline->put_EndTime(ABI::Windows::Foundation::TimeSpan{ duration * 10000 }); - ASSERT(S_OK == hr); - hr = timeline->put_MaxSeekTime(ABI::Windows::Foundation::TimeSpan{ duration * 10000 }); - ASSERT(S_OK == hr); - } - if (controls2) { - hr = controls2->UpdateTimelineProperties(timeline); - ASSERT(S_OK == hr); - } -} - -void MediaTransControls::UpdatePosition(int64_t postion) { - if (!m_enabled) - return; - HRESULT hr; - if (timeline) { - hr = timeline->put_Position(ABI::Windows::Foundation::TimeSpan{ postion * 10000 }); - ASSERT(S_OK == hr); - } - if (controls2) { - hr = controls2->UpdateTimelineProperties(timeline); - ASSERT(S_OK == hr); - } -} + std::lock_guard lock(m_mutex); + pImpl.reset(); + if (!enable) + return true; -void MediaTransControls::UpdateAlbumArtist(wstring album_artist) { - if (music) { - auto ret = music->put_AlbumArtist(HStringReference(album_artist.c_str()).Get()); - ASSERT(ret == S_OK); - } -} - -void MediaTransControls::UpdateAlbumTitle(wstring album_title) { - if (music) { - ComPtr p = nullptr; - music.As(&p); - if (p) { - auto ret = p->put_AlbumTitle(HStringReference(album_title.c_str()).Get()); - ASSERT(ret == S_OK); - } - } -} - -void MediaTransControls::UpdateTrackNumber(UINT track) { - if (music) { - ComPtr p = nullptr; - music.As(&p); - if (p) { - auto ret = p->put_TrackNumber(track); - ASSERT(ret == S_OK); - } - } -} - -void MediaTransControls::UpdateAlbumTrackCount(UINT track_count) { - if (music) { - ComPtr p = nullptr; - music.As(&p); - if (p) { - auto ret = p->put_AlbumTrackCount(track_count); - ASSERT(ret == S_OK); - } - } -} - -void MediaTransControls::UpdateGenre(wstring genre) { - std::vector genres(1, genre); - UpdateGenres(genres); -} - -void MediaTransControls::UpdateGenres(std::vector genres) { - if (music) { - ComPtr p = nullptr; - music.As(&p); - if (p) { - ComPtr> vect = nullptr; - auto ret = p->get_Genres(vect.GetAddressOf()); - ASSERT(ret == S_OK); - if (vect) { - ret = vect->Clear(); - ASSERT(ret == S_OK); - for (auto i = genres.begin(); i != genres.end(); i++) { - auto &s = *i; - ret = vect->Append(HStringReference(s.c_str()).Get()); - ASSERT(ret == S_OK); - } + /// Windows 8.1 or later is required + if (!CWinVersionHelper::IsWindows81OrLater()) + return false; + auto ButtonCallback = [](SystemMediaTransportControlsButton type) + { + switch (type) + { + case SystemMediaTransportControlsButton::SystemMediaTransportControlsButton_Play: + SendMessage(AfxGetMainWnd()->GetSafeHwnd(), WM_COMMAND, ID_PLAY, 0); + break; + case SystemMediaTransportControlsButton::SystemMediaTransportControlsButton_Pause: + SendMessage(AfxGetMainWnd()->GetSafeHwnd(), WM_COMMAND, ID_PAUSE, 0); + break; + case SystemMediaTransportControlsButton::SystemMediaTransportControlsButton_Stop: + SendMessage(AfxGetMainWnd()->GetSafeHwnd(), WM_COMMAND, ID_STOP, 0); + break; + case SystemMediaTransportControlsButton::SystemMediaTransportControlsButton_Previous: + SendMessage(AfxGetMainWnd()->GetSafeHwnd(), WM_COMMAND, ID_PREVIOUS, 0); + break; + case SystemMediaTransportControlsButton::SystemMediaTransportControlsButton_Next: + SendMessage(AfxGetMainWnd()->GetSafeHwnd(), WM_COMMAND, ID_NEXT, 0); + break; } - } - } -} - -void MediaTransControls::UpdateSpeed(float speed) { - if (m_enabled && controls2) { - auto ret = controls2->put_PlaybackRate(speed); - ASSERT(ret == S_OK); - } + }; + auto SeekCallback = [](INT64 postion) + { + if (CPlayer::GetInstance().GetPlayStatusMutex().try_lock_for(std::chrono::milliseconds(1000))) + { + CPlayer::GetInstance().SeekTo(static_cast(postion / 10000)); + CPlayer::GetInstance().GetPlayStatusMutex().unlock(); + } + }; + auto SetSpeedCallback = [](DOUBLE rate) + { + CPlayer::GetInstance().SetSpeed(static_cast(rate)); + }; + pImpl = std::make_unique(AfxGetMainWnd()->GetSafeHwnd(), ButtonCallback, SeekCallback, SetSpeedCallback); + return pImpl->IsActive(); } -#else - -MediaTransControls::MediaTransControls() +void MediaTransControls::loadThumbnail(const wstring& fn) { + std::lock_guard lock(m_mutex); + if (!pImpl) return; + auto i = fn.find(L"://"); + if (i != std::wstring::npos && i > 1) + pImpl->loadThumbnailFromUrl(fn); + else + pImpl->loadThumbnailFromFile(fn); } -void MediaTransControls::SetEnabled(bool enable) +void MediaTransControls::loadThumbnail(const BYTE* content, size_t size) { + std::lock_guard lock(m_mutex); + if (!pImpl) return; + pImpl->loadThumbnailFromBuff(content, size); } -bool MediaTransControls::Init() +bool MediaTransControls::IsActive() { - return false; + std::lock_guard lock(m_mutex); + if (!pImpl) return false; + return pImpl->IsActive(); } -void MediaTransControls::loadThumbnail(wstring fn) +void MediaTransControls::ClearAll() { + std::lock_guard lock(m_mutex); + if (!pImpl) return; + pImpl->ClearAll(); } -void MediaTransControls::loadThumbnail(const BYTE* content, size_t size) -{ -} -void MediaTransControls::loadThumbnailFromUrl(wstring url) -{ -} -bool MediaTransControls::IsActive() +void MediaTransControls::UpdateControls(PlaybackStatus status) { - return false; + std::lock_guard lock(m_mutex); + if (!pImpl) return; + MediaPlaybackStatus status_media{}; + switch (status) + { + case PlaybackStatus::Closed: status_media = MediaPlaybackStatus::MediaPlaybackStatus_Closed; break; + case PlaybackStatus::Changing: status_media = MediaPlaybackStatus::MediaPlaybackStatus_Changing; break; + case PlaybackStatus::Stopped: status_media = MediaPlaybackStatus::MediaPlaybackStatus_Stopped; break; + case PlaybackStatus::Playing: status_media = MediaPlaybackStatus::MediaPlaybackStatus_Playing; break; + case PlaybackStatus::Paused: status_media = MediaPlaybackStatus::MediaPlaybackStatus_Paused; break; + default: ASSERT(FALSE); break; + } + pImpl->UpdateControls(status_media); } -void MediaTransControls::ClearAll() + +void MediaTransControls::UpdateControlsMetadata(const SongInfo& song) { + std::lock_guard lock(m_mutex); + if (!pImpl) return; + const wstring& title = (!song.IsTitleEmpty() || song.file_path.empty()) ? song.GetTitle() : song.GetFileName(); + vector genres(1, song.GetGenre()); + pImpl->UpdateControlsMetadata(title, song.GetAlbum(), song.album_artist, song.GetAlbum(), genres, song.track, song.total_tracks); + pImpl->UpdateDuration(song.length().toInt()); // milliseconds } -void MediaTransControls::UpdateControls(Command cmd) +void MediaTransControls::UpdatePosition(int64_t postion, bool force) { + // 降低更新频率,每秒更新一次,在我的系统(win10使用ModernFlyouts)实际最高有效值大概是500ms一次 + static int64_t last{}; + if (last == postion / 1000 && !force) + return; + last = postion / 1000; + std::lock_guard lock(m_mutex); + if (!pImpl) return; + pImpl->UpdatePosition(postion); } -void MediaTransControls::UpdateControlsMetadata(const SongInfo song) +void MediaTransControls::UpdateSpeed(float speed) { + std::lock_guard lock(m_mutex); + if (!pImpl) return; + pImpl->UpdateSpeed(speed); } -void MediaTransControls::UpdateDuration(int64_t duration) {} +#else +MediaTransControls::MediaTransControls() {} +MediaTransControls::~MediaTransControls() {} +void MediaTransControls::SetEnabled(bool enable) {} +bool MediaTransControls::InitSMTC(bool enable) { return false; } +void MediaTransControls::loadThumbnail(wstring fn) {} +void MediaTransControls::loadThumbnail(const BYTE* content, size_t size) {} +bool MediaTransControls::IsActive() { return false; } +void MediaTransControls::ClearAll() {} +void MediaTransControls::UpdateControls(PlaybackStatus status) {} +void MediaTransControls::UpdateControlsMetadata(const SongInfo& song) {} void MediaTransControls::UpdatePosition(int64_t postion) {} - void MediaTransControls::UpdateSpeed(float speed) {} + #endif diff --git a/MusicPlayer2/MediaTransControls.h b/MusicPlayer2/MediaTransControls.h index b019715bc..f8ae3a5e4 100644 --- a/MusicPlayer2/MediaTransControls.h +++ b/MusicPlayer2/MediaTransControls.h @@ -1,96 +1,36 @@ #pragma once - -#include "Common.h" #include "SongInfo.h" -#ifndef DISABLE_MEDIA_TRANS_CONTROLS -#include -#include -#include -#include -#include +enum class PlaybackStatus +{ + Closed = 0, + Changing = 1, + Stopped = 2, + Playing = 3, + Paused = 4, +}; -using namespace ABI::Windows::Media; +class MediaTransControlsImpl; class MediaTransControls { public: - MediaTransControls(void) { - this->timeline = nullptr; - this->controls = nullptr; - this->updater = nullptr; - this->music = nullptr; - this->controls2 = nullptr; - } - ~MediaTransControls(void) { - if (controls && m_EventRegistrationToken.value) { - controls->remove_ButtonPressed(m_EventRegistrationToken); - } - if (controls2 && m_EventRegistrationToken2.value) { - controls2->remove_PlaybackPositionChangeRequested(m_EventRegistrationToken2); - } - if (controls2 && m_EventRegistrationToken3.value) { - controls2->remove_PlaybackRateChangeRequested(m_EventRegistrationToken3); - } - } - void SetEnabled(bool enable); - /** - * @brief Intitialize the interface - * @param main - * @return true if initalized - */ - bool Init(); - void loadThumbnail(wstring fn); + MediaTransControls(); + ~MediaTransControls(); + bool InitSMTC(bool enable); + void loadThumbnail(const wstring& fn); void loadThumbnail(const BYTE* content, size_t size); - void loadThumbnailFromUrl(wstring url); bool IsActive(); void ClearAll(); - void UpdateControls(Command cmd); - void UpdateControlsMetadata(const SongInfo song); - /// Update duration of stream, in milliseconds - void UpdateDuration(int64_t duration); + void UpdateControls(PlaybackStatus status); + void UpdateControlsMetadata(const SongInfo& song); /// Update current time, in milliseconds - void UpdatePosition(int64_t postion); + void UpdatePosition(int64_t postion, bool force = false); /// Update current speed void UpdateSpeed(float speed); -protected: - CComPtr timeline; - Microsoft::WRL::ComPtr controls; - Microsoft::WRL::ComPtr controls2; - CComPtr updater; - Microsoft::WRL::ComPtr music; - EventRegistrationToken m_EventRegistrationToken, m_EventRegistrationToken2, m_EventRegistrationToken3; - void UpdateTitle(wstring title); - void UpdateArtist(wstring artist); - void UpdateAlbumArtist(wstring album_artist); - void UpdateAlbumTitle(wstring album_title); - void UpdateTrackNumber(UINT track); - void UpdateAlbumTrackCount(UINT track_count); - void UpdateGenre(wstring genre); - void UpdateGenres(std::vector genres); - void OnButtonPressed(SystemMediaTransportControlsButton button); - bool IsURL(wstring s); - bool m_initailzed = false; - bool m_enabled = true; -}; - -#else - -class MediaTransControls -{ -public: - MediaTransControls(); - void SetEnabled(bool enable); - bool Init(); - void loadThumbnail(wstring fn); - void loadThumbnail(const BYTE* content, size_t size); - void loadThumbnailFromUrl(wstring url); - bool IsActive(); - void ClearAll(); - void UpdateControls(Command cmd); - void UpdateControlsMetadata(const SongInfo song); - void UpdateDuration(int64_t duration); - void UpdatePosition(int64_t postion); - void UpdateSpeed(float speed); -}; +#ifndef DISABLE_MEDIA_TRANS_CONTROLS +private: + std::mutex m_mutex; // 使用pImpl指针期间锁定此互斥量 + std::unique_ptr pImpl; #endif +}; diff --git a/MusicPlayer2/MediaTransControlsImpl.cpp b/MusicPlayer2/MediaTransControlsImpl.cpp new file mode 100644 index 000000000..78aadf743 --- /dev/null +++ b/MusicPlayer2/MediaTransControlsImpl.cpp @@ -0,0 +1,353 @@ +#include "stdafx.h" +#include "MediaTransControlsImpl.h" + +#include +#pragma comment(lib, "RuntimeObject.lib") +#pragma comment(lib, "ShCore.lib") + +/// The file content of SystemMediaTransportControlsInterop.h +/// SystemMediaTransportControlsInterop.h can not be found in Win 8.1 SDK +#ifndef ISystemMediaTransportControlsInterop +EXTERN_C const IID IID_ISystemMediaTransportControlsInterop; +MIDL_INTERFACE("ddb0472d-c911-4a1f-86d9-dc3d71a95f5a") +ISystemMediaTransportControlsInterop : public IInspectable{ + public: + virtual HRESULT STDMETHODCALLTYPE GetForWindow( + /* [in] */ __RPC__in HWND appWindow, + /* [in] */ __RPC__in REFIID riid, + /* [iid_is][retval][out] */ + __RPC__deref_out_opt void** mediaTransportControl) = 0; +}; +#endif + +using Windows::Foundation::GetActivationFactory; +using Windows::Foundation::ActivateInstance; +using Microsoft::WRL::Wrappers::HStringReference; + +using namespace ABI::Windows::Media; +using namespace ABI::Windows::Storage; +using namespace Microsoft::WRL; + + +MediaTransControlsImpl::MediaTransControlsImpl(HWND appWindow, std::function ButtonCallback, std::function SeekCallback, std::function SetSpeedCallback) +{ + CComPtr op; + HRESULT ret; + if ((ret = GetActivationFactory(HStringReference(RuntimeClass_Windows_Media_SystemMediaTransportControls).Get(), &op)) != S_OK) { + controls = nullptr; + return; + } + if ((ret = op->GetForWindow(appWindow, IID_PPV_ARGS(&controls))) != S_OK) { + controls = nullptr; + return; + } + controls->put_PlaybackStatus(MediaPlaybackStatus::MediaPlaybackStatus_Closed); + ret = controls->get_DisplayUpdater(&this->updater); + ASSERT(ret == S_OK); + if (ret != S_OK) { + controls = nullptr; + return; + } + ret = updater->put_Type(MediaPlaybackType::MediaPlaybackType_Music); + ASSERT(ret == S_OK); + if (ret != S_OK) { + controls = nullptr; + updater = nullptr; + return; + } + ret = updater->get_MusicProperties(&music); + ASSERT(ret == S_OK); + if (ret != S_OK) { + controls = nullptr; + updater = nullptr; + return; + } + auto callbackButtonPressed = Callback>( + [ButtonCallback](ISystemMediaTransportControls*, ISystemMediaTransportControlsButtonPressedEventArgs* pArgs) { + HRESULT ret; + SystemMediaTransportControlsButton button; + if ((ret = pArgs->get_Button(&button)) != S_OK) { + return ret; + } + ButtonCallback(button); + return S_OK; + }); + ret = controls->add_ButtonPressed(callbackButtonPressed.Get(), &m_EventRegistrationToken); + ASSERT(ret == S_OK); + if (ret != S_OK) { + controls = nullptr; + updater = nullptr; + music = nullptr; + return; + } + controls->put_IsPlayEnabled(true); + controls->put_IsPauseEnabled(true); + controls->put_IsStopEnabled(true); + controls->put_IsPreviousEnabled(true); + controls->put_IsNextEnabled(true); + ret = controls->put_IsEnabled(true); + ASSERT(ret == S_OK); + ret = ActivateInstance(HStringReference(RuntimeClass_Windows_Media_SystemMediaTransportControlsTimelineProperties).Get(), &timeline); + if (timeline && ret == S_OK) { + timeline->put_StartTime(ABI::Windows::Foundation::TimeSpan{ 0 }); + timeline->put_Position(ABI::Windows::Foundation::TimeSpan{ 0 }); + timeline->put_MinSeekTime(ABI::Windows::Foundation::TimeSpan{ 0 }); + timeline->put_EndTime(ABI::Windows::Foundation::TimeSpan{ 0 }); + timeline->put_MaxSeekTime(ABI::Windows::Foundation::TimeSpan{ 0 }); + } + controls.As(&controls2); + if (controls2) { + controls2->UpdateTimelineProperties(timeline); + auto callbackPlaybackPositionChangeRequested = Callback>( + [SeekCallback](ISystemMediaTransportControls*, IPlaybackPositionChangeRequestedEventArgs* pArgs) { + HRESULT ret; + ABI::Windows::Foundation::TimeSpan time; + if ((ret = pArgs->get_RequestedPlaybackPosition(&time)) == S_OK) { + SeekCallback(time.Duration); + } + return S_OK; + }); + controls2->add_PlaybackPositionChangeRequested(callbackPlaybackPositionChangeRequested.Get(), &m_EventRegistrationToken2); + auto callbackPlaybackRateChangeRequested = Callback>( + [SetSpeedCallback](ISystemMediaTransportControls*, IPlaybackRateChangeRequestedEventArgs* pArgs) { + HRESULT ret; + DOUBLE rate = 1.0; + ret = pArgs->get_RequestedPlaybackRate(&rate); + if (ret == S_OK) { + SetSpeedCallback(rate); + } + return S_OK; + }); + controls2->add_PlaybackRateChangeRequested(callbackPlaybackRateChangeRequested.Get(), &m_EventRegistrationToken3); + } +} + +MediaTransControlsImpl::~MediaTransControlsImpl() +{ + if (controls && m_EventRegistrationToken.value) { + controls->remove_ButtonPressed(m_EventRegistrationToken); + } + if (controls2 && m_EventRegistrationToken2.value) { + controls2->remove_PlaybackPositionChangeRequested(m_EventRegistrationToken2); + } + if (controls2 && m_EventRegistrationToken3.value) { + controls2->remove_PlaybackRateChangeRequested(m_EventRegistrationToken3); + } + if (updater) + updater->ClearAll(); + if (controls) + controls->put_IsEnabled(false); +} + +namespace { + template + bool AwaitForIAsyncOperation(CComPtr> io) { + CComPtr info; + ABI::Windows::Foundation::AsyncStatus status; + HRESULT ret; + info = io; + while (true) { + if ((ret = info->get_Status(&status)) != S_OK) { + return false; + } + if (status != ABI::Windows::Foundation::AsyncStatus::Started) { + if (status == ABI::Windows::Foundation::AsyncStatus::Completed) return true; + return false; + } + Sleep(10); + } + } +} + +void MediaTransControlsImpl::loadThumbnailFromFile(const wstring& file_path) +{ + if (!file_path.length() || !updater) return; + HRESULT ret; + CComPtr sfs; + if ((ret = GetActivationFactory(HStringReference(RuntimeClass_Windows_Storage_StorageFile).Get(), &sfs)) != S_OK) { + return; + } + CComPtr> af; + if ((ret = sfs->GetFileFromPathAsync(HStringReference(file_path.c_str()).Get(), &af)) != S_OK) { + return; + } + /// Present file + CComPtr f; + if (!AwaitForIAsyncOperation(af)) { + return; + } + if ((ret = af->GetResults(&f)) != S_OK) { + return; + } + CComPtr rasrs; + if ((ret = GetActivationFactory(HStringReference(RuntimeClass_Windows_Storage_Streams_RandomAccessStreamReference).Get(), &rasrs)) != S_OK) { + return; + } + CComPtr stream; + if ((ret = rasrs->CreateFromFile(f, &stream)) != S_OK) { + return; + } + updater->put_Thumbnail(stream); + updater->Update(); +} + +void MediaTransControlsImpl::loadThumbnailFromBuff(const BYTE* content, size_t size) +{ + if (!content || !size || !updater) return; + ComPtr s; + HRESULT ret; + if ((ret = ActivateInstance(HStringReference(RuntimeClass_Windows_Storage_Streams_InMemoryRandomAccessStream).Get(), s.GetAddressOf())) != S_OK) { + return; + } + ComPtr writer; + CreateStreamOverRandomAccessStream(s.Get(), IID_PPV_ARGS(writer.GetAddressOf())); + writer->Write(content, (ULONG)size, nullptr); + CComPtr rasrs; + if ((ret = GetActivationFactory(HStringReference(RuntimeClass_Windows_Storage_Streams_RandomAccessStreamReference).Get(), &rasrs)) != S_OK) { + return; + } + CComPtr stream; + if ((ret = rasrs->CreateFromStream(s.Get(), &stream)) != S_OK) { + return; + } + updater->put_Thumbnail(stream); + updater->Update(); +} + +void MediaTransControlsImpl::loadThumbnailFromUrl(const wstring& url) +{ + if (!url.length() || !updater) return; + HRESULT ret; + CComPtr u; + if ((ret = Windows::Foundation::GetActivationFactory(HStringReference(RuntimeClass_Windows_Foundation_Uri).Get(), &u)) != S_OK) { + return; + } + CComPtr uri; + if ((ret = u->CreateUri(HStringReference(url.c_str()).Get(), &uri)) != S_OK) { + return; + } + CComPtr rasrs; + if ((ret = GetActivationFactory(HStringReference(RuntimeClass_Windows_Storage_Streams_RandomAccessStreamReference).Get(), &rasrs)) != S_OK) { + return; + } + CComPtr stream; + if ((ret = rasrs->CreateFromUri(uri, &stream)) != S_OK) { + return; + } + ret = updater->put_Thumbnail(stream); + ASSERT(ret == S_OK); + updater->Update(); +} + +bool MediaTransControlsImpl::IsActive() +{ + if (controls) { + boolean enabled; + HRESULT hr; + if ((hr = controls->get_IsEnabled(&enabled)) == S_OK) { + return enabled; + } + } + return false; +} + +void MediaTransControlsImpl::ClearAll() +{ + if (updater) + updater->ClearAll(); +} + +void MediaTransControlsImpl::UpdateDuration(int64_t duration) +{ + HRESULT hr; + if (timeline) { + hr = timeline->put_EndTime(ABI::Windows::Foundation::TimeSpan{ duration * 10000 }); + ASSERT(S_OK == hr); + hr = timeline->put_MaxSeekTime(ABI::Windows::Foundation::TimeSpan{ duration * 10000 }); + ASSERT(S_OK == hr); + } + if (controls2) { + hr = controls2->UpdateTimelineProperties(timeline); + ASSERT(S_OK == hr); + } +} + +void MediaTransControlsImpl::UpdatePosition(int64_t postion) +{ + HRESULT hr; + if (timeline) { + hr = timeline->put_Position(ABI::Windows::Foundation::TimeSpan{ postion * 10000 }); + ASSERT(S_OK == hr); + } + if (controls2) { + hr = controls2->UpdateTimelineProperties(timeline); + ASSERT(S_OK == hr); + } +} + +void MediaTransControlsImpl::UpdateSpeed(float speed) +{ + if (controls2) { + auto ret = controls2->put_PlaybackRate(speed); + ASSERT(ret == S_OK); + } +} + +void MediaTransControlsImpl::UpdateControls(MediaPlaybackStatus status) +{ + if (controls) + controls->put_PlaybackStatus(status); +} + +void MediaTransControlsImpl::UpdateControlsMetadata(const wstring& title, const wstring& artist, const wstring& album_artist, const wstring& album_title, const vector& genres, UINT track, UINT track_count) +{ + if (updater && music) + { + HRESULT ret = 0; + ret = updater->put_Type(MediaPlaybackType::MediaPlaybackType_Music); + ASSERT(ret == S_OK); + // 标题 + ret = music->put_Title(HStringReference(title.c_str()).Get()); + ASSERT(ret == S_OK); + // 艺术家 + ret = music->put_Artist(HStringReference(artist.c_str()).Get()); + ASSERT(ret == S_OK); + // 专辑艺术家 + ret = music->put_AlbumArtist(HStringReference(album_artist.c_str()).Get()); + ASSERT(ret == S_OK); + + ComPtr p2 = nullptr; + ret = music.As(&p2); + if (p2) + { + // 专辑名 + ret = p2->put_AlbumTitle(HStringReference(album_title.c_str()).Get()); + ASSERT(ret == S_OK); + // 流派 + ComPtr> vect = nullptr; + auto ret = p2->get_Genres(vect.GetAddressOf()); + ASSERT(ret == S_OK); + if (vect) { + ret = vect->Clear(); + ASSERT(ret == S_OK); + for (const auto& s : genres) { + ret = vect->Append(HStringReference(s.c_str()).Get()); + ASSERT(ret == S_OK); + } + } + // 音轨号 + ret = p2->put_TrackNumber(track); + ASSERT(ret == S_OK); + } + + ComPtr p3 = nullptr; + ret = music.As(&p3); + if (p3) + { + // 此专辑的总音轨数 + ret = p3->put_AlbumTrackCount(track_count); + ASSERT(ret == S_OK); + } + updater->Update(); + } +} diff --git a/MusicPlayer2/MediaTransControlsImpl.h b/MusicPlayer2/MediaTransControlsImpl.h new file mode 100644 index 000000000..d7140adb4 --- /dev/null +++ b/MusicPlayer2/MediaTransControlsImpl.h @@ -0,0 +1,36 @@ +#include +#include +#include + +using ABI::Windows::Media::SystemMediaTransportControlsButton; +using ABI::Windows::Media::MediaPlaybackStatus; + +class MediaTransControlsImpl +{ +public: + MediaTransControlsImpl(HWND appWindow, + std::function ButtonCallback, + std::function SeekCallback, + std::function SetSpeedCallback + ); + ~MediaTransControlsImpl(); + + void loadThumbnailFromFile(const wstring& file_path); + void loadThumbnailFromBuff(const BYTE* content, size_t size); + void loadThumbnailFromUrl(const wstring& url); + bool IsActive(); + void ClearAll(); + void UpdateDuration(int64_t duration); + void UpdatePosition(int64_t postion); + void UpdateSpeed(float speed); + void UpdateControls(MediaPlaybackStatus status); + void UpdateControlsMetadata(const wstring& title, const wstring& artist, const wstring& album_artist, const wstring& album_title, const vector& genres, UINT track, UINT track_count); + +private: + CComPtr timeline = nullptr; + CComPtr updater = nullptr; + Microsoft::WRL::ComPtr controls = nullptr; + Microsoft::WRL::ComPtr controls2 = nullptr; + Microsoft::WRL::ComPtr music = nullptr; + EventRegistrationToken m_EventRegistrationToken{}, m_EventRegistrationToken2{}, m_EventRegistrationToken3{}; +}; diff --git a/MusicPlayer2/MenuEditCtrl.cpp b/MusicPlayer2/MenuEditCtrl.cpp index 743e9cf8a..315880a64 100644 --- a/MusicPlayer2/MenuEditCtrl.cpp +++ b/MusicPlayer2/MenuEditCtrl.cpp @@ -27,13 +27,10 @@ void CMenuEditCtrl::SetTooltopText(const CString& tooltip_text) void CMenuEditCtrl::OnBrowse() { PostMessage(WM_KILLFOCUS, 0, 0); - if (theApp.m_menu_set.m_recent_folder_playlist_menu.m_hMenu != 0) - { - CRect rect; - GetWindowRect(rect); - //ClientToScreen(rect); - theApp.m_menu_set.m_recent_folder_playlist_menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, rect.left, rect.bottom, AfxGetMainWnd()); - } + CRect rect; + GetWindowRect(rect); + //ClientToScreen(rect); + theApp.m_menu_mgr.GetMenu(MenuMgr::RecentFolderPlaylistMenu)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, rect.left, rect.bottom, AfxGetMainWnd()); } void CMenuEditCtrl::OnDrawBrowseButton(CDC* pDC, CRect rect, BOOL bIsButtonPressed, BOOL bIsButtonHot) @@ -46,7 +43,7 @@ void CMenuEditCtrl::OnDrawBrowseButton(CDC* pDC, CRect rect, BOOL bIsButtonPress //使用双缓冲绘图 CDrawDoubleBuffer drawDoubleBuffer(pDC, rect); CDrawCommon drawer; - drawer.Create(drawDoubleBuffer.GetMemDC(), this); + drawer.Create(drawDoubleBuffer.GetMemDC()); CRect rc_draw{ rect }; rc_draw.MoveToXY(0, 0); @@ -85,7 +82,8 @@ void CMenuEditCtrl::OnDrawBrowseButton(CDC* pDC, CRect rect, BOOL bIsButtonPress CPoint icon_top_left; icon_top_left.x = rc_draw.left + (rc_draw.Width() - icon_size.cx) / 2; icon_top_left.y = rc_draw.top + (rc_draw.Height() - icon_size.cy) / 2; - drawer.DrawIcon(theApp.m_icon_set.expand.GetIcon(true), icon_top_left, icon_size); + HICON hIcon = theApp.m_icon_mgr.GetHICON(IconMgr::IconType::IT_Triangle_Down, IconMgr::IconStyle::IS_OutlinedDark, IconMgr::IconSize::IS_DPI_16); + drawer.DrawIcon(hIcon, icon_top_left, icon_size); } diff --git a/MusicPlayer2/MenuMgr.cpp b/MusicPlayer2/MenuMgr.cpp new file mode 100644 index 000000000..f39cc7f07 --- /dev/null +++ b/MusicPlayer2/MenuMgr.cpp @@ -0,0 +1,925 @@ +#include "stdafx.h" +#include "MusicPlayer2.h" +#include "MenuMgr.h" +#include "WinVersionHelper.h" + + +class MenuMgr::MenuBase +{ +public: + MenuBase(MenuMgr* pMenuMgr, MenuMgr::MenuType menu_type) + : m_pMenuMgr(pMenuMgr), m_menu_type(menu_type) {} + ~MenuBase() {} + + void CreateMenu(bool is_popup, bool add_accelerator) + { + m_add_accelerator = add_accelerator; + if (is_popup) + m_menu.CreatePopupMenu(); + else + m_menu.CreateMenu(); + } + + void AppendItem(UINT wID, const wstring& id_text, IconMgr::IconType icon_type = IconMgr::IT_NO_ICON, const wchar_t* text = nullptr) + { + wstring menu_text; // mii使用其内部数据指针,此对象需要有效到api完成 + MENUITEMINFO mii = { sizeof(mii) }; + mii.fMask = MIIM_ID | MIIM_STRING | MIIM_FTYPE; + mii.wID = wID; + if (id_text.empty() && text != nullptr) // 空id_text的话直接使用参数text做正文(给UpdateMenu开的后门) + mii.dwTypeData = const_cast(text); + else + { + menu_text = theApp.m_str_table.LoadMenuText(MenuMgr::GetMenuNameStr(m_menu_type), id_text); + if (text != nullptr) // 由参数直接指定的快捷键优先级更高 + { + menu_text.append(L"\t").append(text); + } + else if (m_add_accelerator) // 如果CreateMenu时要求自动附加Accelerator快捷键描述 + { + wstring shortcut = theApp.m_accelerator_res.GetShortcutDescriptionById(wID); + if (!shortcut.empty()) + menu_text += L'\t' + shortcut; + } + mii.dwTypeData = const_cast(menu_text.c_str()); + } +#ifndef COMPILE_IN_WIN_XP + if (HBITMAP hBmp = m_pMenuMgr->GetMenuBitmapHandle(icon_type)) + { + mii.fMask |= MIIM_BITMAP; + mii.hbmpItem = hBmp; + } +#endif + m_menu.InsertMenuItemW(m_end_pos++, &mii, TRUE); + } + + void AppendSubMenu(MenuMgr::MenuType sub_menu_type, IconMgr::IconType icon_type = IconMgr::IT_NO_ICON) + { + MENUITEMINFO mii = { sizeof(mii) }; + mii.fMask = MIIM_STRING | MIIM_SUBMENU | MIIM_FTYPE; + mii.hSubMenu = m_pMenuMgr->GetSafeHmenu(sub_menu_type); + wstring menu_text = theApp.m_str_table.LoadMenuText(MenuMgr::GetMenuNameStr(m_menu_type), MenuMgr::GetMenuNameStr(sub_menu_type)); + mii.dwTypeData = const_cast(menu_text.c_str()); +#ifndef COMPILE_IN_WIN_XP + if (HBITMAP hBmp = m_pMenuMgr->GetMenuBitmapHandle(icon_type)) + { + mii.fMask |= MIIM_BITMAP; + mii.hbmpItem = hBmp; + } +#endif + m_menu.InsertMenuItemW(m_end_pos++, &mii, TRUE); + } + + void AppendSeparator() + { + m_menu.AppendMenuW(MF_SEPARATOR); + m_end_pos++; + } + + void SetDefaultItem() + { + ASSERT(m_end_pos > 0); + m_menu.SetDefaultItem(m_end_pos - 1, TRUE); + } + + void UpdateMenu(const vector& items) + { + ASSERT(m_update_pos != -1); + static wstring empty{ L"" }; + // 将items插入菜单中m_update_pos位置,会替换掉上次设置的内容(此方法不能为一个菜单更新两段内容) + int bk_org_cnt = m_end_pos; // m_end_pos为菜单初始化后的初始项目数 + m_end_pos = m_update_pos; // 也是新项目的插入点 + int cnt = m_menu.GetMenuItemCount() - bk_org_cnt; + while (cnt--) // 删除旧的外部提供菜单项 + m_menu.DeleteMenu(m_update_pos, MF_BYPOSITION); // DeleteMenu如果用于移除子菜单项会销毁子菜单句柄 + for (const auto& item : items) // 插入新的外部提供菜单项 + { + if (item.id != NULL) + AppendItem(item.id, empty, item.icon_type, item.text.c_str()); + else + AppendSeparator(); + } + m_end_pos = bk_org_cnt; // 恢复为初始项目数 + // 这里有一点小问题,如果不销毁重建菜单句柄那么菜单会记忆其所需过的文本宽度,也就是不会变窄(至少我不知道怎样做) + // 销毁重建会使得这里的共享子菜单机制不能正常工作 + } + + MenuMgr::MenuType GetMenuType() const { return m_menu_type; } + void SetUpdatePos() { m_update_pos = m_end_pos; } + + CMenu m_menu; +private: + MenuMgr* m_pMenuMgr; + MenuMgr::MenuType m_menu_type; + int m_end_pos{ 0 }; + int m_update_pos{ -1 }; + bool m_add_accelerator{ false }; // AppendItem是否自动根据命令ID附加加速键列表中的快捷键文本 +}; + +MenuMgr::MenuMgr() +{ +} + +MenuMgr::~MenuMgr() +{ +} + +typedef DWORD ARGB; + +HBITMAP MenuMgr::GetMenuBitmapHandle(IconMgr::IconType icon_type) +{ + if (auto pBitmap = GetMenuBitmap(icon_type)) + return static_cast(pBitmap->GetSafeHandle()); + return NULL; +} + +const CBitmap* MenuMgr::GetMenuBitmap(IconMgr::IconType icon_type) +{ + if (icon_type == IconMgr::IconType::IT_NO_ICON) + return nullptr; + + HICON hIcon = theApp.m_icon_mgr.GetHICON(icon_type, IconMgr::IS_OutlinedDark, IconMgr::IconSize::IS_DPI_16); + // 取得默认图标尺寸(应该与GetSystemMetrics(SM_CXSMICON/SM_CYSMICON)相同) + auto[width, height] = IconMgr::GetIconSize(IconMgr::IconSize::IS_DPI_16); + + if (m_icon_bitmap_map[hIcon].GetSafeHandle()) // 已有bitmap时不再二次转换 + return &m_icon_bitmap_map[hIcon]; + + // 创建一个带Alpha通道的DIB节 + BITMAPINFO bmi{}; + bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmi.bmiHeader.biWidth = width; + bmi.bmiHeader.biHeight = -height; // 使用负高度以保证DIB的顶向下的排列 + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = 32; // 每像素32位,带Alpha通道 + bmi.bmiHeader.biCompression = BI_RGB; + + void* pvBits; + HBITMAP hbm = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, &pvBits, NULL, 0); + HDC hdcMem = CreateCompatibleDC(NULL); + HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, hbm); + // 用透明背景填充位图 + BLENDFUNCTION bf = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA }; + AlphaBlend(hdcMem, 0, 0, width, height, hdcMem, 0, 0, width, height, bf); + // 将图标绘制到位图上 + DrawIconEx(hdcMem, 0, 0, hIcon, width, height, 0, NULL, DI_NORMAL); + // 清理 + SelectObject(hdcMem, hbmOld); + DeleteDC(hdcMem); + + m_icon_bitmap_map[hIcon].Attach(hbm); + + return &m_icon_bitmap_map[hIcon]; +} + +void MenuMgr::UpdateMenu(MenuType menu_type, const vector& items) +{ + MenuBase& menu = GetMenuBase(menu_type); + menu.UpdateMenu(items); +} + +HMENU MenuMgr::GetSafeHmenu(MenuType menu_type) +{ + return GetMenuBase(menu_type).m_menu.GetSafeHmenu(); +} + +CMenu* MenuMgr::GetMenu(MenuType menu_type) +{ + return &GetMenuBase(menu_type).m_menu; +} + +MenuMgr::MenuBase& MenuMgr::GetMenuBase(MenuType menu_type) +{ + if (m_menus[menu_type] != nullptr) + { + // 此断言失败说明有代码错误销毁了它之前得到的菜单句柄,菜单句柄生命周期由MenuBase对象负责,其他位置只能使用 + ASSERT(m_menus[menu_type]->m_menu.GetSafeHmenu()); + return *m_menus[menu_type]; + } + m_menus[menu_type] = std::make_unique(this, menu_type); + CreateMenu(*m_menus[menu_type]); // 内部创建子菜单时会使用MenuBase构造得到的this指针调用MenuMgr::GetSafeHmenu递归 + return *m_menus[menu_type]; +} + +const wchar_t* MenuMgr::GetMenuNameStr(MenuMgr::MenuType menu_type) +{ + // 这里记录菜单在language.ini的键名,当需要同样翻译的不同菜单时(比如是否为其附加全局快捷键) + // 可以为不同的菜单枚举使用相同的键名以复用相同的翻译字符串(建议仅为子集关系的菜单这样做) + switch (menu_type) + { + case MenuMgr::MainPopupMenu: + return L"MAIN_POP"; + case MenuMgr::MainMenu: + return L"MAIN"; + case MenuMgr::MainFileMenu: + return L"MAIN_FILE"; + case MenuMgr::MainPlayCtrlMenu: + return L"MAIN_PLAYCTRL"; + case MenuMgr::MainPlayCtrlRepeatModeMenu: + return L"MAIN_PLAYCTRL_REPEAT_MODE"; + case MenuMgr::MainPlayCtrlAbRepeatMenu: + return L"MAIN_PLAYCTRL_AB"; + case MenuMgr::MainPlaylistMenu: + return L"MAIN_PLAYLIST"; + case MenuMgr::MainPlaylistAddMenu: + return L"MAIN_PLAYLIST_ADD"; + case MenuMgr::MainPlaylistDelMenu: + return L"MAIN_PLAYLIST_DEL"; + case MenuMgr::MainPlaylistSortMenu: + return L"MAIN_PLAYLIST_SORT"; + case MenuMgr::MainPlaylistDispModeMenu: + return L"MAIN_PLAYLIST_DISP_MODE"; + case MenuMgr::MainLyricMenu: + return L"MAIN_LRC"; + case MenuMgr::MainLrcChConvMenu: + return L"MAIN_LRC_CH_CONV"; + case MenuMgr::MainLrcInnerLrcMenu: + return L"MAIN_LRC_INNER_LRC"; + case MenuMgr::MainViewMenu: + return L"MAIN_VIEW"; + case MenuMgr::MainViewSwitchUiMenu: + return L"MAIN_VIEW_SWITCH_UI"; + case MenuMgr::MainToolMenu: + return L"MAIN_TOOL"; + case MenuMgr::MainToolCreateShortcutMenu: + return L"MAIN_TOOL_SHORTCUT"; + case MenuMgr::MainToolAlbumCoverMenu: + return L"MAIN_TOOL_ALBUM_COVER"; + case MenuMgr::MainToolDelCurPlayingMenu: + return L"MAIN_TOOL_DEL_CUR_PLAYING"; + case MenuMgr::MainHelpMenu: + return L"MAIN_HELP"; + case MenuMgr::PlaylistToolBarMenu: + return L"PLAYLIST_TOOLBAR"; + case MenuMgr::PlaylistToolBarListMenu: + return L"PLAYLIST_TOOLBAR_LIST"; + case MenuMgr::PlaylistToolBarEditMenu: + return L"PLAYLIST_TOOLBAR_EDIT"; + case MenuMgr::PlaylistToolBarFolderMenu: + return L"PLAYLIST_TOOLBAR_FOLDER"; + case MenuMgr::MainAreaMenu: + return L"MAIN_AREA"; + case MenuMgr::MainAreaLrcMenu: + return L"MAIN_LRC"; + case MenuMgr::MainAreaPlaylistBtnMenu: + return L"MAIN_AREA_PLAYLIST_BTN"; + case MenuMgr::DlrcMenu: + return L"DLRC"; + case MenuMgr::DlrcDefMenu: + return L"DLRC_DEFAULT_STYLE"; + case MenuMgr::RecentFolderPlaylistMenu: + return L"RECENT_FOLDER_PLAYLIST"; + case MenuMgr::PlaylistMenu: + return L"PLAYLIST"; + case MenuMgr::RateMenu: + return L"RATE"; + case MenuMgr::AddToPlaylistMenu: + return L"ADD_TO_PLAYLIST"; + case MenuMgr::MiniAreaMenu: + return L"MINI_AREA"; + case MenuMgr::MiniModeSwitchUiMenu: + return L"MINI_SWITCH_UI"; + case MenuMgr::NotifyMenu: + return L"NOTIFY"; + case MenuMgr::LibSetPathMenu: + return L"LIB_SET_PATH"; + case MenuMgr::LibPlaylistMenu: + return L"LIB_PLAYLIST"; + case MenuMgr::LibLeftMenu: + return L"LIB_LEFT"; + case MenuMgr::LibRightMenu: + return L"LIB_RIGHT"; + case MenuMgr::LeMenu: + return L"LE"; + case MenuMgr::LeFileMenu: + return L"LE_FILE"; + case MenuMgr::LeEditMenu: + return L"LE_EDIT"; + case MenuMgr::LeEditChConvMenu: + return L"LE_EDIT_CH_CONV"; + case MenuMgr::LeEditTagDislocMenu: + return L"LE_EDIT_TAG_DISLOC"; + case MenuMgr::LePlayCtrlMenu: + return L"LE_PLAY_CTRL"; + case MenuMgr::FcListMenu: + return L"FC_LIST"; + case MenuMgr::LdListMenu: + return L"LD_LIST"; + case MenuMgr::OptDlrcDefStyleMenu: + return L"OPT_DLRC_DEFAULT_STYLE"; + case MenuMgr::OptDlrcModDefStyleMenu: + return L"OPT_DLRC_MOD_DEF_STYLE"; + case MenuMgr::PropertyAdvMenu: + return L"PROPERTY_ADV"; + case MenuMgr::PropertyCoverMenu: + return L"PROPERTY_COVER"; + default: + return L""; + break; + } +} + +#define EX_ID(id) id, L#id + +void MenuMgr::CreateMenu(MenuBase& menu) +{ + // git log 47698b win11下使用复选功能的菜单项不设置图标 + static bool is_win11OrLater = CWinVersionHelper::IsWindows11OrLater(); + switch (menu.GetMenuType()) + { + case MenuMgr::MainPopupMenu: + menu.CreateMenu(true, true); + menu.AppendSubMenu(MainFileMenu, IconMgr::IconType::IT_Folder); + menu.AppendSubMenu(MainPlayCtrlMenu, IconMgr::IconType::IT_Play); + menu.AppendSubMenu(MainPlaylistMenu, IconMgr::IconType::IT_Playlist); + menu.AppendSubMenu(MainLyricMenu, IconMgr::IconType::IT_Lyric); + menu.AppendSubMenu(MainViewMenu, IconMgr::IconType::IT_Playlist_Dock); + menu.AppendSubMenu(MainToolMenu, IconMgr::IconType::IT_Setting); + menu.AppendSubMenu(MainHelpMenu, IconMgr::IconType::IT_Help); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_MENU_EXIT), IconMgr::IconType::IT_Exit); +#ifdef _DEBUG + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_TEST)); + menu.AppendItem(EX_ID(ID_TEST_DIALOG)); +#endif + break; + case MenuMgr::MainMenu: + menu.CreateMenu(false, true); + menu.AppendSubMenu(MainFileMenu); + menu.AppendSubMenu(MainPlayCtrlMenu); + menu.AppendSubMenu(MainPlaylistMenu); + menu.AppendSubMenu(MainLyricMenu); + menu.AppendSubMenu(MainViewMenu); + menu.AppendSubMenu(MainToolMenu); + menu.AppendSubMenu(MainHelpMenu); + break; + case MenuMgr::MainFileMenu: + menu.CreateMenu(true, true); + menu.AppendItem(EX_ID(ID_FILE_OPEN), IconMgr::IconType::IT_Music); + menu.AppendItem(EX_ID(ID_FILE_OPEN_FOLDER), IconMgr::IconType::IT_Folder); + menu.AppendItem(EX_ID(ID_FILE_OPEN_URL), IconMgr::IconType::IT_Link); + menu.AppendItem(EX_ID(ID_FILE_OPEN_PLAYLIST), IconMgr::IconType::IT_Playlist); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_MENU_EXIT), IconMgr::IconType::IT_Exit); + break; + case MenuMgr::MainPlayCtrlMenu: + menu.CreateMenu(true, true); + menu.AppendItem(EX_ID(ID_PLAY_PAUSE), IconMgr::IconType::IT_Play_Pause); + menu.AppendItem(EX_ID(ID_STOP), IconMgr::IconType::IT_Stop); + menu.AppendItem(EX_ID(ID_PREVIOUS), IconMgr::IconType::IT_Previous); + menu.AppendItem(EX_ID(ID_NEXT), IconMgr::IconType::IT_Next); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_REW), IconMgr::IconType::IT_Rewind); + menu.AppendItem(EX_ID(ID_FF), IconMgr::IconType::IT_Fast_Forward); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_SPEED_UP), IconMgr::IconType::IT_Speed_Up); + menu.AppendItem(EX_ID(ID_SLOW_DOWN), IconMgr::IconType::IT_Slow_Down); + menu.AppendItem(EX_ID(ID_ORIGINAL_SPEED)); + menu.AppendSeparator(); + menu.AppendSubMenu(MainPlayCtrlRepeatModeMenu); + menu.AppendSubMenu(MainPlayCtrlAbRepeatMenu); + break; + case MenuMgr::MainPlayCtrlRepeatModeMenu: + menu.CreateMenu(true, false); + menu.AppendItem(EX_ID(ID_PLAY_ORDER), IconMgr::IconType::IT_Play_Order); + menu.AppendItem(EX_ID(ID_PLAY_SHUFFLE), IconMgr::IconType::IT_Play_Shuffle); + menu.AppendItem(EX_ID(ID_PLAY_RANDOM), IconMgr::IconType::IT_Play_Random); + menu.AppendItem(EX_ID(ID_LOOP_PLAYLIST), IconMgr::IconType::IT_Loop_Playlist); + menu.AppendItem(EX_ID(ID_LOOP_TRACK), IconMgr::IconType::IT_Loop_Track); + menu.AppendItem(EX_ID(ID_PLAY_TRACK), IconMgr::IconType::IT_Play_Track); + break; + case MenuMgr::MainPlayCtrlAbRepeatMenu: + menu.CreateMenu(true, true); + menu.AppendItem(EX_ID(ID_AB_REPEAT)); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_SET_A_POINT)); + menu.AppendItem(EX_ID(ID_SET_B_POINT)); + menu.AppendItem(EX_ID(ID_NEXT_AB_REPEAT)); + menu.AppendItem(EX_ID(ID_RESET_AB_REPEAT)); + break; + case MenuMgr::MainPlaylistMenu: + menu.CreateMenu(true, true); + menu.AppendSubMenu(MainPlaylistAddMenu, IconMgr::IconType::IT_Add); + menu.AppendSubMenu(MainPlaylistDelMenu, IconMgr::IconType::IT_Cancel); + menu.AppendItem(EX_ID(ID_RELOAD_PLAYLIST), IconMgr::IconType::IT_Loop_Playlist); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_SAVE_AS_NEW_PLAYLIST), IconMgr::IconType::IT_Save); + menu.AppendItem(EX_ID(ID_SAVE_CURRENT_PLAYLIST_AS), IconMgr::IconType::IT_Save_As); + menu.AppendSeparator(); + menu.AppendSubMenu(MainPlaylistSortMenu, IconMgr::IconType::IT_Sort_Mode); + menu.AppendSubMenu(MainPlaylistDispModeMenu, IconMgr::IconType::IT_Playlist_Display_Mode); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_LOCATE_TO_CURRENT), IconMgr::IconType::IT_Locate); + break; + case MenuMgr::MainPlaylistAddMenu: + menu.CreateMenu(true, true); + menu.AppendItem(EX_ID(ID_PLAYLIST_ADD_FILE), IconMgr::IconType::IT_Music); + menu.AppendItem(EX_ID(ID_PLAYLIST_ADD_FOLDER), IconMgr::IconType::IT_Folder); + menu.AppendItem(EX_ID(ID_PLAYLIST_ADD_URL), IconMgr::IconType::IT_Link); + break; + case MenuMgr::MainPlaylistDelMenu: + menu.CreateMenu(true, true); + menu.AppendItem(EX_ID(ID_REMOVE_FROM_PLAYLIST), IconMgr::IconType::IT_Cancel); + menu.AppendItem(EX_ID(ID_DELETE_FROM_DISK)); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_EMPTY_PLAYLIST)); + menu.AppendItem(EX_ID(ID_REMOVE_SAME_SONGS)); + menu.AppendItem(EX_ID(ID_REMOVE_INVALID_ITEMS)); + break; + case MenuMgr::MainPlaylistSortMenu: + menu.CreateMenu(true, true); + menu.AppendItem(EX_ID(ID_SORT_BY_FILE)); + menu.AppendItem(EX_ID(ID_SORT_BY_PATH)); + menu.AppendItem(EX_ID(ID_SORT_BY_TITLE)); + menu.AppendItem(EX_ID(ID_SORT_BY_ARTIST)); + menu.AppendItem(EX_ID(ID_SORT_BY_ALBUM)); + menu.AppendItem(EX_ID(ID_SORT_BY_TRACK)); + menu.AppendItem(EX_ID(ID_SORT_BY_LISTEN_TIME)); + menu.AppendItem(EX_ID(ID_SORT_BY_MODIFIED_TIME)); + break; + case MenuMgr::MainPlaylistDispModeMenu: + menu.CreateMenu(true, true); + menu.AppendItem(EX_ID(ID_DISP_FILE_NAME)); + menu.AppendItem(EX_ID(ID_DISP_TITLE)); + menu.AppendItem(EX_ID(ID_DISP_ARTIST_TITLE)); + menu.AppendItem(EX_ID(ID_DISP_TITLE_ARTIST)); + break; + case MenuMgr::MainLyricMenu: + menu.CreateMenu(true, true); + menu.AppendItem(EX_ID(ID_RELOAD_LYRIC), IconMgr::IconType::IT_Loop_Playlist); + menu.AppendItem(EX_ID(ID_COPY_CURRENT_LYRIC), IconMgr::IconType::IT_Copy); + menu.AppendItem(EX_ID(ID_COPY_ALL_LYRIC)); + menu.AppendItem(EX_ID(ID_EDIT_LYRIC), IconMgr::IconType::IT_Edit); + menu.AppendSubMenu(MainLrcChConvMenu); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_SHOW_LYRIC_TRANSLATE)); + menu.AppendItem(EX_ID(ID_SHOW_DESKTOP_LYRIC)); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_LYRIC_FORWARD), IconMgr::IconType::IT_Triangle_Left); + menu.AppendItem(EX_ID(ID_LYRIC_DELAY), IconMgr::IconType::IT_Triangle_Right); + menu.AppendItem(EX_ID(ID_SAVE_MODIFIED_LYRIC), IconMgr::IconType::IT_Save); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_RELATE_LOCAL_LYRIC), IconMgr::IconType::IT_Lyric); + menu.AppendItem(EX_ID(ID_DELETE_LYRIC), IconMgr::IconType::IT_Cancel); + menu.AppendItem(EX_ID(ID_UNLINK_LYRIC), IconMgr::IconType::IT_Unlink); + menu.AppendItem(EX_ID(ID_BROWSE_LYRIC), IconMgr::IconType::IT_Folder_Explore); + menu.AppendSubMenu(MainLrcInnerLrcMenu, IconMgr::IconType::IT_Internal_Lyric); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_DOWNLOAD_LYRIC), IconMgr::IconType::IT_Download); + menu.AppendItem(EX_ID(ID_LYRIC_BATCH_DOWNLOAD), IconMgr::IconType::IT_Download_Batch); + break; + case MenuMgr::MainLrcChConvMenu: + menu.CreateMenu(true, true); + menu.AppendItem(EX_ID(ID_TRANSLATE_TO_SIMPLIFIED_CHINESE)); + menu.AppendItem(EX_ID(ID_TRANSLATE_TO_TRANDITIONAL_CHINESE)); + break; + case MenuMgr::MainLrcInnerLrcMenu: + menu.CreateMenu(true, true); + menu.AppendItem(EX_ID(ID_EMBED_LYRIC_TO_AUDIO_FILE)); + menu.AppendItem(EX_ID(ID_DELETE_LYRIC_FROM_AUDIO_FILE)); + break; + case MenuMgr::MainViewMenu: + menu.CreateMenu(true, true); + menu.AppendItem(EX_ID(ID_SHOW_PLAYLIST), is_win11OrLater ? IconMgr::IconType::IT_NO_ICON : IconMgr::IconType::IT_Playlist_Dock); + menu.AppendItem(EX_ID(ID_FLOAT_PLAYLIST), is_win11OrLater ? IconMgr::IconType::IT_NO_ICON : IconMgr::IconType::IT_Playlist_Float); + menu.AppendItem(EX_ID(ID_USE_STANDARD_TITLE_BAR)); + menu.AppendItem(EX_ID(ID_SHOW_MENU_BAR), is_win11OrLater ? IconMgr::IconType::IT_NO_ICON : IconMgr::IconType::IT_Menu); + menu.AppendItem(EX_ID(ID_ALWAYS_SHOW_STATUS_BAR)); + menu.AppendItem(EX_ID(ID_ALWAYS_ON_TOP), is_win11OrLater ? IconMgr::IconType::IT_NO_ICON : IconMgr::IconType::IT_Pin); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_MINI_MODE), IconMgr::IconType::IT_Mini_On); + menu.AppendItem(EX_ID(ID_FULL_SCREEN), IconMgr::IconType::IT_Full_Screen_On); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_DARK_MODE), IconMgr::IconType::IT_Dark_Mode_On); + menu.AppendSubMenu(MainViewSwitchUiMenu, IconMgr::IconType::IT_Skin); + break; + case MenuMgr::MainViewSwitchUiMenu: + menu.CreateMenu(true, true); + menu.AppendItem(EX_ID(ID_SWITCH_UI), IconMgr::IconType::IT_Skin); + menu.AppendSeparator(); + menu.SetUpdatePos(); // 设置Update插入点 + break; + case MenuMgr::MainToolMenu: + menu.CreateMenu(true, true); + menu.AppendItem(EX_ID(ID_MEDIA_LIB), IconMgr::IconType::IT_Media_Lib); + menu.AppendItem(EX_ID(ID_FIND), IconMgr::IconType::IT_Find); + menu.AppendItem(EX_ID(ID_EXPLORE_PATH), IconMgr::IconType::IT_Folder_Explore); + menu.AppendItem(EX_ID(ID_SONG_INFO), IconMgr::IconType::IT_Info); + menu.AppendItem(EX_ID(ID_EQUALIZER), IconMgr::IconType::IT_Equalizer); + menu.AppendItem(EX_ID(ID_FORMAT_CONVERT1), IconMgr::IconType::IT_Convert); + menu.AppendItem(EX_ID(ID_CURRENT_EXPLORE_ONLINE), IconMgr::IconType::IT_Online); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_RE_INI_BASS), IconMgr::IconType::IT_Loop_Playlist); + menu.AppendSubMenu(MainToolCreateShortcutMenu, IconMgr::IconType::IT_Shortcut); + menu.AppendSeparator(); + menu.AppendSubMenu(MainToolAlbumCoverMenu, IconMgr::IconType::IT_Album_Cover); + menu.AppendSubMenu(MainToolDelCurPlayingMenu, IconMgr::IconType::IT_Cancel); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_LISTEN_STATISTICS), IconMgr::IconType::IT_Statistics); + menu.AppendItem(EX_ID(ID_TOOL_FILE_RELATE), IconMgr::IconType::IT_File_Relate); + menu.AppendItem(EX_ID(ID_OPTION_SETTINGS), IconMgr::IconType::IT_Setting); + break; + case MenuMgr::MainToolCreateShortcutMenu: + menu.CreateMenu(true, true); + menu.AppendItem(EX_ID(ID_CREATE_DESKTOP_SHORTCUT)); + menu.AppendItem(EX_ID(ID_CREATE_PLAY_SHORTCUT)); + menu.AppendItem(EX_ID(ID_CREATE_MINI_MODE_SHORT_CUT)); + break; + case MenuMgr::MainToolAlbumCoverMenu: + menu.CreateMenu(true, true); + menu.AppendItem(EX_ID(ID_DOWNLOAD_ALBUM_COVER), IconMgr::IconType::IT_Download); + menu.AppendItem(EX_ID(ID_ALBUM_COVER_SAVE_AS), IconMgr::IconType::IT_Save_As); + menu.AppendItem(EX_ID(ID_DELETE_ALBUM_COVER), IconMgr::IconType::IT_Cancel); + menu.AppendItem(EX_ID(ID_ALBUM_COVER_INFO), IconMgr::IconType::IT_Album_Cover); + break; + case MenuMgr::MainToolDelCurPlayingMenu: + menu.CreateMenu(true, true); + menu.AppendItem(EX_ID(ID_REMOVE_CURRENT_FROM_PLAYLIST)); + menu.AppendItem(EX_ID(ID_DELETE_CURRENT_FROM_DISK)); + break; + case MenuMgr::MainHelpMenu: + menu.CreateMenu(true, true); + menu.AppendItem(EX_ID(ID_HELP), IconMgr::IconType::IT_Help, L"F1"); + menu.AppendItem(EX_ID(ID_ONLINE_HELP)); + menu.AppendItem(EX_ID(ID_HELP_FAQ)); + menu.AppendItem(EX_ID(ID_HELP_CUSTOM_UI)); + menu.AppendItem(EX_ID(ID_HELP_UPDATE_LOG)); + menu.AppendItem(EX_ID(ID_SUPPORTED_FORMAT)); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_APP_ABOUT), IconMgr::IconType::IT_App); + break; + case MenuMgr::PlaylistToolBarMenu: + menu.CreateMenu(true, true); + menu.AppendSubMenu(MainPlaylistAddMenu, IconMgr::IconType::IT_Add); + menu.AppendSubMenu(MainPlaylistDelMenu, IconMgr::IconType::IT_Cancel); + menu.AppendSubMenu(MainPlaylistSortMenu, IconMgr::IconType::IT_Sort_Mode); + menu.AppendSubMenu(PlaylistToolBarListMenu, IconMgr::IconType::IT_Playlist); + menu.AppendSubMenu(PlaylistToolBarEditMenu, IconMgr::IconType::IT_Edit); + menu.AppendSubMenu(PlaylistToolBarFolderMenu, IconMgr::IconType::IT_Folder); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_LOCATE_TO_CURRENT), IconMgr::IconType::IT_Locate); + break; + case MenuMgr::PlaylistToolBarListMenu: + menu.CreateMenu(true, true); + menu.AppendItem(EX_ID(ID_RELOAD_PLAYLIST), IconMgr::IconType::IT_Loop_Playlist); + menu.AppendItem(EX_ID(ID_SAVE_AS_NEW_PLAYLIST), IconMgr::IconType::IT_Save); + menu.AppendItem(EX_ID(ID_SAVE_CURRENT_PLAYLIST_AS), IconMgr::IconType::IT_Save_As); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_PLAYLIST_FIX_PATH_ERROR), IconMgr::IconType::IT_Fix); + menu.AppendSubMenu(MainPlaylistDispModeMenu, IconMgr::IconType::IT_Playlist_Display_Mode); + menu.AppendItem(EX_ID(ID_PLAYLIST_OPTIONS), IconMgr::IconType::IT_Setting); + break; + case MenuMgr::PlaylistToolBarEditMenu: + menu.CreateMenu(true, true); + menu.AppendSubMenu(AddToPlaylistMenu, IconMgr::IconType::IT_Add); + menu.AppendItem(EX_ID(ID_COPY_FILE_TO)); + menu.AppendItem(EX_ID(ID_MOVE_FILE_TO)); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_MOVE_PLAYLIST_ITEM_UP)); + menu.AppendItem(EX_ID(ID_MOVE_PLAYLIST_ITEM_DOWN)); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_PLAYLIST_SELECT_ALL)); + menu.AppendItem(EX_ID(ID_PLAYLIST_SELECT_NONE)); + menu.AppendItem(EX_ID(ID_PLAYLIST_SELECT_REVERT)); + break; + case MenuMgr::PlaylistToolBarFolderMenu: + menu.CreateMenu(true, true); + menu.AppendItem(EX_ID(ID_FILE_OPEN_FOLDER), IconMgr::IconType::IT_Folder); + menu.AppendItem(EX_ID(ID_CONTAIN_SUB_FOLDER)); + break; + case MenuMgr::MainAreaMenu: + menu.CreateMenu(true, true); + menu.AppendItem(EX_ID(ID_SONG_INFO), IconMgr::IconType::IT_Info); + menu.AppendSubMenu(MainPlayCtrlRepeatModeMenu); + menu.AppendSubMenu(AddToPlaylistMenu, IconMgr::IconType::IT_Add); + menu.AppendSubMenu(RateMenu, IconMgr::IconType::IT_Star); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_MEDIA_LIB), IconMgr::IconType::IT_Media_Lib); + menu.AppendItem(EX_ID(ID_FIND), IconMgr::IconType::IT_Find); + menu.AppendItem(EX_ID(ID_EXPLORE_PATH), IconMgr::IconType::IT_Folder_Explore); + menu.AppendItem(EX_ID(ID_EQUALIZER), IconMgr::IconType::IT_Equalizer); + menu.AppendItem(EX_ID(ID_CURRENT_EXPLORE_ONLINE), IconMgr::IconType::IT_Online); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_DOWNLOAD_ALBUM_COVER), IconMgr::IconType::IT_Download); + menu.AppendItem(EX_ID(ID_ALBUM_COVER_SAVE_AS), IconMgr::IconType::IT_Save_As); + menu.AppendItem(EX_ID(ID_DELETE_ALBUM_COVER), IconMgr::IconType::IT_Cancel); + menu.AppendItem(EX_ID(ID_ALWAYS_USE_EXTERNAL_ALBUM_COVER)); + menu.AppendItem(EX_ID(ID_ALBUM_COVER_INFO), IconMgr::IconType::IT_Album_Cover); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_VIEW_ARTIST), IconMgr::IconType::IT_Artist); + menu.AppendItem(EX_ID(ID_VIEW_ALBUM), IconMgr::IconType::IT_Album); + menu.AppendSeparator(); + menu.AppendSubMenu(MainViewSwitchUiMenu, IconMgr::IconType::IT_Skin); + menu.AppendItem(EX_ID(ID_OPTION_SETTINGS), IconMgr::IconType::IT_Setting); + break; + case MenuMgr::MainAreaLrcMenu: + menu.CreateMenu(true, true); + menu.AppendItem(EX_ID(ID_RELOAD_LYRIC), IconMgr::IconType::IT_Loop_Playlist); + menu.AppendItem(EX_ID(ID_COPY_CURRENT_LYRIC), IconMgr::IconType::IT_Copy); + menu.AppendItem(EX_ID(ID_COPY_ALL_LYRIC)); + menu.AppendItem(EX_ID(ID_EDIT_LYRIC), IconMgr::IconType::IT_Edit); + menu.AppendSubMenu(MainLrcChConvMenu); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_SHOW_LYRIC_TRANSLATE)); + menu.AppendItem(EX_ID(ID_SHOW_DESKTOP_LYRIC)); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_LYRIC_FORWARD), IconMgr::IconType::IT_Triangle_Left); + menu.AppendItem(EX_ID(ID_LYRIC_DELAY), IconMgr::IconType::IT_Triangle_Right); + menu.AppendItem(EX_ID(ID_SAVE_MODIFIED_LYRIC), IconMgr::IconType::IT_Save); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_RELATE_LOCAL_LYRIC), IconMgr::IconType::IT_Lyric); + menu.AppendItem(EX_ID(ID_DELETE_LYRIC), IconMgr::IconType::IT_Cancel); + menu.AppendItem(EX_ID(ID_UNLINK_LYRIC), IconMgr::IconType::IT_Unlink); + menu.AppendItem(EX_ID(ID_BROWSE_LYRIC), IconMgr::IconType::IT_Folder_Explore); + menu.AppendSubMenu(MainLrcInnerLrcMenu, IconMgr::IconType::IT_Internal_Lyric); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_DOWNLOAD_LYRIC), IconMgr::IconType::IT_Download); + menu.AppendItem(EX_ID(ID_LYRIC_BATCH_DOWNLOAD), IconMgr::IconType::IT_Download_Batch); + menu.AppendSeparator(); + menu.AppendSubMenu(MainViewSwitchUiMenu, IconMgr::IconType::IT_Skin); + menu.AppendItem(EX_ID(ID_OPTION_SETTINGS), IconMgr::IconType::IT_Setting); + break; + case MenuMgr::MainAreaPlaylistBtnMenu: + menu.CreateMenu(true, false); + menu.AppendItem(EX_ID(ID_DOCKED_PLAYLIST)); + menu.AppendItem(EX_ID(ID_FLOATED_PLAYLIST)); + break; + case MenuMgr::DlrcMenu: + menu.CreateMenu(true, true); + menu.AppendItem(EX_ID(ID_PLAY_PAUSE), IconMgr::IconType::IT_Play_Pause); + menu.AppendItem(EX_ID(ID_STOP), IconMgr::IconType::IT_Stop); + menu.AppendItem(EX_ID(ID_PREVIOUS), IconMgr::IconType::IT_Previous); + menu.AppendItem(EX_ID(ID_NEXT), IconMgr::IconType::IT_Next); + menu.AppendSubMenu(MainPlayCtrlRepeatModeMenu); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_SHOW_MAIN_WINDOW)); + menu.AppendItem(EX_ID(ID_LYRIC_DISPLAYED_DOUBLE_LINE), IconMgr::IconType::IT_Double_Line); + menu.AppendItem(EX_ID(ID_LYRIC_BACKGROUND_PENETRATE), IconMgr::IconType::IT_Skin); + menu.AppendItem(EX_ID(ID_LOCK_DESKTOP_LRYIC), IconMgr::IconType::IT_Lock); + menu.AppendSubMenu(DlrcDefMenu, IconMgr::IconType::IT_Media_Lib); + menu.AppendItem(EX_ID(ID_OPTION_SETTINGS), IconMgr::IconType::IT_Setting); + menu.AppendItem(EX_ID(ID_CLOSE_DESKTOP_LYRIC), IconMgr::IconType::IT_Cancel); + break; + case MenuMgr::DlrcDefMenu: + menu.CreateMenu(true, true); + menu.AppendItem(EX_ID(ID_LYRIC_DEFAULT_STYLE1)); + menu.AppendItem(EX_ID(ID_LYRIC_DEFAULT_STYLE2)); + menu.AppendItem(EX_ID(ID_LYRIC_DEFAULT_STYLE3)); + break; + case MenuMgr::RecentFolderPlaylistMenu: + menu.CreateMenu(true, false); + menu.SetUpdatePos(); // 设置Update插入点 + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_MEDIA_LIB), IconMgr::IconType::IT_Media_Lib); + break; + case MenuMgr::PlaylistMenu: + menu.CreateMenu(true, true); + menu.AppendItem(EX_ID(ID_PLAY_ITEM), IconMgr::IconType::IT_Play); + menu.SetDefaultItem(); + menu.AppendItem(EX_ID(ID_PLAY_AS_NEXT), IconMgr::IconType::IT_Play_As_Next); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_EXPLORE_ONLINE), IconMgr::IconType::IT_Online); + menu.AppendItem(EX_ID(ID_FORMAT_CONVERT), IconMgr::IconType::IT_Convert); + menu.AppendSubMenu(RateMenu, IconMgr::IconType::IT_Star); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_RELOAD_PLAYLIST), IconMgr::IconType::IT_Loop_Playlist); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_REMOVE_FROM_PLAYLIST), IconMgr::IconType::IT_Cancel); + menu.AppendItem(EX_ID(ID_DELETE_FROM_DISK)); + menu.AppendSeparator(); + menu.AppendSubMenu(AddToPlaylistMenu, IconMgr::IconType::IT_Add); + menu.AppendItem(EX_ID(ID_COPY_FILE_TO)); + menu.AppendItem(EX_ID(ID_MOVE_FILE_TO)); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_MOVE_PLAYLIST_ITEM_UP)); + menu.AppendItem(EX_ID(ID_MOVE_PLAYLIST_ITEM_DOWN)); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_PLAYLIST_VIEW_ARTIST), IconMgr::IconType::IT_Artist); + menu.AppendItem(EX_ID(ID_PLAYLIST_VIEW_ALBUM), IconMgr::IconType::IT_Album); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_RENAME), IconMgr::IconType::IT_Rename); + menu.AppendItem(EX_ID(ID_EXPLORE_TRACK), IconMgr::IconType::IT_Folder_Explore); + menu.AppendItem(EX_ID(ID_ITEM_PROPERTY), IconMgr::IconType::IT_Info); + break; + case MenuMgr::RateMenu: + menu.CreateMenu(true, true); + menu.AppendItem(EX_ID(ID_RATING_1)); + menu.AppendItem(EX_ID(ID_RATING_2)); + menu.AppendItem(EX_ID(ID_RATING_3)); + menu.AppendItem(EX_ID(ID_RATING_4)); + menu.AppendItem(EX_ID(ID_RATING_5)); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_RATING_NONE)); + break; + case MenuMgr::AddToPlaylistMenu: + menu.CreateMenu(true, true); + menu.AppendItem(EX_ID(ID_ADD_TO_NEW_PLAYLIST), IconMgr::IconType::IT_Add); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_ADD_TO_DEFAULT_PLAYLIST)); + menu.AppendItem(EX_ID(ID_ADD_TO_MY_FAVOURITE), IconMgr::IconType::IT_Favorite_On); + menu.SetUpdatePos(); // 设置Update插入点 + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_ADD_TO_OTHER_PLAYLIST), IconMgr::IconType::IT_Playlist); + break; + case MenuMgr::MiniAreaMenu: + menu.CreateMenu(true, true); + menu.AppendItem(EX_ID(ID_SONG_INFO), IconMgr::IconType::IT_Info); + menu.AppendSubMenu(MainPlayCtrlRepeatModeMenu); + menu.AppendSubMenu(AddToPlaylistMenu, IconMgr::IconType::IT_Add); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_DOWNLOAD_LYRIC), IconMgr::IconType::IT_Download); + menu.AppendItem(EX_ID(ID_DOWNLOAD_ALBUM_COVER), IconMgr::IconType::IT_Album_Cover); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_ADD_REMOVE_FROM_FAVOURITE), IconMgr::IconType::IT_Favorite_On); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_MEDIA_LIB), IconMgr::IconType::IT_Media_Lib); + menu.AppendItem(EX_ID(ID_FIND), IconMgr::IconType::IT_Find); + menu.AppendItem(EX_ID(ID_EXPLORE_PATH), IconMgr::IconType::IT_Folder_Explore); + menu.AppendItem(EX_ID(ID_EQUALIZER), IconMgr::IconType::IT_Equalizer); + menu.AppendItem(EX_ID(ID_OPTION_SETTINGS), IconMgr::IconType::IT_Setting); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_SHOW_PLAY_LIST), is_win11OrLater ? IconMgr::IconType::IT_NO_ICON : IconMgr::IconType::IT_Playlist, L"Ctrl+L"); + menu.AppendItem(EX_ID(ID_MINI_MODE_ALWAYS_ON_TOP), is_win11OrLater ? IconMgr::IconType::IT_NO_ICON : IconMgr::IconType::IT_Pin); + menu.AppendSubMenu(MiniModeSwitchUiMenu, IconMgr::IconType::IT_Skin); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_MINI_MIDE_MINIMIZE), IconMgr::IconType::IT_Minimize); + menu.AppendItem(EX_ID(IDOK), IconMgr::IconType::IT_Mini_Off, L"Esc"); + menu.AppendItem(EX_ID(ID_MINI_MODE_EXIT), IconMgr::IconType::IT_Exit, L"Ctrl+X"); + break; + case MenuMgr::MiniModeSwitchUiMenu: + menu.CreateMenu(true, true); + menu.AppendItem(EX_ID(ID_MINIMODE_UI_DEFAULT)); + menu.SetUpdatePos(); // 设置Update插入点 + break; + case MenuMgr::NotifyMenu: + menu.CreateMenu(true, false); + menu.AppendItem(EX_ID(ID_PLAY_PAUSE), IconMgr::IconType::IT_Play_Pause); + menu.AppendItem(EX_ID(ID_PREVIOUS), IconMgr::IconType::IT_Previous); + menu.AppendItem(EX_ID(ID_NEXT), IconMgr::IconType::IT_Next); + menu.AppendSubMenu(MainPlayCtrlRepeatModeMenu); + menu.AppendItem(EX_ID(ID_MINIMODE_RESTORE), IconMgr::IconType::IT_Mini_Off); + menu.AppendItem(EX_ID(ID_SHOW_DESKTOP_LYRIC), IconMgr::IconType::IT_Lyric); + menu.AppendItem(EX_ID(ID_LOCK_DESKTOP_LRYIC), IconMgr::IconType::IT_Lock); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_OPTION_SETTINGS), IconMgr::IconType::IT_Setting); + menu.AppendItem(EX_ID(ID_MENU_EXIT), IconMgr::IconType::IT_Exit); + break; + case MenuMgr::LibSetPathMenu: + menu.CreateMenu(true, false); + menu.AppendItem(EX_ID(ID_PLAY_PATH), IconMgr::IconType::IT_Play); + menu.SetDefaultItem(); + menu.AppendItem(EX_ID(ID_DELETE_PATH), IconMgr::IconType::IT_Cancel); + menu.AppendItem(EX_ID(ID_BROWSE_PATH), IconMgr::IconType::IT_Folder_Explore); + menu.AppendItem(EX_ID(ID_CONTAIN_SUB_FOLDER)); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_CLEAR_INVALID_PATH)); + break; + case MenuMgr::LibPlaylistMenu: + menu.CreateMenu(true, false); + menu.AppendItem(EX_ID(ID_PLAY_PLAYLIST), IconMgr::IconType::IT_Play); + menu.SetDefaultItem(); + menu.AppendItem(EX_ID(ID_RENAME_PLAYLIST), IconMgr::IconType::IT_Rename); + menu.AppendItem(EX_ID(ID_DELETE_PLAYLIST), IconMgr::IconType::IT_Cancel); + menu.AppendItem(EX_ID(ID_SAVE_AS_NEW_PLAYLIST), IconMgr::IconType::IT_Save); + menu.AppendItem(EX_ID(ID_PLAYLIST_SAVE_AS), IconMgr::IconType::IT_Save_As); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_PLAYLIST_BROWSE_FILE), IconMgr::IconType::IT_Folder_Explore); + menu.AppendItem(EX_ID(ID_PLAYLIST_FIX_PATH_ERROR), IconMgr::IconType::IT_Fix); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_NEW_PLAYLIST), IconMgr::IconType::IT_Add); + break; + case MenuMgr::LibLeftMenu: + menu.CreateMenu(true, false); + menu.AppendItem(EX_ID(ID_PLAY_ITEM), IconMgr::IconType::IT_Play); + menu.SetDefaultItem(); + menu.AppendSubMenu(AddToPlaylistMenu, IconMgr::IconType::IT_Add); + menu.AppendItem(EX_ID(ID_ADD_TO_NEW_PLAYLIST_AND_PLAY), IconMgr::IconType::IT_Play_In_Playlist); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_COPY_TEXT), IconMgr::IconType::IT_Copy); + break; + case MenuMgr::LibRightMenu: + menu.CreateMenu(true, false); + menu.AppendItem(EX_ID(ID_PLAY_ITEM), IconMgr::IconType::IT_Play); + menu.SetDefaultItem(); + menu.AppendItem(EX_ID(ID_PLAY_AS_NEXT), IconMgr::IconType::IT_Play_As_Next); + menu.AppendItem(EX_ID(ID_PLAY_ITEM_IN_FOLDER_MODE), IconMgr::IconType::IT_Play_In_Folder); + menu.AppendSeparator(); + menu.AppendSubMenu(AddToPlaylistMenu, IconMgr::IconType::IT_Add); + menu.AppendItem(EX_ID(ID_ADD_TO_NEW_PLAYLIST_AND_PLAY), IconMgr::IconType::IT_Play_In_Playlist); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_EXPLORE_ONLINE), IconMgr::IconType::IT_Online); + menu.AppendItem(EX_ID(ID_FORMAT_CONVERT), IconMgr::IconType::IT_Convert); + menu.AppendItem(EX_ID(ID_EXPLORE_TRACK), IconMgr::IconType::IT_Folder_Explore); + menu.AppendItem(EX_ID(ID_DELETE_FROM_DISK), IconMgr::IconType::IT_Cancel); + menu.AppendItem(EX_ID(ID_ITEM_PROPERTY), IconMgr::IconType::IT_Info); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_COPY_TEXT), IconMgr::IconType::IT_Copy); + break; + case MenuMgr::LeMenu: + menu.CreateMenu(false, false); + menu.AppendSubMenu(LeFileMenu); + menu.AppendSubMenu(LeEditMenu); + menu.AppendSubMenu(LePlayCtrlMenu); + break; + case MenuMgr::LeFileMenu: + menu.CreateMenu(true, false); + menu.AppendItem(EX_ID(ID_LYRIC_OPEN), IconMgr::IconType::IT_Music); + menu.AppendItem(EX_ID(ID_LYRIC_SAVE), IconMgr::IconType::IT_Save, L"Ctrl+S"); + menu.AppendItem(EX_ID(ID_LYRIC_SAVE_AS), IconMgr::IconType::IT_Save_As); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(IDCANCEL), IconMgr::IconType::IT_Exit); + break; + case MenuMgr::LeEditMenu: + menu.CreateMenu(true, false); + menu.AppendItem(EX_ID(ID_LYRIC_INSERT_TAG), IconMgr::IconType::IT_Le_Tag_Insert, L"F8"); + menu.AppendItem(EX_ID(ID_LYRIC_REPLACE_TAG), IconMgr::IconType::IT_Le_Tag_Replace, L"F9"); + menu.AppendItem(EX_ID(ID_LYRIC_DELETE_TAG), IconMgr::IconType::IT_Le_Tag_Delete , L"Ctrl+Del"); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_LYRIC_FIND), IconMgr::IconType::IT_Le_Find, L"Ctrl+F"); + menu.AppendItem(EX_ID(ID_LYRIC_REPLACE), IconMgr::IconType::IT_Le_Replace, L"Ctrl+H"); + menu.AppendItem(EX_ID(ID_FIND_NEXT), IconMgr::IconType::IT_NO_ICON, L"F3"); + menu.AppendSeparator(); + menu.AppendSubMenu(LeEditChConvMenu); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_LRYIC_MERGE_SAME_TIME_TAG)); + menu.AppendItem(EX_ID(ID_LYRIC_SWAP_TEXT_AND_TRANSLATION)); + menu.AppendSubMenu(LeEditTagDislocMenu); + break; + case MenuMgr::LeEditChConvMenu: + menu.CreateMenu(true, false); + menu.AppendItem(EX_ID(ID_LE_TRANSLATE_TO_SIMPLIFIED_CHINESE)); + menu.AppendItem(EX_ID(ID_LE_TRANSLATE_TO_TRANDITIONAL_CHINESE)); + break; + case MenuMgr::LeEditTagDislocMenu: + menu.CreateMenu(true, false); + menu.AppendItem(EX_ID(ID_LYRIC_TIME_TAG_FORWARD)); + menu.AppendItem(EX_ID(ID_LYRIC_TIME_TAG_DELAY)); + break; + case MenuMgr::LePlayCtrlMenu: + menu.CreateMenu(true, false); + menu.AppendItem(EX_ID(ID_PLAY_PAUSE), IconMgr::IconType::IT_Play_Pause, L"Ctrl+P"); + menu.AppendItem(EX_ID(ID_REW), IconMgr::IconType::IT_Rewind, CAcceleratorRes::Key(VK_LEFT, true).ToString().c_str()); + menu.AppendItem(EX_ID(ID_FF), IconMgr::IconType::IT_Fast_Forward, CAcceleratorRes::Key(VK_RIGHT, true).ToString().c_str()); + menu.AppendItem(EX_ID(ID_SEEK_TO_CUR_LINE), IconMgr::IconType::IT_Locate, L"Ctrl+G"); + break; + case MenuMgr::FcListMenu: + menu.CreateMenu(true, false); + menu.AppendItem(EX_ID(ID_ADD_FILE), IconMgr::IconType::IT_Add); + menu.AppendItem(EX_ID(ID_CLEAR_LIST)); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_EDIT_TAG_INFO), IconMgr::IconType::IT_Edit); + menu.AppendItem(EX_ID(ID_DELETE_SELECT), IconMgr::IconType::IT_Cancel); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_MOVE_UP), IconMgr::IconType::IT_NO_ICON, CAcceleratorRes::Key(VK_UP, true).ToString().c_str()); + menu.AppendItem(EX_ID(ID_MOVE_DOWN), IconMgr::IconType::IT_NO_ICON, CAcceleratorRes::Key(VK_DOWN, true).ToString().c_str()); + break; + case MenuMgr::LdListMenu: + menu.CreateMenu(true, false); + menu.AppendItem(EX_ID(ID_LD_LYRIC_DOWNLOAD), IconMgr::IconType::IT_Download); + menu.SetDefaultItem(); + menu.AppendItem(EX_ID(ID_LD_PREVIEW)); + menu.AppendItem(EX_ID(ID_LD_LYRIC_SAVEAS), IconMgr::IconType::IT_Save_As); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_LD_COPY_TITLE)); + menu.AppendItem(EX_ID(ID_LD_COPY_ARTIST)); + menu.AppendItem(EX_ID(ID_LD_COPY_ALBUM)); + menu.AppendItem(EX_ID(ID_LD_COPY_ID)); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_LD_RELATE)); + menu.AppendItem(EX_ID(ID_LD_VIEW_ONLINE), IconMgr::IconType::IT_Online); + break; + case MenuMgr::OptDlrcDefStyleMenu: + menu.CreateMenu(true, false); + menu.AppendItem(EX_ID(ID_LYRIC_DEFAULT_STYLE1)); + menu.AppendItem(EX_ID(ID_LYRIC_DEFAULT_STYLE2)); + menu.AppendItem(EX_ID(ID_LYRIC_DEFAULT_STYLE3)); + menu.AppendSeparator(); + menu.AppendSubMenu(OptDlrcModDefStyleMenu); + break; + case MenuMgr::OptDlrcModDefStyleMenu: + menu.CreateMenu(true, false); + menu.AppendItem(EX_ID(ID_LYRIC_DEFAULT_STYLE1_MODIFY)); + menu.AppendItem(EX_ID(ID_LYRIC_DEFAULT_STYLE2_MODIFY)); + menu.AppendItem(EX_ID(ID_LYRIC_DEFAULT_STYLE3_MODIFY)); + menu.AppendSeparator(); + menu.AppendItem(EX_ID(ID_RESTORE_DEFAULT_STYLE)); + break; + case MenuMgr::PropertyAdvMenu: + menu.CreateMenu(true, false); + menu.AppendItem(EX_ID(ID_COPY_TEXT)); + menu.AppendItem(EX_ID(ID_COPY_ALL_TEXT)); + break; + case MenuMgr::PropertyCoverMenu: + menu.CreateMenu(true, false); + menu.AppendItem(EX_ID(ID_COVER_BROWSE), IconMgr::IconType::IT_Folder_Explore); + menu.AppendItem(EX_ID(ID_COVER_DELETE), IconMgr::IconType::IT_Cancel); + menu.AppendItem(EX_ID(ID_COVER_SAVE_AS), IconMgr::IconType::IT_Save_As); + menu.AppendItem(EX_ID(ID_COMPRESS_SIZE)); + break; + default: + ASSERT(false); // 参数错误或缺少case或缺少break + menu.CreateMenu(true, true); // 创建一个空的弹出菜单占位 + break; + } +} diff --git a/MusicPlayer2/MenuMgr.h b/MusicPlayer2/MenuMgr.h new file mode 100644 index 000000000..1605020e9 --- /dev/null +++ b/MusicPlayer2/MenuMgr.h @@ -0,0 +1,103 @@ +#pragma once +#include "IconMgr.h" + +class MenuMgr +{ +public: + MenuMgr(); + virtual ~MenuMgr(); + + HBITMAP GetMenuBitmapHandle(IconMgr::IconType icon_type); + const CBitmap* GetMenuBitmap(IconMgr::IconType icon_type); +private: + std::map m_icon_bitmap_map; + +public: + enum MenuType + { + MainPopupMenu, // 主窗口(弹出菜单ver)(shift+右键) + MainMenu, // 主窗口 + MainFileMenu, // 主窗口->子菜单"文件" + MainPlayCtrlMenu, // 主窗口->子菜单"播放控制" + MainPlayCtrlRepeatModeMenu, // 主窗口->子菜单"播放控制"->子菜单"循环模式" + MainPlayCtrlAbRepeatMenu, // 主窗口->子菜单"播放控制"->子菜单"AB重复" + MainPlaylistMenu, // 主窗口->子菜单"播放列表" + MainPlaylistAddMenu, // 主窗口->子菜单"播放列表"->子菜单"添加" 播放列表工具栏->添加(0) + MainPlaylistDelMenu, // 主窗口->子菜单"播放列表"->子菜单"删除" 播放列表工具栏->删除(1) + MainPlaylistSortMenu, // 主窗口->子菜单"播放列表"->子菜单"排序方式" 播放列表工具栏->排序(2) + MainPlaylistDispModeMenu, // 主窗口->子菜单"播放列表"->子菜单"播放列表显示方式" + MainLyricMenu, // 主窗口->子菜单"歌词" + MainLrcChConvMenu, // 主窗口->子菜单"歌词"->子菜单"繁简转换" + MainLrcInnerLrcMenu, // 主窗口->子菜单"歌词"->子菜单"内嵌歌词" + MainViewMenu, // 主窗口->子菜单"视图" + MainViewSwitchUiMenu, // 主窗口->子菜单"视图"->子菜单"切换界面" + MainToolMenu, // 主窗口->子菜单"工具" + MainToolCreateShortcutMenu, // 主窗口->子菜单"工具"->子菜单"创建快捷方式" + MainToolAlbumCoverMenu, // 主窗口->子菜单"工具"->子菜单"专辑封面" + MainToolDelCurPlayingMenu, // 主窗口->子菜单"工具"->子菜单"删除正在播放的曲目" + MainHelpMenu, // 主窗口->子菜单"帮助" + + PlaylistToolBarMenu, // 播放列表工具栏(弹出菜单) + PlaylistToolBarListMenu, // 播放列表工具栏->列表(3) + PlaylistToolBarEditMenu, // 播放列表工具栏->编辑(4) + PlaylistToolBarFolderMenu, // 播放列表工具栏->文件夹(5) + + MainAreaMenu, // 主界面区域菜单 + MainAreaLrcMenu, // 主界面歌词区域菜单(与MainLyricMenu共用翻译) + MainAreaPlaylistBtnMenu, // 主界面播放列表按钮 + DlrcMenu, // 桌面歌词窗口 + DlrcDefMenu, // 桌面歌词窗口->子菜单"预设方案" + RecentFolderPlaylistMenu, // MenuEditCtrl控件(最近播放文件夹/播放列表) + PlaylistMenu, // 播放列表菜单 + RateMenu, // "分级"菜单 + AddToPlaylistMenu, // "添加到播放列表"菜单 + + MiniAreaMenu, // 迷你模式区域菜单 + MiniModeSwitchUiMenu, // 迷你模式切换界面菜单 + NotifyMenu, // 系统托盘图标 + + LibSetPathMenu, // 媒体库文件夹标签页菜单 + LibPlaylistMenu, // 媒体库播放列表标签页菜单 + LibLeftMenu, // 媒体库左侧菜单 + LibRightMenu, // 媒体库右侧菜单 + + LeMenu, // 歌词编辑对话框->窗口菜单 + LeFileMenu, // 歌词编辑对话框->窗口菜单->子菜单"文件" + LeEditMenu, // 歌词编辑对话框->窗口菜单->子菜单"编辑" + LeEditChConvMenu, // 歌词编辑对话框->窗口菜单->子菜单"编辑"->子菜单"繁简转换" + LeEditTagDislocMenu, // 歌词编辑对话框->窗口菜单->子菜单"编辑"->子菜单"时间标签错位" + LePlayCtrlMenu, // 歌词编辑对话框->窗口菜单->子菜单"播放控制" + + FcListMenu, // 转换格式对话框->列表控件 + LdListMenu, // 歌词下载对话框->列表控件 + OptDlrcDefStyleMenu, // 选项设置->歌词设置->预设方案按钮 + OptDlrcModDefStyleMenu, // 选项设置->歌词设置->预设方案按钮菜单->子菜单"修改预设方案" + PropertyAdvMenu, // 属性对话框->高级标签信息标签页->列表控件 + PropertyCoverMenu, // 属性对话框->专辑封面标签页 + + MenuMax // 菜单数量 + }; + // 目前只支持更新为关联到命令的普通菜单项(默认构造表示分隔符) + struct MenuItem + { + UINT id{ NULL }; + IconMgr::IconType icon_type{ IconMgr::IT_NO_ICON }; + wstring text; + }; + // 更新菜单项 + void UpdateMenu(MenuType menu_type, const vector& items); + // 获取菜单句柄 + HMENU GetSafeHmenu(MenuType menu_type); + // 获取CMenu指针 + CMenu* GetMenu(MenuType menu_type); + // 获取菜单在 .ini 中的键名字符串 + static const wchar_t* GetMenuNameStr(MenuType menu_type); + +private: + class MenuBase; + MenuBase& GetMenuBase(MenuType menu_type); + void CreateMenu(MenuBase& menu_base); +private: + std::unique_ptr m_menus[MenuMax]; +}; + diff --git a/MusicPlayer2/MessageDlg.cpp b/MusicPlayer2/MessageDlg.cpp index ac300784d..c8cd89b6b 100644 --- a/MusicPlayer2/MessageDlg.cpp +++ b/MusicPlayer2/MessageDlg.cpp @@ -1,4 +1,4 @@ -// HelpDlg.cpp : 实现文件 +// MessageDlg.cpp: 实现文件 // #include "stdafx.h" @@ -10,69 +10,41 @@ #define MESSAGE_DLG_ICON_SIZE (theApp.DPI(32)) -IMPLEMENT_DYNAMIC(CMessageDlg, CDialog) +IMPLEMENT_DYNAMIC(CMessageDlg, CBaseDialog) -CMessageDlg::CMessageDlg(CWnd* pParent /*=NULL*/) - : CDialog(IDD_MESSAGE_DIALOG, pParent) +CMessageDlg::CMessageDlg(const wstring& dialog_name, CWnd* pParent) + : CBaseDialog(IDD_MESSAGE_DIALOG, pParent) { - + ASSERT(!dialog_name.empty()); + m_dialog_name = dialog_name; } CMessageDlg::~CMessageDlg() { } -void CMessageDlg::SetWindowTitle(LPCTSTR str) -{ - m_title = str; -} - -void CMessageDlg::SetInfoText(LPCTSTR str) -{ - m_info = str; -} - -void CMessageDlg::SetMessageText(LPCTSTR str) -{ - m_message = str; -} - -void CMessageDlg::SetLinkInfo(LPCTSTR text, LPCTSTR url) -{ - m_link_text = text; - m_link_url = url; -} - -void CMessageDlg::SetMessageIcon(HICON hIcon) -{ - m_icon = hIcon; -} - -void CMessageDlg::SetInfoStaticSize(int cx) +bool CMessageDlg::InitializeControls() { - if (m_icon != NULL && m_info_static.GetSafeHwnd() != NULL) - { - CRect rc_info{ m_rc_info }; - rc_info.left = m_rc_info.left + MESSAGE_DLG_ICON_SIZE + theApp.DPI(8); - if (cx > 0) - rc_info.right = cx; - m_info_static.MoveWindow(rc_info); - } + SetWindowTextW(m_title.c_str()); + SetDlgItemTextW(IDC_INFO_STATIC, m_info.c_str()); + SetDlgItemTextW(IDC_HELP_EDIT, m_message.c_str()); + SetDlgItemTextW(IDC_SYSLINK1, (L"" + m_link_text + L"").c_str()); + + RepositionTextBasedControls({ + { CtrlTextInfo::L1, IDC_SYSLINK1, CtrlTextInfo::W_50 }, + { CtrlTextInfo::R1, IDOK, CtrlTextInfo::W32 } + }); + return true; } void CMessageDlg::DoDataExchange(CDataExchange* pDX) { - CDialog::DoDataExchange(pDX); - DDX_Control(pDX, IDC_HELP_EDIT, m_message_edit); - DDX_Control(pDX, IDC_INFO_STATIC, m_info_static); + CBaseDialog::DoDataExchange(pDX); } -BEGIN_MESSAGE_MAP(CMessageDlg, CDialog) - ON_WM_GETMINMAXINFO() - ON_NOTIFY(NM_CLICK, IDC_SYSLINK1, &CMessageDlg::OnNMClickSyslink1) - ON_WM_PAINT() - ON_WM_SIZE() +BEGIN_MESSAGE_MAP(CMessageDlg, CBaseDialog) + ON_NOTIFY(NM_CLICK, IDC_SYSLINK1, &CMessageDlg::OnNMClickSyslink1) END_MESSAGE_MAP() @@ -81,85 +53,26 @@ END_MESSAGE_MAP() BOOL CMessageDlg::OnInitDialog() { - CDialog::OnInitDialog(); - - // TODO: 在此添加额外的初始化 - - SetIcon(AfxGetApp()->LoadIcon(IDR_MAINFRAME), FALSE); // 设置小图标 - - //获取初始时窗口的大小 - CRect rect; - GetWindowRect(rect); - m_min_size.cx = rect.Width(); - m_min_size.cy = rect.Height(); - - SetWindowText(m_title); - m_info_static.SetWindowText(m_info); - m_message_edit.SetWindowText(m_message); - - CWnd* pLinkCtrl = GetDlgItem(IDC_SYSLINK1); - if (pLinkCtrl != nullptr) - { - pLinkCtrl->ShowWindow(m_show_link_ctrl); - pLinkCtrl->SetWindowText(_T("") + m_link_text + _T("")); - } - - //设置图标的位置 - if (m_icon != NULL) - { - CRect rc_edit; - m_message_edit.GetWindowRect(rc_edit); - ScreenToClient(rc_edit); - m_icon_pos.x = rc_edit.left; - m_icon_pos.y = (rc_edit.top - MESSAGE_DLG_ICON_SIZE) / 2; - - m_info_static.GetWindowRect(m_rc_info); - ScreenToClient(m_rc_info); - SetInfoStaticSize(0); - } - - return TRUE; // return TRUE unless you set the focus to a control - // 异常: OCX 属性页应返回 FALSE -} - - -void CMessageDlg::OnGetMinMaxInfo(MINMAXINFO* lpMMI) -{ - // TODO: 在此添加消息处理程序代码和/或调用默认值 - //限制窗口最小大小 - lpMMI->ptMinTrackSize.x = m_min_size.cx; //设置最小宽度 - lpMMI->ptMinTrackSize.y = m_min_size.cy; //设置最小高度 + CBaseDialog::OnInitDialog(); - CDialog::OnGetMinMaxInfo(lpMMI); -} + // TODO: 在此添加额外的初始化 + SetIcon(IconMgr::IconType::IT_App, FALSE); // 设置小图标 + ShowDlgCtrl(IDC_SYSLINK1, !m_link_text.empty()); -void CMessageDlg::OnNMClickSyslink1(NMHDR *pNMHDR, LRESULT *pResult) -{ - // TODO: 在此添加控件通知处理程序代码 - if(!m_link_url.IsEmpty()) - ShellExecute(NULL, _T("open"), m_link_url, NULL, NULL, SW_SHOW); //打开超链接 + CWnd* pWnd = GetDlgItem(IDOK); + if (pWnd != nullptr) + pWnd->SetFocus(); - *pResult = 0; + return FALSE; // return TRUE unless you set the focus to a control + // 异常: OCX 属性页应返回 FALSE } - -void CMessageDlg::OnPaint() -{ - CPaintDC dc(this); // device context for painting - // TODO: 在此处添加消息处理程序代码 - // 不为绘图消息调用 CDialog::OnPaint() - - CDrawCommon draw; - draw.Create(&dc, this); - draw.DrawIcon(m_icon, m_icon_pos, CSize(MESSAGE_DLG_ICON_SIZE, MESSAGE_DLG_ICON_SIZE)); -} - - -void CMessageDlg::OnSize(UINT nType, int cx, int cy) +void CMessageDlg::OnNMClickSyslink1(NMHDR *pNMHDR, LRESULT *pResult) { - CDialog::OnSize(nType, cx, cy); + // TODO: 在此添加控件通知处理程序代码 + if(!m_link_url.empty()) + ShellExecute(NULL, _T("open"), m_link_url.c_str(), NULL, NULL, SW_SHOW); //打开超链接 - // TODO: 在此处添加消息处理程序代码 - SetInfoStaticSize(cx); + *pResult = 0; } diff --git a/MusicPlayer2/MessageDlg.h b/MusicPlayer2/MessageDlg.h index c157f414e..52d685b7c 100644 --- a/MusicPlayer2/MessageDlg.h +++ b/MusicPlayer2/MessageDlg.h @@ -1,57 +1,51 @@ #pragma once -#include "afxwin.h" +#include "BaseDialog.h" // CMessageDlg 对话框 -class CMessageDlg : public CDialog +class CMessageDlg : public CBaseDialog { - DECLARE_DYNAMIC(CMessageDlg) + DECLARE_DYNAMIC(CMessageDlg) public: - CMessageDlg(CWnd* pParent = NULL); // 标准构造函数 - virtual ~CMessageDlg(); - - void SetWindowTitle(LPCTSTR str); - void SetInfoText(LPCTSTR str); - void SetMessageText(LPCTSTR str); - void ShowLinkStatic(bool show = true) { m_show_link_ctrl = show; } - void SetLinkInfo(LPCTSTR text, LPCTSTR url); - void SetMessageIcon(HICON hIcon); - -// 对话框数据 + // 关于dialog_name参数,参考CBaseDialog::GetDialogName() + CMessageDlg(const wstring& dialog_name, CWnd* pParent = NULL); + virtual ~CMessageDlg(); + + // 设置窗口大小是否保存(默认不保存) + void EnableSaveDlgSize() { m_save_dlg_size = true; }; + // 设置窗口标题 + void SetWindowTitle(const wstring& str) { m_title = str; }; + // 设置描述说明文本 + void SetInfoText(const wstring& str) { m_info = str; }; + // 设置内容 + void SetMessageText(const wstring& str) { m_message = str; }; + // 仅在设置了非空text时显示此超链接控件 + void SetLinkInfo(const wstring& text, const wstring& url) { m_link_text = text; m_link_url = url; }; + + // 对话框数据 #ifdef AFX_DESIGN_TIME - enum { IDD = IDD_MESSAGE_DIALOG }; + enum { IDD = IDD_MESSAGE_DIALOG }; #endif protected: - CEdit m_message_edit; - CSize m_min_size; //窗口的最小大小 - CStatic m_info_static; - - CString m_title; - CString m_info; - CString m_message; - - CString m_link_text; - CString m_link_url; + wstring m_dialog_name{}; + bool m_save_dlg_size{ false }; // CMessageDlg默认不保存窗口大小 - HICON m_icon{}; - CPoint m_icon_pos{}; //图标的位置 - CRect m_rc_info{}; //错误信息Static控件的初始区域 - - bool m_show_link_ctrl{ false }; + wstring m_title{}; + wstring m_info{}; + wstring m_message{}; + wstring m_link_text{}; + wstring m_link_url{}; protected: - void SetInfoStaticSize(int cx); //如果设置了图标,则需要将错误信息Static控件向右移动一些 - - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 - - DECLARE_MESSAGE_MAP() + virtual CString GetDialogName() const override { return m_dialog_name.c_str(); } + virtual bool IsRememberDialogSizeEnable() const override { return m_save_dlg_size; }; + virtual bool InitializeControls() override; + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 + DECLARE_MESSAGE_MAP() public: - virtual BOOL OnInitDialog(); - afx_msg void OnGetMinMaxInfo(MINMAXINFO* lpMMI); - afx_msg void OnNMClickSyslink1(NMHDR *pNMHDR, LRESULT *pResult); - afx_msg void OnPaint(); - afx_msg void OnSize(UINT nType, int cx, int cy); + virtual BOOL OnInitDialog(); + afx_msg void OnNMClickSyslink1(NMHDR *pNMHDR, LRESULT *pResult); }; diff --git a/MusicPlayer2/MiniModeDlg.cpp b/MusicPlayer2/MiniModeDlg.cpp index 67d2be5a6..58b251bc4 100644 --- a/MusicPlayer2/MiniModeDlg.cpp +++ b/MusicPlayer2/MiniModeDlg.cpp @@ -4,7 +4,6 @@ #include "stdafx.h" #include "MusicPlayer2.h" #include "MiniModeDlg.h" -#include "afxdialogex.h" #include "MusicPlayerDlg.h" #include "MiniModeUserUi.h" #include "SongInfoHelper.h" @@ -23,7 +22,7 @@ CMiniModeDlg::CMiniModeDlg(int& item_selected, vector& items_selected, CWnd AfxRegisterClass(&wc); //初始化界面类 - m_ui_list.push_back(std::make_shared(m_ui_data, this)); + m_ui_list.push_back(std::make_shared(this, IDR_MINI_UI0)); // 默认界面 std::vector skin_files; CCommon::GetFiles(theApp.m_local_dir + L"skins\\miniMode\\*.xml", skin_files); for (const auto& file_name : skin_files) @@ -71,25 +70,6 @@ CPlayerUIBase* CMiniModeDlg::GetCurUi() return nullptr; } -void CMiniModeDlg::UpdateSongTipInfo() -{ - CString song_tip_info; - song_tip_info += CCommon::LoadText(IDS_NOW_PLAYING, _T(": ")); - song_tip_info += CPlayer::GetInstance().GetFileName().c_str(); - song_tip_info += _T("\r\n"); - song_tip_info += CCommon::LoadText(IDS_TITLE, _T(": ")); - song_tip_info += CPlayer::GetInstance().GetPlayList()[CPlayer::GetInstance().GetIndex()].GetTitle().c_str(); - song_tip_info += _T("\r\n"); - song_tip_info += CCommon::LoadText(IDS_ARTIST, _T(": ")); - song_tip_info += CPlayer::GetInstance().GetPlayList()[CPlayer::GetInstance().GetIndex()].GetArtist().c_str(); - song_tip_info += _T("\r\n"); - song_tip_info += CCommon::LoadText(IDS_ALBUM, _T(": ")); - song_tip_info += CPlayer::GetInstance().GetPlayList()[CPlayer::GetInstance().GetIndex()].GetAlbum().c_str(); - CMiniModeUI* cur_ui{ dynamic_cast(GetCurUi()) }; - if (cur_ui != nullptr) - cur_ui->UpdateSongInfoTip(song_tip_info); -} - void CMiniModeDlg::SetTitle() { CString title; @@ -114,6 +94,8 @@ void CMiniModeDlg::AdjustWindowSize() //获取窗口大小 int width{}, height{}, height_with_playlist{}; CalculateWindowSize(width, height, height_with_playlist); + m_ui_width = width; + m_ui_height = height; if (width != 0 && height != 0) { SetWindowPos(nullptr, 0, 0, width, (m_show_playlist ? height_with_playlist : height), SWP_NOMOVE | SWP_NOZORDER); @@ -141,21 +123,11 @@ bool CMiniModeDlg::CalculateWindowSize(int& width, int& height, int& height_with CPlayerUIBase* cur_ui{ GetCurUi() }; if (cur_ui == nullptr) return false; - CMiniModeUI* mini_mode_ui = dynamic_cast(cur_ui); - if (mini_mode_ui != nullptr) - { - width = m_ui_data.widnow_width; - height = m_ui_data.window_height; - height_with_playlist = m_ui_data.window_height2; - } - else + CMiniModeUserUi* user_ui = dynamic_cast(cur_ui); + if (user_ui != nullptr) { - CMiniModeUserUi* user_ui = dynamic_cast(cur_ui); - if (user_ui != nullptr) - { - user_ui->GetUiSize(width, height); - height_with_playlist = height + theApp.DPI(292); - } + user_ui->GetUiSize(width, height); + height_with_playlist = height + theApp.DPI(292); } return true; } @@ -168,12 +140,10 @@ BEGIN_MESSAGE_MAP(CMiniModeDlg, CDialogEx) ON_WM_RBUTTONUP() ON_COMMAND(ID_MINI_MODE_EXIT, &CMiniModeDlg::OnMiniModeExit) ON_WM_INITMENU() - ON_WM_MOUSEWHEEL() ON_WM_LBUTTONDBLCLK() ON_NOTIFY(NM_DBLCLK, IDC_LIST2, &CMiniModeDlg::OnNMDblclkList2) ON_NOTIFY(NM_RCLICK, IDC_LIST2, &CMiniModeDlg::OnNMRClickList2) ON_WM_PAINT() - //ON_STN_CLICKED(IDC_MINI_PROGRESS_STATIC, &CMiniModeDlg::OnStnClickedMiniProgressStatic) ON_WM_MOUSEMOVE() ON_WM_LBUTTONUP() ON_COMMAND(ID_SHOW_PLAY_LIST, &CMiniModeDlg::OnShowPlayList) @@ -196,41 +166,27 @@ void CMiniModeDlg::Init() //载入配置 LoadConfig(); - //初始化“切换界面”菜单 - CMenu* pMenu = theApp.m_menu_set.m_mini_mode_menu.GetSubMenu(0)->GetSubMenu(17); - ASSERT(pMenu != nullptr); - if (pMenu != nullptr) + // 初始化“mini模式切换界面”菜单 + vector menu_list; + menu_list.emplace_back(MenuMgr::MenuItem{}); // 插入一个分隔符 + for (size_t i = 1; i < m_ui_list.size(); ++i) // 跳过第一个默认界面 { - //将ID_MINIMODE_UI_DEFAULT后面的所有菜单项删除 - int start_pos = 1; - while (pMenu->GetMenuItemCount() > start_pos) - { - pMenu->DeleteMenu(start_pos, MF_BYPOSITION); - } - - std::vector user_ui_list; - for (size_t i{}; i < m_ui_list.size(); i++) - { - CMiniModeUserUi* user_ui = dynamic_cast(m_ui_list[i].get()); - if (user_ui != nullptr) - user_ui_list.push_back(user_ui); - } - - if (!user_ui_list.empty()) - pMenu->AppendMenu(MF_SEPARATOR); - - const int MINIMODE_UI_MAX = ID_MINIMODE_UI_MAX - ID_MINIMODE_UI_DEFAULT; - bool user_ui_separator_added{}; - for (size_t i{}; i < user_ui_list.size() && i < MINIMODE_UI_MAX; i++) + // 转换到派生类以调用SetIndex/GetUIName + if (auto ui_mini = std::dynamic_pointer_cast(m_ui_list[i])) { - user_ui_list[i]->SetIndex(i + 1); - CString str_name = user_ui_list[i]->GetUIName(); //获取界面的名称 - if (str_name.IsEmpty()) - str_name.Format(_T("%s %d"), CCommon::LoadText(IDS_MINI_MODE).GetString(), i + 1); //如果名称为空(没有指定名称),则使用“迷你模式 +数字”的默认名称 - - pMenu->AppendMenu(MF_STRING | MF_ENABLED, ID_MINIMODE_UI_DEFAULT + i + 1, str_name); + ui_mini->SetIndex(menu_list.size()); // 设置界面序号 + wstring str_name = ui_mini->GetUIName(); // 获取界面的名称 + if (str_name.empty()) // 如果名称为空(没有指定名称),则使用“迷你模式 + 数字”的默认名称 + str_name = theApp.m_str_table.LoadTextFormat(L"TXT_UI_NAME_MINI_DEFAULT", { i }); + UINT id = ID_MINIMODE_UI_DEFAULT + i; + menu_list.emplace_back(MenuMgr::MenuItem{ id, IconMgr::IconType::IT_NO_ICON, str_name }); + + if (ID_MINIMODE_UI_DEFAULT + i >= ID_MINIMODE_UI_MAX) + break; } } + if (menu_list.size() > 1) // 如果只有一个分隔符就不更新 + theApp.m_menu_mgr.UpdateMenu(MenuMgr::MiniModeSwitchUiMenu, menu_list); } void CMiniModeDlg::UpdatePlayPauseButton() @@ -270,7 +226,7 @@ BOOL CMiniModeDlg::OnInitDialog() // 设置mini窗口为工具窗口使其不在多任务切换界面显示并可跨虚拟桌面 SetWindowLongW(m_hWnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW); - m_playlist_ctrl.SetFont(theApp.m_pMainWnd->GetFont()); + m_playlist_ctrl.SetFont(&theApp.m_font_set.dlg.GetFont()); m_pDC = GetDC(); for (auto& ui : m_ui_list) @@ -280,14 +236,11 @@ BOOL CMiniModeDlg::OnInitDialog() m_show_playlist = false; - //获取窗口大小 - int width{}, height{}, height_with_playlist{}; - CalculateWindowSize(width, height, height_with_playlist); - //初始化窗口位置 if (m_position_x != -1 && m_position_y != -1) SetWindowPos(nullptr, m_position_x, m_position_y, 0, 0, SWP_NOSIZE | SWP_NOZORDER); + //获取窗口大小 AdjustWindowSize(); //设置定时器 @@ -304,7 +257,6 @@ BOOL CMiniModeDlg::OnInitDialog() SetTransparency(); m_show_playlist = false; - m_ui_data.m_show_volume = false; m_first_start = true; return TRUE; // return TRUE unless you set the focus to a control @@ -333,16 +285,13 @@ void CMiniModeDlg::OnTimer(UINT_PTR nIDEvent) if (nIDEvent == TIMER_ID_MINI) { //更新鼠标提示 - static int index{}; - static wstring song_name{}; + static SongInfo last_song_info; + const SongInfo& song_info = CPlayer::GetInstance().GetCurrentSongInfo(); //如果当前播放的歌曲发生变化,就更新鼠标提示信息 - if (index != CPlayer::GetInstance().GetIndex() || song_name != CPlayer::GetInstance().GetFileName()) + if (!song_info.IsSameSong(last_song_info)) { - UpdateSongTipInfo(); + last_song_info = song_info; SetTitle(); - //m_Mytip.UpdateTipText(m_song_tip_info, this); - index = CPlayer::GetInstance().GetIndex(); - song_name = CPlayer::GetInstance().GetFileName(); m_draw_reset = true; } } @@ -350,34 +299,21 @@ void CMiniModeDlg::OnTimer(UINT_PTR nIDEvent) { if (m_first_start) { - UpdateSongTipInfo(); SetTitle(); } m_first_start = false; } - if (nIDEvent == 11) - { - m_ui_data.m_show_volume = false; - KillTimer(11); - } CDialogEx::OnTimer(nIDEvent); } -void CMiniModeDlg::SetVolume(bool up) +void CMiniModeDlg::SetVolume(int step) { - if (up) - CPlayer::GetInstance().MusicControl(Command::VOLUME_UP); - else - CPlayer::GetInstance().MusicControl(Command::VOLUME_DOWN); + CPlayer::GetInstance().MusicControl(Command::VOLUME_ADJ, step); CUserUi* cur_ui{ dynamic_cast(GetCurUi()) }; if (cur_ui != nullptr) cur_ui->VolumeAdjusted(); - - KillTimer(11); - SetTimer(11, 1500, NULL); //显示音量后设置一个1500毫秒的定时器(音量显示保持1.5秒) - m_ui_data.m_show_volume = true; } void CMiniModeDlg::SetTransparency() @@ -425,12 +361,12 @@ BOOL CMiniModeDlg::PreTranslateMessage(MSG* pMsg) //按上下方向键调整音量 if (pMsg->wParam == VK_UP) { - SetVolume(true); + SetVolume(theApp.m_nc_setting_data.volum_step); return TRUE; } if (pMsg->wParam == VK_DOWN) { - SetVolume(false); + SetVolume(-theApp.m_nc_setting_data.volum_step); return TRUE; } @@ -460,7 +396,7 @@ BOOL CMiniModeDlg::PreTranslateMessage(MSG* pMsg) { CRect rect; GetWindowRect(rect); - theApp.m_menu_set.m_main_popup_menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, rect.left, rect.bottom, this); + theApp.m_menu_mgr.GetMenu(MenuMgr::MainAreaMenu)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, rect.left, rect.bottom, this); return TRUE; } @@ -473,12 +409,22 @@ BOOL CMiniModeDlg::PreTranslateMessage(MSG* pMsg) } } - ////将此窗口的其他键盘消息转发给主窗口 - //if (pMsg->message == WM_KEYDOWN) - //{ - // ::PostMessage(theApp.m_pMainWnd->m_hWnd, WM_KEYDOWN, pMsg->wParam, pMsg->lParam); - // return TRUE; - //} + if (pMsg->message == WM_MOUSEWHEEL) // 将滚轮消息转发给主窗口处理音量调整 + { + CRect rect{}; + GetWindowRect(rect); + CRect m_ui_rect{ rect.left, rect.top, rect.left + m_ui_width, rect.top + m_ui_height }; + if (m_ui_rect.PtInRect(pMsg->pt)) // 仅自绘区域可调整音量 + { + if (CWnd* pMainWnd = AfxGetMainWnd()) + { + POINT pt = { INT16_MAX, INT16_MAX }; // 修改pt参数为一个特殊值 + LPARAM lParam = MAKELPARAM(pt.x, pt.y); + pMainWnd->SendMessage(WM_MOUSEWHEEL, pMsg->wParam, lParam); + return TRUE; + } + } + } if (pMsg->message == WM_MOUSEMOVE) { @@ -525,11 +471,11 @@ void CMiniModeDlg::OnRButtonUp(UINT nFlags, CPoint point) GetCursorPos(&point1); //获取当前光标的位置,以便使得菜单可以跟随光标 if (nFlags == MK_SHIFT) //按住Shift键点击鼠标右键时,弹出系统菜单 { - theApp.m_menu_set.m_main_menu_popup.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point1.x, point1.y, this); + theApp.m_menu_mgr.GetMenu(MenuMgr::MainPopupMenu)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point1.x, point1.y, this); } else { - CMenu* pContextMenu = theApp.m_menu_set.m_mini_mode_menu.GetSubMenu(0); + CMenu* pContextMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::MiniAreaMenu); pContextMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point1.x, point1.y, this); //在指定位置显示弹出菜单 } @@ -559,9 +505,6 @@ void CMiniModeDlg::OnInitMenu(CMenu* pMenu) pMenu->CheckMenuItem(ID_ADD_REMOVE_FROM_FAVOURITE, MF_BYCOMMAND | (CPlayer::GetInstance().IsFavourite() ? MF_CHECKED : MF_UNCHECKED)); pMenu->CheckMenuItem(ID_MINI_MODE_ALWAYS_ON_TOP, MF_BYCOMMAND | (m_always_on_top ? MF_CHECKED : MF_UNCHECKED)); - //设置播放列表右键菜单的默认菜单项 - pMenu->SetDefaultItem(ID_PLAY_ITEM); - //设置“切换界面”菜单的状态 pMenu->CheckMenuRadioItem(ID_MINIMODE_UI_DEFAULT, ID_MINIMODE_UI_MAX, ID_MINIMODE_UI_DEFAULT + m_ui_index, MF_BYCOMMAND | MF_CHECKED); @@ -570,22 +513,6 @@ void CMiniModeDlg::OnInitMenu(CMenu* pMenu) } -BOOL CMiniModeDlg::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) -{ - // TODO: 在此添加消息处理程序代码和/或调用默认值 - if (zDelta > 0) - { - SetVolume(true); - } - if (zDelta < 0) - { - SetVolume(false); - } - - return CDialogEx::OnMouseWheel(nFlags, zDelta, pt); -} - - void CMiniModeDlg::OnLButtonDblClk(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 @@ -616,7 +543,7 @@ void CMiniModeDlg::OnNMRClickList2(NMHDR *pNMHDR, LRESULT *pResult) m_item_selected = pNMItemActivate->iItem; //获取鼠标选中的项目 m_playlist_ctrl.GetItemSelected(m_items_selected); - CMenu* pContextMenu = theApp.m_menu_set.m_list_popup_menu.GetSubMenu(0); //获取第一个弹出菜单 + CMenu* pContextMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::PlaylistMenu); m_playlist_ctrl.ShowPopupMenu(pContextMenu, pNMItemActivate->iItem, this); *pResult = 0; } @@ -631,15 +558,6 @@ void CMiniModeDlg::OnPaint() } -//void CMiniModeDlg::OnStnClickedMiniProgressStatic() -//{ -// // TODO: 在此添加控件通知处理程序代码 -// //int pos = m_progress_bar.GetPos(); -// //int song_pos = static_cast<__int64>(pos) * CPlayer::GetInstance().GetSongLength() / 1000; -// //CPlayer::GetInstance().SeekTo(song_pos); -//} - - void CMiniModeDlg::OnMouseMove(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 diff --git a/MusicPlayer2/MiniModeDlg.h b/MusicPlayer2/MiniModeDlg.h index f702fa273..ea5bdcbea 100644 --- a/MusicPlayer2/MiniModeDlg.h +++ b/MusicPlayer2/MiniModeDlg.h @@ -1,12 +1,9 @@ #pragma once #include"Player.h" -#include "afxwin.h" #include "PropertyDlg.h" -#include "afxcmn.h" #include "PlayListCtrl.h" #include "ColorConvert.h" #include "DrawCommon.h" -#include "CMiniModeUI.h" #include "CPlayerUIBase.h" // CMiniModeDlg 对话框 @@ -33,7 +30,7 @@ class CMiniModeDlg : public CDialogEx void MoveWindowPos(); - void SetVolume(bool up); // + void SetVolume(int step); void SetTransparency(); void SetDragEnable(); @@ -50,13 +47,15 @@ class CMiniModeDlg : public CDialogEx int m_position_x; int m_position_y; + int m_ui_width{}; + int m_ui_height{}; + bool m_show_playlist{ false }; //是否显示播放列表 LONG m_playlist_y_offset{}; //播放列表收起时窗口需要进行的y坐标偏移量 int& m_item_selected; //播放列表中鼠标选中的项目,引用MusicPlayerDlg类中的同名变量,当迷你窗口中播放列表选中的项目变化时,同步到主窗口中选中的项目 vector& m_items_selected; - CMiniModeUI::SMiniModeUIData m_ui_data; //(仅用于默认的迷你模式界面) std::vector> m_ui_list; //保存每个界面类的指针 int m_ui_index{}; @@ -76,7 +75,6 @@ class CMiniModeDlg : public CDialogEx void SaveConfig() const; void LoadConfig(); - void UpdateSongTipInfo(); void SetTitle(); void SetAlwaysOnTop(); void AdjustWindowSize(); @@ -97,13 +95,11 @@ class CMiniModeDlg : public CDialogEx afx_msg void OnRButtonUp(UINT nFlags, CPoint point); afx_msg void OnMiniModeExit(); afx_msg void OnInitMenu(CMenu* pMenu); - afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt); afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); afx_msg void OnNMDblclkList2(NMHDR *pNMHDR, LRESULT *pResult); afx_msg void OnNMRClickList2(NMHDR *pNMHDR, LRESULT *pResult); afx_msg void OnPaint(); public: - //afx_msg void OnStnClickedMiniProgressStatic(); afx_msg void OnMouseMove(UINT nFlags, CPoint point); afx_msg void OnLButtonUp(UINT nFlags, CPoint point); afx_msg void OnShowPlayList(); diff --git a/MusicPlayer2/MiniModeUserUi.cpp b/MusicPlayer2/MiniModeUserUi.cpp index 795997df7..5eb2c8a6c 100644 --- a/MusicPlayer2/MiniModeUserUi.cpp +++ b/MusicPlayer2/MiniModeUserUi.cpp @@ -6,6 +6,11 @@ CMiniModeUserUi::CMiniModeUserUi(CWnd* pMainWnd, const std::wstring& xml_path) { } +CMiniModeUserUi::CMiniModeUserUi(CWnd* pMainWnd, UINT id) + : CUserUi(pMainWnd, id) +{ +} + CMiniModeUserUi::~CMiniModeUserUi() { } @@ -76,7 +81,7 @@ bool CMiniModeUserUi::LButtonUp(CPoint point) btn.second.pressed = false; CPoint point1; GetCursorPos(&point1); - CMenu* pMenu = theApp.m_menu_set.m_mini_mode_menu.GetSubMenu(0)->GetSubMenu(17); + CMenu* pMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::MiniModeSwitchUiMenu); ASSERT(pMenu != nullptr); if (pMenu != nullptr) pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point1.x, point1.y, m_pMainWnd); diff --git a/MusicPlayer2/MiniModeUserUi.h b/MusicPlayer2/MiniModeUserUi.h index fb1dd2279..cbd8c2bce 100644 --- a/MusicPlayer2/MiniModeUserUi.h +++ b/MusicPlayer2/MiniModeUserUi.h @@ -1,10 +1,11 @@ -#pragma once +#pragma once #include "UserUi.h" class CMiniModeUserUi : public CUserUi { public: CMiniModeUserUi(CWnd* pMainWnd, const std::wstring& xml_path); + CMiniModeUserUi(CWnd* pMainWnd, UINT id); // id为xml资源ID ~CMiniModeUserUi(); bool GetUiSize(int& width, int& height); diff --git a/MusicPlayer2/MusicPlayer2.cpp b/MusicPlayer2/MusicPlayer2.cpp index ab934e6e4..484b7d1c5 100644 --- a/MusicPlayer2/MusicPlayer2.cpp +++ b/MusicPlayer2/MusicPlayer2.cpp @@ -4,13 +4,13 @@ #include "stdafx.h" #include "MusicPlayer2.h" +#include "WinVersionHelper.h" #include "MusicPlayerDlg.h" #include "MessageDlg.h" #include "crashtool.h" #include #include "UpdateHelper.h" #include "MusicPlayerCmdHelper.h" -#include "WIC.h" #include "SongDataManager.h" #include "PlaylistMgr.h" @@ -110,10 +110,13 @@ BOOL CMusicPlayerApp::InitInstance() //当程序被Windows重新启动时,直接退出程序 if (cmd_line.find(L"RestartByRestartManager") != wstring::npos) { - //将命令行参数写入日志文件 - CString info = CCommon::LoadTextFormat(IDS_RESTART_EXIT, { cmd_line }); - //swprintf_s(buff, CCommon::LoadText(IDS_RESTART_EXIT), cmd_line.c_str()); - WriteLog(wstring{ info.GetString() }); + LoadConfig(); // m_str_table.Init之前需要先加载语言配置 + // Init略花时间,不应当在互斥量成功创建之前执行,这里是特例 + m_str_table.Init(m_local_dir + L"language\\", m_general_setting_data.language_); + CCommon::SetThreadLanguageList(m_str_table.GetLanguageTag()); + // 将命令行参数写入日志文件 + wstring info = theApp.m_str_table.LoadTextFormat(L"LOG_RESTART_EXIT", { cmd_line }); + WriteLog(info); return FALSE; } @@ -198,28 +201,37 @@ BOOL CMusicPlayerApp::InitInstance() } else //仍然找不到窗口句柄,说明程序还没有退出 { - AfxMessageBox(IDS_APP_RUNING_INFO, MB_ICONINFORMATION | MB_OK); + LoadConfig(); + m_str_table.Init(m_local_dir + L"language\\", m_general_setting_data.language_); + CCommon::SetThreadLanguageList(m_str_table.GetLanguageTag()); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_APP_RUNING_INFO"); + AfxMessageBox(info.c_str(), MB_ICONINFORMATION | MB_OK); } return FALSE; //退出当前程序 } } - //CString str = CCommon::LoadTextFormat(IDS_TEST_STR, { 3, L"asdfghhh", 1.2 }); + LoadConfig(); + // 获取互斥量后StrTable应尽早初始化以免某些LoadText后以静态变量保存字符串引用的地方加载到空字符串 + m_str_table.Init(m_local_dir + L"language\\", m_general_setting_data.language_); LoadSongData(); LoadLastFMData(); - LoadConfig(); + // 获取默认线程语言 + CCommon::GetThreadLanguageList(m_def_lang_list); //初始化界面语言 - CCommon::SetThreadLanguage(m_general_setting_data.language); + CCommon::SetThreadLanguageList(m_str_table.GetLanguageTag()); //检查bass.dll的版本是否和API的版本匹配 WORD dll_version{ HIWORD(BASS_GetVersion()) }; //WORD dll_version{ 0x203 }; if (dll_version != BASSVERSION) { - CString info = CCommon::LoadTextFormat(IDS_BASS_VERSION_WARNING, { HIBYTE(dll_version), LOBYTE(dll_version), HIBYTE(BASSVERSION), LOBYTE(BASSVERSION) }); - if (AfxMessageBox(info, MB_ICONWARNING | MB_OKCANCEL) == IDCANCEL) + wstring dll_version_str{ std::to_wstring(static_cast(HIBYTE(dll_version))) + L'.' + std::to_wstring(static_cast(LOBYTE(dll_version))) }; + wstring bass_version_str{ std::to_wstring(static_cast(HIBYTE(BASSVERSION))) + L'.' + std::to_wstring(static_cast(LOBYTE(BASSVERSION))) }; + wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_BASS_VERSION_WARNING", { dll_version_str, bass_version_str }); + if (AfxMessageBox(info.c_str(), MB_ICONWARNING | MB_OKCANCEL) == IDCANCEL) return FALSE; } @@ -269,6 +281,10 @@ BOOL CMusicPlayerApp::InitInstance() if (m_hot_key_setting_data.global_multimedia_key_enable && !CWinVersionHelper::IsWindows81OrLater()) m_multimedia_key_hook = SetWindowsHookEx(WH_KEYBOARD_LL, CMusicPlayerApp::MultiMediaKeyHookProc, m_hInstance, 0); + // 初始化ITaskbarList3 + if (CWinVersionHelper::IsWindows7OrLater()) + EnableTaskbarInteraction(TRUE); + Gdiplus::GdiplusStartupInput gdiplusStartupInput; GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL); @@ -291,8 +307,8 @@ BOOL CMusicPlayerApp::InitInstance() } else if (nResponse == -1) { - TRACE(traceAppMsg, 0, "警告: 对话框创建失败,应用程序将意外终止。\n"); - TRACE(traceAppMsg, 0, "警告: 如果您在对话框上使用 MFC 控件,则无法 #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS。\n"); + TRACE(traceAppMsg, 0, L"警告: 对话框创建失败,应用程序将意外终止。\n"); + TRACE(traceAppMsg, 0, L"警告: 如果您在对话框上使用 MFC 控件,则无法 #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS。\n"); } SaveLastFMData(); @@ -334,26 +350,14 @@ BOOL CMusicPlayerApp::InitInstance() void CMusicPlayerApp::OnHelp() { // TODO: 在此添加命令处理程序代码 - static bool dialog_exist{ false }; - - if (!dialog_exist) //确保对话框已经存在时不再弹出 - { - dialog_exist = true; - CMessageDlg helpDlg; - helpDlg.SetWindowTitle(CCommon::LoadText(IDS_HELP)); - helpDlg.SetInfoText(CCommon::LoadText(IDS_WELCOM_TO_USE)); - helpDlg.ShowLinkStatic(true); - helpDlg.SetLinkInfo(CCommon::LoadText(IDS_SHOW_ONLINE_HELP_INFO), _T("https://github.com/zhongyang219/MusicPlayer2/wiki")); - - CString info{ GetHelpString() }; - info += _T("\r\n\r\n"); - info += GetSystemInfoString(); - - helpDlg.SetMessageText(info); - helpDlg.DoModal(); - - dialog_exist = false; - } + CMessageDlg helpDlg(L"HelpDlg"); // 此字符串对应CBaseDialog::GetDialogName,用于保证对话框不会重复打开 + helpDlg.SetWindowTitle(theApp.m_str_table.LoadText(L"TITLE_HELP_DLG")); + helpDlg.SetInfoText(theApp.m_str_table.LoadText(L"TXT_HELP_DLG_WELCOM_TO_USE")); + helpDlg.SetLinkInfo(theApp.m_str_table.LoadText(L"TXT_HELP_DLG_SHOW_ONLINE_HELP"), L"https://github.com/zhongyang219/MusicPlayer2/wiki"); + wstring info = theApp.m_str_table.LoadText(L"TXT_HELP_DLG_HELP_INFO"); + info += L"\r\n\r\n" + GetSystemInfoString(); + helpDlg.SetMessageText(info); + helpDlg.DoModal(); } void CMusicPlayerApp::SaveSongData() @@ -370,14 +374,15 @@ void CMusicPlayerApp::CheckUpdate(bool message) wstring version; //程序版本 wstring link; //下载链接 - wstring contents_zh_cn; //更新内容(简体中文) - wstring contents_en; //更新内容(English) CUpdateHelper update_helper; update_helper.SetUpdateSource(static_cast(m_general_setting_data.update_source)); if (!update_helper.CheckForUpdate()) { if (message) - AfxMessageBox(CCommon::LoadText(IDS_CHECK_UPDATA_FAILED), MB_OK | MB_ICONWARNING); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_UPDATE_CHECK_FAILED"); + AfxMessageBox(info.c_str(), MB_OK | MB_ICONWARNING); + } return; } @@ -387,42 +392,29 @@ void CMusicPlayerApp::CheckUpdate(bool message) #else link = update_helper.GetLink(); #endif - contents_zh_cn = update_helper.GetContentsZhCn(); - contents_en = update_helper.GetContentsEn(); if (version.empty() || link.empty()) { if (message) { - CString info = CCommon::LoadText(IDS_CHECK_UPDATA_ERROR); - info += _T("\r\nrow_data="); - info += std::to_wstring(update_helper.IsRowData()).c_str(); - theApp.m_pMainWnd->MessageBox(info, NULL, MB_OK | MB_ICONWARNING); + wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_UPDATE_CHECK_ERROR", { L"row_data = " + std::to_wstring(update_helper.IsRowData()) }); + theApp.m_pMainWnd->MessageBox(info.c_str(), NULL, MB_OK | MB_ICONWARNING); } return; } if (version > APP_VERSION) //如果服务器上的版本大于本地版本 { - CString info; //根据语言设置选择对应语言版本的更新内容 - int language_code = _ttoi(CCommon::LoadText(IDS_LANGUAGE_CODE)); - wstring contents_lan; - switch (language_code) - { - case 2: - contents_lan = contents_zh_cn; - break; - default: - contents_lan = contents_en; - break; - } + bool is_zh_cn = theApp.m_str_table.IsSimplifiedChinese(); + wstring contents{ is_zh_cn ? update_helper.GetContentsZhCn() : update_helper.GetContentsEn() }; - if (contents_lan.empty()) - info = CCommon::LoadTextFormat(IDS_UPDATE_AVLIABLE, { version }); + wstring info; + if (contents.empty()) + info = theApp.m_str_table.LoadTextFormat(L"MSG_UPDATE_AVLIABLE", { version }); else - info = CCommon::LoadTextFormat(IDS_UPDATE_AVLIABLE2, { version, contents_lan }); + info = theApp.m_str_table.LoadTextFormat(L"MSG_UPDATE_AVLIABLE_2", { version, contents }); - if (theApp.m_pMainWnd->MessageBox(info, NULL, MB_YESNO | MB_ICONQUESTION) == IDYES) + if (theApp.m_pMainWnd->MessageBox(info.c_str(), NULL, MB_YESNO | MB_ICONQUESTION) == IDYES) { ShellExecute(NULL, _T("open"), link.c_str(), NULL, NULL, SW_SHOW); //转到下载链接 } @@ -430,7 +422,10 @@ void CMusicPlayerApp::CheckUpdate(bool message) else { if (message) - theApp.m_pMainWnd->MessageBox(CCommon::LoadText(IDS_ALREADY_UPDATED), NULL, MB_OK | MB_ICONINFORMATION); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_UPDATE_ALREADY"); + theApp.m_pMainWnd->MessageBox(info.c_str(), NULL, MB_OK | MB_ICONINFORMATION); + } } } @@ -487,26 +482,18 @@ void CMusicPlayerApp::SaveGlobalConfig() UINT CMusicPlayerApp::CheckUpdateThreadFunc(LPVOID lpParam) { - CCommon::SetThreadLanguage(theApp.m_general_setting_data.language); + CCommon::SetThreadLanguageList(theApp.m_str_table.GetLanguageTag()); theApp.CheckUpdate(lpParam); //检查更新 return 0; } -//UINT CMusicPlayerApp::ClassifySongDataThreadFunc(LPVOID lpParam) -//{ -// //theApp.m_artist_classifer.ClassifyMedia(); -// //theApp.m_album_classifer.ClassifyMedia(); -// //theApp.m_genre_classifer.ClassifyMedia(); -// //theApp.m_year_classifer.ClassifyMedia(); -// return 0; -//} - void CMusicPlayerApp::SaveConfig() { CIniHelper ini(m_config_path); ini.WriteString(L"app", L"version", APP_VERSION); ini.WriteBool(L"general", L"check_update_when_start", m_general_setting_data.check_update_when_start); - ini.WriteInt(_T("general"), _T("language"), static_cast(m_general_setting_data.language)); + // ini.WriteInt(_T("general"), _T("language"), static_cast(m_general_setting_data.language)); + ini.WriteString(L"general", L"language_", m_general_setting_data.language_); if (!CWinVersionHelper::IsWindows81OrLater()) ini.WriteBool(L"hot_key", L"global_multimedia_key_enable", m_hot_key_setting_data.global_multimedia_key_enable); ini.Save(); @@ -517,518 +504,20 @@ void CMusicPlayerApp::LoadConfig() CIniHelper ini(m_config_path); wstring config_version = ini.GetString(L"app", L"version", L""); m_general_setting_data.check_update_when_start = ini.GetBool(L"general", L"check_update_when_start", true); - m_general_setting_data.language = static_cast(ini.GetInt(L"general", L"language", 0)); + // m_general_setting_data.language = static_cast(ini.GetInt(L"general", L"language", 0)); + m_general_setting_data.language_ = ini.GetString(L"general", L"language_", L""); // 留空表示“跟随系统” if (!CWinVersionHelper::IsWindows81OrLater()) m_hot_key_setting_data.global_multimedia_key_enable = ini.GetBool(L"hot_key", L"global_multimedia_key_enable", false); } -void CMusicPlayerApp::LoadIconResource() +void CMusicPlayerApp::LoadImgResource() { -#ifdef _DEBUG - m_icon_set.app.Load(IDI_APP_DEBUG, NULL, DPI(16)); -#else - m_icon_set.app.Load(IDR_MAINFRAME, NULL, DPI(16)); -#endif - m_icon_set.default_cover = CDrawCommon::LoadIconResource(IDI_DEFAULT_COVER, 512, 512); - m_icon_set.default_cover_small = CDrawCommon::LoadIconResource(IDI_DEFAULT_COVER, DPI(32), DPI(32)); - m_icon_set.default_cover_not_played = CDrawCommon::LoadIconResource(IDI_DEFAULT_COVER_NOT_PLAYED, 512, 512); - m_icon_set.default_cover_small_not_played = CDrawCommon::LoadIconResource(IDI_DEFAULT_COVER_NOT_PLAYED, DPI(32), DPI(32)); - m_icon_set.default_cover_toolbar.Load(IDI_DEFAULT_COVER, IDI_DEFAULT_COVER, DPI(16)); - m_icon_set.default_cover_toolbar_not_played.Load(IDI_DEFAULT_COVER_NOT_PLAYED, IDI_DEFAULT_COVER_NOT_PLAYED, DPI(16)); - m_icon_set.skin.Load(IDI_SKIN, IDI_SKIN_D, DPI(16)); - m_icon_set.eq.Load(IDI_EQ, IDI_EQ_D, DPI(16)); - m_icon_set.setting.Load(IDI_SETTING, IDI_SETTING_D, DPI(16)); - m_icon_set.mini.Load(IDI_MINI, IDI_MINI_D, DPI(16)); - m_icon_set.play_oder.Load(IDI_PLAY_ORDER, IDI_PLAY_ORDER_D, DPI(16)); - m_icon_set.play_shuffle.Load(IDI_PLAY_SHUFFLE, IDI_PLAY_SHUFFLE_D, DPI(16)); - m_icon_set.play_random.Load(IDI_PLAY_RANDOM, IDI_PLAY_RANDOM_D, DPI(16)); - m_icon_set.loop_playlist.Load(IDI_LOOP_PLAYLIST, IDI_LOOP_PLAYLIST_D, DPI(16)); - m_icon_set.loop_track.Load(IDI_LOOP_TRACK, IDI_LOOP_TRACK_D, DPI(16)); - m_icon_set.play_track.Load(IDI_PLAY_TRACK, IDI_PLAY_TRACK_D, DPI(16)); - m_icon_set.info.Load(IDI_SONG_INFO, IDI_SONG_INFO_D, DPI(16)); - m_icon_set.select_folder.Load(IDI_SELECT_FOLDER, IDI_SELECT_FOLDER_D, DPI(16)); - m_icon_set.media_lib.Load(IDI_MEDIA_LIB, IDI_MEDIA_LIB_D, DPI(16)); - m_icon_set.show_playlist.Load(IDI_PLAYLIST, IDI_PLAYLIST_D, DPI(16)); - m_icon_set.find_songs.Load(IDI_FIND_SONGS, IDI_FIND_SONGS_D, DPI(16)); - m_icon_set.full_screen.Load(IDI_FULL_SCREEN, IDI_FULL_SCREEN_D, DPI(16)); - m_icon_set.full_screen1.Load(IDI_FULL_SCREEN1, IDI_FULL_SCREEN1_D, DPI(16)); - m_icon_set.menu.Load(IDI_MENU, IDI_MENU_D, DPI(16)); - m_icon_set.favourite.Load(IDI_FAVOURITE, IDI_FAVOURITE_D, DPI(16)); - m_icon_set.heart.Load(IDI_HEART, NULL, DPI(16)); - m_icon_set.double_line.Load(IDI_DOUBLE_LINE_D, NULL, DPI(16)); - m_icon_set.lock.Load(IDI_LOCK_D, NULL, DPI(16)); - m_icon_set.close.Load(IDI_CLOSE_D, NULL, DPI(16)); - m_icon_set.edit.Load(IDI_EDIT_D, NULL, DPI(16)); - m_icon_set.add.Load(IDI_ADD, IDI_ADD_D, DPI(16)); - m_icon_set.artist.Load(IDI_ARTIST_D, NULL, DPI(16)); - m_icon_set.album.Load(IDI_ALBUM_D, NULL, DPI(16)); - m_icon_set.genre.Load(IDI_GENRE_D, NULL, DPI(16)); - m_icon_set.year.Load(IDI_YEAR_D, NULL, DPI(16)); - m_icon_set.folder_explore.Load(IDI_FOLDER_EXPLORE_D, NULL, DPI(16)); - m_icon_set.lyric_forward.Load(IDI_LYRIC_FORWARD_D, NULL, DPI(16)); - m_icon_set.lyric_delay.Load(IDI_LYRIC_DELAY_D, NULL, DPI(16)); - m_icon_set.recent_songs.Load(IDI_RECENT_SONG_D, NULL, DPI(16)); - m_icon_set.volume1.Load(IDI_VOLUME1, IDI_VOLUME1_D, DPI(16)); - m_icon_set.volume2.Load(IDI_VOLUME2, IDI_VOLUME2_D, DPI(16)); - m_icon_set.volume3.Load(IDI_VOLUME3, IDI_VOLUME3_D, DPI(16)); - m_icon_set.volume0.Load(IDI_VOLUME0, IDI_VOLUME0_D, DPI(16)); - m_icon_set.dark_mode.Load(IDI_LIGHT_MODE, IDI_DARK_MODE_D, DPI(16)); - - m_icon_set.previous.Load(IDI_PREVIOUS, NULL, DPI(16)); - m_icon_set.play.Load(IDI_PLAY, NULL, DPI(16)); - m_icon_set.pause.Load(IDI_PAUSE, NULL, DPI(16)); - m_icon_set.next.Load(IDI_NEXT1, NULL, DPI(16)); - m_icon_set.stop.Load(IDI_STOP, NULL, DPI(16)); - - //用于主界面的播放控制图标,大小为20像素 - m_icon_set.play_l.Load(IDI_PLAY_NEW, IDI_PLAY_NEW_D, DPI(20)); - m_icon_set.pause_l.Load(IDI_PAUSE_NEW, IDI_PAUSE_NEW_D, DPI(20)); - m_icon_set.previous_l.Load(IDI_PREVIOUS_NEW, IDI_PREVIOUS_NEW_D, DPI(20)); - m_icon_set.next_l.Load(IDI_NEXT_NEW, IDI_NEXT_NEW_D, DPI(20)); - m_icon_set.stop_l.Load(IDI_STOP_NEW, IDI_STOP_NEW_D, DPI(20)); - - //用于迷你模式的播放控制图标,大小为16像素 - m_icon_set.play_new.Load(IDI_PLAY_NEW, IDI_PLAY_NEW_D, DPI(16)); - m_icon_set.pause_new.Load(IDI_PAUSE_NEW, IDI_PAUSE_NEW_D, DPI(16)); - m_icon_set.previous_new.Load(IDI_PREVIOUS_NEW, IDI_PREVIOUS_NEW_D, DPI(16)); - m_icon_set.next_new.Load(IDI_NEXT_NEW, IDI_NEXT_NEW_D, DPI(16)); - - m_icon_set.app_close.Load(IDI_CLOSE, IDI_CLOSE_D, DPI(16)); - m_icon_set.maximize.Load(IDI_MAXIMIZE, IDI_MAXIMIZE_D, DPI(16)); - m_icon_set.minimize.Load(IDI_MINIMIZE, IDI_MINIMIZE_D, DPI(16)); - m_icon_set.restore.Load(IDI_RESTORE, IDI_RESTORE_D, DPI(16)); - m_icon_set.sort.Load(IDI_SORT, IDI_SORT_D, DPI(16)); - m_icon_set.display_mode.Load(IDI_DISPLAY_MODE, IDI_DISPLAY_MODE_D, DPI(16)); - m_icon_set.link.Load(IDI_LINK, IDI_LINK_D, DPI(16)); - m_icon_set.unlink.Load(IDI_UNLINK, IDI_UNLINK_D, DPI(16)); - m_icon_set.switch_display.Load(IDI_SWITCH, IDI_SWITCH_D, DPI(16)); - m_icon_set.help.Load(IDI_HELP, IDI_HELP_D, DPI(16)); - m_icon_set.lyric.Load(IDI_LYRIC, IDI_LYRIC_D, DPI(16)); - m_icon_set.playlist_dock.Load(IDI_PLAYLIST_DOCK, IDI_PLAYLIST_DOCK_D, DPI(16)); - m_icon_set.mini_restore.Load(IDI_MINI_RESTORE, IDI_IDI_MINI_RESTORE_D, DPI(16)); - m_icon_set.locate.Load(IDI_LOCATE, IDI_LOCATE_D, DPI(16)); - m_icon_set.expand.Load(IDI_EXPAND, IDI_EXPAND_D, DPI(16)); - - //菜单图标 - m_icon_set.stop_new = CDrawCommon::LoadIconResource(IDI_STOP_NEW_D, DPI(16), DPI(16)); - m_icon_set.save_new = CDrawCommon::LoadIconResource(IDI_SAVE_NEW_D, DPI(16), DPI(16)); - m_icon_set.save_as = CDrawCommon::LoadIconResource(IDI_SAVE_AS_D, DPI(16), DPI(16)); - m_icon_set.music = CDrawCommon::LoadIconResource(IDI_MUSIC_D, DPI(16), DPI(16)); - m_icon_set.file_relate = CDrawCommon::LoadIconResource(IDI_FILE_RELATE_D, DPI(16), DPI(16)); - m_icon_set.online = CDrawCommon::LoadIconResource(IDI_ONLINE_D, DPI(16), DPI(16)); - m_icon_set.play_pause = CDrawCommon::LoadIconResource(IDI_PLAY_PAUSE_D, DPI(16), DPI(16)); - m_icon_set.convert = CDrawCommon::LoadIconResource(IDI_CONVERT_D, DPI(16), DPI(16)); - m_icon_set.download = CDrawCommon::LoadIconResource(IDI_DOWNLOAD_D, DPI(16), DPI(16)); - m_icon_set.download1 = CDrawCommon::LoadIconResource(IDI_DOWNLOAD1_D, DPI(16), DPI(16)); - m_icon_set.ff_new = CDrawCommon::LoadIconResource(IDI_FF_NEW_D, DPI(16), DPI(16)); - m_icon_set.rew_new = CDrawCommon::LoadIconResource(IDI_REW_NEW_D, DPI(16), DPI(16)); - m_icon_set.playlist_float = CDrawCommon::LoadIconResource(IDI_PLAYLIST_FLOAT_D, DPI(16), DPI(16)); - m_icon_set.statistics = CDrawCommon::LoadIconResource(IDI_STATISTICS_D, DPI(16), DPI(16)); - m_icon_set.pin = CDrawCommon::LoadIconResource(IDI_PIN_D, DPI(16), DPI(16)); - m_icon_set.exit = CDrawCommon::LoadIconResource(IDI_EXIT_D, DPI(16), DPI(16)); - m_icon_set.album_cover = CDrawCommon::LoadIconResource(IDI_ALBUM_COVER_D, DPI(16), DPI(16)); - m_icon_set.rename = CDrawCommon::LoadIconResource(IDI_RENAME_D, DPI(16), DPI(16)); - m_icon_set.tag = CDrawCommon::LoadIconResource(IDI_TAG, DPI(16), DPI(16)); - m_icon_set.star = CDrawCommon::LoadIconResource(IDI_STAR, DPI(16), DPI(16)); - m_icon_set.internal_lyric = CDrawCommon::LoadIconResource(IDI_INTERNAL_LYRIC_D, DPI(16), DPI(16)); - m_icon_set.speed_up = CDrawCommon::LoadIconResource(IDI_SPEED_UP_D, DPI(16), DPI(16)); - m_icon_set.slow_down = CDrawCommon::LoadIconResource(IDI_SLOW_DOWN_D, DPI(16), DPI(16)); - m_icon_set.shortcut = CDrawCommon::LoadIconResource(IDI_SHORTCUT_D, DPI(16), DPI(16)); - m_icon_set.play_as_next = CDrawCommon::LoadIconResource(IDI_PLAY_AS_NEXT, DPI(16), DPI(16)); - m_icon_set.play_in_playlist = CDrawCommon::LoadIconResource(IDI_PLAY_IN_PLAYLIST, DPI(16), DPI(16)); - m_icon_set.copy = CDrawCommon::LoadIconResource(IDI_COPY, DPI(16), DPI(16)); - m_icon_set.play_in_folder = CDrawCommon::LoadIconResource(IDI_PLAY_IN_FOLDER, DPI(16), DPI(16)); - m_icon_set.bitrate = CDrawCommon::LoadIconResource(IDI_BITRATE, DPI(16), DPI(16)); - m_icon_set.reverb = CDrawCommon::LoadIconResource(IDI_REVERB, DPI(16), DPI(16)); - m_icon_set.hot_key = CDrawCommon::LoadIconResource(IDI_HOT_KEY, DPI(16), DPI(16)); - m_icon_set.fix = CDrawCommon::LoadIconResource(IDI_FIX_D, DPI(16), DPI(16)); - - m_icon_set.ok = CDrawCommon::LoadIconResource(IDI_OK_D, DPI(16), DPI(16)); - - //加载通知区图标 - m_icon_set.notify_icons[0] = m_icon_set.app.GetIcon(); //应用图标直接使用前面加载过的 - m_icon_set.notify_icons[1] = CDrawCommon::LoadIconResource(IDI_APP_LIGHT, DPI(16), DPI(16)); - m_icon_set.notify_icons[2] = CDrawCommon::LoadIconResource(IDI_APP_DARK, DPI(16), DPI(16)); - //加载图片资源 - m_image_set.default_cover = CCommon::GetPngImageResource(IDB_DEFAULT_ALBUM_COVER); - m_image_set.default_cover_not_played = CCommon::GetPngImageResource(IDB_DEFAULT_ALBUM_COVER_NOT_PLAYED); - - m_image_set.default_cover_data = CCommon::GetPngImageResourceData(IDB_DEFAULT_ALBUM_COVER); - m_image_set.default_cover_not_played_data = CCommon::GetPngImageResourceData(IDB_DEFAULT_ALBUM_COVER_NOT_PLAYED); -} - -void CMusicPlayerApp::InitMenuResourse() -{ - m_menu_set.m_main_menu.LoadMenu(IDR_MENU1); - AddMenuShortcuts(&m_menu_set.m_main_menu); - m_menu_set.m_list_popup_menu.LoadMenu(IDR_POPUP_MENU); //装载播放列表右键菜单 - AddMenuShortcuts(&m_menu_set.m_list_popup_menu); - m_menu_set.m_playlist_toolbar_menu.LoadMenu(IDR_PLAYLIST_TOOLBAR_MENU); - AddMenuShortcuts(&m_menu_set.m_playlist_toolbar_menu); - - m_menu_set.m_popup_menu.LoadMenu(IDR_LYRIC_POPUP_MENU); //装载歌词右键菜单 - AddMenuShortcuts(&m_menu_set.m_popup_menu); - m_menu_set.m_main_popup_menu.LoadMenu(IDR_MAIN_POPUP_MENU); - AddMenuShortcuts(&m_menu_set.m_main_popup_menu); - - m_menu_set.m_playlist_btn_menu.LoadMenu(IDR_PLAYLIST_BTN_MENU); - m_menu_set.m_lyric_default_style.LoadMenu(IDR_LRYIC_DEFAULT_STYLE_MENU); - m_menu_set.m_media_lib_popup_menu.LoadMenu(IDR_MEDIA_LIB_POPUP_MENU); - - m_menu_set.m_media_lib_folder_menu.LoadMenu(IDR_SET_PATH_POPUP_MENU); - m_menu_set.m_media_lib_folder_menu.GetSubMenu(0)->SetDefaultItem(ID_PLAY_PATH); - - m_menu_set.m_media_lib_playlist_menu.LoadMenu(IDR_SELETE_PLAYLIST_POPUP_MENU); - m_menu_set.m_media_lib_playlist_menu.GetSubMenu(0)->SetDefaultItem(ID_PLAY_PLAYLIST); - - m_menu_set.m_notify_menu.LoadMenu(IDR_NOTIFY_MENU); - //AddMenuShortcuts(&m_menu_set.m_notify_menu); - m_menu_set.m_mini_mode_menu.LoadMenu(IDR_MINI_MODE_MENU); - AddMenuShortcuts(&m_menu_set.m_mini_mode_menu); - m_menu_set.m_property_cover_menu.LoadMenu(IDR_PROPERTY_COVER_MENU); - m_menu_set.m_property_menu.LoadMenu(IDR_PROPERTY_MENU); - - //为菜单添加图标 - //主菜单 - //文件 - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_FILE_OPEN, FALSE, m_icon_set.music); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_FILE_OPEN_FOLDER, FALSE, m_icon_set.select_folder.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_FILE_OPEN_PLAYLIST, FALSE, m_icon_set.show_playlist.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_FILE_OPEN_URL, FALSE, m_icon_set.link.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_MENU_EXIT, FALSE, m_icon_set.exit); - //播放控制 - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_PLAY_PAUSE, FALSE, m_icon_set.play_pause); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_STOP, FALSE, m_icon_set.stop_new); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_PREVIOUS, FALSE, m_icon_set.previous_new.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_NEXT, FALSE, m_icon_set.next_new.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_REW, FALSE, m_icon_set.rew_new); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_FF, FALSE, m_icon_set.ff_new); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_SPEED_UP, FALSE, m_icon_set.speed_up); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_SLOW_DOWN, FALSE, m_icon_set.slow_down); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_PLAY_ORDER, FALSE, m_icon_set.play_oder.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_PLAY_SHUFFLE, FALSE, m_icon_set.play_shuffle.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_PLAY_RANDOM, FALSE, m_icon_set.play_random.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_LOOP_PLAYLIST, FALSE, m_icon_set.loop_playlist.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_LOOP_TRACK, FALSE, m_icon_set.loop_track.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_PLAY_TRACK, FALSE, m_icon_set.play_track.GetIcon(true)); - //播放列表 - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSubMenu(2)->GetSafeHmenu(), 0, TRUE, m_icon_set.add.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_PLAYLIST_ADD_FILE, FALSE, m_icon_set.music); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_PLAYLIST_ADD_FOLDER, FALSE, m_icon_set.select_folder.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_PLAYLIST_ADD_URL, FALSE, m_icon_set.link.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSubMenu(2)->GetSafeHmenu(), 1, TRUE, m_icon_set.close.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_RELOAD_PLAYLIST, FALSE, m_icon_set.loop_playlist.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_SAVE_AS_NEW_PLAYLIST, FALSE, m_icon_set.save_new); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_SAVE_CURRENT_PLAYLIST_AS, FALSE, m_icon_set.save_as); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSubMenu(2)->GetSafeHmenu(), 7, TRUE, m_icon_set.sort.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSubMenu(2)->GetSafeHmenu(), 8, TRUE, m_icon_set.display_mode.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_LOCATE_TO_CURRENT, FALSE, m_icon_set.locate.GetIcon(true)); - //歌词 - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_RELOAD_LYRIC, FALSE, m_icon_set.loop_playlist.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_COPY_CURRENT_LYRIC, FALSE, m_icon_set.copy); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_EDIT_LYRIC, FALSE, m_icon_set.edit.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_LYRIC_FORWARD, FALSE, m_icon_set.lyric_forward.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_LYRIC_DELAY, FALSE, m_icon_set.lyric_delay.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_SAVE_MODIFIED_LYRIC, FALSE, m_icon_set.save_new); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_RELATE_LOCAL_LYRIC, FALSE, m_icon_set.lyric.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_DELETE_LYRIC, FALSE, m_icon_set.close.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_UNLINK_LYRIC, FALSE, m_icon_set.unlink.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_BROWSE_LYRIC, FALSE, m_icon_set.folder_explore.GetIcon(true)); - ASSERT(m_menu_set.m_main_menu.GetSubMenu(3)->GetSubMenu(18) != nullptr); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSubMenu(3)->GetSafeHmenu(), 18, TRUE, m_icon_set.internal_lyric); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_DOWNLOAD_LYRIC, FALSE, m_icon_set.download); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_LYRIC_BATCH_DOWNLOAD, FALSE, m_icon_set.download1); - //视图 - if (!CWinVersionHelper::IsWindows11OrLater()) - { - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_SHOW_PLAYLIST, FALSE, m_icon_set.playlist_dock.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_FLOAT_PLAYLIST, FALSE, m_icon_set.playlist_float); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_SHOW_MENU_BAR, FALSE, m_icon_set.menu.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_ALWAYS_ON_TOP, FALSE, m_icon_set.pin); - } - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_MINI_MODE, FALSE, m_icon_set.mini.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_FULL_SCREEN, FALSE, m_icon_set.full_screen1.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_DARK_MODE, FALSE, m_icon_set.dark_mode.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_SWITCH_UI, FALSE, m_icon_set.skin.GetIcon(true)); - ASSERT(m_menu_set.m_main_menu.GetSubMenu(4)->GetSubMenu(11) != nullptr); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSubMenu(4)->GetSafeHmenu(), 11, TRUE, m_icon_set.skin.GetIcon(true)); - //工具 - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_SET_PATH, FALSE, m_icon_set.media_lib.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_FIND, FALSE, m_icon_set.find_songs.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_EXPLORE_PATH, FALSE, m_icon_set.folder_explore.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_SONG_INFO, FALSE, m_icon_set.info.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_EQUALIZER, FALSE, m_icon_set.eq.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_FORMAT_CONVERT1, FALSE, m_icon_set.convert); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_CURRENT_EXPLORE_ONLINE, FALSE, m_icon_set.online); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_RE_INI_BASS, FALSE, m_icon_set.loop_playlist.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_LISTEN_STATISTICS, FALSE, m_icon_set.statistics); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_TOOL_FILE_RELATE, FALSE, m_icon_set.file_relate); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_OPTION_SETTINGS, FALSE, m_icon_set.setting.GetIcon(true)); - ASSERT(m_menu_set.m_main_menu.GetSubMenu(5)->GetSubMenu(9) != nullptr); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSubMenu(5)->GetSafeHmenu(), 9, TRUE, m_icon_set.shortcut); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSubMenu(5)->GetSafeHmenu(), 11, TRUE, m_icon_set.album_cover); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_DOWNLOAD_ALBUM_COVER, FALSE, m_icon_set.download); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_ALBUM_COVER_SAVE_AS, FALSE, m_icon_set.save_as); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_DELETE_ALBUM_COVER, FALSE, m_icon_set.close.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_ALBUM_COVER_INFO, FALSE, m_icon_set.album_cover); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSubMenu(5)->GetSafeHmenu(), 12, TRUE, m_icon_set.close.GetIcon(true)); - //帮助 - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_HELP, FALSE, m_icon_set.help.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu.GetSafeHmenu(), ID_APP_ABOUT, FALSE, m_icon_set.app.GetIcon()); - - //界面右键菜单 - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_popup_menu.GetSafeHmenu(), ID_SONG_INFO, FALSE, m_icon_set.info.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_popup_menu.GetSafeHmenu(), ID_PLAY_ORDER, FALSE, m_icon_set.play_oder.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_popup_menu.GetSafeHmenu(), ID_PLAY_SHUFFLE, FALSE, m_icon_set.play_shuffle.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_popup_menu.GetSafeHmenu(), ID_PLAY_RANDOM, FALSE, m_icon_set.play_random.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_popup_menu.GetSafeHmenu(), ID_LOOP_PLAYLIST, FALSE, m_icon_set.loop_playlist.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_popup_menu.GetSafeHmenu(), ID_LOOP_TRACK, FALSE, m_icon_set.loop_track.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_popup_menu.GetSafeHmenu(), ID_PLAY_TRACK, FALSE, m_icon_set.play_track.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_popup_menu.GetSubMenu(0)->GetSafeHmenu(), 2, TRUE, m_icon_set.add.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_popup_menu.GetSubMenu(0)->GetSafeHmenu(), 3, TRUE, m_icon_set.star); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_popup_menu.GetSafeHmenu(), ID_ADD_TO_NEW_PLAYLIST, FALSE, m_icon_set.add.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_popup_menu.GetSafeHmenu(), ID_ADD_TO_MY_FAVOURITE, FALSE, m_icon_set.favourite.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_popup_menu.GetSafeHmenu(), ID_VIEW_ARTIST, FALSE, m_icon_set.artist.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_popup_menu.GetSafeHmenu(), ID_VIEW_ALBUM, FALSE, m_icon_set.album.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_popup_menu.GetSafeHmenu(), ID_SET_PATH, FALSE, m_icon_set.media_lib.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_popup_menu.GetSafeHmenu(), ID_FIND, FALSE, m_icon_set.find_songs.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_popup_menu.GetSafeHmenu(), ID_EXPLORE_PATH, FALSE, m_icon_set.folder_explore.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_popup_menu.GetSafeHmenu(), ID_EQUALIZER, FALSE, m_icon_set.eq.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_popup_menu.GetSafeHmenu(), ID_CURRENT_EXPLORE_ONLINE, FALSE, m_icon_set.online); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_popup_menu.GetSafeHmenu(), ID_DOWNLOAD_ALBUM_COVER, FALSE, m_icon_set.album_cover); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_popup_menu.GetSafeHmenu(), ID_ALBUM_COVER_SAVE_AS, FALSE, m_icon_set.save_as); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_popup_menu.GetSafeHmenu(), ID_DELETE_ALBUM_COVER, FALSE, m_icon_set.close.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_popup_menu.GetSafeHmenu(), ID_ALBUM_COVER_INFO, FALSE, m_icon_set.album_cover); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_popup_menu.GetSafeHmenu(), ID_SWITCH_UI, FALSE, m_icon_set.skin.GetIcon(true)); - ASSERT(m_menu_set.m_main_popup_menu.GetSubMenu(0)->GetSubMenu(20) != nullptr); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_popup_menu.GetSubMenu(0)->GetSafeHmenu(), 20, TRUE, m_icon_set.skin.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_popup_menu.GetSafeHmenu(), ID_OPTION_SETTINGS, FALSE, m_icon_set.setting.GetIcon(true)); - - //歌词右键菜单 - CMenuIcon::AddIconToMenuItem(m_menu_set.m_popup_menu.GetSafeHmenu(), ID_RELOAD_LYRIC, FALSE, m_icon_set.loop_playlist.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_popup_menu.GetSafeHmenu(), ID_COPY_CURRENT_LYRIC, FALSE, m_icon_set.copy); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_popup_menu.GetSafeHmenu(), ID_EDIT_LYRIC, FALSE, m_icon_set.edit.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_popup_menu.GetSafeHmenu(), ID_LYRIC_FORWARD, FALSE, m_icon_set.lyric_forward.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_popup_menu.GetSafeHmenu(), ID_LYRIC_DELAY, FALSE, m_icon_set.lyric_delay.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_popup_menu.GetSafeHmenu(), ID_SAVE_MODIFIED_LYRIC, FALSE, m_icon_set.save_new); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_popup_menu.GetSafeHmenu(), ID_RELATE_LOCAL_LYRIC, FALSE, m_icon_set.lyric.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_popup_menu.GetSafeHmenu(), ID_DELETE_LYRIC, FALSE, m_icon_set.close.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_popup_menu.GetSafeHmenu(), ID_UNLINK_LYRIC, FALSE, m_icon_set.unlink.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_popup_menu.GetSafeHmenu(), ID_BROWSE_LYRIC, FALSE, m_icon_set.folder_explore.GetIcon(true)); - ASSERT(m_menu_set.m_popup_menu.GetSubMenu(0)->GetSubMenu(17) != nullptr); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_popup_menu.GetSubMenu(0)->GetSafeHmenu(), 17, TRUE, m_icon_set.internal_lyric); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_popup_menu.GetSafeHmenu(), ID_DOWNLOAD_LYRIC, FALSE, m_icon_set.download); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_popup_menu.GetSafeHmenu(), ID_LYRIC_BATCH_DOWNLOAD, FALSE, m_icon_set.download1); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_popup_menu.GetSafeHmenu(), ID_SWITCH_UI, FALSE, m_icon_set.skin.GetIcon(true)); - ASSERT(m_menu_set.m_popup_menu.GetSubMenu(0)->GetSubMenu(22) != nullptr); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_popup_menu.GetSubMenu(0)->GetSafeHmenu(), 22, TRUE, m_icon_set.skin.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_popup_menu.GetSafeHmenu(), ID_OPTION_SETTINGS, FALSE, m_icon_set.setting.GetIcon(true)); - - //播放列表菜单 - CMenuIcon::AddIconToMenuItem(m_menu_set.m_playlist_toolbar_menu.GetSafeHmenu(), ID_FILE_OPEN_FOLDER, FALSE, m_icon_set.select_folder.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_playlist_toolbar_menu.GetSafeHmenu(), ID_PLAYLIST_ADD_FILE, FALSE, m_icon_set.music); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_playlist_toolbar_menu.GetSafeHmenu(), ID_PLAYLIST_ADD_FOLDER, FALSE, m_icon_set.select_folder.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_playlist_toolbar_menu.GetSafeHmenu(), ID_PLAYLIST_ADD_URL, FALSE, m_icon_set.link.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_playlist_toolbar_menu.GetSafeHmenu(), ID_REMOVE_FROM_PLAYLIST, FALSE, m_icon_set.close.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_playlist_toolbar_menu.GetSafeHmenu(), ID_RELOAD_PLAYLIST, FALSE, m_icon_set.loop_playlist.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_playlist_toolbar_menu.GetSafeHmenu(), ID_SAVE_AS_NEW_PLAYLIST, FALSE, m_icon_set.save_new); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_playlist_toolbar_menu.GetSafeHmenu(), ID_SAVE_CURRENT_PLAYLIST_AS, FALSE, m_icon_set.save_as); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_playlist_toolbar_menu.GetSafeHmenu(), ID_PLAYLIST_FIX_PATH_ERROR, FALSE, m_icon_set.fix); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_playlist_toolbar_menu.GetSubMenu(3)->GetSafeHmenu(), 5, TRUE, m_icon_set.display_mode.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_playlist_toolbar_menu.GetSafeHmenu(), ID_PLAYLIST_OPTIONS, FALSE, m_icon_set.setting.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_playlist_toolbar_menu.GetSubMenu(4)->GetSafeHmenu(), 0, TRUE, m_icon_set.add.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_playlist_toolbar_menu.GetSafeHmenu(), ID_ADD_TO_NEW_PLAYLIST, FALSE, m_icon_set.add.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_playlist_toolbar_menu.GetSafeHmenu(), ID_ADD_TO_MY_FAVOURITE, FALSE, m_icon_set.favourite.GetIcon(true)); - - //播放列表右键菜单 - CMenuIcon::AddIconToMenuItem(m_menu_set.m_list_popup_menu.GetSafeHmenu(), ID_PLAY_ITEM, FALSE, m_icon_set.play_new.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_list_popup_menu.GetSafeHmenu(), ID_PLAY_AS_NEXT, FALSE, m_icon_set.play_as_next); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_list_popup_menu.GetSafeHmenu(), ID_EXPLORE_ONLINE, FALSE, m_icon_set.online); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_list_popup_menu.GetSafeHmenu(), ID_FORMAT_CONVERT, FALSE, m_icon_set.convert); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_list_popup_menu.GetSubMenu(0)->GetSafeHmenu(), 5, TRUE, m_icon_set.star); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_list_popup_menu.GetSafeHmenu(), ID_RELOAD_PLAYLIST, FALSE, m_icon_set.loop_playlist.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_list_popup_menu.GetSafeHmenu(), ID_REMOVE_FROM_PLAYLIST, FALSE, m_icon_set.close.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_list_popup_menu.GetSubMenu(0)->GetSafeHmenu(), 12, TRUE, m_icon_set.add.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_list_popup_menu.GetSafeHmenu(), ID_ADD_TO_NEW_PLAYLIST, FALSE, m_icon_set.add.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_list_popup_menu.GetSafeHmenu(), ID_ADD_TO_MY_FAVOURITE, FALSE, m_icon_set.favourite.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_list_popup_menu.GetSafeHmenu(), ID_RENAME, FALSE, m_icon_set.rename); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_list_popup_menu.GetSafeHmenu(), ID_EXPLORE_TRACK, FALSE, m_icon_set.folder_explore.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_list_popup_menu.GetSafeHmenu(), ID_ITEM_PROPERTY, FALSE, m_icon_set.info.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_list_popup_menu.GetSafeHmenu(), ID_PLAYLIST_VIEW_ARTIST, FALSE, m_icon_set.artist.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_list_popup_menu.GetSafeHmenu(), ID_PLAYLIST_VIEW_ALBUM, FALSE, m_icon_set.album.GetIcon(true)); - - //媒体库-文件夹的右键菜单 - CMenuIcon::AddIconToMenuItem(m_menu_set.m_media_lib_folder_menu.GetSafeHmenu(), ID_PLAY_PATH, FALSE, m_icon_set.play_new.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_media_lib_folder_menu.GetSafeHmenu(), ID_DELETE_PATH, FALSE, m_icon_set.close.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_media_lib_folder_menu.GetSafeHmenu(), ID_BROWSE_PATH, FALSE, m_icon_set.folder_explore.GetIcon(true)); - - //媒体库-播放列表的右键菜单 - CMenuIcon::AddIconToMenuItem(m_menu_set.m_media_lib_playlist_menu.GetSafeHmenu(), ID_PLAY_PLAYLIST, FALSE, m_icon_set.play_new.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_media_lib_playlist_menu.GetSafeHmenu(), ID_DELETE_PLAYLIST, FALSE, m_icon_set.close.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_media_lib_playlist_menu.GetSafeHmenu(), ID_RENAME_PLAYLIST, FALSE, m_icon_set.rename); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_media_lib_playlist_menu.GetSafeHmenu(), ID_NEW_PLAYLIST, FALSE, m_icon_set.add.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_media_lib_playlist_menu.GetSafeHmenu(), ID_SAVE_AS_NEW_PLAYLIST, FALSE, m_icon_set.save_new); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_media_lib_playlist_menu.GetSafeHmenu(), ID_PLAYLIST_SAVE_AS, FALSE, m_icon_set.save_as); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_media_lib_playlist_menu.GetSafeHmenu(), ID_PLAYLIST_FIX_PATH_ERROR, FALSE, m_icon_set.fix); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_media_lib_playlist_menu.GetSafeHmenu(), ID_PLAYLIST_BROWSE_FILE, FALSE, m_icon_set.folder_explore.GetIcon(true)); - - //媒体库右键菜单 - //左侧菜单 - CMenuIcon::AddIconToMenuItem(m_menu_set.m_media_lib_popup_menu.GetSafeHmenu(), ID_PLAY_ITEM, FALSE, m_icon_set.play_new.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_media_lib_popup_menu.GetSubMenu(0)->GetSafeHmenu(), 1, TRUE, m_icon_set.add.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_media_lib_popup_menu.GetSafeHmenu(), ID_ADD_TO_NEW_PLAYLIST, FALSE, m_icon_set.add.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_media_lib_popup_menu.GetSafeHmenu(), ID_ADD_TO_MY_FAVOURITE, FALSE, m_icon_set.favourite.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_media_lib_popup_menu.GetSubMenu(0)->GetSafeHmenu(), ID_ADD_TO_NEW_PALYLIST_AND_PLAY, FALSE, m_icon_set.play_in_playlist); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_media_lib_popup_menu.GetSubMenu(0)->GetSafeHmenu(), ID_COPY_TEXT, FALSE, m_icon_set.copy); - //右侧菜单 - CMenuIcon::AddIconToMenuItem(m_menu_set.m_media_lib_popup_menu.GetSubMenu(1)->GetSafeHmenu(), ID_PLAY_ITEM, FALSE, m_icon_set.play_new.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_media_lib_popup_menu.GetSubMenu(1)->GetSafeHmenu(), ID_PLAY_AS_NEXT, FALSE, m_icon_set.play_as_next); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_media_lib_popup_menu.GetSubMenu(1)->GetSafeHmenu(), ID_PLAY_ITEM_IN_FOLDER_MODE, FALSE, m_icon_set.play_in_folder); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_media_lib_popup_menu.GetSubMenu(1)->GetSafeHmenu(), 4, TRUE, m_icon_set.add.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_media_lib_popup_menu.GetSubMenu(1)->GetSafeHmenu(), ID_ADD_TO_NEW_PLAYLIST, FALSE, m_icon_set.add.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_media_lib_popup_menu.GetSubMenu(1)->GetSafeHmenu(), ID_ADD_TO_MY_FAVOURITE, FALSE, m_icon_set.favourite.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_media_lib_popup_menu.GetSubMenu(1)->GetSafeHmenu(), ID_ADD_TO_NEW_PALYLIST_AND_PLAY, FALSE, m_icon_set.play_in_playlist); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_media_lib_popup_menu.GetSubMenu(1)->GetSafeHmenu(), ID_EXPLORE_ONLINE, FALSE, m_icon_set.online); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_media_lib_popup_menu.GetSubMenu(1)->GetSafeHmenu(), ID_FORMAT_CONVERT, FALSE, m_icon_set.convert); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_media_lib_popup_menu.GetSubMenu(1)->GetSafeHmenu(), ID_EXPLORE_TRACK, FALSE, m_icon_set.folder_explore.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_media_lib_popup_menu.GetSubMenu(1)->GetSafeHmenu(), ID_DELETE_FROM_DISK, FALSE, m_icon_set.close.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_media_lib_popup_menu.GetSubMenu(1)->GetSafeHmenu(), ID_ITEM_PROPERTY, FALSE, m_icon_set.info.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_media_lib_popup_menu.GetSubMenu(1)->GetSafeHmenu(), ID_COPY_TEXT, FALSE, m_icon_set.copy); - - //通知区图标右键菜单 - CMenuIcon::AddIconToMenuItem(m_menu_set.m_notify_menu.GetSafeHmenu(), ID_PLAY_PAUSE, FALSE, m_icon_set.play_pause); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_notify_menu.GetSafeHmenu(), ID_PREVIOUS, FALSE, m_icon_set.previous_new.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_notify_menu.GetSafeHmenu(), ID_NEXT, FALSE, m_icon_set.next_new.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_notify_menu.GetSafeHmenu(), ID_PLAY_ORDER, FALSE, m_icon_set.play_oder.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_notify_menu.GetSafeHmenu(), ID_PLAY_SHUFFLE, FALSE, m_icon_set.play_shuffle.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_notify_menu.GetSafeHmenu(), ID_PLAY_RANDOM, FALSE, m_icon_set.play_random.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_notify_menu.GetSafeHmenu(), ID_LOOP_PLAYLIST, FALSE, m_icon_set.loop_playlist.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_notify_menu.GetSafeHmenu(), ID_LOOP_TRACK, FALSE, m_icon_set.loop_track.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_notify_menu.GetSafeHmenu(), ID_PLAY_TRACK, FALSE, m_icon_set.play_track.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_notify_menu.GetSafeHmenu(), ID_MINIMODE_RESTORE, FALSE, m_icon_set.mini.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_notify_menu.GetSafeHmenu(), ID_SHOW_DESKTOP_LYRIC, FALSE, m_icon_set.lyric.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_notify_menu.GetSafeHmenu(), ID_LOCK_DESKTOP_LRYIC, FALSE, m_icon_set.lock.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_notify_menu.GetSafeHmenu(), ID_OPTION_SETTINGS, FALSE, m_icon_set.setting.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_notify_menu.GetSafeHmenu(), ID_MENU_EXIT, FALSE, m_icon_set.exit); - - //迷你模式右键菜单 - CMenuIcon::AddIconToMenuItem(m_menu_set.m_mini_mode_menu.GetSafeHmenu(), ID_SONG_INFO, FALSE, m_icon_set.info.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_mini_mode_menu.GetSafeHmenu(), ID_PLAY_ORDER, FALSE, m_icon_set.play_oder.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_mini_mode_menu.GetSafeHmenu(), ID_PLAY_SHUFFLE, FALSE, m_icon_set.play_shuffle.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_mini_mode_menu.GetSafeHmenu(), ID_PLAY_RANDOM, FALSE, m_icon_set.play_random.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_mini_mode_menu.GetSafeHmenu(), ID_LOOP_PLAYLIST, FALSE, m_icon_set.loop_playlist.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_mini_mode_menu.GetSafeHmenu(), ID_LOOP_TRACK, FALSE, m_icon_set.loop_track.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_mini_mode_menu.GetSafeHmenu(), ID_PLAY_TRACK, FALSE, m_icon_set.play_track.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_mini_mode_menu.GetSubMenu(0)->GetSafeHmenu(), 2, TRUE, m_icon_set.add.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_mini_mode_menu.GetSafeHmenu(), ID_ADD_TO_NEW_PLAYLIST, FALSE, m_icon_set.add.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_mini_mode_menu.GetSafeHmenu(), ID_ADD_TO_MY_FAVOURITE, FALSE, m_icon_set.favourite.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_mini_mode_menu.GetSafeHmenu(), ID_DOWNLOAD_LYRIC, FALSE, m_icon_set.download); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_mini_mode_menu.GetSafeHmenu(), ID_DOWNLOAD_ALBUM_COVER, FALSE, m_icon_set.album_cover); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_mini_mode_menu.GetSafeHmenu(), ID_ADD_REMOVE_FROM_FAVOURITE, FALSE, m_icon_set.favourite.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_mini_mode_menu.GetSafeHmenu(), ID_SET_PATH, FALSE, m_icon_set.media_lib.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_mini_mode_menu.GetSafeHmenu(), ID_FIND, FALSE, m_icon_set.find_songs.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_mini_mode_menu.GetSafeHmenu(), ID_EXPLORE_PATH, FALSE, m_icon_set.folder_explore.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_mini_mode_menu.GetSafeHmenu(), ID_EQUALIZER, FALSE, m_icon_set.eq.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_mini_mode_menu.GetSafeHmenu(), ID_OPTION_SETTINGS, FALSE, m_icon_set.setting.GetIcon(true)); - if (!CWinVersionHelper::IsWindows11OrLater()) - { - CMenuIcon::AddIconToMenuItem(m_menu_set.m_mini_mode_menu.GetSafeHmenu(), ID_SHOW_PLAY_LIST, FALSE, m_icon_set.show_playlist.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_mini_mode_menu.GetSafeHmenu(), ID_MINI_MODE_ALWAYS_ON_TOP, FALSE, m_icon_set.pin); - } - CMenuIcon::AddIconToMenuItem(m_menu_set.m_mini_mode_menu.GetSubMenu(0)->GetSafeHmenu(), 17, TRUE, m_icon_set.skin.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_mini_mode_menu.GetSafeHmenu(), ID_MINI_MIDE_MINIMIZE, FALSE, m_icon_set.minimize.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_mini_mode_menu.GetSafeHmenu(), IDOK, FALSE, m_icon_set.mini_restore.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_mini_mode_menu.GetSafeHmenu(), ID_MINI_MODE_EXIT, FALSE, m_icon_set.exit); - - //属性——专辑封面右键菜单 - CMenuIcon::AddIconToMenuItem(m_menu_set.m_property_cover_menu.GetSafeHmenu(), ID_COVER_BROWSE, FALSE, m_icon_set.folder_explore.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_property_cover_menu.GetSafeHmenu(), ID_COVER_DELETE, FALSE, m_icon_set.close.GetIcon(true)); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_property_cover_menu.GetSafeHmenu(), ID_COVER_SAVE_AS, FALSE, m_icon_set.save_as); - - - //初始化按Shift键弹出的右键菜单 - m_menu_set.m_main_menu_popup.CreatePopupMenu(); - CCommon::AppendMenuOp(m_menu_set.m_main_menu_popup.GetSafeHmenu(), m_menu_set.m_main_menu.GetSafeHmenu()); - m_menu_set.m_main_menu_popup.AppendMenu(MF_SEPARATOR); - CString exitStr; - m_menu_set.m_main_menu.GetMenuString(ID_MENU_EXIT, exitStr, 0); - m_menu_set.m_main_menu_popup.AppendMenu(MF_STRING, ID_MENU_EXIT, exitStr); - //为一级菜单添加图标 - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu_popup.GetSafeHmenu(), 0, TRUE, m_icon_set.select_folder.GetIcon(true)); //文件 - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu_popup.GetSafeHmenu(), 1, TRUE, m_icon_set.play_new.GetIcon(true)); //播放控制 - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu_popup.GetSafeHmenu(), 2, TRUE, m_icon_set.show_playlist.GetIcon(true)); //播放列表 - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu_popup.GetSafeHmenu(), 3, TRUE, m_icon_set.lyric.GetIcon(true)); //歌词 - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu_popup.GetSafeHmenu(), 4, TRUE, m_icon_set.playlist_dock.GetIcon(true)); //视图 - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu_popup.GetSafeHmenu(), 5, TRUE, m_icon_set.setting.GetIcon(true)); //工具 - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu_popup.GetSafeHmenu(), 6, TRUE, m_icon_set.help.GetIcon(true)); //帮助 - int index = m_menu_set.m_main_menu_popup.GetMenuItemCount(); - CMenuIcon::AddIconToMenuItem(m_menu_set.m_main_menu_popup.GetSafeHmenu(), index - 1, TRUE, m_icon_set.exit); //退出 - - //将主菜单添加到系统菜单中 - CMenu* pSysMenu = m_pMainWnd->GetSystemMenu(FALSE); - if (pSysMenu != NULL) - { - pSysMenu->AppendMenu(MF_SEPARATOR); - index = pSysMenu->GetMenuItemCount(); - CCommon::AppendMenuOp(pSysMenu->GetSafeHmenu(), m_menu_set.m_main_menu.GetSafeHmenu()); //将主菜单添加到系统菜单 - //为一级菜单添加图标 - CMenuIcon::AddIconToMenuItem(pSysMenu->GetSafeHmenu(), index + 0, TRUE, m_icon_set.select_folder.GetIcon(true)); //文件 - CMenuIcon::AddIconToMenuItem(pSysMenu->GetSafeHmenu(), index + 1, TRUE, m_icon_set.play_new.GetIcon(true)); //播放控制 - CMenuIcon::AddIconToMenuItem(pSysMenu->GetSafeHmenu(), index + 2, TRUE, m_icon_set.show_playlist.GetIcon(true)); //播放列表 - CMenuIcon::AddIconToMenuItem(pSysMenu->GetSafeHmenu(), index + 3, TRUE, m_icon_set.music); //歌词 - CMenuIcon::AddIconToMenuItem(pSysMenu->GetSafeHmenu(), index + 4, TRUE, m_icon_set.playlist_dock.GetIcon(true)); //视图 - CMenuIcon::AddIconToMenuItem(pSysMenu->GetSafeHmenu(), index + 5, TRUE, m_icon_set.setting.GetIcon(true)); //工具 - CMenuIcon::AddIconToMenuItem(pSysMenu->GetSafeHmenu(), index + 6, TRUE, m_icon_set.help.GetIcon(true)); //帮助 - - pSysMenu->AppendMenu(MF_SEPARATOR); - pSysMenu->AppendMenu(MF_STRING, IDM_MINIMODE, CCommon::LoadText(IDS_MINI_MODE2, _T("\tCtrl+M"))); - CMenuIcon::AddIconToMenuItem(pSysMenu->GetSafeHmenu(), IDM_MINIMODE, FALSE, m_icon_set.mini.GetIcon(true)); - - CString exitStr; - m_menu_set.m_main_menu.GetMenuString(ID_MENU_EXIT, exitStr, 0); - pSysMenu->AppendMenu(MF_STRING, ID_MENU_EXIT, exitStr); - index = pSysMenu->GetMenuItemCount(); - CMenuIcon::AddIconToMenuItem(pSysMenu->GetSafeHmenu(), index - 1, TRUE, m_icon_set.exit); //由于“文件”子菜单下已经有一个“退出”,命令,因此这里只能通过菜单项的序号指定 - - //添加一个测试命令 -#ifdef _DEBUG - pSysMenu->AppendMenu(MF_STRING, ID_TEST, _T("Test Command")); - pSysMenu->AppendMenu(MF_STRING, ID_TEST_DIALOG, _T("Test Dialog")); -#endif - } + m_image_set.default_cover_img = CCommon::GetPngImageResource(IDB_DEFAULT_ALBUM_COVER); + m_image_set.default_cover_not_played_img = CCommon::GetPngImageResource(IDB_DEFAULT_ALBUM_COVER_NOT_PLAYED); - //初始化播放列表工具栏弹出菜单 - m_menu_set.m_playlist_toolbar_popup_menu.CreatePopupMenu(); - CCommon::AppendMenuOp(m_menu_set.m_playlist_toolbar_popup_menu.GetSafeHmenu(), m_menu_set.m_playlist_toolbar_menu.GetSafeHmenu()); - m_menu_set.m_playlist_toolbar_popup_menu.AppendMenu(MF_SEPARATOR); - CString temp = CCommon::LoadText(IDS_LOCATE, CPlayerUIBase::GetCmdShortcutKeyForTooltips(ID_LOCATE_TO_CURRENT)); - m_menu_set.m_playlist_toolbar_popup_menu.AppendMenu(MF_STRING, ID_LOCATE_TO_CURRENT, temp); - //为播放列表工具栏弹出菜单添加图标 - CMenuIcon::AddIconToMenuItem(m_menu_set.m_playlist_toolbar_popup_menu.GetSafeHmenu(), 0, TRUE, m_icon_set.add.GetIcon(true)); //添加 - CMenuIcon::AddIconToMenuItem(m_menu_set.m_playlist_toolbar_popup_menu.GetSafeHmenu(), 1, TRUE, m_icon_set.close.GetIcon(true)); //删除 - CMenuIcon::AddIconToMenuItem(m_menu_set.m_playlist_toolbar_popup_menu.GetSafeHmenu(), 2, TRUE, m_icon_set.sort.GetIcon(true)); //排序 - CMenuIcon::AddIconToMenuItem(m_menu_set.m_playlist_toolbar_popup_menu.GetSafeHmenu(), 3, TRUE, m_icon_set.show_playlist.GetIcon(true)); //列表 - CMenuIcon::AddIconToMenuItem(m_menu_set.m_playlist_toolbar_popup_menu.GetSafeHmenu(), 4, TRUE, m_icon_set.edit.GetIcon(true)); //编辑 - CMenuIcon::AddIconToMenuItem(m_menu_set.m_playlist_toolbar_popup_menu.GetSafeHmenu(), 5, TRUE, m_icon_set.select_folder.GetIcon(true)); //文件夹 - CMenuIcon::AddIconToMenuItem(m_menu_set.m_playlist_toolbar_popup_menu.GetSafeHmenu(), ID_LOCATE_TO_CURRENT, FALSE, m_icon_set.locate.GetIcon(true)); //文件夹 -} - -void CMusicPlayerApp::AddMenuShortcuts(CMenu* pMenu) -{ - //遍历所有子菜单项 - CCommon::IterateMenuItem(pMenu, [&](CMenu* pParentNenu, UINT id) - { - CString menu_text; - pParentNenu->GetMenuString(id, menu_text, MF_BYCOMMAND); - std::wstring shortcut = m_accelerator_res.GetShortcutDescriptionById(id); - if (!shortcut.empty()) - { - menu_text += _T("\t"); - menu_text += shortcut.c_str(); - pParentNenu->ModifyMenu(id, MF_BYCOMMAND, id, menu_text); - } - }); + m_image_set.default_cover_img_data = CCommon::GetPngImageResourceData(IDB_DEFAULT_ALBUM_COVER); + m_image_set.default_cover_not_played_img_data = CCommon::GetPngImageResourceData(IDB_DEFAULT_ALBUM_COVER_NOT_PLAYED); } int CMusicPlayerApp::DPI(int pixel) @@ -1056,55 +545,19 @@ void CMusicPlayerApp::GetDPIFromWindow(CWnd* pWnd) m_dpi = GetDeviceCaps(hDC, LOGPIXELSY); } -WORD CMusicPlayerApp::GetCurrentLanguage() const +wstring CMusicPlayerApp::GetSystemInfoString() { - switch (m_general_setting_data.language) - { - case Language::SIMPLIFIED_CHINESE: - return MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED); - default: - return MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US); - } -} + std::wstringstream wss; + wss << L"System Info:\r\n" + << L"Windows Version: " << CWinVersionHelper::GetMajorVersion() << L'.' << CWinVersionHelper::GetMinorVersion() + << L" build " << CWinVersionHelper::GetBuildNumber() << L"\r\n" + << L"DPI: " << GetDPI() << L"\r\n"; -//bool CMusicPlayerApp::IsGlobalMultimediaKeyEnabled() const -//{ -// return m_multimedia_key_hook != NULL; -//} + wss << L"System Language List:\r\n"; + for (const wstring& str : m_def_lang_list) + wss << str << L"; "; -CString CMusicPlayerApp::GetHelpString() -{ - CString help_info; - HRSRC hRes; - if (m_general_setting_data.language == Language::FOLLOWING_SYSTEM) - hRes = FindResource(NULL, MAKEINTRESOURCE(IDR_TEXT1), _T("TEXT")); - else - hRes = FindResourceEx(NULL, _T("TEXT"), MAKEINTRESOURCE(IDR_TEXT1), GetCurrentLanguage()); - if (hRes != NULL) - { - HGLOBAL hglobal = LoadResource(NULL, hRes); - if (hglobal != NULL) - help_info.Format(_T("%s"), (LPVOID)hglobal); - } - - return help_info; -} - -CString CMusicPlayerApp::GetSystemInfoString() -{ - CString info; - info += _T("System Info:\r\n"); - - CString strTmp; - strTmp.Format(_T("Windows Version: %d.%d build %d\r\n"), CWinVersionHelper::GetMajorVersion(), - CWinVersionHelper::GetMinorVersion(), CWinVersionHelper::GetBuildNumber()); - info += strTmp; - - strTmp.Format(_T("DPI: %d"), GetDPI()); - info += strTmp; - info += _T("\r\n"); - - return info; + return std::move(wss).str(); } void CMusicPlayerApp::SetAutoRun(bool auto_run) @@ -1158,6 +611,8 @@ bool CMusicPlayerApp::GetAutoRun() void CMusicPlayerApp::WriteLog(const wstring& log_str, int log_type) { + static std::mutex log_mutex; + std::lock_guard lock(log_mutex); if (((log_type & NonCategorizedSettingData::LT_ERROR) != 0) && ((m_nc_setting_data.debug_log & NonCategorizedSettingData::LT_ERROR) != 0)) CCommon::WriteLog((m_config_dir + L"error.log").c_str(), log_str); #ifdef _DEBUG @@ -1166,22 +621,24 @@ void CMusicPlayerApp::WriteLog(const wstring& log_str, int log_type) #endif } -void CMusicPlayerApp::StartUpdateMediaLib(bool refresh) +void CMusicPlayerApp::StartUpdateMediaLib(bool force) { if (!m_media_lib_updating) { m_media_lib_updating = true; + m_media_update_para.num_added = 0; + m_media_update_para.force = force; m_media_lib_update_thread = AfxBeginThread([](LPVOID lpParam)->UINT { if (theApp.m_media_lib_setting_data.remove_file_not_exist_when_update) { + CMusicPlayerCmdHelper::CleanUpRecentFolders(); // 虽然仍有线程安全问题不过这行在“启动时更新媒体库”时立刻进行冲突的可能性比较小 CMusicPlayerCmdHelper::CleanUpSongData(); - CMusicPlayerCmdHelper::CleanUpRecentFolders(); } - CMusicPlayerCmdHelper::UpdateMediaLib(lpParam); + CMusicPlayerCmdHelper::UpdateMediaLib(); theApp.m_media_lib_updating = false; return 0; - }, (LPVOID)refresh); + }, nullptr); } } @@ -1205,9 +662,16 @@ void CMusicPlayerApp::AutoSelectNotifyIcon() HICON CMusicPlayerApp::GetNotifyIncon(int index) { - if (index < 0 || index >= MAX_NOTIFY_ICON) - index = 0; - return m_icon_set.notify_icons[index]; + static HICON hIcon_color = theApp.m_icon_mgr.GetHICON(IconMgr::IconType::IT_App, IconMgr::IconStyle::IS_Color, IconMgr::IconSize::IS_DPI_16); + static HICON hIcon_white = theApp.m_icon_mgr.GetHICON(IconMgr::IconType::IT_App_Monochrome, IconMgr::IconStyle::IS_OutlinedLight, IconMgr::IconSize::IS_DPI_16); + static HICON hIcon_black = theApp.m_icon_mgr.GetHICON(IconMgr::IconType::IT_App_Monochrome, IconMgr::IconStyle::IS_OutlinedDark, IconMgr::IconSize::IS_DPI_16); + + if (index == 1) + return hIcon_white; + else if (index == 2) + return hIcon_black; + else + return hIcon_color; } bool CMusicPlayerApp::IsScintillaLoaded() const @@ -1268,6 +732,25 @@ int CMusicPlayerApp::ExitInstance() // 卸载GDI+ Gdiplus::GdiplusShutdown(m_gdiplusToken); + const auto& unknown_key = m_str_table.GetUnKnownKey(); + if (!unknown_key.empty()) + { + wstring log_str = m_str_table.LoadText(L"LOG_STRING_TABLE_UNKNOWN_KEY"); + for (const auto& item : unknown_key) + log_str += item + L';'; + WriteLog(log_str); + } + const auto& error_para_key = m_str_table.GetErrorParaKey(); + if (!error_para_key.empty()) + { + wstring log_str = m_str_table.LoadText(L"LOG_STRING_TABLE_PARA_ERROR"); + for (const auto& item : error_para_key) + log_str += item + L';'; + WriteLog(log_str); + } + // 释放ITaskbarList3 + ReleaseTaskBarRefs(); + return CWinApp::ExitInstance(); } @@ -1275,8 +758,8 @@ int CMusicPlayerApp::ExitInstance() void CMusicPlayerApp::OnHelpUpdateLog() { // TODO: 在此添加命令处理程序代码 - CString language = CCommon::LoadText(IDS_LANGUAGE_CODE); - if (language == _T("2")) + bool is_zh_cn = theApp.m_str_table.IsSimplifiedChinese(); + if (is_zh_cn) ShellExecute(NULL, _T("open"), _T("https://github.com/zhongyang219/MusicPlayer2/blob/master/Documents/update_log.md"), NULL, NULL, SW_SHOW); else ShellExecute(NULL, _T("open"), _T("https://github.com/zhongyang219/MusicPlayer2/blob/master/Documents/update_log_en-us.md"), NULL, NULL, SW_SHOW); @@ -1292,8 +775,8 @@ void CMusicPlayerApp::OnHelpCustomUi() void CMusicPlayerApp::OnHelpFaq() { - CString language = CCommon::LoadText(IDS_LANGUAGE_CODE); - if (language == _T("2")) + bool is_zh_cn = theApp.m_str_table.IsSimplifiedChinese(); + if (is_zh_cn) ShellExecute(NULL, _T("open"), _T("https://github.com/zhongyang219/MusicPlayer2/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98"), NULL, NULL, SW_SHOW); else ShellExecute(NULL, _T("open"), _T("https://github.com/zhongyang219/MusicPlayer2/wiki/FAQ"), NULL, NULL, SW_SHOW); diff --git a/MusicPlayer2/MusicPlayer2.h b/MusicPlayer2/MusicPlayer2.h index 051696057..b989fd3aa 100644 --- a/MusicPlayer2/MusicPlayer2.h +++ b/MusicPlayer2/MusicPlayer2.h @@ -8,18 +8,13 @@ #error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件" #endif -#include "resource.h" // 主符号 -#include "Player.h" -#include "AudioCommon.h" -#include "ColorConvert.h" -#include "DrawCommon.h" -#include "IniHelper.h" -#include "WinVersionHelper.h" -#include "CHotkeyManager.h" +#include "resource.h" // 主符号 #include "CommonData.h" -#include "MediaLibHelper.h" #include "AcceleratorRes.h" #include "LastFM.h" +#include "StrTable.h" +#include "MenuMgr.h" +#include "IconMgr.h" // CMusicPlayerApp: @@ -50,11 +45,6 @@ class CMusicPlayerApp : public CWinApp vector m_screen_rects; // 屏幕的范围 - //CMediaClassifier m_artist_classifer{ CMediaClassifier::CT_ARTIST, true }; //将所有歌曲信息按艺术家分类 - //CMediaClassifier m_album_classifer{ CMediaClassifier::CT_ALBUM, true }; //将所有歌曲信息按唱片集分类 - //CMediaClassifier m_genre_classifer{ CMediaClassifier::CT_GENRE, true }; //将所有歌曲信息按流派分类 - //CMediaClassifier m_year_classifer{ CMediaClassifier::CT_YEAR, true }; //将所有歌曲信息按年份分类 - LyricSettingData m_lyric_setting_data; //“选项设置”对话框中“歌词设置”中的数据 ApperanceSettingData m_app_setting_data; //“选项设置”对话框中“外观设置”中的数据 GeneralSettingData m_general_setting_data; //“选项设置”对话框中“常规设置”中的数据 @@ -62,20 +52,22 @@ class CMusicPlayerApp : public CWinApp NonCategorizedSettingData m_nc_setting_data; //未分类的设置数据 GlobalHotKeySettingData m_hot_key_setting_data; //“全局快捷键”设置 MediaLibSettingData m_media_lib_setting_data; //“媒体库”设置 - CHotkeyManager m_hot_key; CAcceleratorRes m_accelerator_res; + StrTable m_str_table; // 实际上负责language manger + // IconMgr比MenuMgr先构造,后析构,虽然懒加载下不是必须不过语义应当如此 + IconMgr m_icon_mgr; // 负责图标句柄缓存与懒加载 + MenuMgr m_menu_mgr; + UIData m_ui_data; - IconSet m_icon_set; //图标资源 FontSet m_font_set; //字体资源 - MenuSet m_menu_set; //菜单资源 ImageSet m_image_set; //图片资源 - int m_cmd; + int m_cmd{}; int m_fps{}; - CString m_window_title; //窗口的标题 + wstring m_window_title; // 窗口的标题 volatile bool m_lyric_download_dialog_exit{ true }; //用于指示歌词下载对话框已经退出 volatile bool m_batch_download_dialog_exit{ true }; //用于指示歌词批量下载对话框已经退出 @@ -96,9 +88,7 @@ class CMusicPlayerApp : public CWinApp void LoadConfig(); - void LoadIconResource(); - void InitMenuResourse(); - void AddMenuShortcuts(CMenu* pMenu); //在菜单项后面添加快捷键 + void LoadImgResource(); int DPI(int pixel); //将一个像素值进行DPI变换 int DPI(double pixel); @@ -107,19 +97,13 @@ class CMusicPlayerApp : public CWinApp int DPIRound(double pixel, double round = 0.5); //对结果进行四舍五入处理 void GetDPIFromWindow(CWnd* pWnd); - int GetDPI() + int GetDPI() const { return m_dpi; } - WORD GetCurrentLanguage() const; - //bool IsGlobalMultimediaKeyEnabled() const; - - //获取帮助文本 - CString GetHelpString(); - //获取系统信息文本 - CString GetSystemInfoString(); + wstring GetSystemInfoString(); void SetAutoRun(bool auto_run); bool GetAutoRun(); @@ -127,11 +111,9 @@ class CMusicPlayerApp : public CWinApp void WriteLog(const wstring& log_str, int log_type = NonCategorizedSettingData::LT_ERROR); - //void StartClassifySongData(); - //开启一个后台线程并更新媒体库 - //refresh: 如果为true,则会自动更新所有最近修改时间比上次获取时新的文件的信息 - void StartUpdateMediaLib(bool refresh = false); + // force为true时强制重新获取媒体库文件夹下的所有歌曲元数据,false时获取修改时间改变的歌曲元数据 + void StartUpdateMediaLib(bool force); bool IsMeidaLibUpdating() const { return m_media_lib_updating; } bool IsCheckingForUpdate() const { return m_checking_update; } //是否正在检查更新 @@ -160,9 +142,10 @@ class CMusicPlayerApp : public CWinApp HHOOK m_multimedia_key_hook = NULL; int m_dpi{}; - bool m_song_data_modified{ false }; - ULONG_PTR m_gdiplusToken; + vector m_def_lang_list; // 线程启动时的默认UI语言列表(仅用于GetSystemInfoString) + + ULONG_PTR m_gdiplusToken{}; bool m_media_lib_updating{ false }; bool m_checking_update{ false }; //是否正在检查更新 diff --git a/MusicPlayer2/MusicPlayer2.rc b/MusicPlayer2/MusicPlayer2.rc index 92c75acc6..3f33b67b4 100644 --- a/MusicPlayer2/MusicPlayer2.rc +++ b/MusicPlayer2/MusicPlayer2.rc @@ -50,16 +50,25 @@ BEGIN "#define _AFX_NO_TRACKER_RESOURCES\r\n" "#define _AFX_NO_PROPERTY_RESOURCES\r\n" "\r\n" - "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)\r\n" - "LANGUAGE 4, 2\r\n" - "#include ""res\\MusicPlayer2.rc2"" // ??? Microsoft Visual C++ ?a丯??-|i??a丯o???\r\n" - "#include ""l.CHS\\afxres.rc"" // ?a丯o?a??a丯|?t\r\n" + "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n" + "LANGUAGE 9, 1\r\n" + "#include ""res\\MusicPlayer2.rc2"" // non-Microsoft Visual C++ edited resources\r\n" + "#include ""afxres.rc"" // Standard components\r\n" "#endif\r\n" "\0" END #endif // APSTUDIO_INVOKED +#endif // 中文(简体,中国) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// 英语(美国) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US ///////////////////////////////////////////////////////////////////////////// // @@ -374,7 +383,7 @@ IDI_HOT_KEY ICON "res\\hot_key.ico" IDI_MINI_RESTORE ICON "res\\mini_restore.ico" -IDI_IDI_MINI_RESTORE_D ICON "res\\mini_restore_d.ico" +IDI_MINI_RESTORE_D ICON "res\\mini_restore_d.ico" IDI_LOCATE ICON "res\\locate.ico" @@ -382,1026 +391,1192 @@ IDI_EXPAND ICON "res\\expand.ico" IDI_FIX_D ICON "res\\fix_d.ico" +IDI_UP_D ICON "res\\up_d.ico" + ///////////////////////////////////////////////////////////////////////////// // -// Dialog +// Version // -IDD_ABOUTBOX DIALOGEX 0, 0, 191, 137 -STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "关于 MusicPlayer2" -FONT 9, "微软雅黑", 400, 0, 0x0 +VS_VERSION_INFO VERSIONINFO + FILEVERSION 2,7,6,1 + PRODUCTVERSION 2,7,6,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L BEGIN - LTEXT "MusicPlayer2,版",IDC_STATIC_VERSION,11,36,162,8,SS_NOPREFIX - LTEXT "Copyright (C) 2017- By ZhongYang\n最后编译日期:",IDC_STATIC_COPYRIGHT,11,46,163,17 - DEFPUSHBUTTON "确定",IDOK,145,115,39,14,WS_GROUP - CONTROL "联系作者",IDC_SYSLINK1,"SysLink",0x0,6,114,31,10 - CONTROL "检查更新",IDC_SYSLINK2,"SysLink",WS_TABSTOP,40,114,30,10 - CONTROL "GitHub",IDC_GITHUB_SYSLINK,"SysLink",WS_TABSTOP,73,114,28,10 - CONTROL "捐助",IDC_DONATE_SYSLINK,"SysLink",WS_TABSTOP,7,124,19,10 - CONTROL "开源协议",IDC_LICENSE_SYSLINK,"SysLink",WS_TABSTOP,102,114,30,10 - LTEXT "本项目使用的第三方库:",IDC_STATIC,11,68,118,8 - CONTROL "BASS",IDC_SYSLINK_BASS,"SysLink",WS_TABSTOP,11,78,25,10 - CONTROL "TagLib",IDC_SYSLINK_TAGLIB,"SysLink",WS_TABSTOP,40,78,32,10 - CONTROL "TinyXML2",IDC_SYSLINK_TINYXML2,"SysLink",WS_TABSTOP,75,78,37,10 - CONTROL "Scintilla",IDC_SYSLINK_SCINTILLA,"SysLink",WS_TABSTOP,124,78,35,10 - LTEXT "作者的其他软件:",IDC_STATIC,11,90,118,8 - CONTROL "TrafficMonitor",IDC_SYSLINK_TRAFFICMONITOR, - "SysLink",WS_TABSTOP,11,100,54,10 - CONTROL "SimpleNotePad",IDC_SYSLINK_SIMPLENOTEPAD,"SysLink",WS_TABSTOP,73,100,54,10 - CONTROL "鸣谢",IDC_ACKNOWLEDGEMENT_SYSLINK,"SysLink",WS_TABSTOP,39,123,37,9 + BLOCK "StringFileInfo" + BEGIN + BLOCK "080404b0" + BEGIN + VALUE "CompanyName", "By ZhongYang" + VALUE "FileDescription", "MusicPlayer2" + VALUE "FileVersion", "2.7.6.1" + VALUE "InternalName", "MusicPlayer2.exe" + VALUE "LegalCopyright", "By ZhongYang. All rights reserved." + VALUE "OriginalFilename", "MusicPlayer2.exe" + VALUE "ProductName", "MusicPlayer2" + VALUE "ProductVersion", "2.7.6.1" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x804, 1200 + END END -IDD_SET_PATH_DIALOG DIALOGEX 0, 0, 279, 173 -STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU -EXSTYLE WS_EX_APPWINDOW -FONT 9, "微软雅黑", 400, 0, 0x0 -BEGIN - LTEXT "当前文件夹:",IDC_STATIC,4,5,41,8 - PUSHBUTTON "打开新文件夹(&O)...",IDC_OPEN_FOLDER,207,3,68,14 - EDITTEXT IDC_PATH_EDIT,49,4,155,12,ES_AUTOHSCROLL | ES_READONLY - CONTROL "",IDC_PATH_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,4,34,271,135 - CONTROL "",IDC_SEARCH_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x80,4,19,271,12 -END -IDD_FIND_DIALOG DIALOGEX 0, 0, 256, 211 -STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -EXSTYLE WS_EX_APPWINDOW -CAPTION "查找文件" -FONT 9, "微软雅黑", 400, 0, 0x86 -BEGIN - DEFPUSHBUTTON "播放选中曲目",IDOK,133,190,59,14 - PUSHBUTTON "关闭",IDCANCEL,199,190,50,14 - EDITTEXT IDC_FIND_EDIT,78,7,119,12,ES_AUTOHSCROLL - LTEXT "输入要查找的关键字:",IDC_STATIC,7,9,70,8 - PUSHBUTTON "查找(&F)",IDC_FIND_BUTTON,199,6,50,14 - LTEXT "上次的查找结果:",IDC_FIND_RESULT_STATIC,7,60,61,8 - CONTROL "",IDC_FIND_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,69,242,118 - GROUPBOX "查找选项",IDC_STATIC,118,22,131,35 - CONTROL "查找文件名",IDC_FIND_FILE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,129,32,50,10 - CONTROL "查找标题",IDC_FIND_TITLE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,190,32,43,10 - CONTROL "查找艺术家",IDC_FIND_ARTIST_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,129,44,50,10 - CONTROL "查找唱片集",IDC_FIND_ALBUM_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,190,44,50,10 - GROUPBOX "查找范围",IDC_STATIC,7,22,104,35 - CONTROL "查找当前播放列表(&C)",IDC_FIND_CURRENT_PLAYLIST_RADIO,"Button",BS_AUTORADIOBUTTON,16,33,83,10 - CONTROL "查找整个媒体库(&A)",IDC_FIND_ALL_PLAYLIST_RADIO,"Button",BS_AUTORADIOBUTTON,16,44,87,10 - LTEXT "",IDC_FIND_INFO_STATIC,138,60,111,8 -END +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// -IDD_OPTIONS_DIALOG DIALOGEX 0, 0, 269, 210 -STYLE DS_SETFONT | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -CAPTION "选项设置" -FONT 9, "微软雅黑", 400, 0, 0x86 -BEGIN - DEFPUSHBUTTON "确定",IDOK,103,190,50,14 - PUSHBUTTON "取消",IDCANCEL,158,190,50,14 - CONTROL "",IDC_OPTIONS_TAB,"SysTabControl32",0x0,5,4,259,183 - PUSHBUTTON "应用",IDC_APPLY_BUTTON,214,190,50,14 -END +IDB_CORTANA_BLACK BITMAP "res\\Cortana_black.bmp" -IDD_LYRIC_SETTING_DIALOG DIALOGEX 0, 0, 246, 382 -STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU -FONT 9, "微软雅黑", 400, 0, 0x86 +IDB_CORTANA_WHITE BITMAP "res\\Cortana_white.bmp" + +IDR_LYRIC_EDIT_TOOLBAR BITMAP "res\\toolbar1.bmp" + +IDB_DONATE BITMAP "res\\donate.bmp" + +IDB_DONATE_WECHAT BITMAP "res\\donate_wechat.bmp" + +IDB_NOTIFY_ICON_PREVIEW BITMAP "res\\notify_preview.bmp" + +IDB_NOTIFY_ICON_PREVIEW_LIGHT BITMAP "res\\notify_preview_light.bmp" + +IDB_DEFAULT_COVER BITMAP "res\\default_cover.bmp" + + +///////////////////////////////////////////////////////////////////////////// +// +// Toolbar +// + +IDR_LYRIC_EDIT_TOOLBAR TOOLBAR 16, 15 BEGIN - GROUPBOX "歌词选项",IDC_STATIC,7,6,232,79 - CONTROL "歌词卡拉OK样式显示(&K)",IDC_KARAOKE_DISP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,17,86,10 - CONTROL "歌词模糊匹配(&F)",IDC_LYRIC_FUZZY_MATCH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,145,17,63,10 - LTEXT "歌词文件夹:",IDC_STATIC,17,43,42,8 - GROUPBOX "任务栏搜索框显示播放信息",IDC_STATIC,7,262,232,110 - CONTROL "允许在任务栏搜索框中显示播放信息(&C)",IDC_SHOW_LYRIC_IN_CORTANA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,275,156,10 - CONTROL "歌词双行显示(&D)",IDC_LYRIC_DOUBLE_LINE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,137,299,93,10 - LTEXT "搜索框背景颜色:",IDC_STATIC,131,287,56,8 - COMBOBOX IDC_CORTANA_COLOR_COMBO,186,285,42,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "搜索框中显示专辑封面(&A)",IDC_SHOW_ALBUM_COVER_IN_CORTANA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,312,114,10 - CONTROL "Cortana图标跟随音乐节奏跳动(&B)",IDC_CORTANA_ICON_DEAT_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,324,115,10 - CONTROL "使用兼容模式显示歌词(&P)",IDC_LYRIC_COMPATIBLE_MODE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,360,112,10 - PUSHBUTTON "设置字体(&F)...",IDC_SET_FONT,179,334,50,14 - LTEXT "显示字体:",IDC_STATIC,141,337,37,8 - CONTROL "暂停时保持显示(&K)",IDC_KEEP_DISPLAY_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,137,324,93,10 - CONTROL "搜索框中显示频谱分析",IDC_SHOW_SPECTRUM_IN_CORTANA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,137,312,88,10 - CONTROL "搜索框中显示歌词(&L)",IDC_SHOW_LYRIC_IN_CORTANA2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,287,108,10 - GROUPBOX "桌面歌词",IDC_STATIC,7,140,232,116 - CONTROL "显示桌面歌词",IDC_SHOW_DESKTOP_LYRIC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,153,104,10 - CONTROL "歌词双行显示(&D)",IDC_LYRIC_DOUBLE_LINE_CHECK2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,165,100,10 - PUSHBUTTON "设置字体(&F)...",IDC_SET_FONT2,161,150,50,14 - LTEXT "显示字体:",IDC_STATIC,123,153,37,8 - LTEXT "文字颜色:",IDC_STATIC,17,214,36,8 - LTEXT "",IDC_TEXT_COLOR1_STATIC,57,213,13,11,NOT WS_GROUP | WS_TABSTOP,WS_EX_STATICEDGE - LTEXT "",IDC_TEXT_COLOR2_STATIC,73,213,13,11,NOT WS_GROUP | WS_TABSTOP,WS_EX_STATICEDGE - COMBOBOX IDC_TEXT_GRADIENT_COMBO,134,213,49,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "文字渐变:",IDC_STATIC,96,214,38,8 - LTEXT "高亮颜色:",IDC_STATIC,17,228,36,8 - LTEXT "",IDC_HIGHLIGHT_COLOR1_STATIC,57,227,13,11,NOT WS_GROUP | WS_TABSTOP,WS_EX_STATICEDGE - LTEXT "",IDC_HIGHLIGHT_COLOR2_STATIC,73,227,13,11,NOT WS_GROUP | WS_TABSTOP,WS_EX_STATICEDGE - COMBOBOX IDC_HIGHLIGHT_GRADIENT_COMBO,134,227,49,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "高亮渐变:",IDC_STATIC,96,228,38,8 - CONTROL "",IDC_LYRIC_OPACITY_SLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,66,242,81,10 - LTEXT "歌词不透明度:",IDC_STATIC,17,242,49,8 - LTEXT "100%",IDC_LYRIC_OPACITY_STATIC,153,242,21,8 - CONTROL "锁定桌面歌词(&L)",IDC_LOCK_DESKTOP_LYRIC_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,123,165,93,10 - CONTROL "没有歌词时隐藏歌词窗口",IDC_HIDE_LYRIC_WITHOUT_LYRIC_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,176,103,10 - CONTROL "暂停时隐藏歌词窗口",IDC_HIDE_LYRIC_PAUSE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,123,176,100,10 - PUSHBUTTON "预设方案",IDC_DEFAULT_STYLE,189,219,47,14 - CONTROL "歌词背景穿透",IDC_HIDE_LYRIC_WITHOUT_LYRIC_CHECK3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,187,103,10 - CONTROL "",IDC_LYRIC_PATH_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x880,61,42,166,12 - LTEXT "歌词对齐方式:",IDC_STATIC,17,300,51,8 - COMBOBOX IDC_ALIGNMENT_COMBO,68,299,56,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "歌词调整后:",IDC_STATIC,130,59,42,8 - COMBOBOX IDC_LYRIC_SAVE_COMBO,173,58,54,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "优先使用内嵌歌词",IDC_USE_INNER_LYRIC_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,58,97,10 - CONTROL "锁定时显示解锁按钮",IDC_SHOW_UNLOCK_WHEN_LOCKED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,123,187,100,10 - CONTROL "没有专辑封面时显示黑胶唱片图标",IDC_SHOW_DEFAULT_ALBUM_ICON_CHK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,336,114,10 - CONTROL "Windows10浅色模式下搜索框背景透明",IDC_SEARCH_BOX_TRANSPARENT_IN_WHITE_MODE, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,348,148,10 - GROUPBOX "歌词显示",IDC_STATIC,7,91,232,43 - LTEXT "字体:",IDC_STATIC,17,103,21,8 - PUSHBUTTON "设置字体(&F)...",IDC_SET_FONT_BUTTON,37,101,50,14 - LTEXT "歌词行间距:",IDC_STATIC,100,104,41,8 - EDITTEXT IDC_FONT_SIZE_EDIT2,142,102,24,12,ES_AUTOHSCROLL - LTEXT "像素",IDC_STATIC,169,106,17,8 - LTEXT "歌词对齐方式:",IDC_STATIC,17,120,54,8 - COMBOBOX IDC_ALIGNMENT_COMBO2,72,118,58,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "歌词对齐方式:",IDC_STATIC,17,199,51,8 - COMBOBOX IDC_DESKTOP_LYRIC_ALIGNMENT_COMBO,68,198,56,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "显示歌词翻译(如果有)",IDC_SHOW_LYRIC_TRANSLATE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,145,29,93,10 - CONTROL "单行和双行显示模式下不显示空白行",IDC_LYRIC_HIDE_BLANK_LINE_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,29,125,10 - CONTROL "没有歌词时显示歌曲信息",IDC_SHOW_SONG_INFO_IF_LYRIC_NOT_EXIST_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,71,107,10 + BUTTON ID_LYRIC_INSERT_TAG + BUTTON ID_LYRIC_REPLACE_TAG + BUTTON ID_LYRIC_DELETE_TAG + BUTTON ID_LYRIC_SAVE + SEPARATOR + BUTTON ID_PLAY_PAUSE + BUTTON ID_REW + BUTTON ID_FF + BUTTON ID_SEEK_TO_CUR_LINE + SEPARATOR + BUTTON ID_LYRIC_FIND + BUTTON ID_LYRIC_REPLACE END -IDD_APPEREANCE_SETTING_DLG DIALOGEX 0, 0, 246, 452 -STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU -FONT 9, "微软雅黑", 400, 0, 0x86 + +///////////////////////////////////////////////////////////////////////////// +// +// Cursor +// + +IDC_DRAG_CURSOR CURSOR "res\\drag.cur" + + +///////////////////////////////////////////////////////////////////////////// +// +// PNG +// + +IDB_DEFAULT_ALBUM_COVER PNG "res\\黑色胶片.png" + +IDB_DEFAULT_ALBUM_COVER_NOT_PLAYED PNG "res\\黑色胶片_not_played.png" + + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDR_ACCELERATOR1 ACCELERATORS BEGIN - GROUPBOX "主窗口不透明度",IDC_STATIC,149,230,90,39 - CONTROL "",IDC_TRANSPARENT_SLIDER,"msctls_trackbar32",TBS_NOTICKS | WS_TABSTOP,156,243,60,12 - LTEXT "xx%",IDC_TRANSPARENT_STATIC,218,244,19,8 - GROUPBOX "视觉效果",IDC_STATIC,7,5,112,105 - CONTROL "显示频谱分析",IDC_SHOW_SPECTRUM_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,15,53,10 - CONTROL "显示专辑封面",IDC_SHOW_ALBUM_COVER_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,52,52,10 - LTEXT "频谱分析高度:",IDC_STATIC,12,28,43,8 - CONTROL "",IDC_SPECTRUM_HEIGHT_SLIDER,"msctls_trackbar32",TBS_NOTICKS | WS_TABSTOP,57,27,42,12 - LTEXT "Static",IDC_SPECTRUM_HEIGHT_STATIC,98,28,18,8 - LTEXT "专辑封面契合度:",IDC_STATIC,12,65,57,8 - COMBOBOX IDC_ALBUM_FIT_COMBO,68,64,47,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "使用专辑封面作为背景",IDC_ALBUM_COVER_BACKGROUND_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,130,27,92,10 - LTEXT "背景不透明度:",IDC_STATIC,130,39,51,8 - CONTROL "",IDC_BACKGROUND_TRANSPARENCY_SLIDER,"msctls_trackbar32",TBS_NOTICKS | WS_TABSTOP,174,38,43,12 - LTEXT "Static",IDC_BACKGROUND_TRANSPARENCY_STATIC,220,39,18,8 - GROUPBOX "主题颜色",IDC_STATIC,7,179,232,45 - LTEXT "",IDC_COLOR_STATIC,20,193,30,13,NOT WS_GROUP,WS_EX_STATICEDGE - GROUPBOX "预置颜色",IDC_STATIC,62,184,111,25 - LTEXT "",IDC_COLOR_STATIC2,69,194,12,11,NOT WS_GROUP | WS_TABSTOP,WS_EX_STATICEDGE - LTEXT "",IDC_COLOR_STATIC3,86,194,12,11,NOT WS_GROUP | WS_TABSTOP,WS_EX_STATICEDGE - LTEXT "",IDC_COLOR_STATIC4,103,194,12,11,NOT WS_GROUP | WS_TABSTOP,WS_EX_STATICEDGE - LTEXT "",IDC_COLOR_STATIC5,120,194,12,11,NOT WS_GROUP | WS_TABSTOP,WS_EX_STATICEDGE - LTEXT "",IDC_COLOR_STATIC6,137,194,12,11,NOT WS_GROUP | WS_TABSTOP,WS_EX_STATICEDGE - LTEXT "",IDC_COLOR_STATIC7,154,194,12,11,NOT WS_GROUP | WS_TABSTOP,WS_EX_STATICEDGE - PUSHBUTTON "更多颜色(&C)...",IDC_SET_PROGRESS_COLOR_BUTTON,178,192,50,14 - CONTROL "跟随系统主题色",IDC_FOLLOW_SYSTEM_COLOR_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,211,173,10 - CONTROL "没有专辑封面时使用外部图片",IDC_USE_OUT_IMAGE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,106,126,104,10 - LTEXT "外部图片文件名:",IDC_STATIC,16,140,53,8 - CONTROL "背景高斯模糊",IDC_BACKGROUND_GAUSS_BLUR_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,130,49,86,10 - LTEXT "高斯模糊半径:",IDC_STATIC,130,61,51,8 - CONTROL "",IDC_GAUSS_BLURE_RADIUS_SLIDER,"msctls_trackbar32",TBS_NOTICKS | WS_TABSTOP,174,60,43,12 - LTEXT "Static",IDC_GAUSS_BLUR_RADIUS_STATIC,220,61,18,8 - CONTROL "歌词界面背景",IDC_LYRIC_BACKGROUND_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,77,55,10 - CONTROL "深色模式",IDC_DARK_MODE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,71,77,45,10 - CONTROL "优先使用内嵌专辑封面",IDC_USE_INNER_IMAGE_FIRST_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,126,79,10 - CONTROL "启用背景",IDC_ENABLE_BACKGROUND_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,130,15,60,10 - CONTROL "低频部分显示在中间",IDC_LOW_FREQ_IN_CENTER_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,40,105,10 - GROUPBOX "高级",IDC_STATIC,7,403,232,40 - CONTROL "专辑封面使用GDI+绘图(质量更高但是会占用更多的CPU资源)",IDC_DEFAULT_ALBUM_COVER_HQ, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,414,220,10 - LTEXT "界面刷新时间间隔:",IDC_STATIC,16,428,62,8 - EDITTEXT IDC_UI_INTERVAL_EDIT,80,426,34,12,ES_AUTOHSCROLL | ES_NUMBER - LTEXT "毫秒",IDC_STATIC,117,428,22,8 - PUSHBUTTON "恢复默认(&D)",IDC_RESTORE_DEFAULT_BUTTON,140,425,50,14 - GROUPBOX "通知区图标",IDC_STATIC,7,344,232,54 - LTEXT "选择通知区图标:",IDC_STATIC,16,357,59,8 - COMBOBOX IDC_COMBO1,16,368,62,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "预览:",IDC_PREVIEW_STATIC,94,351,27,8 - CONTROL "使用单色图标时根据Windows10深色/浅色模式自动适应",IDC_NOTIFY_ICON_AUTO_ADAPT_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,385,209,10 - CONTROL "使用圆角风格",IDC_BTN_ROUND_CORNERS_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,89,55,10 - LTEXT "默认背景图片:",IDC_STATIC,130,73,48,8 - CONTROL "",IDC_DEFAULT_BACKGROUND_PATH_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x880,130,84,103,12 - GROUPBOX "背景设置",IDC_STATIC,125,5,114,105 - CONTROL "使用桌面背景",IDC_USE_DESKTOP_BACKGROUND_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,130,98,89,10 - GROUPBOX "状态栏",IDC_STATIC,7,230,134,39 - CONTROL "显示下一曲",IDC_SHOW_NEXT_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,254,49,10 - CONTROL "显示帧率",IDC_SHOW_FPS_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,79,254,43,10 - CONTROL "",IDC_DEFAULT_COVER_NAME_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x80,67,138,166,12 - GROUPBOX "封面选项",IDC_STATIC,7,116,232,57 - LTEXT "封面文件夹:",IDC_STATIC,16,155,44,8 - CONTROL "",IDC_ALBUM_COVER_PATH_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x880,67,154,166,12 - GROUPBOX "标题栏",IDC_STATIC,7,275,232,62 - CONTROL "总是显示状态栏",IDC_ALWAYS_SHOW_STATUSBAR_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,241,63,10 - CONTROL "使用系统标准标题栏",IDC_SHOW_SYSTEM_TITLEBAR_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,286,76,10 - LTEXT "在标题栏中显示的按钮(仅当未勾选“使用系统标准标题栏”时有效):",IDC_STATIC,16,299,215,8 - CONTROL "设置",IDC_SHOW_SETTINGS_BTN_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,310,29,10 - CONTROL "切换界面",IDC_SHOW_SKIN_BTN_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,57,310,43,10 - CONTROL "迷你模式",IDC_SHOW_MINI_MODE_BTN_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,112,310,43,10 - CONTROL "全屏显示",IDC_SHOW_FULLSCREEN_BTN_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,164,310,43,10 - CONTROL "最小化",IDC_SHOW_MINIMIZE_BTN_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,322,36,10 - CONTROL "最大化/还原",IDC_SHOW_MAXIMIZE_BTN_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,57,322,52,10 + "R", ID_AB_REPEAT, VIRTKEY, CONTROL, NOINVERT + "W", ID_ALBUM_COVER_INFO, VIRTKEY, CONTROL, NOINVERT + "T", ID_ALWAYS_ON_TOP, VIRTKEY, SHIFT, CONTROL, NOINVERT + "D", ID_DARK_MODE, VIRTKEY, SHIFT, CONTROL, NOINVERT + VK_DELETE, ID_DELETE_CURRENT_FROM_DISK, VIRTKEY, SHIFT, CONTROL, NOINVERT + VK_DELETE, ID_DELETE_FROM_DISK, VIRTKEY, SHIFT, NOINVERT + "E", ID_EDIT_LYRIC, VIRTKEY, SHIFT, CONTROL, NOINVERT + "E", ID_EQUALIZER, VIRTKEY, CONTROL, NOINVERT + "B", ID_EXPLORE_PATH, VIRTKEY, CONTROL, NOINVERT + VK_RIGHT, ID_FF, VIRTKEY, NOINVERT + "O", ID_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT + "D", ID_FILE_OPEN_FOLDER, VIRTKEY, CONTROL, NOINVERT + "F", ID_FIND, VIRTKEY, CONTROL, NOINVERT + "K", ID_FLOAT_PLAYLIST, VIRTKEY, CONTROL, NOINVERT + VK_F11, ID_FULL_SCREEN, VIRTKEY, NOINVERT + "G", ID_LOCATE_TO_CURRENT, VIRTKEY, CONTROL, NOINVERT + VK_NEXT, ID_LYRIC_DELAY, VIRTKEY, CONTROL, NOINVERT + VK_PRIOR, ID_LYRIC_FORWARD, VIRTKEY, CONTROL, NOINVERT + "M", ID_MINI_MODE, VIRTKEY, CONTROL, NOINVERT + VK_DOWN, ID_MOVE_PLAYLIST_ITEM_DOWN, VIRTKEY, CONTROL, NOINVERT + VK_UP, ID_MOVE_PLAYLIST_ITEM_UP, VIRTKEY, CONTROL, NOINVERT + "N", ID_NEXT, VIRTKEY, NOINVERT + "N", ID_NEXT_AB_REPEAT, VIRTKEY, SHIFT, CONTROL, NOINVERT + "I", ID_OPTION_SETTINGS, VIRTKEY, CONTROL, NOINVERT + VK_RETURN, ID_ORIGINAL_SPEED, VIRTKEY, CONTROL, NOINVERT + "P", ID_PLAY_PAUSE, VIRTKEY, NOINVERT + VK_SPACE, ID_PLAY_PAUSE, VIRTKEY, NOINVERT + "V", ID_PREVIOUS, VIRTKEY, NOINVERT + "Q", ID_RE_INI_BASS, VIRTKEY, CONTROL, NOINVERT + VK_DELETE, ID_REMOVE_CURRENT_FROM_PLAYLIST, VIRTKEY, CONTROL, NOINVERT + VK_DELETE, ID_REMOVE_FROM_PLAYLIST, VIRTKEY, NOINVERT + "M", ID_REPEAT_MODE, VIRTKEY, NOINVERT + "C", ID_RESET_AB_REPEAT, VIRTKEY, SHIFT, CONTROL, NOINVERT + VK_LEFT, ID_REW, VIRTKEY, NOINVERT + "S", ID_SAVE_MODIFIED_LYRIC, VIRTKEY, CONTROL, NOINVERT + "A", ID_SET_A_POINT, VIRTKEY, SHIFT, CONTROL, NOINVERT + "B", ID_SET_B_POINT, VIRTKEY, SHIFT, CONTROL, NOINVERT + "T", ID_MEDIA_LIB, VIRTKEY, CONTROL, NOINVERT + "Y", ID_SHOW_DESKTOP_LYRIC, VIRTKEY, CONTROL, NOINVERT + "L", ID_SHOW_PLAYLIST, VIRTKEY, CONTROL, NOINVERT + VK_OEM_MINUS, ID_SLOW_DOWN, VIRTKEY, CONTROL, NOINVERT + "N", ID_SONG_INFO, VIRTKEY, CONTROL, NOINVERT + VK_OEM_PLUS, ID_SPEED_UP, VIRTKEY, CONTROL, NOINVERT + "S", ID_STOP, VIRTKEY, NOINVERT + "U", ID_SWITCH_UI, VIRTKEY, CONTROL, NOINVERT + "1", ID_SWITCH_UI_1, VIRTKEY, CONTROL, NOINVERT + "0", ID_SWITCH_UI_10, VIRTKEY, CONTROL, NOINVERT + "2", ID_SWITCH_UI_2, VIRTKEY, CONTROL, NOINVERT + "3", ID_SWITCH_UI_3, VIRTKEY, CONTROL, NOINVERT + "4", ID_SWITCH_UI_4, VIRTKEY, CONTROL, NOINVERT + "5", ID_SWITCH_UI_5, VIRTKEY, CONTROL, NOINVERT + "6", ID_SWITCH_UI_6, VIRTKEY, CONTROL, NOINVERT + "7", ID_SWITCH_UI_7, VIRTKEY, CONTROL, NOINVERT + "8", ID_SWITCH_UI_8, VIRTKEY, CONTROL, NOINVERT + "9", ID_SWITCH_UI_9, VIRTKEY, CONTROL, NOINVERT + VK_DOWN, ID_VOLUME_DOWN, VIRTKEY, NOINVERT + VK_UP, ID_VOLUME_UP, VIRTKEY, NOINVERT END -IDD_PROPERTY_DIALOG DIALOGEX 0, 0, 304, 143 -STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU -FONT 9, "微软雅黑", 400, 0, 0x86 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_TEST_DIALOG DIALOGEX 0, 0, 309, 176 +STYLE DS_SETFONT | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +CAPTION "测试" +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - EDITTEXT IDC_FILE_NAME_EDIT,47,15,104,12,ES_AUTOHSCROLL | ES_READONLY - EDITTEXT IDC_FILE_PATH_EDIT,47,30,104,12,ES_AUTOHSCROLL | ES_READONLY - EDITTEXT IDC_FILE_TYPE_EDIT,47,45,104,12,ES_AUTOHSCROLL | ES_READONLY - EDITTEXT IDC_SONG_LENGTH_EDIT,47,60,34,12,ES_AUTOHSCROLL | ES_READONLY - EDITTEXT IDC_FILE_SIZE_EDIT,118,60,33,12,ES_AUTOHSCROLL | ES_READONLY - EDITTEXT IDC_BIT_RATE_EDIT,47,75,34,12,ES_AUTOHSCROLL | ES_READONLY - EDITTEXT IDC_LYRIC_FILE_EDIT,47,105,104,12,ES_AUTOHSCROLL | ES_READONLY - EDITTEXT IDC_TITEL_EDIT,195,15,98,12,ES_AUTOHSCROLL | ES_READONLY - EDITTEXT IDC_ARTIST_EDIT,195,30,98,12,ES_AUTOHSCROLL | ES_READONLY - EDITTEXT IDC_ALBUM_EDIT,195,45,98,12,ES_AUTOHSCROLL | ES_READONLY - EDITTEXT IDC_TRACK_EDIT,195,60,27,12,ES_AUTOHSCROLL | ES_READONLY - EDITTEXT IDC_YEAR_EDIT,254,60,39,12,ES_AUTOHSCROLL | ES_READONLY - EDITTEXT IDC_COMMENT_EDIT,195,90,98,18,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL - LTEXT "文件名:",IDC_STATIC,10,18,28,8 - LTEXT "文件路径:",IDC_STATIC,10,32,35,8 - LTEXT "文件类型:",IDC_STATIC,10,47,35,8 - LTEXT "长度:",IDC_STATIC,10,62,22,8 - LTEXT "文件大小:",IDC_STATIC,85,61,32,8 - LTEXT "比特率:",IDC_STATIC,10,76,28,8 - GROUPBOX "文件信息",IDC_STATIC,5,4,150,117 - LTEXT "标题:",IDC_STATIC,165,18,22,8 - LTEXT "艺术家:",IDC_STATIC,165,32,28,8 - LTEXT "唱片集:",IDC_STATIC,165,47,28,8 - GROUPBOX "标签信息",IDC_STATIC,160,4,138,117 - LTEXT "年份:",IDC_STATIC,231,61,22,8 - LTEXT "流派:",IDC_STATIC,165,77,22,8 - LTEXT "注释:",IDC_STATIC,165,92,22,8 - LTEXT "音轨号:",IDC_STATIC,165,62,28,8 - LTEXT "Static",IDC_TAG_TYPE_STATIC,165,110,121,8 - LTEXT "歌词文件:",IDC_LYRIC_FILE_STATIC,10,106,35,8 - COMBOBOX IDC_GENRE_COMBO,195,76,98,38,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "在线获取标签...",IDC_GET_TAG_ONLINE_BUTTON,135,124,55,14 - PUSHBUTTON "从歌词获取标签",IDC_GET_TAG_FROM_LYRIC_BUTTON,77,124,55,14 - PUSHBUTTON "从文件名获取标签...",IDC_GET_TAG_FROM_FILE_NAME_BUTTON,5,124,69,14 - EDITTEXT IDC_SAMPLE_FREQ,47,90,34,12,ES_AUTOHSCROLL | ES_READONLY - LTEXT "采样频率:",IDC_STATIC,10,91,32,8 - EDITTEXT IDC_CHANNELS,118,75,33,12,ES_AUTOHSCROLL | ES_READONLY - LTEXT "声道数:",IDC_STATIC,85,76,32,8 - EDITTEXT IDC_BITS_DIPTH,118,90,33,12,ES_AUTOHSCROLL | ES_READONLY - LTEXT "位深度:",IDC_STATIC,85,91,31,9 + DEFPUSHBUTTON "确定",IDOK,198,155,50,14 + PUSHBUTTON "取消",IDCANCEL,252,155,50,14 + LTEXT "这是工具栏",IDC_TEST_TOOLBAR,7,7,295,12 + LTEXT "一个进度条",IDC_TEST_PROGRESS_BAR,7,23,44,8 + CONTROL "",IDC_MFCEDITBROWSE1,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x80,7,42,123,12 END -IDD_MESSAGE_DIALOG DIALOGEX 0, 0, 217, 176 -STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -EXSTYLE WS_EX_APPWINDOW -CAPTION "消息" -FONT 9, "微软雅黑", 400, 0, 0x0 +IDD_PROPERTY_ADVANCED_DIALOG DIALOGEX 0, 0, 344, 148 +STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - DEFPUSHBUTTON "确定",IDOK,160,155,50,14 - EDITTEXT IDC_HELP_EDIT,7,19,203,132,ES_MULTILINE | ES_READONLY | WS_VSCROLL - LTEXT "",IDC_INFO_STATIC,7,7,203,8 - CONTROL "SysLink1",IDC_SYSLINK1,"SysLink",WS_TABSTOP,7,160,148,8 + CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,7,330,134 END IDD_MINI_DIALOG DIALOGEX 0, 0, 173, 168 STYLE DS_SETFONT | WS_POPUP | WS_VISIBLE EXSTYLE WS_EX_TOPMOST CLASS "MiniDlg_ByH87M" -FONT 9, "微软雅黑", 400, 0, 0x0 +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN CONTROL "",IDC_LIST2,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | LVS_OWNERDATA | LVS_NOCOLUMNHEADER | WS_BORDER | WS_TABSTOP,0,22,168,144 END -IDD_LYRIC_EDIT_DIALOG DIALOGEX 0, 0, 297, 242 -STYLE DS_SETFONT | DS_MODALFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU -EXSTYLE WS_EX_APPWINDOW -CAPTION "编辑歌词" -MENU IDR_LYRIC_EDIT_MENU -FONT 9, "微软雅黑", 400, 0, 0x0 -BEGIN - EDITTEXT IDC_LYRIC_PATH_EDIT2,40,17,253,12,ES_AUTOHSCROLL | ES_READONLY - LTEXT "歌词路径:",IDC_STATIC1,4,18,35,8 -END - -IDD_DATA_SETTINGS_DIALOG DIALOGEX 0, 0, 246, 234 +IDD_MEDIA_CLASSIFY_DIALOG DIALOGEX 0, 0, 330, 170 STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU -FONT 9, "微软雅黑", 400, 0, 0x86 -BEGIN - GROUPBOX "应用程序设置",IDC_STATIC,7,6,123,66 - GROUPBOX "下载设置",IDC_STATIC,7,77,232,61 - CONTROL "没有专辑封面时自动下载",IDC_COVER_AUTO_DOWNLOAD_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,88,95,10 - CONTROL "没有歌词时自动下载",IDC_LYRIC_AUTO_DOWNLOAD_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,129,88,95,10 - CONTROL "启动时检查更新",IDC_CHECK_UPDATE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,18,89,10 - LTEXT "MIDI 音色库路径:",IDC_STATIC,13,155,57,8 - GROUPBOX "MIDI 设置",IDC_STATIC,7,144,232,39 - CONTROL "优先显示 MIDI 音乐内嵌的歌词",IDC_MIDI_USE_INNER_LYRIC_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,170,122,10 - CONTROL "只有歌曲信息完整时才自动下载",IDC_DOWNLOAD_WHEN_TAG_FULL_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,122,114,10 - LTEXT "语言:",IDC_STATIC,13,57,23,8 - COMBOBOX IDC_COMBO1,37,55,65,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - GROUPBOX "关闭主窗口",IDC_STATIC,7,189,232,34 - CONTROL "最小化到通知区",IDC_MINIMIZE_TO_NOTIFY_RADIO,"Button",BS_AUTORADIOBUTTON | WS_GROUP,13,199,85,10 - CONTROL "退出程序",IDC_EXIT_PROGRAM_RADIO,"Button",BS_AUTORADIOBUTTON,13,210,90,10 - CONTROL "",IDC_SF2_PATH_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x80,70,154,158,12 - LTEXT "自动下载歌词保存位置:",IDC_STATIC,13,100,74,8 - CONTROL "保存到歌曲所在目录",IDC_SAVE_TO_SONG_FOLDER,"Button",BS_AUTORADIOBUTTON | WS_GROUP,88,99,75,10 - CONTROL "保存到歌词文件夹",IDC_SAVE_TO_LYRIC_FOLDER,"Button",BS_AUTORADIOBUTTON,165,99,68,10 - CONTROL "开机自动运行",IDC_AUTO_RUN_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,43,73,10 - LTEXT "更新源:",IDC_STATIC,13,32,32,8 - CONTROL "GitHub",IDC_GITHUB_RADIO,"Button",BS_AUTORADIOBUTTON | WS_GROUP,47,31,38,10 - CONTROL "Gitee",IDC_GITEE_RADIO,"Button",BS_AUTORADIOBUTTON,92,31,33,10 - GROUPBOX "配置和数据文件",IDC_STATIC,137,6,102,66 - CONTROL "保存到 Appdata 目录",IDC_SAVE_TO_APPDATA_RADIO,"Button",BS_AUTORADIOBUTTON | WS_GROUP,145,18,92,10 - CONTROL "保存到程序所在目录",IDC_SAVE_TO_PROGRAM_DIR_RADIO,"Button",BS_AUTORADIOBUTTON,145,30,92,10 - PUSHBUTTON "打开配置文件所在目录(&D)",IDC_OPEN_CONFIG_PATH_BUTTON,144,43,88,14 - LTEXT "自动下载封面保存位置:",IDC_STATIC,13,111,77,8 - CONTROL "保存到歌曲所在目录",IDC_SAVE_TO_SONG_FOLDER3,"Button",BS_AUTORADIOBUTTON | WS_GROUP,88,110,75,10 - CONTROL "保存到封面文件夹",IDC_SAVE_TO_ALBUM_FOLDER3,"Button",BS_AUTORADIOBUTTON,165,110,68,10 -END - -IDD_LYRIC_DOWNLOAD_DIALOG DIALOGEX 0, 0, 256, 189 -STYLE DS_SETFONT | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -CAPTION "下载歌词(通过网易云音乐的API)" -FONT 9, "微软雅黑", 400, 0, 0x0 +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - PUSHBUTTON "关闭",IDCANCEL,199,168,50,14 - PUSHBUTTON "搜索(&S)",IDC_SEARCH_BUTTON2,199,6,50,14 - EDITTEXT IDC_TITLE_EDIT1,29,7,69,12,ES_AUTOHSCROLL - LTEXT "标题:",IDC_STATIC,7,7,20,11,SS_CENTERIMAGE - EDITTEXT IDC_ARTIST_EDIT1,131,7,63,12,ES_AUTOHSCROLL - LTEXT "艺术家:",IDC_STATIC,103,7,27,11,SS_CENTERIMAGE - CONTROL "",IDC_LYRIC_DOWN_LIST1,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,31,242,97 - LTEXT "搜索结果:",IDC_STATIC_INFO,7,22,95,8 - DEFPUSHBUTTON "下载选中项",IDC_DOWNLOAD_SELECTED,74,168,52,14 - CONTROL "下载翻译歌词(如果有)",IDC_DOWNLOAD_TRANSLATE_CHECK1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,140,99,10 - GROUPBOX "下载选项",IDC_STATIC,7,129,242,36 - COMBOBOX IDC_COMBO2,178,139,48,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "保存的编码格式:",IDC_STATIC,122,141,55,8 - LTEXT "歌词保存位置:",IDC_STATIC,11,153,57,8 - CONTROL "保存到歌曲所在目录",IDC_SAVE_TO_SONG_FOLDER1,"Button",BS_AUTORADIOBUTTON,63,152,75,10 - CONTROL "保存到歌词文件夹",IDC_SAVE_TO_LYRIC_FOLDER1,"Button",BS_AUTORADIOBUTTON,151,152,68,10 - PUSHBUTTON "选中项另存为...",IDC_SELECTED_SAVE_AS,131,168,63,14 - CONTROL "取消关联",IDC_UNASSOCIATE_LINK,"SysLink",WS_TABSTOP,105,21,38,9 + CONTROL "",IDC_MFCEDITBROWSE1,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x80,4,4,322,12 + CONTROL "",IDC_CLASSIFY_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | LVS_OWNERDATA | WS_BORDER | WS_TABSTOP,4,20,124,146 + CONTROL "",IDC_SONG_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | LVS_OWNERDATA | WS_BORDER | WS_TABSTOP,131,20,195,146 + CONTROL "",IDC_HSPLITER_STATIC,"Static",SS_BLACKFRAME,128,20,3,146 END -IDD_LYRIC_BATCH_DOWN_DIALOG DIALOGEX 0, 0, 279, 228 -STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -EXSTYLE WS_EX_APPWINDOW -CAPTION "歌词批量下载(通过网易云音乐的API)" -FONT 9, "微软雅黑", 400, 0, 0x0 +IDD_FOLDER_EXPLORE_DIALOG DIALOGEX 0, 0, 330, 170 +STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - PUSHBUTTON "关闭",IDCANCEL,222,207,50,14 - CONTROL "",IDC_SONG_LIST1,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,67,265,137 - DEFPUSHBUTTON "开始下载",IDC_START_DOWNLOAD,166,207,50,14 - LTEXT "歌曲列表:",IDC_STATIC,7,58,39,8 - CONTROL "跳过已经有歌词的歌曲",IDC_SKIP_EXIST_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,18,81,10 - COMBOBOX IDC_COMBO1,188,18,48,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP - GROUPBOX "下载选项",IDC_STATIC,7,7,265,49 - LTEXT "保存的编码格式:",IDC_STATIC,132,19,56,8 - LTEXT "",IDC_INFO_STATIC,43,209,122,8 - CONTROL "下载翻译歌词(如果有)",IDC_DOWNLOAD_TRASNLATE_CHECK2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,29,105,10 - LTEXT "歌词保存位置:",IDC_STATIC,17,42,57,8 - CONTROL "保存到歌曲所在目录",IDC_SAVE_TO_SONG_FOLDER,"Button",BS_AUTORADIOBUTTON,69,41,75,10 - CONTROL "保存到歌词文件夹",IDC_SAVE_TO_LYRIC_FOLDER,"Button",BS_AUTORADIOBUTTON,157,41,68,10 - LTEXT "progressbar",IDC_PROGRESS_BAR,7,209,32,8 + CONTROL "",IDC_MFCEDITBROWSE1,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x80,4,4,322,12 + CONTROL "",IDC_FOLDER_EXPLORE_TREE,"SysTreeView32",TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | WS_BORDER | WS_HSCROLL | WS_TABSTOP,4,20,121,145 + CONTROL "",IDC_SONG_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | LVS_OWNERDATA | WS_BORDER | WS_TABSTOP,128,30,198,135 + LTEXT "",IDC_PATH_STATIC,128,20,198,8,SS_ENDELLIPSIS + CONTROL "",IDC_HSPLITER_STATIC,"Static",SS_BLACKFRAME,125,20,3,145 END -IDD_EQUALIZER_DIALOG DIALOGEX 0, 0, 277, 107 +IDD_ALL_MEDIA_DIALOG DIALOGEX 0, 0, 330, 170 STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU -FONT 9, "微软雅黑", 400, 0, 0x86 +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - CONTROL "启用均衡器",IDC_ENABLE_EQU_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,7,60,10 - CONTROL "",IDC_SLIDER1,"msctls_trackbar32",TBS_VERT | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,88,17,13,64 - CONTROL "",IDC_SLIDER2,"msctls_trackbar32",TBS_VERT | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,105,17,13,64 - CONTROL "",IDC_SLIDER3,"msctls_trackbar32",TBS_VERT | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,122,17,13,64 - CONTROL "",IDC_SLIDER4,"msctls_trackbar32",TBS_VERT | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,139,17,13,64 - CONTROL "",IDC_SLIDER5,"msctls_trackbar32",TBS_VERT | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,156,17,13,64 - CONTROL "",IDC_SLIDER6,"msctls_trackbar32",TBS_VERT | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,173,17,13,64 - CONTROL "",IDC_SLIDER7,"msctls_trackbar32",TBS_VERT | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,190,17,13,64 - CONTROL "",IDC_SLIDER8,"msctls_trackbar32",TBS_VERT | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,207,17,13,64 - CONTROL "",IDC_SLIDER9,"msctls_trackbar32",TBS_VERT | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,224,17,13,64 - CONTROL "",IDC_SLIDER10,"msctls_trackbar32",TBS_VERT | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,241,17,13,64 - GROUPBOX "均衡器预设",IDC_STATIC,7,20,66,75 - GROUPBOX "通道设定",IDC_STATIC,81,7,183,88 - LTEXT "80",IDC_STATIC,91,81,13,8 - LTEXT "125",IDC_STATIC,106,81,13,8 - LTEXT "250",IDC_STATIC,123,81,13,8 - LTEXT "500",IDC_STATIC,140,81,13,8 - LTEXT "1K",IDC_STATIC,159,81,13,8 - LTEXT "1.5K",IDC_STATIC,174,81,13,8 - LTEXT "2K",IDC_STATIC,193,81,13,8 - LTEXT "4K",IDC_STATIC,208,81,13,8 - LTEXT "8K",IDC_STATIC,226,81,13,8 - LTEXT "16K",IDC_STATIC,241,81,13,8 - CONTROL "",IDC_EQU_STYLES_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,13,31,54,59 + CONTROL "",IDC_SEARCH_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x80,4,4,322,12 + CONTROL "",IDC_SONG_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | LVS_OWNERDATA | WS_BORDER | WS_TABSTOP,4,20,322,146 END -IDD_SOUND_EFFECT_DIALOG DIALOGEX 0, 0, 290, 144 +IDD_ABOUTBOX DIALOGEX 0, 0, 222, 151 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "音效设定" -FONT 9, "微软雅黑", 400, 0, 0x0 +CAPTION "About MusicPlayer2" +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - PUSHBUTTON "关闭",IDCANCEL,233,123,50,14 - CONTROL "",IDC_TAB1,"SysTabControl32",0x0,7,7,276,113 + LTEXT "MusicPlayer2,V",IDC_STATIC_VERSION,14,43,194,8,SS_NOPREFIX | SS_ENDELLIPSIS + LTEXT "Copyright (C) 2017- By ZhongYang\r\nLast compiled date: <%1%>",IDC_STATIC_COPYRIGHT,14,53,194,16 + LTEXT "The third-party libraries used in this project:",IDC_STATIC_THIRD_PARTY_LIB,14,72,194,8,SS_ENDELLIPSIS + CONTROL "BASS",IDC_SYSLINK_BASS,"SysLink",WS_TABSTOP,14,82,25,8 + CONTROL "TagLib",IDC_SYSLINK_TAGLIB,"SysLink",WS_TABSTOP,43,82,36,8 + CONTROL "TinyXML2",IDC_SYSLINK_TINYXML2,"SysLink",WS_TABSTOP,82,82,38,8 + CONTROL "Scintilla",IDC_SYSLINK_SCINTILLA,"SysLink",WS_TABSTOP,130,82,38,8 + LTEXT "The author's other software:",IDC_STATIC_OTHER_SOFTWARE,14,93,194,8,SS_ENDELLIPSIS + CONTROL "TrafficMonitor",IDC_SYSLINK_TRAFFICMONITOR, + "SysLink",WS_TABSTOP,14,103,59,8,WS_EX_TRANSPARENT + CONTROL "SimpleNotePad",IDC_SYSLINK_SIMPLENOTEPAD,"SysLink",WS_TABSTOP,82,103,60,8 + CONTROL "Contract author",IDC_SYSLINK1,"SysLink",0x0,14,119,50,8,WS_EX_TRANSPARENT + CONTROL "Check for update",IDC_SYSLINK2,"SysLink",WS_TABSTOP,72,119,50,8 + CONTROL "GitHub",IDC_GITHUB_SYSLINK,"SysLink",WS_TABSTOP,14,129,50,8 + CONTROL "License",IDC_LICENSE_SYSLINK,"SysLink",WS_TABSTOP,72,129,50,8 + CONTROL "Donate",IDC_DONATE_SYSLINK,"SysLink",WS_TABSTOP,14,139,50,8 + CONTROL "Acknowledgement",IDC_ACKNOWLEDGEMENT_SYSLINK, + "SysLink",WS_TABSTOP,72,139,50,8 + DEFPUSHBUTTON "OK",IDOK,166,132,50,14,WS_GROUP END -IDD_REVERB_DIALOG DIALOGEX 0, 0, 258, 139 +IDD_APPEREANCE_SETTING_DLG DIALOGEX 0, 0, 344, 578 STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU -FONT 9, "微软雅黑", 400, 0, 0x0 +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - CONTROL "启用混响",IDC_ENABLE_REVERB_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,7,42,10 - CONTROL "",IDC_REVERB_MIX_SLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,44,25,100,13 - CONTROL "",IDC_REVERB_TIME_SLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,44,44,100,13 - LTEXT "混响强度:",IDC_STATIC,7,27,37,8 - LTEXT "混响时间:",IDC_STATIC,7,46,37,8 - LTEXT "x%",IDC_REVERB_MIX_STATIC,146,27,37,8 - LTEXT "0.00s",IDC_REVERB_TIME_STATIC,146,46,37,8 + GROUPBOX "Visual Effects",IDC_VISUAL_EFFECTS_STATIC,7,4,330,104,WS_GROUP + CONTROL "Show spectrum analysis",IDC_SHOW_SPECTRUM_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,16,126,8 + CONTROL "Low-frequency parts appears in the middle",IDC_LOW_FREQ_IN_CENTER_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,16,180,8 + RTEXT "Spectrum height:",IDC_TXT_SPECTRUM_HIGHT_STATIC,14,29,126,8 + CONTROL "",IDC_SPECTRUM_HEIGHT_SLIDER,"msctls_trackbar32",TBS_NOTICKS | WS_TABSTOP,150,29,100,12 + LTEXT "xxx%",IDC_SPECTRUM_HEIGHT_STATIC,260,30,70,8 + CONTROL "Show album cover",IDC_SHOW_ALBUM_COVER_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,42,126,8 + RTEXT "Album cover fit:",IDC_TXT_COVER_FIT_STATIC,14,54,126,8 + COMBOBOX IDC_ALBUM_FIT_COMBO,150,53,100,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "Lyric background",IDC_LYRIC_BACKGROUND_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,70,126,8 + CONTROL "Use rounded corner style",IDC_BTN_ROUND_CORNERS_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,70,180,8 + CONTROL "Dark mode",IDC_DARK_MODE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,82,126,8 + RTEXT "Main Window Opacity:",IDC_TXT_TRANSPARENT_STATIC,14,93,126,8 + CONTROL "",IDC_TRANSPARENT_SLIDER,"msctls_trackbar32",TBS_NOTICKS | WS_TABSTOP,150,92,100,12 + LTEXT "xx%",IDC_TRANSPARENT_STATIC,260,92,70,8 + GROUPBOX "Background Settings",IDC_TXT_BG_SETTING_STATIC,7,114,330,82,WS_GROUP + CONTROL "Enable background",IDC_ENABLE_BACKGROUND_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,126,126,8 + CONTROL "Use desktop background",IDC_USE_DESKTOP_BACKGROUND_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,126,180,8 + RTEXT "Background opacity:",IDC_TXT_BG_TRANSPARENCY_STATIC,14,139,126,8 + CONTROL "",IDC_BACKGROUND_TRANSPARENCY_SLIDER,"msctls_trackbar32",TBS_NOTICKS | WS_TABSTOP,150,138,100,12 + LTEXT "xx%",IDC_BACKGROUND_TRANSPARENCY_STATIC,260,139,70,8 + CONTROL "Use album cover as background",IDC_ALBUM_COVER_BACKGROUND_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,152,126,8 + CONTROL "Background Gaussian blur",IDC_BACKGROUND_GAUSS_BLUR_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,152,180,8 + RTEXT "Gaussian blur radius:",IDC_TXT_GAUSS_BLUR_RADIUS_STATIC,14,165,126,8 + CONTROL "",IDC_GAUSS_BLURE_RADIUS_SLIDER,"msctls_trackbar32",TBS_NOTICKS | WS_TABSTOP,150,164,100,12 + LTEXT "xx%",IDC_GAUSS_BLUR_RADIUS_STATIC,260,165,70,8 + RTEXT "Default background image:",IDC_TXT_DEFAULT_BG_PATH_EDIT_STATIC,14,179,126,8 + CONTROL "",IDC_DEFAULT_BACKGROUND_PATH_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x880,150,178,180,11 + GROUPBOX "Album Cover Options",IDC_TXT_COVER_OPT_STATIC,7,201,330,69,WS_GROUP + CONTROL "Use the Internal album cover first",IDC_USE_INNER_IMAGE_FIRST_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,213,316,8 + CONTROL "Use external picture when album cover not exist",IDC_USE_OUT_IMAGE_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,224,316,8 + RTEXT "External picture file name:",IDC_TXT_EXT_COVER_FILE_NAME_STATIC,14,239,126,8 + CONTROL "",IDC_DEFAULT_COVER_NAME_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x80,150,237,180,11 + RTEXT "Album cover folder:",IDC_TXT_EXT_COVER_FOLDER_STATIC,14,253,126,8 + CONTROL "",IDC_ALBUM_COVER_PATH_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x880,150,252,180,11 + GROUPBOX "Theme Color",IDC_TXT_THEME_COLOR_STATIC,7,276,330,50,WS_GROUP + LTEXT "",IDC_COLOR_STATIC,25,291,30,13,NOT WS_GROUP,WS_EX_STATICEDGE + GROUPBOX " Preset color",IDC_PRESET_COLOR_STATIC,73,283,134,27 + LTEXT "",IDC_COLOR_STATIC2,83,293,12,11,NOT WS_GROUP | WS_TABSTOP,WS_EX_STATICEDGE + LTEXT "",IDC_COLOR_STATIC3,103,293,12,11,NOT WS_GROUP | WS_TABSTOP,WS_EX_STATICEDGE + LTEXT "",IDC_COLOR_STATIC4,123,293,12,11,NOT WS_GROUP | WS_TABSTOP,WS_EX_STATICEDGE + LTEXT "",IDC_COLOR_STATIC5,143,293,12,11,NOT WS_GROUP | WS_TABSTOP,WS_EX_STATICEDGE + LTEXT "",IDC_COLOR_STATIC6,163,293,12,11,NOT WS_GROUP | WS_TABSTOP,WS_EX_STATICEDGE + LTEXT "",IDC_COLOR_STATIC7,183,293,12,11,NOT WS_GROUP | WS_TABSTOP,WS_EX_STATICEDGE + PUSHBUTTON "More Color...",IDC_SET_PROGRESS_COLOR_BUTTON,260,291,70,14 + CONTROL "Follow the system theme color",IDC_FOLLOW_SYSTEM_COLOR_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,313,180,8 + GROUPBOX "Status bar",IDC_TXT_STATUS_BAR_STATIC,7,331,330,35,WS_GROUP + CONTROL "Always show status bar",IDC_ALWAYS_SHOW_STATUSBAR_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,342,316,8 + CONTROL "Show next track",IDC_SHOW_NEXT_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,353,126,8 + CONTROL "Show fps",IDC_SHOW_FPS_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,353,180,8 + GROUPBOX "Title bar",IDC_TXT_TITLE_BAR_STATIC,7,372,330,77,WS_GROUP + CONTROL "Use system standard title bar",IDC_SHOW_SYSTEM_TITLEBAR_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,383,316,8 + LTEXT "Buttons displayed in the title bar(only available when ""Use system standard title bar"" is not checked):",IDC_TXT_TITLE_BAR_BTN_SEL_STATIC,14,394,316,17 + CONTROL "Settings",IDC_SHOW_SETTINGS_BTN_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,414,126,8 + CONTROL "Switch UI",IDC_SHOW_SKIN_BTN_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,414,180,8 + CONTROL "Mini mode",IDC_SHOW_MINI_MODE_BTN_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,425,126,8 + CONTROL "Full screen",IDC_SHOW_FULLSCREEN_BTN_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,425,180,8 + CONTROL "Minimize",IDC_SHOW_MINIMIZE_BTN_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,436,126,8 + CONTROL "Maximize/Restore",IDC_SHOW_MAXIMIZE_BTN_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,436,180,8 + GROUPBOX "Notification Area Icon",IDC_NA_ICO_STATIC,7,455,330,65,WS_GROUP + LTEXT "Preview:",IDC_PREVIEW_STATIC,14,467,126,8 + LTEXT "Select notification area icon:",IDC_TXT_NA_ICO_SEL_STATIC,150,467,180,8 + COMBOBOX IDC_COMBO1,150,481,100,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "Automatically adapt to Windows 10 dark/light mode when using the monochrome icons.",IDC_NOTIFY_ICON_AUTO_ADAPT_CHECK, + "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,14,498,316,18 + GROUPBOX "Advanced",IDC_TXT_ADV_STATIC,7,525,330,46,WS_GROUP + RTEXT "Interface refresh interval (ms):",IDC_TXT_UI_INTERVAL_STATIC,14,538,126,8 + EDITTEXT IDC_UI_INTERVAL_EDIT,150,537,51,12,ES_AUTOHSCROLL | ES_NUMBER + PUSHBUTTON "Restore Defaults",IDC_RESTORE_DEFAULT_BUTTON,260,536,70,14 + CONTROL "Album covers use GDI+ drawing (higher quality but will take up more CPU resources)",IDC_DEFAULT_ALBUM_COVER_HQ, + "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,14,551,316,17 END -IDD_COVER_DOWNLOAD_DIALOG DIALOGEX 0, 0, 257, 179 +IDD_OPTIONS_DIALOG DIALOGEX 0, 0, 369, 247 STYLE DS_SETFONT | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -CAPTION "下载专辑封面(通过网易云音乐的API)" -FONT 9, "微软雅黑", 400, 0, 0x0 +CAPTION "Option Settings" +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - PUSHBUTTON "取消",IDCANCEL,200,158,50,14 - PUSHBUTTON "搜索(&S)",IDC_SEARCH_BUTTON,199,6,50,14 - EDITTEXT IDC_TITLE_EDIT,29,7,69,12,ES_AUTOHSCROLL - LTEXT "标题:",IDC_STATIC,7,7,20,11,SS_CENTERIMAGE - EDITTEXT IDC_ARTIST_EDIT,131,7,63,12,ES_AUTOHSCROLL - LTEXT "艺术家:",IDC_STATIC,103,7,27,11,SS_CENTERIMAGE - CONTROL "",IDC_COVER_DOWN_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,31,242,97 - LTEXT "搜索结果:",IDC_STATIC_INFO,7,22,95,8 - DEFPUSHBUTTON "下载选中项",IDC_DOWNLOAD_SELECTED,144,158,50,14 - CONTROL "取消关联",IDC_UNASSOCIATE_LINK,"SysLink",WS_TABSTOP,105,21,38,9 - GROUPBOX "下载选项",IDC_DOWNLOAD_OPTION_GROUPBOX,7,130,243,25 - LTEXT "封面保存位置:",IDC_COVER_LOCATION_STATIC,12,142,47,8 - CONTROL "保存到歌曲所在目录",IDC_SAVE_TO_SONG_FOLDER2,"Button",BS_AUTORADIOBUTTON,66,142,78,10 - CONTROL "保存到封面文件夹",IDC_SAVE_TO_ALBUM_FOLDER2,"Button",BS_AUTORADIOBUTTON,156,142,74,10 + DEFPUSHBUTTON "OK",IDOK,204,227,50,14 + PUSHBUTTON "Cancel",IDCANCEL,259,227,50,14 + CONTROL "",IDC_OPTIONS_TAB,"SysTabControl32",0x0,5,4,359,217 + PUSHBUTTON "Apply",IDC_APPLY_BUTTON,314,227,50,14 END -IDD_FORMAT_CONVERT_DIALOG DIALOGEX 0, 0, 251, 238 -STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -EXSTYLE WS_EX_APPWINDOW -CAPTION "转换格式" -FONT 9, "微软雅黑", 400, 0, 0x0 +IDD_COVER_DOWNLOAD_DIALOG DIALOGEX 0, 0, 265, 231 +STYLE DS_SETFONT | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +CAPTION "Download album cover (From NetEase cloud music)" +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - CONTROL "",IDC_SONG_LIST1,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,32,237,80 - LTEXT "输出编码格式:",IDC_STATIC,7,8,49,8 - COMBOBOX IDC_OUT_FORMAT_COMBO,57,7,130,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "输出目录:",IDC_STATIC,14,196,32,8 - PUSHBUTTON "开始转换(&C)",IDC_START_CONVERT_BUTTON,138,217,53,14 - PUSHBUTTON "配置(&F)...",IDC_ENCODER_CONFIG_BUTTON,194,6,50,14 - GROUPBOX "选项",IDC_STATIC,6,116,238,97 - CONTROL "向目标文件写入标签信息",IDC_COPY_TAG_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,139,89,10 - CONTROL "向目标文件写入专辑封面",IDC_COPY_ALBUM_COVER_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,151,88,10 - LTEXT "当目标文件存在时:",IDC_STATIC,116,140,62,8 - COMBOBOX IDC_TARGET_FILE_EXIST_COMBO,178,139,60,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "为每个目标文件添加数字编号",IDC_ADD_NUMBER_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,116,152,99,10 - LTEXT "文件列表",IDC_STATIC,7,22,40,8 - PUSHBUTTON "取消",IDCANCEL,194,217,50,14 - LTEXT "Static",IDC_PROGRESS_TEXT,46,220,82,8 - LTEXT "progressbar",IDC_PROGRESS_BAR,7,220,36,8 - CONTROL "转换采样频率:",IDC_CHANGE_FREQ_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,127,59,10 - COMBOBOX IDC_FREQ_COMBO,82,126,72,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "",IDC_OUT_DIR_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x880,54,194,184,12 - CONTROL "转换完成后打开输出目录",IDC_OPEN_TARGET_DIR_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,163,88,10 - LTEXT "目标文件名:",IDC_STATIC,14,179,36,8 - CONTROL "",IDC_OUT_NAME_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x880,54,177,184,12 + LTEXT "Title:",IDC_TXT_COVER_DL_TITLE_STATIC,7,9,20,8 + EDITTEXT IDC_TITLE_EDIT,31,7,167,12,ES_AUTOHSCROLL + PUSHBUTTON "Search",IDC_SEARCH_BUTTON,208,7,50,14 + LTEXT "Artist:",IDC_TXT_COVER_DL_ARTIST_STATIC,7,23,20,8 + EDITTEXT IDC_ARTIST_EDIT,31,22,167,12,ES_AUTOHSCROLL + LTEXT "Search result:",IDC_STATIC_INFO,7,38,215,8,SS_ENDELLIPSIS + CONTROL "Cancel Link",IDC_UNASSOCIATE_LINK,"SysLink",LWS_RIGHT | WS_TABSTOP,234,37,24,9 + CONTROL "",IDC_COVER_DOWN_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,51,251,96 + GROUPBOX "Download options",IDC_DOWNLOAD_OPTION_GROUPBOX,7,152,251,49 + LTEXT "Album Cover Save Location:",IDC_COVER_LOCATION_STATIC,14,163,237,8 + CONTROL "Save to the same directory as the song",IDC_SAVE_TO_SONG_FOLDER2, + "Button",BS_AUTORADIOBUTTON,21,174,230,10 + CONTROL "Save to album cover directory",IDC_SAVE_TO_ALBUM_FOLDER2, + "Button",BS_AUTORADIOBUTTON,21,186,230,10 + DEFPUSHBUTTON "Download selected",IDC_DOWNLOAD_SELECTED,148,210,50,14 + PUSHBUTTON "Cancel",IDCANCEL,208,210,50,14 END -IDD_MP3_ENCODE_CFG_DIALOG DIALOGEX 0, 0, 176, 127 -STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "MP3 编码选项" -FONT 9, "微软雅黑", 400, 0, 0x0 +IDD_DATA_SETTINGS_DIALOG DIALOGEX 0, 0, 344, 241 +STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - CONTROL "恒定比特率 (CBR)",IDC_CBR_RADIO,"Button",BS_AUTORADIOBUTTON,7,7,68,10 - CONTROL "平均比特率 (ABR)",IDC_ABR_RADIO,"Button",BS_AUTORADIOBUTTON,7,21,67,10 - CONTROL "动态比特率 (VBR) (推荐)",IDC_VBR_RADIO,"Button",BS_AUTORADIOBUTTON,7,35,117,10 - CONTROL "自定义 lame 参数",IDC_USER_RADIO,"Button",BS_AUTORADIOBUTTON,7,63,93,10 - COMBOBOX IDC_CBR_RATE_COMBO,77,7,64,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "kbps",IDC_STATIC,145,8,24,8 - COMBOBOX IDC_ABR_RATE_COMBO,77,21,64,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "kbps",IDC_STATIC,145,22,24,8 - LTEXT "压缩品质:",IDC_STATIC,15,48,43,8 - LTEXT "编码器参数:",IDC_STATIC,7,79,43,8 - EDITTEXT IDC_ENCODE_CMDLINE_EDIT,56,77,113,12,ES_AUTOHSCROLL - DEFPUSHBUTTON "确定",IDOK,66,106,50,14 - PUSHBUTTON "取消",IDCANCEL,119,106,50,14 - CONTROL "",IDC_SLIDER1,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,75,47,77,10 - LTEXT "低",IDC_STATIC,63,48,12,8 - LTEXT "高",IDC_STATIC,157,48,12,8 - CONTROL "对于双声道采用联合立体声编码",IDC_JOINT_STEREO_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,92,120,10 + GROUPBOX "Application Settings",IDC_TXT_OPT_DATA_APP_SETTING_STATIC,7,4,133,95 + CONTROL "Check for update at startup",IDC_CHECK_UPDATE_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,16,119,8 + LTEXT "Update source:",IDC_TXT_OPT_DATA_UPDATE_SOURCE_SEL_STATIC,14,27,119,8 + CONTROL "GitHub",IDC_GITHUB_RADIO,"Button",BS_AUTORADIOBUTTON | WS_GROUP,21,38,112,8 + CONTROL "Gitee",IDC_GITEE_RADIO,"Button",BS_AUTORADIOBUTTON,21,49,112,8 + CONTROL "Auto run when Windows starts",IDC_AUTO_RUN_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,60,119,8 + LTEXT "Language:",IDC_TXT_OPT_DATA_LANGUAGE_SEL_STATIC,14,71,119,8 + COMBOBOX IDC_COMBO1,21,82,112,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + GROUPBOX "Configuration And Data Files",IDC_TXT_OPT_DATA_DATA_FILE_CFG_STATIC,150,4,187,55 + CONTROL "Save to Appdata directory",IDC_SAVE_TO_APPDATA_RADIO, + "Button",BS_AUTORADIOBUTTON | WS_GROUP,157,15,173,8 + CONTROL "Save to the program directory",IDC_SAVE_TO_PROGRAM_DIR_RADIO, + "Button",BS_AUTORADIOBUTTON,157,26,173,8 + PUSHBUTTON "Open configuration file directory",IDC_OPEN_CONFIG_PATH_BUTTON,157,39,173,14 + GROUPBOX "Close Main Window",IDC_TXT_OPT_DATA_CLOSE_MAIN_WINDOW_STATIC,150,63,187,36 + CONTROL "Minimize to notification area",IDC_MINIMIZE_TO_NOTIFY_RADIO, + "Button",BS_AUTORADIOBUTTON | WS_GROUP,157,74,173,8 + CONTROL "Exit the program",IDC_EXIT_PROGRAM_RADIO,"Button",BS_AUTORADIOBUTTON,157,86,173,8 + GROUPBOX "Automatic Download Settings",IDC_TXT_OPT_DATA_AUTO_DL_SETTING_STATIC,7,103,330,87 + CONTROL "Automatically download when lyric is not exist",IDC_LYRIC_AUTO_DOWNLOAD_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,114,316,8 + LTEXT "Automatically Download Lyrics Save Location:",IDC_TXT_OPT_DATA_AUTO_DL_LYRIC_SAVE_SEL_STATIC,14,125,316,8 + CONTROL "Save to the same directory as the song",IDC_SAVE_TO_SONG_FOLDER, + "Button",BS_AUTORADIOBUTTON | WS_GROUP,150,135,180,8 + CONTROL "Save to lyrics directory",IDC_SAVE_TO_LYRIC_FOLDER, + "Button",BS_AUTORADIOBUTTON,21,135,119,8 + CONTROL "Automatically download when album cover is not exist",IDC_COVER_AUTO_DOWNLOAD_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,146,316,8 + LTEXT "Automatically Download Album Cover Save Location:",IDC_TXT_OPT_DATA_AUTO_DL_COVER_SAVE_SEL_STATIC,14,156,316,8 + CONTROL "Save to the same directory as the song",IDC_SAVE_TO_SONG_FOLDER3, + "Button",BS_AUTORADIOBUTTON | WS_GROUP,150,167,180,8 + CONTROL "Save to album cover directory",IDC_SAVE_TO_ALBUM_FOLDER3, + "Button",BS_AUTORADIOBUTTON,21,167,119,8 + CONTROL "Download automatically only when the song information is complete",IDC_DOWNLOAD_WHEN_TAG_FULL_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,178,316,8 + GROUPBOX "MIDI Setting",IDC_TXT_OPT_DATA_MIDI_SETTING_STATIC,7,195,330,39 + CONTROL "Display the inner lyric in MIDI music first",IDC_MIDI_USE_INNER_LYRIC_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,206,316,8 + RTEXT "MIDI sound font path:",IDC_TXT_OPT_DATA_MIDI_SF2_PATH_STATIC,14,219,126,8 + CONTROL "",IDC_SF2_PATH_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x80,150,218,180,12 END -IDD_OGG_ENCODE_CFG_DIALOG DIALOGEX 0, 0, 181, 62 -STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "OGG 编码选项" -FONT 9, "微软雅黑", 400, 0, 0x0 +IDD_EQUALIZER_DIALOG DIALOGEX 0, 0, 299, 107 +STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - DEFPUSHBUTTON "确定",IDOK,67,41,50,14 - PUSHBUTTON "取消",IDCANCEL,123,41,50,14 - LTEXT "编码质量:",IDC_STATIC,7,7,37,8 - CONTROL "",IDC_QUALITY_SLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,62,7,100,10 - LTEXT "当前选择:",IDC_INFO_STATIC,7,22,129,8 - LTEXT "低",IDC_STATIC,51,7,10,8 - LTEXT "高",IDC_STATIC,163,7,11,8 + CONTROL "Enable equalizer",IDC_ENABLE_EQU_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,7,83,8 + GROUPBOX "Equalizer Presets",IDC_TXT_EQ_PRESET_STATIC,7,19,83,81 + CONTROL "",IDC_EQU_STYLES_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,14,32,69,61 + GROUPBOX "Channel Settings",IDC_TXT_EQ_CHANNEL_SETTING_STATIC,100,7,192,93 + CONTROL "",IDC_SLIDER1,"msctls_trackbar32",TBS_VERT | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,107,19,15,66 + CONTROL "",IDC_SLIDER2,"msctls_trackbar32",TBS_VERT | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,125,19,15,66 + CONTROL "",IDC_SLIDER3,"msctls_trackbar32",TBS_VERT | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,143,19,15,66 + CONTROL "",IDC_SLIDER4,"msctls_trackbar32",TBS_VERT | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,161,19,15,66 + CONTROL "",IDC_SLIDER5,"msctls_trackbar32",TBS_VERT | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,179,19,15,66 + CONTROL "",IDC_SLIDER6,"msctls_trackbar32",TBS_VERT | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,197,19,15,66 + CONTROL "",IDC_SLIDER7,"msctls_trackbar32",TBS_VERT | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,215,19,15,66 + CONTROL "",IDC_SLIDER8,"msctls_trackbar32",TBS_VERT | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,233,19,15,66 + CONTROL "",IDC_SLIDER9,"msctls_trackbar32",TBS_VERT | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,251,19,15,66 + CONTROL "",IDC_SLIDER10,"msctls_trackbar32",TBS_VERT | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,269,19,15,66 + CTEXT "80",IDC_STATIC,107,85,15,8 + CTEXT "125",IDC_STATIC,125,85,15,8 + CTEXT "250",IDC_STATIC,143,85,15,8 + CTEXT "500",IDC_STATIC,161,85,15,8 + CTEXT "1K",IDC_STATIC,179,85,15,8 + CTEXT "1.5K",IDC_STATIC,197,85,15,8 + CTEXT "2K",IDC_STATIC,215,85,15,8 + CTEXT "4K",IDC_STATIC,233,85,15,8 + CTEXT "8K",IDC_STATIC,251,85,15,8 + CTEXT "16K",IDC_STATIC,269,85,15,8 +END + +IDD_FIND_DIALOG DIALOGEX 0, 0, 290, 208 +STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +EXSTYLE WS_EX_APPWINDOW +CAPTION "Find File" +FONT 9, "Segoe UI", 400, 0, 0x0 +BEGIN + LTEXT "Enter the keyword to find:",IDC_TXT_FIND_KEY_WORD_INPUT_STATIC,7,7,19,12,SS_CENTERIMAGE + EDITTEXT IDC_FIND_EDIT,33,7,195,12,ES_AUTOHSCROLL + PUSHBUTTON "Find",IDC_FIND_BUTTON,233,6,50,14 + GROUPBOX "Find Range",IDC_TXT_FIND_FIND_RANGE_STATIC,7,21,113,35 + CONTROL "Find the current playlist",IDC_FIND_CURRENT_PLAYLIST_RADIO, + "Button",BS_AUTORADIOBUTTON,14,32,99,10 + CONTROL "Find entire media library",IDC_FIND_ALL_PLAYLIST_RADIO, + "Button",BS_AUTORADIOBUTTON,14,43,99,10 + GROUPBOX "Find options",IDC_TXT_FIND_OPT_STATIC,130,21,153,35 + CONTROL "Find file name",IDC_FIND_FILE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,137,32,69,10 + CONTROL "Find title",IDC_FIND_TITLE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,206,32,70,10 + CONTROL "Find artist",IDC_FIND_ARTIST_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,137,43,69,10 + CONTROL "Find album",IDC_FIND_ALBUM_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,206,43,70,10 + LTEXT "Last find results:",IDC_FIND_RESULT_STATIC,7,59,113,8,SS_ENDELLIPSIS + RTEXT "Find keyword <%1%>, <%2%> results.",IDC_FIND_INFO_STATIC,130,59,153,8,SS_ENDELLIPSIS + CONTROL "",IDC_FIND_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,69,276,112 + DEFPUSHBUTTON "Play the selected track",IDOK,171,187,50,14 + PUSHBUTTON "Close",IDCANCEL,233,187,50,14 +END + +IDD_FORMAT_CONVERT_DIALOG DIALOGEX 0, 0, 320, 244 +STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +EXSTYLE WS_EX_APPWINDOW +CAPTION "Convert Format" +FONT 9, "Segoe UI", 400, 0, 0x0 +BEGIN + LTEXT "Output encoding format:",IDC_TXT_FORMAT_CONVERT_OUT_FORMAT_SEL_STATIC,7,8,43,8,SS_ENDELLIPSIS + COMBOBOX IDC_OUT_FORMAT_COMBO,61,7,187,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Config...",IDC_ENCODER_CONFIG_BUTTON,263,6,50,14 + LTEXT "File list:",IDC_TXT_FORMAT_CONVERT_FILE_LIST_STATIC,7,21,306,8 + CONTROL "",IDC_SONG_LIST1,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,32,306,78 + GROUPBOX "Options",IDC_TXT_FORMAT_CONVERT_OPT_STATIC,7,112,306,107 + CONTROL "Convert sampling frequency:",IDC_CHANGE_FREQ_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,122,56,11 + COMBOBOX IDC_FREQ_COMBO,77,122,88,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "Write tag information",IDC_COPY_TAG_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,136,146,10 + CONTROL "Write album cover",IDC_COPY_ALBUM_COVER_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,170,136,136,10 + LTEXT "Destination file name:",IDC_TXT_FORMAT_CONVERT_OUT_FILE_NAME_STATIC,14,150,29,8,SS_ENDELLIPSIS + CONTROL "",IDC_OUT_NAME_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x880,51,148,255,12 + CONTROL "Add a number to each destination file",IDC_ADD_NUMBER_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,162,285,10 + RTEXT "When the destination file exists:",IDC_TXT_FORMAT_CONVERT_FILE_EXIST_SEL_STATIC,14,175,146,8,SS_ENDELLIPSIS + COMBOBOX IDC_TARGET_FILE_EXIST_COMBO,170,173,89,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Output directory:",IDC_TXT_FORMAT_CONVERT_OUT_DIR_STATIC,14,190,29,8,SS_ENDELLIPSIS + CONTROL "",IDC_OUT_DIR_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x880,51,188,255,12 + CONTROL "Open output directory after the conversion is complete",IDC_OPEN_TARGET_DIR_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,203,285,10 + LTEXT "progressbar",IDC_PROGRESS_BAR,9,225,40,8 + LTEXT "<%1%>% completed, please wait...",IDC_PROGRESS_TEXT,53,225,155,8,SS_ENDELLIPSIS + PUSHBUTTON "Start convert",IDC_START_CONVERT_BUTTON,210,223,50,14 + PUSHBUTTON "Cancel",IDCANCEL,263,223,50,14 END -IDD_WMA_ENCODE_CFG_DIALOG DIALOGEX 0, 0, 163, 65 -STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "WMA 编码选项" -FONT 9, "微软雅黑", 400, 0, 0x0 +IDD_MESSAGE_DIALOG DIALOGEX 0, 0, 235, 176 +STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +EXSTYLE WS_EX_APPWINDOW +CAPTION "Message" +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - DEFPUSHBUTTON "确定",IDOK,49,44,50,14 - PUSHBUTTON "取消",IDCANCEL,106,44,50,14 - COMBOBOX IDC_BITRATE_COMBO,73,7,54,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "kbps",IDC_STATIC,132,8,24,8 - CONTROL "恒定比特率(CBR):",IDC_CBR_RADIO,"Button",BS_AUTORADIOBUTTON,7,7,65,10 - COMBOBOX IDC_VBR_QUALITY_COMBO,73,24,54,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "基于质量的 VBR:",IDC_CBR_RADIO2,"Button",BS_AUTORADIOBUTTON,7,24,65,10 - LTEXT "%",IDC_STATIC,132,25,24,8 + LTEXT "Info:",IDC_INFO_STATIC,7,7,221,8 + EDITTEXT IDC_HELP_EDIT,7,19,221,132,ES_MULTILINE | ES_READONLY | WS_VSCROLL + CONTROL "SysLink",IDC_SYSLINK1,"SysLink",WS_TABSTOP,8,157,30,8 + DEFPUSHBUTTON "OK",IDOK,178,155,50,14 END -IDD_TAG_EDIT_DIALOG DIALOGEX 0, 0, 157, 163 -STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "编辑音频标签" -FONT 9, "微软雅黑", 400, 0, 0x0 +IDD_HOT_KEY_SETTINGS_DIALOG DIALOGEX 0, 0, 344, 190 +STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - PUSHBUTTON "关闭",IDCANCEL,100,142,50,14 - EDITTEXT IDC_TITEL_EDIT,37,22,113,12,ES_AUTOHSCROLL - EDITTEXT IDC_ARTIST_EDIT,37,37,113,12,ES_AUTOHSCROLL - EDITTEXT IDC_ALBUM_EDIT,37,52,113,12,ES_AUTOHSCROLL - EDITTEXT IDC_TRACK_EDIT,37,67,33,12,ES_AUTOHSCROLL - EDITTEXT IDC_YEAR_EDIT,105,67,45,12,ES_AUTOHSCROLL - EDITTEXT IDC_COMMENT_EDIT,37,97,113,36,ES_MULTILINE | WS_VSCROLL - LTEXT "标题:",IDC_STATIC,7,25,22,8 - LTEXT "艺术家:",IDC_STATIC,7,39,28,8 - LTEXT "唱片集:",IDC_STATIC,7,54,28,8 - LTEXT "年份:",IDC_STATIC,82,68,22,8 - LTEXT "流派:",IDC_STATIC,7,84,22,8 - LTEXT "注释:",IDC_STATIC,7,99,22,8 - LTEXT "音轨号:",IDC_STATIC,7,69,28,8 - COMBOBOX IDC_GENRE_COMBO,37,83,113,38,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "<",IDC_PREVIOUS_BUTTON,7,142,15,14 - PUSHBUTTON ">",IDC_NEXT_BUTTON,24,142,15,14 - LTEXT "Static",IDC_ITEM_STATIC,7,134,45,8 - EDITTEXT IDC_PATH_EDIT,37,7,113,12,ES_AUTOHSCROLL | ES_READONLY - LTEXT "路径:",IDC_STATIC,7,10,22,8 - PUSHBUTTON "保存",IDC_SAVE_BUTTON,46,142,50,14 + CONTROL "Enable global hot keys",IDC_HOT_KEY_ENABLE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,7,153,8 + CONTROL "Enable global multimedia keys",IDC_ENABLE_GLOBAL_MULTIMEDIA_KEY_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,170,7,167,8 + CONTROL "",IDC_HOT_KEY_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,20,330,142 + RTEXT "Key:",IDC_TXT_OPT_HOT_KEY_SHORTCUT_KEY_SEL_STATIC,7,171,108,8 + CONTROL "",IDC_HOTKEY1,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,123,169,156,12 + PUSHBUTTON "Set",IDC_SET_BUTTON,287,168,50,14 END -IDD_RECORDER_DIALOG DIALOGEX 0, 0, 227, 72 -STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "录音机" -FONT 9, "微软雅黑", 400, 0, 0x0 +IDD_LYRIC_BATCH_DOWN_DIALOG DIALOGEX 0, 0, 344, 234 +STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +EXSTYLE WS_EX_APPWINDOW +CAPTION "Lyrics batch download (From NetEase cloud music)" +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - LTEXT "编码格式:",IDC_STATIC,74,10,33,8 - COMBOBOX IDC_OUT_FORMAT_COMBO,108,9,57,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "输出目录:",IDC_STATIC,7,54,32,8 - EDITTEXT IDC_OUT_DIR_EDIT,39,53,133,12,ES_AUTOHSCROLL | ES_READONLY - PUSHBUTTON "浏览(&B)...",IDC_BROWSE_BUTTON,175,51,45,14 - PUSHBUTTON "配置(&F)...",IDC_ENCODER_CONFIG_BUTTON,170,7,50,14 - PUSHBUTTON "录制(&R)",IDC_RECORD_BUTTON,75,25,45,14 - PUSHBUTTON "暂停/继续(&P)",IDC_PAUSE_RESUME_BUTTON,125,25,45,14 - PUSHBUTTON "停止(&S)",IDC_STOP_BUTTON,175,25,45,14 - LTEXT "Static",IDC_TIME_STATIC,75,42,45,8,0,WS_EX_STATICEDGE - COMBOBOX IDC_RECORDE_INPUT_COMBO,7,7,54,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + GROUPBOX "Download Options",IDC_TXT_LYRIC_BDL_DL_OPT_STATIC,7,7,330,62 + CONTROL "Skip songs that already have lyrics",IDC_SKIP_EXIST_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,18,136,8 + RTEXT "Saved encoding format:",IDC_TXT_LYRIC_BDL_SAVE_ENCODE_SEL_STATIC,160,18,107,8 + COMBOBOX IDC_COMBO1,272,16,58,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + CONTROL "Download translated lyrics (If any)",IDC_DOWNLOAD_TRASNLATE_CHECK2, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,31,316,8 + LTEXT "Lyrics Save Location:",IDC_TXT_LYRIC_BDL_SAVE_DIR_SEL_STATIC,14,43,316,8 + CONTROL "Save to lyrics directory",IDC_SAVE_TO_LYRIC_FOLDER, + "Button",BS_AUTORADIOBUTTON,21,55,129,8 + CONTROL "Save to the same directory as the song",IDC_SAVE_TO_SONG_FOLDER, + "Button",BS_AUTORADIOBUTTON,160,55,170,8 + LTEXT "Song list:",IDC_TXT_LYRIC_BDL_SONG_LIST_STATIC,7,72,330,8 + CONTROL "",IDC_SONG_LIST1,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,83,330,126 + LTEXT "progressbar",IDC_PROGRESS_BAR,7,216,40,8 + LTEXT "Downloading, <%1%>% completed, please wait...",IDC_INFO_STATIC,50,216,179,8,SS_ENDELLIPSIS + DEFPUSHBUTTON "Start download",IDC_START_DOWNLOAD,233,213,50,14 + PUSHBUTTON "Close",IDCANCEL,287,213,50,14 END -IDD_PLAY_SETTING_DIALOG DIALOGEX 0, 0, 246, 287 -STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU -FONT 9, "微软雅黑", 400, 0, 0x86 +IDD_LYRIC_DOWNLOAD_DIALOG DIALOGEX 0, 0, 300, 225 +STYLE DS_SETFONT | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +CAPTION "Lyric download (From NetEase cloud music)" +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - GROUPBOX "播放选项",IDC_STATIC,7,5,232,61 - CONTROL "出现错误时停止播放(&E)",IDC_STOP_WHEN_ERROR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,17,83,10 - CONTROL "在任务栏显示播放进度(&P)",IDC_SHOW_TASKBAR_PROGRESS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,29,93,10 - GROUPBOX "播放设备",IDC_STATIC,7,114,232,78 - COMBOBOX IDC_OUTPUT_DEVICE_COMBO,68,124,161,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "选择播放设备:",IDC_STATIC,17,125,47,8 - CONTROL "",IDC_OUTPUT_DEVICE_INFO_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,17,140,212,46 - CONTROL "程序启动时自动播放(&A)",IDC_AUTO_PLAY_WHEN_START_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,124,17,102,10 - CONTROL "在任务栏显示播放状态图标(&I)",IDC_SHOW_PLAY_STATE_ICON_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,124,29,102,10 - CONTROL "声音淡入淡出效果(&F)",IDC_SOUND_FADE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,41,91,10 - GROUPBOX "播放内核",IDC_STATIC,7,71,232,38 - CONTROL "BASS",IDC_BASS_RADIO,"Button",BS_AUTORADIOBUTTON,17,83,93,10 - CONTROL "MCI (Media Control Interface)",IDC_MCI_RADIO,"Button",BS_AUTORADIOBUTTON,123,83,114,10 - CONTROL "FFMPEG",IDC_FFMPEG_RADIO,"Button",BS_AUTORADIOBUTTON,17,95,46,10 - CONTROL "切换播放列表时继续播放(&S)",IDC_CONTINUE_WHEN_SWITCH_PLAYLIST_CHECK, - "Button",BS_AUTOCHECKBOX | BS_ICON | WS_TABSTOP,124,41,98,10 - GROUPBOX "FFMPEG 核心设置",IDC_STATIC,7,198,232,78 - LTEXT "缓存时长:",IDC_STATIC,17,209,39,8 - EDITTEXT IDC_FFMPEG_CACHE_LENGTH,49,208,24,12,ES_AUTOHSCROLL - LTEXT "秒",IDC_STATIC,77,209,10,8 - LTEXT "最大重试次数:",IDC_STATIC,17,223,60,8 - EDITTEXT IDC_FFMPEG_MAX_RETRY_COUNT,61,222,36,12,ES_AUTOHSCROLL - LTEXT "次(-1为无限制)",IDC_STATIC,101,223,70,8 - LTEXT "重试间隔:",IDC_STATIC,17,237,60,8 - EDITTEXT IDC_FFMPEG_URL_RETRY_INTERVAL,49,236,24,12,ES_AUTOHSCROLL - LTEXT "秒(仅非本地文件)",IDC_STATIC,76,237,70,8 - CONTROL "点击此处下载",IDC_FFMPEG_DOWN_SYSLINK,"SysLink",WS_TABSTOP,66,95,157,10 - CONTROL "启用WASAPI",IDC_FFMPEG_ENABLE_WASAPI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,249,55,10 - CONTROL "启用独占模式",IDC_FFMPEG_ENABLE_WASAPI_EXCLUSIVE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,120,249,55,10 - LTEXT "定位等操作最大等待时间:",IDC_STATIC,17,262,80,8 - EDITTEXT IDC_FFMPEG_MAX_WAIT_TIME,93,261,40,12,ES_AUTOHSCROLL - LTEXT "毫秒",IDC_STATIC,136,262,14,8 - CONTROL "使用系统媒体控件(需要重新启动)",IDC_USE_MEDIA_TRANS_CONTORL_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,53,139,10 + LTEXT "Title:",IDC_TXT_LYRIC_DL_TITLE_STATIC,7,7,20,12,SS_CENTERIMAGE + EDITTEXT IDC_TITLE_EDIT1,34,7,200,12,ES_AUTOHSCROLL + PUSHBUTTON "Search",IDC_SEARCH_BUTTON2,243,6,50,14 + LTEXT "Artist:",IDC_TXT_LYRIC_DL_ARTIST_STATIC,7,22,20,12,SS_CENTERIMAGE + EDITTEXT IDC_ARTIST_EDIT1,34,22,200,12,ES_AUTOHSCROLL + LTEXT "Search results:",IDC_STATIC_INFO,7,38,227,8 + CONTROL "Cancel Link",IDC_UNASSOCIATE_LINK,"SysLink",LWS_RIGHT | WS_TABSTOP,243,38,50,8 + CONTROL "",IDC_LYRIC_DOWN_LIST1,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,49,286,88 + GROUPBOX "Download options",IDC_TXT_LYRIC_DL_OPT_STATIC,7,140,286,60 + CONTROL "Download translated lyrics (If any)",IDC_DOWNLOAD_TRANSLATE_CHECK1, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,152,272,8 + RTEXT "Saved encoding format:",IDC_TXT_LYRIC_DL_SAVE_ENCODE_SEL_STATIC,14,164,150,8 + COMBOBOX IDC_COMBO2,173,162,69,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + LTEXT "Lyrics Save Location:",IDC_TXT_LYRIC_DL_SAVE_DIR_SEL_STATIC,14,175,272,8 + CONTROL "Save to lyrics directory",IDC_SAVE_TO_LYRIC_FOLDER1, + "Button",BS_AUTORADIOBUTTON,21,186,105,8 + CONTROL "Save to the same directory as the song",IDC_SAVE_TO_SONG_FOLDER1, + "Button",BS_AUTORADIOBUTTON,141,186,145,8 + DEFPUSHBUTTON "Download selected",IDC_DOWNLOAD_SELECTED,133,204,50,14 + PUSHBUTTON "Selected save as...",IDC_SELECTED_SAVE_AS,188,204,50,14 + PUSHBUTTON "Close",IDCANCEL,243,204,50,14 END -IDD_SUPPORT_FORMAT_DIALOG DIALOGEX 0, 0, 275, 182 -STYLE DS_SETFONT | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -CAPTION "支持的格式" -FONT 9, "微软雅黑", 400, 0, 0x0 +IDD_LYRIC_EDIT_DIALOG DIALOGEX 0, 0, 297, 242 +STYLE DS_SETFONT | DS_MODALFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_APPWINDOW +CAPTION "Edit Lyric" +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - DEFPUSHBUTTON "确定",IDOK,218,161,50,14 - LTEXT "",IDC_INFO_STATIC,7,7,261,19 - CONTROL "",IDC_FORMAT_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,30,261,125 + LTEXT "Lyric path:",IDC_STATIC1,4,19,22,8,SS_ENDELLIPSIS + EDITTEXT IDC_LYRIC_PATH_EDIT2,29,17,264,12,ES_AUTOHSCROLL | ES_READONLY END -IDD_HOT_KEY_SETTINGS_DIALOG DIALOGEX 0, 0, 255, 168 +IDD_LYRIC_SETTING_DIALOG DIALOGEX 0, 0, 344, 417 STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU -FONT 9, "微软雅黑", 400, 0, 0x0 +FONT 9, "Segoe UI", 400, 0, 0x0 +BEGIN + GROUPBOX "Lyric Options",IDC_TXT_OPT_LRC_OPT_STATIC,7,4,330,81 + CONTROL "Use the Internal lyrics first",IDC_USE_INNER_LYRIC_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,16,126,8 + CONTROL "Lyrics fuzzy match",IDC_LYRIC_FUZZY_MATCH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,16,180,8 + CONTROL "Show lyrics translation (If any)",IDC_SHOW_LYRIC_TRANSLATE_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,28,126,8 + CONTROL "Show song Info when no lyrics",IDC_SHOW_SONG_INFO_IF_LYRIC_NOT_EXIST_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,28,180,8 + RTEXT "Lyrics folder:",IDC_TXT_OPT_LRC_LRC_FOLDER_STATIC,14,42,126,8,SS_ENDELLIPSIS + CONTROL "",IDC_LYRIC_PATH_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x880,150,40,180,12 + RTEXT "After lyrics modified:",IDC_TXT_OPT_LRC_SAVE_POLICY_SEL_STATIC,14,57,126,8,SS_ENDELLIPSIS + COMBOBOX IDC_LYRIC_SAVE_COMBO,150,55,100,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "Lyrics displayed in karaoke style",IDC_KARAOKE_DISP, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,71,126,8 + CONTROL "Do not display empty lines for lyrics",IDC_LYRIC_HIDE_BLANK_LINE_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,71,180,8 + GROUPBOX "Window Lyrics",IDC_TXT_OPT_LRC_WINDOW_LRC_STATIC,7,90,330,44 + RTEXT "Lyrics line spacing (pixel):",IDC_TXT_OPT_LRC_WINDOW_LRC_LINE_SPACING_STATIC,14,101,126,8,SS_ENDELLIPSIS + EDITTEXT IDC_FONT_SIZE_EDIT2,150,99,50,12,ES_AUTOHSCROLL + RTEXT "Lyrics alignment:",IDC_TXT_OPT_LRC_WINDOW_LRC_ALIGN_SEL_STATIC,14,118,126,8,SS_ENDELLIPSIS + COMBOBOX IDC_ALIGNMENT_COMBO2,150,116,100,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Set Font...",IDC_SET_FONT_BUTTON,260,114,70,14 + GROUPBOX "Desktop Lyrics",IDC_TXT_OPT_LRC_DESKTOP_LRC_STATIC,7,139,330,123 + CONTROL "Show desktop lyrics",IDC_SHOW_DESKTOP_LYRIC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,150,126,8 + CONTROL "Lock desktop lyrics",IDC_LOCK_DESKTOP_LYRIC_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,174,119,8 + CONTROL "Hide lyrics window without lyrics",IDC_HIDE_LYRIC_WITHOUT_LYRIC_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,162,119,8 + CONTROL "Hide lyrics window when paused",IDC_HIDE_LYRIC_PAUSE_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,162,180,8 + CONTROL "Lyrics background penetrate",IDC_HIDE_LYRIC_WITHOUT_LYRIC_CHECK3, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,150,180,8 + CONTROL "Show unlock button when locked",IDC_SHOW_UNLOCK_WHEN_LOCKED, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,174,180,8 + CONTROL "Lyrics displayed in double line",IDC_LYRIC_DOUBLE_LINE_CHECK2, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,186,119,8 + RTEXT "Text color:",IDC_TXT_OPT_LRC_DESKTOP_LRC_COLOR_TEXT_STATIC,21,200,79,8,SS_ENDELLIPSIS + LTEXT "",IDC_TEXT_COLOR1_STATIC,106,198,15,11,NOT WS_GROUP | WS_TABSTOP,WS_EX_STATICEDGE + LTEXT "",IDC_TEXT_COLOR2_STATIC,125,198,15,11,NOT WS_GROUP | WS_TABSTOP,WS_EX_STATICEDGE + RTEXT "Highlight color:",IDC_TXT_OPT_LRC_DESKTOP_LRC_COLOR_HIGHLIGHT_STATIC,21,215,79,8,SS_ENDELLIPSIS + LTEXT "",IDC_HIGHLIGHT_COLOR1_STATIC,106,213,15,11,NOT WS_GROUP | WS_TABSTOP,WS_EX_STATICEDGE + LTEXT "",IDC_HIGHLIGHT_COLOR2_STATIC,125,213,15,11,NOT WS_GROUP | WS_TABSTOP,WS_EX_STATICEDGE + COMBOBOX IDC_TEXT_GRADIENT_COMBO,150,198,100,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_HIGHLIGHT_GRADIENT_COMBO,150,213,100,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Styles Preset",IDC_DEFAULT_STYLE,260,204,70,14 + RTEXT "Lyrics opacity:",IDC_TXT_OPT_LRC_DESKTOP_LRC_TRANSPARENCY_STATIC,21,230,119,8,SS_ENDELLIPSIS + CONTROL "",IDC_LYRIC_OPACITY_SLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,150,229,100,10 + LTEXT "100%",IDC_LYRIC_OPACITY_STATIC,260,229,70,8 + RTEXT "Lyrics alignment:",IDC_TXT_OPT_LRC_DESKTOP_LRC_ALIGN_SEL_STATIC,21,245,119,8,SS_ENDELLIPSIS + COMBOBOX IDC_DESKTOP_LYRIC_ALIGNMENT_COMBO,150,243,100,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Set Font...",IDC_SET_FONT2,260,242,70,14 + GROUPBOX "Show play information in taskbar search box",IDC_TXT_OPT_LRC_SEARCH_BOX_FUNCTION_STATIC,7,268,330,142 + CONTROL "Enable taskbar search box function",IDC_SHOW_LYRIC_IN_CORTANA, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,280,126,8 + CONTROL "Display lyrics using compatibility mode",IDC_LYRIC_COMPATIBLE_MODE, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,280,180,8 + CONTROL "Keep on display when paused",IDC_KEEP_DISPLAY_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,292,309,8 + RTEXT "Search box background color:",IDC_TXT_OPT_LRC_SEARCH_BOX_BG_COLOR_SEL_STATIC,21,305,119,8,SS_ENDELLIPSIS + COMBOBOX IDC_CORTANA_COLOR_COMBO,150,303,100,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "The search box background is transparent in Windows 10 light mode",IDC_SEARCH_BOX_TRANSPARENT_IN_WHITE_MODE, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,317,309,8 + CONTROL "Show album cover in search box",IDC_SHOW_ALBUM_COVER_IN_CORTANA, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,329,309,8 + CONTROL "Show phonograph icon in the search box when there is no album cover",IDC_SHOW_DEFAULT_ALBUM_ICON_CHK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,341,309,8 + CONTROL "Cortana icon beats following the music rhythm",IDC_CORTANA_ICON_DEAT_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,353,309,8 + CONTROL "Show spectrum analysis in search box",IDC_SHOW_SPECTRUM_IN_CORTANA, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,365,309,8 + CONTROL "Show lyrics in search box",IDC_SHOW_LYRIC_IN_CORTANA2, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,377,117,8 + CONTROL "Lyrics displayed in double line",IDC_LYRIC_DOUBLE_LINE_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,377,180,8 + RTEXT "Lyrics alignment:",IDC_TXT_OPT_LRC_SEARCH_BOX_ALIGN_SEL_STATIC,21,392,119,8,SS_ENDELLIPSIS + COMBOBOX IDC_ALIGNMENT_COMBO,150,390,100,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Set Font...",IDC_SET_FONT,260,389,70,14 +END + +IDD_MP3_ENCODE_CFG_DIALOG DIALOGEX 0, 0, 249, 118 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "MP3 Encode Options" +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - CONTROL "启用全局快捷键",IDC_HOT_KEY_ENABLE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,5,105,10 - CONTROL "",IDC_HOT_KEY_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,16,192,118 - CONTROL "",IDC_HOTKEY1,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,38,139,97,12 - LTEXT "快捷键:",IDC_STATIC,7,141,29,8 - PUSHBUTTON "设置(&S)",IDC_SET_BUTTON,141,138,50,14 - CONTROL "启用全局多媒体快捷键",IDC_ENABLE_GLOBAL_MULTIMEDIA_KEY_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,154,151,10 + CONTROL "Constant bit rate (CBR):",IDC_CBR_RADIO,"Button",BS_AUTORADIOBUTTON,7,7,125,8 + COMBOBOX IDC_CBR_RATE_COMBO,139,5,64,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "Average bit rate (ABR):",IDC_ABR_RADIO,"Button",BS_AUTORADIOBUTTON,7,20,125,8 + COMBOBOX IDC_ABR_RATE_COMBO,139,19,64,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "Variable bit rate (VBR) (recommended)",IDC_VBR_RADIO, + "Button",BS_AUTORADIOBUTTON,7,33,235,8 + RTEXT "Compression quality:",IDC_TXT_ENCODE_OPT_MP3_VBR_QUALITY_SEL_STATIC,7,45,125,8,SS_ENDELLIPSIS + CONTROL "",IDC_SLIDER1,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,139,44,96,10 + LTEXT "low",IDC_TXT_ENCODE_OPT_MP3_VBR_QUALITY_LOW_STATIC,139,56,48,8 + RTEXT "High",IDC_TXT_ENCODE_OPT_MP3_VBR_QUALITY_HIGH_STATIC,187,56,48,8 + CONTROL "Joint stereo encoding for dual channels",IDC_JOINT_STEREO_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,67,235,8 + CONTROL "Custom lame parameters:",IDC_USER_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,81,41,8 + EDITTEXT IDC_ENCODE_CMDLINE_EDIT,58,80,184,12,ES_AUTOHSCROLL + DEFPUSHBUTTON "OK",IDOK,135,97,50,14 + PUSHBUTTON "Cancel",IDCANCEL,192,97,50,14 END -IDD_MUSICPLAYER2_DIALOG DIALOGEX 0, 0, 374, 264 +IDD_MUSICPLAYER2_DIALOG DIALOGEX 0, 0, 382, 250 STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME EXSTYLE WS_EX_ACCEPTFILES | WS_EX_APPWINDOW CAPTION "MusicPlayer" CLASS "MusicPlayer_l3gwYT" -FONT 9, "微软雅黑", 400, 0, 0x0 +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - LTEXT "当前文件夹:",IDC_PATH_STATIC,188,2,43,12,SS_CENTERIMAGE | WS_TABSTOP - CONTROL "",IDC_PLAYLIST_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | LVS_OWNERDATA | LVS_NOCOLUMNHEADER | WS_BORDER | WS_TABSTOP,185,39,182,202 - PUSHBUTTON "媒体库(&L)...",ID_SET_PATH,316,0,51,14 - LTEXT "工具栏",IDC_PLAYLIST_TOOLBAR,185,29,182,8 - CONTROL "",IDC_SEARCH_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x80,188,15,178,12 - LTEXT "UI Static",IDC_UI_STATIC,2,0,96,53 - CONTROL "",IDC_PATH_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x880,232,2,80,11 - CONTROL "",IDC_HSPLITER_STATIC,"Static",SS_BLACKFRAME,182,2,3,255 + LTEXT "UI Static",IDC_UI_STATIC,3,0,108,53 + LTEXT "Folder:",IDC_PATH_STATIC,186,3,46,12,SS_CENTERIMAGE | WS_TABSTOP + CONTROL "",IDC_PATH_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x880,225,2,90,11 + PUSHBUTTON "Media &Library...",ID_MEDIA_LIB,321,1,54,13 + CONTROL "",IDC_SEARCH_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x80,188,17,178,12 + LTEXT "Toolbar",IDC_PLAYLIST_TOOLBAR,185,32,182,9 + CONTROL "",IDC_PLAYLIST_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | LVS_OWNERDATA | LVS_NOCOLUMNHEADER | WS_BORDER | WS_TABSTOP,185,42,190,200 + CONTROL "",IDC_HSPLITER_STATIC,"Static",SS_BLACKFRAME,180,0,4,243 END -IDD_LISTEN_TIME_STATISTICS_DLG DIALOGEX 0, 0, 306, 172 -STYLE DS_SETFONT | DS_MODALFRAME | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "累计播放时间统计" -FONT 9, "微软雅黑", 400, 0, 0x0 +IDD_OGG_ENCODE_CFG_DIALOG DIALOGEX 0, 0, 171, 65 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "OGG Encode Options" +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - DEFPUSHBUTTON "关闭(&C)",IDOK,249,151,50,14 - CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,7,292,140 - PUSHBUTTON "导出(&E)...",IDC_EXPORT_BUTTON,7,151,50,14 - PUSHBUTTON "清空",IDC_CLEAR_BUTTON,64,151,50,14 + LTEXT "Encoding quality:",IDC_TXT_ENCODE_OPT_OGG_ENCODE_QUALITY_SEL_STATIC,7,7,157,8 + CONTROL "",IDC_QUALITY_SLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,7,19,103,10 + LTEXT "10 (500 kbps)",IDC_INFO_STATIC,113,20,51,8 + LTEXT "Low",IDC_TXT_ENCODE_OPT_OGG_ENCODE_QUALITY_LOW_STATIC,7,31,50,8 + RTEXT "High",IDC_TXT_ENCODE_OPT_OGG_ENCODE_QUALITY_HIGH_STATIC,60,31,50,8 + DEFPUSHBUTTON "OK",IDOK,57,44,50,14 + PUSHBUTTON "Cancel",IDCANCEL,114,44,50,14 END -IDD_DONATE_DIALOG DIALOGEX 0, 0, 229, 130 -STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "捐助" -FONT 9, "微软雅黑", 400, 0, 0x86 +IDD_PLAY_SETTING_DIALOG DIALOGEX 0, 0, 344, 298 +STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - PUSHBUTTON "关闭",IDCANCEL,172,109,50,14 - LTEXT "如果你觉得这个软件对你有帮助,你可以扫描右边的二维码通过支付宝或微信捐助作者,以帮助作者把这个软件做得更好。金额请随意。",IDC_DONATE_STATIC,7,7,215,25 + GROUPBOX "Play Options",IDC_TXT_OPT_PLAY_PLAY_OPT_STATIC,7,4,330,61 + CONTROL "Stop playing when an error occurs",IDC_STOP_WHEN_ERROR, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,16,146,8 + CONTROL "Auto play when the program starts",IDC_AUTO_PLAY_WHEN_START_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,170,16,160,8 + CONTROL "Show playing progress in the taskbar",IDC_SHOW_TASKBAR_PROGRESS, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,28,146,8 + CONTROL "Show playing status icon in the taskbar",IDC_SHOW_PLAY_STATE_ICON_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,170,28,160,8 + CONTROL "Sound fade in and out effect",IDC_SOUND_FADE_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,40,146,8 + CONTROL "Continue playing when switch playlist",IDC_CONTINUE_WHEN_SWITCH_PLAYLIST_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,170,40,160,8 + CONTROL "Use system media transport controls",IDC_USE_MEDIA_TRANS_CONTORL_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,52,316,8 + GROUPBOX "Player Kernal",IDC_TXT_OPT_PLAY_CORE_STATIC,7,71,330,40 + CONTROL "BASS",IDC_BASS_RADIO,"Button",BS_AUTORADIOBUTTON,14,84,146,8 + CONTROL "MCI (Media Control Interface)",IDC_MCI_RADIO,"Button",BS_AUTORADIOBUTTON,170,84,160,8 + CONTROL "FFMPEG",IDC_FFMPEG_RADIO,"Button",BS_AUTORADIOBUTTON,14,96,39,8 + CONTROL "Click here to download",IDC_FFMPEG_DOWN_SYSLINK, + "SysLink",WS_TABSTOP,60,96,270,8 + GROUPBOX "Play Device",IDC_TXT_OPT_PLAY_DEVICE_STATIC,7,118,330,87 + LTEXT "Select play device:",IDC_TXT_OPT_PLAY_DEVICE_SEL_STATIC,14,131,30,8,SS_ENDELLIPSIS + COMBOBOX IDC_OUTPUT_DEVICE_COMBO,50,129,280,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "",IDC_OUTPUT_DEVICE_INFO_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,14,146,316,52 + GROUPBOX "FFMPEG Core Settings",IDC_TXT_OPT_PLAY_FFMPEG_CORE_SETTING_STATIC,7,210,330,81 + RTEXT "Cache duration (sec):",IDC_TXT_OPT_PLAY_FFMPEG_CORE_CACHE_LENGTH_STATIC,14,222,146,8,SS_ENDELLIPSIS + EDITTEXT IDC_FFMPEG_CACHE_LENGTH,170,220,50,12,ES_AUTOHSCROLL + RTEXT "Max retry attempts (-1 for unlimited):",IDC_TXT_OPT_PLAY_FFMPEG_CORE_MAX_RETRY_COUNT_STATIC,14,236,146,8,SS_ENDELLIPSIS + EDITTEXT IDC_FFMPEG_MAX_RETRY_COUNT,170,234,50,12,ES_AUTOHSCROLL + RTEXT "Non-local file retry interval (sec):",IDC_TXT_OPT_PLAY_FFMPEG_CORE_URL_RETRY_INTERVAL_STATIC,14,250,146,8,SS_ENDELLIPSIS + EDITTEXT IDC_FFMPEG_URL_RETRY_INTERVAL,170,248,50,12,ES_AUTOHSCROLL + RTEXT "Max wait time for seeking (ms):",IDC_TXT_OPT_PLAY_FFMPEG_CORE_MAX_WAIT_TIME_STATIC,14,264,146,8,SS_ENDELLIPSIS + EDITTEXT IDC_FFMPEG_MAX_WAIT_TIME,170,262,50,12,ES_AUTOHSCROLL + CONTROL "Enable WASAPI",IDC_FFMPEG_ENABLE_WASAPI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,277,146,8 + CONTROL "Enable exclusive mode",IDC_FFMPEG_ENABLE_WASAPI_EXCLUSIVE, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,170,277,160,8 END -IDD_MEDIA_LIB_DIALOG DIALOGEX 0, 0, 343, 218 -STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -EXSTYLE WS_EX_APPWINDOW -CAPTION "媒体库" -FONT 9, "微软雅黑", 400, 0, 0x0 +IDD_PROPERTY_DIALOG DIALOGEX 0, 0, 344, 148 +STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - PUSHBUTTON "关闭",IDCANCEL,288,199,50,14 - CONTROL "",IDC_TAB1,"SysTabControl32",0x0,5,4,333,191 - PUSHBUTTON "播放选中",IDC_PLAY_SELECTED,232,199,50,14 - PUSHBUTTON "媒体库设置(&S)...",IDC_MEDIA_LIB_SETTINGS_BTN,5,199,64,14 - PUSHBUTTON "统计信息(&I)",IDC_STATISTICS_INFO_BUTTON,74,199,53,14 + GROUPBOX "File information",IDC_TXT_PROPERTY_DLG_FILE_INFO_STATIC,5,2,185,125 + RTEXT "File name:",IDC_TXT_PROPERTY_DLG_FILE_NAME_STATIC,10,14,20,8,SS_ENDELLIPSIS + EDITTEXT IDC_FILE_NAME_EDIT,33,13,152,12,ES_AUTOHSCROLL | ES_READONLY + RTEXT "File path:",IDC_TXT_PROPERTY_DLG_FILE_PATH_STATIC,10,30,20,8,SS_ENDELLIPSIS + EDITTEXT IDC_FILE_PATH_EDIT,33,29,152,12,ES_AUTOHSCROLL | ES_READONLY + RTEXT "File type:",IDC_TXT_PROPERTY_DLG_FILE_TYPE_STATIC,10,46,20,8,SS_ENDELLIPSIS + EDITTEXT IDC_FILE_TYPE_EDIT,33,45,152,12,ES_AUTOHSCROLL | ES_READONLY + RTEXT "Duration:",IDC_TXT_PROPERTY_DLG_FILE_DURATION_STATIC,10,62,20,8,SS_ENDELLIPSIS + EDITTEXT IDC_SONG_LENGTH_EDIT,33,61,72,12,ES_AUTOHSCROLL | ES_READONLY + RTEXT "File size:",IDC_TXT_PROPERTY_DLG_FILE_SIZE_STATIC,108,62,20,8,SS_ENDELLIPSIS + EDITTEXT IDC_FILE_SIZE_EDIT,131,61,54,12,ES_AUTOHSCROLL | ES_READONLY + RTEXT "Bit rate:",IDC_TXT_PROPERTY_DLG_FILE_BIT_RATE_STATIC,10,78,20,8,SS_ENDELLIPSIS + EDITTEXT IDC_BIT_RATE_EDIT,33,77,72,12,ES_AUTOHSCROLL | ES_READONLY + RTEXT "Channels:",IDC_TXT_PROPERTY_DLG_FILE_CHANNELS_STATIC,108,78,20,8,SS_ENDELLIPSIS + EDITTEXT IDC_CHANNELS,131,77,54,12,ES_AUTOHSCROLL | ES_READONLY + RTEXT "Frequency:",IDC_TXT_PROPERTY_DLG_FILE_FREQ_STATIC,10,94,20,8,SS_ENDELLIPSIS + EDITTEXT IDC_SAMPLE_FREQ,33,93,72,12,ES_AUTOHSCROLL | ES_READONLY + RTEXT "Bit depth:",IDC_TXT_PROPERTY_DLG_FILE_BIT_DEPTH_STATIC,108,94,20,8,SS_ENDELLIPSIS + EDITTEXT IDC_BITS_DIPTH,131,93,54,12,ES_AUTOHSCROLL | ES_READONLY + RTEXT "Lyric file:",IDC_LYRIC_FILE_STATIC,10,110,20,8,SS_ENDELLIPSIS + EDITTEXT IDC_LYRIC_FILE_EDIT,33,109,152,12,ES_AUTOHSCROLL | ES_READONLY + GROUPBOX "Tag information",IDC_TXT_PROPERTY_DLG_TAG_INFO_STATIC,195,2,144,125 + RTEXT "Title:",IDC_TXT_PROPERTY_DLG_TAG_TITLE_STATIC,200,14,20,8,SS_ENDELLIPSIS + EDITTEXT IDC_TITEL_EDIT,223,13,111,12,ES_AUTOHSCROLL | ES_READONLY + RTEXT "Artist:",IDC_TXT_PROPERTY_DLG_TAG_ARTIST_STATIC,200,30,20,8,SS_ENDELLIPSIS + EDITTEXT IDC_ARTIST_EDIT,223,29,111,12,ES_AUTOHSCROLL | ES_READONLY + RTEXT "Album:",IDC_TXT_PROPERTY_DLG_TAG_ALBUM_STATIC,200,46,20,8,SS_ENDELLIPSIS + EDITTEXT IDC_ALBUM_EDIT,223,45,111,12,ES_AUTOHSCROLL | ES_READONLY + RTEXT "Track:",IDC_TXT_PROPERTY_DLG_TAG_TRACK_STATIC,200,62,20,8,SS_ENDELLIPSIS + EDITTEXT IDC_TRACK_EDIT,223,61,47,12,ES_AUTOHSCROLL | ES_READONLY + RTEXT "Year:",IDC_TXT_PROPERTY_DLG_TAG_YEAR_STATIC,273,62,20,8,SS_ENDELLIPSIS + EDITTEXT IDC_YEAR_EDIT,296,61,38,12,ES_AUTOHSCROLL | ES_READONLY + RTEXT "Genre:",IDC_TXT_PROPERTY_DLG_TAG_GENRE_STATIC,200,78,20,8,SS_ENDELLIPSIS + COMBOBOX IDC_GENRE_COMBO,223,77,111,38,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + RTEXT "Comment:",IDC_TXT_PROPERTY_DLG_TAG_COMMENT_STATIC,200,94,20,8,SS_ENDELLIPSIS + EDITTEXT IDC_COMMENT_EDIT,223,92,111,18,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | ES_WANTRETURN | WS_VSCROLL + LTEXT "Tag type: <%1%>",IDC_TAG_TYPE_STATIC,200,113,134,8 + PUSHBUTTON "Get tag from file name...",IDC_GET_TAG_FROM_FILE_NAME_BUTTON,5,131,50,14 + PUSHBUTTON "Get tag from lyrics",IDC_GET_TAG_FROM_LYRIC_BUTTON,59,131,50,14 + PUSHBUTTON "Get tag online...",IDC_GET_TAG_ONLINE_BUTTON,113,131,50,14 +END + +IDD_REVERB_DIALOG DIALOGEX 0, 0, 299, 107 +STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU +FONT 9, "Segoe UI", 400, 0, 0x0 +BEGIN + CONTROL "Enable reverb",IDC_ENABLE_REVERB_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,7,285,8 + CONTROL "",IDC_REVERB_MIX_SLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,72,25,100,13 + CONTROL "",IDC_REVERB_TIME_SLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,72,44,100,13 + RTEXT "Reverb strength:",IDC_TXT_REVERB_STRENGTH_STATIC,14,27,50,8,SS_ENDELLIPSIS + RTEXT "Reverb time:",IDC_TXT_REVERB_TIME_STATIC,14,46,50,8,SS_ENDELLIPSIS + LTEXT "x%",IDC_REVERB_MIX_STATIC,178,27,30,8 + LTEXT "0.00s",IDC_REVERB_TIME_STATIC,178,46,30,8 END -IDD_SELECT_PLAYLIST_DIALOG DIALOGEX 0, 0, 327, 178 +IDD_SET_PATH_DIALOG DIALOGEX 0, 0, 330, 170 STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU -FONT 9, "微软雅黑", 400, 0, 0x0 +EXSTYLE WS_EX_APPWINDOW +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,4,21,155,153 - PUSHBUTTON "新建播放列表(&N)...",IDC_NEW_PLAYLIST,4,4,69,14 - CONTROL "",IDC_SEARCH_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x80,184,5,138,12 - CONTROL "",IDC_SONG_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | LVS_OWNERDATA | WS_BORDER | WS_TABSTOP,162,21,160,153 - CONTROL "",IDC_HSPLITER_STATIC,"Static",SS_BLACKFRAME,159,21,3,153 + LTEXT "Current folder:",IDC_TXT_LIB_PATH_CURRENT_FOLDER_STATIC,4,7,30,8,SS_ENDELLIPSIS + PUSHBUTTON "Open New Folder...",IDC_OPEN_FOLDER,276,4,50,14 + EDITTEXT IDC_PATH_EDIT,39,5,233,12,ES_AUTOHSCROLL | ES_READONLY + CONTROL "",IDC_PATH_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,4,38,322,128 + CONTROL "",IDC_SEARCH_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x80,4,22,322,12 END -IDD_INPUT_DLG DIALOGEX 0, 0, 183, 67 +IDD_SOUND_EFFECT_DIALOG DIALOGEX 0, 0, 316, 153 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Dialog" -FONT 9, "微软雅黑", 400, 0, 0x0 +CAPTION "Sound Effect Settings" +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - DEFPUSHBUTTON "确定",IDOK,70,46,50,14 - PUSHBUTTON "取消",IDCANCEL,126,46,50,14 - EDITTEXT IDC_INPUT_EDIT,7,25,169,12,ES_AUTOHSCROLL - LTEXT "Static",IDC_INFO_STATIC,7,7,169,13 + PUSHBUTTON "Close",IDCANCEL,259,132,50,14 + CONTROL "",IDC_TAB1,"SysTabControl32",0x0,7,7,302,119 END -IDD_FILE_RELATE_DIALOG DIALOGEX 0, 0, 271, 182 +IDD_SUPPORT_FORMAT_DIALOG DIALOGEX 0, 0, 275, 181 STYLE DS_SETFONT | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -CAPTION "文件关联" -FONT 9, "微软雅黑", 400, 0, 0x0 +CAPTION "Supported Formats" +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - DEFPUSHBUTTON "确定",IDOK,158,161,50,14 - PUSHBUTTON "取消",IDCANCEL,214,161,50,14 - CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,7,257,150 - CONTROL "全选(&A)",IDC_SELECT_ALL_CHECK,"Button",BS_AUTO3STATE | WS_TABSTOP,7,163,36,10 - PUSHBUTTON "默认(&D)",IDC_DEFAULT_BUTTON,44,161,50,14 + DEFPUSHBUTTON "OK",IDOK,218,160,50,14 + LTEXT "",IDC_INFO_STATIC,7,7,261,32 + CONTROL "",IDC_FORMAT_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,41,261,114 END -IDD_TEST_DIALOG DIALOGEX 0, 0, 309, 176 +IDD_TAG_EDIT_DIALOG DIALOGEX 0, 0, 300, 164 STYLE DS_SETFONT | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -CAPTION "测试" -FONT 9, "微软雅黑", 400, 0, 0x0 +CAPTION "Edit Audio Tags" +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - DEFPUSHBUTTON "确定",IDOK,198,155,50,14 - PUSHBUTTON "取消",IDCANCEL,252,155,50,14 - LTEXT "这是工具栏",IDC_TEST_TOOLBAR,7,7,295,12 - LTEXT "一个进度条",IDC_TEST_PROGRESS_BAR,7,23,44,8 - CONTROL "",IDC_MFCEDITBROWSE1,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x80,7,42,123,12 + RTEXT "Path:",IDC_TXT_TAG_EDIT_PATH_STATIC,7,8,20,8,SS_ENDELLIPSIS + EDITTEXT IDC_PATH_EDIT,32,7,261,12,ES_AUTOHSCROLL | ES_READONLY + RTEXT "Title:",IDC_TXT_PROPERTY_DLG_TAG_TITLE_STATIC,7,23,20,8,SS_ENDELLIPSIS + EDITTEXT IDC_TITEL_EDIT,32,22,261,12,ES_AUTOHSCROLL + RTEXT "Artist:",IDC_TXT_PROPERTY_DLG_TAG_ARTIST_STATIC,7,38,20,8,SS_ENDELLIPSIS + EDITTEXT IDC_ARTIST_EDIT,32,37,261,12,ES_AUTOHSCROLL + RTEXT "Album:",IDC_TXT_PROPERTY_DLG_TAG_ALBUM_STATIC,7,53,20,8,SS_ENDELLIPSIS + EDITTEXT IDC_ALBUM_EDIT,32,52,261,12,ES_AUTOHSCROLL + RTEXT "Track:",IDC_TXT_PROPERTY_DLG_TAG_TRACK_STATIC,7,68,20,8,SS_ENDELLIPSIS + EDITTEXT IDC_TRACK_EDIT,32,67,118,12,ES_AUTOHSCROLL | ES_NUMBER + RTEXT "Year:",IDC_TXT_PROPERTY_DLG_TAG_YEAR_STATIC,156,68,20,8,SS_ENDELLIPSIS + EDITTEXT IDC_YEAR_EDIT,180,67,113,12,ES_AUTOHSCROLL | ES_NUMBER + RTEXT "Genre:",IDC_TXT_PROPERTY_DLG_TAG_GENRE_STATIC,7,83,20,8,SS_ENDELLIPSIS + COMBOBOX IDC_GENRE_COMBO,32,82,261,38,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + RTEXT "Comment:",IDC_TXT_PROPERTY_DLG_TAG_COMMENT_STATIC,7,98,20,8,SS_ENDELLIPSIS + EDITTEXT IDC_COMMENT_EDIT,32,96,261,42,ES_MULTILINE | WS_VSCROLL + PUSHBUTTON "Previous",IDC_PREVIOUS_BUTTON,7,143,50,14 + PUSHBUTTON "Next",IDC_NEXT_BUTTON,60,143,50,14 + LTEXT "xxxx/xxxx",IDC_ITEM_STATIC,114,146,72,8 + PUSHBUTTON "Save",IDC_SAVE_BUTTON,190,143,50,14 + PUSHBUTTON "Close",IDCANCEL,243,143,50,14 END -IDD_MEDIA_CLASSIFY_DIALOG DIALOGEX 0, 0, 292, 155 -STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU -FONT 9, "微软雅黑", 400, 0, 0x0 +IDD_WMA_ENCODE_CFG_DIALOG DIALOGEX 0, 0, 190, 65 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "WMA Encode Options" +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - CONTROL "",IDC_CLASSIFY_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | LVS_OWNERDATA | WS_BORDER | WS_TABSTOP,4,19,107,132 - CONTROL "",IDC_SONG_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | LVS_OWNERDATA | WS_BORDER | WS_TABSTOP,114,19,173,132 - CONTROL "",IDC_MFCEDITBROWSE1,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x80,4,4,283,12 - CONTROL "",IDC_HSPLITER_STATIC,"Static",SS_BLACKFRAME,111,19,3,132 + CONTROL "Constant bit rate (CBR):",IDC_CBR_RADIO,"Button",BS_AUTORADIOBUTTON,7,8,118,8 + COMBOBOX IDC_BITRATE_COMBO,129,7,54,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "Quality-based VBR:",IDC_CBR_RADIO2,"Button",BS_AUTORADIOBUTTON,7,25,118,8 + COMBOBOX IDC_VBR_QUALITY_COMBO,129,24,54,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "OK",IDOK,78,44,50,14 + PUSHBUTTON "Cancel",IDCANCEL,133,44,50,14 END -IDD_FOLDER_EXPLORE_DIALOG DIALOGEX 0, 0, 293, 160 -STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU -FONT 9, "微软雅黑", 400, 0, 0x0 +IDD_LISTEN_TIME_STATISTICS_DLG DIALOGEX 0, 0, 340, 172 +STYLE DS_SETFONT | DS_MODALFRAME | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Total Play Time Statistics" +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - CONTROL "",IDC_MFCEDITBROWSE1,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x80,4,4,284,12 - CONTROL "",IDC_FOLDER_EXPLORE_TREE,"SysTreeView32",TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | WS_BORDER | WS_HSCROLL | WS_TABSTOP,4,19,107,136 - CONTROL "",IDC_SONG_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | LVS_OWNERDATA | WS_BORDER | WS_TABSTOP,114,27,174,128 - LTEXT "",IDC_PATH_STATIC,115,18,172,8 - CONTROL "",IDC_HSPLITER_STATIC,"Static",SS_BLACKFRAME,111,19,3,136 + CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,7,326,140 + PUSHBUTTON "Export...",IDC_EXPORT_BUTTON,7,151,50,14 + PUSHBUTTON "Clear",IDC_CLEAR_BUTTON,65,151,50,14 + DEFPUSHBUTTON "Close",IDCANCEL,283,151,50,14 END -IDD_MEDIA_LIB_SETTING_DIALOG DIALOGEX 0, 0, 243, 567 -STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU -FONT 9, "微软雅黑", 400, 0, 0x0 +IDD_DONATE_DIALOG DIALOGEX 0, 0, 256, 139 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Donate" +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - GROUPBOX "媒体库目录",IDC_STATIC,6,103,230,66 - CONTROL "",IDC_DIR_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,14,115,156,47 - PUSHBUTTON "添加(&A)...",IDC_ADD_BUTTON,176,119,50,14 - PUSHBUTTON "删除(&D)",IDC_DELETE_BUTTON,176,137,50,14 - GROUPBOX "媒体库选项",IDC_STATIC,6,5,230,92 - CONTROL "将只有一项的分类归到其他类中",IDC_CLASSIFY_OTHER_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,18,133,10 - CONTROL "启动时自动更新媒体库",IDC_UPDATE_MEDIA_LIB_CHK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,29,95,10 - LTEXT "当前数据文件大小:",IDC_SIZE_STATIC,14,365,178,8 - PUSHBUTTON "清理(&C)...",IDC_CLEAN_DATA_FILE_BUTTON,14,377,53,14 - GROUPBOX "清理媒体库",IDC_STATIC,6,353,230,43 - PUSHBUTTON "清空最近播放曲目列表(&R)...",IDC_CLEAR_RECENT_PLAYED_LIST_BTN,13,328,95,14 - GROUPBOX "最近播放",IDC_STATIC,6,302,230,45 - GROUPBOX "播放列表",IDC_STATIC,6,219,230,76 - CONTROL "禁用播放列表拖放排序",IDC_DISABLE_DRAGE_SORT_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,230,89,10 - LTEXT "播放列表显示方式:",IDC_STATIC,107,231,64,8 - COMBOBOX IDC_PLAYLIST_DISPLAY_MODE_OMBO,173,229,59,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "最近播放显示范围:",IDC_STATIC,14,314,66,8 - COMBOBOX IDC_RECENT_PLAYED_RANGE_OMBO,85,312,111,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "向播放列表添加曲目时插入列表开头而不是追加到末尾",IDC_INSERT_BEGIN_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,243,182,10 - GROUPBOX "在媒体库中显示的项目",IDC_STATIC,6,175,230,39 - CONTROL "艺术家",IDC_ARTIST_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,187,36,10 - CONTROL "唱片集",IDC_ALBUM_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,55,186,36,10 - CONTROL "流派",IDC_GENRE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,99,186,29,10 - CONTROL "年份",IDC_YEAR_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,143,186,29,10 - CONTROL "文件类型",IDC_FILE_TYPE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,187,186,43,10 - CONTROL "比特率",IDC_BITRATE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,200,36,10 - CONTROL "所有曲目",IDC_ALL_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,99,199,43,10 - CONTROL "最近播放",IDC_RECENT_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,143,199,43,10 - CONTROL "文件夹浏览",IDC_FOLDER_EXPLORE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,187,199,49,10 - CONTROL "分级",IDC_RATING_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,55,199,29,10 - GROUPBOX "标签读写",IDC_STATIC,6,403,230,32 - LTEXT "ID3v2写入类型:",IDC_STATIC,14,417,61,8 - COMBOBOX IDC_ID3V2_TYPE_COMBO,74,416,48,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "刷新媒体库(&R)",IDC_REFRESH_MEDIA_LIB_BUTTON,153,20,59,14 - CONTROL "禁用从磁盘删除",IDC_DISABLE_DELETE_FROM_DISK_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,63,73,10 - CONTROL "显示播放列表鼠标提示",IDC_SHOW_PLAYLIST_TOOLTIP_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,255,87,10 - CONTROL "浮动播放列表跟随主窗口",IDC_FLOAT_PLAYLIST_FOLLOW_MAIN_WND_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,267,159,10 - LTEXT "播放列表项目高度:",IDC_STATIC,14,281,66,8 - EDITTEXT IDC_PLAYLIST_ITEM_HEIGHT_EDIT,81,279,34,12,ES_AUTOHSCROLL - LTEXT "像素",IDC_STATIC,117,281,26,8 - GROUPBOX "Last.fm",IDC_STATIC,6,442,230,118 - CONTROL "启用 last.fm 相关功能",IDC_ENABLE_LASTFM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,453,80,10 - LTEXT "当前状态:",IDC_STATIC,14,466,34,8 - LTEXT "状态",IDC_LASTFM_STATUS,46,466,124,8 - PUSHBUTTON "登录",IDC_LASTFM_LOGIN,177,462,50,14,WS_DISABLED - LTEXT "当播放进度满足以下所有条件时将记录计入缓存:",IDC_STATIC,14,479,207,8 - LTEXT "至少播放歌曲的",IDC_STATIC,14,491,52,8 - EDITTEXT IDC_LASTFM_LEAST_PERDUR,66,490,29,12,ES_AUTOHSCROLL - LTEXT "% 并至少播放",IDC_STATIC,98,491,46,8 - EDITTEXT IDC_LASTFM_LEAST_DUR,144,490,29,12,ES_AUTOHSCROLL - LTEXT "秒。",IDC_STATIC,175,492,18,8 - CONTROL "当缓存中的记录数超过",IDC_LASTFM_AUTO_SCROBBLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,506,80,10 - EDITTEXT IDC_LASTFM_AUTO_SCROBBLE_MIN,94,505,29,12,ES_AUTOHSCROLL - LTEXT "条时,自动上传缓存。",IDC_STATIC,126,507,97,8 - LTEXT "缓存状态:",IDC_STATIC,14,520,34,8 - LTEXT "X条记录",IDC_LASTFM_CACHE_STATUS,46,520,123,8 - PUSHBUTTON "上传缓存",IDC_LASTFM_UPLOAD_CACHE,177,519,50,14,WS_DISABLED - CONTROL "使用 HTTPS 与 last.fm 服务器通信",IDC_LASTFM_ENABLE_HTTPS, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,532,116,10 - CONTROL "上传当前播放歌曲",IDC_LASTFM_ENABLE_NOWPLAYING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,545,67,10 - CONTROL "更新媒体库时移除不存在的音频文件",IDC_REMOVE_FILE_NOT_EXIST_WHEN_UPDATE_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,51,147,10 - CONTROL "",IDC_ARTIST_SPLIT_EXT_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x80,69,78,157,11 - LTEXT "艺术家识别例外:",IDC_STATIC,14,79,54,8 - CONTROL "更新媒体库时忽略时长低于阈值的文件",IDC_IGNORE_TOO_SHORT_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,40,132,10 - LTEXT "音频文件低时长阈值:",IDC_STATIC,122,64,73,8 - LTEXT "秒",IDC_STATIC,217,64,8,8 - EDITTEXT IDC_FILE_TOO_SHORT_SEC_EDIT,187,62,27,12,ES_AUTOHSCROLL + LTEXT "If you think this software is helpful to you, you can scan the following QR code through Alipay or WeChart Pay to donate the author to help the author to make this software better. Please feel free for the amount.",IDC_DONATE_STATIC,7,7,242,40 + DEFPUSHBUTTON "Close",IDCANCEL,199,118,50,14 END -IDD_ADD_TO_PLAYLIST_DIALOG DIALOGEX 0, 0, 186, 152 -STYLE DS_SETFONT | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -CAPTION "选择播放列表" -FONT 9, "微软雅黑", 400, 0, 0x0 +IDD_MEDIA_LIB_DIALOG DIALOGEX 0, 0, 345, 212 +STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +EXSTYLE WS_EX_APPWINDOW +CAPTION "Media Library" +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - DEFPUSHBUTTON "确定",IDOK,74,131,50,14 - PUSHBUTTON "取消",IDCANCEL,129,131,50,14 - CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,22,172,104 - CONTROL "",IDC_SEARCH_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x80,7,7,172,12 + CONTROL "",IDC_TAB1,"SysTabControl32",0x0,5,4,335,185 + PUSHBUTTON "Media Library Settings...",IDC_MEDIA_LIB_SETTINGS_BTN,5,193,50,14 + PUSHBUTTON "Statistics",IDC_STATISTICS_INFO_BUTTON,61,193,50,14 + DEFPUSHBUTTON "Play Selected",IDC_PLAY_SELECTED,234,193,50,14 + PUSHBUTTON "Close",IDCANCEL,290,193,50,14 END -IDD_ALL_MEDIA_DIALOG DIALOGEX 0, 0, 291, 156 -STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU -FONT 9, "微软雅黑", 400, 0, 0x0 +IDD_INPUT_DLG DIALOGEX 0, 0, 200, 65 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Dialog" +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - CONTROL "",IDC_SONG_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | LVS_OWNERDATA | WS_BORDER | WS_TABSTOP,4,19,282,132 - CONTROL "",IDC_SEARCH_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x80,4,4,282,12 + DEFPUSHBUTTON "OK",IDOK,86,44,50,14 + PUSHBUTTON "Cancel",IDCANCEL,143,44,50,14 + EDITTEXT IDC_INPUT_EDIT,7,26,186,12,ES_AUTOHSCROLL + LTEXT "Static",IDC_INFO_STATIC,7,7,186,16 END -IDD_LYRIC_RELATE_DIALOG DIALOGEX 0, 0, 311, 178 -STYLE DS_SETFONT | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -CAPTION "关联本地歌词" -FONT 9, "微软雅黑", 400, 0, 0x0 +IDD_SELECT_PLAYLIST_DIALOG DIALOGEX 0, 0, 330, 170 +STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - DEFPUSHBUTTON "关联选中歌词",IDOK,193,157,56,14 - PUSHBUTTON "取消",IDCANCEL,254,157,50,14 - PUSHBUTTON "不关联歌词",IDC_DONOT_RELATE_BUTTON,7,157,50,14 - LTEXT "歌词标题:",IDC_STATIC,7,8,37,8 - EDITTEXT IDC_LYRIC_NAME_EDIT,46,7,142,12,ES_AUTOHSCROLL - CONTROL "部分匹配",IDC_FUZZY_MATCH_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,195,8,43,10 - PUSHBUTTON "本地搜索(&S)",IDC_LOCAL_SEARCH_BUTTON,253,7,51,14 - CONTROL "",IDC_SEARCH_RESULT_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,32,240,119 - LTEXT "搜索结果:",IDC_STATIC,7,22,144,8 - PUSHBUTTON "浏览(&B)...",IDC_BROWSE_BUTTON1,253,32,51,14 - PUSHBUTTON "删除文件(&D)",IDC_DELETE_FILE_BUTTON,253,54,51,14 + PUSHBUTTON "New Playlist...",IDC_NEW_PLAYLIST,4,4,50,14 + CONTROL "",IDC_SEARCH_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x80,146,5,180,12 + CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,4,22,160,144 + CONTROL "",IDC_SONG_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | LVS_OWNERDATA | WS_BORDER | WS_TABSTOP,167,22,159,144 + CONTROL "",IDC_HSPLITER_STATIC,"Static",SS_BLACKFRAME,164,22,3,144 END -IDD_CLEAN_UP_RANGE_DIALOG DIALOGEX 0, 0, 130, 114 -STYLE DS_SETFONT | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -CAPTION "清理媒体库" -FONT 9, "微软雅黑", 400, 0, 0x0 +IDD_FILE_RELATE_DIALOG DIALOGEX 0, 0, 305, 182 +STYLE DS_SETFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +CAPTION "File Relate" +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - DEFPUSHBUTTON "确定",IDOK,18,93,50,14 - PUSHBUTTON "取消",IDCANCEL,73,93,50,14 - LTEXT "请选择要清理的范围:",IDC_STATIC,7,7,116,8 - CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,18,116,70 + CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,7,291,150 + PUSHBUTTON "Default",IDC_DEFAULT_BUTTON,7,161,50,14 + CONTROL "Select All",IDC_SELECT_ALL_CHECK,"Button",BS_AUTO3STATE | WS_TABSTOP,65,164,45,8 + DEFPUSHBUTTON "OK",IDOK,190,161,50,14 + PUSHBUTTON "Cancel",IDCANCEL,248,161,50,14 END -IDD_PROPERTY_PARENT_DIALOG DIALOGEX 0, 0, 318, 181 +IDD_ADD_TO_PLAYLIST_DIALOG DIALOGEX 0, 0, 210, 153 STYLE DS_SETFONT | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -CAPTION "属性" -FONT 9, "微软雅黑", 400, 0, 0x0 +CAPTION "Select Playlist" +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - PUSHBUTTON "关闭",IDCANCEL,264,163,50,14 - PUSHBUTTON "上一页",IDC_PREVIOUS_BUTTON,4,163,38,14 - PUSHBUTTON "下一页",IDC_NEXT_BUTTON,45,163,38,14 - LTEXT "Static",IDC_ITEM_STATIC,86,165,45,8 - PUSHBUTTON "保存到文件",IDC_SAVE_TO_FILE_BUTTON,207,163,53,14 - CONTROL "",IDC_TAB1,"SysTabControl32",0x0,4,4,310,156 + CONTROL "",IDC_SEARCH_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x80,7,7,196,12 + CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,22,196,103 + DEFPUSHBUTTON "OK",IDOK,96,132,50,14 + PUSHBUTTON "Cancel",IDCANCEL,153,132,50,14 END -IDD_PROPERTY_ALBUM_COVER_DIALOG DIALOGEX 0, 0, 304, 128 +IDD_MEDIA_LIB_SETTING_DIALOG DIALOGEX 0, 0, 344, 600 STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU -FONT 9, "微软雅黑", 400, 0, 0x0 +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,159,4,138,91 - PUSHBUTTON "浏览(&B)...",IDC_BROWSE_BUTTON,159,98,50,14 - PUSHBUTTON "删除(&D)",IDC_DELETE_BUTTON,212,98,50,14 - CONTROL "将外部专辑封面嵌入到音频文件(&E)",IDC_SAVE_ALBUM_COVER_BUTTON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,160,114,127,10 - CONTROL "显示外部专辑封面(&O)",IDC_SHOW_OUT_ALBUM_COVER_CHK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,114,127,10 + GROUPBOX "Media Library Options",IDC_TXT_OPT_MEDIA_LIB_MEDIA_LIB_OPT_STATIC,7,4,330,55 + CONTROL "Disable delete from disk",IDC_DISABLE_DELETE_FROM_DISK_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,15,126,8 + CONTROL "Classify only-one items into others",IDC_CLASSIFY_OTHER_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,15,180,8 + RTEXT "Low duration threshold (sec):",IDC_TXT_OPT_MEDIA_LIB_TOO_SHORT_SEC_STATIC,14,28,126,8,SS_ENDELLIPSIS + EDITTEXT IDC_FILE_TOO_SHORT_SEC_EDIT,150,27,50,12,ES_AUTOHSCROLL + RTEXT "Artist recognition exception:",IDC_TXT_OPT_MEDIA_LIB_ARTIST_SPLIT_EXT_SEL_STATIC,14,42,126,8,SS_ENDELLIPSIS + CONTROL "",IDC_ARTIST_SPLIT_EXT_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x80,150,42,180,12 + GROUPBOX "Media Library Update Options",IDC_TXT_OPT_MEDIA_LIB_MEDIA_LIB_UPDATE_OPT_STATIC,7,64,330,45 + CONTROL "Remove non-existing files",IDC_REMOVE_FILE_NOT_EXIST_WHEN_UPDATE_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,76,126,8 + CONTROL "Ignore files with durations below the threshold",IDC_IGNORE_TOO_SHORT_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,76,180,8 + CONTROL "Auto-update media library on startup",IDC_UPDATE_MEDIA_LIB_CHK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,89,256,8 + PUSHBUTTON "Force reload",IDC_REFRESH_MEDIA_LIB_BUTTON,280,89,50,14 + GROUPBOX "Media Library Directory",IDC_TXT_OPT_MEDIA_LIB_MEDIA_LIB_DIR_STATIC,7,114,330,66 + CONTROL "",IDC_DIR_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,14,126,256,47 + PUSHBUTTON "Add...",IDC_ADD_BUTTON,280,126,50,14 + PUSHBUTTON "Delete",IDC_DELETE_BUTTON,280,144,50,14 + GROUPBOX "Items Displayed in the Media Library",IDC_TXT_OPT_MEDIA_LIB_MEDIA_LIB_DISP_TAB_STATIC,7,185,330,70 + CONTROL "Artist",IDC_ARTIST_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,197,126,8 + CONTROL "Album",IDC_ALBUM_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,197,180,8 + CONTROL "Genre",IDC_GENRE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,208,126,8 + CONTROL "Year",IDC_YEAR_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,208,180,8 + CONTROL "File type",IDC_FILE_TYPE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,219,126,8 + CONTROL "Bitrate",IDC_BITRATE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,219,180,8 + CONTROL "Rating",IDC_RATING_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,230,126,8 + CONTROL "All tracks",IDC_ALL_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,230,180,8 + CONTROL "Recently played",IDC_RECENT_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,241,126,8 + CONTROL "Folder explore",IDC_FOLDER_EXPLORE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,241,180,8 + GROUPBOX "Playlist Options",IDC_TXT_OPT_MEDIA_LIB_PLAYLIST_OPT_STATIC,7,260,330,88 + CONTROL "Disable drag-and-drop sorting of tracks in the playlist",IDC_DISABLE_DRAGE_SORT_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,271,316,8 + CONTROL "Insert at the start of the playlist when adding songs, not at the end",IDC_INSERT_BEGIN_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,282,316,8 + CONTROL "Use floating playlist by default",IDC_FLOAT_PLAYLIST_BY_DEFAULT_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,293,126,8 + CONTROL "Floating playlist follows main window",IDC_FLOAT_PLAYLIST_FOLLOW_MAIN_WND_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,293,180,8 + CONTROL "Show playlist tool tip",IDC_SHOW_PLAYLIST_TOOLTIP_CHECK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,304,126,8 + RTEXT "Playlist display mode:",IDC_TXT_OPT_MEDIA_LIB_PLAYLIST_DISPLAY_MODE_STATIC,14,317,126,8,SS_ENDELLIPSIS + COMBOBOX IDC_PLAYLIST_DISPLAY_MODE_OMBO,150,317,90,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + RTEXT "Playlist item height (pixel):",IDC_TXT_OPT_MEDIA_LIB_PLAYLIST_ITEM_HEIGHT_STATIC,14,331,126,8,SS_ENDELLIPSIS + EDITTEXT IDC_PLAYLIST_ITEM_HEIGHT_EDIT,150,331,50,12,ES_AUTOHSCROLL + GROUPBOX "Recently played",IDC_TXT_OPT_MEDIA_LIB_RECENT_PLAY_STATIC,7,353,330,46 + RTEXT "Recently played display range:",IDC_TXT_OPT_MEDIA_LIB_RECENT_PLAY_RANGE_SEL_STATIC,14,365,126,8,SS_ENDELLIPSIS + COMBOBOX IDC_RECENT_PLAYED_RANGE_OMBO,150,364,90,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Clear recently played tracks list...",IDC_CLEAR_RECENT_PLAYED_LIST_BTN,280,379,50,14 + GROUPBOX "Clean up the Media library",IDC_TXT_OPT_MEDIA_LIB_CLEAN_MEDIA_LIB_STATIC,7,404,330,29 + LTEXT "Current data file size: <%2%> MB (<%1%> Bytes)",IDC_SIZE_STATIC,14,417,256,8,SS_ENDELLIPSIS + PUSHBUTTON "Clean up...",IDC_CLEAN_DATA_FILE_BUTTON,280,414,50,14 + GROUPBOX "Music tag reading and writing",IDC_TXT_OPT_MEDIA_LIB_TAG_EDIT_STATIC,7,439,330,27 + RTEXT "ID3v2 write type:",IDC_TXT_OPT_MEDIA_LIB_TAG_ID3V2_WRITE_TYPE_STATIC,14,450,126,8,SS_ENDELLIPSIS + COMBOBOX IDC_ID3V2_TYPE_COMBO,150,449,90,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + GROUPBOX "Last.fm",IDC_TXT_OPT_LAST_FM_STATIC,7,471,330,122 + CONTROL "Enable last.fm support",IDC_ENABLE_LASTFM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,484,126,8 + RTEXT "Current status: Already logged in (<%1%>)",IDC_LASTFM_STATUS,150,484,180,8,SS_ENDELLIPSIS + CONTROL "Use HTTPS when communicating with the last.fm server",IDC_LASTFM_ENABLE_HTTPS, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,496,249,8 + PUSHBUTTON "Log in",IDC_LASTFM_LOGIN,280,498,50,14,WS_DISABLED + CONTROL "Upload now playing track",IDC_LASTFM_ENABLE_NOWPLAYING, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,508,249,8 + GROUPBOX "Cache Scrobble Conditions",IDC_TXT_OPT_LAST_FM_CACHE_CONDITION_STATIC,14,519,193,42 + RTEXT "At least played percentage:",IDC_TXT_OPT_LAST_FM_CACHE_CONDITION_PERCENT_STATIC,21,530,119,8,SS_ENDELLIPSIS + EDITTEXT IDC_LASTFM_LEAST_PERDUR,150,528,50,12,ES_AUTOHSCROLL + RTEXT "At least played duration (sec):",IDC_TXT_OPT_LAST_FM_CACHE_CONDITION_DURATION_STATIC,21,544,119,8,SS_ENDELLIPSIS + EDITTEXT IDC_LASTFM_LEAST_DUR,150,543,50,12,ES_AUTOHSCROLL + RTEXT "Cache status: <%1%>scrobbles",IDC_LASTFM_CACHE_STATUS,211,530,119,8,SS_ENDELLIPSIS + PUSHBUTTON "Upload cache",IDC_LASTFM_UPLOAD_CACHE,280,542,50,14 + CONTROL "Upload scrobbles when cached scrobbles reach the threshold",IDC_LASTFM_AUTO_SCROBBLE, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,21,565,309,8 + RTEXT "Auto upload threshold:",IDC_TXT_OPT_LAST_FM_AUTO_UPLOAD_THRESHOLD_STATIC,21,578,119,8,SS_ENDELLIPSIS + EDITTEXT IDC_LASTFM_AUTO_SCROBBLE_MIN,150,577,50,12,ES_AUTOHSCROLL END -IDD_TAG_FROM_FILE_NAME_DIALOG DIALOGEX 0, 0, 191, 134 -STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "从文件名获取标签" -FONT 9, "微软雅黑", 400, 0, 0x0 +IDD_LYRIC_RELATE_DIALOG DIALOGEX 0, 0, 329, 178 +STYLE DS_SETFONT | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +CAPTION "Link local lyrics" +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - DEFPUSHBUTTON "确定",IDOK,78,113,50,14 - PUSHBUTTON "取消",IDCANCEL,134,113,50,14 - COMBOBOX IDC_COMBO1,7,18,177,30,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - LTEXT "请输入歌曲文件名格式:",IDC_STATIC,7,7,168,8 - LTEXT "标题:",IDC_STATIC,7,36,27,8 - PUSHBUTTON "",IDC_TITLE_BUTTON,34,33,50,14 - LTEXT "艺术家:",IDC_STATIC,98,36,29,8 - PUSHBUTTON "",IDC_ARTIST_BUTTON,129,33,50,14 - LTEXT "唱片集:",IDC_STATIC,7,53,27,8 - PUSHBUTTON "",IDC_ALBUM_BUTTON,34,50,50,14 - LTEXT "音轨号:",IDC_STATIC,98,53,29,8 - PUSHBUTTON "",IDC_TRACK_BUTTON,129,50,50,14 - LTEXT "年份:",IDC_STATIC,7,70,27,8 - PUSHBUTTON "",IDC_YEAR_BUTTON,34,67,50,14 - LTEXT "流派:",IDC_STATIC,98,70,29,8 - PUSHBUTTON "",IDC_GENRE_BUTTON,129,67,50,14 - LTEXT "点击按钮时:",IDC_STATIC,7,101,45,8 - CONTROL "插入",IDC_INSERT_RADIO,"Button",BS_AUTORADIOBUTTON,58,101,50,10 - CONTROL "复制到剪贴板",IDC_COPY_RADIO,"Button",BS_AUTORADIOBUTTON,114,101,63,10 - LTEXT "注释:",IDC_STATIC,7,87,27,8 - PUSHBUTTON "",IDC_COMMENT_BUTTON,34,84,50,14 - LTEXT "原文件名:",IDC_ORIGINAL_STATIC,97,87,34,8 - PUSHBUTTON "",IDC_ORIGINAL_BUTTON,129,84,50,14 + LTEXT "Lyrics title:",IDC_TXT_LRC_RELATE_LRC_TITLE_STATIC,7,7,24,12,SS_CENTERIMAGE + EDITTEXT IDC_LYRIC_NAME_EDIT,37,7,198,12,ES_AUTOHSCROLL + CONTROL "Partial match",IDC_FUZZY_MATCH_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,242,8,22,10 + PUSHBUTTON "Local Search",IDC_LOCAL_SEARCH_BUTTON,272,6,50,14 + LTEXT "Search results:",IDC_TXT_LRC_RELATE_SEARCH_RESULT_STATIC,7,23,315,8 + CONTROL "",IDC_SEARCH_RESULT_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,34,256,117 + PUSHBUTTON "Browse...",IDC_BROWSE_BUTTON1,272,34,50,14 + PUSHBUTTON "Delete File",IDC_DELETE_FILE_BUTTON,272,56,50,14 + PUSHBUTTON "Unlink lyrics",IDC_DONOT_RELATE_BUTTON,7,157,50,14 + DEFPUSHBUTTON "Link selected lyrics",IDOK,214,157,50,14 + PUSHBUTTON "Cancel",IDCANCEL,272,157,50,14 END -IDD_PROPERTY_ADVANCED_DIALOG DIALOGEX 0, 0, 192, 116 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU -FONT 8, "MS Shell Dlg", 400, 0, 0x1 +IDD_CLEAN_UP_RANGE_DIALOG DIALOGEX 0, 0, 188, 114 +STYLE DS_SETFONT | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +CAPTION "Clean up the media library" +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,7,178,102 + CONTROL "Please select the range you want to clean:",IDC_TXT_CLEAN_UP_RANGE_SEL_STATIC, + "Static",SS_LEFTNOWORDWRAP | SS_ENDELLIPSIS | WS_GROUP,7,7,174,8 + CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,18,174,70 + DEFPUSHBUTTON "OK",IDOK,70,93,50,14 + PUSHBUTTON "Cancel",IDCANCEL,131,93,50,14 END -IDD_SELECT_ITEM_DIALOG DIALOGEX 0, 0, 135, 87 -STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -CAPTION "Dialog" -FONT 9, "微软雅黑", 400, 0, 0x0 +IDD_PROPERTY_ALBUM_COVER_DIALOG DIALOGEX 0, 0, 344, 148 +STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - DEFPUSHBUTTON "确定",IDOK,24,66,50,14 - PUSHBUTTON "取消",IDCANCEL,78,66,50,14 - CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,7,121,55 + CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,150,7,187,93 + PUSHBUTTON "Browse...",IDC_BROWSE_BUTTON,150,104,50,14 + PUSHBUTTON "Delete",IDC_DELETE_BUTTON,204,104,50,14 + CONTROL "Show external album cover",IDC_SHOW_OUT_ALBUM_COVER_CHK, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,121,187,8 + CONTROL "Embed external album cover into the audio file",IDC_SAVE_ALBUM_COVER_BUTTON, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,150,133,187,8 END -IDD_FLAC_ENCODE_CFG_DIALOG DIALOGEX 0, 0, 176, 96 -STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Flac 编码选项" -FONT 9, "微软雅黑", 400, 0, 0x0 +IDD_PROPERTY_PARENT_DIALOG DIALOGEX 0, 0, 360, 191 +STYLE DS_SETFONT | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +CAPTION "Property" +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - DEFPUSHBUTTON "确定",IDOK,60,75,50,14 - PUSHBUTTON "取消",IDCANCEL,119,75,50,14 - LTEXT "压缩级别:",IDC_STATIC,7,8,38,8 - CONTROL "",IDC_SLIDER1,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,60,7,87,10 - LTEXT "低",IDC_STATIC,47,8,12,8 - LTEXT "高",IDC_STATIC,152,8,12,8 - LTEXT "当前选择:",IDC_STATIC,7,20,36,8 - LTEXT "Static",IDC_COMP_LEVEL_STATIC,47,20,22,8 - CONTROL "自定义 Flac 编码参数",IDC_SPECIFY_PARA_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,34,87,10 - LTEXT "编码器参数:",IDC_STATIC,7,48,51,8 - EDITTEXT IDC_EDIT1,57,46,99,12,ES_AUTOHSCROLL + CONTROL "",IDC_TAB1,"SysTabControl32",0x0,5,5,350,163 + PUSHBUTTON "Previous",IDC_PREVIOUS_BUTTON,5,172,50,14 + PUSHBUTTON "Next",IDC_NEXT_BUTTON,60,172,50,14 + LTEXT "xxxx/xxxx",IDC_ITEM_STATIC,117,174,127,8 + PUSHBUTTON "Save to file",IDC_SAVE_TO_FILE_BUTTON,251,172,50,14 + DEFPUSHBUTTON "Close",IDCANCEL,305,172,50,14 END +IDD_TAG_MODE_SELECT_DIALOG DIALOGEX 0, 0, 245, 144 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "CTagSelBaseDlg" +FONT 9, "Segoe UI", 400, 0, 0x0 +BEGIN + LTEXT "Set text by derived class",IDC_INFO_STATIC,7,7,231,16 + COMBOBOX IDC_COMBO1,7,25,231,30,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + RTEXT "Title:",IDC_TXT_PROPERTY_DLG_TAG_TITLE_STATIC,7,43,20,8,SS_ENDELLIPSIS + PUSHBUTTON "%(Title)",IDC_TITLE_BUTTON,33,40,87,14 + RTEXT "Artist:",IDC_TXT_PROPERTY_DLG_TAG_ARTIST_STATIC,126,43,20,8,SS_ENDELLIPSIS + PUSHBUTTON "%(Artist)",IDC_ARTIST_BUTTON,151,40,87,14 + RTEXT "Album:",IDC_TXT_PROPERTY_DLG_TAG_ALBUM_STATIC,7,60,20,8,SS_ENDELLIPSIS + PUSHBUTTON "%(Album)",IDC_ALBUM_BUTTON,33,57,87,14 + RTEXT "Track:",IDC_TXT_PROPERTY_DLG_TAG_TRACK_STATIC,126,60,20,8,SS_ENDELLIPSIS + PUSHBUTTON "%(Track)",IDC_TRACK_BUTTON,151,57,87,14 + RTEXT "Year:",IDC_TXT_PROPERTY_DLG_TAG_YEAR_STATIC,7,77,20,8,SS_ENDELLIPSIS + PUSHBUTTON "%(Year)",IDC_YEAR_BUTTON,33,74,87,14 + RTEXT "Genre:",IDC_TXT_PROPERTY_DLG_TAG_GENRE_STATIC,126,77,20,8,SS_ENDELLIPSIS + PUSHBUTTON "%(Genre)",IDC_GENRE_BUTTON,151,74,87,14 + RTEXT "Comment:",IDC_TXT_PROPERTY_DLG_TAG_COMMENT_STATIC,7,94,20,8,SS_ENDELLIPSIS + PUSHBUTTON "%(Comment)",IDC_COMMENT_BUTTON,33,91,87,14 + RTEXT "Original:",IDC_ORIGINAL_STATIC,126,94,20,8,SS_ENDELLIPSIS + PUSHBUTTON "%(Original)",IDC_ORIGINAL_BUTTON,151,91,87,14 + LTEXT "When click the button:",IDC_TXT_TAG_SEL_CLICK_BTN_SEL_STATIC,7,110,40,8,SS_ENDELLIPSIS + CONTROL "Insert",IDC_INSERT_RADIO,"Button",BS_AUTORADIOBUTTON,53,110,30,8 + CONTROL "Copy to clipboard",IDC_COPY_RADIO,"Button",BS_AUTORADIOBUTTON,89,110,30,8 + DEFPUSHBUTTON "OK",IDOK,133,123,50,14 + PUSHBUTTON "Cancel",IDCANCEL,188,123,50,14 +END + +IDD_SELECT_ITEM_DIALOG DIALOGEX 0, 0, 150, 90 +STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +CAPTION "SelectItemDlg / MediaLibStatisticsDlg" +FONT 9, "Segoe UI", 400, 0, 0x0 +BEGIN + CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,7,136,57 + DEFPUSHBUTTON "OK",IDOK,39,69,50,14 + PUSHBUTTON "Cancel",IDCANCEL,93,69,50,14 +END -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,7,6,1 - PRODUCTVERSION 2,7,6,1 - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE 0x1L - FILESUBTYPE 0x0L +IDD_FLAC_ENCODE_CFG_DIALOG DIALOGEX 0, 0, 210, 91 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Flac Encode Options" +FONT 9, "Segoe UI", 400, 0, 0x0 BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "080404b0" - BEGIN - VALUE "CompanyName", "By ZhongYang" - VALUE "FileDescription", "MusicPlayer2" - VALUE "FileVersion", "2.7.6.1" - VALUE "InternalName", "MusicPlayer2.exe" - VALUE "LegalCopyright", "By ZhongYang. All rights reserved." - VALUE "OriginalFilename", "MusicPlayer2.exe" - VALUE "ProductName", "MusicPlayer2" - VALUE "ProductVersion", "2.7.6.1" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x804, 1200 - END + GROUPBOX "Compression level",IDC_TXT_ENCODE_OPT_FLAC_CMP_LEVEL_STATIC,7,7,196,40 + CONTROL "",IDC_SLIDER1,"msctls_trackbar32",TBS_AUTOTICKS | WS_TABSTOP,14,18,142,13 + LTEXT "1~8",IDC_COMP_LEVEL_STATIC,167,19,22,8 + LTEXT "Low",IDC_TXT_ENCODE_OPT_FLAC_CMP_LEVEL_LOW_STATIC,14,34,54,8 + RTEXT "High",IDC_TXT_ENCODE_OPT_FLAC_CMP_LEVEL_HIGH_STATIC,102,34,54,8 + CONTROL "Custom flac parameters",IDC_SPECIFY_PARA_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,53,49,8 + EDITTEXT IDC_EDIT1,66,52,137,12,ES_AUTOHSCROLL + DEFPUSHBUTTON "OK",IDOK,95,70,50,14 + PUSHBUTTON "Cancel",IDCANCEL,153,70,50,14 END @@ -1413,202 +1588,308 @@ END #ifdef APSTUDIO_INVOKED GUIDELINES DESIGNINFO BEGIN - IDD_ABOUTBOX, DIALOG + IDD_TEST_DIALOG, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 184 - VERTGUIDE, 11 + RIGHTMARGIN, 302 TOPMARGIN, 7 - BOTTOMMARGIN, 131 + BOTTOMMARGIN, 169 END - IDD_SET_PATH_DIALOG, DIALOG + IDD_PROPERTY_ADVANCED_DIALOG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 337 + TOPMARGIN, 7 + BOTTOMMARGIN, 141 + END + + IDD_MINI_DIALOG, DIALOG + BEGIN + RIGHTMARGIN, 168 + BOTTOMMARGIN, 22 + END + + IDD_MEDIA_CLASSIFY_DIALOG, DIALOG BEGIN LEFTMARGIN, 4 - RIGHTMARGIN, 275 + RIGHTMARGIN, 326 TOPMARGIN, 4 - BOTTOMMARGIN, 169 + BOTTOMMARGIN, 166 + BOTTOMMARGIN, 166 END - IDD_FIND_DIALOG, DIALOG + IDD_FOLDER_EXPLORE_DIALOG, DIALOG BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 249 - TOPMARGIN, 7 - BOTTOMMARGIN, 204 + LEFTMARGIN, 4 + RIGHTMARGIN, 326 + TOPMARGIN, 4 + BOTTOMMARGIN, 165 END - IDD_OPTIONS_DIALOG, DIALOG + IDD_ALL_MEDIA_DIALOG, DIALOG BEGIN - LEFTMARGIN, 5 - RIGHTMARGIN, 264 + LEFTMARGIN, 4 + RIGHTMARGIN, 326 TOPMARGIN, 4 - BOTTOMMARGIN, 204 + BOTTOMMARGIN, 166 END - IDD_LYRIC_SETTING_DIALOG, DIALOG + IDD_ABOUTBOX, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 239 - VERTGUIDE, 17 - TOPMARGIN, 2 - BOTTOMMARGIN, 378 + RIGHTMARGIN, 215 + VERTGUIDE, 14 + VERTGUIDE, 208 + TOPMARGIN, 7 + BOTTOMMARGIN, 148 END IDD_APPEREANCE_SETTING_DLG, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 239 - VERTGUIDE, 12 - VERTGUIDE, 16 - TOPMARGIN, 7 - BOTTOMMARGIN, 447 + RIGHTMARGIN, 337 + VERTGUIDE, 14 + VERTGUIDE, 140 + VERTGUIDE, 150 + VERTGUIDE, 250 + VERTGUIDE, 260 + VERTGUIDE, 330 + TOPMARGIN, 4 + BOTTOMMARGIN, 571 END - IDD_PROPERTY_DIALOG, DIALOG + IDD_OPTIONS_DIALOG, DIALOG BEGIN LEFTMARGIN, 5 - RIGHTMARGIN, 298 - VERTGUIDE, 293 + RIGHTMARGIN, 364 TOPMARGIN, 4 - BOTTOMMARGIN, 138 + BOTTOMMARGIN, 241 END - IDD_MESSAGE_DIALOG, DIALOG + IDD_COVER_DOWNLOAD_DIALOG, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 210 + RIGHTMARGIN, 258 + VERTGUIDE, 14 + VERTGUIDE, 21 + VERTGUIDE, 198 + VERTGUIDE, 208 + VERTGUIDE, 251 TOPMARGIN, 7 - BOTTOMMARGIN, 169 + BOTTOMMARGIN, 224 END - IDD_MINI_DIALOG, DIALOG + IDD_DATA_SETTINGS_DIALOG, DIALOG BEGIN - RIGHTMARGIN, 168 - BOTTOMMARGIN, 22 + LEFTMARGIN, 7 + RIGHTMARGIN, 337 + VERTGUIDE, 14 + VERTGUIDE, 21 + VERTGUIDE, 133 + VERTGUIDE, 140 + VERTGUIDE, 150 + VERTGUIDE, 157 + VERTGUIDE, 330 + TOPMARGIN, 4 + BOTTOMMARGIN, 234 END - IDD_LYRIC_EDIT_DIALOG, DIALOG + IDD_EQUALIZER_DIALOG, DIALOG BEGIN - LEFTMARGIN, 4 - RIGHTMARGIN, 293 - TOPMARGIN, 3 - BOTTOMMARGIN, 235 + LEFTMARGIN, 7 + RIGHTMARGIN, 292 + VERTGUIDE, 14 + VERTGUIDE, 83 + VERTGUIDE, 90 + VERTGUIDE, 100 + VERTGUIDE, 107 + VERTGUIDE, 285 + TOPMARGIN, 7 + BOTTOMMARGIN, 100 + HORZGUIDE, 19 + HORZGUIDE, 85 END - IDD_DATA_SETTINGS_DIALOG, DIALOG + IDD_FIND_DIALOG, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 239 - VERTGUIDE, 13 - TOPMARGIN, 6 - BOTTOMMARGIN, 230 + RIGHTMARGIN, 283 + VERTGUIDE, 14 + VERTGUIDE, 113 + VERTGUIDE, 120 + VERTGUIDE, 130 + VERTGUIDE, 137 + VERTGUIDE, 206 + VERTGUIDE, 276 + TOPMARGIN, 7 + BOTTOMMARGIN, 201 END - IDD_LYRIC_DOWNLOAD_DIALOG, DIALOG + IDD_FORMAT_CONVERT_DIALOG, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 249 + RIGHTMARGIN, 313 + VERTGUIDE, 14 + VERTGUIDE, 21 + VERTGUIDE, 160 + VERTGUIDE, 170 + VERTGUIDE, 306 TOPMARGIN, 7 - BOTTOMMARGIN, 182 + BOTTOMMARGIN, 237 END - IDD_LYRIC_BATCH_DOWN_DIALOG, DIALOG + IDD_MESSAGE_DIALOG, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 272 + RIGHTMARGIN, 228 TOPMARGIN, 7 - BOTTOMMARGIN, 221 + BOTTOMMARGIN, 169 END - IDD_EQUALIZER_DIALOG, DIALOG + IDD_HOT_KEY_SETTINGS_DIALOG, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 270 + RIGHTMARGIN, 337 + VERTGUIDE, 160 + VERTGUIDE, 170 TOPMARGIN, 7 - BOTTOMMARGIN, 100 - HORZGUIDE, 81 + BOTTOMMARGIN, 183 END - IDD_SOUND_EFFECT_DIALOG, DIALOG + IDD_LYRIC_BATCH_DOWN_DIALOG, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 283 + RIGHTMARGIN, 337 + VERTGUIDE, 14 + VERTGUIDE, 21 + VERTGUIDE, 150 + VERTGUIDE, 160 + VERTGUIDE, 330 TOPMARGIN, 7 - BOTTOMMARGIN, 137 + BOTTOMMARGIN, 227 END - IDD_REVERB_DIALOG, DIALOG + IDD_LYRIC_DOWNLOAD_DIALOG, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 251 + RIGHTMARGIN, 293 + VERTGUIDE, 14 + VERTGUIDE, 21 + VERTGUIDE, 286 TOPMARGIN, 7 - BOTTOMMARGIN, 132 + BOTTOMMARGIN, 218 END - IDD_COVER_DOWNLOAD_DIALOG, DIALOG + IDD_LYRIC_EDIT_DIALOG, DIALOG BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 250 - TOPMARGIN, 7 - BOTTOMMARGIN, 172 + LEFTMARGIN, 4 + RIGHTMARGIN, 293 + TOPMARGIN, 3 + BOTTOMMARGIN, 235 END - IDD_FORMAT_CONVERT_DIALOG, DIALOG + IDD_LYRIC_SETTING_DIALOG, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 244 - TOPMARGIN, 7 - BOTTOMMARGIN, 231 + RIGHTMARGIN, 337 + VERTGUIDE, 14 + VERTGUIDE, 21 + VERTGUIDE, 140 + VERTGUIDE, 150 + VERTGUIDE, 250 + VERTGUIDE, 260 + VERTGUIDE, 330 + TOPMARGIN, 4 + BOTTOMMARGIN, 410 END IDD_MP3_ENCODE_CFG_DIALOG, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 169 + RIGHTMARGIN, 242 + VERTGUIDE, 14 + VERTGUIDE, 235 TOPMARGIN, 7 - BOTTOMMARGIN, 120 + BOTTOMMARGIN, 111 END - IDD_OGG_ENCODE_CFG_DIALOG, DIALOG + IDD_MUSICPLAYER2_DIALOG, DIALOG BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 174 - TOPMARGIN, 7 - BOTTOMMARGIN, 55 + LEFTMARGIN, 2 + RIGHTMARGIN, 375 + BOTTOMMARGIN, 243 END - IDD_WMA_ENCODE_CFG_DIALOG, DIALOG + IDD_OGG_ENCODE_CFG_DIALOG, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 156 + RIGHTMARGIN, 164 TOPMARGIN, 7 BOTTOMMARGIN, 58 END - IDD_TAG_EDIT_DIALOG, DIALOG + IDD_PLAY_SETTING_DIALOG, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 150 - TOPMARGIN, 7 - BOTTOMMARGIN, 156 + RIGHTMARGIN, 337 + VERTGUIDE, 14 + VERTGUIDE, 160 + VERTGUIDE, 170 + VERTGUIDE, 330 + TOPMARGIN, 4 + BOTTOMMARGIN, 291 + END + + IDD_PROPERTY_DIALOG, DIALOG + BEGIN + LEFTMARGIN, 5 + RIGHTMARGIN, 339 + VERTGUIDE, 10 + VERTGUIDE, 30 + VERTGUIDE, 33 + VERTGUIDE, 105 + VERTGUIDE, 108 + VERTGUIDE, 128 + VERTGUIDE, 131 + VERTGUIDE, 185 + VERTGUIDE, 190 + VERTGUIDE, 195 + VERTGUIDE, 200 + VERTGUIDE, 220 + VERTGUIDE, 223 + VERTGUIDE, 270 + VERTGUIDE, 273 + VERTGUIDE, 293 + VERTGUIDE, 296 + VERTGUIDE, 334 + TOPMARGIN, 2 + BOTTOMMARGIN, 145 END - IDD_RECORDER_DIALOG, DIALOG + IDD_REVERB_DIALOG, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 220 + RIGHTMARGIN, 292 + VERTGUIDE, 14 TOPMARGIN, 7 - BOTTOMMARGIN, 65 + BOTTOMMARGIN, 100 END - IDD_PLAY_SETTING_DIALOG, DIALOG + IDD_SET_PATH_DIALOG, DIALOG + BEGIN + LEFTMARGIN, 4 + RIGHTMARGIN, 326 + TOPMARGIN, 4 + BOTTOMMARGIN, 166 + END + + IDD_SOUND_EFFECT_DIALOG, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 239 - VERTGUIDE, 17 + RIGHTMARGIN, 309 TOPMARGIN, 7 - BOTTOMMARGIN, 285 + BOTTOMMARGIN, 146 END IDD_SUPPORT_FORMAT_DIALOG, DIALOG @@ -1616,27 +1897,31 @@ BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 268 TOPMARGIN, 7 - BOTTOMMARGIN, 175 + BOTTOMMARGIN, 174 END - IDD_HOT_KEY_SETTINGS_DIALOG, DIALOG + IDD_TAG_EDIT_DIALOG, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 248 - TOPMARGIN, 4 + RIGHTMARGIN, 293 + VERTGUIDE, 27 + VERTGUIDE, 32 + TOPMARGIN, 7 + BOTTOMMARGIN, 157 END - IDD_MUSICPLAYER2_DIALOG, DIALOG + IDD_WMA_ENCODE_CFG_DIALOG, DIALOG BEGIN - LEFTMARGIN, 2 - RIGHTMARGIN, 367 - BOTTOMMARGIN, 257 + LEFTMARGIN, 7 + RIGHTMARGIN, 183 + TOPMARGIN, 7 + BOTTOMMARGIN, 58 END IDD_LISTEN_TIME_STATISTICS_DLG, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 299 + RIGHTMARGIN, 333 TOPMARGIN, 7 BOTTOMMARGIN, 165 END @@ -1644,97 +1929,72 @@ BEGIN IDD_DONATE_DIALOG, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 222 + RIGHTMARGIN, 249 TOPMARGIN, 7 - BOTTOMMARGIN, 123 + BOTTOMMARGIN, 132 END IDD_MEDIA_LIB_DIALOG, DIALOG BEGIN LEFTMARGIN, 5 - RIGHTMARGIN, 338 - TOPMARGIN, 4 - BOTTOMMARGIN, 213 - END - - IDD_SELECT_PLAYLIST_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 4 - RIGHTMARGIN, 322 + RIGHTMARGIN, 340 TOPMARGIN, 4 - BOTTOMMARGIN, 173 + BOTTOMMARGIN, 207 END IDD_INPUT_DLG, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 176 - TOPMARGIN, 7 - BOTTOMMARGIN, 60 - END - - IDD_FILE_RELATE_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 264 - TOPMARGIN, 7 - BOTTOMMARGIN, 175 - END - - IDD_TEST_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 302 + RIGHTMARGIN, 193 TOPMARGIN, 7 - BOTTOMMARGIN, 169 - END - - IDD_MEDIA_CLASSIFY_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 4 - RIGHTMARGIN, 287 - TOPMARGIN, 4 - BOTTOMMARGIN, 149 - BOTTOMMARGIN, 151 + BOTTOMMARGIN, 58 END - IDD_FOLDER_EXPLORE_DIALOG, DIALOG + IDD_SELECT_PLAYLIST_DIALOG, DIALOG BEGIN LEFTMARGIN, 4 - RIGHTMARGIN, 288 + RIGHTMARGIN, 326 TOPMARGIN, 4 - BOTTOMMARGIN, 155 + BOTTOMMARGIN, 166 END - IDD_MEDIA_LIB_SETTING_DIALOG, DIALOG + IDD_FILE_RELATE_DIALOG, DIALOG BEGIN - LEFTMARGIN, 6 - RIGHTMARGIN, 236 - VERTGUIDE, 14 - TOPMARGIN, 5 - BOTTOMMARGIN, 563 + LEFTMARGIN, 7 + RIGHTMARGIN, 298 + TOPMARGIN, 7 + BOTTOMMARGIN, 175 END IDD_ADD_TO_PLAYLIST_DIALOG, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 179 + RIGHTMARGIN, 203 TOPMARGIN, 7 - BOTTOMMARGIN, 145 + BOTTOMMARGIN, 146 END - IDD_ALL_MEDIA_DIALOG, DIALOG + IDD_MEDIA_LIB_SETTING_DIALOG, DIALOG BEGIN - LEFTMARGIN, 4 - RIGHTMARGIN, 286 + LEFTMARGIN, 7 + RIGHTMARGIN, 337 + VERTGUIDE, 14 + VERTGUIDE, 21 + VERTGUIDE, 140 + VERTGUIDE, 150 + VERTGUIDE, 240 + VERTGUIDE, 250 + VERTGUIDE, 270 + VERTGUIDE, 280 + VERTGUIDE, 330 TOPMARGIN, 4 - BOTTOMMARGIN, 151 + BOTTOMMARGIN, 593 END IDD_LYRIC_RELATE_DIALOG, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 304 + RIGHTMARGIN, 322 TOPMARGIN, 7 BOTTOMMARGIN, 171 END @@ -1742,58 +2002,57 @@ BEGIN IDD_CLEAN_UP_RANGE_DIALOG, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 123 + RIGHTMARGIN, 181 TOPMARGIN, 7 BOTTOMMARGIN, 107 END - IDD_PROPERTY_PARENT_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 4 - RIGHTMARGIN, 314 - TOPMARGIN, 4 - BOTTOMMARGIN, 177 - END - IDD_PROPERTY_ALBUM_COVER_DIALOG, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 297 - TOPMARGIN, 4 - BOTTOMMARGIN, 124 + RIGHTMARGIN, 337 + VERTGUIDE, 150 + TOPMARGIN, 7 + BOTTOMMARGIN, 141 END - IDD_TAG_FROM_FILE_NAME_DIALOG, DIALOG + IDD_PROPERTY_PARENT_DIALOG, DIALOG BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 184 - VERTGUIDE, 84 - TOPMARGIN, 7 - BOTTOMMARGIN, 127 + LEFTMARGIN, 5 + RIGHTMARGIN, 355 + TOPMARGIN, 5 + BOTTOMMARGIN, 186 END - IDD_PROPERTY_ADVANCED_DIALOG, DIALOG + IDD_TAG_MODE_SELECT_DIALOG, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 185 + RIGHTMARGIN, 238 + VERTGUIDE, 27 + VERTGUIDE, 33 + VERTGUIDE, 120 + VERTGUIDE, 126 + VERTGUIDE, 146 + VERTGUIDE, 151 TOPMARGIN, 7 - BOTTOMMARGIN, 109 + BOTTOMMARGIN, 137 END IDD_SELECT_ITEM_DIALOG, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 128 + RIGHTMARGIN, 143 TOPMARGIN, 7 - BOTTOMMARGIN, 80 + BOTTOMMARGIN, 83 END IDD_FLAC_ENCODE_CFG_DIALOG, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 169 + RIGHTMARGIN, 203 + VERTGUIDE, 14 TOPMARGIN, 7 - BOTTOMMARGIN, 89 + BOTTOMMARGIN, 84 END END #endif // APSTUDIO_INVOKED @@ -1804,14 +2063,51 @@ END // AFX_DIALOG_LAYOUT // -IDD_SET_PATH_DIALOG AFX_DIALOG_LAYOUT +IDD_TEST_DIALOG AFX_DIALOG_LAYOUT BEGIN 0, + 100, 100, 0, 0, + 100, 100, 0, 0, + 0, 0, 100, 0, 0, 0, 0, 0, - 100, 0, 0, 0, + 0, 0, 0, 0 +END + +IDD_PROPERTY_ADVANCED_DIALOG AFX_DIALOG_LAYOUT +BEGIN + 0, + 0, 0, 100, 100 +END + +IDD_MINI_DIALOG AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +IDD_MEDIA_CLASSIFY_DIALOG AFX_DIALOG_LAYOUT +BEGIN + 0, 0, 0, 100, 0, - 0, 0, 100, 100, - 0, 0, 100, 0 + 0, 0, 20, 100, + 20, 0, 80, 100, + 20, 0, 0, 100 +END + +IDD_FOLDER_EXPLORE_DIALOG AFX_DIALOG_LAYOUT +BEGIN + 0, + 0, 0, 100, 0, + 0, 0, 20, 100, + 20, 0, 80, 100, + 20, 0, 80, 0, + 20, 0, 0, 100 +END + +IDD_ALL_MEDIA_DIALOG AFX_DIALOG_LAYOUT +BEGIN + 0, + 0, 0, 100, 0, + 0, 0, 100, 100 END IDD_ABOUTBOX AFX_DIALOG_LAYOUT @@ -1819,16 +2115,45 @@ BEGIN 0 END -IDD_FIND_DIALOG AFX_DIALOG_LAYOUT +IDD_APPEREANCE_SETTING_DLG AFX_DIALOG_LAYOUT BEGIN 0, - 100, 100, 0, 0, - 100, 100, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 100, 100, + 0, 0, 100, 0, + 0, 0, 40, 0, + 40, 0, 60, 0, + 0, 0, 40, 0, + 40, 0, 40, 0, + 80, 0, 20, 0, + 0, 0, 40, 0, + 0, 0, 40, 0, + 40, 0, 40, 0, + 0, 0, 40, 0, + 40, 0, 60, 0, + 0, 0, 40, 0, + 0, 0, 40, 0, + 40, 0, 40, 0, + 80, 0, 20, 0, + 0, 0, 100, 0, + 0, 0, 40, 0, + 40, 0, 60, 0, + 0, 0, 40, 0, + 40, 0, 40, 0, + 80, 0, 20, 0, + 0, 0, 40, 0, + 40, 0, 60, 0, + 0, 0, 40, 0, + 40, 0, 40, 0, + 80, 0, 20, 0, + 0, 0, 40, 0, + 40, 0, 60, 0, + 0, 0, 100, 0, + 0, 0, 100, 0, + 0, 0, 100, 0, + 0, 0, 40, 0, + 40, 0, 60, 0, + 0, 0, 40, 0, + 40, 0, 60, 0, + 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1837,6 +2162,30 @@ BEGIN 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 80, 0, 20, 0, + 40, 0, 60, 0, + 0, 0, 100, 0, + 0, 0, 100, 0, + 0, 0, 40, 0, + 40, 0, 60, 0, + 0, 0, 100, 0, + 0, 0, 100, 0, + 0, 0, 100, 0, + 0, 0, 40, 0, + 40, 0, 60, 0, + 0, 0, 40, 0, + 40, 0, 60, 0, + 0, 0, 40, 0, + 40, 0, 60, 0, + 0, 0, 100, 0, + 0, 0, 40, 0, + 40, 0, 60, 0, + 40, 0, 40, 0, + 0, 0, 100, 0, + 0, 0, 100, 0, + 0, 0, 40, 0, + 40, 0, 0, 0, + 80, 0, 20, 0, 0, 0, 100, 0 END @@ -1849,3543 +2198,57 @@ BEGIN 100, 100, 0, 0 END -IDD_LYRIC_SETTING_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0 -END - -IDD_APPEREANCE_SETTING_DLG AFX_DIALOG_LAYOUT -BEGIN - 0 -END - -IDD_PROPERTY_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0, - 0, 0, 50, 0, - 0, 0, 50, 0, - 0, 0, 50, 0, - 0, 0, 25, 0, - 25, 0, 25, 0, - 0, 0, 25, 0, - 0, 0, 50, 0, - 50, 0, 50, 0, - 50, 0, 50, 0, - 50, 0, 50, 0, - 50, 0, 25, 0, - 75, 0, 25, 0, - 50, 0, 50, 100, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 25, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 50, 0, - 50, 0, 0, 0, - 50, 0, 0, 0, - 50, 0, 0, 0, - 50, 0, 50, 100, - 75, 0, 0, 0, - 50, 0, 0, 0, - 50, 0, 0, 0, - 50, 0, 0, 0, - 50, 100, 50, 0, - 0, 0, 0, 0, - 50, 0, 50, 0, - 0, 100, 0, 0, - 0, 100, 0, 0, - 0, 100, 0, 0, - 0, 0, 25, 0, - 0, 0, 0, 0, - 25, 0, 25, 0, - 25, 0, 0, 0, - 25, 0, 25, 0, - 25, 0, 0, 0 -END - -IDD_MESSAGE_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0, - 100, 100, 0, 0, - 0, 0, 100, 100, - 0, 0, 100, 0, - 0, 100, 100, 0 -END - -IDD_MINI_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0 -END - -IDD_LYRIC_EDIT_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0, - 0, 0, 100, 0, - 0, 0, 0, 0 -END - -IDD_DATA_SETTINGS_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0 -END - -IDD_LYRIC_DOWNLOAD_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0, - 100, 100, 0, 0, - 100, 0, 0, 0, - 0, 0, 50, 0, - 0, 0, 0, 0, - 50, 0, 50, 0, - 50, 0, 0, 0, - 0, 0, 100, 100, - 0, 0, 100, 0, - 100, 100, 0, 0, - 0, 100, 0, 0, - 0, 100, 100, 0, - 0, 100, 0, 0, - 0, 100, 0, 0, - 0, 100, 0, 0, - 0, 100, 0, 0, - 0, 100, 0, 0, - 100, 100, 0, 0, - 100, 0, 0, 0 -END - -IDD_LYRIC_BATCH_DOWN_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0, - 100, 100, 0, 0, - 0, 0, 100, 100, - 100, 100, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 100, 0, - 0, 0, 0, 0, - 0, 100, 100, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 100, 0, 0 -END - -IDD_EQUALIZER_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0 -END - -IDD_SOUND_EFFECT_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0 -END - -IDD_REVERB_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0 -END - -IDD_COVER_DOWNLOAD_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0, - 100, 100, 0, 0, - 100, 0, 0, 0, - 0, 0, 50, 0, - 0, 0, 0, 0, - 50, 0, 50, 0, - 50, 0, 0, 0, - 0, 0, 100, 100, - 0, 0, 100, 0, - 100, 100, 0, 0, - 100, 0, 0, 0, - 0, 100, 100, 0, - 0, 100, 0, 0, - 0, 100, 0, 0, - 0, 100, 0, 0 -END - -IDD_FORMAT_CONVERT_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0, - 0, 0, 100, 100, - 0, 0, 0, 0, - 0, 0, 100, 0, - 0, 100, 0, 0, - 100, 100, 0, 0, - 100, 0, 0, 0, - 0, 100, 100, 0, - 0, 100, 0, 0, - 0, 100, 0, 0, - 0, 100, 0, 0, - 0, 100, 0, 0, - 0, 100, 0, 0, - 0, 0, 0, 0, - 100, 100, 0, 0, - 0, 100, 100, 0, - 0, 100, 0, 0, - 0, 100, 0, 0, - 0, 100, 0, 0, - 0, 100, 100, 0, - 0, 100, 0, 0, - 0, 100, 0, 0, - 0, 100, 100, 0 -END - -IDD_MP3_ENCODE_CFG_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0 -END - -IDD_OGG_ENCODE_CFG_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0 -END - -IDD_WMA_ENCODE_CFG_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0 -END - -IDD_TAG_EDIT_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0 -END - -IDD_RECORDER_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0, - 0, 0, 0, 0, - 0, 0, 100, 0, - 0, 100, 0, 0, - 0, 100, 0, 0, - 0, 100, 0, 0, - 100, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0 -END - -IDD_PLAY_SETTING_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0 -END - -IDD_SUPPORT_FORMAT_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0, - 100, 100, 0, 0, - 0, 0, 100, 0, - 0, 0, 100, 100 -END - -IDD_HOT_KEY_SETTINGS_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0 -END - -IDD_MUSICPLAYER2_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0 -END - -IDD_LISTEN_TIME_STATISTICS_DLG AFX_DIALOG_LAYOUT -BEGIN - 0, - 100, 100, 0, 0, - 0, 0, 100, 100, - 0, 100, 0, 0, - 0, 100, 0, 0 -END - -IDD_DONATE_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0 -END - -IDD_MEDIA_LIB_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0, - 100, 100, 0, 0, - 0, 0, 100, 100, - 100, 100, 0, 0, - 0, 100, 0, 0, - 0, 100, 0, 0 -END - -IDD_SELECT_PLAYLIST_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0, - 0, 0, 30, 100, - 0, 0, 0, 0, - 100, 0, 0, 0, - 30, 0, 70, 100, - 30, 0, 0, 100 -END - -IDD_INPUT_DLG AFX_DIALOG_LAYOUT -BEGIN - 0 -END - -IDD_FILE_RELATE_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0, - 100, 100, 0, 0, - 100, 100, 0, 0, - 0, 0, 100, 100, - 0, 100, 0, 0, - 0, 100, 0, 0 -END - -IDD_TEST_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0, - 100, 100, 0, 0, - 100, 100, 0, 0, - 0, 0, 100, 0, - 0, 0, 0, 0, - 0, 0, 0, 0 -END - -IDD_MEDIA_CLASSIFY_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0, - 0, 0, 20, 100, - 20, 0, 80, 100, - 0, 0, 100, 0, - 20, 0, 0, 100 -END - -IDD_FOLDER_EXPLORE_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0, - 0, 0, 100, 0, - 0, 0, 20, 100, - 20, 0, 80, 100, - 20, 0, 80, 0, - 20, 0, 0, 100 -END - -IDD_MEDIA_LIB_SETTING_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0 -END - -IDD_ADD_TO_PLAYLIST_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0, - 100, 100, 0, 0, - 100, 100, 0, 0, - 0, 0, 100, 100, - 0, 0, 100, 0 -END - -IDD_ALL_MEDIA_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0, - 0, 0, 100, 100, - 0, 0, 100, 0 -END - -IDD_LYRIC_RELATE_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0, - 100, 100, 0, 0, - 100, 100, 0, 0, - 0, 100, 0, 0, - 0, 0, 0, 0, - 0, 0, 100, 0, - 100, 0, 0, 0, - 100, 0, 0, 0, - 0, 0, 100, 100, - 0, 0, 0, 0, - 100, 0, 0, 0, - 100, 0, 0, 0 -END - -IDD_CLEAN_UP_RANGE_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0, - 100, 100, 0, 0, - 100, 100, 0, 0, - 0, 0, 100, 0, - 0, 0, 100, 100 -END - -IDD_PROPERTY_PARENT_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0, - 100, 100, 0, 0, - 0, 100, 0, 0, - 0, 100, 0, 0, - 0, 100, 0, 0, - 100, 100, 0, 0, - 0, 0, 100, 100 -END - -IDD_PROPERTY_ALBUM_COVER_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0, - 80, 0, 20, 100, - 80, 100, 0, 0, - 80, 100, 0, 0, - 80, 100, 0, 0, - 0, 100, 0, 0 -END - -IDD_TAG_FROM_FILE_NAME_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0 -END - -IDD_PROPERTY_ADVANCED_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0, - 0, 0, 100, 100 -END - -IDD_SELECT_ITEM_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0, - 100, 100, 0, 0, - 100, 100, 0, 0, - 0, 0, 100, 100 -END - -IDD_FLAC_ENCODE_CFG_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -IDR_MENU1 MENU -BEGIN - POPUP "文件(&F)" - BEGIN - MENUITEM "打开文件(&O)...", ID_FILE_OPEN - MENUITEM "打开文件夹(&F)...", ID_FILE_OPEN_FOLDER - MENUITEM "打开&URL...", ID_FILE_OPEN_URL - MENUITEM "打开播放列表(&P)...", ID_FILE_OPEN_PLAYLIST - MENUITEM SEPARATOR - MENUITEM "退出(&X)", ID_MENU_EXIT - END - POPUP "播放控制(&P)" - BEGIN - MENUITEM "播放/暂停(&P)", ID_PLAY_PAUSE - MENUITEM "停止(&S)", ID_STOP - MENUITEM "上一曲(&V)", ID_PREVIOUS - MENUITEM "下一曲(&N)", ID_NEXT - MENUITEM SEPARATOR - MENUITEM "快退5秒(&R)", ID_REW - MENUITEM "快进5秒(&F)", ID_FF - MENUITEM SEPARATOR - MENUITEM "加速播放", ID_SPEED_UP - MENUITEM "减速播放", ID_SLOW_DOWN - MENUITEM "恢复原速", ID_ORIGINAL_SPEED - MENUITEM SEPARATOR - POPUP "循环模式(&M)" - BEGIN - MENUITEM "顺序播放", ID_PLAY_ORDER - MENUITEM "无序播放", ID_PLAY_SHUFFLE - MENUITEM "随机播放", ID_PLAY_RANDOM - MENUITEM "列表循环", ID_LOOP_PLAYLIST - MENUITEM "单曲循环", ID_LOOP_TRACK - MENUITEM "单曲播放", ID_PLAY_TRACK - END - POPUP "AB重复(&E)" - BEGIN - MENUITEM "AB重复(&R)", ID_AB_REPEAT - MENUITEM SEPARATOR - MENUITEM "设置A点(&A)", ID_SET_A_POINT - MENUITEM "设置B点(&B)", ID_SET_B_POINT - MENUITEM "继续下一句AB重复(&N)", ID_NEXT_AB_REPEAT - MENUITEM "取消AB重复(&C)", ID_RESET_AB_REPEAT - END - END - POPUP "播放列表(&L)" - BEGIN - POPUP "添加(&A)" - BEGIN - MENUITEM "添加文件(&A)...", ID_PLAYLIST_ADD_FILE - MENUITEM "添加文件夹(&F)...", ID_PLAYLIST_ADD_FOLDER - MENUITEM "添加&URL...", ID_PLAYLIST_ADD_URL - END - POPUP "删除(&D)" - BEGIN - MENUITEM "从列表中删除(&L)", ID_REMOVE_FROM_PLAYLIST - MENUITEM "从磁盘删除(&D)", ID_DELETE_FROM_DISK - MENUITEM SEPARATOR - MENUITEM "清空播放列表(&E)", ID_EMPTY_PLAYLIST - MENUITEM "删除相同项(&S)", ID_REMOVE_SAME_SONGS - MENUITEM "删除无效项(&I)", ID_REMOVE_INVALID_ITEMS - END - MENUITEM "重新载入播放列表(&R)", ID_RELOAD_PLAYLIST - MENUITEM SEPARATOR - MENUITEM "保存为新播放列表(&N)...", ID_SAVE_AS_NEW_PLAYLIST - MENUITEM "当前播放列表另存为(&S)...", ID_SAVE_CURRENT_PLAYLIST_AS - MENUITEM SEPARATOR - POPUP "排序方式" - BEGIN - MENUITEM "按文件名排序", ID_SORT_BY_FILE - MENUITEM "按路径排序", ID_SORT_BY_PATH - MENUITEM "按标题排序", ID_SORT_BY_TITLE - MENUITEM "按艺术家排序", ID_SORT_BY_ARTIST - MENUITEM "按唱片集排序", ID_SORT_BY_ALBUM - MENUITEM "按音轨序号排序", ID_SORT_BY_TRACK - MENUITEM "按修改时间排序", ID_SORT_BY_MODIFIED_TIME - MENUITEM SEPARATOR - MENUITEM "升序", ID_ACCENDING_ORDER - MENUITEM "降序", ID_DESENDING_ORDER - MENUITEM SEPARATOR - MENUITEM "倒序排列", ID_INVERT_PLAYLIST - END - POPUP "播放列表显示方式" - BEGIN - MENUITEM "文件名", ID_DISP_FILE_NAME - MENUITEM "标题", ID_DISP_TITLE - MENUITEM "艺术家 - 标题", ID_DISP_ARTIST_TITLE - MENUITEM "标题 - 艺术家", ID_DISP_TITLE_ARTIST - END - MENUITEM SEPARATOR - MENUITEM "定位到正在播放曲目(&L)", ID_LOCATE_TO_CURRENT - END - POPUP "歌词(&C)" - BEGIN - MENUITEM "重新载入歌词(&R)", ID_RELOAD_LYRIC - MENUITEM "复制当前歌词(&C)", ID_COPY_CURRENT_LYRIC - MENUITEM "复制所有歌词(&A)", ID_COPY_ALL_LYRIC - MENUITEM SEPARATOR - MENUITEM "编辑歌词(&E)...", ID_EDIT_LYRIC - POPUP "繁简转换(&V)" - BEGIN - MENUITEM "转换为简体中文(&S)", ID_TRANSLATE_TO_SIMPLIFIED_CHINESE - MENUITEM "转换为繁体中文(&T)", ID_TRANSLATE_TO_TRANDITIONAL_CHINESE - END - MENUITEM SEPARATOR - MENUITEM "显示歌词翻译(&N)", ID_SHOW_LYRIC_TRANSLATE - MENUITEM "显示桌面歌词(&K)", ID_SHOW_DESKTOP_LYRIC - MENUITEM SEPARATOR - MENUITEM "歌词提前0.5秒", ID_LYRIC_FORWARD - MENUITEM "歌词延后0.5秒", ID_LYRIC_DELAY - MENUITEM "保存歌词更改(&S)", ID_SAVE_MODIFIED_LYRIC - MENUITEM SEPARATOR - MENUITEM "关联本地歌词(&T)...", ID_RELATE_LOCAL_LYRIC - MENUITEM "删除歌词(&D)", ID_DELETE_LYRIC - MENUITEM "撤消歌词关联(&U)", ID_UNLINK_LYRIC - MENUITEM "打开歌词文件位置(&O)...", ID_BROWSE_LYRIC - POPUP "内嵌歌词" - BEGIN - MENUITEM "嵌入到音频文件(&E)", ID_EMBED_LYRIC_TO_AUDIO_FILE - MENUITEM "从音频文件中删除(&D)", ID_DELETE_LYRIC_FROM_AUDIO_FILE - END - MENUITEM SEPARATOR - MENUITEM "下载歌词(&L)...", ID_DOWNLOAD_LYRIC - MENUITEM "歌词批量下载(&B)...", ID_LYRIC_BATCH_DOWNLOAD - END - POPUP "视图(&V)" - BEGIN - MENUITEM "显示播放列表(&L)", ID_SHOW_PLAYLIST - MENUITEM "浮动播放列表(&P)", ID_FLOAT_PLAYLIST - MENUITEM "使用系统标准标题栏(&B)", ID_USE_STANDARD_TITLE_BAR - MENUITEM "显示菜单栏(&N)", ID_SHOW_MENU_BAR - MENUITEM "总是显示状态栏(&S)", ID_ALWAYS_SHOW_STATUS_BAR - MENUITEM "总是置顶(&T)", ID_ALWAYS_ON_TOP - MENUITEM SEPARATOR - MENUITEM "迷你模式(&M)", ID_MINI_MODE - MENUITEM "全屏显示(&F)", ID_FULL_SCREEN - MENUITEM SEPARATOR - MENUITEM "深色模式(&D)", ID_DARK_MODE - POPUP "切换界面" - BEGIN - MENUITEM "切换界面(U)", ID_SWITCH_UI - END - END - POPUP "工具(&T)" - BEGIN - MENUITEM "媒体库(&M)...", ID_SET_PATH - MENUITEM "查找歌曲(&F)...", ID_FIND - MENUITEM "打开文件位置(&B)", ID_EXPLORE_PATH - MENUITEM "曲目信息(&I)...", ID_SONG_INFO - MENUITEM "音效设定(&E)...", ID_EQUALIZER - MENUITEM "转换格式(&C)...", ID_FORMAT_CONVERT1 - MENUITEM "在线查看(&L)", ID_CURRENT_EXPLORE_ONLINE - MENUITEM SEPARATOR - MENUITEM "重新初始化播放器(&N)", ID_RE_INI_BASS - POPUP "创建快捷方式" - BEGIN - MENUITEM "创建桌面快捷方式(&D)", ID_CREATE_DESKTOP_SHORTCUT - MENUITEM "创建播放控制快捷方式(&S)", ID_CREATE_PLAY_SHORTCUT - MENUITEM "创建迷你模式快捷方式(&M)", ID_CREATE_MINI_MODE_SHORT_CUT - END - MENUITEM SEPARATOR - POPUP "专辑封面(&A)" - BEGIN - MENUITEM "下载专辑封面(&D)...", ID_DOWNLOAD_ALBUM_COVER - MENUITEM "专辑封面另存为(&S)...", ID_ALBUM_COVER_SAVE_AS - MENUITEM "删除专辑封面(&E)", ID_DELETE_ALBUM_COVER - MENUITEM "专辑封面详情(&C)...", ID_ALBUM_COVER_INFO - END - POPUP "删除正在播放的曲目" - BEGIN - MENUITEM "从播放列表删除(&P)", ID_REMOVE_CURRENT_FROM_PLAYLIST - MENUITEM "从磁盘删除(&D)", ID_DELETE_CURRENT_FROM_DISK - END - MENUITEM SEPARATOR - MENUITEM "播放时间统计(&S)...", ID_LISTEN_STATISTICS - MENUITEM "文件关联(R)...", ID_TOOL_FILE_RELATE - MENUITEM "选项(&O)...", ID_OPTION_SETTINGS - END - POPUP "帮助(&H)" - BEGIN - MENUITEM "帮助(&H)\tF1", ID_HELP - MENUITEM "在线帮助(&O)", ID_ONLINE_HELP - MENUITEM "常见问题(&F)", 33390 - MENUITEM "自定义界面(&U)", ID_HELP_CUSTOM_UI - MENUITEM "更新日志(&L)", ID_HELP_UPDATE_LOG - MENUITEM "支持的格式(&F)", ID_SUPPORTED_FORMAT - MENUITEM SEPARATOR - MENUITEM "关于(&A)...", ID_APP_ABOUT - END -END - -IDR_POPUP_MENU MENU -BEGIN - POPUP "菜单" - BEGIN - MENUITEM "播放(&P)", ID_PLAY_ITEM - MENUITEM "下一首播放(&N)", ID_PLAY_AS_NEXT - MENUITEM SEPARATOR - MENUITEM "在线查看(&O)", ID_EXPLORE_ONLINE - MENUITEM "转换格式(&F)...", ID_FORMAT_CONVERT - POPUP "分级(&A)" - BEGIN - MENUITEM "1 星(1)", ID_RATING_1 - MENUITEM "2 星(2)", ID_RATING_2 - MENUITEM "3 星(3)", ID_RATING_3 - MENUITEM "4 星(4)", ID_RATING_4 - MENUITEM "5 星(5)", ID_RATING_5 - MENUITEM SEPARATOR - MENUITEM "未分级(&U)", ID_RATING_NONE - END - MENUITEM SEPARATOR - MENUITEM "重新载入播放列表(&R)", ID_RELOAD_PLAYLIST - MENUITEM SEPARATOR - MENUITEM "从列表中删除(&L)", ID_REMOVE_FROM_PLAYLIST - MENUITEM "从磁盘删除(&D)", ID_DELETE_FROM_DISK - MENUITEM SEPARATOR - POPUP "添加到播放列表(&T)" - BEGIN - MENUITEM "新建播放列表(&N)...", ID_ADD_TO_NEW_PLAYLIST - MENUITEM SEPARATOR - MENUITEM "默认", ID_ADD_TO_DEFAULT_PLAYLIST - MENUITEM "我喜欢的音乐", ID_ADD_TO_MY_FAVOURITE - END - MENUITEM "复制文件到(&C)...", ID_COPY_FILE_TO - MENUITEM "移动文件到(&M)...", ID_MOVE_FILE_TO - MENUITEM SEPARATOR - MENUITEM "上移(&U)", ID_MOVE_PLAYLIST_ITEM_UP - MENUITEM "下移(&W)", ID_MOVE_PLAYLIST_ITEM_DOWN - MENUITEM SEPARATOR - MENUITEM "查看艺术家(&I)...", ID_PLAYLIST_VIEW_ARTIST - MENUITEM "查看唱片集(&V)...", ID_PLAYLIST_VIEW_ALBUM - MENUITEM SEPARATOR - MENUITEM "重命名(&E)...", ID_RENAME - MENUITEM "打开文件位置(&B)", ID_EXPLORE_TRACK - MENUITEM "属性(&Y)...", ID_ITEM_PROPERTY - END -END - -IDR_MINI_MODE_MENU MENU -BEGIN - POPUP "菜单" - BEGIN - MENUITEM "曲目信息(&I)...", ID_SONG_INFO - POPUP "循环模式(&M)" - BEGIN - MENUITEM "顺序播放", ID_PLAY_ORDER - MENUITEM "无序播放", ID_PLAY_SHUFFLE - MENUITEM "随机播放", ID_PLAY_RANDOM - MENUITEM "列表循环", ID_LOOP_PLAYLIST - MENUITEM "单曲循环", ID_LOOP_TRACK - MENUITEM "单曲播放", ID_PLAY_TRACK - END - POPUP "添加到播放列表(&T)" - BEGIN - MENUITEM "新建播放列表(&N)...", ID_ADD_TO_NEW_PLAYLIST - MENUITEM SEPARATOR - MENUITEM "默认", ID_ADD_TO_DEFAULT_PLAYLIST - MENUITEM "我喜欢的音乐", ID_ADD_TO_MY_FAVOURITE - END - MENUITEM SEPARATOR - MENUITEM "下载歌词(&L)...", ID_DOWNLOAD_LYRIC - MENUITEM "下载专辑封面(&D)...", ID_DOWNLOAD_ALBUM_COVER - MENUITEM SEPARATOR - MENUITEM "添加到我喜欢的音乐(&A)", ID_ADD_REMOVE_FROM_FAVOURITE - MENUITEM SEPARATOR - MENUITEM "媒体库(&T)...", ID_SET_PATH - MENUITEM "查找歌曲(&F)...", ID_FIND - MENUITEM "打开文件位置(&B)", ID_EXPLORE_PATH - MENUITEM "音效设定(&E)...", ID_EQUALIZER - MENUITEM "选项(&O)...", ID_OPTION_SETTINGS - MENUITEM SEPARATOR - MENUITEM "显示播放列表(&P)\tCtrl+L", ID_SHOW_PLAY_LIST - MENUITEM "总是置顶(&Y)", ID_MINI_MODE_ALWAYS_ON_TOP - POPUP "切换界面" - BEGIN - MENUITEM "默认界面(&D)", ID_MINIMODE_UI_DEFAULT - END - MENUITEM SEPARATOR - MENUITEM "最小化(&N)", ID_MINI_MIDE_MINIMIZE - MENUITEM "返回正常模式(&R)\tEsc", IDOK - MENUITEM "退出(&X)", ID_MINI_MODE_EXIT - END -END - -IDR_LYRIC_POPUP_MENU MENU -BEGIN - POPUP "菜单" - BEGIN - MENUITEM "重新载入歌词(&R)", ID_RELOAD_LYRIC - MENUITEM "复制当前歌词(&C)", ID_COPY_CURRENT_LYRIC - MENUITEM "复制所有歌词(&A)", ID_COPY_ALL_LYRIC - MENUITEM "编辑歌词(&E)...", ID_EDIT_LYRIC - POPUP "繁简转换(&V)" - BEGIN - MENUITEM "转换为简体中文(&S)", ID_TRANSLATE_TO_SIMPLIFIED_CHINESE - MENUITEM "转换为繁体中文(&T)", ID_TRANSLATE_TO_TRANDITIONAL_CHINESE - END - MENUITEM SEPARATOR - MENUITEM "显示歌词翻译(&N)", ID_SHOW_LYRIC_TRANSLATE - MENUITEM "显示桌面歌词(&K)", ID_SHOW_DESKTOP_LYRIC - MENUITEM SEPARATOR - MENUITEM "歌词提前0.5秒", ID_LYRIC_FORWARD - MENUITEM "歌词延后0.5秒", ID_LYRIC_DELAY - MENUITEM "保存歌词更改(&S)", ID_SAVE_MODIFIED_LYRIC - MENUITEM SEPARATOR - MENUITEM "关联本地歌词(&T)...", ID_RELATE_LOCAL_LYRIC - MENUITEM "删除歌词(&D)", ID_DELETE_LYRIC - MENUITEM "撤消歌词关联(&U)", ID_UNLINK_LYRIC - MENUITEM "打开歌词文件位置(&W)", ID_BROWSE_LYRIC - POPUP "内嵌歌词" - BEGIN - MENUITEM "嵌入到音频文件(&E)", ID_EMBED_LYRIC_TO_AUDIO_FILE - MENUITEM "从音频文件中删除(&D)", ID_DELETE_LYRIC_FROM_AUDIO_FILE - END - MENUITEM SEPARATOR - MENUITEM "下载歌词(&L)...", ID_DOWNLOAD_LYRIC - MENUITEM "歌词批量下载(&B)...", ID_LYRIC_BATCH_DOWNLOAD - MENUITEM SEPARATOR - POPUP "切换界面" - BEGIN - MENUITEM "切换界面(U)", ID_SWITCH_UI - END - MENUITEM "选项(&O)...", ID_OPTION_SETTINGS - END -END - -IDR_LYRIC_EDIT_MENU MENU -BEGIN - POPUP "文件(&F)" - BEGIN - MENUITEM "打开(&O)...", ID_LYRIC_OPEN - MENUITEM "保存(&S)\tCtrl+S", ID_LYRIC_SAVE - MENUITEM "另存为(&A)...", ID_LYRIC_SAVE_AS - MENUITEM SEPARATOR - MENUITEM "退出(&X)", IDCANCEL - END - POPUP "编辑(&E)" - BEGIN - MENUITEM "插入时间标签(&I)\tF8", ID_LYRIC_INSERT_TAG - MENUITEM "替换时间标签(&R)\tF9", ID_LYRIC_REPLACE_TAG - MENUITEM "删除时间标签(&D)\tCtrl+Del", ID_LYRIC_DELETE_TAG - MENUITEM SEPARATOR - MENUITEM "查找(&F)...\tCtrl+F", ID_LYRIC_FIND - MENUITEM "替换(&R)...\tCtrl+H", ID_LYRIC_REPLACE - MENUITEM "查找下一个(&N)\tF3", ID_FIND_NEXT - MENUITEM SEPARATOR - POPUP "繁简转换(&C)" - BEGIN - MENUITEM "转换为简体中文(&S)", ID_LE_TRANSLATE_TO_SIMPLIFIED_CHINESE - MENUITEM "转换为繁体中文(&T)", ID_LE_TRANSLATE_TO_TRANDITIONAL_CHINESE - END - MENUITEM SEPARATOR - MENUITEM "合并时间标签相同的歌词(&M)", ID_LRYIC_MERGE_SAME_TIME_TAG - MENUITEM "交换歌词原文和翻译(&S)", ID_LYRIC_SWAP_TEXT_AND_TRANSLATION - POPUP "时间标签错位" - BEGIN - MENUITEM "时间标签提前一句(&F)", ID_LYRIC_TIME_TAG_FORWARD - MENUITEM "时间标签延后一句(&D)", ID_LYRIC_TIME_TAG_DELAY - END - END - POPUP "播放控制(&P)" - BEGIN - MENUITEM "播放/暂停(&P)\tCtrl+P", ID_PLAY_PAUSE - MENUITEM "快退(&R)\tCtrl+←", ID_REW - MENUITEM "快进(&F)\tCtrl+→", ID_FF - MENUITEM "定位到当前行(&G)\tCtrl+G", ID_SEEK_TO_CUR_LINE - END -END - -IDR_LYRIC_DOWNLOAD_MENU MENU -BEGIN - POPUP "菜单" - BEGIN - MENUITEM "下载(&D)", ID_LD_LYRIC_DOWNLOAD - MENUITEM "预览(&P)", ID_LD_PREVIEW - MENUITEM "另存为(&A)...", ID_LD_LYRIC_SAVEAS - MENUITEM SEPARATOR - MENUITEM "复制歌曲标题(&T)", ID_LD_COPY_TITLE - MENUITEM "复制艺术家(&S)", ID_LD_COPY_ARTIST - MENUITEM "复制唱片集(&B)", ID_LD_COPY_ALBUM - MENUITEM "复制歌曲I&D", ID_LD_COPY_ID - MENUITEM SEPARATOR - MENUITEM "关联此项(&R)", 33197 - MENUITEM "在线查看(&L)", ID_LD_VIEW_ONLINE - END -END - -IDR_FIND_POPUP_MENU MENU -BEGIN - POPUP "菜单" - BEGIN - MENUITEM "播放(&P)", ID_FD_PLAY - MENUITEM SEPARATOR - MENUITEM "复制文本(&C)", ID_FD_COPY_TEXT - MENUITEM "打开文件位置(&L)", ID_FD_OPEN_FILE_LOCATION - END -END - -IDR_MAIN_POPUP_MENU MENU -BEGIN - POPUP "菜单" - BEGIN - MENUITEM "曲目信息(&I)...", ID_SONG_INFO - POPUP "循环模式(&M)" - BEGIN - MENUITEM "顺序播放", ID_PLAY_ORDER - MENUITEM "无序播放", ID_PLAY_SHUFFLE - MENUITEM "随机播放", ID_PLAY_RANDOM - MENUITEM "列表循环", ID_LOOP_PLAYLIST - MENUITEM "单曲循环", ID_LOOP_TRACK - MENUITEM "单曲播放", ID_PLAY_TRACK - END - POPUP "添加到播放列表(&T)" - BEGIN - MENUITEM "新建播放列表(&N)...", ID_ADD_TO_NEW_PLAYLIST - MENUITEM SEPARATOR - MENUITEM "默认", ID_ADD_TO_DEFAULT_PLAYLIST - MENUITEM "我喜欢的音乐", ID_ADD_TO_MY_FAVOURITE - END - POPUP "分级(&A)" - BEGIN - MENUITEM "1 星(1)", ID_RATING_1 - MENUITEM "2 星(2)", ID_RATING_2 - MENUITEM "3 星(3)", ID_RATING_3 - MENUITEM "4 星(4)", ID_RATING_4 - MENUITEM "5 星(5)", ID_RATING_5 - MENUITEM SEPARATOR - MENUITEM "未分级(&U)", ID_RATING_NONE - END - MENUITEM SEPARATOR - MENUITEM "媒体库(&T)...", ID_SET_PATH - MENUITEM "查找歌曲(&F)...", ID_FIND - MENUITEM "打开文件位置(&X)", ID_EXPLORE_PATH - MENUITEM "音效设定(&E)...", ID_EQUALIZER - MENUITEM "在线查看(&L)", ID_CURRENT_EXPLORE_ONLINE - MENUITEM SEPARATOR - MENUITEM "下载专辑封面(&A)...", ID_DOWNLOAD_ALBUM_COVER - MENUITEM "专辑封面另存为(&S)...", ID_ALBUM_COVER_SAVE_AS - MENUITEM "删除专辑封面(&D)", ID_DELETE_ALBUM_COVER - MENUITEM "总是使用外部专辑封面(&N)", ID_ALWAYS_USE_EXTERNAL_ALBUM_COVER - MENUITEM "专辑封面详情(&C)...", ID_ALBUM_COVER_INFO - MENUITEM SEPARATOR - MENUITEM "查看艺术家(&R)...", ID_VIEW_ARTIST - MENUITEM "查看唱片集(&B)...", ID_VIEW_ALBUM - MENUITEM SEPARATOR - POPUP "切换界面" - BEGIN - MENUITEM "切换界面(U)", ID_SWITCH_UI - END - MENUITEM "选项(&O)...", ID_OPTION_SETTINGS - END -END - -IDR_SET_PATH_POPUP_MENU MENU -BEGIN - POPUP "菜单" - BEGIN - MENUITEM "播放文件夹(&P)", ID_PLAY_PATH - MENUITEM "从列表中删除(&D)", ID_DELETE_PATH - MENUITEM "打开文件夹位置(&B)", ID_BROWSE_PATH - MENUITEM "包含子文件夹(&S)", ID_CONTAIN_SUB_FOLDER - MENUITEM SEPARATOR - MENUITEM "清除无效文件夹(&C)", ID_CLEAR_INVALID_PATH - END -END - -IDR_FORMAT_CONVERT_POPUP_MENU MENU -BEGIN - POPUP "菜单" - BEGIN - MENUITEM "添加文件(&A)...", ID_ADD_FILE - MENUITEM "清空列表(&C)", ID_CLEAR_LIST - MENUITEM SEPARATOR - MENUITEM "编辑标签信息(&E)...", ID_EDIT_TAG_INFO - MENUITEM "删除&D)", ID_DELETE_SELECT - MENUITEM SEPARATOR - MENUITEM "上移(&U)\tCtrl+↑", ID_MOVE_UP - MENUITEM "下移(&D)\tCtrl+↓", ID_MOVE_DOWN - END -END - -IDR_NOTIFY_MENU MENU -BEGIN - POPUP "菜单" - BEGIN - MENUITEM "播放/暂停(&P)", ID_PLAY_PAUSE - MENUITEM "上一曲(&V)", ID_PREVIOUS - MENUITEM "下一曲(&N)", ID_NEXT - POPUP "循环模式(&M)" - BEGIN - MENUITEM "顺序播放", ID_PLAY_ORDER - MENUITEM "无序播放", ID_PLAY_SHUFFLE - MENUITEM "随机播放", ID_PLAY_RANDOM - MENUITEM "列表循环", ID_LOOP_PLAYLIST - MENUITEM "单曲循环", ID_LOOP_TRACK - MENUITEM "单曲播放", ID_PLAY_TRACK - END - MENUITEM "迷你模式/还原(&R)", ID_MINIMODE_RESTORE - MENUITEM "显示桌面歌词(&S)", ID_SHOW_DESKTOP_LYRIC - MENUITEM "锁定桌面歌词(&L)", ID_LOCK_DESKTOP_LRYIC - MENUITEM SEPARATOR - MENUITEM "选项(&O)...", ID_OPTION_SETTINGS - MENUITEM "退出(&X)", ID_MENU_EXIT - END -END - -IDR_PLAYLIST_BTN_MENU MENU -BEGIN - POPUP "菜单" - BEGIN - MENUITEM "停靠的播放列表", ID_DOCKED_PLAYLIST - MENUITEM "浮动的播放列表", ID_FLOATED_PLAYLIST - END -END - -IDR_SELETE_PLAYLIST_POPUP_MENU MENU -BEGIN - POPUP "菜单" - BEGIN - MENUITEM "播放(&P)", ID_PLAY_PLAYLIST - MENUITEM "重命名(&R)...", ID_RENAME_PLAYLIST - MENUITEM "删除(&D)", ID_DELETE_PLAYLIST - MENUITEM "保存为新播放列表(&S)...", ID_SAVE_AS_NEW_PLAYLIST - MENUITEM "另存为(&A)...", ID_PLAYLIST_SAVE_AS - MENUITEM SEPARATOR - MENUITEM "打开播放列表文件位置(&B)", ID_PLAYLIST_BROWSE_FILE - MENUITEM "修复错误的文件路径(&F)", ID_PLAYLIST_FIX_PATH_ERROR - MENUITEM SEPARATOR - MENUITEM "新建播放列表(&N)...", ID_NEW_PLAYLIST - END -END - -IDR_DESKTOP_LYRIC_POPUP_MENU MENU -BEGIN - POPUP "菜单" - BEGIN - MENUITEM "播放/暂停(&P)", ID_PLAY_PAUSE - MENUITEM "停止(&S)", ID_STOP - MENUITEM "上一曲(&V)", ID_PREVIOUS - MENUITEM "下一曲(&N)", ID_NEXT - POPUP "循环模式(&M)" - BEGIN - MENUITEM "顺序播放", ID_PLAY_ORDER - MENUITEM "无序播放", ID_PLAY_SHUFFLE - MENUITEM "随机播放", ID_PLAY_RANDOM - MENUITEM "列表循环", ID_LOOP_PLAYLIST - MENUITEM "单曲循环", ID_LOOP_TRACK - MENUITEM "单曲播放", ID_PLAY_TRACK - END - MENUITEM SEPARATOR - MENUITEM "显示主窗口(&W)", 33150 - MENUITEM "歌词双行显示(&D)", ID_LYRIC_DISPLAYED_DOUBLE_LINE - MENUITEM "歌词背景穿透(&B)", ID_LYRIC_BACKGROUND_PENETRATE - MENUITEM "锁定桌面歌词(&L)", ID_LOCK_DESKTOP_LRYIC - POPUP "预设方案" - BEGIN - MENUITEM "预设1", ID_LYRIC_DEFAULT_STYLE1 - MENUITEM "预设2", ID_LYRIC_DEFAULT_STYLE2 - MENUITEM "预设3", ID_LYRIC_DEFAULT_STYLE3 - END - MENUITEM "选项(&O)...", ID_OPTION_SETTINGS - MENUITEM "关闭桌面歌词(&C)", ID_CLOSE_DESKTOP_LYRIC - END -END - -IDR_LRYIC_DEFAULT_STYLE_MENU MENU -BEGIN - POPUP "1" - BEGIN - MENUITEM "预设1", ID_LYRIC_DEFAULT_STYLE1 - MENUITEM "预设2", ID_LYRIC_DEFAULT_STYLE2 - MENUITEM "预设3", ID_LYRIC_DEFAULT_STYLE3 - END - POPUP "2" - BEGIN - MENUITEM "预设1", ID_LYRIC_DEFAULT_STYLE1 - MENUITEM "预设2", ID_LYRIC_DEFAULT_STYLE2 - MENUITEM "预设3", ID_LYRIC_DEFAULT_STYLE3 - MENUITEM SEPARATOR - POPUP "修改预设方案" - BEGIN - MENUITEM "预设1", ID_LYRIC_DEFAULT_STYLE1_MODIFY - MENUITEM "预设2", ID_LYRIC_DEFAULT_STYLE2_MODIFY - MENUITEM "预设3", ID_LYRIC_DEFAULT_STYLE3_MODIFY - MENUITEM SEPARATOR - MENUITEM "恢复默认", ID_RESTORE_DEFAULT_STYLE - END - END -END - -IDR_PLAYLIST_TOOLBAR_MENU MENU -BEGIN - POPUP "添加" - BEGIN - MENUITEM "添加文件(&A)...", ID_PLAYLIST_ADD_FILE - MENUITEM "添加文件夹(&F)...", ID_PLAYLIST_ADD_FOLDER - MENUITEM "添加&URL...", ID_PLAYLIST_ADD_URL - END - POPUP "删除" - BEGIN - MENUITEM "从列表中删除(&L)", ID_REMOVE_FROM_PLAYLIST - MENUITEM "从磁盘删除(&D)", ID_DELETE_FROM_DISK - MENUITEM SEPARATOR - MENUITEM "清空播放列表(&E)", ID_EMPTY_PLAYLIST - MENUITEM "删除相同项(&S)", ID_REMOVE_SAME_SONGS - MENUITEM "删除无效项(&I)", ID_REMOVE_INVALID_ITEMS - END - POPUP "排序" - BEGIN - MENUITEM "按文件名排序", ID_SORT_BY_FILE - MENUITEM "按路径排序", ID_SORT_BY_PATH - MENUITEM "按标题排序", ID_SORT_BY_TITLE - MENUITEM "按艺术家排序", ID_SORT_BY_ARTIST - MENUITEM "按唱片集排序", ID_SORT_BY_ALBUM - MENUITEM "按音轨序号排序", ID_SORT_BY_TRACK - MENUITEM "按修改时间排序", ID_SORT_BY_MODIFIED_TIME - MENUITEM SEPARATOR - MENUITEM "升序", ID_ACCENDING_ORDER - MENUITEM "降序", ID_DESENDING_ORDER - MENUITEM SEPARATOR - MENUITEM "倒序排列", ID_INVERT_PLAYLIST - END - POPUP "列表" - BEGIN - MENUITEM "重新载入播放列表(&R)", ID_RELOAD_PLAYLIST - MENUITEM "保存为新播放列表(&N)...", ID_SAVE_AS_NEW_PLAYLIST - MENUITEM "当前播放列表另存为(&S)...", ID_SAVE_CURRENT_PLAYLIST_AS - MENUITEM SEPARATOR - MENUITEM "修复错误的文件路径(&F)", ID_PLAYLIST_FIX_PATH_ERROR - POPUP "播放列表显示方式" - BEGIN - MENUITEM "文件名", ID_DISP_FILE_NAME - MENUITEM "标题", ID_DISP_TITLE - MENUITEM "艺术家 - 标题", ID_DISP_ARTIST_TITLE - MENUITEM "标题 - 艺术家", ID_DISP_TITLE_ARTIST - END - MENUITEM "选项(&O)...", ID_PLAYLIST_OPTIONS - END - POPUP "编辑" - BEGIN - POPUP "添加到播放列表(&T)" - BEGIN - MENUITEM "新建播放列表(&N)...", ID_ADD_TO_NEW_PLAYLIST - MENUITEM SEPARATOR - MENUITEM "默认", ID_ADD_TO_DEFAULT_PLAYLIST - MENUITEM "我喜欢的音乐", ID_ADD_TO_MY_FAVOURITE - END - MENUITEM SEPARATOR - MENUITEM "复制文件到(&C)...", ID_COPY_FILE_TO - MENUITEM "移动文件到(&M)...", ID_MOVE_FILE_TO - MENUITEM SEPARATOR - MENUITEM "上移(&U)", ID_MOVE_PLAYLIST_ITEM_UP - MENUITEM "下移(&W)", ID_MOVE_PLAYLIST_ITEM_DOWN - MENUITEM SEPARATOR - MENUITEM "全部选择(&A)", ID_PLAYLIST_SELECT_ALL - MENUITEM "全部取消(&L)", ID_PLAYLIST_SELECT_NONE - MENUITEM "反向选择(&R)", ID_PLAYLIST_SELECT_REVERT - END - POPUP "文件夹" - BEGIN - MENUITEM "打开文件夹(&F)...", ID_FILE_OPEN_FOLDER - MENUITEM "包含子文件夹(&S)", ID_CONTAIN_SUB_FOLDER - END -END - -IDR_MEDIA_LIB_POPUP_MENU MENU -BEGIN - POPUP "左侧菜单" - BEGIN - MENUITEM "播放(&P)", ID_PLAY_ITEM - POPUP "添加到播放列表(&T)" - BEGIN - MENUITEM "新建播放列表(&N)...", ID_ADD_TO_NEW_PLAYLIST - MENUITEM SEPARATOR - MENUITEM "默认", ID_ADD_TO_DEFAULT_PLAYLIST - MENUITEM "我喜欢的音乐", ID_ADD_TO_MY_FAVOURITE - END - MENUITEM "添加到新播放列表并播放(&N)...", ID_ADD_TO_NEW_PALYLIST_AND_PLAY - MENUITEM SEPARATOR - MENUITEM "复制文本(&C)", ID_COPY_TEXT - END - POPUP "右侧菜单" - BEGIN - MENUITEM "播放(&P)", ID_PLAY_ITEM - MENUITEM "下一首播放(&N)", ID_PLAY_AS_NEXT - MENUITEM "在文件夹模式中播放(&D)", ID_PLAY_ITEM_IN_FOLDER_MODE - MENUITEM SEPARATOR - POPUP "添加到播放列表(&T)" - BEGIN - MENUITEM "新建播放列表(&N)...", ID_ADD_TO_NEW_PLAYLIST - MENUITEM SEPARATOR - MENUITEM "默认", ID_ADD_TO_DEFAULT_PLAYLIST - MENUITEM "我喜欢的音乐", ID_ADD_TO_MY_FAVOURITE - END - MENUITEM "添加到新播放列表并播放(&N)...", ID_ADD_TO_NEW_PALYLIST_AND_PLAY - MENUITEM SEPARATOR - MENUITEM "在线查看(&O)", ID_EXPLORE_ONLINE - MENUITEM "转换格式(&F)...", ID_FORMAT_CONVERT - MENUITEM "打开文件位置(&B)", ID_EXPLORE_TRACK - MENUITEM "从磁盘删除(&D)", ID_DELETE_FROM_DISK - MENUITEM "属性(&Y)...", ID_ITEM_PROPERTY - MENUITEM SEPARATOR - MENUITEM "复制文本(&C)", ID_COPY_TEXT - END -END - -IDR_PROPERTY_COVER_MENU MENU -BEGIN - POPUP "1" - BEGIN - MENUITEM "浏览(&B)...", ID_COVER_BROWSE - MENUITEM "删除(&D)", ID_COVER_DELETE - MENUITEM "另存为(&S)...", ID_COVER_SAVE_AS - MENUITEM "压缩尺寸(&C)", 33387 - END -END - -IDR_CONTROL_MENU MENU -BEGIN - POPUP "list ctrl" - BEGIN - MENUITEM "复制文本(&C)", ID_COPY_TEXT - END -END - -IDR_PROPERTY_MENU MENU -BEGIN - POPUP "1" - BEGIN - MENUITEM "复制文本(&C)", ID_COPY_TEXT - MENUITEM "复制全部(&A)", ID_COPY_ALL_TEXT - END -END - - -///////////////////////////////////////////////////////////////////////////// -// -// TEXT -// - -IDR_TEXT1 TEXT "Help.txt" - -IDR_ACKNOWLEDGEMENT TEXT "res\\Acknowledgement.txt" - -IDR_COMPILE_TIME TEXT "compile_time.txt" - - -///////////////////////////////////////////////////////////////////////////// -// -// Bitmap -// - -IDB_CORTANA_BLACK BITMAP "res\\Cortana_black.bmp" - -IDB_CORTANA_WHITE BITMAP "res\\Cortana_white.bmp" - -IDR_LYRIC_EDIT_TOOLBAR BITMAP "res\\toolbar1.bmp" - -IDB_DONATE BITMAP "res\\donate.bmp" - -IDB_DONATE_WECHAT BITMAP "res\\donate_wechat.bmp" - -IDB_NOTIFY_ICON_PREVIEW BITMAP "res\\notify_preview.bmp" - -IDB_NOTIFY_ICON_PREVIEW_LIGHT BITMAP "res\\notify_preview_light.bmp" - - -///////////////////////////////////////////////////////////////////////////// -// -// Toolbar -// - -IDR_LYRIC_EDIT_TOOLBAR TOOLBAR 16, 15 -BEGIN - BUTTON ID_LYRIC_INSERT_TAG - BUTTON ID_LYRIC_REPLACE_TAG - BUTTON ID_LYRIC_DELETE_TAG - BUTTON ID_LYRIC_SAVE - SEPARATOR - BUTTON ID_PLAY_PAUSE - BUTTON ID_REW - BUTTON ID_FF - BUTTON ID_SEEK_TO_CUR_LINE - SEPARATOR - BUTTON ID_LYRIC_FIND - BUTTON ID_LYRIC_REPLACE -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Cursor -// - -IDC_DRAG_CURSOR CURSOR "res\\drag.cur" - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog Info -// - -IDD_MUSICPLAYER2_DIALOG DLGINIT -BEGIN - IDC_SEARCH_EDIT, 0x37c, 42, 0 -0x4d3c, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, 0x4d5f, 0x646f, -0x3e65, 0x3c33, 0x4d2f, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, -0x4d5f, 0x646f, 0x3e65, - IDC_PATH_EDIT, 0x37c, 42, 0 -0x4d3c, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, 0x4d5f, 0x646f, -0x3e65, 0x3c31, 0x4d2f, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, -0x4d5f, 0x646f, 0x3e65, - 0 -END - -IDD_SET_PATH_DIALOG DLGINIT -BEGIN - IDC_SEARCH_EDIT, 0x37c, 42, 0 -0x4d3c, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, 0x4d5f, 0x646f, -0x3e65, 0x3c33, 0x4d2f, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, -0x4d5f, 0x646f, 0x3e65, - 0 -END - -IDD_SELECT_PLAYLIST_DIALOG DLGINIT -BEGIN - IDC_SEARCH_EDIT, 0x37c, 42, 0 -0x4d3c, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, 0x4d5f, 0x646f, -0x3e65, 0x3c33, 0x4d2f, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, -0x4d5f, 0x646f, 0x3e65, - 0 -END - -IDD_TEST_DIALOG DLGINIT -BEGIN - IDC_MFCEDITBROWSE1, 0x37c, 42, 0 -0x4d3c, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, 0x4d5f, 0x646f, -0x3e65, 0x3c31, 0x4d2f, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, -0x4d5f, 0x646f, 0x3e65, - 0 -END - -IDD_LYRIC_SETTING_DIALOG DLGINIT -BEGIN - IDC_LYRIC_PATH_EDIT, 0x37c, 42, 0 -0x4d3c, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, 0x4d5f, 0x646f, -0x3e65, 0x3c31, 0x4d2f, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, -0x4d5f, 0x646f, 0x3e65, - 0 -END - -IDD_DATA_SETTINGS_DIALOG DLGINIT -BEGIN - IDC_SF2_PATH_EDIT, 0x37c, 42, 0 -0x4d3c, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, 0x4d5f, 0x646f, -0x3e65, 0x3c31, 0x4d2f, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, -0x4d5f, 0x646f, 0x3e65, - 0 -END - -IDD_FORMAT_CONVERT_DIALOG DLGINIT -BEGIN - IDC_OUT_DIR_EDIT, 0x37c, 42, 0 -0x4d3c, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, 0x4d5f, 0x646f, -0x3e65, 0x3c31, 0x4d2f, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, -0x4d5f, 0x646f, 0x3e65, - IDC_OUT_NAME_EDIT, 0x37c, 42, 0 -0x4d3c, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, 0x4d5f, 0x646f, -0x3e65, 0x3c33, 0x4d2f, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, -0x4d5f, 0x646f, 0x3e65, - 0 -END - -IDD_MEDIA_CLASSIFY_DIALOG DLGINIT -BEGIN - IDC_MFCEDITBROWSE1, 0x37c, 42, 0 -0x4d3c, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, 0x4d5f, 0x646f, -0x3e65, 0x3c31, 0x4d2f, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, -0x4d5f, 0x646f, 0x3e65, - 0 -END - -IDD_FOLDER_EXPLORE_DIALOG DLGINIT -BEGIN - IDC_MFCEDITBROWSE1, 0x37c, 42, 0 -0x4d3c, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, 0x4d5f, 0x646f, -0x3e65, 0x3c31, 0x4d2f, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, -0x4d5f, 0x646f, 0x3e65, - 0 -END - -IDD_ALL_MEDIA_DIALOG DLGINIT -BEGIN - IDC_SEARCH_EDIT, 0x37c, 42, 0 -0x4d3c, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, 0x4d5f, 0x646f, -0x3e65, 0x3c31, 0x4d2f, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, -0x4d5f, 0x646f, 0x3e65, - 0 -END - -IDD_APPEREANCE_SETTING_DLG DLGINIT -BEGIN - IDC_DEFAULT_BACKGROUND_PATH_EDIT, 0x37c, 42, 0 -0x4d3c, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, 0x4d5f, 0x646f, -0x3e65, 0x3c31, 0x4d2f, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, -0x4d5f, 0x646f, 0x3e65, - IDC_DEFAULT_COVER_NAME_EDIT, 0x37c, 42, 0 -0x4d3c, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, 0x4d5f, 0x646f, -0x3e65, 0x3c33, 0x4d2f, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, -0x4d5f, 0x646f, 0x3e65, - IDC_ALBUM_COVER_PATH_EDIT, 0x37c, 42, 0 -0x4d3c, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, 0x4d5f, 0x646f, -0x3e65, 0x3c32, 0x4d2f, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, -0x4d5f, 0x646f, 0x3e65, - 0 -END - -IDD_ADD_TO_PLAYLIST_DIALOG DLGINIT -BEGIN - IDC_SEARCH_EDIT, 0x37c, 42, 0 -0x4d3c, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, 0x4d5f, 0x646f, -0x3e65, 0x3c33, 0x4d2f, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, -0x4d5f, 0x646f, 0x3e65, - 0 -END - -IDD_MEDIA_LIB_SETTING_DIALOG DLGINIT -BEGIN - IDC_ARTIST_SPLIT_EXT_EDIT, 0x37c, 42, 0 -0x4d3c, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, 0x4d5f, 0x646f, -0x3e65, 0x3c33, 0x4d2f, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, -0x4d5f, 0x646f, 0x3e65, - 0 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// PNG -// - -IDB_DEFAULT_ALBUM_COVER PNG "res\\黑色胶片.png" - -IDB_DEFAULT_ALBUM_COVER_NOT_PLAYED PNG "res\\黑色胶片_not_played.png" - - -///////////////////////////////////////////////////////////////////////////// -// -// Accelerator -// - -IDR_ACCELERATOR1 ACCELERATORS -BEGIN - "R", ID_AB_REPEAT, VIRTKEY, CONTROL, NOINVERT - "W", ID_ALBUM_COVER_INFO, VIRTKEY, CONTROL, NOINVERT - "T", ID_ALWAYS_ON_TOP, VIRTKEY, SHIFT, CONTROL, NOINVERT - "D", ID_DARK_MODE, VIRTKEY, SHIFT, CONTROL, NOINVERT - VK_DELETE, ID_DELETE_CURRENT_FROM_DISK, VIRTKEY, SHIFT, CONTROL, NOINVERT - VK_DELETE, ID_DELETE_FROM_DISK, VIRTKEY, SHIFT, NOINVERT - "E", ID_EDIT_LYRIC, VIRTKEY, SHIFT, CONTROL, NOINVERT - "E", ID_EQUALIZER, VIRTKEY, CONTROL, NOINVERT - "B", ID_EXPLORE_PATH, VIRTKEY, CONTROL, NOINVERT - VK_RIGHT, ID_FF, VIRTKEY, NOINVERT - "O", ID_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT - "D", ID_FILE_OPEN_FOLDER, VIRTKEY, CONTROL, NOINVERT - "F", ID_FIND, VIRTKEY, CONTROL, NOINVERT - "K", ID_FLOAT_PLAYLIST, VIRTKEY, CONTROL, NOINVERT - VK_F11, ID_FULL_SCREEN, VIRTKEY, NOINVERT - "G", ID_LOCATE_TO_CURRENT, VIRTKEY, CONTROL, NOINVERT - VK_NEXT, ID_LYRIC_DELAY, VIRTKEY, CONTROL, NOINVERT - VK_PRIOR, ID_LYRIC_FORWARD, VIRTKEY, CONTROL, NOINVERT - "M", ID_MINI_MODE, VIRTKEY, CONTROL, NOINVERT - VK_DOWN, ID_MOVE_PLAYLIST_ITEM_DOWN, VIRTKEY, CONTROL, NOINVERT - VK_UP, ID_MOVE_PLAYLIST_ITEM_UP, VIRTKEY, CONTROL, NOINVERT - "N", ID_NEXT, VIRTKEY, NOINVERT - "N", ID_NEXT_AB_REPEAT, VIRTKEY, SHIFT, CONTROL, NOINVERT - "I", ID_OPTION_SETTINGS, VIRTKEY, CONTROL, NOINVERT - VK_RETURN, ID_ORIGINAL_SPEED, VIRTKEY, CONTROL, NOINVERT - "P", ID_PLAY_PAUSE, VIRTKEY, NOINVERT - VK_SPACE, ID_PLAY_PAUSE, VIRTKEY, NOINVERT - "V", ID_PREVIOUS, VIRTKEY, NOINVERT - "Q", ID_RE_INI_BASS, VIRTKEY, CONTROL, NOINVERT - VK_DELETE, ID_REMOVE_CURRENT_FROM_PLAYLIST, VIRTKEY, CONTROL, NOINVERT - VK_DELETE, ID_REMOVE_FROM_PLAYLIST, VIRTKEY, NOINVERT - "M", ID_REPEAT_MODE, VIRTKEY, NOINVERT - "C", ID_RESET_AB_REPEAT, VIRTKEY, SHIFT, CONTROL, NOINVERT - VK_LEFT, ID_REW, VIRTKEY, NOINVERT - "S", ID_SAVE_MODIFIED_LYRIC, VIRTKEY, CONTROL, NOINVERT - "A", ID_SET_A_POINT, VIRTKEY, SHIFT, CONTROL, NOINVERT - "B", ID_SET_B_POINT, VIRTKEY, SHIFT, CONTROL, NOINVERT - "T", ID_SET_PATH, VIRTKEY, CONTROL, NOINVERT - "Y", ID_SHOW_DESKTOP_LYRIC, VIRTKEY, CONTROL, NOINVERT - "L", ID_SHOW_PLAYLIST, VIRTKEY, CONTROL, NOINVERT - VK_OEM_MINUS, ID_SLOW_DOWN, VIRTKEY, CONTROL, NOINVERT - "N", ID_SONG_INFO, VIRTKEY, CONTROL, NOINVERT - VK_OEM_PLUS, ID_SPEED_UP, VIRTKEY, CONTROL, NOINVERT - "S", ID_STOP, VIRTKEY, NOINVERT - "U", ID_SWITCH_UI, VIRTKEY, CONTROL, NOINVERT - "1", ID_SWITCH_UI_1, VIRTKEY, CONTROL, NOINVERT - "0", ID_SWITCH_UI_10, VIRTKEY, CONTROL, NOINVERT - "2", ID_SWITCH_UI_2, VIRTKEY, CONTROL, NOINVERT - "3", ID_SWITCH_UI_3, VIRTKEY, CONTROL, NOINVERT - "4", ID_SWITCH_UI_4, VIRTKEY, CONTROL, NOINVERT - "5", ID_SWITCH_UI_5, VIRTKEY, CONTROL, NOINVERT - "6", ID_SWITCH_UI_6, VIRTKEY, CONTROL, NOINVERT - "7", ID_SWITCH_UI_7, VIRTKEY, CONTROL, NOINVERT - "8", ID_SWITCH_UI_8, VIRTKEY, CONTROL, NOINVERT - "9", ID_SWITCH_UI_9, VIRTKEY, CONTROL, NOINVERT - VK_DOWN, ID_VOLUME_DOWN, VIRTKEY, NOINVERT - VK_UP, ID_VOLUME_UP, VIRTKEY, NOINVERT -END - - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE -BEGIN - IDS_ABOUTBOX "关于 MusicPlayer2(&A)..." - IDS_STRING102 "警告:当前选择字体大小过大,可能会导致控制台窗口信息无法完全显示!" - IDS_STRING103 "要保存的内容含有Unicode字符,如果以ANSI格式保存,这些字符将会丢失。如果要保留这些字符,请选择保存为UTF-8格式。确实要保存吗?" - IDS_LYRIC_FOLDER_NOT_EXIST "歌词文件夹不存在,请重新设置歌词文件夹!" - IDS_BASS_VERSION_WARNING - "bass.dll文件版本不匹配,版本为<%1%>.<%2%>,期望的版本为<%3%>.<%4%>。不匹配的版本可能会导致播放异常,仍要继续吗?" - IDS_CHECK_UPDATA_FAILED "检查更新失败,请检查你的网络连接!" - IDS_CHECK_UPDATA_ERROR "检查更新出错,从远程获取到了错误的信息,请联系作者!" - IDS_UPDATE_AVLIABLE "检测到新版本 V<%1%>,是否前往更新?" - IDS_UPDATE_AVLIABLE2 "检测到新版本 V<%1%>,更新内容:\r\n<%2%>\r\n是否前往更新?" - IDS_ALREADY_UPDATED "当前已经是最新版本。" - IDS_RESTART_EXIT "程序已被Windows的RestartManager重启,重启参数:<%1%>,程序已退出。" -END - -STRINGTABLE -BEGIN - IDS_SERIALIZE_ERROR "读取数据文件“<%1%>”时发生了序列化异常,异常类型:CArchiveException,m_cause = <%2%>。可能是数据文件被损坏或版本不匹配造成的。" - IDS_SEND_EMAIL_TO_ATHOUR "向作者发送电子邮件" - IDS_GOTO_GITHUB "转到此项目在GitHub上的页面" - IDS_DONATE_ATHOUR "捐助作者" - IDS_LANGUAGE_CODE "2" - IDS_DEFAULT_FONT "微软雅黑" - IDS_PLAY "播放" - IDS_PAUSE "暂停" - IDS_PREVIOUS "上一曲" - IDS_NEXT "下一曲" - IDS_PLAY2 "播放(&P)" - IDS_PAUSE2 "暂停(&P)" - IDS_CREATE_SHORTCUT_INFO "你可能是第一次运行此程序,是否要在桌面上创建程序的快捷方式?" - IDS_SHORTCUT_CREATED "已经在“<%1%>”路径下创建了程序的快捷方式。" - IDS_SHORTCUT_CREAT_FAILED "快捷方式创建失败!" - IDS_MINI_MODE "迷你模式" -END - -STRINGTABLE -BEGIN - IDS_MINI_MODE2 "迷你模式(&I)" - IDS_SELECT_RENENT_FOLDER "选择最近播放过的文件夹" - IDS_PLAY_TIME "播放时间" - IDS_CLEAR_SEARCH_RESULT "清除搜索结果" - IDS_INPUT_KEY_WORD "键入要搜索的关键词" - IDS_SEARCH_HERE "在此处键入搜索(F)" - IDS_NOW_PLAYING "正在播放" - IDS_CONNOT_FIND_FILE "找不到文件“<%1%>”!可能已经被移动或删除。" - IDS_ALL_SUPPORTED_FORMAT "所有支持的音频格式" - IDS_ALL_FILES "所有文件" - IDS_OPEN_FOLDER_INFO "请选择一个文件夹,文件夹里的所有音频文件都将添加到播放列表。" - IDS_DELETE_FILE_INQUARY "确实要删除选中的 <%1%> 首歌曲吗?" - IDS_CONNOT_DELETE_FILE "无法删除文件!" - IDS_COPY_CLIPBOARD_FAILED "复制到剪贴板失败!" - IDS_ALL_LRYIC_COPIED "已复制全部歌词到剪贴板。" - IDS_DEBUG_MODE "(DEBUG模式)" -END - -STRINGTABLE -BEGIN - IDS_NO_MIDI_SF2_WARNING "你正在播放 MIDI 音乐,但是由于没有正确载入 MIDI 音色库,因此你将听不到任何声音。 请在菜单“工具”——“选项”——“常规设置”的“MIDI 音色库路径”中选择正确的MIDI 音色库路径。 点击“取消”不再提示。" - IDS_SELECT_COPY_TARGET_FOLDER "选择复制的目标文件夹" - IDS_SELECT_MOVE_TARGET_FOLDER "选择移动的目标文件夹" - IDS_DEFAULT_TITLE "<未知标题>" - IDS_DEFAULT_ARTIST "<未知艺术家>" - IDS_DEFAULT_ALBUM "<未知唱片集>" - IDS_DEFAULT_YEAR "<未知年份>" - IDS_DEFAULT_GENRE "<未知流派>" - IDS_DEFAULT_LYRIC_TEXT "……" - IDS_DEFAULT_LYRIC_TEXT_CORTANA "Music …" - IDS_VOLUME "音量" - IDS_PLAY_ERROR "播放出错" - IDS_SEEK_TO_MINUTE_SECOND "定位到%d分%.2d秒" - IDS_SHOW_HIDE_PLAYLIST "显示/隐藏播放列表" - IDS_BACK_TO_NARMAL "返回正常模式" - IDS_EXIT_PROGRAM "退出程序" -END - -STRINGTABLE -BEGIN - IDS_SEEK_TO "定位到" - IDS_TITLE "标题" - IDS_RHYTHM "节拍" - IDS_SOUND_FONT "音色库" - IDS_ARTIST "艺术家" - IDS_ALBUM "唱片集" - IDS_FORMAT "格式" - IDS_MONO "单声道" - IDS_STEREO "立体声" - IDS_CHANNEL "声道" - IDS_NO_LYRIC_INFO "当前歌曲没有歌词" - IDS_LYRIC_SHOW "歌词秀" - IDS_TRAS "译" - IDS_ALBUM_COVER "专辑封面" - IDS_INNER_ALBUM_COVER_TIP_INFO "内嵌图片\r\n图片格式: " - IDS_OUT_IMAGE "外部图片" -END - -STRINGTABLE -BEGIN - IDS_PLAYLIST_INIT_INFO "找到<%1%>首歌曲,正在读取音频文件信息,请稍候……" - IDS_REPEAT_MODE "循环模式" - IDS_PLAY_ODER "顺序播放" - IDS_LOOP_PLAYLIST "列表循环" - IDS_LOOP_TRACK "单曲循环" - IDS_PLAY_SHUFFLE "无序播放" - IDS_SHOW_LYRIC_TRANSLATION "显示歌词翻译" - IDS_MOUSE_WHEEL_ADJUST_VOLUME "鼠标滚轮调整音量" - IDS_SWITCH_UI "切换界面" - IDS_SOUND_EFFECT_SETTING "音效设定" - IDS_SETTINGS "设置" - IDS_FIND_DLG_INFO "查找关键字:<%1%>,结果数:<%2%>" - IDS_FIND_RESULT "查找结果" - IDS_NO_RESULT "没有找到结果!" - IDS_NUMBER "序号" - IDS_FILE_NAME "文件名" -END - -STRINGTABLE -BEGIN - IDS_FILE_PATH "文件路径" - IDS_CHARACTER_TOTAL "共<%1%>个字符" - IDS_MODIFIED "已修改" - IDS_UNMODIFIED "未修改" - IDS_ENCODE_FORMAT "编码格式" - IDS_UTF8_NO_BOM "UTF8无BOM" - IDS_LYRIC_SAVE_INRUARY "歌词已更改,是否要保存?" - IDS_LYRIC_FILE_FILTER "歌词文件(*.lrc;*.ksc)|*.lrc;*.ksc|文本文件(*.txt)|*.txt|所有文件(*.*)|*.*||" - IDS_SAVE_AS_ANSI "以ANSI格式保存" - IDS_SAVE_AS_UTF8 "以UTF-8格式保存" - IDS_REPLACE_COMPLETE_INFO "替换完成,共替换<%1%>个字符串。" - IDS_CONNOT_FIND_STRING "找不到“<%1%>”" - IDS_INSERT_TIME_TAG_TIP "插入时间标签 (F8)" - IDS_REPLACE_TIME_TAG_TIP "替换时间标签 (F9)" - IDS_DELETE_TIME_TAG_TIP "删除时间标签 (Ctrl+Del)" - IDS_SAVE_TIP "保存 (Ctrl+S)" -END - -STRINGTABLE -BEGIN - IDS_PLAY_PAUSE_TIP "播放/暂停 (Ctrl+P)" - IDS_REWIND_TIP "快退 (Ctrl+←)" - IDS_FAST_FOWARD_TIP "快进 (Ctrl+→)" - IDS_FIND_TIP "查找 (Ctrl+F)" - IDS_REPLACE_TIP "替换 (Ctrl+H)" - IDS_CANNOT_GET_SONG_LENGTH "暂未获取或无法获取音频的长度" - IDS_NO_MATCHED_LYRIC "没有匹配的歌词" - IDS_MP3_TAG_TYPE "标签类型:" - IDS_UNKNOW "未知" - IDS_CANNOT_WRITE_TO_FILE "无法写入文件!" - IDS_FOLDER "文件夹" - IDS_PATH "路径" - IDS_TRACK_PLAYED "上次播放" - IDS_TRACK_TOTAL_NUM "曲目数" - IDS_TOTAL_LENGTH "总时长" - IDS_CLEAR_PATH_INQUARY "确实要清除列表中无效的文件夹吗?" -END - -STRINGTABLE -BEGIN - IDS_PATH_CLEAR_COMPLETE "完成,清除了 <%1%> 个无效的文件夹。" - IDS_NONE "无" - IDS_CLASSICAL "古典" - IDS_POP "流行" - IDS_JAZZ "爵士" - IDS_ROCK "摇滚" - IDS_SOFT "柔和" - IDS_BASS "重低音" - IDS_ELIMINATE_BASS "消除低音" - IDS_WEAKENING_TREBLE "弱化高音" - IDS_USER_DEFINE "自定义" - IDS_EQUALIZER "均衡器" - IDS_REVERB "混响" - IDS_PLUGIN_FILE_NAME "插件文件名" - IDS_FORMAT_SUPPORTED "提供的格式支持" - IDS_FILE_EXTENSION "文件的扩展名" -END - -STRINGTABLE -BEGIN - IDS_STATE "状态" - IDS_LYRIC_BATCH_DOWNLOADING_INFO "正在下载歌词,已完成 <%1%>%,请稍候……" - IDS_DOWNLOADING "正在下载…" - IDS_SKIPED "已跳过" - IDS_NETWORK_CONNECTION_FAILED "网络连接失败或超时" - IDS_CANNOT_FIND_THIS_SONG "找不到此歌曲" - IDS_LYRIC_DOWNLOAD_FAILED "歌词下载失败" - IDS_SONG_NO_LYRIC "该歌曲没有歌词" - IDS_DOWNLOAD_ENCODE_WARNING "成功,但是歌词中有无法转换的Unicode字符,建议保存为UTF-8格式" - IDS_SUCCESSED "成功" - IDS_DOWNLOAD_COMPLETE "下载完成。" - IDS_RETURN_VALUE_OF_WAIT_FOR_SINGLE_OBJECT "WaitForSingleObject函数的返回值为%x。" - IDS_SEARCHING "正在搜索……" - IDS_SEARCH_FAILED_INFO "搜索失败,请检查你的网络连接!" - IDS_SEARCH_TIME_OUT "搜索超时!" - IDS_SEARCH_NO_SONG "搜索结果:(没有找到歌曲)" -END - -STRINGTABLE -BEGIN - IDS_SEARCH_NO_MATCHED "搜索结果:(似乎没有最佳匹配的项)" - IDS_SEARCH_RELATED "搜索结果:(已关联项:<%1%>)" - IDS_SEARCH_BEST_MATCHED "搜索结果:(最佳匹配项:<%1%>)" - IDS_LYRIC_OVERWRITE_INQUARY "歌词文件已存在,要替换它吗?" - IDS_DOWNLOAD_COMPLETE_SAVED "下载完成,保存为“<%1%>”。" - IDS_CONVERTING_STATE "转换状态" - IDS_MP3_LAME_ENCODER "MP3 (lame编码器)" - IDS_AUTO_RENAME "自动重命名" - IDS_IGNORE "跳过" - IDS_OVERWRITE "覆盖" - IDS_CONVERT_WMA_ERROR "转换 “<%1%>” 到 WMA 出错:" - IDS_NO_WMP9_OR_LATER "没有安装 Windows Media Player 9 或更高版本。" - IDS_NO_SUPPORTED_ENCODER_WARNING "无法找到可支持请求的采样格式和比特率的编解码器。" - IDS_UNKNOW_ERROR "未知错误。" - IDS_BASS_ENCODER_LOAD_ERROR "BASS 编码器加载失败,文件 “<%1%>” 可能丢失或已经损坏!" - IDS_SET_OUTPUT_DIR_INFO "请设置输出目录!" -END - -STRINGTABLE -BEGIN - IDS_OUTPUT_DIR_NOT_EXIST "输出目录 ""<%1%>"" 不存在!" - IDS_SELECT_OUTPUT_FOLDER "选择输出文件夹" - IDS_ERROR "出错" - IDS_COMPLEATE "完成" - IDS_SKIPED1 "跳过" - IDS_CURRENT_SELECTED "当前选择" - IDS_CURRENT_COLOR "当前的颜色" - IDS_LIGNT_BLUE "天蓝色" - IDS_GREEN "绿色" - IDS_ORANGE "橙色" - IDS_CYAN_GREEN "青绿色" - IDS_PINK "浅红色" - IDS_LIGHT_PURPLE "淡紫色" - IDS_STRETCH "拉伸" - IDS_FILL "填充" - IDS_ADAPT "适应" -END - -STRINGTABLE -BEGIN - IDS_COVER_FIT_TIP_INFO "拉伸:会改变长宽比\r\n填充:不会改变长宽比,会裁剪长边\r\n适应:不会改变长宽比,不裁剪" - IDS_USE_OUT_IMAGE_TIP_INFO "如果无法从音频文件获取专辑封面,则尝试在音频文件所在目录下查找下面指定的文件名为专辑封面" - IDS_DEFAULT_COVER_NAME_TIP_INFO - "在此设置默认的专辑封面文件名,多个文件名之间使用半角逗号隔开,支持通配符与相对路径,设置绝对路径会使封面查找总是成功无法自动下载专辑封面" - IDS_WHITE_THEME_COLOR_WARNING "警告:将主题颜色设置成白色会使进度条完全看不见!" - IDS_FOLLOWING_SYSTEM "跟随系统" - IDS_CLEAR_DATA_FILE_TIP_INFO - "说明:程序目录下的 song_data.dat 文件保存了所有加载过的歌曲信息,用于加快播放列表的载入速度。点击此按钮以清理不存在的文件。" - IDS_AUTO_DOWNLOAD_LYRIC_TIP_INFO - "勾选此项后,只有当歌曲的“标题”和“艺术家”信息都不为空时,才自动下载歌词和专辑封面。" - IDS_MIDI_INNER_LYRIC_TIP_INFO "有些 MIDI 音乐包含歌词,勾选此项后,会优先显示 MIDI 音乐内嵌的歌词。" - IDS_CURRENT_DATA_FILE_SIZE "当前数据文件大小" - IDS_BYTE "字节" - IDS_CLEAR_COMPLETE_INFO "清理完成,已删除 <%1%> 个项目,数据文件大小减小 <%2%> 个字节。" - IDS_SOUND_FONT_FILTER "音色库文件|*.SF2|所有文件|*.*||" - IDS_FUNCTION "功能" - IDS_SHORTCUT_KEY "快捷键" - IDS_PLAY_PAUSE "播放/暂停" - IDS_STOP "停止" -END - -STRINGTABLE -BEGIN - IDS_FAST_FORWARD "快进" - IDS_REWIND "快退" - IDS_VOLUME_UP "增大音量" - IDS_VOLUME_DOWN "减小音量" - IDS_EXIT "退出" - IDS_GLOBLE_HOT_KEY_WARNING "全局快捷键至少需要包含Ctrl、Shift、Alt中的一个!" - IDS_LYRIC_FUZZY_MATHC_TIP_INFO - "如果去掉此复选框的勾选,则只会匹配和歌曲文件名完全一样的歌词文件;\r\n如果选中此复选框,当找不到文件名完全一样的歌词文件时,会匹配文件名中包含艺术家和歌曲标题的歌词文件。\r\n(可能需要重新启动程序才能生效。)" - IDS_LYRIC_PATH_TIP_INFO "说明:如果歌曲所在目录下找不到匹配的歌词文件,就会在此文件夹下寻找歌词文件。" - IDS_CORTANA_SHOW_LYRIC_TIP_INFO - "勾选项后,可以在 Cortana 搜索框中显示歌词、歌曲名称和专辑封面。开启此功能后可能需要重新启动软件才能生效。" - IDS_BLACK "黑色" - IDS_WHITE "白色" - IDS_SELECT_LYRIC_FOLDER "选择歌词文件夹" - IDS_LYRIC_SETTINGS "歌词设置" - IDS_APPEARANCE_SETTINGS "外观设置" - IDS_GENERAL_SETTINGS "常规设置" - IDS_PLAY_SETTINGS "播放设置" -END - -STRINGTABLE -BEGIN - IDS_GLOBLE_HOTKEY "全局快捷键" - IDS_DEVICE_TYPE_DIGITAL "通过用于未知类型数字接口的连接器连接到音频适配器的音频端点设备。" - IDS_DEVICE_TYPE_DISPLAYPORT "通过 DisplayPort 连接器连接到音频适配器的音频端点设备。" - IDS_DEVICE_TYPE_HANDSET "包含用于双向通信的扬声器和麦克风的手持电话的一部分。" - IDS_DEVICE_TYPE_HDMI "通过高清晰度多媒体接口 (HDMI) 连接器连接到音频适配器的音频端点设备。" - IDS_DEVICE_TYPE_HEADPHONES "耳机" - IDS_DEVICE_TYPE_HEADSET "用于双向通信的带话筒的单个或一对耳机。" - IDS_DEVICE_TYPE_LINE "音频端点设备, 用于将线路级模拟信号发送到音频适配器上的线路输入插孔, 或从适配器上的输出插孔接收线路级模拟信号。" - IDS_DEVICE_TYPE_MICROPHONE "麦克风" - IDS_DEVICE_TYPE_NETWORK "用户通过网络远程访问的音频端点设备。" - IDS_DEVICE_TYPE_SPDIF "通过索尼/飞利浦数字接口 (PDIF) 连接器连接到音频适配器的音频端点设备。" - IDS_DEVICE_TYPE_SPEAKERS "扬声器" - IDS_ITEM "项目" - IDS_VLAUE "值" - IDS_NAME "名称" - IDS_DRIVER "驱动程序" -END - -STRINGTABLE -BEGIN - IDS_DEVICE_TYPE "设备类型" - IDS_ALBUM_COVER_DOWNLOAD_FAILED_WARNING "专辑封面下载失败,请检查你的网络连接!" - IDS_AUDIO_FILE "音频文件" - IDS_MINI_SEQUENCE "MIDI 序列" - IDS_DELETE "删除" - IDS_COPY "复制" - IDS_MOVE "移动" - IDS_INVALID_DIR_WARNING "无效的目录,请重新选择!" - IDS_DEFAULT_OUTPUT_DEVICE "默认输出设备" - IDS_BASIC_AUDIO_FORMAT "基本音频格式" - IDS_SOUND_FONT_LOAD_FAILED "音色库“<%1%>”加载失败!" - IDS_LOAD_FAILED "加载失败" - IDS_BASS_ERROR_LOG_INFO "BASS音频库发生了错误,错误代码:<%1%>,文件:<%2%>" - IDS_LANGUAGE_CHANGE_INFO "请重新启动程序使语言设置生效。" - IDS_STOPED "已停止" - IDS_PAUSED "已暂停" -END - -STRINGTABLE -BEGIN - IDS_RECENT_PATH_SERIALIZE_ERROR_LOG - "读取最近播放路径文件文件时发生了序列化异常,异常类型:CArchiveException,m_cause = <%1%>。可能是recent_path.dat文件被损坏或版本不匹配造成的。" - IDS_NO_RESULT_TO_SHOW "没有结果可以显示。" - IDS_BITRATE "比特率" - IDS_TRACK "曲目" - IDS_LENGTH "长度" - IDS_TEST_STR "测试_<%1%>_@@#$_#_<%2%>_ERgfde<%3%>_444" - IDS_CLOSE "关闭" - IDS_MULTI_MEDIA_KEY_TIP "勾选此选项后,即使程序在后台运行,你仍然可以使用键盘上的多媒体按键控制音乐的播放。需要重新启动程序才能生效。" - IDS_SONG_INFO "曲目信息" - IDS_SELECT_FOLDER "选择文件夹" - IDS_FIND_SONGS "查找歌曲" - IDS_EXIT_FULL_SCREEN "退出全屏" - IDS_FULL_SCREEN "全屏显示" - IDS_WELCOM_TO_USE "欢迎使用MusicPlayer2!" - IDS_ERROR_MESSAGE "错误信息:" - IDS_CRASH_INFO "很抱歉,程序出现了错误,请将此文件 “<%1%>” 通过电子邮件发送到 zhongyang219@hotmail.com,以帮助作者确定问题所在。并将以下内容添加到邮件正文中:" -END - -STRINGTABLE -BEGIN - IDS_ERROR1 "错误" - IDS_HELP "帮助" - IDS_FILE_NOT_FOUND "没有找到文件" - IDS_PLAY_SHORTCUT_CREATED "已经在“<%1%>”目录下创建了播放控制快捷方式。" - IDS_CREATE_PLAY_SHORTCUT_INFO - "此命令将会在程序所在目录下创建播放控制快捷方式,当播放器正在运行时,你可以通过这些快捷方式来控制音乐的播放。你也可以将它们固定到任务栏。要创建播放控制快捷方式吗?" - IDS_LISTEN_TIME "累计时间" - IDS_LISTEN_TIME_FILE_DLG_FILTER "csv文件(*.csv)|*.csv|所有文件(*.*)|*.*||" - IDS_LISTEN_TIMES "累计次数" - IDS_LISTEN_TIME_STATISTICS "累计播放时间统计" - IDS_HIDE_MENU_BAR_TIP "提示:隐藏菜单栏后可以右击窗口标题栏,或者点击右上角的主菜单“≡”按钮,在弹出的菜单中选择“视图”——“显示菜单栏”以重新显示菜单栏。\r\n点击“取消”不再提示。" - IDS_LYRIC_PREVIEW "歌词预览" - IDS_CRASH_ERROR_LOG_INFO "程序崩溃了,dump文件已经保存到“<%1%>”。" - IDS_MAIN_MENU "主菜单" - IDS_LYRIC_SAVE_FAILED "歌词保存失败,请检查目标文件夹是否有写入权限!" - IDS_PLAYLIST "播放列表" - IDS_PLAYLIST_FILTER "文本文件(*.txt)|*.txt|所有文件(*.*)|*.*||" -END - -STRINGTABLE -BEGIN - IDS_CLEAR_PLAYLIST_WARNING "确实要清空播放列表吗?" - IDS_DEFAULT "默认" - IDS_NEW_PLAYLIST "新建播放列表" - IDS_INPUT_PLAYLIST_NAME "输入播放列表名称:" - IDS_RENAME_PLAYLIST "重命名播放列表" - IDS_CURRENT_FOLDER "当前文件夹" - IDS_PLAYLIST_EXIST_WARNING "播放列表“<%1%>”已存在!" - IDS_REMOVE_SAME_SONGS_INFO "完成,已删除 <%1%> 个项目。" - IDS_MEDIA_LIB "媒体库" - IDS_OPEN_MEDIA_LIB "打开媒体库" - IDS_ADD_TO_PLAYLIST_FAILED_WARNING "添加失败,播放列表“<%1%>”不存在!" - IDS_DESCRIPTION "说明" - IDS_INCLUDE_SUB_DIR "包含子文件夹" - IDS_MY_FAVURITE "我喜欢的音乐" - IDS_ADD_TO_MA_FAVOURITE "添加到“我喜欢的音乐”" - IDS_REMANE_FAILED "重命名失败!" -END - -STRINGTABLE -BEGIN - IDS_REMOVE_MY_FAVOURITE_WARNING "取消“我喜欢”会将正在播放的曲目从当前播放列表中移除,要继续吗?" - IDS_FILE_NAME_INVALID_WARNING "名称中不能包含以下字符:\n\\""/:*?<>|" - IDS_OPEN_URL "打开URL" - IDS_ADD_URL "添加URL" - IDS_INPUT_URL_TIP "请输入URL:" - IDS_MCI_INIT_FAILED "MCI初始化失败!" - IDS_MCI_NO_THIS_FUNCTION_WARNING "MCI内核无法使用此功能!" - IDS_MCI_KERNAL_TIP "使用MCI内核将导致格式转换和音效设置功能无法使用,且部分音频无法播放。建议仅在需要的时候切换为此内核。" - IDS_CLEAR_LISTEN_TIME_WARNING "确实要清空所有统计数据吗?" - IDS_PLAYLIST_NAME_EMPTY_WARNING "播放列表名称不能为空!" - IDS_ALBUM_COVER_COMPRESSED "已压缩尺寸过大的专辑封面" - IDS_TOW_COLOR_GRADIENT "两色渐变" - IDS_THREE_COLOR_GRADIENT "三色渐变" - IDS_NO_GRADIENT "无渐变" - IDS_LRC "词" - IDS_SHOW_DESKTOP_LYRIC "显示桌面歌词" -END - -STRINGTABLE -BEGIN - IDS_LOCK_DESKTOP_LYRIC "锁定桌面歌词" - IDS_CLOSE_DESKTOP_LYRIC "关闭桌面歌词窗口" - IDS_LYRIC_DOUBLE_LINE "歌词双行显示" - IDS_LYRIC_BACKGROUND_PENETRATE "歌词背景穿透" - IDS_ULOCK_DESKTOP_LYRIC "解锁桌面歌词" - IDS_ADD "添加" - IDS_SORT "排序" - IDS_LIST "列表" - IDS_EDIT "编辑" - IDS_DEFAULT_STYLE "预设方案" - IDS_MODIFY_DEFAULT_STYLE_WARNING "确实要用当前颜色方案覆盖“预设 <%1%>”吗?" - IDS_RESTORE_DEFAULT_STYTLE_WARNING "所有修改过的预设方案都将被恢复,要继续吗?" - IDS_URL_INVALID_WARNING "请输入正确的URL!" - IDS_PROGRESS_INFO "已完成 <%1%>%,请稍候……" - IDS_BASS_MIX_LOAD_ERROR "BASSmix 加载失败,文件 “<%1%>” 可能丢失或已经损坏!" - IDS_BROWSE "浏览" -END - -STRINGTABLE -BEGIN - IDS_OTHER "其他" - IDS_SEARCH_ARTIST "在此处键入搜索艺术家" - IDS_SEARCH_ALBUM "在此处键入搜索唱片集" - IDS_TEMP_PLAYLIST "临时的播放列表" - IDS_GENRE "流派" - IDS_SEARCH_GENRE "在此处键入搜索流派" - IDS_YEAR "年份" - IDS_SEARCH_YEAR "在此处键入搜索年份" - IDS_TRACK_NUM "音轨号" - IDS_FOLDER_EXPLORE "文件夹浏览" - IDS_SEARCH_FORDER "在此处键入搜索文件夹" - IDS_BTN_SETTINGS "设置(&S)..." - IDS_MORE_PLAYLIST "更多播放列表" - IDS_SEARCH_RESULT "搜索结果:" - IDS_UPDATING_MEDIA_LIB_INFO "正在更新媒体库……已更新 <%1%> 个曲目" - IDS_ERROR_CODE "错误代码" -END - -STRINGTABLE -BEGIN - IDS_UPDATE_MEDIA_LIB_TIP "勾选此项时,程序会在启动时自动扫描“媒体库目录”中的音频文件。" - IDS_FILE_NOT_EXIST "文件不存在" - IDS_FILE_CONNOT_BE_OPEND "文件无法打开" - IDS_ALIGN_LEFT "左对齐" - IDS_ALIGN_RIGHT "右对齐" - IDS_CENTER "居中" - IDS_ALL_TRACKS "所有曲目" - IDS_DO_NOT_SAVE "不保存" - IDS_AUTO_SAVE "自动保存" - IDS_INQUIRY "询问" - IDS_LYRIC_FORWARD "歌词提前0.5秒" - IDS_LYRIC_DELAY "歌词延后0.5秒" - IDS_RECENT_PLAYED "最近播放" - IDS_LAST_PLAYED_TIME "上次播放时间" - IDS_CLEAR_RECENT_PLAYLIST_INFO "确实要清空最近播放曲目列表吗?" - IDS_AB_REPEAT_A_SELECTED "AB重复:已选择A点 (<%1%>)" -END - -STRINGTABLE -BEGIN - IDS_AB_REPEAT_ON_INFO "AB重复:开 (<%1%>-<%2%>)" - IDS_AB_REPEAT "AB重复" - IDS_INNER_LYRIC "内嵌歌词" - IDS_SHOW_ONLINE_HELP_INFO "点击此处查看详细在线帮助文档。" - IDS_PLAYLIST_FILE_FILTER - "全部支持的播放列表文件|*.playlist;*.m3u;*.m3u8|MusicPlayer2播放列表文件|*.playlist|m3u播放列表文件|*.m3u|m3u8播放列表文件|*.m3u8|所有文件(*.*)|*.*||" - IDS_SAVE_PLAYLIST_FILTER - "m3u播放列表文件|*.m3u|m3u8播放列表文件|*.m3u8|MusicPlayer2播放列表文件|*.playlist|所有文件(*.*)|*.*||" - IDS_CREATE_MINI_MODE_SHORTCUT_INFO - "此命令将会在程序所在目录下创建一个迷你模式的快捷方式,通过此快捷方式将总是以迷你模式启动播放器。要创建迷你模式快捷方式吗?" - IDS_CREATE_DESKTOP_SHORTCUT_INFO "确实要创建程序的桌面快捷方式吗?" - IDS_DELETE_SINGLE_FILE_INQUIRY "确实要删除文件“<%1%>”吗?" - IDS_ALL "全部" - IDS_LAST_WEEK "最近一星期" - IDS_LAST_MONTH "最近一个月" - IDS_LAST_HALF_YEAR "最近半年" - IDS_LAST_YEAR "最近一年" - IDS_TODAY "今天" - IDS_LAST_THREE_DAYS "最近三天" -END - -STRINGTABLE -BEGIN - IDS_LICENSE_EXPLAIN "使用本软件的源代码时请遵守以下开源协议。" - IDS_LICENSE "开源协议" - IDS_FILE_EXIST_IN_PLAYLIST_INFO "文件已存在于播放列表中。" - IDS_IS_RELATED "是否关联" - IDS_YES "是" - IDS_ALBUM_COVER_INFO "专辑封面详情" - IDS_INNER_ALBUM_COVER "内嵌专辑封面" - IDS_WIDTH "宽度" - IDS_HEIGHT "高度" - IDS_BPP "每像素位数" - IDS_FILE_SIZE "文件大小" - IDS_DEFAULT_ICON "默认图标" - IDS_LIGHT_ICON "浅色图标" - IDS_DARK_ICON "深色图标" - IDS_NO "否" - IDS_CONVERT_ERROR_FILE_CONNOT_OPEN "源文件无法读取" -END - -STRINGTABLE -BEGIN - IDS_CONVERT_ERROR_ENCODE_CHANNEL_FAILED "编码通道创建失败" - IDS_CONVERT_ERROR_ENCODE_PARA_ERROR "找不到编码器或编码器参数错误" - IDS_CONVERT_ERROR_MIDI_NO_SF2 "没有MIDI音色库" - IDS_CONTAIN_SUB_FOLDER "包含子文件夹" - IDS_TYPE "类型" - IDS_FILE_TYPE "文件类型" - IDS_CLEAN_UP_MEDIA_WARNING "清选择一个清理范围!" - IDS_FILES_THAT_NOT_EXIST "不存在的文件" - IDS_FILES_NOT_IN_MEDIA_LIB_DIR "不在媒体库目录中的文件" - IDS_FILES_THAT_ERROR "错误的文件" - IDS_IMAGE_FILE_FILTER "图片文件(*.jpg;*.jpeg;*.png;*.bmp;*.gif)|*.jpg;*.jpeg;*.png;*.bmp;*.gif|所有文件(*.*)|*.*||" - IDS_SEARCH_FILE_TYPE "在此处键入搜索文件类型" - IDS_SEARCH_BITRATE "在此处键入搜索比特率" - IDS_PLAY_RANDOM "随机播放" - IDS_FILE_PROPERTY "文件属性" - IDS_PROPERTY_TITLE_INFO " (<%1%>个文件)" -END - -STRINGTABLE -BEGIN - IDS_MULTI_VALUE "<多个数值>" - IDS_TAG_BATCH_EDIT_INFO "已保存到 <%1%> 个文件。" - IDS_GET_TAG_ONLINE_TITLE "在线获取标签信息" - IDS_GET_THIS "获取此项" - IDS_NO_LYRICS_FOUND_INFO "没有找到歌词!" - IDS_CLEAR_HISTORY "清除历史记录..." - IDS_CLEAR_HISTORY_INFO "确实要清除历史记录吗?" - IDS_RENAME "重命名" - IDS_RENAME_INFO "重命名 <%1%> 个文件,成功 <%2%> 个,忽略 <%3%> 个,失败 <%4%> 个。" - IDS_PLAY_TRACK "单曲播放" - IDS_ADVANCED_PROPERTY "高级标签信息" - IDS_CONNOT_FIND_ARTIST_WARNING "无法在媒体库中找到艺术家 <%1%>!" - IDS_CONNOT_FIND_ALBUM_WARNING "无法在媒体库中找到唱片集 <%1%>!" - IDS_SCI_NOT_LOADED_ERROR_INFO - "无法打开此对话框,因为 SciLexer.dll 没有正确加载,请检查 SciLexer.dll 是否丢失!" - IDS_SELECT_ARTIST "选择艺术家" - IDS_LOCATE_TO_CURRENT "定位到正在播放曲目" -END - -STRINGTABLE -BEGIN - IDS_UI "界面" - IDS_RATING "分级" - IDS_UNRATED "未分级" - IDS_RANDOM_TRACK "随机曲目" - IDS_NEXT_TRACK "下一曲" - IDS_MEDIA_LIB_UPDATING_INFO "媒体库正在更新,请稍后再试!" - IDS_MINIMIZE "最小化" - IDS_MAXIMIZE "最大化" - IDS_RESTORE "还原" - IDS_SET_FILENAME_FORM "设置文件名格式" - IDS_SET_MULTI_OUT_ALBUM_COVER_FILE_NAME "设置多个外部专辑封面的文件名" - IDS_DARK "深色" - IDS_LIGHT "浅色" - IDS_SHOW_HIDE_PLAYER "显示/隐藏播放器" - IDS_MUTE "静音" - IDS_UNDEFINED "未定义" -END - -STRINGTABLE -BEGIN - IDS_DELETE_INNER_ALBUM_COVER_INQUERY - "当前专辑封面是内嵌在音频文件里的,删除后将不可恢复,确实要删除内嵌的专辑封面吗?" - IDS_TOTAL_TRACKS "曲目总数" - IDS_TRACKS_PLAYED "播放过的曲目数" - IDS_MEDIALIB_STATISTICS "媒体库统计" - IDS_CFG_DIR_CHANGED_INFO - "你更改了配置文件和数据文件的保存位置,重启后生效。你可能需要手动将配置文件和数据文件转移到新的位置。" - IDS_ADD_TO_PLAYLIST "添加到播放列表" - IDS_LYRICS_HIDE_BLANK_LINES_TIP - "勾选此选项后,在歌词单行显示和双行显示时,如果遇到空白行,则不再显示“Music...”,而是会提前显示之后的歌词,若同时勾选了“歌词卡拉OK样式显示”则会将大于一定时长的空白行替换为音乐进度符号(♪♪♪)。此选项也会影响桌面歌词的显示。" - IDS_BOLD "加粗" - IDS_ITALIC "倾斜" - IDS_SDL_DEFAULT_DEVICE "SDL 默认音频设备" - IDS_FFMPEG_CORE "使用FFMPEG内核将导致混响功能和格式转换无法使用,且不支持播放MIDI文件。需要有 ffmpeg_core.dll。" - IDS_FFMPEG_INIT_FAILED "FFMPEG内核初始化失败!" - IDS_FFMPEG_NO_THIS_FUNCTION "FFMPEG内核下暂不支持此功能!" - IDS_SUPPORTTED_FORMAT_INFO - "MusicPlayer2支持多种播放内核,当前使用的播放内核为BASS音频库。\r\n更多音频格式支持依赖于BASS引擎插件(位于"".\\Plugins""目录下)。" - IDS_SUPPORTTED_FORMAT_INFO_MCI - "MusicPlayer2支持多种播放内核,当前使用的播放内核为MCI。仅支持mp3、wma、wav、mid格式,需要支持更多音频格式的播放,请切换到BASS或FFMPEG内核。" - IDS_SUPPORTTED_FORMAT_INFO_FFMPEG "MusicPlayer2支持多种播放内核,当前使用的播放内核为FFMPEG。" -END - -STRINGTABLE -BEGIN - IDS_OTHER_FORMATS "其他音频格式" - IDS_IDS_ENCODER_INIT_ERROR "编码器初始化失败!" - IDS_SEEK_TO_LINE_TIP "定位到当前行 (Ctrl+G)" - IDS_SWITCH_DISPLAY "切换显示" - IDS_FILE "文件" - IDS_PLAY_CONTROL "播放控制" - IDS_LYRICS "歌词" - IDS_VIEW "视图" - IDS_TOOLS "工具" - IDS_DOWNLOAD_FFMPEG_CORE_INFO - "FFMPEG内核需要单独下载,下载后请将解压得到的所有dll文件放到程序所在目录下。要下载FFMPEG内核吗?" - IDS_TRAFFICMONITOR_DESCRIPTION "TrafficMonitor: 功能强大的Windows网速监控软件" - IDS_SIMPLENOTEPAD_DESCRIPTION "SimpleNotePad: 简洁的 Windows 文本编辑器" - IDS_NO_TRACKS_TIP_INFO "当前没有正在播放的曲目,你可以:\r\n按下<%1%>打开播放列表,并向播放列表中添加歌曲;\r\n点击“主菜单”——“文件”——“打开文件”或者快捷键<%2%>来打开一个音频文件;\r\n点击“主菜单”——“文件”——“打开文件夹”或者快捷键<%3%>打开并播放一个文件夹;\r\n按下<%4%>打开媒体库,在媒体库中寻找要播放的歌曲。" - IDS_SWITHC_TO_DARK_MODE "切换到深色模式" - IDS_SWITCH_TO_LIGHT_MODE "切换到浅色模式" - IDS_SHORCUT_LEFT "←" -END - -STRINGTABLE -BEGIN - IDS_SHOTCUT_RIGHT "→" - IDS_SHOTCUT_UP "↑" - IDS_SHOTCUT_DOWN "↓" - IDS_SPACE "空格" - IDS_ALBUM_COVER_PATH_EDIT_TIP_INFO "如果歌曲所在目录下没有找到专辑封面则会在此文件夹下寻找封面文件。" - IDS_LOGIN_REQUIRED "需要登录" - IDS_LOGGED "已登录" - IDS_LASTFM_LOGIN "请您在打开的浏览器窗口内完成登录并在登录成功后单击确定。" - IDS_LOGIN_FAILED "登录失败!" - IDS_LASTFM_CACHE_STATUS "%i条记录" - IDS_SHOW_HIDE_DESKTOP_LYRIC "显示/隐藏桌面歌词" - IDS_APP_RUNING_INFO "MusicPlayer2 还在进行,请等待进程退出,或者通过任务管理器结束进程。" - IDS_SHOW_SONG_INFO_WHEN_LYRICS_NOT_EXIST_TIP - "勾选此项后,如果没有歌词,会显示歌曲的艺术家、唱片集和歌曲标题等信息,而不是显示“当前歌曲没有歌词”。" - IDS_EXCLUSIVE_MODE "独占模式" - IDS_PLAYLIST_FIX_PATH_ERROR_INFO - "此功能将会检查播放列表中不存在的曲目,通过在媒体库中寻找匹配的曲目来修复错误的路径。需要修复播放列表中错误的路径吗?" - IDS_PLAYLIST_FIX_PATH_ERROR_COMPLETE "完成,已修复<%1%>个错误的路径。" -END - -STRINGTABLE -BEGIN - IDS_LOCATE "定位" - IDS_PLAYLIST_MENU "播放列表菜单" - IDS_RECENT_FOLDER_OR_PLAYLIST "最近播放的文件夹/播放列表" - IDS_PLAYLIST_EMPTY_INFO "播放列表为空。" - IDS_CONTINUE_WHEN_SWITCH_PLAYLIST_TIP - "勾选此项后,在切换播放列表时,如果新的播放列表中存在正在播放的曲目,则在切换播放列表后继续播放当前播放的曲目。" - IDS_ACKNOWLEDGEMENT "鸣谢" - IDS_SIMPLE_UI "简洁UI" - IDS_GROOVE_MUSIC_STYLE "Groove音乐风格" - IDS_DEFAULT_UI "默认界面" - IDS_ALIGN_AUTO "自动" - IDS_SET_MULTI_ARTIST_SPLIT_EXT "设置多个艺术家识别例外" - IDS_ARTIST_SPLIT_EXT_TIP_INFO "添加所有名称本身含有“/;&&、”的艺术家作为例外,避免程序误识别。" - IDS_FILES_TOO_SHORT "过短的文件" - IDS_FILES_NON_MAIN_IN_OSU "osu! 文件夹中的非主要文件" - IDS_WAIT_AND_RETRY "请等待当前操作完成后重试。" -END - -#endif // 中文(简体,中国) resources -///////////////////////////////////////////////////////////////////////////// - - -///////////////////////////////////////////////////////////////////////////// -// 英语(美国) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_ABOUTBOX DIALOGEX 0, 0, 222, 139 -STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "About MusicPlayer2" -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - LTEXT "MusicPlayer2, V",IDC_STATIC_VERSION,13,41,158,8,SS_NOPREFIX - LTEXT "Copyright (C) 2017- By ZhongYang\nLast compiled date: ",IDC_STATIC_COPYRIGHT,13,52,158,18 - DEFPUSHBUTTON "OK",IDOK,167,119,48,14,WS_GROUP - CONTROL "Contract author",IDC_SYSLINK1,"SysLink",0x0,8,117,57,8 - CONTROL "Check for update",IDC_SYSLINK2,"SysLink",WS_TABSTOP,8,126,59,8 - CONTROL "GitHub",IDC_GITHUB_SYSLINK,"SysLink",WS_TABSTOP,69,117,30,10 - CONTROL "Donate",IDC_DONATE_SYSLINK,"SysLink",WS_TABSTOP,69,126,28,8 - CONTROL "License",IDC_LICENSE_SYSLINK,"SysLink",WS_TABSTOP,100,117,30,10 - LTEXT "The third-party libraries used in this project:",IDC_STATIC,13,72,159,8 - CONTROL "BASS",IDC_SYSLINK_BASS,"SysLink",WS_TABSTOP,13,82,27,9 - CONTROL "TagLib",IDC_SYSLINK_TAGLIB,"SysLink",WS_TABSTOP,44,82,35,9 - CONTROL "TinyXML2",IDC_SYSLINK_TINYXML2,"SysLink",WS_TABSTOP,82,82,40,9 - CONTROL "Scintilla",IDC_SYSLINK_SCINTILLA,"SysLink",WS_TABSTOP,135,82,38,9 - LTEXT "The author's other software:",IDC_STATIC,13,93,144,8 - CONTROL "TrafficMonitor",IDC_SYSLINK_TRAFFICMONITOR, - "SysLink",WS_TABSTOP,13,102,59,9 - CONTROL "SimpleNotePad",IDC_SYSLINK_SIMPLENOTEPAD,"SysLink",WS_TABSTOP,80,102,59,9 - CONTROL "Acknowledgement",IDC_ACKNOWLEDGEMENT_SYSLINK, - "SysLink",WS_TABSTOP,100,126,66,8 -END - -IDD_APPEREANCE_SETTING_DLG DIALOGEX 0, 0, 338, 469 -STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - GROUPBOX "Main Window Opacity",IDC_STATIC,202,240,129,40 - CONTROL "",IDC_TRANSPARENT_SLIDER,"msctls_trackbar32",TBS_NOTICKS | WS_TABSTOP,212,251,87,12 - LTEXT "xx%",IDC_TRANSPARENT_STATIC,300,252,19,8 - GROUPBOX "Visual Effects",IDC_STATIC,7,5,173,115 - CONTROL "Show spectrum analysis",IDC_SHOW_SPECTRUM_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,16,111,10 - CONTROL "Show album cover",IDC_SHOW_ALBUM_COVER_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,55,92,10 - LTEXT "Spectrum height:",IDC_STATIC,12,30,63,8 - CONTROL "",IDC_SPECTRUM_HEIGHT_SLIDER,"msctls_trackbar32",TBS_NOTICKS | WS_TABSTOP,75,29,61,12 - LTEXT "Static",IDC_SPECTRUM_HEIGHT_STATIC,141,30,18,8 - LTEXT "Album cover fit:",IDC_STATIC,12,68,57,8 - COMBOBOX IDC_ALBUM_FIT_COMBO,73,66,47,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "Use album cover as background",IDC_ALBUM_COVER_BACKGROUND_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,194,28,124,10 - LTEXT "Background opacity:",IDC_STATIC,195,41,71,8 - CONTROL "",IDC_BACKGROUND_TRANSPARENCY_SLIDER,"msctls_trackbar32",TBS_NOTICKS | WS_TABSTOP,262,40,46,12 - LTEXT "Static",IDC_BACKGROUND_TRANSPARENCY_STATIC,309,41,18,8 - GROUPBOX "Theme Color",IDC_STATIC,7,189,324,45 - LTEXT "",IDC_COLOR_STATIC,20,203,30,13,NOT WS_GROUP,WS_EX_STATICEDGE - GROUPBOX "Preset color",IDC_STATIC,62,194,111,25 - LTEXT "",IDC_COLOR_STATIC2,69,204,12,11,NOT WS_GROUP | WS_TABSTOP,WS_EX_STATICEDGE - LTEXT "",IDC_COLOR_STATIC3,86,204,12,11,NOT WS_GROUP | WS_TABSTOP,WS_EX_STATICEDGE - LTEXT "",IDC_COLOR_STATIC4,103,204,12,11,NOT WS_GROUP | WS_TABSTOP,WS_EX_STATICEDGE - LTEXT "",IDC_COLOR_STATIC5,120,204,12,11,NOT WS_GROUP | WS_TABSTOP,WS_EX_STATICEDGE - LTEXT "",IDC_COLOR_STATIC6,137,204,12,11,NOT WS_GROUP | WS_TABSTOP,WS_EX_STATICEDGE - LTEXT "",IDC_COLOR_STATIC7,154,204,12,11,NOT WS_GROUP | WS_TABSTOP,WS_EX_STATICEDGE - PUSHBUTTON "More &Color...",IDC_SET_PROGRESS_COLOR_BUTTON,178,202,55,14 - CONTROL "Follow the system theme color",IDC_FOLLOW_SYSTEM_COLOR_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,221,173,10 - CONTROL "Use external picture when album cover not exist",IDC_USE_OUT_IMAGE_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,152,137,174,10 - LTEXT "External picture file name:",IDC_STATIC,18,150,89,8 - CONTROL "Background Gaussian blur",IDC_BACKGROUND_GAUSS_BLUR_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,194,52,120,10 - LTEXT "Gaussian blur radius:",IDC_STATIC,195,65,70,8 - CONTROL "",IDC_GAUSS_BLURE_RADIUS_SLIDER,"msctls_trackbar32",TBS_NOTICKS | WS_TABSTOP,261,64,46,12 - LTEXT "Static",IDC_GAUSS_BLUR_RADIUS_STATIC,308,65,18,8 - CONTROL "Lyric background",IDC_LYRIC_BACKGROUND_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,80,84,10 - CONTROL "Dark mode",IDC_DARK_MODE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,103,80,69,10 - CONTROL "Use the Internal album cover first",IDC_USE_INNER_IMAGE_FIRST_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,137,130,10 - CONTROL "Enable background",IDC_ENABLE_BACKGROUND_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,194,16,113,10 - CONTROL "Low-frequency parts appears in the middle",IDC_LOW_FREQ_IN_CENTER_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,42,166,10 - GROUPBOX "Advanced",IDC_STATIC,7,418,324,40 - CONTROL "Album covers use GDI+ drawing (higher quality but will take up more CPU resources)",IDC_DEFAULT_ALBUM_COVER_HQ, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,430,312,10 - LTEXT "Interface refresh interval:",IDC_STATIC,18,444,92,8 - EDITTEXT IDC_UI_INTERVAL_EDIT,108,442,39,12,ES_AUTOHSCROLL | ES_NUMBER - LTEXT "milliseconds",IDC_STATIC,149,444,45,8 - PUSHBUTTON "Restore &Defaults",IDC_RESTORE_DEFAULT_BUTTON,199,441,63,14 - GROUPBOX "Notification Area Icon",IDC_STATIC,7,358,324,54 - LTEXT "Select notification area icon:",IDC_STATIC,18,371,114,8 - COMBOBOX IDC_COMBO1,18,382,100,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Preview:",IDC_PREVIEW_STATIC,148,365,41,8 - CONTROL "Automatically adapt to Windows 10 dark/light mode when using the monochrome icons.",IDC_NOTIFY_ICON_AUTO_ADAPT_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,398,312,10 - CONTROL "Use rounded corner style",IDC_BTN_ROUND_CORNERS_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,93,137,10 - LTEXT "Default background image:",IDC_STATIC,195,78,102,8 - CONTROL "",IDC_DEFAULT_BACKGROUND_PATH_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x880,195,91,129,11 - GROUPBOX "Background Settings",IDC_STATIC,187,5,144,115 - CONTROL "Use desktop background",IDC_USE_DESKTOP_BACKGROUND_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,195,106,108,9 - GROUPBOX "Statusbar",IDC_STATIC,7,240,184,40 - CONTROL "Show next track",IDC_SHOW_NEXT_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,264,88,10 - CONTROL "Show fps",IDC_SHOW_FPS_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,116,264,55,10 - CONTROL "",IDC_DEFAULT_COVER_NAME_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x80,108,149,216,11 - GROUPBOX "Album Cover Options",IDC_STATIC,7,125,324,58 - LTEXT "Album cover folder:",IDC_STATIC,18,165,89,8 - CONTROL "",IDC_ALBUM_COVER_PATH_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x880,108,164,216,11 - CONTROL "Always show statusbar",IDC_ALWAYS_SHOW_STATUSBAR_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,251,90,10 - GROUPBOX "Titlebar",IDC_STATIC,7,284,324,69 - CONTROL "Use system standard titlebar",IDC_SHOW_SYSTEM_TITLEBAR_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,296,110,10 - LTEXT "Buttons displayed in the titlebar(only available when ""Use system standard titlebar"" is not checked):",IDC_STATIC,18,309,298,15 - CONTROL "Settings",IDC_SHOW_SETTINGS_BTN_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,328,43,10 - CONTROL "Switch UI",IDC_SHOW_SKIN_BTN_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,88,328,47,10 - CONTROL "Mini mode",IDC_SHOW_MINI_MODE_BTN_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,157,328,52,10 - CONTROL "Full screen",IDC_SHOW_FULLSCREEN_BTN_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,240,328,51,10 - CONTROL "Minimize",IDC_SHOW_MINIMIZE_BTN_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,341,47,10 - CONTROL "Maximize/Restore",IDC_SHOW_MAXIMIZE_BTN_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,88,341,76,10 -END - -IDD_OPTIONS_DIALOG DIALOGEX 0, 0, 361, 247 -STYLE DS_SETFONT | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -CAPTION "Option Settings" -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - DEFPUSHBUTTON "OK",IDOK,195,227,50,14 - PUSHBUTTON "Cancel",IDCANCEL,250,227,50,14 - CONTROL "",IDC_OPTIONS_TAB,"SysTabControl32",0x0,5,4,351,217 - PUSHBUTTON "Apply",IDC_APPLY_BUTTON,306,227,50,14 -END - -IDD_COVER_DOWNLOAD_DIALOG DIALOGEX 0, 0, 257, 204 -STYLE DS_SETFONT | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -CAPTION "Download album cover (From NetEase cloud music)" -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - PUSHBUTTON "Cancel",IDCANCEL,200,183,50,14 - PUSHBUTTON "&Search",IDC_SEARCH_BUTTON,199,6,50,14 - EDITTEXT IDC_TITLE_EDIT,29,7,69,12,ES_AUTOHSCROLL - LTEXT "Title:",IDC_STATIC,7,7,20,11,SS_CENTERIMAGE - EDITTEXT IDC_ARTIST_EDIT,131,7,63,12,ES_AUTOHSCROLL - LTEXT "Artist:",IDC_STATIC,103,7,27,11,SS_CENTERIMAGE - CONTROL "",IDC_COVER_DOWN_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,31,242,97 - LTEXT "Search result:",IDC_STATIC_INFO,7,22,110,8 - DEFPUSHBUTTON "&Download selected",IDC_DOWNLOAD_SELECTED,113,183,83,14 - CONTROL "Cancel Link",IDC_UNASSOCIATE_LINK,"SysLink",WS_TABSTOP,120,21,74,9 - GROUPBOX "Download options",IDC_DOWNLOAD_OPTION_GROUPBOX,7,129,243,49 - LTEXT "Album Cover Save Location:",IDC_COVER_LOCATION_STATIC,12,140,104,8 - CONTROL "Save to the same directory as the song",IDC_SAVE_TO_SONG_FOLDER2, - "Button",BS_AUTORADIOBUTTON,11,152,144,10 - CONTROL "Save to album cover directory",IDC_SAVE_TO_ALBUM_FOLDER2, - "Button",BS_AUTORADIOBUTTON,11,163,139,10 -END - -IDD_DATA_SETTINGS_DIALOG DIALOGEX 0, 0, 337, 267 -STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - GROUPBOX "Application Settings",IDC_STATIC,7,6,166,66 - GROUPBOX "Download setting",IDC_STATIC,7,77,324,95 - CONTROL "Automatically download when album cover is not exist",IDC_COVER_AUTO_DOWNLOAD_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,90,188,10 - CONTROL "Automatically download when lyric is not exist",IDC_LYRIC_AUTO_DOWNLOAD_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,101,200,10 - CONTROL "Check for update at startup",IDC_CHECK_UPDATE_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,18,109,10 - LTEXT "MIDI sound font path:",IDC_STATIC,15,189,83,8 - GROUPBOX "MIDI Setting",IDC_STATIC,7,178,324,39 - CONTROL "Display the inner lyric in MIDI music first",IDC_MIDI_USE_INNER_LYRIC_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,204,216,10 - CONTROL "Download automatically only when the song information is complete",IDC_DOWNLOAD_WHEN_TAG_FULL_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,157,280,10 - LTEXT "Language:",IDC_STATIC,15,55,40,8 - COMBOBOX IDC_COMBO1,56,54,75,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - GROUPBOX "Close Main Window",IDC_STATIC,7,223,324,36 - CONTROL "Minimize to notification area",IDC_MINIMIZE_TO_NOTIFY_RADIO, - "Button",BS_AUTORADIOBUTTON | WS_GROUP,15,233,116,10 - CONTROL "Exit the program",IDC_EXIT_PROGRAM_RADIO,"Button",BS_AUTORADIOBUTTON,15,245,102,10 - CONTROL "",IDC_SF2_PATH_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x80,99,188,186,12 - LTEXT "Automatically Download Lyrics Save Location:",IDC_STATIC,15,113,160,8 - CONTROL "Save to the same directory as the song",IDC_SAVE_TO_SONG_FOLDER, - "Button",BS_AUTORADIOBUTTON | WS_GROUP,15,123,140,10 - CONTROL "Save to lyrics directory",IDC_SAVE_TO_LYRIC_FOLDER, - "Button",BS_AUTORADIOBUTTON,163,123,94,10 - CONTROL "Auto run when Windows starts",IDC_AUTO_RUN_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,41,121,10 - LTEXT "Update source:",IDC_STATIC,15,31,59,8 - CONTROL "GitHub",IDC_GITHUB_RADIO,"Button",BS_AUTORADIOBUTTON | WS_GROUP,76,30,41,9 - CONTROL "Gitee",IDC_GITEE_RADIO,"Button",BS_AUTORADIOBUTTON,125,30,36,9 - GROUPBOX "Configuration and data files",IDC_STATIC,183,6,148,66 - CONTROL "Save to Appdata directory",IDC_SAVE_TO_APPDATA_RADIO, - "Button",BS_AUTORADIOBUTTON | WS_GROUP,191,18,130,10 - CONTROL "Save to the program directory",IDC_SAVE_TO_PROGRAM_DIR_RADIO, - "Button",BS_AUTORADIOBUTTON,191,30,130,10 - PUSHBUTTON "Open configuration file &directory",IDC_OPEN_CONFIG_PATH_BUTTON,190,43,126,14 - LTEXT "Automatically Download Album Cover Save Location:",IDC_STATIC,15,134,180,8 - CONTROL "Save to the same directory as the song",IDC_SAVE_TO_SONG_FOLDER3, - "Button",BS_AUTORADIOBUTTON | WS_GROUP,15,145,140,10 - CONTROL "Save to album cover directory",IDC_SAVE_TO_ALBUM_FOLDER3, - "Button",BS_AUTORADIOBUTTON,163,145,113,10 -END - -IDD_EQUALIZER_DIALOG DIALOGEX 0, 0, 299, 107 -STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - CONTROL "Enable equalizer",IDC_ENABLE_EQU_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,7,78,10 - CONTROL "",IDC_SLIDER1,"msctls_trackbar32",TBS_VERT | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,100,17,13,64 - CONTROL "",IDC_SLIDER2,"msctls_trackbar32",TBS_VERT | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,117,17,13,64 - CONTROL "",IDC_SLIDER3,"msctls_trackbar32",TBS_VERT | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,134,17,13,64 - CONTROL "",IDC_SLIDER4,"msctls_trackbar32",TBS_VERT | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,151,17,13,64 - CONTROL "",IDC_SLIDER5,"msctls_trackbar32",TBS_VERT | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,168,17,13,64 - CONTROL "",IDC_SLIDER6,"msctls_trackbar32",TBS_VERT | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,185,17,13,64 - CONTROL "",IDC_SLIDER7,"msctls_trackbar32",TBS_VERT | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,202,17,13,64 - CONTROL "",IDC_SLIDER8,"msctls_trackbar32",TBS_VERT | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,219,17,13,64 - CONTROL "",IDC_SLIDER9,"msctls_trackbar32",TBS_VERT | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,236,17,13,64 - CONTROL "",IDC_SLIDER10,"msctls_trackbar32",TBS_VERT | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,253,17,13,64 - GROUPBOX "Equalizer Presets",IDC_STATIC,7,20,76,75 - GROUPBOX "Channel Settings",IDC_STATIC,93,7,183,88 - LTEXT "80",IDC_STATIC,103,81,13,8 - LTEXT "125",IDC_STATIC,118,81,13,8 - LTEXT "250",IDC_STATIC,135,81,13,8 - LTEXT "500",IDC_STATIC,152,81,13,8 - LTEXT "1K",IDC_STATIC,171,81,13,8 - LTEXT "1.5K",IDC_STATIC,186,81,13,8 - LTEXT "2K",IDC_STATIC,205,81,13,8 - LTEXT "4K",IDC_STATIC,220,81,13,8 - LTEXT "8K",IDC_STATIC,238,81,13,8 - LTEXT "16K",IDC_STATIC,253,81,13,8 - CONTROL "",IDC_EQU_STYLES_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,15,31,61,59 -END - -IDD_FIND_DIALOG DIALOGEX 0, 0, 273, 211 -STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -EXSTYLE WS_EX_APPWINDOW -CAPTION "Find File" -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - DEFPUSHBUTTON "&Play the selected track",IDOK,113,190,96,14 - PUSHBUTTON "Close",IDCANCEL,216,190,50,14 - EDITTEXT IDC_FIND_EDIT,106,7,110,12,ES_AUTOHSCROLL - LTEXT "Enter the keyword to find:",IDC_STATIC,7,9,95,8 - PUSHBUTTON "&Find",IDC_FIND_BUTTON,219,6,47,14 - LTEXT "Last find results:",IDC_FIND_RESULT_STATIC,7,60,99,8 - CONTROL "",IDC_FIND_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,69,259,118 - GROUPBOX "Find options",IDC_STATIC,123,22,143,35 - CONTROL "Find file &name",IDC_FIND_FILE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,134,32,64,10 - CONTROL "Find &title",IDC_FIND_TITLE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,205,32,48,10 - CONTROL "Find &artist",IDC_FIND_ARTIST_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,134,44,58,10 - CONTROL "Find albu&m",IDC_FIND_ALBUM_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,205,44,54,10 - GROUPBOX "Find Range",IDC_STATIC,7,22,111,35 - CONTROL "Find the ¤t playlist",IDC_FIND_CURRENT_PLAYLIST_RADIO, - "Button",BS_AUTORADIOBUTTON,15,33,99,10 - CONTROL "Find &entire media library",IDC_FIND_ALL_PLAYLIST_RADIO, - "Button",BS_AUTORADIOBUTTON,15,44,94,10 - LTEXT "",IDC_FIND_INFO_STATIC,155,60,111,8 -END - -IDD_FORMAT_CONVERT_DIALOG DIALOGEX 0, 0, 269, 253 -STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -EXSTYLE WS_EX_APPWINDOW -CAPTION "Convert Format" -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - CONTROL "",IDC_SONG_LIST1,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,32,255,78 - LTEXT "Output encoding format:",IDC_STATIC,7,8,90,8 - COMBOBOX IDC_OUT_FORMAT_COMBO,100,7,104,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Output directory:",IDC_STATIC,14,212,61,8 - PUSHBUTTON "&Start convert",IDC_START_CONVERT_BUTTON,149,232,60,14 - PUSHBUTTON "&Config...",IDC_ENCODER_CONFIG_BUTTON,212,6,50,14 - GROUPBOX "Options",IDC_STATIC,7,112,255,116 - CONTROL "Write tag information to the destination file",IDC_COPY_TAG_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,135,208,10 - CONTROL "Write album cover to the destination file",IDC_COPY_ALBUM_COVER_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,159,173,10 - LTEXT "When the destination file exists:",IDC_STATIC,14,147,116,8 - COMBOBOX IDC_TARGET_FILE_EXIST_COMBO,133,146,89,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "Add a number to each destination file",IDC_ADD_NUMBER_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,171,198,10 - LTEXT "File list",IDC_STATIC,7,22,54,8 - PUSHBUTTON "Cancel",IDCANCEL,212,232,50,14 - LTEXT "Static",IDC_PROGRESS_TEXT,50,235,96,8 - LTEXT "progressbar",IDC_PROGRESS_BAR,9,235,38,8 - CONTROL "Convert sampling frequency:",IDC_CHANGE_FREQ_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,122,108,11 - COMBOBOX IDC_FREQ_COMBO,133,122,88,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "",IDC_OUT_DIR_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x880,89,211,164,12 - CONTROL "Open output directory after the conversion is complete",IDC_OPEN_TARGET_DIR_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,183,225,10 - LTEXT "Destination file name:",IDC_STATIC,14,197,75,8 - CONTROL "",IDC_OUT_NAME_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x880,89,196,164,12 -END - -IDD_MESSAGE_DIALOG DIALOGEX 0, 0, 235, 176 -STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -EXSTYLE WS_EX_APPWINDOW -CAPTION "Message" -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - DEFPUSHBUTTON "OK",IDOK,178,155,50,14 - EDITTEXT IDC_HELP_EDIT,7,19,221,132,ES_MULTILINE | ES_READONLY | WS_VSCROLL - LTEXT "",IDC_INFO_STATIC,7,7,221,8 - CONTROL "SysLink1",IDC_SYSLINK1,"SysLink",WS_TABSTOP,8,159,167,8 -END - -IDD_HOT_KEY_SETTINGS_DIALOG DIALOGEX 0, 0, 255, 184 -STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - CONTROL "Enable global hot keys",IDC_HOT_KEY_ENABLE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,7,156,10 - CONTROL "",IDC_HOT_KEY_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,18,223,133 - CONTROL "",IDC_HOTKEY1,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,38,156,131,12 - LTEXT "Key:",IDC_STATIC,7,158,29,8 - PUSHBUTTON "&Set",IDC_SET_BUTTON,175,155,50,14 - CONTROL "Enable global multimedia keys",IDC_ENABLE_GLOBAL_MULTIMEDIA_KEY_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,170,151,11 -END - -IDD_LYRIC_BATCH_DOWN_DIALOG DIALOGEX 0, 0, 279, 243 -STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -EXSTYLE WS_EX_APPWINDOW -CAPTION "Lyrics batch download (From NetEase cloud music)" -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - PUSHBUTTON "Close",IDCANCEL,222,222,50,14 - CONTROL "",IDC_SONG_LIST1,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,93,265,126 - DEFPUSHBUTTON "Start download",IDC_START_DOWNLOAD,145,222,72,14 - LTEXT "Song list",IDC_STATIC,7,82,140,8 - CONTROL "Skip songs that already have lyrics",IDC_SKIP_EXIST_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,18,138,10 - COMBOBOX IDC_COMBO1,123,30,58,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP - GROUPBOX "Download Options",IDC_STATIC,7,7,265,72 - LTEXT "Saved encoding format:",IDC_STATIC,18,31,102,8 - LTEXT "",IDC_INFO_STATIC,43,226,101,8 - CONTROL "Download translated lyrics (If any)",IDC_DOWNLOAD_TRASNLATE_CHECK2, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,43,146,10 - LTEXT "Lyrics Save Location:",IDC_STATIC,18,56,102,8 - CONTROL "Save to the same directory as the song",IDC_SAVE_TO_SONG_FOLDER, - "Button",BS_AUTORADIOBUTTON,17,66,150,10 - CONTROL "Save to lyrics directory",IDC_SAVE_TO_LYRIC_FOLDER, - "Button",BS_AUTORADIOBUTTON,175,66,94,10 - LTEXT "progressbar",IDC_PROGRESS_BAR,7,225,32,8 -END - -IDD_LYRIC_DOWNLOAD_DIALOG DIALOGEX 0, 0, 274, 216 -STYLE DS_SETFONT | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -CAPTION "Lyric download (From NetEase cloud music)" -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - PUSHBUTTON "Close",IDCANCEL,217,195,50,14 - PUSHBUTTON "&Search",IDC_SEARCH_BUTTON2,221,6,46,14 - EDITTEXT IDC_TITLE_EDIT1,29,7,82,12,ES_AUTOHSCROLL - LTEXT "Title:",IDC_STATIC,7,7,20,11,SS_CENTERIMAGE - EDITTEXT IDC_ARTIST_EDIT1,145,7,72,12,ES_AUTOHSCROLL - LTEXT "Artist:",IDC_STATIC,117,7,27,11,SS_CENTERIMAGE - CONTROL "",IDC_LYRIC_DOWN_LIST1,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,31,260,97 - LTEXT "Search results:",IDC_STATIC_INFO,7,22,135,8 - DEFPUSHBUTTON "&Download selected",IDC_DOWNLOAD_SELECTED,44,195,85,14 - CONTROL "Download translated lyrics (If any)",IDC_DOWNLOAD_TRANSLATE_CHECK1, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,140,150,10 - GROUPBOX "Download options",IDC_STATIC,7,129,260,62 - COMBOBOX IDC_COMBO2,104,152,69,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Saved encoding format:",IDC_STATIC,12,153,90,8 - LTEXT "Lyrics Save Location:",IDC_STATIC,12,166,92,8 - CONTROL "Save to the same directory as the song",IDC_SAVE_TO_SONG_FOLDER1, - "Button",BS_AUTORADIOBUTTON,12,177,150,10 - CONTROL "Save to lyrics directory",IDC_SAVE_TO_LYRIC_FOLDER1, - "Button",BS_AUTORADIOBUTTON,166,177,97,10 - PUSHBUTTON "&Selected save as...",IDC_SELECTED_SAVE_AS,133,195,80,14 - CONTROL "Cancel Link",IDC_UNASSOCIATE_LINK,"SysLink",WS_TABSTOP,144,21,74,9 -END - -IDD_LYRIC_EDIT_DIALOG DIALOGEX 0, 0, 297, 242 -STYLE DS_SETFONT | DS_MODALFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU -EXSTYLE WS_EX_APPWINDOW -CAPTION "Edit Lyric" -MENU IDR_LYRIC_EDIT_MENU -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - EDITTEXT IDC_LYRIC_PATH_EDIT2,49,17,244,12,ES_AUTOHSCROLL | ES_READONLY - LTEXT "Lyric path:",IDC_STATIC1,4,18,43,8 -END - -IDD_LYRIC_SETTING_DIALOG DIALOGEX 0, 0, 338, 407 -STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - GROUPBOX "Lyric Options",IDC_STATIC,7,7,324,93 - CONTROL "Lyrics displayed in &karaoke style",IDC_KARAOKE_DISP, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,19,137,10 - CONTROL "Lyrics &fuzzy match",IDC_LYRIC_FUZZY_MATCH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,169,19,88,10 - LTEXT "Lyrics folder:",IDC_STATIC,17,58,47,8 - GROUPBOX "Show play information in taskbar search box",IDC_STATIC,7,284,324,114 - CONTROL "Allow play infomation displayed in &taskbar search box",IDC_SHOW_LYRIC_IN_CORTANA, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,296,215,10 - CONTROL "Lyrics displayed in &double line",IDC_LYRIC_DOUBLE_LINE_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,168,320,132,10 - LTEXT "Search box background color:",IDC_STATIC,149,308,103,8 - COMBOBOX IDC_CORTANA_COLOR_COMBO,255,306,67,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "Show &album cover in search box",IDC_SHOW_ALBUM_COVER_IN_CORTANA, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,333,143,10 - CONTROL "Cortana icon &beats following the music rhythm",IDC_CORTANA_ICON_DEAT_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,346,170,10 - CONTROL "Display lyrics using com&patibility mode",IDC_LYRIC_COMPATIBLE_MODE, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,382,151,10 - PUSHBUTTON "Set &Font...",IDC_SET_FONT,226,380,50,14 - LTEXT "Displayed Font:",IDC_STATIC,168,383,56,9 - CONTROL "&Keep on display when paused",IDC_KEEP_DISPLAY_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,192,345,126,11 - CONTROL "Show spectrum analysis in search box",IDC_SHOW_SPECTRUM_IN_CORTANA, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,168,333,142,11 - CONTROL "Show lyrics in search box",IDC_SHOW_LYRIC_IN_CORTANA2, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,308,117,11 - GROUPBOX "Desktop Lyrics",IDC_STATIC,8,157,323,120 - CONTROL "Show desktop lyrics",IDC_SHOW_DESKTOP_LYRIC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,168,117,10 - CONTROL "Lyrics displayed in &double line",IDC_LYRIC_DOUBLE_LINE_CHECK2, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,180,140,10 - PUSHBUTTON "Set &Font...",IDC_SET_FONT2,222,165,57,14 - LTEXT "Display font:",IDC_STATIC,171,168,48,8 - LTEXT "Text color:",IDC_STATIC,17,220,43,8 - LTEXT "",IDC_TEXT_COLOR1_STATIC,77,219,15,11,NOT WS_GROUP | WS_TABSTOP,WS_EX_STATICEDGE - LTEXT "",IDC_TEXT_COLOR2_STATIC,96,219,15,11,NOT WS_GROUP | WS_TABSTOP,WS_EX_STATICEDGE - COMBOBOX IDC_TEXT_GRADIENT_COMBO,183,219,80,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Text gradient:",IDC_STATIC,121,220,59,8 - LTEXT "Highlight color:",IDC_STATIC,17,235,56,8 - LTEXT "",IDC_HIGHLIGHT_COLOR1_STATIC,77,234,15,11,NOT WS_GROUP | WS_TABSTOP,WS_EX_STATICEDGE - LTEXT "",IDC_HIGHLIGHT_COLOR2_STATIC,96,234,15,11,NOT WS_GROUP | WS_TABSTOP,WS_EX_STATICEDGE - COMBOBOX IDC_HIGHLIGHT_GRADIENT_COMBO,183,234,80,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Highlight gradient:",IDC_STATIC,121,235,59,8 - CONTROL "",IDC_LYRIC_OPACITY_SLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,73,250,91,10 - LTEXT "Lyrics opacity:",IDC_STATIC,17,250,51,8 - LTEXT "100%",IDC_LYRIC_OPACITY_STATIC,170,250,24,8 - CONTROL "Lock desktop lyrics",IDC_LOCK_DESKTOP_LYRIC_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,169,179,150,11 - CONTROL "Hide lyrics window without lyrics",IDC_HIDE_LYRIC_WITHOUT_LYRIC_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,192,141,11 - CONTROL "Hide lyrics window when paused",IDC_HIDE_LYRIC_PAUSE_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,169,192,153,11 - PUSHBUTTON "Styles Preset",IDC_DEFAULT_STYLE,270,225,51,14 - CONTROL "Lyrics background penetrate",IDC_HIDE_LYRIC_WITHOUT_LYRIC_CHECK3, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,205,141,11 - CONTROL "",IDC_LYRIC_PATH_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x880,67,57,251,12 - LTEXT "Lyrics alignment:",IDC_STATIC,17,321,56,8 - COMBOBOX IDC_ALIGNMENT_COMBO,73,320,62,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "After lyrics modified:",IDC_STATIC,169,73,79,8 - COMBOBOX IDC_LYRIC_SAVE_COMBO,250,72,68,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "Use the Internal lyrics first",IDC_USE_INNER_LYRIC_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,72,135,10 - CONTROL "Show unlock button when locked",IDC_SHOW_UNLOCK_WHEN_LOCKED, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,169,206,152,10 - CONTROL "Show phonograph icon in the search box when there is no album cover",IDC_SHOW_DEFAULT_ALBUM_ICON_CHK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,358,286,10 - CONTROL "The search box background is transparent in Windows 10 light mode",IDC_SEARCH_BOX_TRANSPARENT_IN_WHITE_MODE, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,370,293,10 - GROUPBOX "Lyrics Display",IDC_STATIC,7,107,324,44 - LTEXT "Font:",IDC_STATIC,17,119,20,8 - PUSHBUTTON "Set &Font...",IDC_SET_FONT_BUTTON,41,117,54,14 - LTEXT "Lyrics line spacing:",IDC_STATIC,115,119,66,8 - EDITTEXT IDC_FONT_SIZE_EDIT2,184,117,30,12,ES_AUTOHSCROLL - LTEXT "pixel",IDC_STATIC,218,119,17,8 - LTEXT "Lyrics alignment:",IDC_STATIC,17,135,60,8 - COMBOBOX IDC_ALIGNMENT_COMBO2,77,134,64,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Lyrics alignment:",IDC_STATIC,17,264,55,8 - COMBOBOX IDC_DESKTOP_LYRIC_ALIGNMENT_COMBO,73,263,61,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "Show lyrics &translation (If any)",IDC_SHOW_LYRIC_TRANSLATE_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,44,113,10 - CONTROL "Do not display blank lines in single-line and double-line display mode",IDC_LYRIC_HIDE_BLANK_LINE_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,32,294,10 - CONTROL "Display song information when lyrics do not exist",IDC_SHOW_SONG_INFO_IF_LYRIC_NOT_EXIST_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,85,240,9 -END - -IDD_MP3_ENCODE_CFG_DIALOG DIALOGEX 0, 0, 209, 127 -STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "MP3 Encode Options" -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - CONTROL "Constant bit rate (CBR)",IDC_CBR_RADIO,"Button",BS_AUTORADIOBUTTON,7,7,98,10 - CONTROL "Average bit rate (ABR)",IDC_ABR_RADIO,"Button",BS_AUTORADIOBUTTON,7,21,94,10 - CONTROL "Variable bit rate (VBR) (recommended)",IDC_VBR_RADIO, - "Button",BS_AUTORADIOBUTTON,7,35,152,10 - CONTROL "Custom lame parameters",IDC_USER_RADIO,"Button",BS_AUTORADIOBUTTON,7,63,106,10 - COMBOBOX IDC_CBR_RATE_COMBO,107,7,64,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "kbps",IDC_STATIC,178,8,24,8 - COMBOBOX IDC_ABR_RATE_COMBO,107,21,64,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "kbps",IDC_STATIC,178,22,24,8 - LTEXT "Compression quality:",IDC_STATIC,15,48,79,8 - LTEXT "Encoder parameters:",IDC_STATIC,7,79,73,8 - EDITTEXT IDC_ENCODE_CMDLINE_EDIT,89,77,113,12,ES_AUTOHSCROLL - DEFPUSHBUTTON "OK",IDOK,96,106,50,14 - PUSHBUTTON "Cancel",IDCANCEL,152,106,50,14 - CONTROL "",IDC_SLIDER1,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,117,47,65,10 - LTEXT "low",IDC_STATIC,101,48,17,8 - LTEXT "High",IDC_STATIC,183,48,19,8 - CONTROL "Joint stereo encoding for dual channels",IDC_JOINT_STEREO_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,92,174,10 -END - -IDD_MUSICPLAYER2_DIALOG DIALOGEX 0, 0, 382, 250 -STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -EXSTYLE WS_EX_ACCEPTFILES | WS_EX_APPWINDOW -CAPTION "MusicPlayer" -CLASS "MusicPlayer_l3gwYT" -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - LTEXT "Folder:",IDC_PATH_STATIC,186,3,46,12,SS_CENTERIMAGE | WS_TABSTOP - CONTROL "",IDC_PLAYLIST_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | LVS_OWNERDATA | LVS_NOCOLUMNHEADER | WS_BORDER | WS_TABSTOP,185,42,190,200 - PUSHBUTTON "Media &Library...",ID_SET_PATH,321,1,54,13 - LTEXT "Toolbar",IDC_PLAYLIST_TOOLBAR,185,32,182,9 - CONTROL "",IDC_SEARCH_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x80,188,17,178,12 - LTEXT "UI Static",IDC_UI_STATIC,3,0,108,53 - CONTROL "",IDC_PATH_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x880,225,2,90,11 - CONTROL "",IDC_HSPLITER_STATIC,"Static",SS_BLACKFRAME,180,0,4,243 -END - -IDD_OGG_ENCODE_CFG_DIALOG DIALOGEX 0, 0, 199, 62 -STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "OGG Encode Options" -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - DEFPUSHBUTTON "OK",IDOK,86,41,50,14 - PUSHBUTTON "Cancel",IDCANCEL,142,41,50,14 - LTEXT "Encoding quality:",IDC_STATIC,7,7,63,8 - CONTROL "",IDC_QUALITY_SLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,93,7,80,10 - LTEXT "Current selected:",IDC_INFO_STATIC,7,22,142,8 - LTEXT "Low",IDC_STATIC,72,7,19,8 - LTEXT "High",IDC_STATIC,172,7,20,8 -END - -IDD_PLAY_SETTING_DIALOG DIALOGEX 0, 0, 338, 306 -STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - GROUPBOX "Play Options",IDC_STATIC,7,5,324,62 - CONTROL "Stop playing when an &error occurs",IDC_STOP_WHEN_ERROR, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,17,138,10 - CONTROL "Show playing &progress in the taskbar",IDC_SHOW_TASKBAR_PROGRESS, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,29,139,10 - GROUPBOX "Play Device",IDC_STATIC,7,119,324,88 - COMBOBOX IDC_OUTPUT_DEVICE_COMBO,89,131,212,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Select play device:",IDC_STATIC,17,132,71,8 - CONTROL "",IDC_OUTPUT_DEVICE_INFO_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,17,147,284,52 - CONTROL "&Auto play when the program starts",IDC_AUTO_PLAY_WHEN_START_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,157,17,149,10 - CONTROL "Show playing status &icon in the taskbar",IDC_SHOW_PLAY_STATE_ICON_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,157,29,149,10 - CONTROL "Sound &fade in and out effect",IDC_SOUND_FADE_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,42,131,10 - GROUPBOX "Player Kernal",IDC_STATIC,8,73,323,40 - CONTROL "BASS",IDC_BASS_RADIO,"Button",BS_AUTORADIOBUTTON,19,86,105,10 - CONTROL "MCI (Media Control Interface)",IDC_MCI_RADIO,"Button",BS_AUTORADIOBUTTON,139,86,129,10 - CONTROL "FFMPEG",IDC_FFMPEG_RADIO,"Button",BS_AUTORADIOBUTTON,19,98,54,10 - CONTROL "Continue playing when &switch playlist",IDC_CONTINUE_WHEN_SWITCH_PLAYLIST_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,157,42,140,10 - GROUPBOX "FFMPEG core settings",IDC_STATIC,7,213,324,82 - LTEXT "Cache length: ",IDC_STATIC,17,225,48,8 - EDITTEXT IDC_FFMPEG_CACHE_LENGTH,68,224,24,12,ES_AUTOHSCROLL - LTEXT "s",IDC_STATIC,97,225,10,8 - LTEXT "Max retry count: ",IDC_STATIC,17,240,60,8 - EDITTEXT IDC_FFMPEG_MAX_RETRY_COUNT,75,239,36,12,ES_AUTOHSCROLL - LTEXT "times (-1 is unlimited)",IDC_STATIC,114,240,103,8 - LTEXT "Retry interval: ",IDC_STATIC,17,255,60,8 - EDITTEXT IDC_FFMPEG_URL_RETRY_INTERVAL,68,254,24,12,ES_AUTOHSCROLL - LTEXT "seconds (non-local file only)",IDC_STATIC,96,255,122,8 - CONTROL "Click here to download",IDC_FFMPEG_DOWN_SYSLINK, - "SysLink",WS_TABSTOP,75,98,177,10 - CONTROL "Enable WASAPI",IDC_FFMPEG_ENABLE_WASAPI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,267,60,10 - CONTROL "Enable exclusive mode",IDC_FFMPEG_ENABLE_WASAPI_EXCLUSIVE, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,173,267,84,10 - LTEXT "Maximum waiting time when performing a seek operation:",IDC_STATIC,19,279,192,8 - EDITTEXT IDC_FFMPEG_MAX_WAIT_TIME,206,278,40,12,ES_AUTOHSCROLL - LTEXT "ms",IDC_STATIC,249,279,16,8 - CONTROL "Use system &media transport controls (Need to restart)",IDC_USE_MEDIA_TRANS_CONTORL_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,54,213,10 -END - -IDD_PROPERTY_DIALOG DIALOGEX 0, 0, 323, 142 -STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - EDITTEXT IDC_FILE_NAME_EDIT,51,15,104,12,ES_AUTOHSCROLL | ES_READONLY - EDITTEXT IDC_FILE_PATH_EDIT,51,30,104,12,ES_AUTOHSCROLL | ES_READONLY - EDITTEXT IDC_FILE_TYPE_EDIT,51,45,104,12,ES_AUTOHSCROLL | ES_READONLY - EDITTEXT IDC_LYRIC_FILE_EDIT,51,105,104,12,ES_AUTOHSCROLL | ES_READONLY - EDITTEXT IDC_TITEL_EDIT,214,15,98,12,ES_AUTOHSCROLL | ES_READONLY - EDITTEXT IDC_ARTIST_EDIT,214,30,98,12,ES_AUTOHSCROLL | ES_READONLY - EDITTEXT IDC_ALBUM_EDIT,214,45,98,12,ES_AUTOHSCROLL | ES_READONLY - EDITTEXT IDC_TRACK_EDIT,214,60,27,12,ES_AUTOHSCROLL | ES_READONLY - EDITTEXT IDC_YEAR_EDIT,273,60,39,12,ES_AUTOHSCROLL | ES_READONLY - EDITTEXT IDC_COMMENT_EDIT,214,90,98,17,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | ES_WANTRETURN | WS_VSCROLL - LTEXT "File name:",IDC_STATIC,10,18,35,8 - LTEXT "File path:",IDC_STATIC,10,32,35,8 - LTEXT "File type:",IDC_STATIC,10,47,35,8 - GROUPBOX "File information",IDC_STATIC,5,4,156,116 - LTEXT "Title:",IDC_STATIC,175,18,22,8 - LTEXT "Artist:",IDC_STATIC,175,32,28,8 - LTEXT "Album:",IDC_STATIC,175,47,28,8 - GROUPBOX "Tag information",IDC_STATIC,168,4,149,116 - LTEXT "Year:",IDC_STATIC,250,61,22,8 - LTEXT "Genre:",IDC_STATIC,175,77,30,8 - LTEXT "Comment:",IDC_STATIC,175,92,39,8 - LTEXT "Track:",IDC_STATIC,175,62,35,8 - LTEXT "Static",IDC_TAG_TYPE_STATIC,175,109,136,8 - LTEXT "Lyric file:",IDC_LYRIC_FILE_STATIC,10,106,35,8 - COMBOBOX IDC_GENRE_COMBO,214,76,98,38,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Get tag online...",IDC_GET_TAG_ONLINE_BUTTON,173,123,62,14 - PUSHBUTTON "Get tag from lyrics",IDC_GET_TAG_FROM_LYRIC_BUTTON,99,123,70,14 - PUSHBUTTON "Get tag from file name...",IDC_GET_TAG_FROM_FILE_NAME_BUTTON,5,123,90,14 - EDITTEXT IDC_SONG_LENGTH_EDIT,51,60,33,12,ES_AUTOHSCROLL | ES_READONLY - EDITTEXT IDC_FILE_SIZE_EDIT,122,60,33,12,ES_AUTOHSCROLL | ES_READONLY - EDITTEXT IDC_BIT_RATE_EDIT,51,75,33,12,ES_AUTOHSCROLL | ES_READONLY - LTEXT "Length:",IDC_STATIC,10,62,30,8 - LTEXT "File size:",IDC_STATIC,87,61,33,8 - LTEXT "Bit rate:",IDC_STATIC,10,76,30,8 - EDITTEXT IDC_SAMPLE_FREQ,51,90,33,12,ES_AUTOHSCROLL | ES_READONLY - LTEXT "Frequency:",IDC_STATIC,10,91,39,8 - EDITTEXT IDC_CHANNELS,122,75,33,12,ES_AUTOHSCROLL | ES_READONLY - LTEXT "Channels:",IDC_STATIC,87,76,34,8 - EDITTEXT IDC_BITS_DIPTH,122,90,33,12,ES_AUTOHSCROLL | ES_READONLY - LTEXT "Bit depth:",IDC_STATIC,87,91,34,8 -END - -IDD_REVERB_DIALOG DIALOGEX 0, 0, 258, 139 -STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - CONTROL "Enable reverb",IDC_ENABLE_REVERB_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,7,77,10 - CONTROL "",IDC_REVERB_MIX_SLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,65,25,100,13 - CONTROL "",IDC_REVERB_TIME_SLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,65,44,100,13 - LTEXT "Reverb strength:",IDC_STATIC,7,27,58,8 - LTEXT "Reverb time:",IDC_STATIC,7,46,54,8 - LTEXT "x%",IDC_REVERB_MIX_STATIC,167,27,37,8 - LTEXT "0.00s",IDC_REVERB_TIME_STATIC,167,46,37,8 -END - -IDD_SET_PATH_DIALOG DIALOGEX 0, 0, 294, 172 -STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU -EXSTYLE WS_EX_APPWINDOW -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - LTEXT "Current folder:",IDC_STATIC,4,6,49,8 - PUSHBUTTON "&Open New Folder...",IDC_OPEN_FOLDER,219,3,70,14 - EDITTEXT IDC_PATH_EDIT,60,4,156,12,ES_AUTOHSCROLL | ES_READONLY - CONTROL "",IDC_PATH_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,4,34,285,134 - CONTROL "",IDC_SEARCH_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x80,4,19,285,13 -END - -IDD_SOUND_EFFECT_DIALOG DIALOGEX 0, 0, 302, 144 -STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Sound Effect Settings" -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - PUSHBUTTON "Close",IDCANCEL,245,123,50,14 - CONTROL "",IDC_TAB1,"SysTabControl32",0x0,7,7,288,113 -END - -IDD_SUPPORT_FORMAT_DIALOG DIALOGEX 0, 0, 275, 182 -STYLE DS_SETFONT | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -CAPTION "Supported Formats" -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - DEFPUSHBUTTON "OK",IDOK,218,161,50,14 - LTEXT "",IDC_INFO_STATIC,7,7,261,34 - CONTROL "",IDC_FORMAT_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,42,261,114 -END - -IDD_TAG_EDIT_DIALOG DIALOGEX 0, 0, 163, 163 -STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Edit Audio Tags" -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - PUSHBUTTON "Close",IDCANCEL,106,142,50,14 - EDITTEXT IDC_TITEL_EDIT,43,22,113,12,ES_AUTOHSCROLL - EDITTEXT IDC_ARTIST_EDIT,43,37,113,12,ES_AUTOHSCROLL - EDITTEXT IDC_ALBUM_EDIT,43,52,113,12,ES_AUTOHSCROLL - EDITTEXT IDC_TRACK_EDIT,43,67,33,12,ES_AUTOHSCROLL - EDITTEXT IDC_YEAR_EDIT,111,67,45,12,ES_AUTOHSCROLL - EDITTEXT IDC_COMMENT_EDIT,43,97,113,36,ES_MULTILINE | WS_VSCROLL - LTEXT "Title:",IDC_STATIC,7,25,22,8 - LTEXT "Artist:",IDC_STATIC,7,39,28,8 - LTEXT "Album:",IDC_STATIC,7,54,28,8 - LTEXT "Year:",IDC_STATIC,82,68,22,8 - LTEXT "Genre:",IDC_STATIC,7,84,28,8 - LTEXT "Comment:",IDC_STATIC,7,99,34,8 - LTEXT "Track:",IDC_STATIC,7,69,28,8 - COMBOBOX IDC_GENRE_COMBO,43,83,113,38,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "<",IDC_PREVIOUS_BUTTON,7,142,15,14 - PUSHBUTTON ">",IDC_NEXT_BUTTON,24,142,15,14 - LTEXT "Static",IDC_ITEM_STATIC,7,134,45,8 - EDITTEXT IDC_PATH_EDIT,43,7,113,12,ES_AUTOHSCROLL | ES_READONLY - LTEXT "Path:",IDC_STATIC,7,10,28,8 - PUSHBUTTON "Save",IDC_SAVE_BUTTON,51,142,50,14 -END - -IDD_WMA_ENCODE_CFG_DIALOG DIALOGEX 0, 0, 190, 65 -STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "WMA Encode Options" -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - DEFPUSHBUTTON "OK",IDOK,78,44,50,14 - PUSHBUTTON "Cancel",IDCANCEL,133,44,50,14 - COMBOBOX IDC_BITRATE_COMBO,101,7,54,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "kbps",IDC_STATIC,159,8,24,8 - CONTROL "Constant bit rate (CBR):",IDC_CBR_RADIO,"Button",BS_AUTORADIOBUTTON,7,7,92,10 - COMBOBOX IDC_VBR_QUALITY_COMBO,101,24,54,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "Quality-based VBR:",IDC_CBR_RADIO2,"Button",BS_AUTORADIOBUTTON,7,24,81,10 - LTEXT "%",IDC_STATIC,159,25,24,8 -END - -IDD_LISTEN_TIME_STATISTICS_DLG DIALOGEX 0, 0, 328, 172 -STYLE DS_SETFONT | DS_MODALFRAME | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Total Play Time Statistics" -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - DEFPUSHBUTTON "&Close",IDOK,271,151,50,14 - CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,7,314,140 - PUSHBUTTON "&Export...",IDC_EXPORT_BUTTON,7,151,50,14 - PUSHBUTTON "Clear",IDC_CLEAR_BUTTON,65,151,57,14 -END - -IDD_DONATE_DIALOG DIALOGEX 0, 0, 229, 138 -STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Donate" -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - PUSHBUTTON "Close",IDCANCEL,172,117,50,14 - LTEXT "If you think this software is helpful to you, you can scan the following QR code through Alipay or WeChart Pay to donate the author to help the author to make this software better. Please feel free for the amount.",IDC_DONATE_STATIC,7,7,215,36 -END - -IDD_MEDIA_LIB_DIALOG DIALOGEX 0, 0, 346, 224 -STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -EXSTYLE WS_EX_APPWINDOW -CAPTION "Media Library" -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - PUSHBUTTON "Close",IDCANCEL,291,205,50,14 - CONTROL "",IDC_TAB1,"SysTabControl32",0x0,5,4,336,197 - PUSHBUTTON "Play Selected",IDC_PLAY_SELECTED,223,205,64,14 - PUSHBUTTON "Media Library &Settings...",IDC_MEDIA_LIB_SETTINGS_BTN,5,205,96,14 - PUSHBUTTON "&Statistics",IDC_STATISTICS_INFO_BUTTON,107,205,50,14 -END - -IDD_INPUT_DLG DIALOGEX 0, 0, 183, 67 -STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Dialog" -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - DEFPUSHBUTTON "OK",IDOK,70,46,50,14 - PUSHBUTTON "Cancel",IDCANCEL,126,46,50,14 - EDITTEXT IDC_INPUT_EDIT,7,25,169,12,ES_AUTOHSCROLL - LTEXT "Static",IDC_INFO_STATIC,7,7,169,13 -END - -IDD_SELECT_PLAYLIST_DIALOG DIALOGEX 0, 0, 331, 178 -STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,4,21,154,153 - PUSHBUTTON "&New Playlist...",IDC_NEW_PLAYLIST,4,4,65,14 - CONTROL "",IDC_SEARCH_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x80,147,5,179,13 - CONTROL "",IDC_SONG_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | LVS_OWNERDATA | WS_BORDER | WS_TABSTOP,162,21,164,153 - CONTROL "",IDC_HSPLITER_STATIC,"Static",SS_BLACKFRAME,158,21,4,153 -END - -IDD_FILE_RELATE_DIALOG DIALOGEX 0, 0, 271, 182 -STYLE DS_SETFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -CAPTION "File Relate" -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - DEFPUSHBUTTON "OK",IDOK,158,161,50,14 - PUSHBUTTON "Cancel",IDCANCEL,214,161,50,14 - CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,7,257,150 - CONTROL "Select &All",IDC_SELECT_ALL_CHECK,"Button",BS_AUTO3STATE | WS_TABSTOP,7,162,50,11 - PUSHBUTTON "&Default",IDC_DEFAULT_BUTTON,57,161,45,14 -END - -IDD_ADD_TO_PLAYLIST_DIALOG DIALOGEX 0, 0, 186, 138 -STYLE DS_SETFONT | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -CAPTION "Select Playlist" -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - DEFPUSHBUTTON "OK",IDOK,74,117,50,14 - PUSHBUTTON "Cancel",IDCANCEL,129,117,50,14 - CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,22,172,91 - CONTROL "",IDC_SEARCH_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x80,7,7,172,12 -END - -IDD_MEDIA_LIB_SETTING_DIALOG DIALOGEX 0, 0, 342, 573 -STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - GROUPBOX "Media Library Directory",IDC_STATIC,6,108,329,66 - CONTROL "",IDC_DIR_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,14,120,228,47 - PUSHBUTTON "&Add...",IDC_ADD_BUTTON,251,124,50,14 - PUSHBUTTON "&Delete",IDC_DELETE_BUTTON,251,142,50,14 - GROUPBOX "Media Library Options",IDC_STATIC,6,4,329,98 - CONTROL "Classify only-one items into others",IDC_CLASSIFY_OTHER_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,18,187,10 - CONTROL "Automatically update media library on startup",IDC_UPDATE_MEDIA_LIB_CHK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,30,185,10 - LTEXT "Current data file size:",IDC_SIZE_STATIC,14,376,297,8 - PUSHBUTTON "&Clean up...",IDC_CLEAN_DATA_FILE_BUTTON,14,387,59,14 - GROUPBOX "Clean up the media library",IDC_STATIC,6,365,329,40 - PUSHBUTTON "Clear recently played tracks list...",IDC_CLEAR_RECENT_PLAYED_LIST_BTN,14,341,123,14 - GROUPBOX "Recently played",IDC_STATIC,6,315,329,45 - GROUPBOX "Playlist",IDC_STATIC,6,226,329,82 - CONTROL "Disable drag and drop sorting of playlist",IDC_DISABLE_DRAGE_SORT_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,237,149,11 - LTEXT "Playlist Display Mode:",IDC_STATIC,14,252,80,9 - COMBOBOX IDC_PLAYLIST_DISPLAY_MODE_OMBO,96,250,133,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Recently played display range:",IDC_STATIC,16,328,113,8 - COMBOBOX IDC_RECENT_PLAYED_RANGE_OMBO,131,326,125,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "Insert at the beginning of the playlist instead of appending to the end",IDC_INSERT_BEGIN_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,265,263,10 - GROUPBOX "Items displayed in the media library",IDC_STATIC,6,180,329,39 - CONTROL "Artist",IDC_ARTIST_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,192,41,10 - CONTROL "Album",IDC_ALBUM_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,60,192,41,10 - CONTROL "Genre",IDC_GENRE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,111,192,39,10 - CONTROL "Year",IDC_YEAR_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,167,192,33,10 - CONTROL "File type",IDC_FILE_TYPE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,238,192,49,10 - CONTROL "Bitrate",IDC_BITRATE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,205,41,10 - CONTROL "All tracks",IDC_ALL_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,111,205,49,10 - CONTROL "Recently played",IDC_RECENT_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,167,205,69,10 - CONTROL "Folder explore",IDC_FOLDER_EXPLORE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,238,205,73,10 - CONTROL "Rating",IDC_RATING_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,60,205,33,10 - GROUPBOX "Music tag reading and writing",IDC_STATIC,6,412,329,30 - LTEXT "ID3v2 write type:",IDC_STATIC,15,425,66,9 - COMBOBOX IDC_ID3V2_TYPE_COMBO,80,424,52,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "&Refresh media library",IDC_REFRESH_MEDIA_LIB_BUTTON,218,20,85,13 - CONTROL "Disable delete from disk",IDC_DISABLE_DELETE_FROM_DISK_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,66,128,9 - CONTROL "Show playlist tool tip",IDC_SHOW_PLAYLIST_TOOLTIP_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,278,136,9 - GROUPBOX "Last.fm",IDC_STATIC,6,447,329,119 - CONTROL "Enable last.fm support",IDC_ENABLE_LASTFM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,456,87,10 - LTEXT "Current status: ",IDC_STATIC,14,469,49,8 - LTEXT "Status",IDC_LASTFM_STATUS,65,469,190,8 - PUSHBUTTON "Log in",IDC_LASTFM_LOGIN,264,465,50,14,WS_DISABLED - LTEXT "Cache scrobble when following conditions are meeted:",IDC_STATIC,14,481,289,8 - LTEXT "Played",IDC_STATIC,14,494,28,8 - EDITTEXT IDC_LASTFM_LEAST_PERDUR,44,493,30,12,ES_AUTOHSCROLL - LTEXT "% of the song and",IDC_STATIC,78,494,64,8 - EDITTEXT IDC_LASTFM_LEAST_DUR,142,493,30,12,ES_AUTOHSCROLL - LTEXT "Seconds.",IDC_STATIC,176,494,34,8 - CONTROL "Upload scrobbles in cache if the number of cached scrobbles is greater than ",IDC_LASTFM_AUTO_SCROBBLE, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,507,267,10 - EDITTEXT IDC_LASTFM_AUTO_SCROBBLE_MIN,281,507,30,12,ES_AUTOHSCROLL - LTEXT "Cache status:",IDC_STATIC,14,523,42,8 - LTEXT "X scrobbles",IDC_LASTFM_CACHE_STATUS,58,523,196,8 - PUSHBUTTON "Upload cache",IDC_LASTFM_UPLOAD_CACHE,264,522,50,14 - CONTROL "Use HTTPS when communicating with the last.fm server.",IDC_LASTFM_ENABLE_HTTPS, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,536,263,10 - CONTROL "Upload now playing track",IDC_LASTFM_ENABLE_NOWPLAYING, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,549,97,10 - LTEXT "Playlist item height:",IDC_STATIC,14,293,83,8 - EDITTEXT IDC_PLAYLIST_ITEM_HEIGHT_EDIT,97,291,39,12,ES_AUTOHSCROLL - LTEXT "pixel",IDC_STATIC,138,293,30,8 - CONTROL "Remove non-existing audio files when updating media library",IDC_REMOVE_FILE_NOT_EXIST_WHEN_UPDATE_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,54,244,10 - LTEXT "Artist Recognition Exception:",IDC_STATIC,16,81,99,8 - CONTROL "",IDC_ARTIST_SPLIT_EXT_EDIT,"MfcEditBrowse",WS_BORDER | WS_TABSTOP | 0x80,117,80,203,11 - CONTROL "Ignore audio files with durations below the threshold when updating the media library",IDC_IGNORE_TOO_SHORT_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,42,301,10 - LTEXT "Audio file low duration threshold:",IDC_STATIC,135,66,113,8 - LTEXT "seconds",IDC_STATIC,291,66,28,8 - EDITTEXT IDC_FILE_TOO_SHORT_SEC_EDIT,248,64,40,12,ES_AUTOHSCROLL - CONTROL "Floating playlist follows main window",IDC_FLOAT_PLAYLIST_FOLLOW_MAIN_WND_CHECK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,172,278,145,10 -END - -IDD_LYRIC_RELATE_DIALOG DIALOGEX 0, 0, 329, 178 -STYLE DS_SETFONT | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -CAPTION "Link local lyrics" -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - DEFPUSHBUTTON "Link selected lyrics",IDOK,188,157,79,14 - PUSHBUTTON "Cancel",IDCANCEL,272,157,50,14 - PUSHBUTTON "Unlink lyrics",IDC_DONOT_RELATE_BUTTON,7,157,58,14 - LTEXT "Lyrics title:",IDC_STATIC,7,8,44,8 - EDITTEXT IDC_LYRIC_NAME_EDIT,52,7,140,12,ES_AUTOHSCROLL - CONTROL "Partial match",IDC_FUZZY_MATCH_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,197,8,64,10 - PUSHBUTTON "Local &Search",IDC_LOCAL_SEARCH_BUTTON,262,7,60,14 - CONTROL "",IDC_SEARCH_RESULT_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,32,249,119 - LTEXT "Search results:",IDC_STATIC,7,22,144,8 - PUSHBUTTON "&Browse...",IDC_BROWSE_BUTTON1,262,32,60,14 - PUSHBUTTON "&Delete File",IDC_DELETE_FILE_BUTTON,262,54,60,14 -END - -IDD_CLEAN_UP_RANGE_DIALOG DIALOGEX 0, 0, 167, 114 -STYLE DS_SETFONT | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -CAPTION "Clean up the media library" -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - DEFPUSHBUTTON "OK",IDOK,52,93,50,14 - PUSHBUTTON "Cancel",IDCANCEL,110,93,50,14 - LTEXT "Please select the range you want to clean:",IDC_STATIC,7,7,153,8 - CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,18,153,70 -END - -IDD_PROPERTY_ALBUM_COVER_DIALOG DIALOGEX 0, 0, 304, 128 -STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,159,4,138,91 - PUSHBUTTON "&Browse...",IDC_BROWSE_BUTTON,159,98,50,14 - PUSHBUTTON "&Delete",IDC_DELETE_BUTTON,212,98,50,14 - CONTROL "&Embed external album cover into the audio file",IDC_SAVE_ALBUM_COVER_BUTTON, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,160,114,137,10 - CONTROL "Show &external album cover",IDC_SHOW_OUT_ALBUM_COVER_CHK, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,113,143,10 -END - -IDD_PROPERTY_PARENT_DIALOG DIALOGEX 0, 0, 335, 181 -STYLE DS_SETFONT | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -CAPTION "Property" -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - PUSHBUTTON "&Close",IDCANCEL,281,162,50,14 - PUSHBUTTON "&Previous",IDC_PREVIOUS_BUTTON,4,162,46,14 - PUSHBUTTON "&Next",IDC_NEXT_BUTTON,53,162,46,14 - LTEXT "Static",IDC_ITEM_STATIC,101,165,45,8 - PUSHBUTTON "&Save to file",IDC_SAVE_TO_FILE_BUTTON,221,162,56,14 - CONTROL "",IDC_TAB1,"SysTabControl32",0x0,4,4,327,155 -END - -IDD_TAG_FROM_FILE_NAME_DIALOG DIALOGEX 0, 0, 215, 134 -STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Get tag from file name" -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - DEFPUSHBUTTON "OK",IDOK,94,113,50,14 - PUSHBUTTON "Cancel",IDCANCEL,158,113,50,14 - COMBOBOX IDC_COMBO1,7,18,201,30,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - LTEXT "Please input the format of the file name:",IDC_STATIC,7,7,168,8 - LTEXT "Title:",IDC_STATIC,7,36,27,8 - PUSHBUTTON "",IDC_TITLE_BUTTON,44,33,56,14 - LTEXT "Artist:",IDC_STATIC,116,36,29,8 - PUSHBUTTON "",IDC_ARTIST_BUTTON,146,33,56,14 - LTEXT "Album:",IDC_STATIC,7,53,27,8 - PUSHBUTTON "",IDC_ALBUM_BUTTON,44,50,56,14 - LTEXT "Track:",IDC_STATIC,116,53,29,8 - PUSHBUTTON "",IDC_TRACK_BUTTON,146,50,56,14 - LTEXT "Year:",IDC_STATIC,7,70,27,8 - PUSHBUTTON "",IDC_YEAR_BUTTON,44,67,56,14 - LTEXT "Genre:",IDC_STATIC,116,70,29,8 - PUSHBUTTON "",IDC_GENRE_BUTTON,146,67,56,14 - LTEXT "When click the button:",IDC_STATIC,7,102,99,8 - CONTROL "Insert",IDC_INSERT_RADIO,"Button",BS_AUTORADIOBUTTON,89,101,38,10 - CONTROL "Copy to clipboard",IDC_COPY_RADIO,"Button",BS_AUTORADIOBUTTON,134,101,76,10 - LTEXT "Comment:",IDC_STATIC,7,87,42,8 - PUSHBUTTON "",IDC_COMMENT_BUTTON,44,84,56,14 - LTEXT "Original:",IDC_ORIGINAL_STATIC,116,87,29,8 - PUSHBUTTON "",IDC_ORIGINAL_BUTTON,146,84,56,14 -END - -IDD_SELECT_ITEM_DIALOG DIALOGEX 0, 0, 135, 87 -STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -CAPTION "Dialog" -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - DEFPUSHBUTTON "OK",IDOK,24,66,50,14 - PUSHBUTTON "Cancel",IDCANCEL,78,66,50,14 - CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,7,121,55 -END - -IDD_FLAC_ENCODE_CFG_DIALOG DIALOGEX 0, 0, 210, 96 -STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Flac Encode Options" -FONT 9, "Segoe UI", 400, 0, 0x0 -BEGIN - DEFPUSHBUTTON "OK",IDOK,95,75,50,14 - PUSHBUTTON "Cancel",IDCANCEL,153,75,50,14 - LTEXT "Compression level:",IDC_STATIC,7,8,71,8 - CONTROL "",IDC_SLIDER1,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,105,7,76,10 - LTEXT "Low",IDC_STATIC,84,8,23,8 - LTEXT "High",IDC_STATIC,182,8,21,8 - LTEXT "Current selected:",IDC_STATIC,7,20,72,8 - LTEXT "Static",IDC_COMP_LEVEL_STATIC,85,20,22,8 - CONTROL "Custom flac parameters",IDC_SPECIFY_PARA_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,34,149,10 - LTEXT "Encoder parameters:",IDC_STATIC,7,48,76,8 - EDITTEXT IDC_EDIT1,86,46,99,12,ES_AUTOHSCROLL -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_ABOUTBOX, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 215 - TOPMARGIN, 7 - BOTTOMMARGIN, 136 - END - - IDD_APPEREANCE_SETTING_DLG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 331 - VERTGUIDE, 12 - VERTGUIDE, 18 - TOPMARGIN, 7 - BOTTOMMARGIN, 463 - END - - IDD_OPTIONS_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 5 - RIGHTMARGIN, 356 - TOPMARGIN, 4 - BOTTOMMARGIN, 241 - END - - IDD_COVER_DOWNLOAD_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 250 - TOPMARGIN, 7 - BOTTOMMARGIN, 197 - END - - IDD_DATA_SETTINGS_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 330 - VERTGUIDE, 15 - TOPMARGIN, 6 - BOTTOMMARGIN, 259 - HORZGUIDE, 2 - END - - IDD_EQUALIZER_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 292 - TOPMARGIN, 7 - BOTTOMMARGIN, 100 - HORZGUIDE, 81 - END - - IDD_FIND_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 266 - TOPMARGIN, 7 - BOTTOMMARGIN, 204 - END - - IDD_FORMAT_CONVERT_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 262 - TOPMARGIN, 7 - BOTTOMMARGIN, 246 - END - - IDD_MESSAGE_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 228 - TOPMARGIN, 7 - BOTTOMMARGIN, 169 - END - - IDD_HOT_KEY_SETTINGS_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 248 - TOPMARGIN, 7 - END - - IDD_LYRIC_BATCH_DOWN_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 272 - TOPMARGIN, 7 - BOTTOMMARGIN, 236 - END - - IDD_LYRIC_DOWNLOAD_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 267 - TOPMARGIN, 7 - BOTTOMMARGIN, 209 - END - - IDD_LYRIC_EDIT_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 4 - RIGHTMARGIN, 293 - TOPMARGIN, 3 - BOTTOMMARGIN, 235 - END - - IDD_LYRIC_SETTING_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 331 - VERTGUIDE, 17 - VERTGUIDE, 168 - TOPMARGIN, 7 - BOTTOMMARGIN, 403 - END - - IDD_MP3_ENCODE_CFG_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 202 - TOPMARGIN, 7 - BOTTOMMARGIN, 120 - END - - IDD_MUSICPLAYER2_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 2 - RIGHTMARGIN, 375 - BOTTOMMARGIN, 243 - END - - IDD_OGG_ENCODE_CFG_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 192 - TOPMARGIN, 7 - BOTTOMMARGIN, 55 - END - - IDD_PLAY_SETTING_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 331 - VERTGUIDE, 17 - TOPMARGIN, 7 - BOTTOMMARGIN, 301 - END - - IDD_PROPERTY_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 5 - RIGHTMARGIN, 317 - VERTGUIDE, 8 - TOPMARGIN, 4 - BOTTOMMARGIN, 137 - END - - IDD_REVERB_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 251 - TOPMARGIN, 7 - BOTTOMMARGIN, 132 - END - - IDD_SET_PATH_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 4 - RIGHTMARGIN, 289 - TOPMARGIN, 4 - BOTTOMMARGIN, 168 - END - - IDD_SOUND_EFFECT_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 295 - TOPMARGIN, 7 - BOTTOMMARGIN, 137 - END - - IDD_SUPPORT_FORMAT_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 268 - TOPMARGIN, 7 - BOTTOMMARGIN, 175 - END - - IDD_TAG_EDIT_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 156 - TOPMARGIN, 7 - BOTTOMMARGIN, 156 - END - - IDD_WMA_ENCODE_CFG_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 183 - TOPMARGIN, 7 - BOTTOMMARGIN, 58 - END - - IDD_LISTEN_TIME_STATISTICS_DLG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 321 - TOPMARGIN, 7 - BOTTOMMARGIN, 165 - END - - IDD_DONATE_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 222 - TOPMARGIN, 7 - BOTTOMMARGIN, 131 - END - - IDD_MEDIA_LIB_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 5 - RIGHTMARGIN, 341 - TOPMARGIN, 4 - BOTTOMMARGIN, 219 - END - - IDD_INPUT_DLG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 176 - TOPMARGIN, 7 - BOTTOMMARGIN, 60 - END - - IDD_SELECT_PLAYLIST_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 4 - RIGHTMARGIN, 326 - TOPMARGIN, 4 - BOTTOMMARGIN, 174 - END - - IDD_FILE_RELATE_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 264 - TOPMARGIN, 7 - BOTTOMMARGIN, 175 - END - - IDD_ADD_TO_PLAYLIST_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 179 - TOPMARGIN, 7 - BOTTOMMARGIN, 131 - END - - IDD_MEDIA_LIB_SETTING_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 6 - RIGHTMARGIN, 335 - VERTGUIDE, 14 - TOPMARGIN, 4 - BOTTOMMARGIN, 569 - END - - IDD_LYRIC_RELATE_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 322 - TOPMARGIN, 7 - BOTTOMMARGIN, 171 - END - - IDD_CLEAN_UP_RANGE_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 160 - TOPMARGIN, 7 - BOTTOMMARGIN, 107 - END - - IDD_PROPERTY_ALBUM_COVER_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 297 - TOPMARGIN, 4 - BOTTOMMARGIN, 123 - END - - IDD_PROPERTY_PARENT_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 4 - RIGHTMARGIN, 331 - TOPMARGIN, 4 - BOTTOMMARGIN, 176 - END - - IDD_TAG_FROM_FILE_NAME_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 208 - TOPMARGIN, 7 - BOTTOMMARGIN, 127 - END - - IDD_SELECT_ITEM_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 128 - TOPMARGIN, 7 - BOTTOMMARGIN, 80 - END - - IDD_FLAC_ENCODE_CFG_DIALOG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 203 - TOPMARGIN, 7 - BOTTOMMARGIN, 89 - END -END -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// AFX_DIALOG_LAYOUT -// - -IDD_ABOUTBOX AFX_DIALOG_LAYOUT -BEGIN - 0 -END - -IDD_APPEREANCE_SETTING_DLG AFX_DIALOG_LAYOUT +IDD_COVER_DOWNLOAD_DIALOG AFX_DIALOG_LAYOUT BEGIN 0, 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 100, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0 -END - -IDD_OPTIONS_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0, - 100, 100, 0, 0, - 100, 100, 0, 0, - 0, 0, 100, 100, - 100, 100, 0, 0 -END - -IDD_COVER_DOWNLOAD_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0, - 100, 100, 0, 0, 100, 0, 0, 0, - 0, 0, 50, 0, 0, 0, 0, 0, - 50, 0, 50, 0, - 50, 0, 0, 0, - 0, 0, 100, 100, 0, 0, 100, 0, - 100, 100, 0, 0, + 0, 0, 100, 0, 100, 0, 0, 0, + 0, 0, 100, 100, 0, 100, 100, 0, - 0, 100, 0, 0, - 0, 100, 0, 0, - 0, 100, 0, 0 + 0, 100, 100, 0, + 0, 100, 100, 0, + 0, 100, 100, 0, + 100, 100, 0, 0, + 100, 100, 0, 0 END IDD_DATA_SETTINGS_DIALOG AFX_DIALOG_LAYOUT BEGIN - 0 + 0, + 0, 0, 44, 0, + 0, 0, 44, 0, + 0, 0, 44, 0, + 0, 0, 44, 0, + 0, 0, 44, 0, + 0, 0, 44, 0, + 0, 0, 44, 0, + 0, 0, 44, 0, + 44, 0, 56, 0, + 44, 0, 56, 0, + 44, 0, 56, 0, + 44, 0, 56, 0, + 44, 0, 56, 0, + 44, 0, 56, 0, + 44, 0, 56, 0, + 0, 0, 100, 0, + 0, 0, 100, 0, + 0, 0, 100, 0, + 44, 0, 56, 0, + 0, 0, 44, 0, + 0, 0, 100, 0, + 0, 0, 100, 0, + 44, 0, 56, 0, + 0, 0, 44, 0, + 0, 0, 100, 0, + 0, 0, 100, 0, + 0, 0, 100, 0, + 0, 0, 44, 0, + 44, 0, 56, 0 END IDD_EQUALIZER_DIALOG AFX_DIALOG_LAYOUT @@ -5396,117 +2259,179 @@ END IDD_FIND_DIALOG AFX_DIALOG_LAYOUT BEGIN 0, - 100, 100, 0, 0, - 100, 100, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 100, 0, + 100, 0, 0, 0, + 0, 0, 32, 0, + 0, 0, 32, 0, + 0, 0, 32, 0, + 32, 0, 68, 0, + 32, 0, 34, 0, + 66, 0, 34, 0, + 32, 0, 34, 0, + 66, 0, 34, 0, + 0, 0, 32, 0, + 32, 0, 68, 0, 0, 0, 100, 100, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 100, 0 + 100, 100, 0, 0, + 100, 100, 0, 0 END IDD_FORMAT_CONVERT_DIALOG AFX_DIALOG_LAYOUT BEGIN 0, - 0, 0, 100, 100, 0, 0, 0, 0, 0, 0, 100, 0, - 0, 100, 0, 0, - 100, 100, 0, 0, 100, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 100, 100, 0, 100, 100, 0, 0, 100, 0, 0, 0, 100, 0, 0, + 0, 100, 50, 0, + 50, 100, 50, 0, 0, 100, 0, 0, - 0, 100, 0, 0, - 0, 100, 0, 0, - 0, 0, 0, 0, - 100, 100, 0, 0, 0, 100, 100, 0, 0, 100, 0, 0, - 0, 100, 0, 0, + 0, 100, 50, 0, + 50, 100, 30, 0, 0, 100, 0, 0, 0, 100, 100, 0, 0, 100, 0, 0, 0, 100, 0, 0, - 0, 100, 100, 0 + 0, 100, 100, 0, + 100, 100, 0, 0, + 100, 100, 0, 0 END IDD_MESSAGE_DIALOG AFX_DIALOG_LAYOUT BEGIN 0, - 100, 100, 0, 0, - 0, 0, 100, 100, 0, 0, 100, 0, - 0, 100, 100, 0 + 0, 0, 100, 100, + 0, 100, 0, 0, + 100, 100, 0, 0 END IDD_HOT_KEY_SETTINGS_DIALOG AFX_DIALOG_LAYOUT BEGIN - 0 + 0, + 0, 0, 50, 0, + 50, 0, 50, 0, + 0, 0, 100, 0, + 0, 0, 76, 0, + 76, 0, 0, 0, + 76, 0, 24, 0 END IDD_LYRIC_BATCH_DOWN_DIALOG AFX_DIALOG_LAYOUT BEGIN 0, - 100, 100, 0, 0, - 0, 0, 100, 100, - 100, 100, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 100, 0, - 0, 0, 0, 0, + 0, 0, 50, 0, + 50, 0, 50, 0, + 100, 0, 0, 0, + 0, 0, 100, 0, + 0, 0, 100, 0, + 0, 0, 50, 0, + 50, 0, 50, 0, + 0, 0, 100, 0, + 0, 0, 100, 100, + 0, 100, 0, 0, 0, 100, 100, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 100, 0, 0 + 100, 100, 0, 0, + 100, 100, 0, 0 END IDD_LYRIC_DOWNLOAD_DIALOG AFX_DIALOG_LAYOUT BEGIN 0, - 100, 100, 0, 0, + 0, 0, 0, 0, + 0, 0, 100, 0, 100, 0, 0, 0, - 0, 0, 50, 0, 0, 0, 0, 0, - 50, 0, 50, 0, - 50, 0, 0, 0, - 0, 0, 100, 100, 0, 0, 100, 0, - 100, 100, 0, 0, - 0, 100, 0, 0, + 0, 0, 100, 0, + 100, 0, 0, 0, + 0, 0, 100, 100, 0, 100, 100, 0, - 0, 100, 0, 0, - 0, 100, 0, 0, - 0, 100, 0, 0, - 0, 100, 0, 0, - 0, 100, 0, 0, + 0, 100, 100, 0, + 0, 100, 50, 0, + 50, 100, 0, 0, + 0, 100, 100, 0, + 0, 100, 50, 0, + 50, 100, 50, 0, + 100, 100, 0, 0, 100, 100, 0, 0, - 100, 0, 0, 0 + 100, 100, 0, 0 END IDD_LYRIC_EDIT_DIALOG AFX_DIALOG_LAYOUT BEGIN 0, - 0, 0, 100, 0, - 0, 0, 0, 0 + 0, 0, 0, 0, + 0, 0, 100, 0 END IDD_LYRIC_SETTING_DIALOG AFX_DIALOG_LAYOUT BEGIN - 0 + 0, + 0, 0, 100, 0, + 0, 0, 40, 0, + 40, 0, 60, 0, + 0, 0, 40, 0, + 40, 0, 60, 0, + 0, 0, 40, 0, + 40, 0, 60, 0, + 0, 0, 40, 0, + 40, 0, 40, 0, + 0, 0, 40, 0, + 40, 0, 60, 0, + 0, 0, 100, 0, + 0, 0, 40, 0, + 40, 0, 0, 0, + 0, 0, 40, 0, + 40, 0, 40, 0, + 80, 0, 20, 0, + 0, 0, 100, 0, + 0, 0, 40, 0, + 0, 0, 40, 0, + 0, 0, 40, 0, + 40, 0, 60, 0, + 40, 0, 60, 0, + 40, 0, 60, 0, + 0, 0, 40, 0, + 0, 0, 40, 0, + 40, 0, 0, 0, + 40, 0, 0, 0, + 0, 0, 40, 0, + 40, 0, 0, 0, + 40, 0, 0, 0, + 40, 0, 40, 0, + 40, 0, 40, 0, + 80, 0, 20, 0, + 0, 0, 40, 0, + 40, 0, 40, 0, + 80, 0, 20, 0, + 0, 0, 40, 0, + 40, 0, 40, 0, + 80, 0, 20, 0, + 0, 0, 100, 0, + 0, 0, 40, 0, + 40, 0, 60, 0, + 0, 0, 100, 0, + 0, 0, 40, 0, + 40, 0, 40, 0, + 0, 0, 100, 0, + 0, 0, 100, 0, + 0, 0, 100, 0, + 0, 0, 100, 0, + 0, 0, 100, 0, + 0, 0, 40, 0, + 40, 0, 60, 0, + 0, 0, 40, 0, + 40, 0, 40, 0, + 80, 0, 20, 0 END IDD_MP3_ENCODE_CFG_DIALOG AFX_DIALOG_LAYOUT @@ -5525,53 +2450,81 @@ BEGIN END IDD_PLAY_SETTING_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0 -END - -IDD_PROPERTY_DIALOG AFX_DIALOG_LAYOUT BEGIN 0, + 0, 0, 100, 0, 0, 0, 50, 0, - 0, 0, 50, 0, - 0, 0, 50, 0, + 50, 0, 50, 0, 0, 0, 50, 0, 50, 0, 50, 0, + 0, 0, 50, 0, 50, 0, 50, 0, + 0, 0, 100, 0, + 0, 0, 100, 0, + 0, 0, 50, 0, 50, 0, 50, 0, - 50, 0, 25, 0, - 75, 0, 25, 0, - 50, 0, 50, 100, - 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 100, 0, + 0, 0, 100, 0, 0, 0, 0, 0, + 0, 0, 100, 0, + 0, 0, 100, 0, + 0, 0, 100, 0, 0, 0, 50, 0, 50, 0, 0, 0, + 0, 0, 50, 0, 50, 0, 0, 0, + 0, 0, 50, 0, 50, 0, 0, 0, - 50, 0, 50, 100, - 75, 0, 0, 0, - 50, 0, 0, 0, - 50, 0, 0, 0, + 0, 0, 50, 0, 50, 0, 0, 0, + 0, 0, 50, 0, + 50, 0, 50, 0 +END + +IDD_PROPERTY_DIALOG AFX_DIALOG_LAYOUT +BEGIN + 0, + 0, 0, 50, 0, + 0, 0, 10, 0, + 10, 0, 40, 0, + 0, 0, 10, 0, + 10, 0, 40, 0, + 0, 0, 10, 0, + 10, 0, 40, 0, + 0, 0, 10, 0, + 10, 0, 15, 0, + 25, 0, 10, 0, + 35, 0, 15, 0, + 0, 0, 10, 0, + 10, 0, 15, 0, + 25, 0, 10, 0, + 35, 0, 15, 0, + 0, 0, 10, 0, + 10, 0, 15, 0, + 25, 0, 10, 0, + 35, 0, 15, 0, + 0, 0, 10, 0, + 10, 0, 40, 0, + 50, 0, 50, 100, + 50, 0, 10, 0, + 60, 0, 40, 0, + 50, 0, 10, 0, + 60, 0, 40, 0, + 50, 0, 10, 0, + 60, 0, 40, 0, + 50, 0, 10, 0, + 60, 0, 15, 0, + 75, 0, 10, 0, + 85, 0, 15, 0, + 50, 0, 10, 0, + 60, 0, 40, 0, + 50, 0, 10, 0, + 60, 0, 40, 100, 50, 100, 50, 0, - 0, 0, 0, 0, - 50, 0, 50, 0, - 0, 100, 0, 0, 0, 100, 0, 0, 0, 100, 0, 0, - 0, 0, 25, 0, - 25, 0, 25, 0, - 0, 0, 25, 0, - 0, 0, 0, 0, - 25, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 25, 0, - 0, 0, 0, 0, - 25, 0, 25, 0, - 25, 0, 0, 0, - 25, 0, 25, 0, - 25, 0, 0, 0 + 0, 100, 0, 0 END IDD_REVERB_DIALOG AFX_DIALOG_LAYOUT @@ -5604,7 +2557,28 @@ END IDD_TAG_EDIT_DIALOG AFX_DIALOG_LAYOUT BEGIN - 0 + 0, + 0, 0, 10, 0, + 10, 0, 90, 0, + 0, 0, 10, 0, + 10, 0, 90, 0, + 0, 0, 10, 0, + 10, 0, 90, 0, + 0, 0, 10, 0, + 10, 0, 90, 0, + 0, 0, 10, 0, + 10, 0, 40, 0, + 50, 0, 10, 0, + 60, 0, 40, 0, + 0, 0, 10, 0, + 10, 0, 90, 0, + 0, 0, 10, 0, + 10, 0, 90, 100, + 0, 100, 0, 0, + 0, 100, 0, 0, + 0, 100, 100, 0, + 100, 100, 0, 0, + 100, 100, 0, 0 END IDD_WMA_ENCODE_CFG_DIALOG AFX_DIALOG_LAYOUT @@ -5615,10 +2589,10 @@ END IDD_LISTEN_TIME_STATISTICS_DLG AFX_DIALOG_LAYOUT BEGIN 0, - 100, 100, 0, 0, 0, 0, 100, 100, 0, 100, 0, 0, - 0, 100, 0, 0 + 0, 100, 0, 0, + 100, 100, 0, 0 END IDD_DONATE_DIALOG AFX_DIALOG_LAYOUT @@ -5629,11 +2603,11 @@ END IDD_MEDIA_LIB_DIALOG AFX_DIALOG_LAYOUT BEGIN 0, - 100, 100, 0, 0, 0, 0, 100, 100, - 100, 100, 0, 0, 0, 100, 0, 0, - 0, 100, 0, 0 + 0, 100, 0, 0, + 100, 100, 0, 0, + 100, 100, 0, 0 END IDD_INPUT_DLG AFX_DIALOG_LAYOUT @@ -5644,9 +2618,9 @@ END IDD_SELECT_PLAYLIST_DIALOG AFX_DIALOG_LAYOUT BEGIN 0, - 0, 0, 30, 100, 0, 0, 0, 0, 100, 0, 0, 0, + 0, 0, 30, 100, 30, 0, 70, 100, 30, 0, 0, 100 END @@ -5654,861 +2628,205 @@ END IDD_FILE_RELATE_DIALOG AFX_DIALOG_LAYOUT BEGIN 0, - 100, 100, 0, 0, - 100, 100, 0, 0, 0, 0, 100, 100, 0, 100, 0, 0, - 0, 100, 0, 0 + 0, 100, 0, 0, + 100, 100, 0, 0, + 100, 100, 0, 0 END IDD_ADD_TO_PLAYLIST_DIALOG AFX_DIALOG_LAYOUT BEGIN 0, - 100, 100, 0, 0, - 100, 100, 0, 0, + 0, 0, 100, 0, 0, 0, 100, 100, - 0, 0, 100, 0 + 100, 100, 0, 0, + 100, 100, 0, 0 END IDD_MEDIA_LIB_SETTING_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0 -END - -IDD_LYRIC_RELATE_DIALOG AFX_DIALOG_LAYOUT BEGIN 0, - 100, 100, 0, 0, - 100, 100, 0, 0, - 0, 100, 0, 0, - 0, 0, 0, 0, + 0, 0, 100, 0, + 0, 0, 40, 0, + 40, 0, 60, 0, + 0, 0, 40, 0, + 40, 0, 0, 0, + 0, 0, 40, 0, + 40, 0, 60, 0, + 0, 0, 100, 0, + 0, 0, 40, 0, + 40, 0, 60, 0, 0, 0, 100, 0, 100, 0, 0, 0, + 0, 0, 100, 0, + 0, 0, 100, 0, 100, 0, 0, 0, - 0, 0, 100, 100, - 0, 0, 0, 0, 100, 0, 0, 0, - 100, 0, 0, 0 -END - -IDD_CLEAN_UP_RANGE_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0, - 100, 100, 0, 0, - 100, 100, 0, 0, 0, 0, 100, 0, - 0, 0, 100, 100 -END - -IDD_PROPERTY_ALBUM_COVER_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0, - 80, 0, 20, 100, - 80, 100, 0, 0, - 80, 100, 0, 0, - 80, 100, 20, 0, - 0, 100, 0, 0 -END - -IDD_PROPERTY_PARENT_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0, - 100, 100, 0, 0, - 0, 100, 0, 0, - 0, 100, 0, 0, - 0, 100, 0, 0, - 100, 100, 0, 0, - 0, 0, 100, 100 -END - -IDD_TAG_FROM_FILE_NAME_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0 -END - -IDD_SELECT_ITEM_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0, - 100, 100, 0, 0, - 100, 100, 0, 0, - 0, 0, 100, 100 -END - -IDD_FLAC_ENCODE_CFG_DIALOG AFX_DIALOG_LAYOUT -BEGIN - 0 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -IDR_FIND_POPUP_MENU MENU -BEGIN - POPUP "Menu" - BEGIN - MENUITEM "&Play", ID_FD_PLAY - MENUITEM SEPARATOR - MENUITEM "&Copy Text", ID_FD_COPY_TEXT - MENUITEM "Open File &Location", ID_FD_OPEN_FILE_LOCATION - END -END - -IDR_FORMAT_CONVERT_POPUP_MENU MENU -BEGIN - POPUP "Menu" - BEGIN - MENUITEM "&Add File...", ID_ADD_FILE - MENUITEM "&Clear List", ID_CLEAR_LIST - MENUITEM SEPARATOR - MENUITEM "&Edit Tag Info...", ID_EDIT_TAG_INFO - MENUITEM "&Delete", ID_DELETE_SELECT - MENUITEM SEPARATOR - MENUITEM "Move &Up\tCtrl+↑", ID_MOVE_UP - MENUITEM "Move &Down\tCtrl+↓", ID_MOVE_DOWN - END -END - -IDR_LYRIC_DOWNLOAD_MENU MENU -BEGIN - POPUP "Menu" - BEGIN - MENUITEM "&Download", ID_LD_LYRIC_DOWNLOAD - MENUITEM "&Preview", ID_LD_PREVIEW - MENUITEM "&Save As...", ID_LD_LYRIC_SAVEAS - MENUITEM SEPARATOR - MENUITEM "Copy Song &Title", ID_LD_COPY_TITLE - MENUITEM "Copy &Artist", ID_LD_COPY_ARTIST - MENUITEM "Copy Al&bum", ID_LD_COPY_ALBUM - MENUITEM "Copy Song &ID", ID_LD_COPY_ID - MENUITEM SEPARATOR - MENUITEM "&Link This Item", ID_LD_RELATE - MENUITEM "&View Online", ID_LD_VIEW_ONLINE - END -END - -IDR_LYRIC_EDIT_MENU MENU -BEGIN - POPUP "&File" - BEGIN - MENUITEM "&Open...", ID_LYRIC_OPEN - MENUITEM "&Save\tCtrl+S", ID_LYRIC_SAVE - MENUITEM "Save &As...", ID_LYRIC_SAVE_AS - MENUITEM SEPARATOR - MENUITEM "E&xit", IDCANCEL - END - POPUP "&Edit" - BEGIN - MENUITEM "&Insert Time Tag\tF8", ID_LYRIC_INSERT_TAG - MENUITEM "&Replace Time Tag\tF9", ID_LYRIC_REPLACE_TAG - MENUITEM "&Delete Time Tag\tCtrl+Del", ID_LYRIC_DELETE_TAG - MENUITEM SEPARATOR - MENUITEM "&Find...\tCtrl+F", ID_LYRIC_FIND - MENUITEM "&Replace...\tCtrl+H", ID_LYRIC_REPLACE - MENUITEM "Find &Next\tF3", ID_FIND_NEXT - MENUITEM SEPARATOR - POPUP "Chinese &Conversion" - BEGIN - MENUITEM "Convert to &Simplified Chinese", ID_LE_TRANSLATE_TO_SIMPLIFIED_CHINESE - MENUITEM "Convert to &Traditional Chinese", ID_LE_TRANSLATE_TO_TRANDITIONAL_CHINESE - END - MENUITEM SEPARATOR - MENUITEM "&Merge lyrics with the same time tag", ID_LRYIC_MERGE_SAME_TIME_TAG - MENUITEM "&Swap the lyric text and translation", ID_LYRIC_SWAP_TEXT_AND_TRANSLATION - POPUP "Time tag &dislocation" - BEGIN - MENUITEM "One sentence &ahead of time tag", ID_LYRIC_TIME_TAG_FORWARD - MENUITEM "One sentence &postponed of time tag", ID_LYRIC_TIME_TAG_DELAY - END - END - POPUP "&Play Control" - BEGIN - MENUITEM "&Play/Pause\tCtrl+P", ID_PLAY_PAUSE - MENUITEM "&Rewind\tCtrl+Left", ID_REW - MENUITEM "&Fast Forward\tCtrl+Right", ID_FF - MENUITEM "&Seek to current line\tCtrl+G", ID_SEEK_TO_CUR_LINE - END -END - -IDR_LYRIC_POPUP_MENU MENU -BEGIN - POPUP "Menu" - BEGIN - MENUITEM "&Reload Lyrics", ID_RELOAD_LYRIC - MENUITEM "&Copy Current Lyric", ID_COPY_CURRENT_LYRIC - MENUITEM "Copy &All Lyrics", ID_COPY_ALL_LYRIC - MENUITEM "&Edit Lyrics...", ID_EDIT_LYRIC - POPUP "Chinese Co&nversion" - BEGIN - MENUITEM "Convert to &Simplified Chinese", ID_TRANSLATE_TO_SIMPLIFIED_CHINESE - MENUITEM "Convert to &Traditional Chinese", ID_TRANSLATE_TO_TRANDITIONAL_CHINESE - END - MENUITEM SEPARATOR - MENUITEM "Show Lyrics &Translation", ID_SHOW_LYRIC_TRANSLATE - MENUITEM "Show Desktop Lyr&ics", ID_SHOW_DESKTOP_LYRIC - MENUITEM SEPARATOR - MENUITEM "Lyrics 0.5 Seconds in Ad&vance", ID_LYRIC_FORWARD - MENUITEM "Lyrics 0.5 Seconds Dela&yed", ID_LYRIC_DELAY - MENUITEM "&Save Lyrics Changes", ID_SAVE_MODIFIED_LYRIC - MENUITEM SEPARATOR - MENUITEM "Lin&k local lyrics...", ID_RELATE_LOCAL_LYRIC - MENUITEM "&Delete Lyrics", ID_DELETE_LYRIC - MENUITEM "&Unlink Lyrics", ID_UNLINK_LYRIC - MENUITEM "O&pen Lyrics File Location", ID_BROWSE_LYRIC - POPUP "Internal Lyrics" - BEGIN - MENUITEM "&Embed Into Audio File", ID_EMBED_LYRIC_TO_AUDIO_FILE - MENUITEM "&Remove From Audio File", ID_DELETE_LYRIC_FROM_AUDIO_FILE - END - MENUITEM SEPARATOR - MENUITEM "Download &Lyrics...", ID_DOWNLOAD_LYRIC - MENUITEM "Lyrics &Batch Download...", ID_LYRIC_BATCH_DOWNLOAD - MENUITEM SEPARATOR - POPUP "Switch &UI" - BEGIN - MENUITEM "Switch &UI", ID_SWITCH_UI - END - MENUITEM "&Options...", ID_OPTION_SETTINGS - END -END - -IDR_MAIN_POPUP_MENU MENU -BEGIN - POPUP "Menu" - BEGIN - MENUITEM "Song &Info...", ID_SONG_INFO - POPUP "Repeat &Mode" - BEGIN - MENUITEM "Play in &Oder", ID_PLAY_ORDER - MENUITEM "Play &Shuffle", ID_PLAY_SHUFFLE - MENUITEM "Play &Random", ID_PLAY_RANDOM - MENUITEM "&Loop Playlist", ID_LOOP_PLAYLIST - MENUITEM "Loop &Track", ID_LOOP_TRACK - MENUITEM "Play O&nce", ID_PLAY_TRACK - END - POPUP "Add to Playlis&t" - BEGIN - MENUITEM "&New Playlist...", ID_ADD_TO_NEW_PLAYLIST - MENUITEM SEPARATOR - MENUITEM "Default", ID_ADD_TO_DEFAULT_PLAYLIST - MENUITEM "My Favourite", ID_ADD_TO_MY_FAVOURITE - END - POPUP "R&ate" - BEGIN - MENUITEM "&1 star", ID_RATING_1 - MENUITEM "&2 stars", ID_RATING_2 - MENUITEM "&3 stars", ID_RATING_3 - MENUITEM "&4 stars", ID_RATING_4 - MENUITEM "&5 stars", ID_RATING_5 - MENUITEM SEPARATOR - MENUITEM "&Unrated", ID_RATING_NONE - END - MENUITEM SEPARATOR - MENUITEM "Media &Library...", ID_SET_PATH - MENUITEM "&Find Songs...", ID_FIND - MENUITEM "O&pen File Location", ID_EXPLORE_PATH - MENUITEM "Sound &Effect Settings...", ID_EQUALIZER - MENUITEM "&View Online", ID_CURRENT_EXPLORE_ONLINE - MENUITEM SEPARATOR - MENUITEM "Download &Album Cover...", ID_DOWNLOAD_ALBUM_COVER - MENUITEM "Album Cover &Save As...", ID_ALBUM_COVER_SAVE_AS - MENUITEM "&Delete Album Cover", ID_DELETE_ALBUM_COVER - MENUITEM "Always Use Exter&nal Album Cover", ID_ALWAYS_USE_EXTERNAL_ALBUM_COVER - MENUITEM "Album &Cover Details...", ID_ALBUM_COVER_INFO - MENUITEM SEPARATOR - MENUITEM "View A&rtist...", ID_VIEW_ARTIST - MENUITEM "View Al&bum...", ID_VIEW_ALBUM - MENUITEM SEPARATOR - POPUP "Switch &UI" - BEGIN - MENUITEM "Switch &UI", ID_SWITCH_UI - END - MENUITEM "&Options...", ID_OPTION_SETTINGS - END -END - -IDR_MENU1 MENU -BEGIN - POPUP "&File" - BEGIN - MENUITEM "&Open File...", ID_FILE_OPEN - MENUITEM "Open &Folder...", ID_FILE_OPEN_FOLDER - MENUITEM "Open &URL...", ID_FILE_OPEN_URL - MENUITEM "Open &Playlist...", ID_FILE_OPEN_PLAYLIST - MENUITEM SEPARATOR - MENUITEM "E&xit", ID_MENU_EXIT - END - POPUP "&Play Control" - BEGIN - MENUITEM "&Play/Pause", ID_PLAY_PAUSE - MENUITEM "&Stop", ID_STOP - MENUITEM "Pre&vious", ID_PREVIOUS - MENUITEM "&Next", ID_NEXT - MENUITEM SEPARATOR - MENUITEM "&Rewind for 5 Seconds", ID_REW - MENUITEM "Fast forward for 5 Seconds", ID_FF - MENUITEM SEPARATOR - MENUITEM "Speed Up Playback", ID_SPEED_UP - MENUITEM "Slow Down Playback", ID_SLOW_DOWN - MENUITEM "Original Speed Playback", ID_ORIGINAL_SPEED - MENUITEM SEPARATOR - POPUP "Repeat &Mode" - BEGIN - MENUITEM "Play in &Oder", ID_PLAY_ORDER - MENUITEM "Play &Shuffle", ID_PLAY_SHUFFLE - MENUITEM "Play &Random", ID_PLAY_RANDOM - MENUITEM "&Loop Playlist", ID_LOOP_PLAYLIST - MENUITEM "Loop &Track", ID_LOOP_TRACK - MENUITEM "Play &Once", ID_PLAY_TRACK - END - POPUP "AB R&epeat" - BEGIN - MENUITEM "AB &Repeat", ID_AB_REPEAT - MENUITEM SEPARATOR - MENUITEM "Set &A Point", ID_SET_A_POINT - MENUITEM "Set &B Point", ID_SET_B_POINT - MENUITEM "Continue &Next AB Repeat", ID_NEXT_AB_REPEAT - MENUITEM "&Cancel AB Repeat", ID_RESET_AB_REPEAT - END - END - POPUP "Play&list" - BEGIN - POPUP "&Add" - BEGIN - MENUITEM "&Add Files...", ID_PLAYLIST_ADD_FILE - MENUITEM "Add &Folder...", ID_PLAYLIST_ADD_FOLDER - MENUITEM "Add &URL...", ID_PLAYLIST_ADD_URL - END - POPUP "&Delete" - BEGIN - MENUITEM "Remo&ve from Playlist", ID_REMOVE_FROM_PLAYLIST - MENUITEM "&Delete from Disk", ID_DELETE_FROM_DISK - MENUITEM SEPARATOR - MENUITEM "Cl&ear Playlist", ID_EMPTY_PLAYLIST - MENUITEM "Remove &Same Items", ID_REMOVE_SAME_SONGS - MENUITEM "Remove &Invalid Items", ID_REMOVE_INVALID_ITEMS - END - MENUITEM "&Reload Playlist", ID_RELOAD_PLAYLIST - MENUITEM SEPARATOR - MENUITEM "Save As &New Playlist...", ID_SAVE_AS_NEW_PLAYLIST - MENUITEM "&Save Current Playlist As...", ID_SAVE_CURRENT_PLAYLIST_AS - MENUITEM SEPARATOR - POPUP "Sort" - BEGIN - MENUITEM "Sort by File Name", ID_SORT_BY_FILE - MENUITEM "Sort by Path", ID_SORT_BY_PATH - MENUITEM "Sort by Title", ID_SORT_BY_TITLE - MENUITEM "Sort by Artist", ID_SORT_BY_ARTIST - MENUITEM "Sort by Album", ID_SORT_BY_ALBUM - MENUITEM "Sort by Track", ID_SORT_BY_TRACK - MENUITEM "Sort by Modified Time", ID_SORT_BY_MODIFIED_TIME - MENUITEM SEPARATOR - MENUITEM "Ascending", ID_ACCENDING_ORDER - MENUITEM "Descending", ID_DESENDING_ORDER - MENUITEM SEPARATOR - MENUITEM "Invert", ID_INVERT_PLAYLIST - END - POPUP "Playlist Display Mode" - BEGIN - MENUITEM "File Name", ID_DISP_FILE_NAME - MENUITEM "Title", ID_DISP_TITLE - MENUITEM "Artist - Title", ID_DISP_ARTIST_TITLE - MENUITEM "Title - Artist", ID_DISP_TITLE_ARTIST - END - MENUITEM SEPARATOR - MENUITEM "&Locate the track is playing", ID_LOCATE_TO_CURRENT - END - POPUP "Lyri&cs" - BEGIN - MENUITEM "&Reload Lyrics", ID_RELOAD_LYRIC - MENUITEM "&Copy Current Lyric", ID_COPY_CURRENT_LYRIC - MENUITEM "Copy &All Lyrics", ID_COPY_ALL_LYRIC - MENUITEM SEPARATOR - MENUITEM "&Edit Lyrics...", ID_EDIT_LYRIC - POPUP "Chinese Con&version" - BEGIN - MENUITEM "Convert to &Simplified Chinese", ID_TRANSLATE_TO_SIMPLIFIED_CHINESE - MENUITEM "Convert to &Traditional Chinese", ID_TRANSLATE_TO_TRANDITIONAL_CHINESE - END - MENUITEM SEPARATOR - MENUITEM "Show Lyrics &Translation", ID_SHOW_LYRIC_TRANSLATE - MENUITEM "Show Desktop Lyr&ics", ID_SHOW_DESKTOP_LYRIC - MENUITEM SEPARATOR - MENUITEM "Lyrics 0.5 Seconds in Adva&nce", ID_LYRIC_FORWARD - MENUITEM "Lyrics 0.5 Seconds Dela&yed", ID_LYRIC_DELAY - MENUITEM "&Save Lyrics Changes", ID_SAVE_MODIFIED_LYRIC - MENUITEM SEPARATOR - MENUITEM "Lin&k local lyrics...", ID_RELATE_LOCAL_LYRIC - MENUITEM "&Delete Lyrics", ID_DELETE_LYRIC - MENUITEM "&Unlink Lyrics", ID_UNLINK_LYRIC - MENUITEM "&Open Lyrics File Location", ID_BROWSE_LYRIC - POPUP "Internal Lyrics" - BEGIN - MENUITEM "&Embed Into Audio File", ID_EMBED_LYRIC_TO_AUDIO_FILE - MENUITEM "&Remove From Audio File", ID_DELETE_LYRIC_FROM_AUDIO_FILE - END - MENUITEM SEPARATOR - MENUITEM "Download &Lyrics...", ID_DOWNLOAD_LYRIC - MENUITEM "Lyrics &Batch Download...", ID_LYRIC_BATCH_DOWNLOAD - END - POPUP "&View" - BEGIN - MENUITEM "Show &Playlist", ID_SHOW_PLAYLIST - MENUITEM "F&loating Playlist", ID_FLOAT_PLAYLIST - MENUITEM "Use System Standard Title &Bar", ID_USE_STANDARD_TITLE_BAR - MENUITEM "Show Me&nu Bar", ID_SHOW_MENU_BAR - MENUITEM "Always Show &Status Bar", ID_ALWAYS_SHOW_STATUS_BAR - MENUITEM "Always on &Top", ID_ALWAYS_ON_TOP - MENUITEM SEPARATOR - MENUITEM "&Mini Mode", ID_MINI_MODE - MENUITEM "&Full Screen", ID_FULL_SCREEN - MENUITEM SEPARATOR - MENUITEM "&Dark Mode", ID_DARK_MODE - POPUP "Switch &UI" - BEGIN - MENUITEM "Switch &UI", ID_SWITCH_UI - END - END - POPUP "&Tool" - BEGIN - MENUITEM "&Media Library...", ID_SET_PATH - MENUITEM "&Find Songs...", ID_FIND - MENUITEM "Open File &Location", ID_EXPLORE_PATH - MENUITEM "Song &Info...", ID_SONG_INFO - MENUITEM "Sound &Effect Settings...", ID_EQUALIZER - MENUITEM "Format &Convert...", ID_FORMAT_CONVERT1 - MENUITEM "&View Online", ID_CURRENT_EXPLORE_ONLINE - MENUITEM SEPARATOR - MENUITEM "&Reinitialize the Player", ID_RE_INI_BASS - POPUP "Create &Shortcut" - BEGIN - MENUITEM "Create &Desktop Shortcut", ID_CREATE_DESKTOP_SHORTCUT - MENUITEM "Create Play Control &Shortcut", ID_CREATE_PLAY_SHORTCUT - MENUITEM "Create &Mini Mode Shortcut", ID_CREATE_MINI_MODE_SHORT_CUT - END - MENUITEM SEPARATOR - POPUP "&Album Cover" - BEGIN - MENUITEM "Download &Album Cover...", ID_DOWNLOAD_ALBUM_COVER - MENUITEM "Album Cover &Save As...", ID_ALBUM_COVER_SAVE_AS - MENUITEM "&Delete Album Cover", ID_DELETE_ALBUM_COVER - MENUITEM "Album &Cover Details...", ID_ALBUM_COVER_INFO - END - POPUP "Delete Current Playing Track" - BEGIN - MENUITEM "Remove from &Playlist", ID_REMOVE_CURRENT_FROM_PLAYLIST - MENUITEM "Delete from &Disk", ID_DELETE_CURRENT_FROM_DISK - END - MENUITEM SEPARATOR - MENUITEM "Play Time Statistics...", ID_LISTEN_STATISTICS - MENUITEM "File Relate...", ID_TOOL_FILE_RELATE - MENUITEM "&Options...", ID_OPTION_SETTINGS - END - POPUP "&Help" - BEGIN - MENUITEM "&Help\tF1", ID_HELP - MENUITEM "&Online Help", ID_ONLINE_HELP - MENUITEM "&FAQ", ID_HELP_FAQ - MENUITEM "Custom &UI", ID_HELP_CUSTOM_UI - MENUITEM "Update &Log", ID_HELP_UPDATE_LOG - MENUITEM "Supproted &Format", ID_SUPPORTED_FORMAT - MENUITEM SEPARATOR - MENUITEM "&About...", ID_APP_ABOUT - END -END - -IDR_MINI_MODE_MENU MENU -BEGIN - POPUP "Menu" - BEGIN - MENUITEM "Song &Info...", ID_SONG_INFO - POPUP "Repeat &Mode" - BEGIN - MENUITEM "Play in &Oder", ID_PLAY_ORDER - MENUITEM "Play &Shuffle", ID_PLAY_SHUFFLE - MENUITEM "Play &Random", ID_PLAY_RANDOM - MENUITEM "&Loop Playlist", ID_LOOP_PLAYLIST - MENUITEM "Loop &Track", ID_LOOP_TRACK - MENUITEM "Play &Once", ID_PLAY_TRACK - END - POPUP "Add to Playlis&t" - BEGIN - MENUITEM "&New Playlist...", ID_ADD_TO_NEW_PLAYLIST - MENUITEM SEPARATOR - MENUITEM "Default", ID_ADD_TO_DEFAULT_PLAYLIST - MENUITEM "My Favourite", ID_ADD_TO_MY_FAVOURITE - END - MENUITEM SEPARATOR - MENUITEM "&Download Lyrics...", ID_DOWNLOAD_LYRIC - MENUITEM "Download &Album Cover...", ID_DOWNLOAD_ALBUM_COVER - MENUITEM SEPARATOR - MENUITEM "Add to My Fa&vourite", ID_ADD_REMOVE_FROM_FAVOURITE - MENUITEM SEPARATOR - MENUITEM "Media &Library...", ID_SET_PATH - MENUITEM "&Find Songs...", ID_FIND - MENUITEM "Open File Lo&cation", ID_EXPLORE_PATH - MENUITEM "Sound &Effect Settings...", ID_EQUALIZER - MENUITEM "&Options...", ID_OPTION_SETTINGS - MENUITEM SEPARATOR - MENUITEM "Sho&w Playlist\tCtrl+L", ID_SHOW_PLAY_LIST - MENUITEM "Always on &Top", ID_MINI_MODE_ALWAYS_ON_TOP - POPUP "Switch UI" - BEGIN - MENUITEM "&Default UI", ID_MINIMODE_UI_DEFAULT - END - MENUITEM SEPARATOR - MENUITEM "Minimi&ze", ID_MINI_MIDE_MINIMIZE - MENUITEM "Back to &Normal\tEsc", IDOK - MENUITEM "E&xit", ID_MINI_MODE_EXIT - END -END - -IDR_POPUP_MENU MENU -BEGIN - POPUP "Menu" - BEGIN - MENUITEM "&Play", ID_PLAY_ITEM - MENUITEM "Play &Next", ID_PLAY_AS_NEXT - MENUITEM SEPARATOR - MENUITEM "View &Online", ID_EXPLORE_ONLINE - MENUITEM "&Format Convert...", ID_FORMAT_CONVERT - POPUP "R&ate" - BEGIN - MENUITEM "&1 star", ID_RATING_1 - MENUITEM "&2 stars", ID_RATING_2 - MENUITEM "&3 stars", ID_RATING_3 - MENUITEM "&4 stars", ID_RATING_4 - MENUITEM "&5 stars", ID_RATING_5 - MENUITEM SEPARATOR - MENUITEM "&Unrated", ID_RATING_NONE - END - MENUITEM SEPARATOR - MENUITEM "&Reload Playlist", ID_RELOAD_PLAYLIST - MENUITEM SEPARATOR - MENUITEM "Remo&ve from Playlist", ID_REMOVE_FROM_PLAYLIST - MENUITEM "&Delete from Disk", ID_DELETE_FROM_DISK - MENUITEM SEPARATOR - POPUP "Add to Playlis&t" - BEGIN - MENUITEM "&New Playlist...", ID_ADD_TO_NEW_PLAYLIST - MENUITEM SEPARATOR - MENUITEM "Default", ID_ADD_TO_DEFAULT_PLAYLIST - MENUITEM "My Favourite", ID_ADD_TO_MY_FAVOURITE - END - MENUITEM "&Copy File to...", ID_COPY_FILE_TO - MENUITEM "&Move File to...", ID_MOVE_FILE_TO - MENUITEM SEPARATOR - MENUITEM "Move &Up", ID_MOVE_PLAYLIST_ITEM_UP - MENUITEM "Move Do&wn", ID_MOVE_PLAYLIST_ITEM_DOWN - MENUITEM SEPARATOR - MENUITEM "View Art&ist...", ID_PLAYLIST_VIEW_ARTIST - MENUITEM "View Al&bum...", ID_PLAYLIST_VIEW_ALBUM - MENUITEM SEPARATOR - MENUITEM "Renam&e...", ID_RENAME - MENUITEM "Open File &Location", ID_EXPLORE_TRACK - MENUITEM "Propert&y...", ID_ITEM_PROPERTY - END -END - -IDR_SET_PATH_POPUP_MENU MENU -BEGIN - POPUP "Menu" - BEGIN - MENUITEM "&Play Folder", ID_PLAY_PATH - MENUITEM "&Delete From List", ID_DELETE_PATH - MENUITEM "&Open Folder Location", ID_BROWSE_PATH - MENUITEM "Contains &Subfolders", ID_CONTAIN_SUB_FOLDER - MENUITEM SEPARATOR - MENUITEM "&Clear Invalid Folder", ID_CLEAR_INVALID_PATH - END -END - -IDR_NOTIFY_MENU MENU -BEGIN - POPUP "菜单" - BEGIN - MENUITEM "&Play/Pause", ID_PLAY_PAUSE - MENUITEM "Pre&vious", ID_PREVIOUS - MENUITEM "&Next", ID_NEXT - POPUP "Repeat &Mode" - BEGIN - MENUITEM "Play in &Oder", ID_PLAY_ORDER - MENUITEM "Play &Shuffle", ID_PLAY_SHUFFLE - MENUITEM "Play &Random", ID_PLAY_RANDOM - MENUITEM "&Loop Playlist", ID_LOOP_PLAYLIST - MENUITEM "Loop &Track", ID_LOOP_TRACK - MENUITEM "Play &Once", ID_PLAY_TRACK - END - MENUITEM "Mini Mode/&Restore", ID_MINIMODE_RESTORE - MENUITEM "&Show Desktop Lyrics", ID_SHOW_DESKTOP_LYRIC - MENUITEM "&Lock Desktop Lyrics", ID_LOCK_DESKTOP_LRYIC - MENUITEM SEPARATOR - MENUITEM "&Options...", ID_OPTION_SETTINGS - MENUITEM "E&xit", ID_MENU_EXIT - END -END - -IDR_PLAYLIST_BTN_MENU MENU -BEGIN - POPUP "Menu" - BEGIN - MENUITEM "Docked Playlist", ID_DOCKED_PLAYLIST - MENUITEM "Floating Playlist", ID_FLOATED_PLAYLIST - END + 0, 0, 40, 0, + 40, 0, 60, 0, + 0, 0, 40, 0, + 40, 0, 60, 0, + 0, 0, 40, 0, + 40, 0, 60, 0, + 0, 0, 40, 0, + 40, 0, 60, 0, + 0, 0, 40, 0, + 40, 0, 60, 0, + 0, 0, 100, 0, + 0, 0, 100, 0, + 0, 0, 100, 0, + 0, 0, 40, 0, + 40, 0, 60, 0, + 0, 0, 40, 0, + 0, 0, 40, 0, + 40, 0, 40, 0, + 0, 0, 40, 0, + 40, 0, 0, 0, + 0, 0, 100, 0, + 0, 0, 40, 0, + 40, 0, 40, 0, + 100, 0, 0, 0, + 0, 0, 100, 0, + 0, 0, 100, 0, + 100, 0, 0, 0, + 0, 0, 100, 0, + 0, 0, 40, 0, + 40, 0, 40, 0, + 0, 0, 100, 0, + 0, 0, 40, 0, + 40, 0, 60, 0, + 0, 0, 100, 0, + 100, 0, 0, 0, + 0, 0, 100, 0, + 0, 0, 40, 0, + 0, 0, 40, 0, + 40, 0, 0, 0, + 0, 0, 40, 0, + 40, 0, 0, 0, + 40, 0, 60, 0, + 100, 0, 0, 0, + 0, 0, 100, 0, + 0, 0, 40, 0, + 40, 0, 0, 0 END -IDR_SELETE_PLAYLIST_POPUP_MENU MENU +IDD_LYRIC_RELATE_DIALOG AFX_DIALOG_LAYOUT BEGIN - POPUP "菜单" - BEGIN - MENUITEM "&Play", ID_PLAY_PLAYLIST - MENUITEM "&Rename...", ID_RENAME_PLAYLIST - MENUITEM "&Delete...", ID_DELETE_PLAYLIST - MENUITEM "Save As &New Playlist...", ID_SAVE_AS_NEW_PLAYLIST - MENUITEM "Save &As...", ID_PLAYLIST_SAVE_AS - MENUITEM SEPARATOR - MENUITEM "&Open playlist file location", ID_PLAYLIST_BROWSE_FILE - MENUITEM "&Fix the wrong file path", ID_PLAYLIST_FIX_PATH_ERROR - MENUITEM SEPARATOR - MENUITEM "&New Playlist...", ID_NEW_PLAYLIST - END + 0, + 0, 0, 0, 0, + 0, 0, 100, 0, + 100, 0, 0, 0, + 100, 0, 0, 0, + 0, 0, 100, 0, + 0, 0, 100, 100, + 100, 0, 0, 0, + 100, 0, 0, 0, + 0, 100, 0, 0, + 100, 100, 0, 0, + 100, 100, 0, 0 END -IDR_DESKTOP_LYRIC_POPUP_MENU MENU +IDD_CLEAN_UP_RANGE_DIALOG AFX_DIALOG_LAYOUT BEGIN - POPUP "Menu" - BEGIN - MENUITEM "&Play/Pause", ID_PLAY_PAUSE - MENUITEM "&Stop", ID_STOP - MENUITEM "Pre&vious", ID_PREVIOUS - MENUITEM "&Next", ID_NEXT - POPUP "Repeat &Mode" - BEGIN - MENUITEM "Play &Oder", ID_PLAY_ORDER - MENUITEM "Play &Shuffle", ID_PLAY_SHUFFLE - MENUITEM "Play &Random", ID_PLAY_RANDOM - MENUITEM "&Loop Playlist", ID_LOOP_PLAYLIST - MENUITEM "Loop &Track", ID_LOOP_TRACK - MENUITEM "Play &Once", ID_PLAY_TRACK - END - MENUITEM SEPARATOR - MENUITEM "Show Main &Window", ID_SHOW_MAIN_WINDOW - MENUITEM "Lyrics Displayed in &Double Line", ID_LYRIC_DISPLAYED_DOUBLE_LINE - MENUITEM "Lyric &Background Penetrate", ID_LYRIC_BACKGROUND_PENETRATE - MENUITEM "&Lock Desktop Lyric", ID_LOCK_DESKTOP_LRYIC - POPUP "Default Style" - BEGIN - MENUITEM "Default 1", ID_LYRIC_DEFAULT_STYLE1 - MENUITEM "Default 2", ID_LYRIC_DEFAULT_STYLE2 - MENUITEM "Default 3", ID_LYRIC_DEFAULT_STYLE3 - END - MENUITEM "&Options...", ID_OPTION_SETTINGS - MENUITEM "Close Desktop Lyric", ID_CLOSE_DESKTOP_LYRIC - END + 0, + 0, 0, 100, 0, + 0, 0, 100, 100, + 100, 100, 0, 0, + 100, 100, 0, 0 END -IDR_LRYIC_DEFAULT_STYLE_MENU MENU +IDD_PROPERTY_ALBUM_COVER_DIALOG AFX_DIALOG_LAYOUT BEGIN - POPUP "1" - BEGIN - MENUITEM "Preset 1", ID_LYRIC_DEFAULT_STYLE1 - MENUITEM "Preset 2", ID_LYRIC_DEFAULT_STYLE2 - MENUITEM "Preset 3", ID_LYRIC_DEFAULT_STYLE3 - END - POPUP "2" - BEGIN - MENUITEM "Preset 1", ID_LYRIC_DEFAULT_STYLE1 - MENUITEM "Preset 2", ID_LYRIC_DEFAULT_STYLE2 - MENUITEM "Preset 3", ID_LYRIC_DEFAULT_STYLE3 - MENUITEM SEPARATOR - POPUP "Modify Style Preset" - BEGIN - MENUITEM "Preset 1", ID_LYRIC_DEFAULT_STYLE1_MODIFY - MENUITEM "Preset 2", ID_LYRIC_DEFAULT_STYLE2_MODIFY - MENUITEM "Preset 3", ID_LYRIC_DEFAULT_STYLE3_MODIFY - MENUITEM SEPARATOR - MENUITEM "Restore Default", ID_RESTORE_DEFAULT_STYLE - END - END + 0, + 60, 0, 40, 100, + 60, 100, 0, 0, + 60, 100, 0, 0, + 60, 100, 40, 0, + 60, 100, 40, 0 END -IDR_PLAYLIST_TOOLBAR_MENU MENU +IDD_PROPERTY_PARENT_DIALOG AFX_DIALOG_LAYOUT BEGIN - POPUP "Add" - BEGIN - MENUITEM "&Add Files...", ID_PLAYLIST_ADD_FILE - MENUITEM "Add &Folder...", ID_PLAYLIST_ADD_FOLDER - MENUITEM "Add &URL...", ID_PLAYLIST_ADD_URL - END - POPUP "Delete" - BEGIN - MENUITEM "Remo&ve from Playlist", ID_REMOVE_FROM_PLAYLIST - MENUITEM "&Delete from Disk", ID_DELETE_FROM_DISK - MENUITEM SEPARATOR - MENUITEM "Cl&ear Playlist", ID_EMPTY_PLAYLIST - MENUITEM "Remove &Same Items", ID_REMOVE_SAME_SONGS - MENUITEM "Remove &Invalid Items", ID_REMOVE_INVALID_ITEMS - END - POPUP "Sort" - BEGIN - MENUITEM "Sort by File Name", ID_SORT_BY_FILE - MENUITEM "Sort by Path", ID_SORT_BY_PATH - MENUITEM "Sort by Title", ID_SORT_BY_TITLE - MENUITEM "Sort by Artist", ID_SORT_BY_ARTIST - MENUITEM "Sort by Album", ID_SORT_BY_ALBUM - MENUITEM "Sort by Track", ID_SORT_BY_TRACK - MENUITEM "Sort by Modified Time", ID_SORT_BY_MODIFIED_TIME - MENUITEM SEPARATOR - MENUITEM "Ascending", ID_ACCENDING_ORDER - MENUITEM "Descending", ID_DESENDING_ORDER - MENUITEM SEPARATOR - MENUITEM "Invert", ID_INVERT_PLAYLIST - END - POPUP "Playlist" - BEGIN - MENUITEM "&Reload Playlist", ID_RELOAD_PLAYLIST - MENUITEM "Save As &New Playlist...", ID_SAVE_AS_NEW_PLAYLIST - MENUITEM "&Save Current Playlist As...", ID_SAVE_CURRENT_PLAYLIST_AS - MENUITEM SEPARATOR - MENUITEM "&Fix the wrong file path", ID_PLAYLIST_FIX_PATH_ERROR - POPUP "Playlist Display Mode" - BEGIN - MENUITEM "File Name", ID_DISP_FILE_NAME - MENUITEM "Title", ID_DISP_TITLE - MENUITEM "Artist - Title", ID_DISP_ARTIST_TITLE - MENUITEM "Title - Artist", ID_DISP_TITLE_ARTIST - END - MENUITEM "&Options...", ID_PLAYLIST_OPTIONS - END - POPUP "Edit" - BEGIN - POPUP "Add to Playlis&t" - BEGIN - MENUITEM "&New Playlist...", ID_ADD_TO_NEW_PLAYLIST - MENUITEM SEPARATOR - MENUITEM "Default", ID_ADD_TO_DEFAULT_PLAYLIST - MENUITEM "My Favourite", ID_ADD_TO_MY_FAVOURITE - END - MENUITEM SEPARATOR - MENUITEM "&Copy File to...", ID_COPY_FILE_TO - MENUITEM "&Move File to...", ID_MOVE_FILE_TO - MENUITEM SEPARATOR - MENUITEM "Move &Up", ID_MOVE_PLAYLIST_ITEM_UP - MENUITEM "Move Do&wn", ID_MOVE_PLAYLIST_ITEM_DOWN - MENUITEM SEPARATOR - MENUITEM "Select &All", ID_PLAYLIST_SELECT_ALL - MENUITEM "Select N&one", ID_PLAYLIST_SELECT_NONE - MENUITEM "Select &Reverse", ID_PLAYLIST_SELECT_REVERT - END - POPUP "Folder" - BEGIN - MENUITEM "Open &Folder...", ID_FILE_OPEN_FOLDER - MENUITEM "Contains &Subfolders", ID_CONTAIN_SUB_FOLDER - END + 0, + 0, 0, 100, 100, + 0, 100, 0, 0, + 0, 100, 0, 0, + 0, 100, 100, 0, + 100, 100, 0, 0, + 100, 100, 0, 0 END -IDR_MEDIA_LIB_POPUP_MENU MENU +IDD_TAG_MODE_SELECT_DIALOG AFX_DIALOG_LAYOUT BEGIN - POPUP "左侧菜单" - BEGIN - MENUITEM "&Play", ID_PLAY_ITEM - POPUP "Add to Playlis&t" - BEGIN - MENUITEM "&New Playlist...", ID_ADD_TO_NEW_PLAYLIST - MENUITEM SEPARATOR - MENUITEM "Default", ID_ADD_TO_DEFAULT_PLAYLIST - MENUITEM "My Favourite", ID_ADD_TO_MY_FAVOURITE - END - MENUITEM "Add to &New Playlist And Play...", ID_ADD_TO_NEW_PALYLIST_AND_PLAY - MENUITEM SEPARATOR - MENUITEM "&Copy Text", ID_COPY_TEXT - END - POPUP "右侧菜单" - BEGIN - MENUITEM "&Play", ID_PLAY_ITEM - MENUITEM "Play &Next", ID_PLAY_AS_NEXT - MENUITEM "Play in Folder Mode", ID_PLAY_ITEM_IN_FOLDER_MODE - MENUITEM SEPARATOR - POPUP "Add to Playlis&t" - BEGIN - MENUITEM "&New Playlist...", ID_ADD_TO_NEW_PLAYLIST - MENUITEM SEPARATOR - MENUITEM "Default", ID_ADD_TO_DEFAULT_PLAYLIST - MENUITEM "My Favourite", ID_ADD_TO_MY_FAVOURITE - END - MENUITEM "Add to &New Playlist And Play...", ID_ADD_TO_NEW_PALYLIST_AND_PLAY - MENUITEM SEPARATOR - MENUITEM "View &Online", ID_EXPLORE_ONLINE - MENUITEM "&Format Convert...", ID_FORMAT_CONVERT - MENUITEM "Open File &Location", ID_EXPLORE_TRACK - MENUITEM "&Delete from Disk", ID_DELETE_FROM_DISK - MENUITEM "Propert&y...", ID_ITEM_PROPERTY - MENUITEM SEPARATOR - MENUITEM "&Copy Text", ID_COPY_TEXT - END + 0 END -IDR_PROPERTY_COVER_MENU MENU +IDD_SELECT_ITEM_DIALOG AFX_DIALOG_LAYOUT BEGIN - POPUP "1" - BEGIN - MENUITEM "&Browse...", 33198 - MENUITEM "&Delete", 33199 - MENUITEM "&Save As...", ID_COVER_SAVE_AS - MENUITEM "&Compress Size", ID_COMPRESS_SIZE - END + 0, + 0, 0, 100, 100, + 100, 100, 0, 0, + 100, 100, 0, 0 END -IDR_PROPERTY_MENU MENU +IDD_FLAC_ENCODE_CFG_DIALOG AFX_DIALOG_LAYOUT BEGIN - POPUP "1" - BEGIN - MENUITEM "&Copy Text", ID_COPY_TEXT - MENUITEM "Copy &All Text", ID_COPY_ALL_TEXT - END + 0 END ///////////////////////////////////////////////////////////////////////////// // -// TEXT -// - -IDR_TEXT1 TEXT "Help_en_us.txt" - -IDR_LICENSE TEXT "..\\LICENSE" - -IDR_UI1 TEXT "skins\\ui1.xml" - -IDR_UI2 TEXT "skins\\ui2.xml" - -IDR_ACKNOWLEDGEMENT TEXT "res\\Acknowledgement_en.txt" - - -///////////////////////////////////////////////////////////////////////////// -// -// Bitmap +// Dialog Info // -IDB_DEFAULT_COVER BITMAP "res\\default_cover.bmp" +IDD_TEST_DIALOG DLGINIT +BEGIN + IDC_MFCEDITBROWSE1, 0x37c, 42, 0 +0x4d3c, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, 0x4d5f, 0x646f, +0x3e65, 0x3c31, 0x4d2f, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, +0x4d5f, 0x646f, 0x3e65, + 0 +END +IDD_MEDIA_CLASSIFY_DIALOG DLGINIT +BEGIN + IDC_MFCEDITBROWSE1, 0x37c, 42, 0 +0x4d3c, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, 0x4d5f, 0x646f, +0x3e65, 0x3c31, 0x4d2f, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, +0x4d5f, 0x646f, 0x3e65, + 0 +END -///////////////////////////////////////////////////////////////////////////// -// -// Dialog Info -// +IDD_FOLDER_EXPLORE_DIALOG DLGINIT +BEGIN + IDC_MFCEDITBROWSE1, 0x37c, 42, 0 +0x4d3c, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, 0x4d5f, 0x646f, +0x3e65, 0x3c31, 0x4d2f, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, +0x4d5f, 0x646f, 0x3e65, + 0 +END -IDD_MUSICPLAYER2_DIALOG DLGINIT +IDD_ALL_MEDIA_DIALOG DLGINIT BEGIN IDC_SEARCH_EDIT, 0x37c, 42, 0 0x4d3c, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, 0x4d5f, 0x646f, -0x3e65, 0x3c33, 0x4d2f, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, +0x3e65, 0x3c31, 0x4d2f, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, 0x4d5f, 0x646f, 0x3e65, + 0 +END + +IDD_MUSICPLAYER2_DIALOG DLGINIT +BEGIN IDC_PATH_EDIT, 0x37c, 42, 0 0x4d3c, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, 0x4d5f, 0x646f, 0x3e65, 0x3c31, 0x4d2f, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, +0x4d5f, 0x646f, 0x3e65, + IDC_SEARCH_EDIT, 0x37c, 42, 0 +0x4d3c, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, 0x4d5f, 0x646f, +0x3e65, 0x3c33, 0x4d2f, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, 0x4d5f, 0x646f, 0x3e65, 0 END @@ -6551,13 +2869,13 @@ END IDD_FORMAT_CONVERT_DIALOG DLGINIT BEGIN - IDC_OUT_DIR_EDIT, 0x37c, 42, 0 -0x4d3c, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, 0x4d5f, 0x646f, -0x3e65, 0x3c31, 0x4d2f, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, -0x4d5f, 0x646f, 0x3e65, IDC_OUT_NAME_EDIT, 0x37c, 42, 0 0x4d3c, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, 0x4d5f, 0x646f, 0x3e65, 0x3c33, 0x4d2f, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, +0x4d5f, 0x646f, 0x3e65, + IDC_OUT_DIR_EDIT, 0x37c, 42, 0 +0x4d3c, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, 0x4d5f, 0x646f, +0x3e65, 0x3c31, 0x4d2f, 0x4346, 0x6445, 0x7469, 0x7242, 0x776f, 0x6573, 0x4d5f, 0x646f, 0x3e65, 0 END @@ -6600,708 +2918,22 @@ END ///////////////////////////////////////////////////////////////////////////// // -// String Table +// TEXT // -STRINGTABLE -BEGIN - IDS_ABOUTBOX "&About MusicPlayer2..." - IDS_STRING102 "Warning: The current selection of the font size is too large, which may cause the console window information to not be fully displayed!" - IDS_STRING103 "The content to be saved contains Unicode characters that will be lost if saved in ANSI format. If you want to keep these characters, select Save As UTF-8 format. Are you sure you want to save it?" - IDS_LYRIC_FOLDER_NOT_EXIST - "The lyrics folder does not exist, please reset the lyrics folder!" - IDS_BASS_VERSION_WARNING - "The bass.dll file version does not match, the version is <%1%>.<%2%>, and the expected version is <%3%>.<%4%>. The mismatched version may cause an exception when playing. Do you still want to continue?" - IDS_CHECK_UPDATA_FAILED "Check for update failed, please check your network connection!" - IDS_CHECK_UPDATA_ERROR "Check for update failed and get the wrong information from the remote update file, please contact the author!" - IDS_UPDATE_AVLIABLE "New version V<%1%> detected, do you want to go to update?" - IDS_UPDATE_AVLIABLE2 "New version V<%1%> detected, update content: \r\n<%2%>\r\ndo you want to go to update?" - IDS_ALREADY_UPDATED "Already updated to the latest version." - IDS_RESTART_EXIT "The program has been restarted by Windows Restartmanager, restart parameters: <%1%>, the program has exited." -END - -STRINGTABLE -BEGIN - IDS_SERIALIZE_ERROR "A serialization exception occurred while reading the data file ""<%1%>"", the exception type: Carchiveexception,m_cause = <%2%>. It may be caused by the corruption of data file or a version mismatch." - IDS_SEND_EMAIL_TO_ATHOUR "Send an e-mail to the author." - IDS_GOTO_GITHUB "Go to the page on GitHub for this project." - IDS_DONATE_ATHOUR "Donate the author" - IDS_LANGUAGE_CODE "1" - IDS_DEFAULT_FONT "Segoe UI" - IDS_PLAY "Play" - IDS_PAUSE "Pause" - IDS_PREVIOUS "Previous" - IDS_NEXT "Next" - IDS_PLAY2 "&Play" - IDS_PAUSE2 "&Pause" - IDS_CREATE_SHORTCUT_INFO - "You may be running this program for the first time, do you want to create a shortcut to the program on the desktop?" - IDS_SHORTCUT_CREATED "A shortcut to the program has been created under the ""<%1%>"" path." - IDS_SHORTCUT_CREAT_FAILED "Shortcut create failed!" - IDS_MINI_MODE "Mini mode" -END - -STRINGTABLE -BEGIN - IDS_MINI_MODE2 "M&ini Mode" - IDS_SELECT_RENENT_FOLDER "Select a recently played folder" - IDS_PLAY_TIME "Play time" - IDS_CLEAR_SEARCH_RESULT "Clear search results" - IDS_INPUT_KEY_WORD "Input the keyword to search" - IDS_SEARCH_HERE "Type here to search" - IDS_NOW_PLAYING "Now Playing" - IDS_CONNOT_FIND_FILE "The file ""<%1%>"" could not be found! It may have been moved or deleted." - IDS_ALL_SUPPORTED_FORMAT "All supported audio formats" - IDS_ALL_FILES "All files" - IDS_OPEN_FOLDER_INFO "Please select a folder where all audio files in the folder will be added to the playlist." - IDS_DELETE_FILE_INQUARY "Are you sure you want to delete the selected <%1%> songs?" - IDS_CONNOT_DELETE_FILE "Unable to delete file!" - IDS_COPY_CLIPBOARD_FAILED "Copy to clipboard failed!" - IDS_ALL_LRYIC_COPIED "All lyrics have been copied to the Clipboard." - IDS_DEBUG_MODE "(DEBUG Mode)" -END - -STRINGTABLE -BEGIN - IDS_NO_MIDI_SF2_WARNING "You are playing MIDI music, but you will not hear any sound because the MIDI sound font is not loaded correctly. Please select the correct MIDI sound font in the menu ""Tools""--""options""--""General settings""-- ""MIDI sound font path"", and select the correct MIDI sound font path. Click ""Cancel"" will no longer prompt." - IDS_SELECT_COPY_TARGET_FOLDER "Select the copy destination folder" - IDS_SELECT_MOVE_TARGET_FOLDER "Select the move destination folder" - IDS_DEFAULT_TITLE "" - IDS_DEFAULT_ARTIST "" - IDS_DEFAULT_ALBUM "" - IDS_DEFAULT_YEAR "" - IDS_DEFAULT_GENRE "" - IDS_DEFAULT_LYRIC_TEXT "..." - IDS_DEFAULT_LYRIC_TEXT_CORTANA "Music ..." - IDS_VOLUME "Volume" - IDS_PLAY_ERROR "Play error" - IDS_SEEK_TO_MINUTE_SECOND "Seek to %d minute %.2d second" - IDS_SHOW_HIDE_PLAYLIST "Show/hide playlist" - IDS_BACK_TO_NARMAL "Back to normal mode" - IDS_EXIT_PROGRAM "Exit the program" -END - -STRINGTABLE -BEGIN - IDS_SEEK_TO "Seek to" - IDS_TITLE "Title" - IDS_RHYTHM "Rhythm" - IDS_SOUND_FONT "Sound font" - IDS_ARTIST "Artist" - IDS_ALBUM "Album" - IDS_FORMAT "Format" - IDS_MONO "Mono" - IDS_STEREO "Stereo" - IDS_CHANNEL "Channels" - IDS_NO_LYRIC_INFO "The current song has no lyrics" - IDS_LYRIC_SHOW "Lyric Show" - IDS_TRAS "Tr" - IDS_ALBUM_COVER "Album cover" - IDS_INNER_ALBUM_COVER_TIP_INFO "Inner image\r\nImage format: " - IDS_OUT_IMAGE "External image" -END - -STRINGTABLE -BEGIN - IDS_PLAYLIST_INIT_INFO "Find <%1%> songs, reading audio file information, please wait ..." - IDS_REPEAT_MODE "Repeat mode" - IDS_PLAY_ODER "Play in oder" - IDS_LOOP_PLAYLIST "Loop playlist" - IDS_LOOP_TRACK "Loop track" - IDS_PLAY_SHUFFLE "Play shuffle" - IDS_SHOW_LYRIC_TRANSLATION "Show lyric translation" - IDS_MOUSE_WHEEL_ADJUST_VOLUME "Use mouse wheel to adjust volume" - IDS_SWITCH_UI "Switch UI" - IDS_SOUND_EFFECT_SETTING "Sound effect settings" - IDS_SETTINGS "Settings" - IDS_FIND_DLG_INFO "Find keyword <%1%>, <%2%> results." - IDS_FIND_RESULT "Find result" - IDS_NO_RESULT "No results found!" - IDS_NUMBER "No." - IDS_FILE_NAME "File name" -END - -STRINGTABLE -BEGIN - IDS_FILE_PATH "File path" - IDS_CHARACTER_TOTAL "<%1%> characters" - IDS_MODIFIED "Modified" - IDS_UNMODIFIED "Unmodified" - IDS_ENCODE_FORMAT "Encode format" - IDS_UTF8_NO_BOM "UTF8 no BOM" - IDS_LYRIC_SAVE_INRUARY "The lyrics have changed, do you want to save them?" - IDS_LYRIC_FILE_FILTER "Lyric file(*.lrc;*.ksc)|*.lrc;*.ksc|Text file(*.txt)|*.txt|All file(*.*)|*.*||" - IDS_SAVE_AS_ANSI "Save as ANSI format" - IDS_SAVE_AS_UTF8 "Save as UTF8 format" - IDS_REPLACE_COMPLETE_INFO "Replace complete with <%1%> strings." - IDS_CONNOT_FIND_STRING "Can't find ""<%1%>""" - IDS_INSERT_TIME_TAG_TIP "Insert time tag (F8)" - IDS_REPLACE_TIME_TAG_TIP "Replace time tag (F9)" - IDS_DELETE_TIME_TAG_TIP "Delete time tag (Ctrl+Del)" - IDS_SAVE_TIP "Save (Ctrl+S)" -END - -STRINGTABLE -BEGIN - IDS_PLAY_PAUSE_TIP "Play/Pause (Ctrl+P)" - IDS_REWIND_TIP "Rewind (Ctrl+Left)" - IDS_FAST_FOWARD_TIP "Fast forward (Ctrl+Right)" - IDS_FIND_TIP "Find (Ctrl+F)" - IDS_REPLACE_TIP "Replace (Ctrl+H)" - IDS_CANNOT_GET_SONG_LENGTH "Song length not obtained" - IDS_NO_MATCHED_LYRIC "No matched lyrics" - IDS_MP3_TAG_TYPE "Tag type: " - IDS_UNKNOW "Unknown" - IDS_CANNOT_WRITE_TO_FILE "Unable to write to file!" - IDS_FOLDER "Folder" - IDS_PATH "Path" - IDS_TRACK_PLAYED "Last played track" - IDS_TRACK_TOTAL_NUM "Total track number" - IDS_TOTAL_LENGTH "Total length" - IDS_CLEAR_PATH_INQUARY "Are you sure you want to clear the invalid folder in the list?" -END - -STRINGTABLE -BEGIN - IDS_PATH_CLEAR_COMPLETE "Complete, <%1%> invalid folder cleared." - IDS_NONE "None" - IDS_CLASSICAL "Classical" - IDS_POP "Popular" - IDS_JAZZ "Jazz" - IDS_ROCK "Rock" - IDS_SOFT "Soft" - IDS_BASS "Heavy bass" - IDS_ELIMINATE_BASS "Eliminate bass" - IDS_WEAKENING_TREBLE "Weakening treble" - IDS_USER_DEFINE "Custom" - IDS_EQUALIZER "Equalizer" - IDS_REVERB "Reverb" - IDS_PLUGIN_FILE_NAME "Plug-in file name" - IDS_FORMAT_SUPPORTED "Format support provided" - IDS_FILE_EXTENSION "File extension" -END - -STRINGTABLE -BEGIN - IDS_STATE "State" - IDS_LYRIC_BATCH_DOWNLOADING_INFO - "Downloading lyrics, <%1%>% completed, please wait..." - IDS_DOWNLOADING "Downloading..." - IDS_SKIPED "skipped" - IDS_NETWORK_CONNECTION_FAILED "Network connection failed or timed out" - IDS_CANNOT_FIND_THIS_SONG "This song could not be found" - IDS_LYRIC_DOWNLOAD_FAILED "Lyrics download failed" - IDS_SONG_NO_LYRIC "The song has no lyrics" - IDS_DOWNLOAD_ENCODE_WARNING - "Successful, but there are Unicode characters in the lyrics that cannot be converted, it is recommended to save them in UTF-8 format" - IDS_SUCCESSED "Succeed" - IDS_DOWNLOAD_COMPLETE "Download complete." - IDS_RETURN_VALUE_OF_WAIT_FOR_SINGLE_OBJECT - "The return value of WaitForSingleObject is %x." - IDS_SEARCHING "Searching..." - IDS_SEARCH_FAILED_INFO "Search failed, please check your network connection!" - IDS_SEARCH_TIME_OUT "Search Timeout!" - IDS_SEARCH_NO_SONG "Search results: (No songs found)" -END - -STRINGTABLE -BEGIN - IDS_SEARCH_NO_MATCHED "Search results: (Seems to no best match for this item)" - IDS_SEARCH_RELATED "Search results: (Linked item: <%1%>)" - IDS_SEARCH_BEST_MATCHED "Search results: (Best batched item: <%1%>)" - IDS_LYRIC_OVERWRITE_INQUARY - "The lyrics file already exists, do you want to replace it?" - IDS_DOWNLOAD_COMPLETE_SAVED "Download complete, saved as ""<%1%>""." - IDS_CONVERTING_STATE "Conversion state" - IDS_MP3_LAME_ENCODER "MP3 (lame Encoder)" - IDS_AUTO_RENAME "Auto rename" - IDS_IGNORE "Skip" - IDS_OVERWRITE "Overwrite" - IDS_CONVERT_WMA_ERROR "Error converting ""<%1%>"" to WMA:" - IDS_NO_WMP9_OR_LATER "Windows Media Player 9 or later is not installed." - IDS_NO_SUPPORTED_ENCODER_WARNING - "The codec that supports the requested sampling format and bit rate could not be found." - IDS_UNKNOW_ERROR "Unknown error." - IDS_BASS_ENCODER_LOAD_ERROR - "BASS Encoder load failed, file ""<%1%>"" may be lost or corrupted!" - IDS_SET_OUTPUT_DIR_INFO "Please set the output directory!" -END - -STRINGTABLE -BEGIN - IDS_OUTPUT_DIR_NOT_EXIST "Output directory ""<%1%>""does not exist!" - IDS_SELECT_OUTPUT_FOLDER "Select output folder" - IDS_ERROR "Error" - IDS_COMPLEATE "Complete" - IDS_SKIPED1 "Skipped" - IDS_CURRENT_SELECTED "Current selection" - IDS_CURRENT_COLOR "Current color" - IDS_LIGNT_BLUE "Azure" - IDS_GREEN "Green" - IDS_ORANGE "Orange" - IDS_CYAN_GREEN "Turquoise" - IDS_PINK "Pink" - IDS_LIGHT_PURPLE "Pale purple" - IDS_STRETCH "Stretch" - IDS_FILL "Fill" - IDS_ADAPT "Adapt" -END - -STRINGTABLE -BEGIN - IDS_COVER_FIT_TIP_INFO "Stretch: Will change the aspect ratio.\r\nFill: Will not change the aspect ratio, will crop the long edge.\r\nAdatp: will not change the aspect ratio, not crop." - IDS_USE_OUT_IMAGE_TIP_INFO - "If the album cover can't be get from the audio file, it will try to looking for the specified file name for the album cover in the directory where the audio file located." - IDS_DEFAULT_COVER_NAME_TIP_INFO - "Set the default album cover file name here, separated by a comma between multiple file names, support wildcards and relative paths, setting absolute paths will make the cover search always successful and not automatically download the album cover." - IDS_WHITE_THEME_COLOR_WARNING - "Warning: Setting the theme color to white will make the progress bar completely invisible!" - IDS_FOLLOWING_SYSTEM "Following system" - IDS_CLEAR_DATA_FILE_TIP_INFO - "Description: The song_data.dat file in the program directory holds all loaded song information to speed up the loading of the playlist. Click this button to clean up non-existing files." - IDS_AUTO_DOWNLOAD_LYRIC_TIP_INFO - "After checking this item, the lyrics and album covers are automatically downloaded only if neither the title nor the artist information of the song is empty." - IDS_MIDI_INNER_LYRIC_TIP_INFO - "Some MIDI music contains lyrics, and when you check this item, it will give priority to displaying the lyrics embedded in MIDI music." - IDS_CURRENT_DATA_FILE_SIZE "Current data file size" - IDS_BYTE "Bytes" - IDS_CLEAR_COMPLETE_INFO "Cleanup completed, <%1%> items have been deleted, and the data file size is reduced by <%2%> bytes." - IDS_SOUND_FONT_FILTER "Sound font files|*.SF2|All files|*.*||" - IDS_FUNCTION "Function" - IDS_SHORTCUT_KEY "Shortcut key" - IDS_PLAY_PAUSE "Play/Pause" - IDS_STOP "Stop" -END - -STRINGTABLE -BEGIN - IDS_FAST_FORWARD "Fast forward" - IDS_REWIND "Rewind" - IDS_VOLUME_UP "Volume up" - IDS_VOLUME_DOWN "Volume down" - IDS_EXIT "Exit" - IDS_GLOBLE_HOT_KEY_WARNING - "Global shortcuts need to contain at least one of Ctrl, Shift, and Alt!" - IDS_LYRIC_FUZZY_MATHC_TIP_INFO - "If you remove the check of this check box, it will only match the lyrics file that is exactly the same as the song file name; \r\n If you select this check box, the lyrics file that contains the artist and song title in the file name will match when it cannot find the exact same lyrics file for the file name. \r\n (You may need to restart the program to take it effect.) " - IDS_LYRIC_PATH_TIP_INFO "Description: If it can't find a matching lyrics file in the directory where the song is located, it will looking for the lyrics file in this folder." - IDS_CORTANA_SHOW_LYRIC_TIP_INFO - "After the check option, it can display lyrics, song names, and album covers in the Cortana search box. After you turn on this feature, you may need to restart the program to take effect." - IDS_BLACK "Black" - IDS_WHITE "White" - IDS_SELECT_LYRIC_FOLDER "Select lyrics folder" - IDS_LYRIC_SETTINGS "Lyrics Settings" - IDS_APPEARANCE_SETTINGS "Appearance Settings" - IDS_GENERAL_SETTINGS "General Settings" - IDS_PLAY_SETTINGS "Play Settings" -END - -STRINGTABLE -BEGIN - IDS_GLOBLE_HOTKEY "Global Shortcut Keys" - IDS_DEVICE_TYPE_DIGITAL "An audio endpoint device that connects to an audio adapter through a connector for a digital interface of unknown type." - IDS_DEVICE_TYPE_DISPLAYPORT - "An audio endpoint device that connects to an audio adapter through a DisplayPort connector." - IDS_DEVICE_TYPE_HANDSET "The part of a telephone that is held in the hand and that contains a speaker and a microphone for two-way communication." - IDS_DEVICE_TYPE_HDMI "An audio endpoint device that connects to an audio adapter through a High-Definition Multimedia Interface (HDMI) connector. " - IDS_DEVICE_TYPE_HEADPHONES "Headphones" - IDS_DEVICE_TYPE_HEADSET "An earphone or a pair of earphones with an attached mouthpiece for two-way communication." - IDS_DEVICE_TYPE_LINE "An audio endpoint device that sends a line-level analog signal to a line-input jack on an audio adapter or that receives a line-level analog signal from a line-output jack on the adapter." - IDS_DEVICE_TYPE_MICROPHONE "Microphone" - IDS_DEVICE_TYPE_NETWORK "An audio endpoint device that the user accesses remotely through a network." - IDS_DEVICE_TYPE_SPDIF "An audio endpoint device that connects to an audio adapter through a Sony/Philips Digital Interface (S/PDIF) connector. " - IDS_DEVICE_TYPE_SPEAKERS "Speakers" - IDS_ITEM "Item" - IDS_VLAUE "Value" - IDS_NAME "Name" - IDS_DRIVER "Driver" -END - -STRINGTABLE -BEGIN - IDS_DEVICE_TYPE "Device type" - IDS_ALBUM_COVER_DOWNLOAD_FAILED_WARNING - "Album cover download failed, please check your network connection!" - IDS_AUDIO_FILE "Audio file" - IDS_MINI_SEQUENCE "MIDI Sequence" - IDS_DELETE "Delete" - IDS_COPY "Copy" - IDS_MOVE "Move" - IDS_INVALID_DIR_WARNING "Invalid directory, please reselect!" - IDS_DEFAULT_OUTPUT_DEVICE "Default output device" - IDS_BASIC_AUDIO_FORMAT "Basic audio formats" - IDS_SOUND_FONT_LOAD_FAILED "Sound font ""<%1%>"" load failed!" - IDS_LOAD_FAILED "Load failed" - IDS_BASS_ERROR_LOG_INFO "An error occurred with the Bass Audio library, error code: <%1%>. File name: <%2%>" - IDS_LANGUAGE_CHANGE_INFO - "Please restart the application to apply the language setting." - IDS_STOPED "Stopped" - IDS_PAUSED "Paused" -END - -STRINGTABLE -BEGIN - IDS_RECENT_PATH_SERIALIZE_ERROR_LOG - "A serialization exception occurred while reading the recent path file, exception type: Carchiveexception, m_cause = <%1%>. It may be caused by a corrupted recent_path.dat file or a version mismatch." - IDS_NO_RESULT_TO_SHOW "No results to be shown" - IDS_BITRATE "Bit rate" - IDS_TRACK "Track" - IDS_LENGTH "Length" - IDS_TEST_STR "测试_<%1%>_@@#$_#_<%2%>_ERgfde<%3%>_444" - IDS_CLOSE "Close" - IDS_MULTI_MEDIA_KEY_TIP "When this option is checked, even if the program is running in the background, you can still control the playing of the music by the multimedia keys on your keyboard. It would be taken effect after the program is restarted." - IDS_SONG_INFO "Song Info" - IDS_SELECT_FOLDER "Select folder" - IDS_FIND_SONGS "Find songs" - IDS_EXIT_FULL_SCREEN "Exit Full Screen" - IDS_FULL_SCREEN "Full Screen" - IDS_WELCOM_TO_USE "Welcome to use MusicPlayer2!" - IDS_ERROR_MESSAGE "Error Message:" - IDS_CRASH_INFO "Sorry, the program has crashed. Please email this file ""<%1%>"" to zhongyang219@hotmail.com to help the author locate the problem. And add the following to the body of the message:" -END - -STRINGTABLE -BEGIN - IDS_ERROR1 "Error" - IDS_HELP "Help" - IDS_FILE_NOT_FOUND "File not found" - IDS_PLAY_SHORTCUT_CREATED - "The playback control shortcuts has been created in the <%1%> directory." - IDS_CREATE_PLAY_SHORTCUT_INFO - "This command will create the playback control shortcuts in the directory where the program is located. When the player is running, you can control the playback of the music through these shortcuts. You can also pin them to the taskbar. Do you want to create the playback control shortcuts?" - IDS_LISTEN_TIME "Total play time" - IDS_LISTEN_TIME_FILE_DLG_FILTER - "Csv Files(*.csv)|*.csv|All Files(*.*)|*.*||" - IDS_LISTEN_TIMES "Play times" - IDS_LISTEN_TIME_STATISTICS "Total play time statistics" - IDS_HIDE_MENU_BAR_TIP "Tip: After you hide the menu bar, you can right-click the window title bar, or click the main menu ""≡"" button on the top right, and select ""View"" - ""Show Menu Bar"" in the pop-up menu to re-display the menu bar. \r\n Click ""Cancel"" to no longer prompt." - IDS_LYRIC_PREVIEW "Lyric Preview" - IDS_CRASH_ERROR_LOG_INFO - "The program crashed, the dump file has been saved to ""<%1%>""." - IDS_MAIN_MENU "Main Menu" - IDS_LYRIC_SAVE_FAILED "The lyric failed to save, please check if the target folder has write permission!" - IDS_PLAYLIST "Playlist" - IDS_PLAYLIST_FILTER "Text file(*.txt)|*.txt|All file(*.*)|*.*||" -END - -STRINGTABLE -BEGIN - IDS_CLEAR_PLAYLIST_WARNING "Are you sure you want to clear the playlist?" - IDS_DEFAULT "Default" - IDS_NEW_PLAYLIST "New Playlist" - IDS_INPUT_PLAYLIST_NAME "Input the playlist name:" - IDS_RENAME_PLAYLIST "Rename Playlist" - IDS_CURRENT_FOLDER "Current folder" - IDS_PLAYLIST_EXIST_WARNING "Playlist ""<%1%>"" already exists!" - IDS_REMOVE_SAME_SONGS_INFO "Complete, <%1%> item(s) removed." - IDS_MEDIA_LIB "Media Library" - IDS_OPEN_MEDIA_LIB "Open media library" - IDS_ADD_TO_PLAYLIST_FAILED_WARNING - "Add failed, playlist ""<%1%>"" does not exist!" - IDS_DESCRIPTION "Description" - IDS_INCLUDE_SUB_DIR "Include subfolders" - IDS_MY_FAVURITE "My Favourite" - IDS_ADD_TO_MA_FAVOURITE "Add to ""My Favourite""" - IDS_REMANE_FAILED "Rename failed!" -END - -STRINGTABLE -BEGIN - IDS_REMOVE_MY_FAVOURITE_WARNING - "Canceling ""My Favourite"" will remove the track being played from the current playlist. Do you want to continue?" - IDS_FILE_NAME_INVALID_WARNING - "The following characters cannot be included in the name:\n\\""/:*?<>|" - IDS_OPEN_URL "Open URL" - IDS_ADD_URL "Add URL" - IDS_INPUT_URL_TIP "Please input the URL:" - IDS_MCI_INIT_FAILED "MCI initialization failed!" - IDS_MCI_NO_THIS_FUNCTION_WARNING - "This function cannot be used in the MCI kernel!" - IDS_MCI_KERNAL_TIP "Using the MCI kernel will result in format conversion and sound effect settings being unavailable and some audio will not be played. It is recommended to switch to this kernel only when needed." - IDS_CLEAR_LISTEN_TIME_WARNING - "Are you sure you want to clear all the statistics?" - IDS_PLAYLIST_NAME_EMPTY_WARNING "The playlist name cannot be empty!" - IDS_ALBUM_COVER_COMPRESSED "Oversized album cover compressed" - IDS_TOW_COLOR_GRADIENT "Two-color gradient" - IDS_THREE_COLOR_GRADIENT "Three-color gradient" - IDS_NO_GRADIENT "No gradient" - IDS_LRC "Lrc" - IDS_SHOW_DESKTOP_LYRIC "Show desktop lyric" -END - -STRINGTABLE -BEGIN - IDS_LOCK_DESKTOP_LYRIC "Lock desktop lyric" - IDS_CLOSE_DESKTOP_LYRIC "Close desktop lyric window" - IDS_LYRIC_DOUBLE_LINE "Lyrics displayed in &double line" - IDS_LYRIC_BACKGROUND_PENETRATE "Lyrics background penetrate" - IDS_ULOCK_DESKTOP_LYRIC "Unlock desktop lyric" - IDS_ADD "Add" - IDS_SORT "Sort" - IDS_LIST "Playlist" - IDS_EDIT "Edit" - IDS_DEFAULT_STYLE "Default style" - IDS_MODIFY_DEFAULT_STYLE_WARNING - "Are you sure you want to override ""Default <%1%>"" with the current color setting?" - IDS_RESTORE_DEFAULT_STYTLE_WARNING - "All the modified default style will be restored, do you want to continue?" - IDS_URL_INVALID_WARNING "Please input the correct URL!" - IDS_PROGRESS_INFO "<%1%>% completed, please wait..." - IDS_BASS_MIX_LOAD_ERROR "BASSmix load failed, file ""<%1%>"" may be lost or corrupted!" - IDS_BROWSE "Browse" -END - -STRINGTABLE -BEGIN - IDS_OTHER "Others" - IDS_SEARCH_ARTIST "Type here to search artist" - IDS_SEARCH_ALBUM "Type here to search album" - IDS_TEMP_PLAYLIST "Temporary playlist" - IDS_GENRE "Genre" - IDS_SEARCH_GENRE "Type here to search genre" - IDS_YEAR "Year" - IDS_SEARCH_YEAR "Type here to search year" - IDS_TRACK_NUM "Track number" - IDS_FOLDER_EXPLORE "Folder explore" - IDS_SEARCH_FORDER "Type here to search folder" - IDS_BTN_SETTINGS "&Settings..." - IDS_MORE_PLAYLIST "More Playlist" - IDS_SEARCH_RESULT "Search results:" - IDS_UPDATING_MEDIA_LIB_INFO - "Updating media library... <%1%> tracks updated." - IDS_ERROR_CODE "Error code" -END - -STRINGTABLE -BEGIN - IDS_UPDATE_MEDIA_LIB_TIP - "When this option is checked, the program will automatically scan the audio files in the “Media Library Directory” at startup." - IDS_FILE_NOT_EXIST "File does not exist" - IDS_FILE_CONNOT_BE_OPEND "File cannot be opened" - IDS_ALIGN_LEFT "Left alignment" - IDS_ALIGN_RIGHT "Right alignment" - IDS_CENTER "Center" - IDS_ALL_TRACKS "All tracks" - IDS_DO_NOT_SAVE "Do not save" - IDS_AUTO_SAVE "Auto save" - IDS_INQUIRY "Inquiry" - IDS_LYRIC_FORWARD "Lyrics 0.5 Seconds in Advance" - IDS_LYRIC_DELAY "Lyrics 0.5 Seconds Delayed" - IDS_RECENT_PLAYED "Recently played" - IDS_LAST_PLAYED_TIME "Last played time" - IDS_CLEAR_RECENT_PLAYLIST_INFO - "Are you sure you want to clear the recently played tracks list?" - IDS_AB_REPEAT_A_SELECTED "AB Repeat: Point A selected (<%1%>)" -END - -STRINGTABLE -BEGIN - IDS_AB_REPEAT_ON_INFO "AB Repeat: On (<%1%>-<%2%>)" - IDS_AB_REPEAT "AB Repeat" - IDS_INNER_LYRIC "Internal lyrics" - IDS_SHOW_ONLINE_HELP_INFO - "Click here for detailed online help documentation." - IDS_PLAYLIST_FILE_FILTER - "All surpported playlist files|*.playlist;*.m3u;*.m3u8|MusicPlayer2 playlist files|*.playlist|m3u playlist files|*.m3u|m3u8 playlist files|*.m3u8|All files(*.*)|*.*||" - IDS_SAVE_PLAYLIST_FILTER - "m3u playlist files|*.m3u|m3u8 playlist files|*.m3u8|MusicPlayer2 playlist files|*.playlist|All files(*.*)|*.*||" - IDS_CREATE_MINI_MODE_SHORTCUT_INFO - "This command will create a mini mode shortcut in the program directory. The player will always be launched in mini mode by this shortcut. Do you want to create a mini mode shortcut?" - IDS_CREATE_DESKTOP_SHORTCUT_INFO - "Do you want to create a desktop shortcut?" - IDS_DELETE_SINGLE_FILE_INQUIRY - "Are you sure you want to delete the file ""<%1%>""?" - IDS_ALL "All" - IDS_LAST_WEEK "Last week" - IDS_LAST_MONTH "Last month" - IDS_LAST_HALF_YEAR "Last six months" - IDS_LAST_YEAR "Last year" - IDS_TODAY "Today" - IDS_LAST_THREE_DAYS "Last three days" -END - -STRINGTABLE -BEGIN - IDS_LICENSE_EXPLAIN "Please follow the following open source license when using the source code of this software." - IDS_LICENSE "License" - IDS_FILE_EXIST_IN_PLAYLIST_INFO "The file already exists in the playlist." - IDS_IS_RELATED "Linked" - IDS_YES "Yes" - IDS_ALBUM_COVER_INFO "Album Cover Details" - IDS_INNER_ALBUM_COVER "Internal album cover" - IDS_WIDTH "Width" - IDS_HEIGHT "Height" - IDS_BPP "Bits per pixel" - IDS_FILE_SIZE "File size" - IDS_DEFAULT_ICON "Default icon" - IDS_LIGHT_ICON "Light icon" - IDS_DARK_ICON "Dark icon" - IDS_NO "No" - IDS_CONVERT_ERROR_FILE_CONNOT_OPEN "The source file cannot be read." -END - -STRINGTABLE -BEGIN - IDS_CONVERT_ERROR_ENCODE_CHANNEL_FAILED - "Failed to create the encoding channel." - IDS_CONVERT_ERROR_ENCODE_PARA_ERROR - "Cannot find encoder or encoder parameter error." - IDS_CONVERT_ERROR_MIDI_NO_SF2 "No MIDI sound font" - IDS_CONTAIN_SUB_FOLDER "Contains subfolders" - IDS_TYPE "Type" - IDS_FILE_TYPE "File Type" - IDS_CLEAN_UP_MEDIA_WARNING "Please select a clean-up range!" - IDS_FILES_THAT_NOT_EXIST "Files not exist" - IDS_FILES_NOT_IN_MEDIA_LIB_DIR "Files not in the media library directory" - IDS_FILES_THAT_ERROR "The wrong files" - IDS_IMAGE_FILE_FILTER "Image files(*.jpg;*.jpeg;*.png;*.bmp;*.gif)|*.jpg;*.jpeg;*.png;*.bmp;*.gif|All files(*.*)|*.*||" - IDS_SEARCH_FILE_TYPE "Type here to search file type" - IDS_SEARCH_BITRATE "Type here to search bitrate" - IDS_PLAY_RANDOM "Play random" - IDS_FILE_PROPERTY "File properties" - IDS_PROPERTY_TITLE_INFO " (<%1%> Files)" -END +IDR_COMPILE_TIME TEXT "compile_time.txt" -STRINGTABLE -BEGIN - IDS_MULTI_VALUE "" - IDS_TAG_BATCH_EDIT_INFO "Saved to <%1%> file(s)." - IDS_GET_TAG_ONLINE_TITLE "Get tag information online" - IDS_GET_THIS "Get this item" - IDS_NO_LYRICS_FOUND_INFO "No lyrics found!" - IDS_CLEAR_HISTORY "Clear history..." - IDS_CLEAR_HISTORY_INFO "Are you sure you want to clear the history?" - IDS_RENAME "Rename" - IDS_RENAME_INFO "Rename <%1%> files, <%2%> succeeded, <%3%> ignored, <%4%> failed." - IDS_PLAY_TRACK "Play once" - IDS_ADVANCED_PROPERTY "Advanced tag info" - IDS_CONNOT_FIND_ARTIST_WARNING - "Could not find artist <%1%> in the media library!" - IDS_CONNOT_FIND_ALBUM_WARNING - "Could not find album <%1%> in the media library!" - IDS_SCI_NOT_LOADED_ERROR_INFO - "This dialog box cannot be opened because SciLexer.dll is not loaded correctly, please check whether SciLexer.dll is missing!" - IDS_SELECT_ARTIST "Select artist" - IDS_LOCATE_TO_CURRENT "Locate the track is playing" -END +IDR_LICENSE TEXT "..\\LICENSE" -STRINGTABLE -BEGIN - IDS_UI "UI" - IDS_RATING "Rating" - IDS_UNRATED "Unrated" - IDS_RANDOM_TRACK "Random track" - IDS_NEXT_TRACK "Next track" - IDS_MEDIA_LIB_UPDATING_INFO - "The media library is being updated, please try again later!" - IDS_MINIMIZE "Minimize" - IDS_MAXIMIZE "Maximize" - IDS_RESTORE "Restore" - IDS_SET_FILENAME_FORM "Set file name format" - IDS_SET_MULTI_OUT_ALBUM_COVER_FILE_NAME - "Set multiple external album cover file names" - IDS_DARK "Dark" - IDS_LIGHT "Light" - IDS_SHOW_HIDE_PLAYER "Show/hide player" - IDS_MUTE "Mute" - IDS_UNDEFINED "Undefined" -END +IDR_UI1 TEXT "skins\\ui1.xml" -STRINGTABLE -BEGIN - IDS_DELETE_INNER_ALBUM_COVER_INQUERY - "The current album cover is embedded in the audio file and cannot be restored after deletion. Are you sure you want to delete the embedded album cover?" - IDS_TOTAL_TRACKS "Total number of tracks" - IDS_TRACKS_PLAYED "Number of tracks played" - IDS_MEDIALIB_STATISTICS "Media library statistics" - IDS_CFG_DIR_CHANGED_INFO - "You have changed the location where the configuration and data files saved. It will take effect after restarted. You may need to transfer the configuration and data files to the new location manually." - IDS_ADD_TO_PLAYLIST "Add to playlist" - IDS_LYRICS_HIDE_BLANK_LINES_TIP - "After checking this option, when the lyrics are displayed in a single line or double line, if there is a blank line, ""Music..."" will not be displayed. Instead, the lyrics will be displayed in advance, and if ""Show lyrics karaoke style"" is also checked, blank lines longer than a certain length will be replaced with music progress symbols (♪♪♪). This option also affects the display of desktop lyrics." - IDS_BOLD "bold" - IDS_ITALIC "italic" - IDS_SDL_DEFAULT_DEVICE "SDL default audio device" - IDS_FFMPEG_CORE "Using the FFMPEG kernel will result in revertb sound effect and format conversion settings being unavailable and MIDI file will not be played. ffmpeg_core.dll is needed." - IDS_FFMPEG_INIT_FAILED "FFMPEG kernel initialization failed!" - IDS_FFMPEG_NO_THIS_FUNCTION - "This function is not currently supported in the FFMPEG kernel!" - IDS_SUPPORTTED_FORMAT_INFO - "MusicPlayer2 supports multiple playback cores, the currently used playback core is BASS audio library.\r\n More audio format support depends on the bass engine plug-in (located in the "". \\Plugins"" directory)." - IDS_SUPPORTTED_FORMAT_INFO_MCI - "MusicPlayer2 supports multiple playback cores, and the currently used playback core is MCI. Only supports mp3, wma, wav, mid format, if you need to support the playback of more audio formats, please switch to BASS or FFMPEG core." - IDS_SUPPORTTED_FORMAT_INFO_FFMPEG - "MusicPlayer2 supports multiple playback cores. The currently used playback core is FFMPEG." -END +IDR_UI2 TEXT "skins\\ui2.xml" -STRINGTABLE -BEGIN - IDS_OTHER_FORMATS "Other audio formats" - IDS_IDS_ENCODER_INIT_ERROR "Encoder initialization failed!" - IDS_SEEK_TO_LINE_TIP "Seek to current line (Ctrl+G)" - IDS_SWITCH_DISPLAY "Switch display" - IDS_FILE "File" - IDS_PLAY_CONTROL "Play Control" - IDS_LYRICS "Lyrics" - IDS_VIEW "View" - IDS_TOOLS "Tool" - IDS_DOWNLOAD_FFMPEG_CORE_INFO - "The FFMPEG core needs to be downloaded separately. After downloaded, please put all the dll files obtained by decompression into the program directory. Do you want to download FFMPEG core?" - IDS_TRAFFICMONITOR_DESCRIPTION - "TrafficMonitor: A powerful net speed monitoring software for Windows" - IDS_SIMPLENOTEPAD_DESCRIPTION - "SimpleNotePad: A simple text editor for Windows" - IDS_NO_TRACKS_TIP_INFO "There are currently no tracks playing, you can:\r\nPress <%1%> to open playlist and add songs to the playlist;\r\nClick ""Main Menu"" > ""File"" > ""Open File"" or shortcut <%2%> to open an audio file;\r\nClick ""Main Menu"" > ""File"" > ""Open Folder"" or shortcut <%3%> to open and play a folder;\r\nPress <%4%> to open the media library and find the song you want to play in the media library." - IDS_SWITHC_TO_DARK_MODE "Switch to dark mode" - IDS_SWITCH_TO_LIGHT_MODE "Switch to light mode" - IDS_SHORCUT_LEFT "Left" -END +IDR_MINI_UI0 TEXT "skins\\miniMode\\miniMode00.xml" -STRINGTABLE -BEGIN - IDS_SHOTCUT_RIGHT "Right" - IDS_SHOTCUT_UP "Up" - IDS_SHOTCUT_DOWN "Down" - IDS_SPACE "Space" - IDS_ALBUM_COVER_PATH_EDIT_TIP_INFO - "If the album cover is not found in the directory where the song is located then the cover file will be searched for in this folder." - IDS_LOGIN_REQUIRED "Login required" - IDS_LOGGED "Already logged in" - IDS_LASTFM_LOGIN "Please complete the login in the opened browser window and click OK after successful login." - IDS_LOGIN_FAILED "Login failed!" - IDS_LASTFM_CACHE_STATUS "%i scrobbles" - IDS_SHOW_HIDE_DESKTOP_LYRIC "Show/hide desktop lyric" - IDS_APP_RUNING_INFO "MusicPlayer2 is still running, please wait for the process to exit, or end the process through the task manager." - IDS_SHOW_SONG_INFO_WHEN_LYRICS_NOT_EXIST_TIP - "When this option is checked, information such as the artist, album and song title of the song will be displayed if there are no lyrics, instead of ""The current song has no lyrics.""" - IDS_EXCLUSIVE_MODE "Exclusive mode" - IDS_PLAYLIST_FIX_PATH_ERROR_INFO - "This feature will check for tracks that do not exist in the playlist and fix the incorrect path by looking for a match item in the media library. Do you want to fix the incorrect path in the playlist?" - IDS_PLAYLIST_FIX_PATH_ERROR_COMPLETE - "Finished, <%1%> incorrect path(s) have been fixed." -END +IDR_ACKNOWLEDGEMENT TEXT "res\\Acknowledgement.txt" -STRINGTABLE -BEGIN - IDS_LOCATE "Locate" - IDS_PLAYLIST_MENU "Playlist menu" - IDS_RECENT_FOLDER_OR_PLAYLIST "Recently played folder/playlist" - IDS_PLAYLIST_EMPTY_INFO "The playlist is empty." - IDS_CONTINUE_WHEN_SWITCH_PLAYLIST_TIP - "When this option is selected, if the playing track exists in the new playlist, the playing track will continue to be played after the playlist is switched." - IDS_ACKNOWLEDGEMENT "Acknowledgement" - IDS_SIMPLE_UI "Simple UI" - IDS_GROOVE_MUSIC_STYLE "Groove Style" - IDS_DEFAULT_UI "Default UI" - IDS_ALIGN_AUTO "Auto" - IDS_SET_MULTI_ARTIST_SPLIT_EXT - "Set multiple artist recognition exceptions" - IDS_ARTIST_SPLIT_EXT_TIP_INFO - "Add all artists whose names contain ""/;&&、"" as exceptions to prevent inadvertent recognition errors." - IDS_FILES_TOO_SHORT "Too short files" - IDS_FILES_NON_MAIN_IN_OSU "Non-main files in the osu! folder" - IDS_WAIT_AND_RETRY "Please wait and try again after the current operation is completed." -END +IDR_STRING_TABLE TEXT "language\\English.ini" #endif // 英语(美国) resources ///////////////////////////////////////////////////////////////////////////// @@ -7318,10 +2950,10 @@ END #define _AFX_NO_TRACKER_RESOURCES #define _AFX_NO_PROPERTY_RESOURCES -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS) -LANGUAGE 4, 2 -#include "res\MusicPlayer2.rc2" // ??? Microsoft Visual C++ ?a丯??-|i??a丯o??? -#include "l.CHS\afxres.rc" // ?a丯o?a??a丯|?t +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE 9, 1 +#include "res\MusicPlayer2.rc2" // non-Microsoft Visual C++ edited resources +#include "afxres.rc" // Standard components #endif ///////////////////////////////////////////////////////////////////////////// diff --git a/MusicPlayer2/MusicPlayer2.vcxproj b/MusicPlayer2/MusicPlayer2.vcxproj index f7cf3b232..820860056 100644 --- a/MusicPlayer2/MusicPlayer2.vcxproj +++ b/MusicPlayer2/MusicPlayer2.vcxproj @@ -97,7 +97,7 @@ WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions) true true - stdcpp20 + stdcpplatest Windows @@ -111,7 +111,7 @@ _DEBUG;%(PreprocessorDefinitions) - 0x0804 + 0x0409 _DEBUG;%(PreprocessorDefinitions) $(IntDir);%(AdditionalIncludeDirectories) @@ -127,7 +127,7 @@ _WINDOWS;_DEBUG;%(PreprocessorDefinitions) true true - stdcpp20 + stdcpplatest Windows @@ -141,7 +141,7 @@ _DEBUG;%(PreprocessorDefinitions) - 0x0804 + 0x0409 _DEBUG;%(PreprocessorDefinitions) $(IntDir);%(AdditionalIncludeDirectories) @@ -159,7 +159,7 @@ WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions) true true - stdcpp20 + stdcpplatest Windows @@ -175,7 +175,7 @@ NDEBUG;%(PreprocessorDefinitions) - 0x0804 + 0x0409 NDEBUG;%(PreprocessorDefinitions) $(IntDir);%(AdditionalIncludeDirectories) @@ -193,7 +193,7 @@ _WINDOWS;NDEBUG;%(PreprocessorDefinitions) true true - stdcpp20 + stdcpplatest Windows @@ -209,7 +209,7 @@ NDEBUG;%(PreprocessorDefinitions) - 0x0804 + 0x0409 NDEBUG;%(PreprocessorDefinitions) $(IntDir);%(AdditionalIncludeDirectories) @@ -219,17 +219,13 @@ - - - - @@ -253,6 +249,7 @@ + @@ -260,9 +257,12 @@ + + + @@ -270,13 +270,16 @@ + + + @@ -284,14 +287,15 @@ - + + + - @@ -300,7 +304,6 @@ - @@ -327,7 +330,6 @@ - @@ -386,7 +388,6 @@ - @@ -410,6 +411,7 @@ + @@ -417,30 +419,39 @@ + + + + + + + - + + + @@ -452,7 +463,6 @@ - @@ -460,7 +470,6 @@ - @@ -484,7 +493,6 @@ - @@ -545,10 +553,12 @@ + + @@ -678,6 +688,7 @@ + diff --git a/MusicPlayer2/MusicPlayer2.vcxproj.filters b/MusicPlayer2/MusicPlayer2.vcxproj.filters index af1bf0943..6e2cb8d8d 100644 --- a/MusicPlayer2/MusicPlayer2.vcxproj.filters +++ b/MusicPlayer2/MusicPlayer2.vcxproj.filters @@ -74,9 +74,6 @@ {6f54d060-c0cf-4263-b48a-d4ffdc8ab770} - - {bc15dc8a-cf52-42cb-ac8f-03c1795d5ab6} - {31a26140-6f82-4081-be3f-bd5bc3d369f6} @@ -288,9 +285,6 @@ {b109aca1-cfaf-4f5f-9612-96c66b07d09c} - - {cf55aa05-21b8-4cc2-acfd-17327505e681} - {b15ef7d8-56db-471d-9986-4ca1ba98375a} @@ -303,9 +297,6 @@ {81418427-f8ce-49dc-bcfc-5dddf81f8459} - - {92109bff-2233-4c79-afce-77656dc5e247} - {a6f42418-9eb9-473e-ac6f-ed9d60ac79c7} @@ -321,9 +312,6 @@ {82073554-8212-45d0-88a5-574a06218222} - - {05e96306-45ad-47a7-90de-b6ecbdc11cad} - {43bd891c-070b-43ea-8666-f78300c390b6} @@ -384,14 +372,35 @@ {1dbd76ed-58fd-47e0-9639-4519ba00fbd8} + + {c5c39608-c515-4919-a6ae-e23b96f114c6} + + + {182f9a41-5bb3-4552-b8d4-5d143951d54a} + + + {89cbce5a-fb9c-46f0-bedc-fe582d9c3a36} + + + {bd53f37c-760e-4eec-bf7b-755a87ca0565} + + + {1e50ecfe-c7d9-443c-96cb-cb748a7f1087} + + + {5ce11d43-a74b-4aed-8ba7-26aa37b9e090} + + + {737b0ae8-ac0c-4bf1-b335-f027bf625e43} + + + {90131507-09eb-4700-86d0-45b3402783f2} + - - - @@ -538,9 +547,6 @@ 公共的类\GaussBlur - - 对话框类\RecorderDlg - 对话框类\选项设置对话框\LyricSettingsDlg @@ -559,9 +565,6 @@ PlayerUI - - PlayerUI - 功能逻辑类\HotKeyManager @@ -727,18 +730,12 @@ 派生的控件类\SpinEdit - - 公共的类\WICFactory - 对话框类\LyricRelateDlg 对话框类\BaseDialog - - 对话框类\AlbumCoverInfoDlg - 公共的类\GdiPlusTool @@ -775,9 +772,6 @@ 对话框类\PropertyDlg\GetTagOnline - - 对话框类\PropertyDlg\TagFromFileName - 对话框类\PropertyDlg @@ -859,6 +853,36 @@ 派生的控件类\EditableListBox + + 功能逻辑类\StrTable + + + 公共的类\FilterHelper + + + 公共的类\Common + + + 功能逻辑类\CTagSelBaseDlg + + + 对话框类\RenameDlg + + + 对话框类\TagFromNameDlg + + + 对话框类\FileNameFormDlg + + + 功能逻辑类\MenuMgr + + + 公共的类\MediaTransControls + + + 功能逻辑类\IconMgr + @@ -993,9 +1017,6 @@ 公共的类\GaussBlur - - 对话框类\RecorderDlg - 对话框类\选项设置对话框\LyricSettingsDlg @@ -1011,9 +1032,6 @@ PlayerUI - - PlayerUI - 功能逻辑类\HotKeyManager @@ -1170,18 +1188,12 @@ 派生的控件类\SpinEdit - - 公共的类\WICFactory - 对话框类\LyricRelateDlg 对话框类\BaseDialog - - 对话框类\AlbumCoverInfoDlg - 公共的类\GdiPlusTool @@ -1215,9 +1227,6 @@ 对话框类\PropertyDlg\GetTagOnline - - 对话框类\PropertyDlg\TagFromFileName - 对话框类\PropertyDlg @@ -1299,6 +1308,39 @@ 派生的控件类\EditableListBox + + 功能逻辑类\StrTable + + + 公共的类\AudioCommon + + + 公共的类\FilterHelper + + + 公共的类\Common + + + 功能逻辑类\CTagSelBaseDlg + + + 对话框类\RenameDlg + + + 对话框类\TagFromNameDlg + + + 对话框类\FileNameFormDlg + + + 功能逻辑类\MenuMgr + + + 公共的类\MediaTransControls + + + 功能逻辑类\IconMgr + @@ -1319,6 +1361,12 @@ 资源文件 + + 资源文件 + + + 资源文件 + @@ -1829,7 +1877,10 @@ 资源文件\Icons - 资源文件 + 资源文件\Icons + + + 资源文件\Icons \ No newline at end of file diff --git a/MusicPlayer2/MusicPlayerCmdHelper.cpp b/MusicPlayer2/MusicPlayerCmdHelper.cpp index ed1dddde8..355bdc600 100644 --- a/MusicPlayer2/MusicPlayerCmdHelper.cpp +++ b/MusicPlayer2/MusicPlayerCmdHelper.cpp @@ -11,6 +11,7 @@ #include "COSUPlayerHelper.h" #include "SongDataManager.h" #include "SelectItemDlg.h" +#include "CommonDialogMgr.h" CMusicPlayerCmdHelper::CMusicPlayerCmdHelper(CWnd* pOwner) : m_pOwner(pOwner) @@ -24,12 +25,13 @@ CMusicPlayerCmdHelper::~CMusicPlayerCmdHelper() void CMusicPlayerCmdHelper::VeiwOnline(SongInfo& song) { //查找歌曲并获取最佳匹配项的歌曲ID + CSongDataManager::GetInstance().GetSongID(song, song.song_id); // 从媒体库读取id if (song.song_id == 0) //如果没有获取过ID,则获取一次ID { wstring song_id; song_id = CInternetCommon::SearchSongAndGetMatched(song.title, song.artist, song.album, song.GetFileName()).id; song.SetSongId(song_id); - CSongDataManager::GetInstance().SaveSongInfo(song); + CSongDataManager::GetInstance().SetSongID(song, song.song_id); // 与媒体库同步 } if (song.song_id == 0) @@ -54,10 +56,12 @@ void CMusicPlayerCmdHelper::FormatConvert(const std::vector& songs) if (CPlayer::GetInstance().IsMciCore()) { - GetOwner()->MessageBox(CCommon::LoadText(IDS_MCI_NO_THIS_FUNCTION_WARNING), NULL, MB_ICONWARNING | MB_OK); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_MCI_NO_THIS_FUNCTION_WARNING"); + GetOwner()->MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK); return; } else if (CPlayer::GetInstance().IsFfmpegCore()) { - GetOwner()->MessageBox(CCommon::LoadText(IDS_FFMPEG_NO_THIS_FUNCTION), NULL, MB_ICONWARNING | MB_OK); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_FFMPEG_NO_THIS_FUNCTION_WARNING"); + GetOwner()->MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK); return; } @@ -69,26 +73,29 @@ void CMusicPlayerCmdHelper::FormatConvert(const std::vector& songs) bool CMusicPlayerCmdHelper::OnAddToNewPlaylist(std::function&)> get_song_list, std::wstring& playlist_path, const std::wstring& default_name /*= L""*/) { CInputDlg imput_dlg(GetOwner()); - imput_dlg.SetTitle(CCommon::LoadText(IDS_NEW_PLAYLIST)); - imput_dlg.SetInfoText(CCommon::LoadText(IDS_INPUT_PLAYLIST_NAME)); + imput_dlg.SetTitle(theApp.m_str_table.LoadText(L"TITLE_NEW_PLAYLIST").c_str()); + imput_dlg.SetInfoText(theApp.m_str_table.LoadText(L"TXT_NEW_PLAYLIST_INPUT_PLAYLIST_NAME").c_str()); imput_dlg.SetEditText(default_name.c_str()); if (imput_dlg.DoModal() == IDOK) { - CString playlist_name = imput_dlg.GetEditText(); - if (playlist_name.IsEmpty()) + wstring playlist_name = imput_dlg.GetEditText().GetString(); + if (playlist_name.empty()) { - GetOwner()->MessageBox(CCommon::LoadText(IDS_PLAYLIST_NAME_EMPTY_WARNING), NULL, MB_ICONWARNING | MB_OK); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_PLAYLIST_NAME_EMPTY_WARNING"); + GetOwner()->MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK); return false; } - if (!CCommon::IsFileNameValid(wstring(playlist_name.GetString()))) + if (!CCommon::IsFileNameValid(playlist_name)) { - GetOwner()->MessageBox(CCommon::LoadText(IDS_FILE_NAME_INVALID_WARNING), NULL, MB_ICONWARNING | MB_OK); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_FILE_NAME_INVALID_WARNING"); + GetOwner()->MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK); return false; } - playlist_path = theApp.m_playlist_dir + playlist_name.GetString() + PLAYLIST_EXTENSION; + playlist_path = theApp.m_playlist_dir + playlist_name + PLAYLIST_EXTENSION; if (CCommon::FileExist(playlist_path)) { - GetOwner()->MessageBox(CCommon::LoadTextFormat(IDS_PLAYLIST_EXIST_WARNING, { playlist_name }), NULL, MB_ICONWARNING | MB_OK); + wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_PLAYLIST_EXIST_WARNING", { playlist_name }); + GetOwner()->MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK); return false; } //添加空的播放列表 @@ -104,7 +111,8 @@ bool CMusicPlayerCmdHelper::OnAddToNewPlaylist(std::functionMessageBox(CCommon::LoadText(IDS_FILE_EXIST_IN_PLAYLIST_INFO), NULL, MB_ICONINFORMATION | MB_OK); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_FILE_EXIST_IN_PLAYLIST"); + pPlayerDlg->MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); return false; } playlist.SaveToFile(playlist_path); @@ -170,19 +178,20 @@ bool CMusicPlayerCmdHelper::OnAddToPlaylistCommand(std::function= 0 && index < static_cast(recent_playlist.size())) + playlist_path = recent_playlist[index].path; + if (CCommon::FileExist(playlist_path)) { - wstring playlist_path = theApp.m_playlist_dir + menu_string.GetString() + PLAYLIST_EXTENSION; - if (CCommon::FileExist(playlist_path)) - { - AddToPlaylist(selected_item_path, playlist_path); - } - else - { - GetOwner()->MessageBox(CCommon::LoadText(IDS_ADD_TO_PLAYLIST_FAILED_WARNING), NULL, MB_ICONWARNING | MB_OK); - } + AddToPlaylist(selected_item_path, playlist_path); + } + else + { + wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_PLAYLIST_ADD_SONGS_FAILED", + { CFilePathHelper(playlist_path).GetFileNameWithoutExtension() }); + GetOwner()->MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK); } } return true; @@ -195,8 +204,8 @@ bool CMusicPlayerCmdHelper::DeleteSongsFromDisk(const std::vector& fil if (theApp.m_media_lib_setting_data.disable_delete_from_disk) return false; - CString info = CCommon::LoadTextFormat(IDS_DELETE_FILE_INQUARY, { files.size() }); - if (GetOwner()->MessageBox(info, NULL, MB_ICONWARNING | MB_OKCANCEL) != IDOK) + wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_DELETE_SEL_AUDIO_FILE_INQUARY", { files.size() }); + if (GetOwner()->MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OKCANCEL) != IDOK) return false; vector delected_files; @@ -219,7 +228,7 @@ bool CMusicPlayerCmdHelper::DeleteSongsFromDisk(const std::vector& fil CPlayer::GetInstance().GetPlayStatusMutex().unlock(); } int rtn{}; - rtn = CCommon::DeleteFiles(GetOwner()->m_hWnd, delected_files); + rtn = CommonDialogMgr::DeleteFiles(GetOwner()->m_hWnd, delected_files); if (rtn == 0) { //如果文件删除成功,则从歌曲数据中删除 @@ -233,7 +242,7 @@ bool CMusicPlayerCmdHelper::DeleteSongsFromDisk(const std::vector& fil CFilePathHelper file_path(file); file = file_path.ReplaceFileExtension(L"jpg").c_str(); } - CCommon::DeleteFiles(GetOwner()->m_hWnd, delected_files); + CommonDialogMgr::DeleteFiles(GetOwner()->m_hWnd, delected_files); for (const wstring& ext : CLyrics::m_surpported_lyric) // 删除所有后缀的歌词 { for (auto& file : delected_files) @@ -241,7 +250,7 @@ bool CMusicPlayerCmdHelper::DeleteSongsFromDisk(const std::vector& fil CFilePathHelper file_path(file); file = file_path.ReplaceFileExtension(ext.c_str()).c_str(); } - CCommon::DeleteFiles(GetOwner()->m_hWnd, delected_files); + CommonDialogMgr::DeleteFiles(GetOwner()->m_hWnd, delected_files); } } else if (rtn == 1223) //如果在弹出的对话框中点击“取消”则返回值为1223 @@ -250,7 +259,7 @@ bool CMusicPlayerCmdHelper::DeleteSongsFromDisk(const std::vector& fil } else { - GetOwner()->MessageBox(CCommon::LoadText(IDS_CONNOT_DELETE_FILE), NULL, MB_ICONWARNING); + GetOwner()->MessageBox(theApp.m_str_table.LoadText(L"MSG_DELETE_FILE_FAILED").c_str(), NULL, MB_ICONWARNING); return false; } return true; @@ -495,9 +504,11 @@ std::wstring CMusicPlayerCmdHelper::SearchAlbumCover(const SongInfo& song) bool CMusicPlayerCmdHelper::OnRating(const SongInfo& song, DWORD command) { - if (command - ID_RATING_1 <= 5) //如果命令是歌曲分级(应确保分级命令的ID是连续的) + if ((command >= ID_RATING_1 && command <= ID_RATING_5) || command == ID_RATING_NONE) //如果命令是歌曲分级(应确保分级命令的ID是连续的) { - int rating = command - ID_RATING_1 + 1; + int rating = 0; + if (command >= ID_RATING_1 && command <= ID_RATING_5) + rating = command - ID_RATING_1 + 1; SongInfo song_info{ CSongDataManager::GetInstance().GetSongInfo3(song) }; song_info.rating = static_cast(rating); bool succeed{}; @@ -517,70 +528,29 @@ bool CMusicPlayerCmdHelper::OnRating(const SongInfo& song, DWORD command) return true; } -int CMusicPlayerCmdHelper::UpdateMediaLib(bool refresh) +int CMusicPlayerCmdHelper::UpdateMediaLib() { if (CPlayer::GetInstance().IsMciCore()) return 0; - theApp.m_media_update_para.num_added = 0; vector all_media_songs; //获取所有音频文件的路径 for (const auto& item : theApp.m_media_lib_setting_data.media_folders) { // 这里还是特殊处理比较好,避免自动加入大量无关文件(比如配的视频等等) if (!COSUPlayerHelper::IsOsuFolder(item)) - CAudioCommon::GetAudioFiles(item, all_media_songs, 50000, true); + CAudioCommon::GetAudioFiles(item, all_media_songs, MAX_SONG_NUM, true); else COSUPlayerHelper::GetOSUAudioFiles(item, all_media_songs); } - int index = 0; - // 解析并移除cue文件及其关联的音频文件,并将分割后的音轨插入 - // refresh为true时会强制更新cue的时长与标签(直接更新到媒体库) - CAudioCommon::GetCueTracks(all_media_songs, CPlayer::GetInstance().GetPlayerCore(), index, refresh); - // 根据设置阻止非cue的过短文件被自动加入媒体库(这也会阻止获取时长失败的一般文件)(手动仍然可以) - bool ignore_too_short_when_update{ theApp.m_media_lib_setting_data.ignore_too_short_when_update }; - int file_too_short_ms{ theApp.m_media_lib_setting_data.file_too_short_sec * 1000 }; - theApp.m_media_update_para.total_num = all_media_songs.size(); //保存音频总数 - //std::unordered_map new_songs_map; - for (const auto& song : all_media_songs) - { - if (theApp.m_media_update_para.thread_exit) - break; - - if (song.file_path.empty()) continue; - SongInfo song_info{ CSongDataManager::GetInstance().GetSongInfo3(song) }; - // 判断是否重新获取歌曲信息 - bool get_song_info{ (song_info.modified_time == 0 || refresh) && IsSongNewer(song_info) }; // 未获取过修改时间或要求刷新时通过IsSongNewer确认并更新文件修改时间 - if (get_song_info || !song_info.info_acquired || !song_info.ChannelInfoAcquired()) // 如果判断需要获取元数据就获取尽量多的项目 - { - bool is_osu_file{ COSUPlayerHelper::IsOsuFile(song_info.file_path) }; - int flag = AF_BITRATE | AF_CHANNEL_INFO; - if (!song_info.is_cue) - flag |= AF_LENGTH; - if (!is_osu_file && !song_info.is_cue) - flag |= AF_TAG_INFO; - IPlayerCore* pPlayerCore = CPlayer::GetInstance().GetPlayerCore(); - if (pPlayerCore != nullptr) - pPlayerCore->GetAudioInfo(song_info.file_path.c_str(), song_info, flag); - if (ignore_too_short_when_update && !song_info.is_cue && song_info.length().toInt() < file_too_short_ms) - continue; - if (is_osu_file) - COSUPlayerHelper::GetOSUAudioTitleArtist(song_info); - - song_info.info_acquired = true; - song_info.SetChannelInfoAcquired(true); - - if (!song_info.is_cue && !is_osu_file) - { - // 从文件获取分级信息,仅限支持的文件 - CAudioTag audio_tag(song_info); - audio_tag.GetAudioRating(); - } - CSongDataManager::GetInstance().AddItem(song_info); - theApp.m_media_update_para.num_added++; - } - } + CAudioCommon::GetAudioInfo(all_media_songs, + theApp.m_media_update_para.num_added, + theApp.m_media_update_para.thread_exit, + theApp.m_media_update_para.process_percent, + theApp.m_media_update_para.force ? MR_FOECE_FULL : MR_FILE_MODIFICATION, + theApp.m_media_lib_setting_data.ignore_too_short_when_update + ); return theApp.m_media_update_para.num_added; } @@ -661,7 +631,7 @@ void CMusicPlayerCmdHelper::RefreshMediaTabData(eMediaLibTab tab_index) void CMusicPlayerCmdHelper::OnViewArtist(const SongInfo& song_info) { vector artist_list; - song_info.GetArtistList(artist_list, theApp.m_media_lib_setting_data.artist_split_ext); // 获取艺术家(可能有多个) + song_info.GetArtistList(artist_list); // 获取艺术家(可能有多个) wstring artist; if (artist_list.empty()) { @@ -675,8 +645,8 @@ void CMusicPlayerCmdHelper::OnViewArtist(const SongInfo& song_info) { //如果有多个艺术家,弹出“选择艺术家”对话框 CSelectItemDlg dlg(artist_list); - dlg.SetTitle(CCommon::LoadText(IDS_SELECT_ARTIST)); - dlg.SetDlgIcon(theApp.m_icon_set.artist.GetIcon()); + dlg.SetTitle(theApp.m_str_table.LoadText(L"TITLE_SELECT_ARTIST").c_str()); + dlg.SetDlgIcon(IconMgr::IconType::IT_Artist); if (dlg.DoModal() == IDOK) artist = dlg.GetSelectedItem(); else @@ -686,7 +656,8 @@ void CMusicPlayerCmdHelper::OnViewArtist(const SongInfo& song_info) CMusicPlayerDlg* pPlayerDlg = CMusicPlayerDlg::GetInstance(); if (!pPlayerDlg->m_pMediaLibDlg->NavigateToItem(artist)) { - pPlayerDlg->MessageBox(CCommon::LoadTextFormat(IDS_CONNOT_FIND_ARTIST_WARNING, { artist }), NULL, MB_OK | MB_ICONWARNING); + wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_CANNOT_FIND_ARTIST_WARNING", { artist }); + pPlayerDlg->MessageBox(info.c_str(), NULL, MB_OK | MB_ICONWARNING); } } @@ -697,15 +668,17 @@ void CMusicPlayerCmdHelper::OnViewAlbum(const SongInfo& song_info) CMusicPlayerDlg* pPlayerDlg = CMusicPlayerDlg::GetInstance(); if (!pPlayerDlg->m_pMediaLibDlg->NavigateToItem(album)) { - pPlayerDlg->MessageBox(CCommon::LoadTextFormat(IDS_CONNOT_FIND_ALBUM_WARNING, { album }), NULL, MB_OK | MB_ICONWARNING); + wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_CANNOT_FIND_ALBUM_WARNING", { album }); + pPlayerDlg->MessageBox(info.c_str(), NULL, MB_OK | MB_ICONWARNING); } } int CMusicPlayerCmdHelper::FixPlaylistPathError(const std::wstring& path) { + vector song_list; CPlaylistFile playlist_file; playlist_file.LoadFromFile(path); - vector song_list{ playlist_file.GetPlaylist() }; + playlist_file.MoveToSongList(song_list); // move后playlist_file对象不再可用 int fixed_count{}; for (auto& song : song_list) { @@ -728,13 +701,12 @@ int CMusicPlayerCmdHelper::FixPlaylistPathError(const std::wstring& path) if (fixed_count > 0) { //保存播放列表到文件 - playlist_file.FromSongList(song_list); - playlist_file.SaveToFile(path); + CPlaylistFile::SavePlaylistToFile(song_list, path); //如果处理的是正在播放的播放列表 if (CPlayer::GetInstance().IsPlaylistMode() && CPlayer::GetInstance().GetPlaylistPath() == path) { - CPlayer::GetInstance().ReloadPlaylist(false); + CPlayer::GetInstance().ReloadPlaylist(MR_MIN_REQUIRED); } } return fixed_count; @@ -747,9 +719,15 @@ void CMusicPlayerCmdHelper::AddToPlaylist(const std::vector& songs, co { int rtn = CPlayer::GetInstance().AddSongsToPlaylist(songs); if (rtn == 0) - pPlayerDlg->MessageBox(CCommon::LoadText(IDS_FILE_EXIST_IN_PLAYLIST_INFO), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_FILE_EXIST_IN_PLAYLIST"); + pPlayerDlg->MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } else if (rtn == -1) - pPlayerDlg->MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + pPlayerDlg->MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } } else { @@ -758,21 +736,13 @@ void CMusicPlayerCmdHelper::AddToPlaylist(const std::vector& songs, co if (playlist.AddSongsToPlaylist(songs, theApp.m_media_lib_setting_data.insert_begin_of_playlist)) playlist.SaveToFile(playlist_path); else - pPlayerDlg->MessageBox(CCommon::LoadText(IDS_FILE_EXIST_IN_PLAYLIST_INFO), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_FILE_EXIST_IN_PLAYLIST"); + pPlayerDlg->MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } } } -bool CMusicPlayerCmdHelper::IsSongNewer(SongInfo& song_info) -{ - if (!CCommon::FileExist(song_info.file_path)) - return false; - - unsigned __int64 last_modified = CCommon::GetFileLastModified(song_info.file_path); - bool is_newer = (last_modified > song_info.modified_time); - song_info.modified_time = last_modified; - return is_newer; -} - CWnd* CMusicPlayerCmdHelper::GetOwner() { if (m_pOwner != nullptr) diff --git a/MusicPlayer2/MusicPlayerCmdHelper.h b/MusicPlayer2/MusicPlayerCmdHelper.h index e12342e79..96cc795cb 100644 --- a/MusicPlayer2/MusicPlayerCmdHelper.h +++ b/MusicPlayer2/MusicPlayerCmdHelper.h @@ -1,7 +1,6 @@ #pragma once #include "SongInfo.h" #include "FormatConvertDlg.h" -#include class CMusicPlayerCmdHelper { public: @@ -36,8 +35,7 @@ class CMusicPlayerCmdHelper bool OnRating(const SongInfo& song, DWORD command); //更新媒体库,返回新增的歌曲数。(此函数执行时间可能会较长,应该在后台线程中执行) - //refresh: 如果为true,则会自动更新所有最近修改时间比上次获取时新的文件的信息 - static int UpdateMediaLib(bool refresh = false); + static int UpdateMediaLib(); //清理数据,函数对象fun_condition用来判断文件是否要被清理,如果是则返回true static int CleanUpSongData(std::function fun_condition = [&](const SongInfo& song) { return !CCommon::FileExist(song.file_path); }); @@ -73,9 +71,6 @@ class CMusicPlayerCmdHelper protected: void AddToPlaylist(const std::vector& songs, const std::wstring& playlist_path); - //判断一个音频文件的最后修改时间是否比上次获取到的最后修改时间新并更新修改时间 - static bool IsSongNewer(SongInfo& song_info); - private: CWnd* GetOwner(); diff --git a/MusicPlayer2/MusicPlayerDlg.cpp b/MusicPlayer2/MusicPlayerDlg.cpp index d554331d7..8e72d266e 100644 --- a/MusicPlayer2/MusicPlayerDlg.cpp +++ b/MusicPlayer2/MusicPlayerDlg.cpp @@ -5,9 +5,6 @@ #include "stdafx.h" #include "MusicPlayer2.h" #include "MusicPlayerDlg.h" -#include "afxdialogex.h" -#include "afxwin.h" -#include "afxcmn.h" #include "SupportedFormatDlg.h" #include "AboutDlg.h" #include "CTest.h" @@ -20,17 +17,18 @@ #include "COSUPlayerHelper.h" #include "MusicPlayerCmdHelper.h" #include "AddToPlaylistDlg.h" -#include "WIC.h" #include "LyricRelateDlg.h" -#include "AlbumCoverInfoDlg.h" #include "SongDataManager.h" -#include "TagFromFileNameDlg.h" +#include "RenameDlg.h" #include "PropertyDlgHelper.h" #include "TagLibHelper.h" #include "RecentFolderAndPlaylist.h" #include "UserUi.h" #include "FfmpegCore.h" #include "SongInfoHelper.h" +#include "FilterHelper.h" +#include "CommonDialogMgr.h" +#include "WinVersionHelper.h" #ifdef _DEBUG #define new DEBUG_NEW @@ -45,17 +43,13 @@ const UINT WM_TASKBARCREATED{ ::RegisterWindowMessage(_T("TaskbarCreated")) }; CMusicPlayerDlg::CMusicPlayerDlg(wstring cmdLine, CWnd* pParent /*=NULL*/) : m_cmdLine{ cmdLine }, CMainDialogBase(IDD_MUSICPLAYER2_DIALOG, pParent) { - m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); - m_path_edit.SetTooltopText(CCommon::LoadText(IDS_RECENT_FOLDER_OR_PLAYLIST)); + m_hIcon = theApp.m_icon_mgr.GetHICON(IconMgr::IconType::IT_App, IconMgr::IconStyle::IS_Color, IconMgr::IconSize::IS_ALL); + m_path_edit.SetTooltopText(theApp.m_str_table.LoadText(L"UI_TIP_BTN_RECENT_FOLDER_OR_PLAYLIST").c_str()); //初始化UI //加载内置界面 - std::shared_ptr ui1 = std::make_shared(&m_ui_static_ctrl); - std::shared_ptr ui2 = std::make_shared(&m_ui_static_ctrl); - ui1->LoadFromContents(CCommon::GetTextResourceRawData(IDR_UI1)); - ui2->LoadFromContents(CCommon::GetTextResourceRawData(IDR_UI2)); - m_ui_list.push_back(ui1); - m_ui_list.push_back(ui2); + m_ui_list.push_back(std::make_shared(&m_ui_static_ctrl, IDR_UI1)); + m_ui_list.push_back(std::make_shared(&m_ui_static_ctrl, IDR_UI2)); //加载skins目录下的用户自定义界面 std::vector> user_ui_list_with_index; //指定了序号的用户自定义界面 @@ -104,15 +98,6 @@ CMusicPlayerDlg* CMusicPlayerDlg::GetInstance() return dynamic_cast(theApp.m_pMainWnd); } -bool CMusicPlayerDlg::IsTaskbarListEnable() const -{ -#ifdef COMPILE_IN_WIN_XP - return false; -#else - return CWinVersionHelper::IsWindows7OrLater() && m_pTaskbar != nullptr; -#endif -} - void CMusicPlayerDlg::DoDataExchange(CDataExchange* pDX) { CMainDialogBase::DoDataExchange(pDX); @@ -120,9 +105,8 @@ void CMusicPlayerDlg::DoDataExchange(CDataExchange* pDX) DDX_Control(pDX, IDC_PLAYLIST_LIST, m_playlist_list); DDX_Control(pDX, IDC_PATH_STATIC, m_path_static); DDX_Control(pDX, IDC_PATH_EDIT, m_path_edit); - DDX_Control(pDX, ID_SET_PATH, m_set_path_button); + DDX_Control(pDX, ID_MEDIA_LIB, m_media_lib_button); DDX_Control(pDX, IDC_SEARCH_EDIT, m_search_edit); - //DDX_Control(pDX, IDC_CLEAR_SEARCH_BUTTON, m_clear_search_button); DDX_Control(pDX, IDC_PLAYLIST_TOOLBAR, m_playlist_toolbar); DDX_Control(pDX, IDC_UI_STATIC, m_ui_static_ctrl); DDX_Control(pDX, IDC_HSPLITER_STATIC, m_splitter_ctrl); @@ -142,7 +126,7 @@ BEGIN_MESSAGE_MAP(CMusicPlayerDlg, CMainDialogBase) ON_COMMAND(ID_NEXT, &CMusicPlayerDlg::OnNext) ON_COMMAND(ID_REW, &CMusicPlayerDlg::OnRew) ON_COMMAND(ID_FF, &CMusicPlayerDlg::OnFF) - ON_COMMAND(ID_SET_PATH, &CMusicPlayerDlg::OnSetPath) + ON_COMMAND(ID_MEDIA_LIB, &CMusicPlayerDlg::OnMediaLib) ON_COMMAND(ID_FIND, &CMusicPlayerDlg::OnFind) ON_COMMAND(ID_EXPLORE_PATH, &CMusicPlayerDlg::OnExplorePath) ON_WM_DESTROY() @@ -168,10 +152,13 @@ BEGIN_MESSAGE_MAP(CMusicPlayerDlg, CMainDialogBase) ON_WM_HOTKEY() ON_COMMAND(ID_RE_INI_BASS, &CMusicPlayerDlg::OnReIniBass) ON_COMMAND(ID_SORT_BY_FILE, &CMusicPlayerDlg::OnSortByFile) + ON_COMMAND(ID_SORT_BY_PATH, &CMusicPlayerDlg::OnSortByPath) ON_COMMAND(ID_SORT_BY_TITLE, &CMusicPlayerDlg::OnSortByTitle) ON_COMMAND(ID_SORT_BY_ARTIST, &CMusicPlayerDlg::OnSortByArtist) ON_COMMAND(ID_SORT_BY_ALBUM, &CMusicPlayerDlg::OnSortByAlbum) ON_COMMAND(ID_SORT_BY_TRACK, &CMusicPlayerDlg::OnSortByTrack) + ON_COMMAND(ID_SORT_BY_LISTEN_TIME, &CMusicPlayerDlg::OnSortByListenTime) + ON_COMMAND(ID_SORT_BY_MODIFIED_TIME, &CMusicPlayerDlg::OnSortByModifiedTime) ON_COMMAND(ID_DELETE_FROM_DISK, &CMusicPlayerDlg::OnDeleteFromDisk) ON_REGISTERED_MESSAGE(WM_TASKBARCREATED, &CMusicPlayerDlg::OnTaskbarcreated) ON_COMMAND(ID_DISP_FILE_NAME, &CMusicPlayerDlg::OnDispFileName) @@ -179,10 +166,6 @@ BEGIN_MESSAGE_MAP(CMusicPlayerDlg, CMainDialogBase) ON_COMMAND(ID_DISP_ARTIST_TITLE, &CMusicPlayerDlg::OnDispArtistTitle) ON_COMMAND(ID_DISP_TITLE_ARTIST, &CMusicPlayerDlg::OnDispTitleArtist) ON_COMMAND(ID_MINI_MODE, &CMusicPlayerDlg::OnMiniMode) - ON_BN_CLICKED(IDC_STOP, &CMusicPlayerDlg::OnBnClickedStop) - ON_BN_CLICKED(IDC_PREVIOUS, &CMusicPlayerDlg::OnBnClickedPrevious) - ON_BN_CLICKED(IDC_PLAY_PAUSE, &CMusicPlayerDlg::OnBnClickedPlayPause) - ON_BN_CLICKED(IDC_NEXT, &CMusicPlayerDlg::OnBnClickedNext) ON_COMMAND(ID_RELOAD_LYRIC, &CMusicPlayerDlg::OnReloadLyric) ON_COMMAND(ID_SONG_INFO, &CMusicPlayerDlg::OnSongInfo) ON_COMMAND(ID_COPY_CURRENT_LYRIC, &CMusicPlayerDlg::OnCopyCurrentLyric) @@ -211,7 +194,6 @@ BEGIN_MESSAGE_MAP(CMusicPlayerDlg, CMainDialogBase) // ON_MESSAGE(WM_PATH_SELECTED, &CMusicPlayerDlg::OnPathSelected) ON_MESSAGE(WM_CONNOT_PLAY_WARNING, &CMusicPlayerDlg::OnConnotPlayWarning) ON_EN_CHANGE(IDC_SEARCH_EDIT, &CMusicPlayerDlg::OnEnChangeSearchEdit) - //ON_BN_CLICKED(IDC_CLEAR_SEARCH_BUTTON, &CMusicPlayerDlg::OnBnClickedClearSearchButton) ON_COMMAND(ID_DOWNLOAD_ALBUM_COVER, &CMusicPlayerDlg::OnDownloadAlbumCover) ON_MESSAGE(WM_MUSIC_STREAM_OPENED, &CMusicPlayerDlg::OnMusicStreamOpened) ON_COMMAND(ID_CURRENT_EXPLORE_ONLINE, &CMusicPlayerDlg::OnCurrentExploreOnline) @@ -222,7 +204,6 @@ BEGIN_MESSAGE_MAP(CMusicPlayerDlg, CMainDialogBase) ON_COMMAND(ID_FORMAT_CONVERT, &CMusicPlayerDlg::OnFormatConvert) ON_COMMAND(ID_FORMAT_CONVERT1, &CMusicPlayerDlg::OnFormatConvert1) ON_MESSAGE(WM_SETTINGS_APPLIED, &CMusicPlayerDlg::OnSettingsApplied) - ON_COMMAND(ID_RECORDER, &CMusicPlayerDlg::OnRecorder) ON_MESSAGE(WM_ALBUM_COVER_DOWNLOAD_COMPLETE, &CMusicPlayerDlg::OnAlbumCoverDownloadComplete) ON_WM_DWMCOLORIZATIONCOLORCHANGED() ON_COMMAND(ID_SUPPORTED_FORMAT, &CMusicPlayerDlg::OnSupportedFormat) @@ -249,7 +230,6 @@ BEGIN_MESSAGE_MAP(CMusicPlayerDlg, CMainDialogBase) ON_COMMAND(ID_DOCKED_PLAYLIST, &CMusicPlayerDlg::OnDockedPlaylist) ON_COMMAND(ID_FLOATED_PLAYLIST, &CMusicPlayerDlg::OnFloatedPlaylist) ON_MESSAGE(WM_FLOAT_PLAYLIST_CLOSED, &CMusicPlayerDlg::OnFloatPlaylistClosed) - // ON_COMMAND(ID_FILE_OPEN_PALYLIST, &CMusicPlayerDlg::OnFileOpenPalylist) // ON_MESSAGE(WM_PLAYLIST_SELECTED, &CMusicPlayerDlg::OnPlaylistSelected) ON_COMMAND(ID_PLAYLIST_ADD_FILE, &CMusicPlayerDlg::OnPlaylistAddFile) ON_COMMAND(ID_REMOVE_FROM_PLAYLIST, &CMusicPlayerDlg::OnRemoveFromPlaylist) @@ -294,7 +274,6 @@ BEGIN_MESSAGE_MAP(CMusicPlayerDlg, CMainDialogBase) ON_COMMAND(ID_NEXT_AB_REPEAT, &CMusicPlayerDlg::OnNextAbRepeat) ON_COMMAND(ID_SAVE_CURRENT_PLAYLIST_AS, &CMusicPlayerDlg::OnSaveCurrentPlaylistAs) ON_COMMAND(ID_FILE_OPEN_PLAYLIST, &CMusicPlayerDlg::OnFileOpenPlaylist) - //ON_COMMAND(ID_EXPORT_CURRENT_PLAYLIST, &CMusicPlayerDlg::OnExportCurrentPlaylist) ON_COMMAND(ID_SAVE_AS_NEW_PLAYLIST, &CMusicPlayerDlg::OnSaveAsNewPlaylist) ON_COMMAND(ID_CREATE_DESKTOP_SHORTCUT, &CMusicPlayerDlg::OnCreateDesktopShortcut) ON_COMMAND(ID_CREATE_MINI_MODE_SHORT_CUT, &CMusicPlayerDlg::OnCreateMiniModeShortCut) @@ -308,13 +287,8 @@ BEGIN_MESSAGE_MAP(CMusicPlayerDlg, CMainDialogBase) ON_COMMAND(ID_UNLINK_LYRIC, &CMusicPlayerDlg::OnUnlinkLyric) ON_COMMAND(ID_SHOW_DESKTOP_LYRIC, &CMusicPlayerDlg::OnShowDesktopLyric) ON_MESSAGE(WM_MAIN_WINDOW_ACTIVATED, &CMusicPlayerDlg::OnMainWindowActivated) - ON_COMMAND(ID_SORT_BY_MODIFIED_TIME, &CMusicPlayerDlg::OnSortByModifiedTime) - ON_COMMAND(ID_SORT_BY_PATH, &CMusicPlayerDlg::OnSortByPath) ON_COMMAND(ID_CONTAIN_SUB_FOLDER, &CMusicPlayerDlg::OnContainSubFolder) ON_MESSAGE(WM_GET_MUSIC_CURRENT_POSITION, &CMusicPlayerDlg::OnGetMusicCurrentPosition) - ON_COMMAND(ID_ACCENDING_ORDER, &CMusicPlayerDlg::OnAccendingOrder) - ON_COMMAND(ID_DESENDING_ORDER, &CMusicPlayerDlg::OnDesendingOrder) - ON_COMMAND(ID_INVERT_PLAYLIST, &CMusicPlayerDlg::OnInvertPlaylist) ON_COMMAND(ID_PLAY_RANDOM, &CMusicPlayerDlg::OnPlayRandom) ON_MESSAGE(WM_CURRENT_FILE_ALBUM_COVER_CHANGED, &CMusicPlayerDlg::OnCurrentFileAlbumCoverChanged) ON_COMMAND(ID_RENAME, &CMusicPlayerDlg::OnRename) @@ -362,7 +336,6 @@ void CMusicPlayerDlg::SaveConfig() ini.WriteBool(L"config", L"float_playlist", theApp.m_nc_setting_data.float_playlist); ini.WriteInt(L"config", L"float_playlist_width", theApp.m_nc_setting_data.playlist_size.cx); ini.WriteInt(L"config", L"float_playlist_height", theApp.m_nc_setting_data.playlist_size.cy); - ini.WriteBool(L"config", L"playlist_btn_for_float_playlist", theApp.m_nc_setting_data.playlist_btn_for_float_playlist); ini.WriteInt(L"config", L"lyric_save_policy", static_cast(theApp.m_lyric_setting_data.lyric_save_policy)); ini.WriteBool(L"config", L"use_inner_lyric_first", theApp.m_lyric_setting_data.use_inner_lyric_first); @@ -500,7 +473,7 @@ void CMusicPlayerDlg::SaveConfig() //保存热键设置 ini.WriteBool(L"hot_key", L"hot_key_enable", theApp.m_hot_key_setting_data.hot_key_enable); - theApp.m_hot_key.SaveToTni(ini); + m_hot_key.SaveToTni(ini); //保存桌面歌词预设 m_desktop_lyric.SaveDefaultStyle(ini); @@ -520,6 +493,7 @@ void CMusicPlayerDlg::SaveConfig() ini.WriteBool(L"media_lib", L"insert_begin_of_playlist", theApp.m_media_lib_setting_data.insert_begin_of_playlist); ini.WriteBool(L"media_lib", L"show_playlist_tooltip", theApp.m_media_lib_setting_data.show_playlist_tooltip); ini.WriteBool(L"media_lib", L"float_playlist_follow_main_wnd", theApp.m_media_lib_setting_data.float_playlist_follow_main_wnd); + ini.WriteBool(L"config", L"playlist_btn_for_float_playlist", theApp.m_media_lib_setting_data.playlist_btn_for_float_playlist); ini.WriteInt(L"media_lib", L"playlist_item_height", theApp.m_media_lib_setting_data.playlist_item_height); ini.WriteInt(L"media_lib", L"recent_played_range", static_cast(theApp.m_media_lib_setting_data.recent_played_range)); ini.WriteInt(L"media_lib", L"display_item", theApp.m_media_lib_setting_data.display_item); @@ -551,7 +525,6 @@ void CMusicPlayerDlg::LoadConfig() theApp.m_nc_setting_data.float_playlist = ini.GetBool(L"config", L"float_playlist", false); theApp.m_nc_setting_data.playlist_size.cx = ini.GetInt(L"config", L"float_playlist_width", theApp.DPI(320)); theApp.m_nc_setting_data.playlist_size.cy = ini.GetInt(L"config", L"float_playlist_height", theApp.DPI(482)); - theApp.m_nc_setting_data.playlist_btn_for_float_playlist = ini.GetBool(L"config", L"playlist_btn_for_float_playlist", false); theApp.m_lyric_setting_data.lyric_save_policy = static_cast(ini.GetInt(L"config", L"lyric_save_policy", 2)); theApp.m_lyric_setting_data.use_inner_lyric_first = ini.GetBool(L"config", L"use_inner_lyric_first", true); @@ -567,7 +540,7 @@ void CMusicPlayerDlg::LoadConfig() //else theApp.m_lyric_setting_data.cortana_info_enable = ini.GetBool(L"config", L"show_lyric_in_cortana", false); // theApp.m_lyric_setting_data.save_lyric_in_offset = ini.GetBool(L"config", L"save_lyric_in_offset", false); - theApp.m_lyric_setting_data.lyric_font.name = ini.GetString(L"config", L"font", CCommon::LoadText(IDS_DEFAULT_FONT)); + theApp.m_lyric_setting_data.lyric_font.name = ini.GetString(L"config", L"font", theApp.m_str_table.GetDefaultFontName().c_str()); theApp.m_lyric_setting_data.lyric_font.size = ini.GetInt(L"config", L"font_size", 11); theApp.m_lyric_setting_data.lyric_font.style.FromInt(ini.GetInt(L"config", L"font_style", 0)); theApp.m_lyric_setting_data.lyric_line_space = ini.GetInt(L"config", L"lyric_line_space", 4); @@ -584,7 +557,7 @@ void CMusicPlayerDlg::LoadConfig() theApp.m_lyric_setting_data.cortana_show_album_cover = ini.GetBool(L"config", L"cortana_show_album_cover", 1); theApp.m_lyric_setting_data.cortana_icon_beat = ini.GetBool(L"config", L"cortana_icon_beat", 0); theApp.m_lyric_setting_data.cortana_lyric_compatible_mode = ini.GetBool(L"config", L"cortana_lyric_compatible_mode", false); - theApp.m_lyric_setting_data.cortana_font.name = ini.GetString(L"config", L"cortana_font", CCommon::LoadText(IDS_DEFAULT_FONT)); + theApp.m_lyric_setting_data.cortana_font.name = ini.GetString(L"config", L"cortana_font", theApp.m_str_table.GetDefaultFontName().c_str()); theApp.m_lyric_setting_data.cortana_font.size = ini.GetInt(L"config", L"cortana_font_size", 11); theApp.m_lyric_setting_data.cortana_font.style.FromInt(ini.GetInt(L"config", L"cortana_font_style", 0)); theApp.m_lyric_setting_data.cortana_lyric_keep_display = ini.GetBool(L"config", L"cortana_lyric_keep_display", false); @@ -593,7 +566,7 @@ void CMusicPlayerDlg::LoadConfig() theApp.m_lyric_setting_data.show_default_album_icon_in_search_box = ini.GetBool(L"config", L"show_default_album_icon_in_search_box", false); theApp.m_lyric_setting_data.show_desktop_lyric = ini.GetBool(L"desktop_lyric", L"show_desktop_lyric", false); - theApp.m_lyric_setting_data.desktop_lyric_data.lyric_font.name = ini.GetString(L"desktop_lyric", L"font_name", CCommon::LoadText(IDS_DEFAULT_FONT)); + theApp.m_lyric_setting_data.desktop_lyric_data.lyric_font.name = ini.GetString(L"desktop_lyric", L"font_name", theApp.m_str_table.GetDefaultFontName().c_str()); theApp.m_lyric_setting_data.desktop_lyric_data.lyric_font.size = ini.GetInt(L"desktop_lyric", L"font_size", 30); theApp.m_lyric_setting_data.desktop_lyric_data.lyric_font.style.FromInt(ini.GetInt(L"desktop_lyric", L"font_style", 0)); theApp.m_lyric_setting_data.desktop_lyric_data.text_color1 = ini.GetInt(L"desktop_lyric", L"text_color1", RGB(37, 152, 10)); @@ -672,12 +645,9 @@ void CMusicPlayerDlg::LoadConfig() theApp.m_general_setting_data.sf2_path = ini.GetString(L"general", L"sf2_path", L""); theApp.m_general_setting_data.midi_use_inner_lyric = ini.GetBool(L"general", L"midi_use_inner_lyric", 0); theApp.m_general_setting_data.minimize_to_notify_icon = ini.GetBool(L"general", L"minimize_to_notify_icon", false); - bool is_chinese_language{}; //当前语言是否为简体中文 - if (theApp.m_general_setting_data.language == Language::FOLLOWING_SYSTEM) - is_chinese_language = CCommon::LoadText(IDS_LANGUAGE_CODE) == _T("2"); - else - is_chinese_language = (theApp.m_general_setting_data.language == Language::SIMPLIFIED_CHINESE); - theApp.m_general_setting_data.update_source = ini.GetInt(L"general", L"update_source", is_chinese_language ? 1 : 0); //如果当前语言为简体,则默认更新源为Gitee,否则为GitHub + + bool is_zh_cn = theApp.m_str_table.IsSimplifiedChinese(); //当前语言是否为简体中文 + theApp.m_general_setting_data.update_source = ini.GetInt(L"general", L"update_source", is_zh_cn ? 1 : 0); //如果当前语言为简体,则默认更新源为Gitee,否则为GitHub theApp.m_play_setting_data.stop_when_error = ini.GetBool(L"config", L"stop_when_error", true); theApp.m_play_setting_data.auto_play_when_start = ini.GetBool(L"config", L"auto_play_when_start", false); @@ -716,7 +686,7 @@ void CMusicPlayerDlg::LoadConfig() //载入热键设置 theApp.m_hot_key_setting_data.hot_key_enable = ini.GetBool(L"hot_key", L"hot_key_enable", true); - theApp.m_hot_key.LoadFromIni(ini); + m_hot_key.LoadFromIni(ini); //载入桌面歌词预设方案 m_desktop_lyric.LoadDefaultStyle(ini); @@ -736,6 +706,7 @@ void CMusicPlayerDlg::LoadConfig() theApp.m_media_lib_setting_data.insert_begin_of_playlist = ini.GetBool(L"media_lib", L"insert_begin_of_playlist", false); theApp.m_media_lib_setting_data.show_playlist_tooltip = ini.GetBool(L"media_lib", L"show_playlist_tooltip", true); theApp.m_media_lib_setting_data.float_playlist_follow_main_wnd = ini.GetBool(L"media_lib", L"float_playlist_follow_main_wnd", true); + theApp.m_media_lib_setting_data.playlist_btn_for_float_playlist = ini.GetBool(L"config", L"playlist_btn_for_float_playlist", false); theApp.m_media_lib_setting_data.playlist_item_height = ini.GetInt(L"media_lib", L"playlist_item_height", 24); CCommon::SetNumRange(theApp.m_media_lib_setting_data.playlist_item_height, MIN_PLAYLIST_ITEM_HEIGHT, MAX_PLAYLIST_ITEM_HEIGHT); theApp.m_media_lib_setting_data.recent_played_range = static_cast(ini.GetInt(L"media_lib", L"recent_played_range", 0)); @@ -777,100 +748,51 @@ void CMusicPlayerDlg::DrawInfo(bool reset) void CMusicPlayerDlg::SetPlaylistSize(int cx, int cy, int playlist_width) { - //设置播放列表大小 - int playlist_x = cx - playlist_width; CPlayerUIBase* pUiBase = dynamic_cast(m_pUI); - if (!theApp.m_ui_data.narrow_mode) - { - m_playlist_list.MoveWindow(playlist_x + m_layout.margin, m_layout.search_edit_height + m_layout.path_edit_height + m_layout.toolbar_height + 2 * m_layout.margin, - playlist_width - 2 * m_layout.margin, cy - m_layout.search_edit_height - m_layout.path_edit_height - m_layout.toolbar_height - 3 * m_layout.margin); - } - else - { - m_playlist_list.MoveWindow(m_layout.margin, pUiBase->DrawAreaHeight() + m_layout.search_edit_height + m_layout.path_edit_height + m_layout.toolbar_height + m_layout.margin, - cx - 2 * m_layout.margin, cy - pUiBase->DrawAreaHeight() - m_layout.search_edit_height - m_layout.path_edit_height - m_layout.toolbar_height - 2 * m_layout.margin); - } - m_playlist_list.AdjustColumnWidth(); - //设置“当前路径”static控件大小 - CRect rect_static; - m_path_static.GetWindowRect(rect_static); - rect_static.bottom = rect_static.top + m_layout.path_edit_height - 2 * m_layout.margin; - //CDrawCommon draw; - //int width = theApp.DPI(70); - //if (m_pDC != nullptr) - //{ - // draw.Create(m_pDC, this); - // CString str = m_path_static.GetWindowText(); - // width = draw.GetTextExtent(str).cx + theApp.DPI(8); - //} - //rect_static.right = rect_static.left + width; + CRect rect_base; if (!theApp.m_ui_data.narrow_mode) - rect_static.MoveToXY(playlist_x + m_layout.margin, m_layout.margin); + rect_base = { CPoint(cx - playlist_width + m_layout.margin, m_layout.margin), + CSize(playlist_width - 2 * m_layout.margin, cy - 2 * m_layout.margin) }; else - rect_static.MoveToXY(m_layout.margin, pUiBase->DrawAreaHeight()); + rect_base = { CPoint(m_layout.margin, pUiBase->DrawAreaHeight()/* + m_layout.margin*/), // 不知道为什窄界面时上面不需要加边距 + CSize(cx - 2 * m_layout.margin, cy - pUiBase->DrawAreaHeight() - /*2 * */m_layout.margin) }; // 同上 + + // 设置IDC_PATH_STATIC/IDC_PATH_EDIT/ID_MEDIA_LIB的位置和大小 + int edit_height = m_layout.path_edit_height; + CRect rect_static{ rect_base.left, rect_base.top, rect_base.left + max(m_part_static_playlist_width, m_part_static_folder_width), rect_base.top + edit_height }; + CRect rect_media_lib{ rect_base.right - m_medialib_btn_width, rect_base.top - 1, rect_base.right, rect_base.top + edit_height + 1 }; + CRect rect_edit{ rect_static.right + m_layout.margin, rect_base.top, rect_media_lib.left - m_layout.margin, rect_base.top + edit_height }; m_path_static.MoveWindow(rect_static); - - //设置“当前路径”edit控件大小 - CRect rect_edit; - m_path_edit.GetWindowRect(rect_edit); - if (!theApp.m_ui_data.narrow_mode) - { - rect_edit.right = rect_edit.left + (playlist_width - 3 * m_layout.margin - rect_static.Width() - m_medialib_btn_width); - rect_edit.MoveToXY(playlist_x + m_layout.margin + rect_static.Width(), m_layout.margin); - } - else - { - rect_edit.right = rect_edit.left + (cx - 3 * m_layout.margin - rect_static.Width() - m_medialib_btn_width); - rect_edit.MoveToXY(m_layout.margin + rect_static.Width(), pUiBase->DrawAreaHeight()); - } m_path_edit.MoveWindow(rect_edit); + m_media_lib_button.MoveWindow(rect_media_lib); - //设置“选择文件夹”按钮的大小和位置 - CRect rect_select_folder{ rect_edit }; - rect_select_folder.left = rect_edit.right + m_layout.margin; - rect_select_folder.right = cx - m_layout.margin; - rect_select_folder.top--; - rect_select_folder.bottom++; - m_set_path_button.MoveWindow(rect_select_folder); - + rect_base.top += edit_height + m_layout.margin; //设置歌曲搜索框的大小和位置 CRect rect_search; m_search_edit.GetWindowRect(rect_search); - if (!theApp.m_ui_data.narrow_mode) - { - rect_search.right = rect_search.left + (playlist_width - 2 * m_layout.margin); - rect_search.MoveToXY(playlist_x + m_layout.margin, m_layout.path_edit_height + theApp.DPI(1)); - } - else - { - rect_search.right = rect_search.left + (cx - 2 * m_layout.margin); - rect_search.MoveToXY(m_layout.margin, pUiBase->DrawAreaHeight() + m_layout.path_edit_height - theApp.DPI(3)); - } + int search_height = rect_search.Height(); + rect_search = { rect_base.left, rect_base.top, rect_base.right, rect_base.top + search_height }; m_search_edit.MoveWindow(rect_search); - ////设置清除搜索按钮的大小和位置 - //CRect rect_clear{}; - //rect_clear.right = rect_clear.bottom = rect_search.Height(); - ////if (!theApp.m_ui_data.narrow_mode) - //rect_clear.MoveToXY(rect_search.right + m_layout.margin, rect_search.top); - //m_clear_search_button.MoveWindow(rect_clear); - //m_clear_search_button.Invalidate(); + + rect_base.top += search_height + m_layout.margin; //设置播放列表工具栏的大小位置 - CRect rect_toolbar{ rect_search }; - rect_toolbar.top = rect_search.bottom + m_layout.margin; - //rect_toolbar.right = rect_search.right; - rect_toolbar.bottom = rect_toolbar.top + m_layout.toolbar_height; + int toolbar_height = m_layout.toolbar_height; + CRect rect_toolbar{ rect_base.left, rect_base.top, rect_base.right, rect_base.top + toolbar_height }; m_playlist_toolbar.MoveWindow(rect_toolbar); m_playlist_toolbar.Invalidate(); + rect_base.top += toolbar_height + m_layout.margin; + // 设置播放列表控件大小和位置(即rect_base剩余空间) + m_playlist_list.MoveWindow(rect_base); + m_playlist_list.AdjustColumnWidth(); + + //设置分隔条的大小和位置 if (!theApp.m_ui_data.narrow_mode && theApp.m_ui_data.show_playlist) { m_splitter_ctrl.ShowWindow(SW_SHOW); - CRect rect_splitter; - rect_splitter.bottom = cy; - rect_splitter.left = cx - playlist_width - 1; - rect_splitter.right = cx - playlist_width + m_layout.margin - 1; + CRect rect_splitter{ cx - playlist_width - 1, 0, cx - playlist_width + m_layout.margin - 1, cy }; m_splitter_ctrl.MoveWindow(rect_splitter); } else @@ -912,9 +834,24 @@ void CMusicPlayerDlg::SetAlwaysOnTop() bool CMusicPlayerDlg::IsMainWindowPopupMenu() const { - return (m_pCurMenu == theApp.m_menu_set.m_main_popup_menu.GetSubMenu(0) - || m_pCurMenu == theApp.m_menu_set.m_main_popup_menu.GetSubMenu(0)->GetSubMenu(2) - || m_pCurMenu == theApp.m_menu_set.m_mini_mode_menu.GetSubMenu(0)); + return (m_pCurMenu == theApp.m_menu_mgr.GetMenu(MenuMgr::MainAreaMenu) + || m_pCurMenu == theApp.m_menu_mgr.GetMenu(MenuMgr::AddToPlaylistMenu) + || m_pCurMenu == theApp.m_menu_mgr.GetMenu(MenuMgr::MiniAreaMenu)); +} + +void CMusicPlayerDlg::AdjustVolume(int step) +{ + if (m_miniModeDlg.m_hWnd == NULL) + { + CPlayer::GetInstance().MusicControl(Command::VOLUME_ADJ, step); + CUserUi* cur_ui{ dynamic_cast(GetCurrentUi()) }; + if (cur_ui != nullptr) + cur_ui->VolumeAdjusted(); + } + else + { + m_miniModeDlg.SetVolume(step); + } } int CMusicPlayerDlg::CalculatePlaylistWidth(int client_width) @@ -941,13 +878,13 @@ void CMusicPlayerDlg::ShowPlayList(bool highlight_visible) { if (CPlayer::GetInstance().IsPlaylistMode()) { - pStatic->SetWindowText(CCommon::LoadText(IDS_PLAYLIST, _T(":"))); - pStatic->SetIcon(theApp.m_icon_set.show_playlist.GetIcon(true), theApp.m_icon_set.select_folder.GetSize()); + pStatic->SetWindowText(theApp.m_str_table.LoadText(L"UI_TXT_PLAYLIST").c_str()); + pStatic->SetIcon(IconMgr::IconType::IT_Playlist); } else { - pStatic->SetWindowText(CCommon::LoadText(IDS_FOLDER, _T(":"))); - pStatic->SetIcon(theApp.m_icon_set.select_folder.GetIcon(true), theApp.m_icon_set.select_folder.GetSize()); + pStatic->SetWindowText(theApp.m_str_table.LoadText(L"UI_TXT_FOLDER").c_str()); + pStatic->SetIcon(IconMgr::IconType::IT_Folder); } }; updatePathStatic(&m_path_static); @@ -957,11 +894,13 @@ void CMusicPlayerDlg::ShowPlayList(bool highlight_visible) //播放列表模式下,播放列表工具栏第一个菜单为“添加”,文件夹模式下为“文件夹” if (CPlayer::GetInstance().IsPlaylistMode()) { - m_playlist_toolbar.ModifyToolButton(0, theApp.m_icon_set.add, CCommon::LoadText(IDS_ADD), CCommon::LoadText(IDS_ADD), theApp.m_menu_set.m_playlist_toolbar_menu.GetSubMenu(0), true); + const wstring& menu_str = theApp.m_str_table.LoadText(L"UI_TXT_PLAYLIST_TOOLBAR_ADD"); + m_playlist_toolbar.ModifyToolButton(0, IconMgr::IconType::IT_Add, menu_str.c_str(), menu_str.c_str(), theApp.m_menu_mgr.GetMenu(MenuMgr::MainPlaylistAddMenu), true); } else { - m_playlist_toolbar.ModifyToolButton(0, theApp.m_icon_set.select_folder, CCommon::LoadText(IDS_FOLDER), CCommon::LoadText(IDS_FOLDER), theApp.m_menu_set.m_playlist_toolbar_menu.GetSubMenu(5), true); + const wstring& menu_str = theApp.m_str_table.LoadText(L"UI_TXT_PLAYLIST_TOOLBAR_FOLDER"); + m_playlist_toolbar.ModifyToolButton(0, IconMgr::IconType::IT_Folder, menu_str.c_str(), menu_str.c_str(), theApp.m_menu_mgr.GetMenu(MenuMgr::PlaylistToolBarFolderMenu), true); } if (m_miniModeDlg.m_hWnd != NULL) @@ -985,7 +924,7 @@ void CMusicPlayerDlg::SetPlayListColor(bool highlight_visible) m_playlist_list.EnsureVisible(CPlayer::GetInstance().GetIndex(), FALSE); CUserUi* user_ui{ dynamic_cast(GetCurrentUi()) }; if (user_ui != nullptr) - user_ui->PlaylistLocateToCurrent(); + user_ui->PlaylistLocateToIndex(CPlayer::GetInstance().GetIndex()); } if (IsFloatPlaylistExist()) @@ -1033,16 +972,19 @@ void CMusicPlayerDlg::SetPlaylistVisible() m_path_edit.ShowWindow(cmdShow); m_search_edit.ShowWindow(cmdShow); //m_clear_search_button.ShowWindow(cmdShow); - m_set_path_button.ShowWindow(cmdShow); + m_media_lib_button.ShowWindow(cmdShow); m_playlist_toolbar.ShowWindow(cmdShow); - m_splitter_ctrl.ShowWindow(cmdShow); + if (!theApp.m_ui_data.narrow_mode) + m_splitter_ctrl.ShowWindow(cmdShow); + else + m_splitter_ctrl.ShowWindow(SW_HIDE); } void CMusicPlayerDlg::SetMenubarVisible() { if (theApp.m_ui_data.ShowWindowMenuBar() && theApp.m_app_setting_data.show_window_frame && !theApp.m_ui_data.full_screen) { - SetMenu(&theApp.m_menu_set.m_main_menu); + SetMenu(theApp.m_menu_mgr.GetMenu(MenuMgr::MainMenu)); } else { @@ -1050,104 +992,104 @@ void CMusicPlayerDlg::SetMenubarVisible() } } -void CMusicPlayerDlg::UpdateTaskBarProgress() +void CMusicPlayerDlg::TaskBarInit() { -#ifndef COMPILE_IN_WIN_XP - if (IsTaskbarListEnable()) + if (theApp.IsTaskbarInteractionEnabled()) + { + // 向任务栏添加按钮,已有按钮时不能重复调用(在UpdatePlayPauseButton之前) + theApp.GetITaskbarList3()->ThumbBarAddButtons(m_hWnd, 3, m_thumbButton); // 添加任务栏缩略图窗口按钮 + CRect thumbnail_rect = m_pUI->GetThumbnailClipArea(); + if (!thumbnail_rect.IsRectEmpty()) + theApp.GetITaskbarList3()->SetThumbnailClip(m_hWnd, thumbnail_rect); // 设置任务栏缩略图的区域 + + } + UpdateTaskBarProgress(true); + UpdatePlayPauseButton(); +} + +void CMusicPlayerDlg::UpdateTaskBarProgress(bool force) const +{ + if (theApp.IsTaskbarInteractionEnabled()) { + // 降低更新频率,避免win11任务栏卡死(待测试) + const int total = 100; // 将进度分为100段,仅变化时更新 + static int last_progress{}; + static TBPFLAG last_status{ TBPF_NOPROGRESS }; + int progress{}; + TBPFLAG status{ TBPF_NOPROGRESS }; //根据播放状态设置任务栏状态和进度 if (theApp.m_play_setting_data.show_taskbar_progress) { - int position, length; - position = CPlayer::GetInstance().GetCurrentPosition(); - length = CPlayer::GetInstance().GetSongLength(); - if (position == 0) position = 1; - if (length == 0) length = 1; + int position = CPlayer::GetInstance().GetCurrentPosition(); + int length = CPlayer::GetInstance().GetSongLength(); + progress = max(position, 0) * total / max(length, 1); + if (progress > total) progress = total; + if (progress < 1) progress = 1; // 为0时显示效果为TBPF_NOPROGRESS所以直接从1开始 if (CPlayer::GetInstance().IsError()) - m_pTaskbar->SetProgressState(this->GetSafeHwnd(), TBPF_ERROR); + status = TBPF_ERROR; else if (CPlayer::GetInstance().IsPlaying()) - m_pTaskbar->SetProgressState(this->GetSafeHwnd(), TBPF_INDETERMINATE); + status = TBPF_INDETERMINATE; else - m_pTaskbar->SetProgressState(this->GetSafeHwnd(), TBPF_PAUSED); - m_pTaskbar->SetProgressValue(this->GetSafeHwnd(), position, length); + status = TBPF_PAUSED; } - else + if (last_status != status || force) + { + theApp.GetITaskbarList3()->SetProgressState(this->GetSafeHwnd(), status); + last_status = status; + } + if (last_progress != progress || force) { - m_pTaskbar->SetProgressState(this->GetSafeHwnd(), TBPF_NOPROGRESS); + theApp.GetITaskbarList3()->SetProgressValue(this->GetSafeHwnd(), progress, total); + last_progress = progress; } } -#endif } void CMusicPlayerDlg::UpdatePlayPauseButton() { - if (CPlayer::GetInstance().IsPlaying() && !CPlayer::GetInstance().IsError()) + if (theApp.IsTaskbarInteractionEnabled()) { -#ifndef COMPILE_IN_WIN_XP - if (IsTaskbarListEnable()) + HICON hIcon_play = theApp.m_icon_mgr.GetHICON(IconMgr::IconType::IT_Play, IconMgr::IconStyle::IS_Filled, IconMgr::IconSize::IS_DPI_16); + HICON hIcon_pause = theApp.m_icon_mgr.GetHICON(IconMgr::IconType::IT_Pause, IconMgr::IconStyle::IS_Filled, IconMgr::IconSize::IS_DPI_16); + if (CPlayer::GetInstance().IsPlaying() && !CPlayer::GetInstance().IsError()) { //更新任务栏缩略图上“播放/暂停”的图标 - m_thumbButton[1].hIcon = theApp.m_icon_set.pause.GetIcon(); - wcscpy_s(m_thumbButton[1].szTip, CCommon::LoadText(IDS_PAUSE)); + m_thumbButton[1].hIcon = hIcon_pause; + wcscpy_s(m_thumbButton[1].szTip, theApp.m_str_table.LoadText(L"UI_TIP_BTN_PAUSE").c_str()); //更新任务按钮上的播放状态图标 if (theApp.m_play_setting_data.show_playstate_icon) - m_pTaskbar->SetOverlayIcon(m_hWnd, theApp.m_icon_set.play.GetIcon(), L""); + theApp.GetITaskbarList3()->SetOverlayIcon(m_hWnd, hIcon_play, L""); else - m_pTaskbar->SetOverlayIcon(m_hWnd, NULL, L""); + theApp.GetITaskbarList3()->SetOverlayIcon(m_hWnd, NULL, L""); } -#endif - } - else - { -#ifndef COMPILE_IN_WIN_XP - if (IsTaskbarListEnable()) + else { //更新任务栏缩略图上“播放/暂停”的图标 - m_thumbButton[1].hIcon = theApp.m_icon_set.play.GetIcon(); - wcscpy_s(m_thumbButton[1].szTip, CCommon::LoadText(IDS_PLAY)); + m_thumbButton[1].hIcon = hIcon_play; + wcscpy_s(m_thumbButton[1].szTip, theApp.m_str_table.LoadText(L"UI_TIP_BTN_PLAY").c_str()); //更新任务按钮上的播放状态图标 if (theApp.m_play_setting_data.show_playstate_icon && CPlayer::GetInstance().GetPlayingState2() == 1) - m_pTaskbar->SetOverlayIcon(m_hWnd, theApp.m_icon_set.pause.GetIcon(), L""); + theApp.GetITaskbarList3()->SetOverlayIcon(m_hWnd, hIcon_pause, L""); else - m_pTaskbar->SetOverlayIcon(m_hWnd, NULL, L""); + theApp.GetITaskbarList3()->SetOverlayIcon(m_hWnd, NULL, L""); } -#endif + theApp.GetITaskbarList3()->ThumbBarUpdateButtons(m_hWnd, 3, m_thumbButton); } -#ifndef COMPILE_IN_WIN_XP - if (IsTaskbarListEnable()) - m_pTaskbar->ThumbBarUpdateButtons(m_hWnd, 3, m_thumbButton); -#endif if (m_miniModeDlg.m_hWnd != NULL) m_miniModeDlg.UpdatePlayPauseButton(); m_pUI->UpdatePlayPauseButtonTip(); } -void CMusicPlayerDlg::SetThumbnailClipArea() +void CMusicPlayerDlg::TaskBarSetClipArea(CRect rect) { -#ifndef COMPILE_IN_WIN_XP - if (IsTaskbarListEnable() && m_pTaskbar != nullptr) - { - CRect thumbnail_rect = m_pUI->GetThumbnailClipArea(); - if (!thumbnail_rect.IsRectEmpty()) - { - m_pTaskbar->SetThumbnailClip(m_hWnd, thumbnail_rect); - } - } -#endif -} - -void CMusicPlayerDlg::SetThumbnailClipArea(CRect rect) -{ -#ifndef COMPILE_IN_WIN_XP - if (IsTaskbarListEnable() && m_pTaskbar != nullptr) + if (theApp.IsTaskbarInteractionEnabled()) { if (!rect.IsRectEmpty()) { - m_pTaskbar->SetThumbnailClip(m_hWnd, rect); + theApp.GetITaskbarList3()->SetThumbnailClip(m_hWnd, rect); } } -#endif } void CMusicPlayerDlg::EnablePlaylist(bool enable) @@ -1155,7 +1097,7 @@ void CMusicPlayerDlg::EnablePlaylist(bool enable) m_playlist_list.EnableWindow(enable); m_search_edit.EnableWindow(enable); //m_clear_search_button.EnableWindow(enable); - m_set_path_button.EnableWindow(enable); + m_media_lib_button.EnableWindow(enable); m_playlist_toolbar.EnableWindow(enable); m_playlist_toolbar.Invalidate(); @@ -1166,24 +1108,23 @@ void CMusicPlayerDlg::EnablePlaylist(bool enable) } -void CMusicPlayerDlg::CreateDesktopShortcut() +void CMusicPlayerDlg::FirstRunCreateShortcut() { //如果目录下没有recent_path和song_data文件,就判断为是第一次运行程序,提示用户是否创建桌面快捷方式 if (!CCommon::FileExist(theApp.m_song_data_path) && !CCommon::FileExist(theApp.m_recent_path_dat_path)) { - wstring shortcut_path; - - if (MessageBox(CCommon::LoadText(IDS_CREATE_SHORTCUT_INFO), NULL, MB_ICONQUESTION | MB_YESNO) == IDYES) + const wstring& create_info = theApp.m_str_table.LoadText(L"MSG_SHORTCUT_INQUARY_FIRST"); + if (MessageBox(create_info.c_str(), NULL, MB_ICONQUESTION | MB_YESNO) == IDYES) { if (CCommon::CreateFileShortcut(theApp.m_desktop_path.c_str(), NULL, _T("MusicPlayer2.lnk"))) { - CString info; - info = CCommon::LoadTextFormat(IDS_SHORTCUT_CREATED, { theApp.m_desktop_path }); - MessageBox(info, NULL, MB_ICONINFORMATION); + wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_SHORTCUT_CREATED", { theApp.m_desktop_path }); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION); } else { - MessageBox(CCommon::LoadText(IDS_SHORTCUT_CREAT_FAILED), NULL, MB_ICONWARNING); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_SHORTCUT_FAILED"); + MessageBox(info.c_str(), NULL, MB_ICONWARNING); } } } @@ -1221,12 +1162,14 @@ void CMusicPlayerDlg::ApplySettings(const COptionsDlg& optionDlg) bool playlist_item_height_changed{ theApp.m_media_lib_setting_data.playlist_item_height != optionDlg.m_media_lib_dlg.m_data.playlist_item_height }; bool need_restart_player{ theApp.m_play_setting_data.ffmpeg_core_enable_WASAPI != optionDlg.m_tab4_dlg.m_data.ffmpeg_core_enable_WASAPI || (theApp.m_play_setting_data.ffmpeg_core_enable_WASAPI && (theApp.m_play_setting_data.ffmpeg_core_enable_WASAPI_exclusive_mode != optionDlg.m_tab4_dlg.m_data.ffmpeg_core_enable_WASAPI_exclusive_mode)) }; + bool SMTC_enable_changed{ theApp.m_play_setting_data.use_media_trans_control != optionDlg.m_tab4_dlg.m_data.use_media_trans_control }; + bool playlist_btn_changed{ theApp.m_media_lib_setting_data.playlist_btn_for_float_playlist != optionDlg.m_media_lib_dlg.m_data.playlist_btn_for_float_playlist }; theApp.m_lyric_setting_data = optionDlg.m_tab1_dlg.m_data; theApp.m_app_setting_data = optionDlg.m_tab2_dlg.m_data; theApp.m_general_setting_data = optionDlg.m_tab3_dlg.m_data; theApp.m_play_setting_data = optionDlg.m_tab4_dlg.m_data; - theApp.m_hot_key.FromHotkeyGroup(optionDlg.m_tab5_dlg.m_hotkey_group); + m_hot_key.FromHotkeyGroup(optionDlg.m_tab5_dlg.m_hotkey_group); theApp.m_hot_key_setting_data = optionDlg.m_tab5_dlg.m_data; theApp.m_media_lib_setting_data = optionDlg.m_media_lib_dlg.m_data; @@ -1293,15 +1236,25 @@ void CMusicPlayerDlg::ApplySettings(const COptionsDlg& optionDlg) OnReloadLyric(); } - //if (timer_interval_changed) - //{ - // KillTimer(TIMER_ID); - // SetTimer(TIMER_ID, theApp.m_app_setting_data.ui_refresh_interval, NULL); - // if (m_miniModeDlg.GetSafeHwnd() != NULL) - // { - // ::SendMessage(m_miniModeDlg.GetSafeHwnd(), WM_TIMER_INTERVAL_CHANGED, 0, 0); - // } - //} + if (SMTC_enable_changed) + { + CPlayer::GetInstance().m_controls.InitSMTC(theApp.m_play_setting_data.use_media_trans_control); + if (theApp.m_play_setting_data.use_media_trans_control) // 如果设置从禁用更改为启用那么更新一次状态 + { + PlaybackStatus status{}; + switch (CPlayer::GetInstance().GetPlayingState2()) + { + case 0: status = PlaybackStatus::Stopped; break; + case 1: status = PlaybackStatus::Paused; break; + case 2: status = PlaybackStatus::Playing; break; + } + CPlayer::GetInstance().m_controls.UpdateControls(status); + CPlayer::GetInstance().m_controls.UpdateControlsMetadata(CPlayer::GetInstance().GetCurrentSongInfo()); + CPlayer::GetInstance().m_controls.UpdatePosition(CPlayer::GetInstance().GetCurrentPosition(), true); + CPlayer::GetInstance().m_controls.UpdateSpeed(CPlayer::GetInstance().GetSpeed()); + CPlayer::GetInstance().MediaTransControlsLoadThumbnail(); + } + } if (notify_icon_changed) { @@ -1367,6 +1320,8 @@ void CMusicPlayerDlg::ApplySettings(const COptionsDlg& optionDlg) DrawInfo(true); if (pCurUi != nullptr) pCurUi->UpdateToolTipPositionLater(); + if (pCurUi != nullptr && playlist_btn_changed) + pCurUi->UpdatePlaylistBtnToolTip(); } void CMusicPlayerDlg::ApplyThemeColor() @@ -1399,6 +1354,8 @@ void CMusicPlayerDlg::ThemeColorChanged() void CMusicPlayerDlg::SetMenuState(CMenu* pMenu) { + bool is_main_pop = IsMainWindowPopupMenu(); // 菜单是主窗口弹出的,视为选中当前播放,否则为播放列表弹出,选中项为播放列表选中状态 + //设置循环模式菜单的单选标记 RepeatMode repeat_mode{ CPlayer::GetInstance().GetRepeatMode() }; switch (repeat_mode) @@ -1434,7 +1391,7 @@ void CMusicPlayerDlg::SetMenuState(CMenu* pMenu) //bool rating_enable = false; //分级是否可用 bool single_selected = selete_valid && m_items_selected.size() < 2; //只选中了一个 SongInfo rating_file_songinfo; - if (IsMainWindowPopupMenu()) + if (is_main_pop) { rating_file_songinfo = CPlayer::GetInstance().GetCurrentSongInfo(); } @@ -1442,7 +1399,7 @@ void CMusicPlayerDlg::SetMenuState(CMenu* pMenu) { rating_file_songinfo = CPlayer::GetInstance().GetPlayList()[m_item_selected]; } - if (IsMainWindowPopupMenu() || single_selected) + if (is_main_pop || single_selected) { SongInfo song_info{ CSongDataManager::GetInstance().GetSongInfo3(rating_file_songinfo) }; // 对非cue且支持读取分级的本地音频获取分级 @@ -1502,7 +1459,7 @@ void CMusicPlayerDlg::SetMenuState(CMenu* pMenu) pMenu->CheckMenuRadioItem(ID_RATING_1, ID_RATING_NONE, ID_RATING_NONE, MF_BYCOMMAND | MF_CHECKED); //设置分级菜单的启用/禁用状态 - bool rating_menu_emable{ IsMainWindowPopupMenu() || selete_valid }; + bool rating_menu_emable{ is_main_pop || selete_valid }; pMenu->EnableMenuItem(ID_RATING_1, MF_BYCOMMAND | (rating_menu_emable ? MF_ENABLED : MF_GRAYED)); pMenu->EnableMenuItem(ID_RATING_2, MF_BYCOMMAND | (rating_menu_emable ? MF_ENABLED : MF_GRAYED)); pMenu->EnableMenuItem(ID_RATING_3, MF_BYCOMMAND | (rating_menu_emable ? MF_ENABLED : MF_GRAYED)); @@ -1517,7 +1474,7 @@ void CMusicPlayerDlg::SetMenuState(CMenu* pMenu) pMenu->CheckMenuItem(ID_CONTAIN_SUB_FOLDER, MF_BYCOMMAND | (CPlayer::GetInstance().IsContainSubFolder() ? MF_CHECKED : MF_UNCHECKED)); //设置“添加到播放列表”子菜单项的可用状态 - bool add_to_valid{ IsMainWindowPopupMenu() ? true : selete_valid }; + bool add_to_valid{ is_main_pop ? true : selete_valid }; bool use_default_playlist{ CPlaylistMgr::Instance().m_cur_playlist_type == PT_DEFAULT }; pMenu->EnableMenuItem(ID_ADD_TO_DEFAULT_PLAYLIST, MF_BYCOMMAND | (!(playlist_mode && use_default_playlist) && add_to_valid ? MF_ENABLED : MF_GRAYED)); bool use_faourite_playlist{ CPlaylistMgr::Instance().m_cur_playlist_type == PT_FAVOURITE }; @@ -1570,51 +1527,39 @@ void CMusicPlayerDlg::SetMenuState(CMenu* pMenu) int ui_selected = GetUiSelected(); pMenu->CheckMenuRadioItem(ID_SWITCH_UI + 1, ID_SWITCH_UI + m_ui_list.size(), ID_SWITCH_UI + 1 + ui_selected, MF_BYCOMMAND | MF_CHECKED); - //设置播放列表菜单中排序方式的单选标记 - if (!CPlayer::GetInstance().IsPlaylistMode()) - { - switch (CPlayer::GetInstance().m_sort_mode) - { - case SM_FILE: - pMenu->CheckMenuRadioItem(ID_SORT_BY_FILE, ID_SORT_BY_MODIFIED_TIME, ID_SORT_BY_FILE, MF_BYCOMMAND | MF_CHECKED); - break; - case SM_PATH: - pMenu->CheckMenuRadioItem(ID_SORT_BY_FILE, ID_SORT_BY_MODIFIED_TIME, ID_SORT_BY_PATH, MF_BYCOMMAND | MF_CHECKED); - break; - case SM_TITLE: - pMenu->CheckMenuRadioItem(ID_SORT_BY_FILE, ID_SORT_BY_MODIFIED_TIME, ID_SORT_BY_TITLE, MF_BYCOMMAND | MF_CHECKED); - break; - case SM_ARTIST: - pMenu->CheckMenuRadioItem(ID_SORT_BY_FILE, ID_SORT_BY_MODIFIED_TIME, ID_SORT_BY_ARTIST, MF_BYCOMMAND | MF_CHECKED); - break; - case SM_ALBUM: - pMenu->CheckMenuRadioItem(ID_SORT_BY_FILE, ID_SORT_BY_MODIFIED_TIME, ID_SORT_BY_ALBUM, MF_BYCOMMAND | MF_CHECKED); - break; - case SM_TRACK: - pMenu->CheckMenuRadioItem(ID_SORT_BY_FILE, ID_SORT_BY_MODIFIED_TIME, ID_SORT_BY_TRACK, MF_BYCOMMAND | MF_CHECKED); - break; - case SM_TIME: - pMenu->CheckMenuRadioItem(ID_SORT_BY_FILE, ID_SORT_BY_MODIFIED_TIME, ID_SORT_BY_MODIFIED_TIME, MF_BYCOMMAND | MF_CHECKED); - break; - } - if (CPlayer::GetInstance().m_descending) - pMenu->CheckMenuRadioItem(ID_ACCENDING_ORDER, ID_DESENDING_ORDER, ID_DESENDING_ORDER, MF_BYCOMMAND | MF_CHECKED); - else - pMenu->CheckMenuRadioItem(ID_ACCENDING_ORDER, ID_DESENDING_ORDER, ID_ACCENDING_ORDER, MF_BYCOMMAND | MF_CHECKED); - } - else - { - pMenu->CheckMenuItem(ID_SORT_BY_FILE, MF_UNCHECKED); - pMenu->CheckMenuItem(ID_SORT_BY_TITLE, MF_UNCHECKED); - pMenu->CheckMenuItem(ID_SORT_BY_ARTIST, MF_UNCHECKED); - pMenu->CheckMenuItem(ID_SORT_BY_ALBUM, MF_UNCHECKED); - pMenu->CheckMenuItem(ID_SORT_BY_TRACK, MF_UNCHECKED); - pMenu->CheckMenuItem(ID_ACCENDING_ORDER, MF_UNCHECKED); - pMenu->CheckMenuItem(ID_DESENDING_ORDER, MF_UNCHECKED); - } - pMenu->EnableMenuItem(ID_ACCENDING_ORDER, MF_BYCOMMAND | (!CPlayer::GetInstance().IsPlaylistMode() ? MF_ENABLED : MF_GRAYED)); - pMenu->EnableMenuItem(ID_DESENDING_ORDER, MF_BYCOMMAND | (!CPlayer::GetInstance().IsPlaylistMode() ? MF_ENABLED : MF_GRAYED)); - pMenu->EnableMenuItem(ID_INVERT_PLAYLIST, MF_BYCOMMAND | (CPlayer::GetInstance().IsPlaylistMode() ? MF_ENABLED : MF_GRAYED)); + // 设置播放列表菜单中排序方式的图标 + const CBitmap* bitmap_sort_up = theApp.m_menu_mgr.GetMenuBitmap(IconMgr::IconType::IT_Triangle_Up); + const CBitmap* bitmap_sort_down = theApp.m_menu_mgr.GetMenuBitmap(IconMgr::IconType::IT_Triangle_Down); + std::array pSortBitmap{}; + switch (CPlayer::GetInstance().m_sort_mode) + { + case SM_U_FILE: pSortBitmap[0] = bitmap_sort_up; break; + case SM_D_FILE: pSortBitmap[0] = bitmap_sort_down; break; + case SM_U_PATH: pSortBitmap[1] = bitmap_sort_up; break; + case SM_D_PATH: pSortBitmap[1] = bitmap_sort_down; break; + case SM_U_TITLE: pSortBitmap[2] = bitmap_sort_up; break; + case SM_D_TITLE: pSortBitmap[2] = bitmap_sort_down; break; + case SM_U_ARTIST: pSortBitmap[3] = bitmap_sort_up; break; + case SM_D_ARTIST: pSortBitmap[3] = bitmap_sort_down; break; + case SM_U_ALBUM: pSortBitmap[4] = bitmap_sort_up; break; + case SM_D_ALBUM: pSortBitmap[4] = bitmap_sort_down; break; + case SM_U_TRACK: pSortBitmap[5] = bitmap_sort_up; break; + case SM_D_TRACK: pSortBitmap[5] = bitmap_sort_down; break; + case SM_U_LISTEN: pSortBitmap[6] = bitmap_sort_up; break; + case SM_D_LISTEN: pSortBitmap[6] = bitmap_sort_down; break; + case SM_U_TIME: pSortBitmap[7] = bitmap_sort_up; break; + case SM_D_TIME: pSortBitmap[7] = bitmap_sort_down; break; + default: break; + } + pMenu->SetMenuItemBitmaps(ID_SORT_BY_FILE, MF_BYCOMMAND, pSortBitmap[0], NULL); + pMenu->SetMenuItemBitmaps(ID_SORT_BY_PATH, MF_BYCOMMAND, pSortBitmap[1], NULL); + pMenu->SetMenuItemBitmaps(ID_SORT_BY_TITLE, MF_BYCOMMAND, pSortBitmap[2], NULL); + pMenu->SetMenuItemBitmaps(ID_SORT_BY_ARTIST, MF_BYCOMMAND, pSortBitmap[3], NULL); + pMenu->SetMenuItemBitmaps(ID_SORT_BY_ALBUM, MF_BYCOMMAND, pSortBitmap[4], NULL); + pMenu->SetMenuItemBitmaps(ID_SORT_BY_TRACK, MF_BYCOMMAND, pSortBitmap[5], NULL); + pMenu->SetMenuItemBitmaps(ID_SORT_BY_LISTEN_TIME, MF_BYCOMMAND, pSortBitmap[6], NULL); + pMenu->SetMenuItemBitmaps(ID_SORT_BY_MODIFIED_TIME, MF_BYCOMMAND, pSortBitmap[7], NULL); + //设置播放列表菜单中“播放列表显示样式”的单选标记 switch (theApp.m_media_lib_setting_data.display_format) @@ -1633,14 +1578,11 @@ void CMusicPlayerDlg::SetMenuState(CMenu* pMenu) break; } - if (theApp.m_nc_setting_data.playlist_btn_for_float_playlist) + if (theApp.m_media_lib_setting_data.playlist_btn_for_float_playlist) pMenu->CheckMenuRadioItem(ID_DOCKED_PLAYLIST, ID_FLOATED_PLAYLIST, ID_FLOATED_PLAYLIST, MF_BYCOMMAND | MF_CHECKED); else pMenu->CheckMenuRadioItem(ID_DOCKED_PLAYLIST, ID_FLOATED_PLAYLIST, ID_DOCKED_PLAYLIST, MF_BYCOMMAND | MF_CHECKED); - //设置播放列表右键菜单的默认菜单项 - pMenu->SetDefaultItem(ID_PLAY_ITEM); - //根据歌词是否存在设置启用或禁用菜单项 bool midi_lyric{ CPlayer::GetInstance().IsMidi() && theApp.m_general_setting_data.midi_use_inner_lyric && !CPlayer::GetInstance().MidiNoLyric() }; bool lyric_disable{ midi_lyric || CPlayer::GetInstance().m_Lyrics.IsEmpty() }; @@ -1831,86 +1773,39 @@ void CMusicPlayerDlg::GetPlaylistItemSelected() void CMusicPlayerDlg::IniPlaylistPopupMenu() { - //向“添加到播放列表”菜单追加播放列表 - auto initAddToMenu = [](CMenu* pMenu) + //向“添加到播放列表”菜单更新播放列表 + vector menu_list; + const auto& recent_playlist = CPlaylistMgr::Instance().m_recent_playlists; + for (const auto& item : recent_playlist) { - ASSERT(pMenu != nullptr); - if (pMenu != nullptr) - { - //将ID_ADD_TO_MY_FAVOURITE后面的所有菜单项删除 - int start_pos = CCommon::GetMenuItemPosition(pMenu, ID_ADD_TO_MY_FAVOURITE) + 1; - while (pMenu->GetMenuItemCount() > start_pos) - { - pMenu->DeleteMenu(start_pos, MF_BYPOSITION); - } - - auto& recent_playlist{ CPlaylistMgr::Instance().m_recent_playlists }; - for (size_t i{}; i < recent_playlist.size() && i < ADD_TO_PLAYLIST_MAX_SIZE; i++) - { - CFilePathHelper playlist_path{ recent_playlist[i].path }; - pMenu->AppendMenu(MF_STRING | MF_ENABLED, ID_ADD_TO_MY_FAVOURITE + i + 1, playlist_path.GetFileNameWithoutExtension().c_str()); - } - //if (recent_playlist.size() > ADD_TO_PLAYLIST_MAX_SIZE) - //{ - pMenu->AppendMenu(MF_SEPARATOR); - pMenu->AppendMenu(MF_STRING | MF_ENABLED, ID_ADD_TO_OTHER_PLAYLIST, CCommon::LoadText(IDS_MORE_PLAYLIST, _T("..."))); - CMenuIcon::AddIconToMenuItem(pMenu->GetSafeHmenu(), ID_ADD_TO_OTHER_PLAYLIST, FALSE, theApp.m_icon_set.show_playlist.GetIcon(true)); - //} - } - }; - - initAddToMenu(theApp.m_menu_set.m_list_popup_menu.GetSubMenu(0)->GetSubMenu(12)); - initAddToMenu(theApp.m_menu_set.m_playlist_toolbar_menu.GetSubMenu(4)->GetSubMenu(0)); - initAddToMenu(theApp.m_menu_set.m_playlist_toolbar_popup_menu.GetSubMenu(4)->GetSubMenu(0)); - initAddToMenu(theApp.m_menu_set.m_media_lib_popup_menu.GetSubMenu(0)->GetSubMenu(1)); - initAddToMenu(theApp.m_menu_set.m_media_lib_popup_menu.GetSubMenu(1)->GetSubMenu(4)); - initAddToMenu(theApp.m_menu_set.m_main_popup_menu.GetSubMenu(0)->GetSubMenu(2)); - initAddToMenu(theApp.m_menu_set.m_mini_mode_menu.GetSubMenu(0)->GetSubMenu(2)); + if (menu_list.size() >= ADD_TO_PLAYLIST_MAX_SIZE) + break; + UINT id = ID_ADD_TO_MY_FAVOURITE + 1 + menu_list.size(); + menu_list.emplace_back(MenuMgr::MenuItem{ id, IconMgr::IconType::IT_NO_ICON, CFilePathHelper(item.path).GetFileNameWithoutExtension() }); + } + theApp.m_menu_mgr.UpdateMenu(MenuMgr::AddToPlaylistMenu, menu_list); } void CMusicPlayerDlg::InitUiMenu() { - auto initUiMenu = [this](CMenu* pMenu) + vector menu_list; + for (size_t i{}; i < m_ui_list.size(); ++i) { - ASSERT(pMenu != nullptr); - if (pMenu != nullptr) - { - //将ID_SWITCH_UI后面的所有菜单项删除 - int start_pos = CCommon::GetMenuItemPosition(pMenu, ID_SWITCH_UI) + 1; - while (pMenu->GetMenuItemCount() > start_pos) - { - pMenu->DeleteMenu(start_pos, MF_BYPOSITION); - } - - pMenu->AppendMenu(MF_SEPARATOR); - - for (size_t i{}; i < m_ui_list.size() && i < SELECT_UI_MAX_SIZE; i++) - { - CString str_name = m_ui_list[i]->GetUIName(); //获取界面的名称 - if (str_name.IsEmpty()) - str_name.Format(_T("%s %d"), CCommon::LoadText(IDS_UI).GetString(), m_ui_list[i]->GetUiIndex()); //如果名称为空(没有指定名称),则使用“界面 +数字”的默认名称 - - if (i + 1 <= 9) //如果界面的序号在9以内,为其分配Ctrl+数字的快捷键 - { - CString str_short_key; - str_short_key.Format(_T("\tCtrl+%d"), i + 1); - str_name += str_short_key; - } - else if (i == 9) //第10个界面分配快捷键C+0 - { - str_name += _T("\tCtrl+0"); - } - if (i == 2) - pMenu->AppendMenu(MF_SEPARATOR); - pMenu->AppendMenu(MF_STRING | MF_ENABLED, ID_SWITCH_UI + i + 1, str_name); - } - } - }; - - initUiMenu(theApp.m_menu_set.m_main_menu.GetSubMenu(4)->GetSubMenu(11)); - initUiMenu(theApp.m_menu_set.m_main_popup_menu.GetSubMenu(0)->GetSubMenu(20)); - initUiMenu(theApp.m_menu_set.m_popup_menu.GetSubMenu(0)->GetSubMenu(22)); - initUiMenu(theApp.m_menu_set.m_main_menu_popup.GetSubMenu(4)->GetSubMenu(11)); + if (menu_list.size() >= SELECT_UI_MAX_SIZE + 1) + break; + wstring str_name = m_ui_list[i]->GetUIName(); // 获取界面的名称 + if (str_name.empty()) // 如果名称为空(没有指定名称),则使用“界面 +数字”的默认名称 + str_name = theApp.m_str_table.LoadTextFormat(L"TXT_UI_NAME_DEFAULT", { m_ui_list[i]->GetUiIndex() }); + if (i < 9) // 如果界面的序号在9以内,为其分配Ctrl+数字的快捷键 + str_name += L"\tCtrl+" + std::to_wstring(i + 1); + if (i == 9) // 第10个界面分配快捷键C+0 + str_name += L"\tCtrl+0"; + if (i == 2) + menu_list.emplace_back(MenuMgr::MenuItem{}); // 在外部UI前插入一个分割条 + UINT id = ID_SWITCH_UI + i + 1; + menu_list.emplace_back(MenuMgr::MenuItem{ id, IconMgr::IconType::IT_NO_ICON, str_name }); + } + theApp.m_menu_mgr.UpdateMenu(MenuMgr::MainViewSwitchUiMenu, menu_list); } void CMusicPlayerDlg::SetPlaylistDragEnable() @@ -1926,7 +1821,7 @@ void CMusicPlayerDlg::SetPlaylistDragEnable() void CMusicPlayerDlg::_OnOptionSettings(CWnd* pParent) { - theApp.m_hot_key.UnRegisterAllHotKey(); + m_hot_key.UnRegisterAllHotKey(); try { // 设置窗口类的内存申请从栈移动到堆以修正警告 @@ -1942,7 +1837,7 @@ void CMusicPlayerDlg::_OnOptionSettings(CWnd* pParent) pOptionDlg->m_tab2_dlg.m_data = theApp.m_app_setting_data; pOptionDlg->m_tab3_dlg.m_data = theApp.m_general_setting_data; pOptionDlg->m_tab4_dlg.m_data = theApp.m_play_setting_data; - pOptionDlg->m_tab5_dlg.m_hotkey_group = theApp.m_hot_key.GetHotKeyGroup(); + pOptionDlg->m_tab5_dlg.m_hotkey_group = m_hot_key.GetHotKeyGroup(); pOptionDlg->m_tab5_dlg.m_data = theApp.m_hot_key_setting_data; pOptionDlg->m_media_lib_dlg.m_data = theApp.m_media_lib_setting_data; @@ -1974,7 +1869,7 @@ void CMusicPlayerDlg::_OnOptionSettings(CWnd* pParent) // 这里暂时不处理了,只是保险起见 } if (theApp.m_hot_key_setting_data.hot_key_enable) - theApp.m_hot_key.RegisterAllHotKey(); + m_hot_key.RegisterAllHotKey(); } void CMusicPlayerDlg::DoLyricsAutoSave(bool no_inquiry) @@ -1991,11 +1886,14 @@ void CMusicPlayerDlg::DoLyricsAutoSave(bool no_inquiry) OnSaveModifiedLyric(); break; case LyricSettingData::LS_INQUIRY: - if (no_inquiry || MessageBoxW(CCommon::LoadText(IDS_LYRIC_SAVE_INRUARY), NULL, MB_YESNO | MB_ICONQUESTION) == IDYES) // 仅当MessageBox按下是时保存 + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_LYRIC_SAVE_INRUARY"); + if (no_inquiry || MessageBoxW(info.c_str(), NULL, MB_YESNO | MB_ICONQUESTION) == IDYES) // 仅当MessageBox按下是时保存 { OnSaveModifiedLyric(); } break; + } default: break; } @@ -2004,14 +1902,14 @@ void CMusicPlayerDlg::DoLyricsAutoSave(bool no_inquiry) void CMusicPlayerDlg::UpdateABRepeatToolTip() { - CString tooltip_info; + wstring tip_str; if (CPlayer::GetInstance().GetABRepeatMode() == CPlayer::AM_A_SELECTED) - tooltip_info = CCommon::LoadTextFormat(IDS_AB_REPEAT_A_SELECTED, { CPlayer::GetInstance().GetARepeatPosition().toString(false) }); + tip_str = theApp.m_str_table.LoadTextFormat(L"UI_TXT_AB_REPEAT_A_SELECTED", { CPlayer::GetInstance().GetARepeatPosition().toString(false) }); else if (CPlayer::GetInstance().GetABRepeatMode() == CPlayer::AM_AB_REPEAT) - tooltip_info = CCommon::LoadTextFormat(IDS_AB_REPEAT_ON_INFO, { CPlayer::GetInstance().GetARepeatPosition().toString(false), CPlayer::GetInstance().GetBRepeatPosition().toString(false) }); + tip_str = theApp.m_str_table.LoadTextFormat(L"UI_TXT_AB_REPEAT_ON", { CPlayer::GetInstance().GetARepeatPosition().toString(false), CPlayer::GetInstance().GetBRepeatPosition().toString(false) }); else - tooltip_info = CCommon::LoadText(IDS_AB_REPEAT); - m_pUI->UpdateMouseToolTip(CPlayerUIBase::BTN_AB_REPEAT, tooltip_info); + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_AB_REPEAT"); + m_pUI->UpdateMouseToolTip(CPlayerUIBase::BTN_AB_REPEAT, tip_str.c_str()); } void CMusicPlayerDlg::LoadDefaultBackground() @@ -2038,7 +1936,7 @@ void CMusicPlayerDlg::SelectUi(int ui_selected) CUserUi* user_ui{ dynamic_cast(m_pUI) }; if (user_ui != nullptr) - user_ui->PlaylistLocateToCurrent(); + user_ui->PlaylistLocateToIndex(CPlayer::GetInstance().GetIndex()); } int CMusicPlayerDlg::GetUiSelected() const @@ -2090,18 +1988,20 @@ BOOL CMusicPlayerDlg::OnInitDialog() CMainDialogBase::OnInitDialog(); - // 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动 - // 执行此操作 + // 载入图标资源 + theApp.LoadImgResource(); + // 载入字体资源 + theApp.m_font_set.Init(theApp.m_str_table.GetDefaultFontName().c_str()); - //载入图标资源 - theApp.LoadIconResource(); + // 多语言主窗口资源移除后各窗口对象的->GetFont()不再自动跟随语言设置 + // 我没有找到能够修改其返回值的方法,暂时改为使用m_font_set中的字体 + // 设置窗口字体 + CCommon::SetDialogFont(this, &theApp.m_font_set.dlg.GetFont()); + + // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动执行此操作 -#ifdef _DEBUG - SetIcon(theApp.m_icon_set.app.GetIcon(false, true), TRUE); // 设置大图标 -#else SetIcon(m_hIcon, TRUE); // 设置大图标 -#endif - SetIcon(theApp.m_icon_set.app.GetIcon(), FALSE); // 设置小图标 + SetIcon(m_hIcon, FALSE); // 设置小图标 // TODO: 在此添加额外的初始化代码 @@ -2116,10 +2016,6 @@ BOOL CMusicPlayerDlg::OnInitDialog() m_hAccel = LoadAccelerators(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_ACCELERATOR1)); - //初始化字体 - theApp.m_font_set.Init(); - - theApp.InitMenuResourse(); m_miniModeDlg.Init(); @@ -2150,27 +2046,42 @@ BOOL CMusicPlayerDlg::OnInitDialog() ShowTitlebar(theApp.m_app_setting_data.show_window_frame); - //计算“媒体库”按钮的大小 - CDrawCommon draw; + // 测量主窗口受翻译字符串影响的控件所需宽度,并应用翻译字符串到控件 + CString text; + CRect text_size; CDC* pDC = GetDC(); - draw.Create(pDC, this); - CString media_lib_btn_str; - m_set_path_button.GetWindowText(media_lib_btn_str); - m_medialib_btn_width = draw.GetTextExtent(media_lib_btn_str).cx; - if (m_medialib_btn_width < theApp.DPI(66)) - m_medialib_btn_width = theApp.DPI(66); - m_medialib_btn_width += theApp.DPI(20); + pDC->SelectObject(&theApp.m_font_set.dlg.GetFont()); + // "播放列表:"宽度(含图标) + text = theApp.m_str_table.LoadText(L"UI_TXT_PLAYLIST").c_str(); + pDC->DrawTextW(text, &text_size, DT_CALCRECT); + if (m_part_static_playlist_width < text_size.Width() + theApp.DPI(20)) + m_part_static_playlist_width = min(text_size.Width() + theApp.DPI(20), theApp.DPI(150)); + // "文件夹:"宽度(含图标) + text = theApp.m_str_table.LoadText(L"UI_TXT_FOLDER").c_str(); + m_path_static.SetWindowTextW(text); + pDC->DrawTextW(text, &text_size, DT_CALCRECT); + if (m_part_static_folder_width < text_size.Width() + theApp.DPI(20)) + m_part_static_folder_width = min(text_size.Width() + theApp.DPI(20), theApp.DPI(150)); + // 媒体库按钮宽度 + text = theApp.m_str_table.LoadText(L"UI_TXT_BTN_MEDIA_LIB").c_str(); + m_media_lib_button.SetWindowTextW(text); + pDC->DrawTextW(text, &text_size, DT_CALCRECT); + if (m_medialib_btn_width < text_size.Width() + theApp.DPI(40)) + m_medialib_btn_width = min(text_size.Width() + theApp.DPI(40), theApp.DPI(150)); ReleaseDC(pDC); //初始化提示信息 m_tool_tip.Create(this, TTS_ALWAYSTIP); m_tool_tip.SetMaxTipWidth(theApp.DPI(400)); - m_tool_tip.AddTool(GetDlgItem(ID_SET_PATH), CCommon::LoadText(IDS_OPEN_MEDIA_LIB, CPlayerUIBase::GetCmdShortcutKeyForTooltips(ID_SET_PATH))); + wstring tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_MEDIA_LIB") + CPlayerUIBase::GetCmdShortcutKeyForTooltips(ID_MEDIA_LIB).GetString(); + m_tool_tip.AddTool(GetDlgItem(ID_MEDIA_LIB), tip_str.c_str()); SetMenubarVisible(); - m_set_path_button.SetIcon(theApp.m_icon_set.media_lib.GetIcon(true)); - m_search_edit.SetCueBanner(CCommon::LoadText(IDS_SEARCH_HERE), TRUE); + m_media_lib_button.SetIcon(theApp.m_icon_mgr.GetHICON(IconMgr::IconType::IT_Media_Lib, IconMgr::IconStyle::IS_OutlinedDark, IconMgr::IconSize::IS_DPI_16)); + + wstring prompt_str = theApp.m_str_table.LoadText(L"TXT_SEARCH_PROMPT") + L"(F)"; + m_search_edit.SetCueBanner(prompt_str.c_str(), TRUE); //CoInitialize(0); //初始化COM组件,用于支持任务栏显示进度和缩略图按钮 #ifndef COMPILE_IN_WIN_XP @@ -2182,20 +2093,20 @@ BOOL CMusicPlayerDlg::OnInitDialog() //上一曲按钮 m_thumbButton[0].dwMask = dwMask; m_thumbButton[0].iId = IDT_PREVIOUS; - m_thumbButton[0].hIcon = theApp.m_icon_set.previous.GetIcon(); - wcscpy_s(m_thumbButton[0].szTip, CCommon::LoadText(IDS_PREVIOUS)); + m_thumbButton[0].hIcon = theApp.m_icon_mgr.GetHICON(IconMgr::IconType::IT_Previous, IconMgr::IconStyle::IS_Filled, IconMgr::IconSize::IS_DPI_16); + wcscpy_s(m_thumbButton[0].szTip, theApp.m_str_table.LoadText(L"UI_TIP_BTN_PREVIOUS").c_str()); m_thumbButton[0].dwFlags = THBF_ENABLED; //播放/暂停按钮 m_thumbButton[1].dwMask = dwMask; m_thumbButton[1].iId = IDT_PLAY_PAUSE; - m_thumbButton[1].hIcon = theApp.m_icon_set.play.GetIcon(); - wcscpy_s(m_thumbButton[1].szTip, CCommon::LoadText(IDS_PLAY)); + m_thumbButton[1].hIcon = theApp.m_icon_mgr.GetHICON(IconMgr::IconType::IT_Play, IconMgr::IconStyle::IS_Filled, IconMgr::IconSize::IS_DPI_16); + wcscpy_s(m_thumbButton[1].szTip, theApp.m_str_table.LoadText(L"UI_TIP_BTN_PLAY").c_str()); m_thumbButton[1].dwFlags = THBF_ENABLED; //下一曲按钮 m_thumbButton[2].dwMask = dwMask; m_thumbButton[2].iId = IDT_NEXT; - m_thumbButton[2].hIcon = theApp.m_icon_set.next.GetIcon(); - wcscpy_s(m_thumbButton[2].szTip, CCommon::LoadText(IDS_NEXT)); + m_thumbButton[2].hIcon = theApp.m_icon_mgr.GetHICON(IconMgr::IconType::IT_Next, IconMgr::IconStyle::IS_Filled, IconMgr::IconSize::IS_DPI_16); + wcscpy_s(m_thumbButton[2].szTip, theApp.m_str_table.LoadText(L"UI_TIP_BTN_NEXT").c_str()); m_thumbButton[2].dwFlags = THBF_ENABLED; #endif @@ -2213,7 +2124,7 @@ BOOL CMusicPlayerDlg::OnInitDialog() //注册全局热键 if (theApp.m_hot_key_setting_data.hot_key_enable) - theApp.m_hot_key.RegisterAllHotKey(); + m_hot_key.RegisterAllHotKey(); //设置界面的颜色 CColorConvert::ConvertColor(theApp.m_app_setting_data.theme_color); @@ -2262,13 +2173,20 @@ BOOL CMusicPlayerDlg::OnInitDialog() m_notify_icon.AddNotifyIcon(); //初始化播放列表工具栏 + wstring menu_str; m_playlist_toolbar.SetIconSize(theApp.DPI(20)); - m_playlist_toolbar.AddToolButton(theApp.m_icon_set.add, CCommon::LoadText(IDS_ADD), CCommon::LoadText(IDS_ADD), theApp.m_menu_set.m_playlist_toolbar_menu.GetSubMenu(0), true); - m_playlist_toolbar.AddToolButton(theApp.m_icon_set.close, CCommon::LoadText(IDS_DELETE), CCommon::LoadText(IDS_DELETE), theApp.m_menu_set.m_playlist_toolbar_menu.GetSubMenu(1), true); - m_playlist_toolbar.AddToolButton(theApp.m_icon_set.sort, CCommon::LoadText(IDS_SORT), CCommon::LoadText(IDS_SORT), theApp.m_menu_set.m_playlist_toolbar_menu.GetSubMenu(2), true); - m_playlist_toolbar.AddToolButton(theApp.m_icon_set.show_playlist, CCommon::LoadText(IDS_LIST), CCommon::LoadText(IDS_LIST), theApp.m_menu_set.m_playlist_toolbar_menu.GetSubMenu(3), true); - m_playlist_toolbar.AddToolButton(theApp.m_icon_set.edit, CCommon::LoadText(IDS_EDIT), CCommon::LoadText(IDS_EDIT), theApp.m_menu_set.m_playlist_toolbar_menu.GetSubMenu(4), true); - m_playlist_toolbar.AddToolButton(theApp.m_icon_set.locate, nullptr, CCommon::LoadText(IDS_LOCATE_TO_CURRENT, CPlayerUIBase::GetCmdShortcutKeyForTooltips(ID_LOCATE_TO_CURRENT)), ID_LOCATE_TO_CURRENT); + menu_str = theApp.m_str_table.LoadText(L"UI_TXT_PLAYLIST_TOOLBAR_ADD"); + m_playlist_toolbar.AddToolButton(IconMgr::IconType::IT_Add, menu_str.c_str(), menu_str.c_str(), theApp.m_menu_mgr.GetMenu(MenuMgr::MainPlaylistAddMenu), true); + menu_str = theApp.m_str_table.LoadText(L"UI_TXT_PLAYLIST_TOOLBAR_DELETE"); + m_playlist_toolbar.AddToolButton(IconMgr::IconType::IT_Cancel, menu_str.c_str(), menu_str.c_str(), theApp.m_menu_mgr.GetMenu(MenuMgr::MainPlaylistDelMenu), true); + menu_str = theApp.m_str_table.LoadText(L"UI_TXT_PLAYLIST_TOOLBAR_SORT"); + m_playlist_toolbar.AddToolButton(IconMgr::IconType::IT_Sort_Mode, menu_str.c_str(), menu_str.c_str(), theApp.m_menu_mgr.GetMenu(MenuMgr::MainPlaylistSortMenu), true); + menu_str = theApp.m_str_table.LoadText(L"UI_TXT_PLAYLIST_TOOLBAR_LIST"); + m_playlist_toolbar.AddToolButton(IconMgr::IconType::IT_Playlist, menu_str.c_str(), menu_str.c_str(), theApp.m_menu_mgr.GetMenu(MenuMgr::PlaylistToolBarListMenu), true); + menu_str = theApp.m_str_table.LoadText(L"UI_TXT_PLAYLIST_TOOLBAR_EDIT"); + m_playlist_toolbar.AddToolButton(IconMgr::IconType::IT_Edit, menu_str.c_str(), menu_str.c_str(), theApp.m_menu_mgr.GetMenu(MenuMgr::PlaylistToolBarEditMenu), true); + menu_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_LOCATE_TO_CURRENT") + CPlayerUIBase::GetCmdShortcutKeyForTooltips(ID_LOCATE_TO_CURRENT).GetString(); + m_playlist_toolbar.AddToolButton(IconMgr::IconType::IT_Locate, nullptr, menu_str.c_str(), ID_LOCATE_TO_CURRENT); //初始化分隔条 m_splitter_ctrl.RegAdjustLayoutCallBack(CMusicPlayerDlg::OnSplitterChanged); @@ -2291,11 +2209,11 @@ void CMusicPlayerDlg::OnSysCommand(UINT nID, LPARAM lParam) CAboutDlg dlgAbout; dlgAbout.DoModal(); } - else */if (cmd == IDM_MINIMODE) + else if (cmd == IDM_MINIMODE) { OnMiniMode(); } - else + else*/ { CMainDialogBase::OnSysCommand(nID, lParam); } @@ -2426,20 +2344,12 @@ void CMusicPlayerDlg::OnTimer(UINT_PTR nIDEvent) { //此if语句只在定时器第1次触发时才执行 m_first_start = false; -#ifndef COMPILE_IN_WIN_XP - if (IsTaskbarListEnable()) - { - //设置任务栏缩略图窗口按钮 - m_pTaskbar->ThumbBarAddButtons(m_hWnd, 3, m_thumbButton); - } -#endif CRect rect; GetClientRect(rect); //theApp.m_ui_data.client_width = rect.Width(); //theApp.m_ui_data.client_height = rect.Height(); SetPlaylistSize(rect.Width(), rect.Height(), CalculatePlaylistWidth(rect.Width())); //调整播放列表的大小和位置 m_path_static.Invalidate(); - //SetPorgressBarSize(rect.Width(), rect.Height()); //调整进度条在窗口中的大小和位置 SetPlaylistVisible(); if (m_cmdLine.empty()) //没有有通过命令行打开文件 @@ -2490,27 +2400,14 @@ void CMusicPlayerDlg::OnTimer(UINT_PTR nIDEvent) DrawInfo(); m_uiThread = AfxBeginThread(UiThreadFunc, (LPVOID)&m_ui_thread_para); - //注:不应该在这里打开或播放歌曲,应该在播放列表初始化完毕时执行。 - //CPlayer::GetInstance().MusicControl(Command::OPEN); - //CPlayer::GetInstance().MusicControl(Command::SEEK); - //CPlayer::GetInstance().GetPlayerCoreError(); - //SetPorgressBarSize(rect.Width(), rect.Height()); //重新调整进度条在窗口中的大小和位置(需要根据歌曲的时长调整显示时间控件的宽度) - //ShowTime(); - //m_progress_bar.SetSongLength(CPlayer::GetInstance().GetSongLength()); - - //if(!m_cmdLine.empty()) - // CPlayer::GetInstance().MusicControl(Command::PLAY); //如果文件是通过命令行打开的,则打开后直接播放 - - UpdatePlayPauseButton(); - //SetForegroundWindow(); - //ShowPlayList(); + TaskBarInit(); ThemeColorChanged(); //设置窗口不透明度 SetTransparency(); - if (theApp.m_nc_setting_data.float_playlist && theApp.m_nc_setting_data.playlist_btn_for_float_playlist) + if (theApp.m_nc_setting_data.float_playlist && theApp.m_media_lib_setting_data.playlist_btn_for_float_playlist) ShowFloatPlaylist(); IniPlaylistPopupMenu(); @@ -2522,7 +2419,7 @@ void CMusicPlayerDlg::OnTimer(UINT_PTR nIDEvent) } //提示用户是否创建桌面快捷方式 - CreateDesktopShortcut(); + FirstRunCreateShortcut(); SetAlwaysOnTop(); } @@ -2530,11 +2427,6 @@ void CMusicPlayerDlg::OnTimer(UINT_PTR nIDEvent) m_timer_count++; UpdateTaskBarProgress(); - //UpdateProgress(); - - //CPlayer::GetInstance().GetPlayerCoreError(); - //if (m_miniModeDlg.m_hWnd == NULL && (CPlayer::GetInstance().IsPlaying() || GetActiveWindow() == this)) //进入迷你模式时不刷新,不在播放且窗口处于后台时不刷新 - // DrawInfo(); //绘制界面上的信息(如果显示了迷你模式,则不绘制界面信息) // 判断主窗口是否具有焦点 CWnd* pActiveWnd = GetActiveWindow(); @@ -2567,10 +2459,7 @@ void CMusicPlayerDlg::OnTimer(UINT_PTR nIDEvent) //获取频谱分析数据 CPlayer::GetInstance().CalculateSpectralData(); - //if (CPlayer::GetInstance().IsPlaying()) - //{ - // CPlayer::GetInstance().GetPlayerCoreCurrentPosition(); - //} + // 这里在更改播放状态,需要先取得锁,没有成功取得锁的话下次再试 if (CPlayer::GetInstance().GetPlayStatusMutex().try_lock()) @@ -2825,7 +2714,10 @@ void CMusicPlayerDlg::OnPrevious() { // TODO: 在此添加命令处理程序代码 if (!CPlayer::GetInstance().PlayTrack(PREVIOUS)) - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } } @@ -2833,7 +2725,10 @@ void CMusicPlayerDlg::OnNext() { // TODO: 在此添加命令处理程序代码 if (!CPlayer::GetInstance().PlayTrack(NEXT)) - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } } @@ -2865,21 +2760,8 @@ void CMusicPlayerDlg::OnFF() } -void CMusicPlayerDlg::OnSetPath() +void CMusicPlayerDlg::OnMediaLib() { - //static bool dialog_exist{ false }; - - //if (!dialog_exist) //确保对话框已经存在时不再弹出 - //{ - // dialog_exist = true; - // int cur_tab{ CPlayer::GetInstance().IsPlaylistMode() ? 1 : 0 }; - // CMediaLibDlg media_lib_dlg{ cur_tab }; - // media_lib_dlg.DoModal(); - // dialog_exist = false; - // //if (media_lib_dlg.m_playlist_dlg.IsPlaylistModified()) - // //IniPlaylistPopupMenu(); - //} - CMusicPlayerCmdHelper helper; helper.ShowMediaLib(); } @@ -2987,7 +2869,7 @@ void CMusicPlayerDlg::OnDestroy() m_findDlg.SaveConfig(); theApp.SaveConfig(); //解除全局热键 - theApp.m_hot_key.UnRegisterAllHotKey(); + m_hot_key.UnRegisterAllHotKey(); //取消注册接收音频设备变化通知回调的IMMNotificationClient接口 devicesManager->ReleaseDeviceEnumerator(); @@ -3007,8 +2889,9 @@ void CMusicPlayerDlg::OnDestroy() m_notify_icon.DeleteNotifyIcon(); m_ui_thread_para.ui_thread_exit = true; + DWORD rtn{}; if (m_uiThread != nullptr) - WaitForSingleObject(m_uiThread->m_hThread, 2000); //等待线程退出 + rtn = WaitForSingleObject(m_uiThread->m_hThread, 20000); //等待线程退出 m_ui_static_ctrl.ReleaseDC(m_pUiDC); @@ -3027,13 +2910,15 @@ void CMusicPlayerDlg::OnFileOpen() // TODO: 在此添加命令处理程序代码 vector files; //储存打开的多个文件路径 //设置过滤器 - wstring filter = CAudioCommon::GetFileDlgFilter(); - + wstring filter = FilterHelper::GetAudioFileFilter(); CCommon::DoOpenFileDlg(filter, files, this); if (!files.empty()) { if (!CPlayer::GetInstance().OpenFilesInDefaultPlaylist(files)) - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } } } @@ -3043,13 +2928,16 @@ void CMusicPlayerDlg::OnFileOpenFolder() // TODO: 在此添加命令处理程序代码 static bool include_sub_dir{ false }; + static CString include_sub_dir_str{ theApp.m_str_table.LoadText(L"TXT_FOLDER_BROWSER_INCLUDE_SUB_DIR").c_str() }; + const wstring& title = theApp.m_str_table.LoadText(L"TITLE_FOLDER_BROWSER_SONG_SOURCE"); #ifdef COMPILE_IN_WIN_XP CFolderBrowserDlg folderPickerDlg(this->GetSafeHwnd()); - folderPickerDlg.SetInfo(CCommon::LoadText(IDS_OPEN_FOLDER_INFO)); + folderPickerDlg.SetInfo(title.c_str()); #else CFilePathHelper current_path(CPlayer::GetInstance().GetCurrentDir()); CFolderPickerDialog folderPickerDlg(current_path.GetParentDir().c_str()); - folderPickerDlg.AddCheckButton(IDC_OPEN_CHECKBOX, CCommon::LoadText(IDS_INCLUDE_SUB_DIR), include_sub_dir); //在打开对话框中添加一个复选框 + folderPickerDlg.m_ofn.lpstrTitle = title.c_str(); + folderPickerDlg.AddCheckButton(IDC_OPEN_CHECKBOX, include_sub_dir_str, include_sub_dir); //在打开对话框中添加一个复选框 #endif if (folderPickerDlg.DoModal() == IDOK) { @@ -3059,7 +2947,10 @@ void CMusicPlayerDlg::OnFileOpenFolder() include_sub_dir = (checked != FALSE); #endif if (!CPlayer::GetInstance().OpenFolder(wstring(folderPickerDlg.GetPathName()), include_sub_dir)) - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } } } @@ -3094,14 +2985,20 @@ void CMusicPlayerDlg::OnDropFiles(HDROP hDropInfo) int rtn = CPlayer::GetInstance().AddFilesToPlaylist(files); ok = (rtn != -1); // 返回值不是-1说明没有遇到取得锁失败的问题 if (rtn == 0) - MessageBox(CCommon::LoadText(IDS_FILE_EXIST_IN_PLAYLIST_INFO), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_FILE_EXIST_IN_PLAYLIST"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } } else ok = CPlayer::GetInstance().OpenFilesInDefaultPlaylist(files, false); } } if (!ok) - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } CMainDialogBase::OnDropFiles(hDropInfo); } @@ -3193,21 +3090,22 @@ BOOL CMusicPlayerDlg::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) { // TODO: 在此添加消息处理程序代码和/或调用默认值 CRect draw_rect{ 0,0,theApp.m_ui_data.draw_area_width, theApp.m_ui_data.draw_area_height }; + bool from_desktop_lyric{ pt.x == INT16_MAX && pt.y == INT16_MAX }; // 从桌面歌词/迷你模式窗口转发 ScreenToClient(&pt); if (m_pUI->MouseWheel(zDelta, pt)) return TRUE; - if (draw_rect.PtInRect(pt)) + if (draw_rect.PtInRect(pt) || from_desktop_lyric) { - if (zDelta > 0) - { - OnVolumeUp(); - } - if (zDelta < 0) - { - OnVolumeDown(); - } + static int nogori = 0; + if (nogori * zDelta < 0) // 换向时清零累计值使得滚轮总是能够及时响应 + nogori = 0; + // 在触控板下有必要处理zDelta,触控板驱动会通过较小的zDelta连发模拟惯性 + // 每120的zDelta(即滚轮一格)音量调整百分之mouse_volum_step + nogori += zDelta * theApp.m_nc_setting_data.mouse_volum_step; + AdjustVolume(nogori / 120); + nogori = nogori % 120; } return CMainDialogBase::OnMouseWheel(nFlags, zDelta, pt); @@ -3243,7 +3141,10 @@ void CMusicPlayerDlg::OnNMDblclkPlaylistList(NMHDR* pNMHDR, LRESULT* pResult) if (song_index < 0) return; if (!CPlayer::GetInstance().PlayTrack(song_index)) - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } *pResult = 0; } @@ -3266,8 +3167,11 @@ void CMusicPlayerDlg::OnOptionSettings() void CMusicPlayerDlg::OnReloadPlaylist() { // TODO: 在此添加命令处理程序代码 - if (!CPlayer::GetInstance().ReloadPlaylist()) - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + if (!CPlayer::GetInstance().ReloadPlaylist(MR_FOECE_FULL)) // 强制重新获取全部音频元数据 + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } } @@ -3290,9 +3194,9 @@ void CMusicPlayerDlg::OnNMRClickPlaylistList(NMHDR* pNMHDR, LRESULT* pResult) CMenu* pContextMenu{}; if (m_item_selected >= 0) - pContextMenu = theApp.m_menu_set.m_list_popup_menu.GetSubMenu(0); + pContextMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::PlaylistMenu); else - pContextMenu = &theApp.m_menu_set.m_playlist_toolbar_popup_menu; + pContextMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::PlaylistToolBarMenu); m_playlist_list.ShowPopupMenu(pContextMenu, pNMItemActivate->iItem, this); *pResult = 0; @@ -3303,7 +3207,10 @@ void CMusicPlayerDlg::OnPlayItem() { // TODO: 在此添加命令处理程序代码 if (!CPlayer::GetInstance().PlayTrack(m_item_selected)) - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } } @@ -3424,7 +3331,10 @@ BOOL CMusicPlayerDlg::OnCommand(WPARAM wParam, LPARAM lParam) if (item.playlist_info != nullptr) { if (!CPlayer::GetInstance().SetPlaylist(item.playlist_info->path, item.playlist_info->track, item.playlist_info->position)) - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } } } else @@ -3432,61 +3342,73 @@ BOOL CMusicPlayerDlg::OnCommand(WPARAM wParam, LPARAM lParam) if (item.folder_info != nullptr) { if (!CPlayer::GetInstance().SetPath(*item.folder_info)) - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } } } } } } - auto getSelectedItems = [&](std::vector& item_list) + // 这里应当先判断ID再调用IsMainWindowPopupMenu,避免程序初始化时的无关命令导致菜单全量创建 + // 将菜单初始化延迟到用户使用菜单有助于提高启动速度 + + //响应播放列表右键菜单中的“添加到播放列表” + if ((command >= ID_ADD_TO_DEFAULT_PLAYLIST && command <= ID_ADD_TO_MY_FAVOURITE + ADD_TO_PLAYLIST_MAX_SIZE) || command == ID_ADD_TO_OTHER_PLAYLIST) { - item_list.clear(); - if (IsMainWindowPopupMenu()) //如果当前命令是从主界面右键菜单中弹出来的,则是添加正在播放的曲目到播放列表 + auto getSelectedItems = [&](std::vector& item_list) + { + item_list.clear(); + if (IsMainWindowPopupMenu()) //如果当前命令是从主界面右键菜单中弹出来的,则是添加正在播放的曲目到播放列表 + { + item_list.push_back(CPlayer::GetInstance().GetCurrentSongInfo()); + } + else //否则是添加选中的曲目到播放列表 + { + for (auto i : m_items_selected) + { + if (i >= 0 && i < CPlayer::GetInstance().GetSongNum()) + { + item_list.push_back(CPlayer::GetInstance().GetPlayList()[i]); + } + } + } + }; + CMusicPlayerCmdHelper cmd_helper; + if (cmd_helper.OnAddToPlaylistCommand(getSelectedItems, command)) + m_pCurMenu = nullptr; + } + //响应主窗口右键菜单中的分级 + if ((command >= ID_RATING_1 && command <= ID_RATING_5) || command == ID_RATING_NONE) //如果命令是歌曲分级(应确保分级命令的ID是连续的) + { + bool rating_failed{ false }; + CMusicPlayerCmdHelper cmd_helper; + if (IsMainWindowPopupMenu()) { - item_list.push_back(CPlayer::GetInstance().GetCurrentSongInfo()); + if (!cmd_helper.OnRating(CPlayer::GetInstance().GetCurrentSongInfo(), command)) + rating_failed = true; } - else //否则是添加选中的曲目到播放列表 + //响应播放列表右键菜单中的分级 + else { - for (auto i : m_items_selected) + for (int i : m_items_selected) { if (i >= 0 && i < CPlayer::GetInstance().GetSongNum()) { - item_list.push_back(CPlayer::GetInstance().GetPlayList()[i]); + SongInfo& select_file = CPlayer::GetInstance().GetPlayList()[i]; + if (!cmd_helper.OnRating(select_file, command)) + rating_failed = true; } } } - - }; - //响应播放列表右键菜单中的“添加到播放列表” - CMusicPlayerCmdHelper cmd_helper; - if (cmd_helper.OnAddToPlaylistCommand(getSelectedItems, command)) - m_pCurMenu = nullptr; - - //响应主窗口右键菜单中的分级 - bool rating_failed{ false }; - if (IsMainWindowPopupMenu()) - { - if (!cmd_helper.OnRating(CPlayer::GetInstance().GetCurrentSongInfo(), command)) - rating_failed = true; - } - //响应播放列表右键菜单中的分级 - else - { - for (int i : m_items_selected) + if (rating_failed) { - if (i >= 0 && i < CPlayer::GetInstance().GetSongNum()) - { - SongInfo& select_file = CPlayer::GetInstance().GetPlayList()[i]; - if (!cmd_helper.OnRating(select_file, command)) - rating_failed = true; - } + const wstring& info = theApp.m_str_table.LoadText(L"MSG_FILE_WRITE_FAILED"); + MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK); } } - if (rating_failed) - { - MessageBox(CCommon::LoadText(IDS_CANNOT_WRITE_TO_FILE), NULL, MB_ICONWARNING | MB_OK); - } return CMainDialogBase::OnCommand(wParam, lParam); } @@ -3535,14 +3457,25 @@ void CMusicPlayerDlg::OnHotKey(UINT nHotKeyId, UINT nKey1, UINT nKey2) } else if (GetActiveWindow() == this) // 如果窗口拥有焦点则隐藏 { - Show(false); + ShowWindow(SW_HIDE); + if (IsFloatPlaylistExist()) + { + m_pFloatPlaylistDlg->ShowWindow(SW_HIDE); + } } else // 进行窗口恢复并取得焦点 { - if (IsIconic()) + if (IsIconic()) // 如果是最小化的窗口那么还原 ShowWindow(SW_RESTORE); - else - Show(true); + else // 如果是HIDE的窗口那么显示 + { + ShowWindow(SW_SHOW); + if (IsFloatPlaylistExist()) + { + m_pFloatPlaylistDlg->ShowWindow(SW_SHOW); + } + TaskBarInit(); + } SetForegroundWindow(); } } @@ -3567,7 +3500,18 @@ void CMusicPlayerDlg::OnReIniBass() void CMusicPlayerDlg::OnSortByFile() { // TODO: 在此添加命令处理程序代码 - CPlayer::GetInstance().m_sort_mode = SM_FILE; + auto& sort_mode = CPlayer::GetInstance().m_sort_mode; + sort_mode = (sort_mode != SM_U_FILE) ? SM_U_FILE : SM_D_FILE; + CPlayer::GetInstance().SortPlaylist(); + ShowPlayList(); +} + + +void CMusicPlayerDlg::OnSortByPath() +{ + // TODO: 在此添加命令处理程序代码 + auto& sort_mode = CPlayer::GetInstance().m_sort_mode; + sort_mode = (sort_mode != SM_U_PATH) ? SM_U_PATH : SM_D_PATH; CPlayer::GetInstance().SortPlaylist(); ShowPlayList(); } @@ -3576,7 +3520,8 @@ void CMusicPlayerDlg::OnSortByFile() void CMusicPlayerDlg::OnSortByTitle() { // TODO: 在此添加命令处理程序代码 - CPlayer::GetInstance().m_sort_mode = SM_TITLE; + auto& sort_mode = CPlayer::GetInstance().m_sort_mode; + sort_mode = (sort_mode != SM_U_TITLE) ? SM_U_TITLE : SM_D_TITLE; CPlayer::GetInstance().SortPlaylist(); ShowPlayList(); } @@ -3585,7 +3530,8 @@ void CMusicPlayerDlg::OnSortByTitle() void CMusicPlayerDlg::OnSortByArtist() { // TODO: 在此添加命令处理程序代码 - CPlayer::GetInstance().m_sort_mode = SM_ARTIST; + auto& sort_mode = CPlayer::GetInstance().m_sort_mode; + sort_mode = (sort_mode != SM_U_ARTIST) ? SM_U_ARTIST : SM_D_ARTIST; CPlayer::GetInstance().SortPlaylist(); ShowPlayList(); } @@ -3594,7 +3540,8 @@ void CMusicPlayerDlg::OnSortByArtist() void CMusicPlayerDlg::OnSortByAlbum() { // TODO: 在此添加命令处理程序代码 - CPlayer::GetInstance().m_sort_mode = SM_ALBUM; + auto& sort_mode = CPlayer::GetInstance().m_sort_mode; + sort_mode = (sort_mode != SM_U_ALBUM) ? SM_U_ALBUM : SM_D_ALBUM; CPlayer::GetInstance().SortPlaylist(); ShowPlayList(); } @@ -3603,25 +3550,28 @@ void CMusicPlayerDlg::OnSortByAlbum() void CMusicPlayerDlg::OnSortByTrack() { // TODO: 在此添加命令处理程序代码 - CPlayer::GetInstance().m_sort_mode = SM_TRACK; + auto& sort_mode = CPlayer::GetInstance().m_sort_mode; + sort_mode = (sort_mode != SM_U_TRACK) ? SM_U_TRACK : SM_D_TRACK; CPlayer::GetInstance().SortPlaylist(); ShowPlayList(); } -void CMusicPlayerDlg::OnSortByModifiedTime() +void CMusicPlayerDlg::OnSortByListenTime() { // TODO: 在此添加命令处理程序代码 - CPlayer::GetInstance().m_sort_mode = SM_TIME; + auto& sort_mode = CPlayer::GetInstance().m_sort_mode; + sort_mode = (sort_mode != SM_D_LISTEN) ? SM_D_LISTEN : SM_U_LISTEN; // 这个特殊,第一次点击默认为降序 CPlayer::GetInstance().SortPlaylist(); ShowPlayList(); } -void CMusicPlayerDlg::OnSortByPath() +void CMusicPlayerDlg::OnSortByModifiedTime() { // TODO: 在此添加命令处理程序代码 - CPlayer::GetInstance().m_sort_mode = SM_PATH; + auto& sort_mode = CPlayer::GetInstance().m_sort_mode; + sort_mode = (sort_mode != SM_U_TIME) ? SM_U_TIME : SM_D_TIME; CPlayer::GetInstance().SortPlaylist(); ShowPlayList(); } @@ -3635,9 +3585,8 @@ void CMusicPlayerDlg::OnDeleteFromDisk() if (m_item_selected < 0 || m_item_selected >= CPlayer::GetInstance().GetSongNum()) return; - CString info; - info = CCommon::LoadTextFormat(IDS_DELETE_FILE_INQUARY, { m_items_selected.size() }); - if (MessageBoxW(info, NULL, MB_ICONWARNING | MB_OKCANCEL) != IDOK) return; + wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_DELETE_SEL_AUDIO_FILE_INQUARY", { m_items_selected.size() }); + if (MessageBoxW(info.c_str(), NULL, MB_ICONWARNING | MB_OKCANCEL) != IDOK) return; // 以下操作可能涉及MusicControl,先取得锁 if (!CPlayer::GetInstance().GetPlayStatusMutex().try_lock_for(std::chrono::milliseconds(1000))) return; int rtn; @@ -3655,7 +3604,7 @@ void CMusicPlayerDlg::OnDeleteFromDisk() } if (delected_files.empty()) return; - rtn = CCommon::DeleteFiles(m_hWnd, delected_files); + rtn = CommonDialogMgr::DeleteFiles(m_hWnd, delected_files); } else { @@ -3666,7 +3615,7 @@ void CMusicPlayerDlg::OnDeleteFromDisk() return; delected_file = song.file_path; - rtn = CCommon::DeleteAFile(m_hWnd, delected_file); + rtn = CommonDialogMgr::DeleteAFile(m_hWnd, delected_file); } if (rtn == ERROR_SUCCESS) { @@ -3687,7 +3636,7 @@ void CMusicPlayerDlg::OnDeleteFromDisk() CFilePathHelper file_path(file); file = file_path.ReplaceFileExtension(L"jpg").c_str(); } - CCommon::DeleteFiles(m_hWnd, delected_files); + CommonDialogMgr::DeleteFiles(m_hWnd, delected_files); for (const wstring& ext : CLyrics::m_surpported_lyric) // 删除所有后缀的歌词 { for (auto& file : delected_files) @@ -3695,16 +3644,16 @@ void CMusicPlayerDlg::OnDeleteFromDisk() CFilePathHelper file_path(file); file = file_path.ReplaceFileExtension(ext.c_str()).c_str(); } - CCommon::DeleteFiles(m_hWnd, delected_files); + CommonDialogMgr::DeleteFiles(m_hWnd, delected_files); } } else { CFilePathHelper file_path(delected_file); - CCommon::DeleteAFile(m_hWnd, file_path.ReplaceFileExtension(L"jpg").c_str()); + CommonDialogMgr::DeleteAFile(m_hWnd, file_path.ReplaceFileExtension(L"jpg").c_str()); for (const wstring& ext : CLyrics::m_surpported_lyric) // 删除所有后缀的歌词 { - CCommon::DeleteAFile(m_hWnd, file_path.ReplaceFileExtension(ext.c_str()).c_str()); + CommonDialogMgr::DeleteAFile(m_hWnd, file_path.ReplaceFileExtension(ext.c_str()).c_str()); } } } @@ -3723,23 +3672,15 @@ void CMusicPlayerDlg::OnDeleteFromDisk() else { CPlayer::GetInstance().GetPlayStatusMutex().unlock(); // 在进入模态对话框MessageBox前及时解锁 - MessageBox(CCommon::LoadText(IDS_CONNOT_DELETE_FILE), NULL, MB_ICONWARNING); + MessageBox(theApp.m_str_table.LoadText(L"MSG_DELETE_FILE_FAILED").c_str(), NULL, MB_ICONWARNING); } } afx_msg LRESULT CMusicPlayerDlg::OnTaskbarcreated(WPARAM wParam, LPARAM lParam) { -#ifndef COMPILE_IN_WIN_XP - if (IsTaskbarListEnable()) - { - //当资源管理器重启后重新添加任务栏缩略图窗口按钮 - m_pTaskbar->ThumbBarAddButtons(m_hWnd, 3, m_thumbButton); - SetThumbnailClipArea(); - //重新更新任务栏上的播放状态角标 - UpdatePlayPauseButton(); - } -#endif + TaskBarInit(); + //资源管理器重启后Cortana的句柄会发生改变,此时要重新获取Cortana的句柄 m_cortana_lyric.Init(); @@ -3811,29 +3752,12 @@ void CMusicPlayerDlg::OnMiniMode() if (float_playlist_exist) ShowFloatPlaylist(); -#ifndef COMPILE_IN_WIN_XP - if (IsTaskbarListEnable()) - { - m_pTaskbar->ThumbBarAddButtons(m_hWnd, 3, m_thumbButton); //重新添加任务栏缩略图按钮 - SetThumbnailClipArea(); //重新设置任务栏缩略图 - } -#endif SetForegroundWindow(); SwitchTrack(); - UpdatePlayPauseButton(); SetTransparency(); SetAlwaysOnTop(); - } -} - -void CMusicPlayerDlg::Show(bool show) -{ - int window_show{ show ? SW_SHOW : SW_HIDE }; - ShowWindow(window_show); - if (IsFloatPlaylistExist()) - { - m_pFloatPlaylistDlg->ShowWindow(window_show); + TaskBarInit(); } } @@ -3880,9 +3804,8 @@ void CMusicPlayerDlg::LoadUiData() } } catch (CArchiveException* exception) { - CString info; - info = CCommon::LoadTextFormat(IDS_SERIALIZE_ERROR, { theApp.m_ui_data_path, exception->m_cause }); - theApp.WriteLog(wstring{ info }); + wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_SERIALIZE_ERROR", { theApp.m_ui_data_path, exception->m_cause }); + theApp.WriteLog(info); } ar.Close(); file.Close(); @@ -3907,46 +3830,6 @@ void CMusicPlayerDlg::OnSplitterChanged(CRect splitter_rect) } } -void CMusicPlayerDlg::OnBnClickedStop() -{ - // TODO: 在此添加控件通知处理程序代码 - SetFocus(); - OnStop(); -} - - -void CMusicPlayerDlg::OnBnClickedPrevious() -{ - // TODO: 在此添加控件通知处理程序代码 - SetFocus(); - OnPrevious(); -} - - -void CMusicPlayerDlg::OnBnClickedPlayPause() -{ - // TODO: 在此添加控件通知处理程序代码 - SetFocus(); - OnPlayPause(); -} - - -void CMusicPlayerDlg::OnBnClickedNext() -{ - // TODO: 在此添加控件通知处理程序代码 - SetFocus(); - OnNext(); -} - - -//void CMusicPlayerDlg::OnMove(int x, int y) -//{ -// CMainDialogBase::OnMove(x, y); -// -// // TODO: 在此处添加消息处理程序代码 -// SetMaskWindowPos(); -//} - void CMusicPlayerDlg::OnReloadLyric() { @@ -3989,7 +3872,7 @@ void CMusicPlayerDlg::OnCopyCurrentLyric() if (!CCommon::CopyStringToClipboard(lyric_str)) // MessageBox(_T("当前歌词已成功复制到剪贴板。"), NULL, MB_ICONINFORMATION); //else - MessageBox(CCommon::LoadText(IDS_COPY_CLIPBOARD_FAILED), NULL, MB_ICONWARNING); + MessageBox(theApp.m_str_table.LoadText(L"MSG_COPY_CLIPBOARD_FAILED").c_str(), NULL, MB_ICONWARNING); } @@ -3997,9 +3880,9 @@ void CMusicPlayerDlg::OnCopyAllLyric() { // TODO: 在此添加命令处理程序代码 if (CCommon::CopyStringToClipboard(CPlayer::GetInstance().m_Lyrics.GetAllLyricText(theApp.m_lyric_setting_data.show_translate))) - MessageBox(CCommon::LoadText(IDS_ALL_LRYIC_COPIED), NULL, MB_ICONINFORMATION); + MessageBox(theApp.m_str_table.LoadText(L"MSG_COPY_CLIPBOARD_ALL_LYRIC").c_str(), NULL, MB_ICONINFORMATION); else - MessageBox(CCommon::LoadText(IDS_COPY_CLIPBOARD_FAILED), NULL, MB_ICONWARNING); + MessageBox(theApp.m_str_table.LoadText(L"MSG_COPY_CLIPBOARD_FAILED").c_str(), NULL, MB_ICONWARNING); } @@ -4063,7 +3946,8 @@ void CMusicPlayerDlg::OnEditLyric() CCommon::DeleteModelessDialog(m_pLyricEdit); if (!theApp.IsScintillaLoaded()) { - MessageBox(CCommon::LoadText(IDS_SCI_NOT_LOADED_ERROR_INFO), NULL, MB_ICONERROR | MB_OK); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_SCI_NOT_LOADED_ERROR"); + MessageBox(info.c_str(), NULL, MB_ICONERROR | MB_OK); return; } m_pLyricEdit = new CLyricEditDlg; @@ -4098,7 +3982,7 @@ void CMusicPlayerDlg::OnDeleteLyric() // TODO: 在此添加命令处理程序代码 if (CCommon::FileExist(CPlayer::GetInstance().m_Lyrics.GetPathName())) { - int rtn = CCommon::DeleteAFile(m_hWnd, CPlayer::GetInstance().m_Lyrics.GetPathName()); //删除歌词文件 + int rtn = CommonDialogMgr::DeleteAFile(m_hWnd, CPlayer::GetInstance().m_Lyrics.GetPathName()); //删除歌词文件 CPlayer::GetInstance().ClearLyric(); //清除歌词关联 } @@ -4197,7 +4081,7 @@ afx_msg LRESULT CMusicPlayerDlg::OnPlaylistIniComplate(WPARAM wParam, LPARAM lPa static bool first_init{ true }; if (first_init) { - theApp.StartUpdateMediaLib(true); + theApp.StartUpdateMediaLib(false); // 获取不存在的项目以及更新修改时间变化的项目 first_init = false; } } @@ -4208,42 +4092,45 @@ afx_msg LRESULT CMusicPlayerDlg::OnPlaylistIniComplate(WPARAM wParam, LPARAM lPa afx_msg LRESULT CMusicPlayerDlg::OnAfterSetTrack(WPARAM wParam, LPARAM lParam) { - CString title; - title = CSongInfoHelper::GetDisplayStr(CPlayer::GetInstance().GetCurrentSongInfo(), theApp.m_media_lib_setting_data.display_format).c_str(); - - CString title_suffix; - if (!title.IsEmpty()) - title_suffix += _T(" - "); + wstring title = CSongInfoHelper::GetDisplayStr(CPlayer::GetInstance().GetCurrentSongInfo(), theApp.m_media_lib_setting_data.display_format); + wstring title_suffix; + if (!title.empty()) + title_suffix += L" - "; title_suffix += APP_NAME; if (CPlayer::GetInstance().IsMciCore()) - title_suffix += _T(" (MCI)"); + title_suffix += L" (MCI)"; else if (CPlayer::GetInstance().IsFfmpegCore()) { - title_suffix += _T(" (FFMPEG"); + title_suffix += L" (FFMPEG"; auto core = (CFfmpegCore*)CPlayer::GetInstance().GetPlayerCore(); if (core->IsWASAPISupported() && theApp.m_play_setting_data.ffmpeg_core_enable_WASAPI) { - title_suffix += _T(", WASAPI"); + title_suffix += L", WASAPI"; if (theApp.m_play_setting_data.ffmpeg_core_enable_WASAPI_exclusive_mode) { - title_suffix += _T("("); - title_suffix += CCommon::LoadText(IDS_EXCLUSIVE_MODE); - title_suffix += _T(")"); + title_suffix += L'(' + theApp.m_str_table.LoadText(L"UI_TITLE_EXCLUSIVE_MODE") + L')'; } } - title_suffix += _T(")"); + title_suffix += L')'; } #ifdef _DEBUG - title_suffix += _T(' '); - title_suffix += CCommon::LoadText(IDS_DEBUG_MODE); + title_suffix += L' '; + title_suffix += L'(' + theApp.m_str_table.LoadText(L"UI_TITLE_DEBUG_MODE") + L')'; #endif theApp.m_window_title = title + title_suffix; - SetWindowText(theApp.m_window_title); //用当前正在播放的歌曲名作为窗口标题 + SetWindowText(theApp.m_window_title.c_str()); //用当前正在播放的歌曲名作为窗口标题 - int title_length = 128 - title_suffix.GetLength() - 1; - if (title.GetLength() > title_length) - title = title.Left(title_length); - m_notify_icon.SetIconToolTip(title + title_suffix); + if (title_suffix.size() <= 127) + { + size_t title_length = 127 - title_suffix.size(); + if (title.size() > title_length) + title = title.substr(0, title_length) + title_suffix; + else + title += title_suffix; + } + else + title = title_suffix.substr(0, 127); + m_notify_icon.SetIconToolTip(title.c_str()); SwitchTrack(); UpdatePlayPauseButton(); @@ -4257,7 +4144,8 @@ void CMusicPlayerDlg::OnEqualizer() // TODO: 在此添加命令处理程序代码 if (CPlayer::GetInstance().IsMciCore()) { - MessageBox(CCommon::LoadText(IDS_MCI_NO_THIS_FUNCTION_WARNING), NULL, MB_ICONWARNING | MB_OK); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_MCI_NO_THIS_FUNCTION_WARNING"); + MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK); return; } @@ -4276,7 +4164,7 @@ void CMusicPlayerDlg::OnExploreOnline() UINT CMusicPlayerDlg::ViewOnlineThreadFunc(LPVOID lpParam) { - CCommon::SetThreadLanguage(theApp.m_general_setting_data.language); + CCommon::SetThreadLanguageList(theApp.m_str_table.GetLanguageTag()); //此命令用于跳转到歌曲对应的网易云音乐的在线页面 int item_selected = (int)lpParam; if (item_selected >= 0 && item_selected < CPlayer::GetInstance().GetSongNum()) @@ -4290,7 +4178,7 @@ UINT CMusicPlayerDlg::ViewOnlineThreadFunc(LPVOID lpParam) UINT CMusicPlayerDlg::DownloadLyricAndCoverThreadFunc(LPVOID lpParam) { - CCommon::SetThreadLanguage(theApp.m_general_setting_data.language); + CCommon::SetThreadLanguageList(theApp.m_str_table.GetLanguageTag()); //CMusicPlayerDlg* pThis = (CMusicPlayerDlg*)lpParam; bool is_osu{ CPlayer::GetInstance().IsOsuFile() }; @@ -4314,8 +4202,8 @@ UINT CMusicPlayerDlg::DownloadLyricAndCoverThreadFunc(LPVOID lpParam) { //搜索歌曲并获取最佳匹配的项目 match_item = CInternetCommon::SearchSongAndGetMatched(song_info_ori.title, song_info_ori.artist, song_info_ori.album, song_info_ori.GetFileName(), false, &result); - CPlayer::GetInstance().SetRelatedSongID(match_item.id); - song_info_ori = CSongDataManager::GetInstance().GetSongInfo3(CPlayer::GetInstance().GetCurrentSongInfo()); + song_info_ori.SetSongId(match_item.id); + CSongDataManager::GetInstance().SetSongID(song_info_ori, song_info_ori.song_id); // 与媒体库同步 } if (song_info_ori.song_id == 0) { @@ -4425,7 +4313,7 @@ UINT CMusicPlayerDlg::DownloadLyricAndCoverThreadFunc(LPVOID lpParam) UINT CMusicPlayerDlg::UiThreadFunc(LPVOID lpParam) { - CCommon::SetThreadLanguage(theApp.m_general_setting_data.language); + CCommon::SetThreadLanguageList(theApp.m_str_table.GetLanguageTag()); UIThreadPara* pPara = (UIThreadPara*)lpParam; CMusicPlayerDlg* pThis = dynamic_cast(theApp.m_pMainWnd); int fresh_cnt{ }; @@ -4524,7 +4412,7 @@ afx_msg LRESULT CMusicPlayerDlg::OnPlaylistIniStart(WPARAM wParam, LPARAM lParam else if (CPlaylistFile::IsPlaylistFile(remove_list_path)) { CPlaylistMgr::Instance().DeletePlaylist(remove_list_path); - CCommon::DeleteAFile(this->GetSafeHwnd(), remove_list_path); + CommonDialogMgr::DeleteAFile(this->GetSafeHwnd(), remove_list_path); } } return 0; @@ -4558,37 +4446,24 @@ void CMusicPlayerDlg::OnAlbumCoverSaveAs() { // TODO: 在此添加命令处理程序代码 //设置过滤器 - CString szFilter = CCommon::LoadText(IDS_ALL_FILES, _T("(*.*)|*.*||")); + wstring szFilter = theApp.m_str_table.LoadText(L"TXT_FILTER_ALL_FILES") + L"(*.*)|*.*||"; //设置另存为时的默认文件名 CString file_name; - CString extension; + wstring extension; if (CPlayer::GetInstance().IsInnerCover()) { - switch (CPlayer::GetInstance().GetAlbumCoverType()) - { - case 0: - extension = _T("jpg"); - break; - case 1: - extension = _T("png"); - break; - case 2: - extension = _T("gif"); - break; - default: - return; - } + extension = CPlayer::GetInstance().GetAlbumCoverType(); } else { CFilePathHelper cover_path(CPlayer::GetInstance().GetAlbumCoverPath()); - extension = cover_path.GetFileExtension().c_str(); + extension = cover_path.GetFileExtension(); } - file_name.Format(_T("AlbumCover - %s - %s.%s"), CPlayer::GetInstance().GetCurrentSongInfo().artist.c_str(), CPlayer::GetInstance().GetCurrentSongInfo().album.c_str(), extension.GetString()); + file_name.Format(_T("AlbumCover - %s - %s.%s"), CPlayer::GetInstance().GetCurrentSongInfo().artist.c_str(), CPlayer::GetInstance().GetCurrentSongInfo().album.c_str(), extension.c_str()); wstring file_name_wcs{ file_name }; CCommon::FileNameNormalize(file_name_wcs); //替换掉文件名中的无效字符 //构造保存文件对话框 - CFileDialog fileDlg(FALSE, _T("txt"), file_name_wcs.c_str(), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter, this); + CFileDialog fileDlg(FALSE, _T("txt"), file_name_wcs.c_str(), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter.c_str(), this); //显示保存文件对话框 if (IDOK == fileDlg.DoModal()) { @@ -4603,7 +4478,8 @@ afx_msg LRESULT CMusicPlayerDlg::OnConnotPlayWarning(WPARAM wParam, LPARAM lPara { if (theApp.m_nc_setting_data.no_sf2_warning) { - if (MessageBox(CCommon::LoadText(IDS_NO_MIDI_SF2_WARNING), NULL, MB_ICONWARNING | MB_OKCANCEL) == IDCANCEL) + const wstring& info = theApp.m_str_table.LoadText(L"MSG_NO_MIDI_SF2_WARNING"); + if (MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OKCANCEL) == IDCANCEL) theApp.m_nc_setting_data.no_sf2_warning = false; } return 0; @@ -4691,13 +4567,13 @@ void CMusicPlayerDlg::OnCurrentExploreOnline() void CMusicPlayerDlg::OnDeleteAlbumCover() { // TODO: 在此添加命令处理程序代码 - CString str_info; + wstring delete_info; bool is_inner_cover{ CPlayer::GetInstance().IsInnerCover() }; if (is_inner_cover) - str_info = CCommon::LoadText(IDS_DELETE_INNER_ALBUM_COVER_INQUERY); + delete_info = theApp.m_str_table.LoadText(L"MSG_DELETE_INNER_COVER_INQUERY"); else - str_info = CCommon::LoadTextFormat(IDS_DELETE_SINGLE_FILE_INQUIRY, { CPlayer::GetInstance().GetAlbumCoverPath() }); - if (MessageBox(str_info, NULL, MB_ICONQUESTION | MB_OKCANCEL) == IDOK) + delete_info = theApp.m_str_table.LoadTextFormat(L"MSG_DELETE_SINGLE_FILE_INQUARY", { CPlayer::GetInstance().GetAlbumCoverPath() }); + if (MessageBox(delete_info.c_str(), NULL, MB_ICONQUESTION | MB_OKCANCEL) == IDOK) { bool result{ false }; //内嵌专辑封面,从音频文件中删除 @@ -4710,12 +4586,15 @@ void CMusicPlayerDlg::OnDeleteAlbumCover() result = audio_tag.WriteAlbumCover(wstring()); } else - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } } //外部专辑封面,删除专辑封面文件 else { - result = (CCommon::DeleteAFile(theApp.m_pMainWnd->GetSafeHwnd(), CPlayer::GetInstance().GetAlbumCoverPath().c_str()) == ERROR_SUCCESS); + result = (CommonDialogMgr::DeleteAFile(theApp.m_pMainWnd->GetSafeHwnd(), CPlayer::GetInstance().GetAlbumCoverPath().c_str()) == ERROR_SUCCESS); CPlayer::GetInstance().SearchAlbumCover(); // 重新获取专辑封面(代替原来的m_album_cover.Destroy();) CPlayer::GetInstance().AlbumCoverGaussBlur(); } @@ -4728,7 +4607,7 @@ void CMusicPlayerDlg::OnDeleteAlbumCover() } else { - MessageBox(CCommon::LoadText(IDS_CONNOT_DELETE_FILE), NULL, MB_ICONWARNING); + MessageBox(theApp.m_str_table.LoadText(L"MSG_DELETE_FILE_FAILED").c_str(), NULL, MB_ICONWARNING); } } } @@ -4737,14 +4616,14 @@ void CMusicPlayerDlg::OnDeleteAlbumCover() void CMusicPlayerDlg::OnCopyFileTo() { // TODO: 在此添加命令处理程序代码 - LPCTSTR title{ CCommon::LoadText(IDS_SELECT_COPY_TARGET_FOLDER) }; + const wstring& title = theApp.m_str_table.LoadText(L"TITLE_FOLDER_BROWSER_COPY_TARGET"); #ifdef COMPILE_IN_WIN_XP CFolderBrowserDlg folderPickerDlg(this->GetSafeHwnd()); - folderPickerDlg.SetInfo(title); + folderPickerDlg.SetInfo(title.c_str()); #else CFilePathHelper current_path(CPlayer::GetInstance().GetCurrentDir()); CFolderPickerDialog folderPickerDlg(current_path.GetParentDir().c_str()); - folderPickerDlg.m_ofn.lpstrTitle = title; + folderPickerDlg.m_ofn.lpstrTitle = title.c_str(); #endif if (folderPickerDlg.DoModal() == IDOK) { @@ -4761,14 +4640,14 @@ void CMusicPlayerDlg::OnCopyFileTo() } if (source_files.empty()) return; - CCommon::CopyFiles(this->GetSafeHwnd(), source_files, wstring(folderPickerDlg.GetPathName())); + CommonDialogMgr::CopyFiles(this->GetSafeHwnd(), source_files, wstring(folderPickerDlg.GetPathName())); } else { const auto& song = CPlayer::GetInstance().GetPlayList()[m_item_selected]; if (song.is_cue) return; - CCommon::CopyAFile(this->GetSafeHwnd(), song.file_path, wstring(folderPickerDlg.GetPathName())); + CommonDialogMgr::CopyAFile(this->GetSafeHwnd(), song.file_path, wstring(folderPickerDlg.GetPathName())); } } } @@ -4780,14 +4659,14 @@ void CMusicPlayerDlg::OnMoveFileTo() if (theApp.m_media_lib_setting_data.disable_delete_from_disk) return; - LPCTSTR title{ CCommon::LoadText(IDS_SELECT_MOVE_TARGET_FOLDER) }; + const wstring& title = theApp.m_str_table.LoadText(L"TITLE_FOLDER_BROWSER_MOVE_TARGET"); #ifdef COMPILE_IN_WIN_XP CFolderBrowserDlg folderPickerDlg(this->GetSafeHwnd()); - folderPickerDlg.SetInfo(title); + folderPickerDlg.SetInfo(title.c_str()); #else CFilePathHelper current_path(CPlayer::GetInstance().GetCurrentDir()); CFolderPickerDialog folderPickerDlg(current_path.GetParentDir().c_str()); - folderPickerDlg.m_ofn.lpstrTitle = title; + folderPickerDlg.m_ofn.lpstrTitle = title.c_str(); #endif if (folderPickerDlg.DoModal() == IDOK) { @@ -4810,7 +4689,7 @@ void CMusicPlayerDlg::OnMoveFileTo() } if (source_files.empty()) return; - rtn = CCommon::MoveFiles(m_hWnd, source_files, wstring(folderPickerDlg.GetPathName())); + rtn = CommonDialogMgr::MoveFiles(m_hWnd, source_files, wstring(folderPickerDlg.GetPathName())); } else { @@ -4820,7 +4699,7 @@ void CMusicPlayerDlg::OnMoveFileTo() if (song.is_cue || COSUPlayerHelper::IsOsuFile(song.file_path)) return; source_file = song.file_path; - rtn = CCommon::MoveAFile(m_hWnd, source_file, wstring(folderPickerDlg.GetPathName())); + rtn = CommonDialogMgr::MoveAFile(m_hWnd, source_file, wstring(folderPickerDlg.GetPathName())); } if (rtn == ERROR_SUCCESS) { @@ -4838,21 +4717,6 @@ void CMusicPlayerDlg::OnMoveFileTo() } -//afx_msg LRESULT CMusicPlayerDlg::OnOpenFileCommandLine(WPARAM wParam, LPARAM lParam) -//{ -// wstring cmd_line = CCommon::GetStringFromClipboard(); -// if (cmd_line.empty()) -// return 0; -// vector files; -// CCommon::DisposeCmdLineFiles(wstring(cmd_line), files); -// if (!files.empty() && CPlaylistFile::IsPlaylistFile(files[0])) -// CPlayer::GetInstance().OpenPlaylistFile(files[0]); -// else -// CPlayer::GetInstance().OpenFiles(files); -// return 0; -//} - - void CMusicPlayerDlg::OnFormatConvert() { // TODO: 在此添加命令处理程序代码 @@ -4887,14 +4751,6 @@ afx_msg LRESULT CMusicPlayerDlg::OnSettingsApplied(WPARAM wParam, LPARAM lParam) } -void CMusicPlayerDlg::OnRecorder() -{ - // TODO: 在此添加命令处理程序代码 - CRecorderDlg dlg; - dlg.DoModal(); -} - - afx_msg LRESULT CMusicPlayerDlg::OnAlbumCoverDownloadComplete(WPARAM wParam, LPARAM lParam) { //由于此函数放到线程中处理时,拉伸图片的处理CDrawCommon::BitmapStretch有一定的概率出错,原因未知 @@ -4982,32 +4838,12 @@ void CMusicPlayerDlg::OnSwitchUi() void CMusicPlayerDlg::OnVolumeUp() { - if (m_miniModeDlg.m_hWnd == NULL) - { - CPlayer::GetInstance().MusicControl(Command::VOLUME_UP, theApp.m_nc_setting_data.volum_step); - CUserUi* cur_ui{ dynamic_cast(GetCurrentUi()) }; - if (cur_ui != nullptr) - cur_ui->VolumeAdjusted(); - } - else - { - m_miniModeDlg.SetVolume(true); - } + AdjustVolume(theApp.m_nc_setting_data.volum_step); } void CMusicPlayerDlg::OnVolumeDown() { - if (m_miniModeDlg.m_hWnd == NULL) - { - CPlayer::GetInstance().MusicControl(Command::VOLUME_DOWN, theApp.m_nc_setting_data.volum_step); - CUserUi* cur_ui{ dynamic_cast(GetCurrentUi()) }; - if (cur_ui != nullptr) - cur_ui->VolumeAdjusted(); - } - else - { - m_miniModeDlg.SetVolume(false); - } + AdjustVolume(-theApp.m_nc_setting_data.volum_step); } @@ -5023,14 +4859,7 @@ afx_msg LRESULT CMusicPlayerDlg::OnNotifyicon(WPARAM wParam, LPARAM lParam) if (lParam == WM_LBUTTONUP && m_miniModeDlg.m_hWnd == NULL) { -#ifndef COMPILE_IN_WIN_XP - if (IsTaskbarListEnable()) - { - m_pTaskbar->ThumbBarAddButtons(m_hWnd, 3, m_thumbButton); //重新添加任务栏缩略图按钮 - SetThumbnailClipArea(); //重新设置任务栏缩略图 - } -#endif - UpdatePlayPauseButton(); + TaskBarInit(); } return 0; @@ -5050,7 +4879,11 @@ void CMusicPlayerDlg::OnCancel() // TODO: 在此添加专用代码和/或调用基类 if (theApp.m_general_setting_data.minimize_to_notify_icon) { - Show(false); + ShowWindow(SW_HIDE); + if (IsFloatPlaylistExist()) + { + m_pFloatPlaylistDlg->ShowWindow(SW_HIDE); + } } else { @@ -5124,7 +4957,7 @@ void CMusicPlayerDlg::OnAppCommand(CWnd* pWnd, UINT nCmd, UINT nDevice, UINT nKe void CMusicPlayerDlg::OnShowPlaylist() { // TODO: 在此添加命令处理程序代码 - //if (theApp.m_nc_setting_data.playlist_btn_for_float_playlist) + //if (theApp.m_media_lib_setting_data.playlist_btn_for_float_playlist) // ShowHideFloatPlaylist(); //else // ShowHidePlaylist(); @@ -5172,7 +5005,8 @@ void CMusicPlayerDlg::OnShowMenuBar() { if (theApp.m_nc_setting_data.show_hide_menu_bar_tip) { - if (MessageBox(CCommon::LoadText(IDS_HIDE_MENU_BAR_TIP), NULL, MB_ICONINFORMATION | MB_OKCANCEL) == IDCANCEL) + const wstring& info = theApp.m_str_table.LoadText(L"MSG_HIDE_MENU_BAR_INFO"); + if (MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OKCANCEL) == IDCANCEL) theApp.m_nc_setting_data.show_hide_menu_bar_tip = false; } } @@ -5215,28 +5049,41 @@ void CMusicPlayerDlg::OnCreatePlayShortcut() { // TODO: 在此添加命令处理程序代码 - if (MessageBox(CCommon::LoadText(IDS_CREATE_PLAY_SHORTCUT_INFO), NULL, MB_ICONQUESTION | MB_OKCANCEL) == IDOK) + const wstring& create_info = theApp.m_str_table.LoadText(L"MSG_SHORTCUT_INQUARY_PLAY_CONTROL"); + if (MessageBox(create_info.c_str(), NULL, MB_ICONQUESTION | MB_OKCANCEL) == IDOK) { - //创建播放/暂停快捷方式 - wstring play_pause{ CCommon::LoadText(IDS_PLAY_PAUSE, L".lnk") }; - CCommon::FileNameNormalize(play_pause); - bool success = true; - success &= CCommon::CreateFileShortcut(theApp.m_module_dir.c_str(), NULL, play_pause.c_str(), NULL, 0, 0, 1, L"-play_pause", 2); + wstring lnk_name; + //创建播放/暂停快捷方式 + lnk_name = theApp.m_str_table.LoadText(L"UI_TIP_BTN_PLAY_PAUSE") + L".lnk"; + CCommon::FileNameNormalize(lnk_name); + success &= CCommon::CreateFileShortcut(theApp.m_module_dir.c_str(), NULL, lnk_name.c_str(), NULL, 0, 0, 1, L"-play_pause", 2); //创建上一曲快捷方式 - success &= CCommon::CreateFileShortcut(theApp.m_module_dir.c_str(), NULL, CCommon::LoadText(IDS_PREVIOUS, L".lnk"), NULL, 0, 0, 1, L"-previous", 1); + lnk_name = theApp.m_str_table.LoadText(L"UI_TIP_BTN_PREVIOUS") + L".lnk"; + CCommon::FileNameNormalize(lnk_name); + success &= CCommon::CreateFileShortcut(theApp.m_module_dir.c_str(), NULL, lnk_name.c_str(), NULL, 0, 0, 1, L"-previous", 1); //创建下一曲快捷方式 - success &= CCommon::CreateFileShortcut(theApp.m_module_dir.c_str(), NULL, CCommon::LoadText(IDS_NEXT, L".lnk"), NULL, 0, 0, 1, L"-next", 3); + lnk_name = theApp.m_str_table.LoadText(L"UI_TIP_BTN_NEXT") + L".lnk"; + CCommon::FileNameNormalize(lnk_name); + success &= CCommon::CreateFileShortcut(theApp.m_module_dir.c_str(), NULL, lnk_name.c_str(), NULL, 0, 0, 1, L"-next", 3); //创建停止快捷方式 - success &= CCommon::CreateFileShortcut(theApp.m_module_dir.c_str(), NULL, CCommon::LoadText(IDS_STOP, L".lnk"), NULL, 0, 0, 1, L"-stop", 6); + lnk_name = theApp.m_str_table.LoadText(L"UI_TIP_BTN_STOP") + L".lnk"; + CCommon::FileNameNormalize(lnk_name); + success &= CCommon::CreateFileShortcut(theApp.m_module_dir.c_str(), NULL, lnk_name.c_str(), NULL, 0, 0, 1, L"-stop", 6); if (success) - MessageBox(CCommon::LoadTextFormat(IDS_PLAY_SHORTCUT_CREATED, { theApp.m_module_dir }), NULL, MB_ICONINFORMATION); + { + wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_SHORTCUT_CREATED", { theApp.m_module_dir }); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION); + } else - MessageBox(CCommon::LoadText(IDS_SHORTCUT_CREAT_FAILED), NULL, MB_ICONWARNING); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_SHORTCUT_FAILED"); + MessageBox(info.c_str(), NULL, MB_ICONWARNING); + } } } @@ -5268,7 +5115,7 @@ afx_msg LRESULT CMusicPlayerDlg::OnMainMenuPopup(WPARAM wParam, LPARAM lParam) { CPoint point = *((CPoint*)wParam); ClientToScreen(&point); - theApp.m_menu_set.m_main_menu_popup.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this); + theApp.m_menu_mgr.GetMenu(MenuMgr::MainPopupMenu)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this); return 0; } @@ -5286,8 +5133,8 @@ void CMusicPlayerDlg::OnAlwaysOnTop() void CMusicPlayerDlg::OnFloatPlaylist() { // TODO: 在此添加命令处理程序代码 - //theApp.m_nc_setting_data.playlist_btn_for_float_playlist = !theApp.m_nc_setting_data.playlist_btn_for_float_playlist; - //if (theApp.m_nc_setting_data.playlist_btn_for_float_playlist) + //theApp.m_media_lib_setting_data.playlist_btn_for_float_playlist = !theApp.m_media_lib_setting_data.playlist_btn_for_float_playlist; + //if (theApp.m_media_lib_setting_data.playlist_btn_for_float_playlist) //{ // //改为浮动播放列表时,如果显示了停靠的播放列表,则显示浮动播放列表,隐藏停靠播放列表 // if (theApp.m_ui_data.show_playlist) @@ -5310,7 +5157,7 @@ void CMusicPlayerDlg::OnFloatPlaylist() void CMusicPlayerDlg::OnDockedPlaylist() { // TODO: 在此添加命令处理程序代码 - theApp.m_nc_setting_data.playlist_btn_for_float_playlist = false; + theApp.m_media_lib_setting_data.playlist_btn_for_float_playlist = false; auto ui{ GetCurrentUi() }; if (ui != nullptr) ui->UpdatePlaylistBtnToolTip(); @@ -5320,7 +5167,7 @@ void CMusicPlayerDlg::OnDockedPlaylist() void CMusicPlayerDlg::OnFloatedPlaylist() { // TODO: 在此添加命令处理程序代码 - theApp.m_nc_setting_data.playlist_btn_for_float_playlist = true; + theApp.m_media_lib_setting_data.playlist_btn_for_float_playlist = true; auto ui{ GetCurrentUi() }; if (ui != nullptr) ui->UpdatePlaylistBtnToolTip(); @@ -5348,15 +5195,21 @@ void CMusicPlayerDlg::OnPlaylistAddFile() return; vector files; - wstring filter = CAudioCommon::GetFileDlgFilter(); + wstring filter = FilterHelper::GetAudioFileFilter(); CCommon::DoOpenFileDlg(filter, files, this); if (!files.empty()) { int rtn = CPlayer::GetInstance().AddFilesToPlaylist(files); if (rtn == 0) - MessageBox(CCommon::LoadText(IDS_FILE_EXIST_IN_PLAYLIST_INFO), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_FILE_EXIST_IN_PLAYLIST"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } else if(rtn == -1) - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } } } @@ -5372,7 +5225,8 @@ void CMusicPlayerDlg::OnRemoveFromPlaylist() void CMusicPlayerDlg::OnEmptyPlaylist() { // TODO: 在此添加命令处理程序代码 - if (MessageBox(CCommon::LoadText(IDS_CLEAR_PLAYLIST_WARNING), NULL, MB_ICONQUESTION | MB_OKCANCEL) == IDOK) + const wstring& info = theApp.m_str_table.LoadText(L"MSG_PLAYLIST_CLEAR_WARNING"); + if (MessageBox(info.c_str(), NULL, MB_ICONQUESTION | MB_OKCANCEL) == IDOK) { CPlayer::GetInstance().ClearPlaylist(); ShowPlayList(); @@ -5455,7 +5309,8 @@ void CMusicPlayerDlg::OnRemoveSameSongs() { ShowPlayList(); } - MessageBox(CCommon::LoadTextFormat(IDS_REMOVE_SAME_SONGS_INFO, { removed }), NULL, MB_ICONINFORMATION | MB_OK); + wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_PLAYLIST_REMOVE_SONGS", { removed }); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); } @@ -5502,13 +5357,16 @@ void CMusicPlayerDlg::OnPlaylistAddFolder() return; static bool include_sub_dir{ false }; + static CString include_sub_dir_str{ theApp.m_str_table.LoadText(L"TXT_FOLDER_BROWSER_INCLUDE_SUB_DIR").c_str() }; + const wstring& title = theApp.m_str_table.LoadText(L"TITLE_FOLDER_BROWSER_SONG_SOURCE"); #ifdef COMPILE_IN_WIN_XP CFolderBrowserDlg folderPickerDlg(this->GetSafeHwnd()); - folderPickerDlg.SetInfo(CCommon::LoadText(IDS_OPEN_FOLDER_INFO)); + folderPickerDlg.SetInfo(title.c_str()); #else CFilePathHelper current_path(CPlayer::GetInstance().GetCurrentDir()); CFolderPickerDialog folderPickerDlg(current_path.GetParentDir().c_str()); - folderPickerDlg.AddCheckButton(IDC_OPEN_CHECKBOX, CCommon::LoadText(IDS_INCLUDE_SUB_DIR), include_sub_dir); //在打开对话框中添加一个复选框 + folderPickerDlg.m_ofn.lpstrTitle = title.c_str(); + folderPickerDlg.AddCheckButton(IDC_OPEN_CHECKBOX, include_sub_dir_str, include_sub_dir); //在打开对话框中添加一个复选框 #endif if (folderPickerDlg.DoModal() == IDOK) { @@ -5528,9 +5386,15 @@ void CMusicPlayerDlg::OnPlaylistAddFolder() } int rtn = CPlayer::GetInstance().AddFilesToPlaylist(file_list); if (rtn == 0) - MessageBox(CCommon::LoadText(IDS_FILE_EXIST_IN_PLAYLIST_INFO), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_FILE_EXIST_IN_PLAYLIST"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } else if (rtn == -1) - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } } } @@ -5544,7 +5408,8 @@ void CMusicPlayerDlg::OnRemoveInvalidItems() { ShowPlayList(); } - MessageBox(CCommon::LoadTextFormat(IDS_REMOVE_SAME_SONGS_INFO, { removed }), NULL, MB_ICONINFORMATION | MB_OK); + wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_PLAYLIST_REMOVE_SONGS", { removed }); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); } @@ -5592,7 +5457,8 @@ void CMusicPlayerDlg::OnAddRemoveFromFavourite() if (CPlayer::GetInstance().IsPlaylistMode() && CPlaylistMgr::Instance().m_cur_playlist_type == PT_FAVOURITE) { //如果当前播放列表就是“我喜欢”播放列表,则直接将当前歌曲从列表中移除 - if (MessageBox(CCommon::LoadText(IDS_REMOVE_MY_FAVOURITE_WARNING), NULL, MB_ICONINFORMATION | MB_OKCANCEL) == IDOK) + const wstring& info = theApp.m_str_table.LoadText(L"MSG_REMOVE_FAVOURITE_WARNING"); + if (MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OKCANCEL) == IDOK) { CPlayer::GetInstance().RemoveSong(CPlayer::GetInstance().GetIndex()); ShowPlayList(); @@ -5629,20 +5495,24 @@ void CMusicPlayerDlg::OnFileOpenUrl() { // TODO: 在此添加命令处理程序代码 CInputDlg input_dlg; - input_dlg.SetTitle(CCommon::LoadText(IDS_OPEN_URL)); - input_dlg.SetInfoText(CCommon::LoadText(IDS_INPUT_URL_TIP)); + input_dlg.SetTitle(theApp.m_str_table.LoadText(L"TITLE_INPUT_URL_OPEN_URL").c_str()); + input_dlg.SetInfoText(theApp.m_str_table.LoadText(L"TXT_INPUT_URL_INPUT_URL").c_str()); if (input_dlg.DoModal() == IDOK) { wstring strUrl = input_dlg.GetEditText().GetString(); if (!CCommon::IsURL(strUrl)) { - MessageBox(CCommon::LoadText(IDS_URL_INVALID_WARNING), NULL, MB_ICONWARNING | MB_OK); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_INPUT_URL_INVALID_WARNING"); + MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK); return; } vector vecUrl; vecUrl.push_back(strUrl); if (!CPlayer::GetInstance().OpenFilesInDefaultPlaylist(vecUrl)) - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } } } @@ -5654,23 +5524,30 @@ void CMusicPlayerDlg::OnPlaylistAddUrl() return; CInputDlg input_dlg; - input_dlg.SetTitle(CCommon::LoadText(IDS_ADD_URL)); - input_dlg.SetInfoText(CCommon::LoadText(IDS_INPUT_URL_TIP)); + input_dlg.SetTitle(theApp.m_str_table.LoadText(L"TITLE_INPUT_URL_ADD_URL").c_str()); + input_dlg.SetInfoText(theApp.m_str_table.LoadText(L"TXT_INPUT_URL_INPUT_URL").c_str()); if (input_dlg.DoModal() == IDOK) { wstring strUrl = input_dlg.GetEditText().GetString(); if (!CCommon::IsURL(strUrl)) { - MessageBox(CCommon::LoadText(IDS_URL_INVALID_WARNING), NULL, MB_ICONWARNING | MB_OK); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_INPUT_URL_INVALID_WARNING"); + MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK); return; } vector vecUrl; vecUrl.push_back(strUrl); int rtn = CPlayer::GetInstance().AddFilesToPlaylist(vecUrl); if (rtn == 0) - MessageBox(CCommon::LoadText(IDS_FILE_EXIST_IN_PLAYLIST_INFO), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_FILE_EXIST_IN_PLAYLIST"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } else if (rtn == -1) - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } } } @@ -5689,12 +5566,12 @@ void CMusicPlayerDlg::OnLockDesktopLryic() // TODO: 在此添加命令处理程序代码 theApp.m_lyric_setting_data.desktop_lyric_data.lock_desktop_lyric = !theApp.m_lyric_setting_data.desktop_lyric_data.lock_desktop_lyric; m_desktop_lyric.SetLyricWindowLock(theApp.m_lyric_setting_data.desktop_lyric_data.lock_desktop_lyric); - CString strTip; + wstring tip_str; if (theApp.m_lyric_setting_data.desktop_lyric_data.lock_desktop_lyric) - strTip = CCommon::LoadText(IDS_ULOCK_DESKTOP_LYRIC); + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_DESKTOP_LYRIC_UNLOCK"); else - strTip = CCommon::LoadText(IDS_LOCK_DESKTOP_LYRIC); - m_desktop_lyric.UpdateMouseToolTip(CDesktopLyric::BTN_LOCK, strTip); + tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_DESKTOP_LYRIC_LOCK"); + m_desktop_lyric.UpdateMouseToolTip(CDesktopLyric::BTN_LOCK, tip_str.c_str()); } @@ -5895,11 +5772,10 @@ void CMusicPlayerDlg::OnSaveCurrentPlaylistAs() { playlist_name = CFilePathHelper(playlist_name).GetFolderName(); } - CFileDialog fileDlg(FALSE, _T("m3u"), playlist_name.c_str(), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, CCommon::LoadText(IDS_SAVE_PLAYLIST_FILTER), this); + wstring filter = FilterHelper::GetPlaylistSaveAsFilter(); + CFileDialog fileDlg(FALSE, _T("m3u"), playlist_name.c_str(), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, filter.c_str(), this); if (IDOK == fileDlg.DoModal()) { - CPlaylistFile playlist; - playlist.FromSongList(CPlayer::GetInstance().GetPlayList()); //获取当前播放列表 //将当前播放列表保存到文件 wstring file_path{ fileDlg.GetPathName() }; wstring file_extension{ fileDlg.GetFileExt() }; @@ -5911,7 +5787,7 @@ void CMusicPlayerDlg::OnSaveCurrentPlaylistAs() file_type = CPlaylistFile::PL_M3U; else if (file_extension == L".m3u8") file_type = CPlaylistFile::PL_M3U8; - playlist.SaveToFile(file_path, file_type); + CPlaylistFile::SavePlaylistToFile(CPlayer::GetInstance().GetPlayList(), file_path, file_type); } } @@ -5921,27 +5797,23 @@ void CMusicPlayerDlg::OnFileOpenPlaylist() { // TODO: 在此添加命令处理程序代码 //设置过滤器 - CString szFilter = CCommon::LoadText(IDS_PLAYLIST_FILE_FILTER); + wstring filter = FilterHelper::GetPlaylistSelectFilter(); //构造打开文件对话框 - CFileDialog fileDlg(TRUE, NULL, NULL, 0, szFilter, this); + CFileDialog fileDlg(TRUE, NULL, NULL, 0, filter.c_str(), this); //显示打开文件对话框 if (IDOK == fileDlg.DoModal()) { wstring file_path{ fileDlg.GetPathName() }; if (!CPlayer::GetInstance().OpenPlaylistFile(file_path)) - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } } } -//void CMusicPlayerDlg::OnExportCurrentPlaylist() -//{ -// // TODO: 在此添加命令处理程序代码 -// -//} - - void CMusicPlayerDlg::OnSaveAsNewPlaylist() { // TODO: 在此添加命令处理程序代码 @@ -5958,18 +5830,18 @@ void CMusicPlayerDlg::OnSaveAsNewPlaylist() void CMusicPlayerDlg::OnCreateDesktopShortcut() { - // TODO: 在此添加命令处理程序代码 - if (MessageBox(CCommon::LoadText(IDS_CREATE_DESKTOP_SHORTCUT_INFO), NULL, MB_ICONQUESTION | MB_OKCANCEL) == IDOK) + const wstring& create_info = theApp.m_str_table.LoadText(L"MSG_SHORTCUT_INQUARY_DESKTOP"); + if (MessageBox(create_info.c_str(), NULL, MB_ICONQUESTION | MB_YESNO) == IDYES) { if (CCommon::CreateFileShortcut(theApp.m_desktop_path.c_str(), NULL, _T("MusicPlayer2.lnk"))) { - CString info; - info = CCommon::LoadTextFormat(IDS_SHORTCUT_CREATED, { theApp.m_desktop_path }); - MessageBox(info, NULL, MB_ICONINFORMATION); + wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_SHORTCUT_CREATED", { theApp.m_desktop_path }); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION); } else { - MessageBox(CCommon::LoadText(IDS_SHORTCUT_CREAT_FAILED), NULL, MB_ICONWARNING); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_SHORTCUT_FAILED"); + MessageBox(info.c_str(), NULL, MB_ICONWARNING); } } } @@ -5977,17 +5849,22 @@ void CMusicPlayerDlg::OnCreateDesktopShortcut() void CMusicPlayerDlg::OnCreateMiniModeShortCut() { - // TODO: 在此添加命令处理程序代码 - - if (MessageBox(CCommon::LoadText(IDS_CREATE_MINI_MODE_SHORTCUT_INFO), NULL, MB_ICONQUESTION | MB_OKCANCEL) == IDOK) + const wstring& create_info = theApp.m_str_table.LoadText(L"MSG_SHORTCUT_INQUARY_MINIMODE"); + if (MessageBox(create_info.c_str(), NULL, MB_ICONQUESTION | MB_YESNO) == IDYES) { - CString file_name = CCommon::LoadText(IDS_MINI_MODE, L".lnk"); - if (CCommon::CreateFileShortcut(theApp.m_module_dir.c_str(), NULL, file_name, NULL, 0, 0, 1, L"-mini")) - MessageBox(CCommon::LoadTextFormat(IDS_SHORTCUT_CREATED, { theApp.m_module_dir }), NULL, MB_ICONINFORMATION); + wstring file_name = theApp.m_str_table.LoadText(L"UI_TIP_BTN_MINIMODE") + L".lnk"; + CCommon::FileNameNormalize(file_name); + if (CCommon::CreateFileShortcut(theApp.m_module_dir.c_str(), NULL, file_name.c_str(), NULL, 0, 0, 1, L"-mini")) + { + wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_SHORTCUT_CREATED", { theApp.m_desktop_path }); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION); + } else - MessageBox(CCommon::LoadText(IDS_SHORTCUT_CREAT_FAILED), NULL, MB_ICONWARNING); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_SHORTCUT_FAILED"); + MessageBox(info.c_str(), NULL, MB_ICONWARNING); + } } - } @@ -6007,13 +5884,12 @@ void CMusicPlayerDlg::OnDeleteCurrentFromDisk() // TODO: 在此添加命令处理程序代码 if (theApp.m_media_lib_setting_data.disable_delete_from_disk) return; - CString info; SongInfo song = CPlayer::GetInstance().GetCurrentSongInfo(); wstring file_path = song.file_path; if (file_path.empty() || song.is_cue || COSUPlayerHelper::IsOsuFile(file_path)) return; - info = CCommon::LoadTextFormat(IDS_DELETE_SINGLE_FILE_INQUIRY, { file_path }); - if (MessageBox(info, NULL, MB_ICONWARNING | MB_OKCANCEL) != IDOK) + wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_DELETE_SINGLE_FILE_INQUARY", { file_path }); + if (MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OKCANCEL) != IDOK) return; if (!CPlayer::GetInstance().GetPlayStatusMutex().try_lock_for(std::chrono::milliseconds(1000))) return; bool file_exist = CCommon::FileExist(file_path); @@ -6021,7 +5897,7 @@ void CMusicPlayerDlg::OnDeleteCurrentFromDisk() if (file_exist) { CPlayer::GetInstance().MusicControl(Command::CLOSE); - rtn = CCommon::DeleteAFile(m_hWnd, file_path); + rtn = CommonDialogMgr::DeleteAFile(m_hWnd, file_path); } if (rtn == ERROR_SUCCESS || !file_exist) { @@ -6033,8 +5909,8 @@ void CMusicPlayerDlg::OnDeleteCurrentFromDisk() DrawInfo(true); //文件删除后同时删除和文件同名的图片文件和歌词文件 CFilePathHelper file_path(file_path); - CCommon::DeleteAFile(m_hWnd, file_path.ReplaceFileExtension(L"jpg").c_str()); - CCommon::DeleteAFile(m_hWnd, file_path.ReplaceFileExtension(L"lrc").c_str()); + CommonDialogMgr::DeleteAFile(m_hWnd, file_path.ReplaceFileExtension(L"jpg").c_str()); + CommonDialogMgr::DeleteAFile(m_hWnd, file_path.ReplaceFileExtension(L"lrc").c_str()); } else if (rtn == ERROR_CANCELLED) //如果在弹出的对话框中点击“取消”则返回值为1223 { @@ -6049,7 +5925,7 @@ void CMusicPlayerDlg::OnDeleteCurrentFromDisk() else { CPlayer::GetInstance().GetPlayStatusMutex().unlock(); - MessageBox(CCommon::LoadText(IDS_CONNOT_DELETE_FILE), NULL, MB_ICONWARNING); + MessageBox(theApp.m_str_table.LoadText(L"MSG_DELETE_FILE_FAILED").c_str(), NULL, MB_ICONWARNING); } } @@ -6164,13 +6040,7 @@ void CMusicPlayerDlg::OnShowDesktopLyric() afx_msg LRESULT CMusicPlayerDlg::OnMainWindowActivated(WPARAM wParam, LPARAM lParam) { -#ifndef COMPILE_IN_WIN_XP - if (IsTaskbarListEnable()) - { - m_pTaskbar->ThumbBarAddButtons(m_hWnd, 3, m_thumbButton); //重新添加任务栏缩略图按钮 - SetThumbnailClipArea(); //重新设置任务栏缩略图 - } -#endif + TaskBarInit(); return 0; } @@ -6179,7 +6049,10 @@ void CMusicPlayerDlg::OnContainSubFolder() { // TODO: 在此添加命令处理程序代码 if (!CPlayer::GetInstance().SetContainSubFolder()) - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } } @@ -6190,44 +6063,6 @@ afx_msg LRESULT CMusicPlayerDlg::OnGetMusicCurrentPosition(WPARAM wParam, LPARAM } -void CMusicPlayerDlg::OnAccendingOrder() -{ - // TODO: 在此添加命令处理程序代码 - if (!CPlayer::GetInstance().IsPlaylistMode()) - { - //文件夹模式下按升序排列 - CPlayer::GetInstance().m_descending = false; - CPlayer::GetInstance().SortPlaylist(); - ShowPlayList(); - } -} - - -void CMusicPlayerDlg::OnDesendingOrder() -{ - // TODO: 在此添加命令处理程序代码 - if (!CPlayer::GetInstance().IsPlaylistMode()) - { - //文件夹模式下降序排列 - CPlayer::GetInstance().m_descending = true; - CPlayer::GetInstance().SortPlaylist(); - ShowPlayList(); - } -} - - -void CMusicPlayerDlg::OnInvertPlaylist() -{ - // TODO: 在此添加命令处理程序代码 - //播放列表模式下将播放列表倒序 - if (CPlayer::GetInstance().IsPlaylistMode()) - { - CPlayer::GetInstance().InvertPlaylist(); - ShowPlayList(); - } -} - - afx_msg LRESULT CMusicPlayerDlg::OnCurrentFileAlbumCoverChanged(WPARAM wParam, LPARAM lParam) { @@ -6238,52 +6073,44 @@ afx_msg LRESULT CMusicPlayerDlg::OnCurrentFileAlbumCoverChanged(WPARAM wParam, L void CMusicPlayerDlg::OnRename() { // TODO: 在此添加命令处理程序代码 - CTagFromFileNameDlg dlg; - dlg.SetDialogTitle(CCommon::LoadText(IDS_RENAME)); - if (dlg.DoModal() == IDOK) + int count{}, fail_count{}; + CRenameDlg dlg; + auto& cur_playlist = CPlayer::GetInstance().GetPlayList(); + // 单选曲目重命名时建议当前名称 + if (m_items_selected.size() <= 1 && m_item_selected >= 0 && m_item_selected < static_cast(cur_playlist.size())) + dlg.SetInitInsertFormular(CFilePathHelper(cur_playlist[m_item_selected].file_path).GetFileNameWithoutExtension()); + if (dlg.DoModal() != IDOK) + return; + wstring formular = dlg.GetFormularSelected(); + for (int index : m_items_selected) { - int count{}; - int ignore_count{}; - for (int index : m_items_selected) - { - if (index >= 0 && index < CPlayer::GetInstance().GetSongNum()) - { - SongInfo& song{ CPlayer::GetInstance().GetPlayList()[index] }; - if (!song.is_cue && !COSUPlayerHelper::IsOsuFile(song.file_path)) - { - wstring new_name = CPropertyDlgHelper::FileNameFromTag(dlg.GetFormularSelected(), song); - CPlayer::ReOpen reopen(song.IsSameSong(CPlayer::GetInstance().GetCurrentSongInfo())); - if (reopen.IsLockSuccess()) // 这个一般来说是绝对成功的不过确实存在失败的情况 - { - wstring new_file_path = CCommon::FileRename(song.file_path, new_name); - if (!new_file_path.empty()) - { - CSongDataManager::GetInstance().ChangeFilePath(song.file_path, new_file_path); - song.file_path = new_file_path; - ++count; - } - } - else - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); - } - else - { - ignore_count++; - } - } - } - - if (count > 0) + if (index < 0 || index >= static_cast(cur_playlist.size())) + continue; + SongInfo& song = cur_playlist[index]; + if (song.is_cue || COSUPlayerHelper::IsOsuFile(song.file_path)) + continue; + CPlayer::ReOpen reopen(song.IsSameSong(CPlayer::GetInstance().GetCurrentSongInfo())); + if (!reopen.IsLockSuccess()) + continue; + wstring new_name = CRenameDlg::FileNameFromTag(formular, song); + wstring new_file_path = CCommon::FileRename(song.file_path, new_name); + if (!new_file_path.empty()) { - //重命名成功,刷新播放列表 - ShowPlayList(false); - CPlayer::GetInstance().SaveCurrentPlaylist(); + CSongDataManager::GetInstance().ChangeFilePath(song.file_path, new_file_path); + song.file_path = new_file_path; + ++count; } - - CString info; - info = CCommon::LoadTextFormat(IDS_RENAME_INFO, { m_items_selected.size(), count, ignore_count, static_cast(m_items_selected.size()) - count - ignore_count }); - MessageBox(info, NULL, MB_ICONINFORMATION | MB_OK); + else + ++fail_count; + } + if (count > 0) //重命名成功,刷新播放列表 + { + ShowPlayList(false); + CPlayer::GetInstance().SaveCurrentPlaylist(); } + wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_RENAME_SONG_COMPLETED_INFO", + { m_items_selected.size(), count, static_cast(m_items_selected.size()) - count - fail_count, fail_count }); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); } @@ -6307,11 +6134,15 @@ void CMusicPlayerDlg::OnEmbedLyricToAudioFile() failed = !audio_tag.WriteAudioLyric(lyric_contents); } else - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } } if (failed) { - MessageBox(CCommon::LoadText(IDS_CANNOT_WRITE_TO_FILE), NULL, MB_ICONWARNING | MB_OK); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_FILE_WRITE_FAILED"); + MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK); } } } @@ -6334,11 +6165,15 @@ void CMusicPlayerDlg::OnDeleteLyricFromAudioFile() failed = !audio_tag.WriteAudioLyric(wstring()); } else - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } } if (failed) { - MessageBox(CCommon::LoadText(IDS_CANNOT_WRITE_TO_FILE), NULL, MB_ICONWARNING | MB_OK); + const wstring& info = theApp.m_str_table.LoadText(L"MSG_FILE_WRITE_FAILED"); + MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK); } } @@ -6382,7 +6217,7 @@ void CMusicPlayerDlg::OnLocateToCurrent() m_pFloatPlaylistDlg->GetListCtrl().EnsureVisible(CPlayer::GetInstance().GetIndex(), FALSE); CUserUi* user_ui{ dynamic_cast(GetCurrentUi()) }; if (user_ui != nullptr) - user_ui->PlaylistLocateToCurrent(); + user_ui->PlaylistLocateToIndex(CPlayer::GetInstance().GetIndex()); } @@ -6578,71 +6413,25 @@ bool CMusicPlayerDlg::IsPointValid(CPoint point) afx_msg LRESULT CMusicPlayerDlg::OnRecentFolderOrPlaylistChanged(WPARAM wParam, LPARAM lParam) { //初始化点击文件夹/播放列表右侧按钮弹出的菜单 - //检查菜单项目是否有改变 - bool menu_changed{ false }; - int menu_size{}; - if (::IsMenu(theApp.m_menu_set.m_recent_folder_playlist_menu.GetSafeHmenu())) - menu_size = theApp.m_menu_set.m_recent_folder_playlist_menu.GetMenuItemCount(); - else - menu_changed = true; - for (int i{}; i < menu_size; i++) + vector menu_list; + const auto& list = CRecentFolderAndPlaylist::Instance().GetItemList(); + for (const auto& item : list) { - CString str_menu_name; - theApp.m_menu_set.m_recent_folder_playlist_menu.GetMenuString(i, str_menu_name, MF_BYPOSITION); - if (i < static_cast(CRecentFolderAndPlaylist::Instance().GetItemList().size())) + if (item.LastPlayedTime() == 0) + break; + if (menu_list.size() >= RECENT_FOLDER_PLAYLIST_MAX_SIZE) + break; + UINT id = ID_RECENT_FOLDER_PLAYLIST_MENU_START + menu_list.size(); + if (item.is_playlist) { - if (str_menu_name != CRecentFolderAndPlaylist::Instance().GetItemList()[i].GetName().c_str()) - menu_changed = true; - } - } - if (menu_changed) - { - //CMenuIcon类中缓存了所有菜单的位图对象,因此这里不再需要销毁菜单中的位图对象 - ////销毁菜单前先销毁菜单中的位图对象 - //for (int i{}; i < menu_size; i++) - //{ - // MENUITEMINFO mii{}; - // mii.cbSize = sizeof(MENUITEMINFO); - // mii.fMask = MIIM_BITMAP; - // theApp.m_menu_set.m_recent_folder_playlist_menu.GetMenuItemInfo(i, &mii, TRUE); - // if (mii.hbmpItem != nullptr) - // DeleteObject(mii.hbmpItem); - //} - theApp.m_menu_set.m_recent_folder_playlist_menu.DestroyMenu(); - theApp.m_menu_set.m_recent_folder_playlist_menu.CreatePopupMenu(); - int item_count{}; - for (int i{}; i < static_cast(CRecentFolderAndPlaylist::Instance().GetItemList().size()) && i < RECENT_FOLDER_PLAYLIST_MAX_SIZE; i++) - { - const auto& item{ CRecentFolderAndPlaylist::Instance().GetItemList()[i] }; - if (item.LastPlayedTime() == 0) - break; - wstring item_name{ item.GetName() }; - theApp.m_menu_set.m_recent_folder_playlist_menu.AppendMenu(MF_STRING | MF_ENABLED, ID_RECENT_FOLDER_PLAYLIST_MENU_START + i, item_name.c_str()); - item_count++; - } - theApp.m_menu_set.m_recent_folder_playlist_menu.AppendMenu(MF_SEPARATOR); - theApp.m_menu_set.m_recent_folder_playlist_menu.AppendMenu(MF_STRING | MF_ENABLED, ID_SET_PATH, CCommon::LoadText(IDS_MEDIA_LIB, _T("..."))); - - //设置菜单图标 - for (int i{}; i < item_count; i++) - { - const auto& item{ CRecentFolderAndPlaylist::Instance().GetItemList()[i] }; - HICON icon{}; - if (item.is_playlist) - { - if (item.playlist_info->path == CPlaylistMgr::Instance().m_favourite_playlist.path) - icon = theApp.m_icon_set.favourite.GetIcon(true); - else - icon = theApp.m_icon_set.show_playlist.GetIcon(true); - } - else - { - icon = theApp.m_icon_set.select_folder.GetIcon(true); - } - CMenuIcon::AddIconToMenuItem(theApp.m_menu_set.m_recent_folder_playlist_menu.GetSafeHmenu(), i, TRUE, icon); + bool is_favourite{ item.playlist_info->path == CPlaylistMgr::Instance().m_favourite_playlist.path }; + menu_list.emplace_back(MenuMgr::MenuItem{ id, is_favourite ? IconMgr::IconType::IT_Favorite_On : IconMgr::IconType::IT_Playlist, item.GetName() }); } - CMenuIcon::AddIconToMenuItem(theApp.m_menu_set.m_recent_folder_playlist_menu.GetSafeHmenu(), ID_SET_PATH, FALSE, theApp.m_icon_set.media_lib.GetIcon(true)); + else + menu_list.emplace_back(MenuMgr::MenuItem{ id, IconMgr::IconType::IT_Folder, item.GetName() }); } + theApp.m_menu_mgr.UpdateMenu(MenuMgr::RecentFolderPlaylistMenu, menu_list); + return 0; } @@ -6655,11 +6444,13 @@ void CMusicPlayerDlg::OnPlayAsNext() { void CMusicPlayerDlg::OnPlaylistFixPathError() { - if (MessageBox(CCommon::LoadText(IDS_PLAYLIST_FIX_PATH_ERROR_INFO), NULL, MB_ICONQUESTION | MB_YESNO) == IDYES) + const wstring& inquary_info = theApp.m_str_table.LoadText(L"MSG_PLAYLIST_FIX_ERROR_PATH_INQUARY"); + if (MessageBox(inquary_info.c_str(), NULL, MB_ICONQUESTION | MB_YESNO) == IDYES) { CMusicPlayerCmdHelper helper(this); int fixed_count = helper.FixPlaylistPathError(CPlayer::GetInstance().GetPlaylistPath()); - MessageBox(CCommon::LoadTextFormat(IDS_PLAYLIST_FIX_PATH_ERROR_COMPLETE, { fixed_count }), NULL, MB_ICONINFORMATION | MB_OK); + wstring complete_info = theApp.m_str_table.LoadTextFormat(L"MSG_PLAYLIST_FIX_ERROR_PATH_COMPLETE", { fixed_count }); + MessageBox(complete_info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); } } diff --git a/MusicPlayer2/MusicPlayerDlg.h b/MusicPlayer2/MusicPlayerDlg.h index ca3722d33..a0e4bc331 100644 --- a/MusicPlayer2/MusicPlayerDlg.h +++ b/MusicPlayer2/MusicPlayerDlg.h @@ -3,9 +3,6 @@ // #pragma once -#include "afxwin.h" -#include "afxcmn.h" -//#include"Player.h" #include"PlayListCtrl.h" #include"FindDlg.h" #include"OptionsDlg.h" @@ -15,14 +12,12 @@ #include"LyricEditDlg.h" #include "LyricDownloadDlg.h" #include "LyricBatchDownloadDlg.h" -//#include "EqualizerDlg.h" #include "SoundEffectDlg.h" #include "CortanaLyric.h" #include "FilePathHelper.h" #include "CoverDownloadCommon.h" #include "CoverDownloadDlg.h" #include "FormatConvertDlg.h" -#include "RecorderDlg.h" #include "CNotifyIcon.h" #include "StaticEx.h" #include "CMainDialogBase.h" @@ -35,6 +30,7 @@ #include "MenuEditCtrl.h" #include "HorizontalSplitter.h" #include "powrprof.h" +#include "CHotkeyManager.h" #define WM_ALBUM_COVER_DOWNLOAD_COMPLETE (WM_USER+114) //自动下载专辑封面和歌词完成时发出的消息 @@ -49,7 +45,6 @@ class CMusicPlayerDlg : public CMainDialogBase static CMusicPlayerDlg* GetInstance(); - bool IsTaskbarListEnable() const; HACCEL GetAccel() const { return m_hAccel; } CCortanaLyric& GetCortanaLyric() { return m_cortana_lyric; } @@ -77,16 +72,16 @@ class CMusicPlayerDlg : public CMainDialogBase //用于支持鼠标指向列表中的项目时显示歌曲信息) CStaticEx m_path_static; CMenuEditCtrl m_path_edit; - CButton m_set_path_button; + CButton m_media_lib_button; CSearchEditCtrl m_search_edit; //CButton m_clear_search_button; CUIWindow m_ui_static_ctrl{ m_pUI }; #ifndef COMPILE_IN_WIN_XP - ITaskbarList3* m_pTaskbar{ theApp.GetITaskbarList3() }; //用于支持任务栏显示播放进度 THUMBBUTTON m_thumbButton[3]{}; #endif + CHotkeyManager m_hot_key; CFindDlg m_findDlg; //查找对话框 HACCEL m_hAccel{}; @@ -104,7 +99,9 @@ class CMusicPlayerDlg : public CMainDialogBase int m_window_height; //窗口的高度 CPoint m_desktop_lyric_pos{ -1, -1 }; //桌面歌词窗口的位置 CSize m_desktop_lyric_size{ 0, 0 }; - int m_medialib_btn_width{ theApp.DPI(70) }; + int m_part_static_playlist_width{ theApp.DPI(32) }; // 这里的值是最小宽度,窗口init时会根据文字变大 + int m_part_static_folder_width{ theApp.DPI(32) }; // 这里的值是最小宽度,窗口init时会根据文字变大 + int m_medialib_btn_width{ theApp.DPI(64) }; // 这里的值是最小宽度,窗口init时会根据文字变大 SLayoutData m_layout; //窗口布局的固定数据 @@ -196,6 +193,7 @@ class CMusicPlayerDlg : public CMainDialogBase void SetPlaylistSize(int cx, int cy, int playlist_width); //设置播放列表的大小 void SetDrawAreaSize(int cx, int cy, int playlist_width); void SetAlwaysOnTop(); + void AdjustVolume(int step); bool IsMainWindowPopupMenu() const; //当前弹出的右键是主窗口右键菜单还是播放列表右键菜单 @@ -215,13 +213,19 @@ class CMusicPlayerDlg : public CMainDialogBase void SetPlaylistVisible(); void SetMenubarVisible(); - void UpdateTaskBarProgress(); //更新任务栏按钮上的进度 - void UpdatePlayPauseButton(); //根据当前播放状态更新“播放/暂停”按钮上的文字和图标 - void SetThumbnailClipArea(); //设置任务栏缩略图的区域 - void SetThumbnailClipArea(CRect rect); //设置任务栏缩略图的区域 + // 初始化程序任务栏信息,窗口创建后以及窗口SW_HIDE后恢复时调用 + void TaskBarInit(); + + // 更新任务栏按钮上的播放进度与进度指示的颜色,平时由主定时器调用以保持进度更新 + void UpdateTaskBarProgress(bool force = false) const; + // 根据当前播放状态更新“播放/暂停”按钮上的文字和图标(以及任务栏图标角标&按钮状态) + void UpdatePlayPauseButton(); + // 设置任务栏缩略图的区域 + void TaskBarSetClipArea(CRect rect); + void EnablePlaylist(bool enable); //设置启用或禁用播放列表控件 - void CreateDesktopShortcut(); //用于在提示用户创建桌面快捷方式 + void FirstRunCreateShortcut(); // 如果是首次运行那么提示用户是否创建桌面快捷方式 void ApplySettings(const COptionsDlg& optionDlg); //从选项设置对话框获取设置 void ApplyThemeColor(); //应用主题颜色设置 @@ -259,8 +263,6 @@ class CMusicPlayerDlg : public CMainDialogBase bool IsFloatPlaylistExist(); bool MoveFloatPlaylistPos(); - void Show(bool show); - void SaveUiData(); void LoadUiData(); @@ -283,7 +285,7 @@ class CMusicPlayerDlg : public CMainDialogBase afx_msg void OnNext(); afx_msg void OnRew(); afx_msg void OnFF(); - afx_msg void OnSetPath(); + afx_msg void OnMediaLib(); afx_msg void OnFind(); afx_msg void OnExplorePath(); virtual BOOL PreTranslateMessage(MSG* pMsg); @@ -319,10 +321,13 @@ class CMusicPlayerDlg : public CMainDialogBase //afx_msg void OnStnClickedProgressStatic(); afx_msg void OnReIniBass(); afx_msg void OnSortByFile(); + afx_msg void OnSortByPath(); afx_msg void OnSortByTitle(); afx_msg void OnSortByArtist(); afx_msg void OnSortByAlbum(); afx_msg void OnSortByTrack(); + afx_msg void OnSortByListenTime(); + afx_msg void OnSortByModifiedTime(); public: afx_msg void OnDeleteFromDisk(); protected: @@ -334,11 +339,6 @@ class CMusicPlayerDlg : public CMainDialogBase afx_msg void OnDispTitleArtist(); afx_msg void OnMiniMode(); - afx_msg void OnBnClickedStop(); - afx_msg void OnBnClickedPrevious(); - afx_msg void OnBnClickedPlayPause(); - afx_msg void OnBnClickedNext(); - // afx_msg void OnMove(int x, int y); afx_msg void OnReloadLyric(); afx_msg void OnSongInfo(); afx_msg void OnCopyCurrentLyric(); @@ -382,16 +382,10 @@ class CMusicPlayerDlg : public CMainDialogBase afx_msg void OnDeleteAlbumCover(); afx_msg void OnCopyFileTo(); afx_msg void OnMoveFileTo(); -protected: - //afx_msg LRESULT OnOpenFileCommandLine(WPARAM wParam, LPARAM lParam); -public: afx_msg void OnFormatConvert(); afx_msg void OnFormatConvert1(); protected: afx_msg LRESULT OnSettingsApplied(WPARAM wParam, LPARAM lParam); -public: - afx_msg void OnRecorder(); -protected: afx_msg LRESULT OnAlbumCoverDownloadComplete(WPARAM wParam, LPARAM lParam); public: afx_msg void OnColorizationColorChanged(DWORD dwColorizationColor, BOOL bOpacity); @@ -492,15 +486,10 @@ class CMusicPlayerDlg : public CMainDialogBase protected: afx_msg LRESULT OnMainWindowActivated(WPARAM wParam, LPARAM lParam); public: - afx_msg void OnSortByModifiedTime(); - afx_msg void OnSortByPath(); afx_msg void OnContainSubFolder(); protected: afx_msg LRESULT OnGetMusicCurrentPosition(WPARAM wParam, LPARAM lParam); public: - afx_msg void OnAccendingOrder(); - afx_msg void OnDesendingOrder(); - afx_msg void OnInvertPlaylist(); afx_msg void OnPlayRandom(); protected: afx_msg LRESULT OnCurrentFileAlbumCoverChanged(WPARAM wParam, LPARAM lParam); diff --git a/MusicPlayer2/OggEncodeCfgDlg.cpp b/MusicPlayer2/OggEncodeCfgDlg.cpp index 2440c4337..592a44c44 100644 --- a/MusicPlayer2/OggEncodeCfgDlg.cpp +++ b/MusicPlayer2/OggEncodeCfgDlg.cpp @@ -4,15 +4,14 @@ #include "stdafx.h" #include "MusicPlayer2.h" #include "OggEncodeCfgDlg.h" -#include "afxdialogex.h" // COggEncodeCfgDlg 对话框 -IMPLEMENT_DYNAMIC(COggEncodeCfgDlg, CDialog) +IMPLEMENT_DYNAMIC(COggEncodeCfgDlg, CBaseDialog) COggEncodeCfgDlg::COggEncodeCfgDlg(CWnd* pParent /*=nullptr*/) - : CDialog(IDD_OGG_ENCODE_CFG_DIALOG, pParent) + : CBaseDialog(IDD_OGG_ENCODE_CFG_DIALOG, pParent) { } @@ -23,36 +22,64 @@ COggEncodeCfgDlg::~COggEncodeCfgDlg() void COggEncodeCfgDlg::SetInfoText() { - int rate; - switch (m_encode_para.encode_quality) - { - case -1: rate = 45; break; - case 0: rate = 64; break; - case 1: rate = 80; break; - case 2: rate = 96; break; - case 3: rate = 112; break; - case 4: rate = 128; break; - case 5: rate = 160; break; - case 6: rate = 192; break; - case 7: rate = 224; break; - case 8: rate = 256; break; - case 9: rate = 320; break; - case 10: rate = 500; break; - } - CString info; - info.Format(CCommon::LoadText(IDS_CURRENT_SELECTED, _T(": %d (%d kbps)")), m_encode_para.encode_quality, rate); - SetDlgItemText(IDC_INFO_STATIC, info); + int rate{}; + switch (m_encode_para.encode_quality) + { + case -1: rate = 45; break; + case 0: rate = 64; break; + case 1: rate = 80; break; + case 2: rate = 96; break; + case 3: rate = 112; break; + case 4: rate = 128; break; + case 5: rate = 160; break; + case 6: rate = 192; break; + case 7: rate = 224; break; + case 8: rate = 256; break; + case 9: rate = 320; break; + case 10: rate = 500; break; + } + // wstring info = theApp.m_str_table.LoadTextFormat(L"TXT_ENCODE_OPT_OGG_QUALITY_INFO", { m_encode_para.encode_quality, rate }); + std::wstringstream wss; + wss << m_encode_para.encode_quality << L" (" << rate << L" kbps)"; + wstring info = wss.str(); + SetDlgItemTextW(IDC_INFO_STATIC, info.c_str()); +} + +CString COggEncodeCfgDlg::GetDialogName() const +{ + return L"OggEncodeOptDlg"; +} + +bool COggEncodeCfgDlg::InitializeControls() +{ + wstring temp; + temp = theApp.m_str_table.LoadText(L"TITLE_ENCODE_OPT_OGG"); + SetWindowTextW(temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_ENCODE_OPT_OGG_ENCODE_QUALITY_SEL"); + SetDlgItemTextW(IDC_TXT_ENCODE_OPT_OGG_ENCODE_QUALITY_SEL_STATIC, temp.c_str()); + // IDC_QUALITY_SLIDER + // IDC_INFO_STATIC + temp = theApp.m_str_table.LoadText(L"TXT_ENCODE_OPT_OGG_ENCODE_QUALITY_LOW"); + SetDlgItemTextW(IDC_TXT_ENCODE_OPT_OGG_ENCODE_QUALITY_LOW_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_ENCODE_OPT_OGG_ENCODE_QUALITY_HIGH"); + SetDlgItemTextW(IDC_TXT_ENCODE_OPT_OGG_ENCODE_QUALITY_HIGH_STATIC, temp.c_str()); + + RepositionTextBasedControls({ + { CtrlTextInfo::R1, IDOK, CtrlTextInfo::W32 }, + { CtrlTextInfo::R2, IDCANCEL, CtrlTextInfo::W32 } + }); + return true; } void COggEncodeCfgDlg::DoDataExchange(CDataExchange* pDX) { - CDialog::DoDataExchange(pDX); - DDX_Control(pDX, IDC_QUALITY_SLIDER, m_quality_sld); + CBaseDialog::DoDataExchange(pDX); + DDX_Control(pDX, IDC_QUALITY_SLIDER, m_quality_sld); } -BEGIN_MESSAGE_MAP(COggEncodeCfgDlg, CDialog) - ON_NOTIFY(NM_CUSTOMDRAW, IDC_QUALITY_SLIDER, &COggEncodeCfgDlg::OnNMCustomdrawQualitySlider) +BEGIN_MESSAGE_MAP(COggEncodeCfgDlg, CBaseDialog) + ON_NOTIFY(NM_CUSTOMDRAW, IDC_QUALITY_SLIDER, &COggEncodeCfgDlg::OnNMCustomdrawQualitySlider) END_MESSAGE_MAP() @@ -61,22 +88,22 @@ END_MESSAGE_MAP() BOOL COggEncodeCfgDlg::OnInitDialog() { - CDialog::OnInitDialog(); - - // TODO: 在此添加额外的初始化 - m_quality_sld.SetRange(-1, 10); - m_quality_sld.SetPos(m_encode_para.encode_quality); - SetInfoText(); - return TRUE; // return TRUE unless you set the focus to a control - // 异常: OCX 属性页应返回 FALSE + CBaseDialog::OnInitDialog(); + + // TODO: 在此添加额外的初始化 + m_quality_sld.SetRange(-1, 10); + m_quality_sld.SetPos(m_encode_para.encode_quality); + SetInfoText(); + return TRUE; // return TRUE unless you set the focus to a control + // 异常: OCX 属性页应返回 FALSE } void COggEncodeCfgDlg::OnNMCustomdrawQualitySlider(NMHDR *pNMHDR, LRESULT *pResult) { - LPNMCUSTOMDRAW pNMCD = reinterpret_cast(pNMHDR); - // TODO: 在此添加控件通知处理程序代码 + LPNMCUSTOMDRAW pNMCD = reinterpret_cast(pNMHDR); + // TODO: 在此添加控件通知处理程序代码 m_encode_para.encode_quality = m_quality_sld.GetPos(); - SetInfoText(); - *pResult = 0; + SetInfoText(); + *pResult = 0; } diff --git a/MusicPlayer2/OggEncodeCfgDlg.h b/MusicPlayer2/OggEncodeCfgDlg.h index cd7e15e79..e9734e73b 100644 --- a/MusicPlayer2/OggEncodeCfgDlg.h +++ b/MusicPlayer2/OggEncodeCfgDlg.h @@ -1,34 +1,37 @@ #pragma once +#include "BaseDialog.h" #include "IPlayerCore.h" // COggEncodeCfgDlg 对话框 -class COggEncodeCfgDlg : public CDialog +class COggEncodeCfgDlg : public CBaseDialog { - DECLARE_DYNAMIC(COggEncodeCfgDlg) + DECLARE_DYNAMIC(COggEncodeCfgDlg) public: - COggEncodeCfgDlg(CWnd* pParent = nullptr); // 标准构造函数 - virtual ~COggEncodeCfgDlg(); + COggEncodeCfgDlg(CWnd* pParent = nullptr); // 标准构造函数 + virtual ~COggEncodeCfgDlg(); // 对话框数据 #ifdef AFX_DESIGN_TIME - enum { IDD = IDD_OGG_ENCODE_CFG_DIALOG }; + enum { IDD = IDD_OGG_ENCODE_CFG_DIALOG }; #endif OggEncodePara m_encode_para; protected: - //控件变量 - CSliderCtrl m_quality_sld; + //控件变量 + CSliderCtrl m_quality_sld; + void SetInfoText(); - void SetInfoText(); + virtual CString GetDialogName() const; + virtual bool IsRememberDialogSizeEnable() const { return false; }; + virtual bool InitializeControls(); + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 - - DECLARE_MESSAGE_MAP() + DECLARE_MESSAGE_MAP() public: - virtual BOOL OnInitDialog(); - afx_msg void OnNMCustomdrawQualitySlider(NMHDR *pNMHDR, LRESULT *pResult); + virtual BOOL OnInitDialog(); + afx_msg void OnNMCustomdrawQualitySlider(NMHDR *pNMHDR, LRESULT *pResult); }; diff --git a/MusicPlayer2/OptionsDlg.cpp b/MusicPlayer2/OptionsDlg.cpp index 79b0ba2cb..faca0ef9b 100644 --- a/MusicPlayer2/OptionsDlg.cpp +++ b/MusicPlayer2/OptionsDlg.cpp @@ -4,7 +4,6 @@ #include "stdafx.h" #include "MusicPlayer2.h" #include "OptionsDlg.h" -#include "afxdialogex.h" // COptionsDlg 对话框 @@ -26,6 +25,22 @@ CString COptionsDlg::GetDialogName() const return _T("OptionsDlg"); } +bool COptionsDlg::InitializeControls() +{ + wstring temp; + temp = theApp.m_str_table.LoadText(L"TITLE_OPT"); + SetWindowTextW(temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_APPLY"); + SetDlgItemTextW(IDC_APPLY_BUTTON, temp.c_str()); + + RepositionTextBasedControls({ + { CtrlTextInfo::R1, IDOK, CtrlTextInfo::W32 }, + { CtrlTextInfo::R2, IDCANCEL, CtrlTextInfo::W32 }, + { CtrlTextInfo::R3, IDC_APPLY_BUTTON, CtrlTextInfo::W32 } + }); + return true; +} + void COptionsDlg::DoDataExchange(CDataExchange* pDX) { CBaseDialog::DoDataExchange(pDX); @@ -50,7 +65,7 @@ BOOL COptionsDlg::OnInitDialog() // TODO: 在此添加额外的初始化 - SetIcon(theApp.m_icon_set.setting.GetIcon(true), FALSE); + SetIcon(IconMgr::IconType::IT_Setting, FALSE); //创建子对话框 m_tab1_dlg.Create(IDD_LYRIC_SETTING_DIALOG); @@ -77,24 +92,12 @@ BOOL COptionsDlg::OnInitDialog() } //添加对话框 - m_tab.AddWindow(&m_tab1_dlg, CCommon::LoadText(IDS_LYRIC_SETTINGS)); - m_tab.AddWindow(&m_tab2_dlg, CCommon::LoadText(IDS_APPEARANCE_SETTINGS)); - m_tab.AddWindow(&m_tab3_dlg, CCommon::LoadText(IDS_GENERAL_SETTINGS)); - m_tab.AddWindow(&m_tab4_dlg, CCommon::LoadText(IDS_PLAY_SETTINGS)); - m_tab.AddWindow(&m_media_lib_dlg, CCommon::LoadText(IDS_MEDIA_LIB)); - m_tab.AddWindow(&m_tab5_dlg, CCommon::LoadText(IDS_GLOBLE_HOTKEY)); - - //为每个标签添加图标 - CImageList ImageList; - ImageList.Create(theApp.DPI(16), theApp.DPI(16), ILC_COLOR32 | ILC_MASK, 2, 2); - ImageList.Add(theApp.m_icon_set.lyric.GetIcon(true)); - ImageList.Add(theApp.m_icon_set.skin.GetIcon(true)); - ImageList.Add(theApp.m_icon_set.setting.GetIcon(true)); - ImageList.Add(theApp.m_icon_set.play_new.GetIcon(true)); - ImageList.Add(theApp.m_icon_set.media_lib.GetIcon(true)); - ImageList.Add(theApp.m_icon_set.hot_key); - m_tab.SetImageList(&ImageList); - ImageList.Detach(); + m_tab.AddWindow(&m_tab1_dlg, theApp.m_str_table.LoadText(L"TITLE_OPT_LRC").c_str(), IconMgr::IconType::IT_Lyric); + m_tab.AddWindow(&m_tab2_dlg, theApp.m_str_table.LoadText(L"TITLE_OPT_APC").c_str(), IconMgr::IconType::IT_Skin); + m_tab.AddWindow(&m_tab3_dlg, theApp.m_str_table.LoadText(L"TITLE_OPT_DATA").c_str(), IconMgr::IconType::IT_Setting); + m_tab.AddWindow(&m_tab4_dlg, theApp.m_str_table.LoadText(L"TITLE_OPT_PLAY").c_str(), IconMgr::IconType::IT_Play); + m_tab.AddWindow(&m_media_lib_dlg, theApp.m_str_table.LoadText(L"TITLE_OPT_MEDIA_LIB").c_str(), IconMgr::IconType::IT_Media_Lib); + m_tab.AddWindow(&m_tab5_dlg, theApp.m_str_table.LoadText(L"TITLE_OPT_HOT_KEY").c_str(), IconMgr::IconType::IT_Key_Board); m_tab.SetItemSize(CSize(theApp.DPI(60), theApp.DPI(24))); m_tab.AdjustTabWindowSize(); @@ -156,14 +159,10 @@ void COptionsDlg::OnSize(UINT nType, int cx, int cy) CBaseDialog::OnSize(nType, cx, cy); if (nType != SIZE_MINIMIZED) { - //为每个子窗口设置滚动信息 + //为每个子窗口更新滚动信息 for (size_t i = 0; i < m_tab_vect.size(); i++) { - m_tab_vect[i]->ResetScroll(); m_tab_vect[i]->SetScrollbarInfo(m_tab.m_tab_rect.Height(), m_tab_height[i]); } - } - - // TODO: 在此处添加消息处理程序代码 } diff --git a/MusicPlayer2/OptionsDlg.h b/MusicPlayer2/OptionsDlg.h index eb00e031f..fdf853df3 100644 --- a/MusicPlayer2/OptionsDlg.h +++ b/MusicPlayer2/OptionsDlg.h @@ -1,5 +1,4 @@ #pragma once -#include "afxcmn.h" #include "LyricSettingsDlg.h" #include "AppearanceSettingDlg.h" #include "DataSettingsDlg.h" @@ -42,6 +41,7 @@ class COptionsDlg : public CBaseDialog std::vector m_tab_height; virtual CString GetDialogName() const override; + virtual bool InitializeControls() override; virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() diff --git a/MusicPlayer2/PlayListCtrl.cpp b/MusicPlayer2/PlayListCtrl.cpp index 720f87b2d..08b4d1bd1 100644 --- a/MusicPlayer2/PlayListCtrl.cpp +++ b/MusicPlayer2/PlayListCtrl.cpp @@ -3,6 +3,7 @@ #include "stdafx.h" #include "MusicPlayer2.h" +#include "Player.h" #include "PlayListCtrl.h" #include "SongInfoHelper.h" @@ -49,7 +50,7 @@ void CPlayListCtrl::ShowPlaylist(DisplayFormat display_format, bool search_resul { CListCtrlEx::RowData row_data; row_data[0] = wstring(); - row_data[1] = CCommon::LoadText(IDS_NO_RESULT_TO_SHOW).GetString(); + row_data[1] = theApp.m_str_table.LoadText(L"TXT_PLAYLIST_CTRL_NO_RESULT_TO_SHOW"); m_list_data.push_back(std::move(row_data)); } @@ -250,9 +251,9 @@ void CPlayListCtrl::PreSubclassWindow() SetExtendedStyle(style); vector width; CalculateColumeWidth(width); - InsertColumn(0, CCommon::LoadText(IDS_NUMBER), LVCFMT_LEFT, width[0]); //插入第1列 - InsertColumn(1, CCommon::LoadText(IDS_TRACK), LVCFMT_LEFT, width[1]); //插入第2列 - InsertColumn(2, CCommon::LoadText(IDS_LENGTH), LVCFMT_LEFT, width[2]); //插入第3列 + InsertColumn(0, theApp.m_str_table.LoadText(L"TXT_SERIAL_NUMBER").c_str(), LVCFMT_LEFT, width[0]); + InsertColumn(1, theApp.m_str_table.LoadText(L"TXT_TRACK").c_str(), LVCFMT_LEFT, width[1]); + InsertColumn(2, theApp.m_str_table.LoadText(L"TXT_LENGTH").c_str(), LVCFMT_LEFT, width[2]); SetCtrlAEnable(true); SetRowHeight(theApp.DPI(theApp.m_media_lib_setting_data.playlist_item_height)); diff --git a/MusicPlayer2/PlaySettingsDlg.cpp b/MusicPlayer2/PlaySettingsDlg.cpp index 9bd4fb707..1e8257d8f 100644 --- a/MusicPlayer2/PlaySettingsDlg.cpp +++ b/MusicPlayer2/PlaySettingsDlg.cpp @@ -3,9 +3,10 @@ #include "stdafx.h" #include "MusicPlayer2.h" +#include "Player.h" #include "PlaySettingsDlg.h" -#include "afxdialogex.h" #include "FfmpegCore.h" +#include "WinVersionHelper.h" // CPlaySettingsDlg 对话框 @@ -13,7 +14,7 @@ IMPLEMENT_DYNAMIC(CPlaySettingsDlg, CTabDlg) CPlaySettingsDlg::CPlaySettingsDlg(CWnd* pParent /*=nullptr*/) - : CTabDlg(IDD_PLAY_SETTING_DIALOG, pParent) + : CTabDlg(IDD_PLAY_SETTING_DIALOG, pParent) { } @@ -22,28 +23,6 @@ CPlaySettingsDlg::~CPlaySettingsDlg() { } -void CPlaySettingsDlg::DoDataExchange(CDataExchange* pDX) -{ - CTabDlg::DoDataExchange(pDX); - DDX_Control(pDX, IDC_STOP_WHEN_ERROR, m_stop_when_error_check); - DDX_Control(pDX, IDC_SHOW_TASKBAR_PROGRESS, m_show_taskbar_progress_check); - DDX_Control(pDX, IDC_OUTPUT_DEVICE_COMBO, m_output_device_combo); - DDX_Control(pDX, IDC_OUTPUT_DEVICE_INFO_LIST, m_device_info_list); - DDX_Control(pDX, IDC_AUTO_PLAY_WHEN_START_CHECK, m_auto_play_when_start_chk); - DDX_Control(pDX, IDC_SHOW_PLAY_STATE_ICON_CHECK, m_show_play_state_icon_chk); - DDX_Control(pDX, IDC_SOUND_FADE_CHECK, m_sound_fade_chk); - DDX_Control(pDX, IDC_CONTINUE_WHEN_SWITCH_PLAYLIST_CHECK, m_continue_when_switch_playlist_check); - DDX_Control(pDX, IDC_BASS_RADIO, m_bass_radio); - DDX_Control(pDX, IDC_MCI_RADIO, m_mci_radio); - DDX_Control(pDX, IDC_FFMPEG_RADIO, m_ffmpeg_radio); - DDX_Control(pDX, IDC_FFMPEG_CACHE_LENGTH, m_ffmpeg_cache_length); - DDX_Control(pDX, IDC_FFMPEG_MAX_RETRY_COUNT, m_ffmpeg_max_retry_count); - DDX_Control(pDX, IDC_FFMPEG_URL_RETRY_INTERVAL, m_ffmpeg_url_retry_interval); - DDX_Control(pDX, IDC_FFMPEG_ENABLE_WASAPI, m_ffmpeg_enable_wasapi); - DDX_Control(pDX, IDC_FFMPEG_ENABLE_WASAPI_EXCLUSIVE, m_ffmpeg_enable_wasapi_exclusive); - DDX_Control(pDX, IDC_FFMPEG_MAX_WAIT_TIME, m_ffmpeg_max_wait_time); -} - void CPlaySettingsDlg::ShowDeviceInfo() { if (theApp.m_output_devices.empty()) @@ -58,86 +37,72 @@ void CPlaySettingsDlg::ShowDeviceInfo() m_output_device_combo.SetCurSel(m_data.device_selected); // 更新当前设备信息显示 - DeviceInfo& device{ theApp.m_output_devices[m_data.device_selected] }; - m_device_info_list.SetItemText(0, 1, device.name.c_str()); - m_device_info_list.SetItemText(1, 1, device.driver.c_str()); - m_data.output_device = device.name; - DWORD device_type; - device_type = device.flags & BASS_DEVICE_TYPE_MASK; - CString type_info; - switch (device_type) - { - case BASS_DEVICE_TYPE_DIGITAL: - type_info = CCommon::LoadText(IDS_DEVICE_TYPE_DIGITAL); - break; - case BASS_DEVICE_TYPE_DISPLAYPORT: - type_info = CCommon::LoadText(IDS_DEVICE_TYPE_DISPLAYPORT); - break; - case BASS_DEVICE_TYPE_HANDSET: - type_info = CCommon::LoadText(IDS_DEVICE_TYPE_HANDSET); - break; - case BASS_DEVICE_TYPE_HDMI: - type_info = CCommon::LoadText(IDS_DEVICE_TYPE_HDMI); - break; - case BASS_DEVICE_TYPE_HEADPHONES: - type_info = CCommon::LoadText(IDS_DEVICE_TYPE_HEADPHONES); - break; - case BASS_DEVICE_TYPE_HEADSET: - type_info = CCommon::LoadText(IDS_DEVICE_TYPE_HEADSET); - break; - case BASS_DEVICE_TYPE_LINE: - type_info = CCommon::LoadText(IDS_DEVICE_TYPE_LINE); - break; - case BASS_DEVICE_TYPE_MICROPHONE: - type_info = CCommon::LoadText(IDS_DEVICE_TYPE_MICROPHONE); - break; - case BASS_DEVICE_TYPE_NETWORK: - type_info = CCommon::LoadText(IDS_DEVICE_TYPE_NETWORK); - break; - case BASS_DEVICE_TYPE_SPDIF: - type_info = CCommon::LoadText(IDS_DEVICE_TYPE_SPDIF); - break; - case BASS_DEVICE_TYPE_SPEAKERS: - type_info = CCommon::LoadText(IDS_DEVICE_TYPE_SPEAKERS); - break; - } - m_device_info_list.SetItemText(2, 1, type_info); - + DeviceInfo& device{ theApp.m_output_devices[m_data.device_selected] }; + m_device_info_list.SetItemText(0, 1, device.name.c_str()); + m_device_info_list.SetItemText(1, 1, device.driver.c_str()); + m_data.output_device = device.name; + DWORD device_type; + device_type = device.flags & BASS_DEVICE_TYPE_MASK; + wstring type_info; + switch (device_type) + { + case BASS_DEVICE_TYPE_NETWORK: type_info = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_DEVICE_TYPE_BASS_NETWORK"); break; + case BASS_DEVICE_TYPE_SPEAKERS: type_info = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_DEVICE_TYPE_BASS_SPEAKERS"); break; + case BASS_DEVICE_TYPE_LINE: type_info = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_DEVICE_TYPE_BASS_LINE"); break; + case BASS_DEVICE_TYPE_HEADPHONES: type_info = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_DEVICE_TYPE_BASS_HEADPHONES"); break; + case BASS_DEVICE_TYPE_MICROPHONE: type_info = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_DEVICE_TYPE_BASS_MICROPHONE"); break; + case BASS_DEVICE_TYPE_HEADSET: type_info = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_DEVICE_TYPE_BASS_HEADSET"); break; + case BASS_DEVICE_TYPE_HANDSET: type_info = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_DEVICE_TYPE_BASS_HANDSET"); break; + case BASS_DEVICE_TYPE_DIGITAL: type_info = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_DEVICE_TYPE_BASS_DIGITAL"); break; + case BASS_DEVICE_TYPE_SPDIF: type_info = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_DEVICE_TYPE_BASS_SPDIF"); break; + case BASS_DEVICE_TYPE_HDMI: type_info = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_DEVICE_TYPE_BASS_HDMI"); break; + case BASS_DEVICE_TYPE_DISPLAYPORT: type_info = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_DEVICE_TYPE_BASS_DISPLAYPORT"); break; + default: break; + } + m_device_info_list.SetItemText(2, 1, type_info.c_str()); } void CPlaySettingsDlg::EnableControl() { bool enable = !CPlayer::GetInstance().IsMciCore(); bool ffmpeg_enable = CPlayer::GetInstance().IsFfmpegCore(); - m_sound_fade_chk.EnableWindow(CPlayer::GetInstance().IsBassCore()); + EnableDlgCtrl(IDC_SOUND_FADE_CHECK, CPlayer::GetInstance().IsBassCore()); m_device_info_list.EnableWindow(enable); m_output_device_combo.EnableWindow(enable); m_ffmpeg_cache_length.EnableWindow(ffmpeg_enable); m_ffmpeg_max_retry_count.EnableWindow(ffmpeg_enable); m_ffmpeg_url_retry_interval.EnableWindow(ffmpeg_enable); + bool max_wait_time_support{ false }, wasapi_support{ false }; if (ffmpeg_enable) { - auto core = (CFfmpegCore*)CPlayer::GetInstance().GetPlayerCore(); - m_ffmpeg_enable_wasapi.EnableWindow(core->IsWASAPISupported()); + auto core = static_cast(CPlayer::GetInstance().GetPlayerCore()); + wasapi_support = core->IsWASAPISupported(); auto version = core->GetVersion(); - m_ffmpeg_max_wait_time.EnableWindow(version > FFMPEG_CORE_VERSION(1, 0, 0, 0)); - } else { - m_ffmpeg_enable_wasapi.EnableWindow(FALSE); - m_ffmpeg_max_wait_time.EnableWindow(FALSE); - } - if (m_ffmpeg_enable_wasapi.IsWindowEnabled() && m_data.ffmpeg_core_enable_WASAPI) { - m_ffmpeg_enable_wasapi_exclusive.EnableWindow(TRUE); - } else { - m_ffmpeg_enable_wasapi_exclusive.EnableWindow(FALSE); + max_wait_time_support = version > FFMPEG_CORE_VERSION(1, 0, 0, 0); } + m_ffmpeg_max_wait_time.EnableWindow(max_wait_time_support); + EnableDlgCtrl(IDC_FFMPEG_ENABLE_WASAPI, wasapi_support); + EnableDlgCtrl(IDC_FFMPEG_ENABLE_WASAPI_EXCLUSIVE, wasapi_support && m_data.ffmpeg_core_enable_WASAPI); } void CPlaySettingsDlg::GetDataFromUi() { + m_data.stop_when_error = (IsDlgButtonChecked(IDC_STOP_WHEN_ERROR) != FALSE); + m_data.auto_play_when_start = (IsDlgButtonChecked(IDC_AUTO_PLAY_WHEN_START_CHECK) != FALSE); + m_data.show_taskbar_progress = (IsDlgButtonChecked(IDC_SHOW_TASKBAR_PROGRESS) != FALSE); + m_data.show_playstate_icon = (IsDlgButtonChecked(IDC_SHOW_PLAY_STATE_ICON_CHECK) != FALSE); + m_data.fade_effect = (IsDlgButtonChecked(IDC_SOUND_FADE_CHECK) != FALSE); + m_data.continue_when_switch_playlist = (IsDlgButtonChecked(IDC_CONTINUE_WHEN_SWITCH_PLAYLIST_CHECK) != FALSE); + m_data.use_media_trans_control = (IsDlgButtonChecked(IDC_USE_MEDIA_TRANS_CONTORL_CHECK) != FALSE); + + m_data.use_mci = (IsDlgButtonChecked(IDC_MCI_RADIO) != FALSE); + m_data.use_ffmpeg = (IsDlgButtonChecked(IDC_FFMPEG_RADIO) != FALSE); + m_data.ffmpeg_core_cache_length = m_ffmpeg_cache_length.GetValue(); m_data.ffmpeg_core_max_retry_count = m_ffmpeg_max_retry_count.GetValue(); m_data.ffmpeg_core_url_retry_interval = m_ffmpeg_url_retry_interval.GetValue(); m_data.ffmpeg_core_max_wait_time = m_ffmpeg_max_wait_time.GetValue(); - m_data.use_media_trans_control = (IsDlgButtonChecked(IDC_USE_MEDIA_TRANS_CONTORL_CHECK) != FALSE); + m_data.ffmpeg_core_enable_WASAPI = (IsDlgButtonChecked(IDC_FFMPEG_ENABLE_WASAPI) != FALSE); + m_data.ffmpeg_core_enable_WASAPI_exclusive_mode = (IsDlgButtonChecked(IDC_FFMPEG_ENABLE_WASAPI_EXCLUSIVE) != FALSE); } void CPlaySettingsDlg::ApplyDataToUi() @@ -146,22 +111,88 @@ void CPlaySettingsDlg::ApplyDataToUi() EnableControl(); } +bool CPlaySettingsDlg::InitializeControls() +{ + wstring temp; + temp = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_PLAY_OPT"); + SetDlgItemTextW(IDC_TXT_OPT_PLAY_PLAY_OPT_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_STOP_WHEN_ERROR"); + SetDlgItemTextW(IDC_STOP_WHEN_ERROR, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_AUTO_PLAY_WHEN_START"); + SetDlgItemTextW(IDC_AUTO_PLAY_WHEN_START_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_SHOW_TASKBAR_PROGRESS"); + SetDlgItemTextW(IDC_SHOW_TASKBAR_PROGRESS, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_SHOW_TASKBAR_PLAY_STATE_ICON"); + SetDlgItemTextW(IDC_SHOW_PLAY_STATE_ICON_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_SOUND_FADE"); + SetDlgItemTextW(IDC_SOUND_FADE_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_CONTINUE_WHEN_SWITCH_PLAYLIST"); + SetDlgItemTextW(IDC_CONTINUE_WHEN_SWITCH_PLAYLIST_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_USE_MEDIA_TRANS_CONTORL"); + SetDlgItemTextW(IDC_USE_MEDIA_TRANS_CONTORL_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_CORE"); + SetDlgItemTextW(IDC_TXT_OPT_PLAY_CORE_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_CORE_BASS"); + SetDlgItemTextW(IDC_BASS_RADIO, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_CORE_MCI"); + SetDlgItemTextW(IDC_MCI_RADIO, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_CORE_FFMPEG"); + SetDlgItemTextW(IDC_FFMPEG_RADIO, temp.c_str()); + temp = L"" + theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_CORE_FFMPEG_DL_INFO") + L""; + SetDlgItemTextW(IDC_FFMPEG_DOWN_SYSLINK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_DEVICE"); + SetDlgItemTextW(IDC_TXT_OPT_PLAY_DEVICE_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_DEVICE_SEL"); + SetDlgItemTextW(IDC_TXT_OPT_PLAY_DEVICE_SEL_STATIC, temp.c_str()); + // IDC_OUTPUT_DEVICE_COMBO + // IDC_OUTPUT_DEVICE_INFO_LIST + temp = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_FFMPEG_CORE_SETTING"); + SetDlgItemTextW(IDC_TXT_OPT_PLAY_FFMPEG_CORE_SETTING_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_FFMPEG_CORE_CACHE_LENGTH"); + SetDlgItemTextW(IDC_TXT_OPT_PLAY_FFMPEG_CORE_CACHE_LENGTH_STATIC, temp.c_str()); + // IDC_FFMPEG_CACHE_LENGTH + temp = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_FFMPEG_CORE_MAX_RETRY_COUNT"); + SetDlgItemTextW(IDC_TXT_OPT_PLAY_FFMPEG_CORE_MAX_RETRY_COUNT_STATIC, temp.c_str()); + // IDC_FFMPEG_MAX_RETRY_COUNT + temp = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_FFMPEG_CORE_URL_RETRY_INTERVAL"); + SetDlgItemTextW(IDC_TXT_OPT_PLAY_FFMPEG_CORE_URL_RETRY_INTERVAL_STATIC, temp.c_str()); + // IDC_FFMPEG_URL_RETRY_INTERVAL + temp = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_FFMPEG_CORE_MAX_WAIT_TIME"); + SetDlgItemTextW(IDC_TXT_OPT_PLAY_FFMPEG_CORE_MAX_WAIT_TIME_STATIC, temp.c_str()); + // IDC_FFMPEG_MAX_WAIT_TIME + temp = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_FFMPEG_CORE_ENABLE_WASAPI"); + SetDlgItemTextW(IDC_FFMPEG_ENABLE_WASAPI, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_FFMPEG_CORE_ENABLE_WASAPI_EXCLUSIVE"); + SetDlgItemTextW(IDC_FFMPEG_ENABLE_WASAPI_EXCLUSIVE, temp.c_str()); + + RepositionTextBasedControls({ + { CtrlTextInfo::L1, IDC_FFMPEG_RADIO, CtrlTextInfo::W16 }, + { CtrlTextInfo::C0, IDC_FFMPEG_DOWN_SYSLINK } + }); + RepositionTextBasedControls({ + { CtrlTextInfo::L1, IDC_TXT_OPT_PLAY_DEVICE_SEL_STATIC }, + { CtrlTextInfo::C0, IDC_OUTPUT_DEVICE_COMBO } + }); + + return true; +} + +void CPlaySettingsDlg::DoDataExchange(CDataExchange* pDX) +{ + CTabDlg::DoDataExchange(pDX); + DDX_Control(pDX, IDC_OUTPUT_DEVICE_COMBO, m_output_device_combo); + DDX_Control(pDX, IDC_OUTPUT_DEVICE_INFO_LIST, m_device_info_list); + DDX_Control(pDX, IDC_FFMPEG_CACHE_LENGTH, m_ffmpeg_cache_length); + DDX_Control(pDX, IDC_FFMPEG_MAX_RETRY_COUNT, m_ffmpeg_max_retry_count); + DDX_Control(pDX, IDC_FFMPEG_URL_RETRY_INTERVAL, m_ffmpeg_url_retry_interval); + DDX_Control(pDX, IDC_FFMPEG_MAX_WAIT_TIME, m_ffmpeg_max_wait_time); +} + BEGIN_MESSAGE_MAP(CPlaySettingsDlg, CTabDlg) - ON_BN_CLICKED(IDC_STOP_WHEN_ERROR, &CPlaySettingsDlg::OnBnClickedStopWhenError) - ON_BN_CLICKED(IDC_SHOW_TASKBAR_PROGRESS, &CPlaySettingsDlg::OnBnClickedShowTaskbarProgress) - ON_CBN_SELCHANGE(IDC_OUTPUT_DEVICE_COMBO, &CPlaySettingsDlg::OnCbnSelchangeOutputDeviceCombo) - ON_BN_CLICKED(IDC_AUTO_PLAY_WHEN_START_CHECK, &CPlaySettingsDlg::OnBnClickedAutoPlayWhenStartCheck) - ON_BN_CLICKED(IDC_SHOW_PLAY_STATE_ICON_CHECK, &CPlaySettingsDlg::OnBnClickedShowPlayStateIconCheck) - ON_BN_CLICKED(IDC_SOUND_FADE_CHECK, &CPlaySettingsDlg::OnBnClickedSoundFadeCheck) - ON_BN_CLICKED(IDC_CONTINUE_WHEN_SWITCH_PLAYLIST_CHECK, &CPlaySettingsDlg::OnBnClickedContinueWhenSwitchPlaylistCheck) - ON_BN_CLICKED(IDC_BASS_RADIO, &CPlaySettingsDlg::OnBnClickedBassRadio) - ON_BN_CLICKED(IDC_MCI_RADIO, &CPlaySettingsDlg::OnBnClickedMciRadio) - ON_BN_CLICKED(IDC_FFMPEG_RADIO, &CPlaySettingsDlg::OnBnClickedFfmpegRadio) + ON_CBN_SELCHANGE(IDC_OUTPUT_DEVICE_COMBO, &CPlaySettingsDlg::OnCbnSelchangeOutputDeviceCombo) ON_NOTIFY(NM_CLICK, IDC_FFMPEG_DOWN_SYSLINK, &CPlaySettingsDlg::OnNMClickFfmpegDownSyslink) - ON_WM_CTLCOLOR() ON_BN_CLICKED(IDC_FFMPEG_ENABLE_WASAPI, &CPlaySettingsDlg::OnBnClickedFfmpegEnableWasapi) - ON_BN_CLICKED(IDC_FFMPEG_ENABLE_WASAPI_EXCLUSIVE, &CPlaySettingsDlg::OnBnClickedFfmpegEnableWasapiExclusive) END_MESSAGE_MAP() @@ -170,42 +201,37 @@ END_MESSAGE_MAP() BOOL CPlaySettingsDlg::OnInitDialog() { - CTabDlg::OnInitDialog(); + CTabDlg::OnInitDialog(); - // TODO: 在此添加额外的初始化 + // TODO: 在此添加额外的初始化 m_toolTip.Create(this); m_toolTip.SetMaxTipWidth(theApp.DPI(300)); - m_toolTip.AddTool(GetDlgItem(IDC_MCI_RADIO), CCommon::LoadText(IDS_MCI_KERNAL_TIP)); - m_toolTip.AddTool(GetDlgItem(IDC_FFMPEG_RADIO), CCommon::LoadText(IDS_FFMPEG_CORE)); - m_toolTip.AddTool(GetDlgItem(IDC_CONTINUE_WHEN_SWITCH_PLAYLIST_CHECK), CCommon::LoadText(IDS_CONTINUE_WHEN_SWITCH_PLAYLIST_TIP)); + m_toolTip.AddTool(GetDlgItem(IDC_MCI_RADIO), theApp.m_str_table.LoadText(L"TIP_OPT_PLAY_CORE_MCI").c_str()); + m_toolTip.AddTool(GetDlgItem(IDC_FFMPEG_RADIO), theApp.m_str_table.LoadText(L"TIP_OPT_PLAY_CORE_FFMPEG").c_str()); + m_toolTip.AddTool(GetDlgItem(IDC_CONTINUE_WHEN_SWITCH_PLAYLIST_CHECK), theApp.m_str_table.LoadText(L"TIP_OPT_PLAY_CONTINUE_WHEN_SWITCH_PLAYLIST").c_str()); m_toolTip.SetWindowPos(&CWnd::wndTopMost, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); - //初始化各控件的状态 - m_stop_when_error_check.SetCheck(m_data.stop_when_error); - m_auto_play_when_start_chk.SetCheck(m_data.auto_play_when_start); - m_continue_when_switch_playlist_check.SetCheck(m_data.continue_when_switch_playlist); - m_show_taskbar_progress_check.SetCheck(m_data.show_taskbar_progress); - m_show_play_state_icon_chk.SetCheck(m_data.show_playstate_icon); - m_sound_fade_chk.SetCheck(m_data.fade_effect); - - if (!CWinVersionHelper::IsWindows7OrLater() || theApp.GetITaskbarList3() == nullptr) - { - m_show_taskbar_progress_check.SetCheck(FALSE); - m_show_play_state_icon_chk.SetCheck(FALSE); - m_show_taskbar_progress_check.EnableWindow(FALSE); - m_show_play_state_icon_chk.EnableWindow(FALSE); - } - - if (CWinVersionHelper::IsWindows81OrLater()) + //初始化各控件的状态 + if (!CWinVersionHelper::IsWindows7OrLater() || theApp.GetITaskbarList3() == nullptr) { - CheckDlgButton(IDC_USE_MEDIA_TRANS_CONTORL_CHECK, m_data.use_media_trans_control); + m_data.show_taskbar_progress = false; + m_data.show_playstate_icon = false; + EnableDlgCtrl(IDC_SHOW_TASKBAR_PROGRESS, false); + EnableDlgCtrl(IDC_SHOW_PLAY_STATE_ICON_CHECK, false); } - else + if (!CWinVersionHelper::IsWindows81OrLater()) { - CheckDlgButton(IDC_USE_MEDIA_TRANS_CONTORL_CHECK, FALSE); + m_data.use_media_trans_control = false; EnableDlgCtrl(IDC_USE_MEDIA_TRANS_CONTORL_CHECK, FALSE); } + CheckDlgButton(IDC_STOP_WHEN_ERROR, m_data.stop_when_error); + CheckDlgButton(IDC_AUTO_PLAY_WHEN_START_CHECK, m_data.auto_play_when_start); + CheckDlgButton(IDC_SHOW_TASKBAR_PROGRESS, m_data.show_taskbar_progress); + CheckDlgButton(IDC_SHOW_PLAY_STATE_ICON_CHECK, m_data.show_playstate_icon); + CheckDlgButton(IDC_SOUND_FADE_CHECK, m_data.fade_effect); + CheckDlgButton(IDC_CONTINUE_WHEN_SWITCH_PLAYLIST_CHECK, m_data.continue_when_switch_playlist); + CheckDlgButton(IDC_USE_MEDIA_TRANS_CONTORL_CHECK, m_data.use_media_trans_control); bool enable_ffmpeg = false; if (CPlayer::GetInstance().IsFfmpegCore()) { @@ -217,43 +243,44 @@ BOOL CPlaySettingsDlg::OnInitDialog() FreeLibrary(h); } } - m_ffmpeg_radio.EnableWindow(enable_ffmpeg); + EnableDlgCtrl(IDC_FFMPEG_RADIO, enable_ffmpeg); ShowDlgCtrl(IDC_FFMPEG_DOWN_SYSLINK, !enable_ffmpeg); //未检测到ffmpeg内核时,显示下载链接 + m_data.use_ffmpeg &= enable_ffmpeg; - if (m_data.use_mci) - m_mci_radio.SetCheck(TRUE); - else if (m_data.use_ffmpeg) - m_ffmpeg_radio.SetCheck(TRUE); + if (m_data.use_ffmpeg) + CheckDlgButton(IDC_FFMPEG_RADIO, TRUE); + else if (m_data.use_mci) + CheckDlgButton(IDC_MCI_RADIO, TRUE); else - m_bass_radio.SetCheck(TRUE); + CheckDlgButton(IDC_BASS_RADIO, TRUE); - //m_device_info_list.SetColor(theApp.m_app_setting_data.theme_color); + //m_device_info_list.SetColor(theApp.m_app_setting_data.theme_color); m_device_info_list.SetMouseWheelEnable(false); - CRect rect; - m_device_info_list.GetClientRect(rect); - int width0, width1; - width0 = theApp.DPI(70); - width1 = rect.Width() - width0 - theApp.DPI(20); + CRect rect; + m_device_info_list.GetClientRect(rect); + int width0, width1; + width0 = theApp.DPI(70); + width1 = rect.Width() - width0 - theApp.DPI(20); m_device_info_list.SetExtendedStyle(m_device_info_list.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_LABELTIP); - m_device_info_list.InsertColumn(0, CCommon::LoadText(IDS_ITEM), LVCFMT_LEFT, width0); //插入第1列 - m_device_info_list.InsertColumn(1, CCommon::LoadText(IDS_VLAUE), LVCFMT_LEFT, width1); //插入第2列 - m_device_info_list.InsertItem(0, CCommon::LoadText(IDS_NAME)); - m_device_info_list.InsertItem(1, CCommon::LoadText(IDS_DRIVER)); - m_device_info_list.InsertItem(2, CCommon::LoadText(IDS_DEVICE_TYPE)); - ShowDeviceInfo(); + m_device_info_list.InsertColumn(0, theApp.m_str_table.LoadText(L"TXT_ITEM").c_str(), LVCFMT_LEFT, width0); + m_device_info_list.InsertColumn(1, theApp.m_str_table.LoadText(L"TXT_VALUE").c_str(), LVCFMT_LEFT, width1); + m_device_info_list.InsertItem(0, theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_DEVICE_NAME").c_str()); + m_device_info_list.InsertItem(1, theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_DEVICE_DRIVER").c_str()); + m_device_info_list.InsertItem(2, theApp.m_str_table.LoadText(L"TXT_OPT_PLAY_DEVICE_TYPE").c_str()); + ShowDeviceInfo(); EnableControl(); - m_ffmpeg_cache_length.SetRange(1, 60); + m_ffmpeg_cache_length.SetRange(1, 60, 5); m_ffmpeg_cache_length.SetValue(theApp.m_play_setting_data.ffmpeg_core_cache_length); - m_ffmpeg_max_retry_count.SetRange(-1, SHORT_MAX); + m_ffmpeg_max_retry_count.SetRange(-1, 30); m_ffmpeg_max_retry_count.SetValue(theApp.m_play_setting_data.ffmpeg_core_max_retry_count); - m_ffmpeg_url_retry_interval.SetRange(1, 120); + m_ffmpeg_url_retry_interval.SetRange(1, 120, 5); m_ffmpeg_url_retry_interval.SetValue(theApp.m_play_setting_data.ffmpeg_core_url_retry_interval); - m_ffmpeg_enable_wasapi.SetCheck(theApp.m_play_setting_data.ffmpeg_core_enable_WASAPI); - m_ffmpeg_enable_wasapi_exclusive.SetCheck(theApp.m_play_setting_data.ffmpeg_core_enable_WASAPI_exclusive_mode); - m_ffmpeg_max_wait_time.SetRange(100, 30000); + CheckDlgButton(IDC_FFMPEG_ENABLE_WASAPI, theApp.m_play_setting_data.ffmpeg_core_enable_WASAPI); + CheckDlgButton(IDC_FFMPEG_ENABLE_WASAPI_EXCLUSIVE, theApp.m_play_setting_data.ffmpeg_core_enable_WASAPI_exclusive_mode); + m_ffmpeg_max_wait_time.SetRange(100, 30000, 100); m_ffmpeg_max_wait_time.SetValue(theApp.m_play_setting_data.ffmpeg_core_max_wait_time); //设置控件不响应鼠标滚轮消息 @@ -263,80 +290,16 @@ BOOL CPlaySettingsDlg::OnInitDialog() m_ffmpeg_url_retry_interval.SetMouseWheelEnable(false); m_ffmpeg_max_wait_time.SetMouseWheelEnable(false); - return TRUE; // return TRUE unless you set the focus to a control - // 异常: OCX 属性页应返回 FALSE -} - - -void CPlaySettingsDlg::OnBnClickedStopWhenError() -{ - // TODO: 在此添加控件通知处理程序代码 - m_data.stop_when_error = (m_stop_when_error_check.GetCheck() != 0); -} - - -void CPlaySettingsDlg::OnBnClickedShowTaskbarProgress() -{ - // TODO: 在此添加控件通知处理程序代码 - m_data.show_taskbar_progress = (m_show_taskbar_progress_check.GetCheck() != 0); + return TRUE; // return TRUE unless you set the focus to a control + // 异常: OCX 属性页应返回 FALSE } void CPlaySettingsDlg::OnCbnSelchangeOutputDeviceCombo() -{ - // TODO: 在此添加控件通知处理程序代码 - m_data.device_selected = m_output_device_combo.GetCurSel(); - ShowDeviceInfo(); -} - - -void CPlaySettingsDlg::OnBnClickedAutoPlayWhenStartCheck() -{ - // TODO: 在此添加控件通知处理程序代码 - m_data.auto_play_when_start = (m_auto_play_when_start_chk.GetCheck() != 0); -} - - -void CPlaySettingsDlg::OnBnClickedShowPlayStateIconCheck() -{ - // TODO: 在此添加控件通知处理程序代码 - m_data.show_playstate_icon = (m_show_play_state_icon_chk.GetCheck() != 0); -} - - -void CPlaySettingsDlg::OnBnClickedSoundFadeCheck() -{ - // TODO: 在此添加控件通知处理程序代码 - m_data.fade_effect = (m_sound_fade_chk.GetCheck() != 0); -} - - -void CPlaySettingsDlg::OnBnClickedContinueWhenSwitchPlaylistCheck() -{ - // TODO: 在此添加控件通知处理程序代码 - m_data.continue_when_switch_playlist = (m_continue_when_switch_playlist_check.GetCheck() != 0); -} - - -void CPlaySettingsDlg::OnBnClickedBassRadio() { // TODO: 在此添加控件通知处理程序代码 - m_data.use_mci = false; - m_data.use_ffmpeg = false; -} - - -void CPlaySettingsDlg::OnBnClickedMciRadio() -{ - // TODO: 在此添加控件通知处理程序代码 - m_data.use_mci = true; - m_data.use_ffmpeg = false; -} - - -void CPlaySettingsDlg::OnBnClickedFfmpegRadio() { - m_data.use_mci = false; - m_data.use_ffmpeg = true; + m_data.device_selected = m_output_device_combo.GetCurSel(); + ShowDeviceInfo(); } @@ -349,14 +312,12 @@ BOOL CPlaySettingsDlg::PreTranslateMessage(MSG* pMsg) return CTabDlg::PreTranslateMessage(pMsg); } -void CPlaySettingsDlg::OnOK() { -} - void CPlaySettingsDlg::OnNMClickFfmpegDownSyslink(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: 在此添加控件通知处理程序代码 - if (MessageBox(CCommon::LoadText(IDS_DOWNLOAD_FFMPEG_CORE_INFO), NULL, MB_ICONINFORMATION | MB_YESNO) == IDYES) + const wstring& info = theApp.m_str_table.LoadText(L"MSG_OPT_PLAY_CORE_FFMPEG_DL_INFO"); + if (MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_YESNO) == IDYES) { ShellExecute(NULL, _T("open"), _T("https://github.com/lifegpc/ffmpeg_core/releases"), NULL, NULL, SW_SHOW); } @@ -365,34 +326,7 @@ void CPlaySettingsDlg::OnNMClickFfmpegDownSyslink(NMHDR* pNMHDR, LRESULT* pResul } -HBRUSH CPlaySettingsDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) -{ - HBRUSH hbr = CTabDlg::OnCtlColor(pDC, pWnd, nCtlColor); - - // TODO: 在此更改 DC 的任何特性 - UINT id{}; - if (pWnd != nullptr) - id = pWnd->GetDlgCtrlID(); - if (id == IDC_FFMPEG_DOWN_SYSLINK) //设置滑动条控件的背景色为白色 - { - static HBRUSH brush{}; - if (brush == NULL) - brush = CreateSolidBrush(m_background_color); - pDC->SetBkColor(m_background_color); - return brush; - } - - // TODO: 如果默认的不是所需画笔,则返回另一个画笔 - return hbr; -} - - void CPlaySettingsDlg::OnBnClickedFfmpegEnableWasapi() { - m_data.ffmpeg_core_enable_WASAPI = (m_ffmpeg_enable_wasapi.GetCheck() != 0); - m_ffmpeg_enable_wasapi_exclusive.EnableWindow(m_ffmpeg_enable_wasapi.GetCheck()); -} - - -void CPlaySettingsDlg::OnBnClickedFfmpegEnableWasapiExclusive() { - m_data.ffmpeg_core_enable_WASAPI_exclusive_mode = (m_ffmpeg_enable_wasapi_exclusive.GetCheck() != 0); + m_data.ffmpeg_core_enable_WASAPI = (IsDlgButtonChecked(IDC_FFMPEG_ENABLE_WASAPI) != FALSE); + EnableDlgCtrl(IDC_FFMPEG_ENABLE_WASAPI_EXCLUSIVE, m_data.ffmpeg_core_enable_WASAPI); } diff --git a/MusicPlayer2/PlaySettingsDlg.h b/MusicPlayer2/PlaySettingsDlg.h index 6e9bd89f8..3b11f6d71 100644 --- a/MusicPlayer2/PlaySettingsDlg.h +++ b/MusicPlayer2/PlaySettingsDlg.h @@ -1,6 +1,6 @@ #pragma once -#include "ListCtrlEx.h" #include "TabDlg.h" +#include "ListCtrlEx.h" #include "MyComboBox.h" #include "SpinEdit.h" @@ -8,64 +8,42 @@ class CPlaySettingsDlg : public CTabDlg { - DECLARE_DYNAMIC(CPlaySettingsDlg) + DECLARE_DYNAMIC(CPlaySettingsDlg) public: - CPlaySettingsDlg(CWnd* pParent = nullptr); // 标准构造函数 - virtual ~CPlaySettingsDlg(); + CPlaySettingsDlg(CWnd* pParent = nullptr); // 标准构造函数 + virtual ~CPlaySettingsDlg(); - PlaySettingData m_data; + PlaySettingData m_data; // 对话框数据 #ifdef AFX_DESIGN_TIME - enum { IDD = IDD_PLAY_SETTING_DIALOG }; + enum { IDD = IDD_PLAY_SETTING_DIALOG }; #endif protected: - //控件变量 - CButton m_stop_when_error_check; - CButton m_auto_play_when_start_chk; - CButton m_show_taskbar_progress_check; - CButton m_show_play_state_icon_chk; - CButton m_sound_fade_chk; - CButton m_continue_when_switch_playlist_check; + //控件变量 CMyComboBox m_output_device_combo; - CListCtrlEx m_device_info_list; - CButton m_bass_radio; - CButton m_mci_radio; - CButton m_ffmpeg_radio; + CListCtrlEx m_device_info_list; CSpinEdit m_ffmpeg_cache_length; CSpinEdit m_ffmpeg_max_retry_count; CSpinEdit m_ffmpeg_url_retry_interval; CToolTipCtrl m_toolTip; - CButton m_ffmpeg_enable_wasapi; - CButton m_ffmpeg_enable_wasapi_exclusive; CSpinEdit m_ffmpeg_max_wait_time; protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 - - void ShowDeviceInfo(); + void ShowDeviceInfo(); void EnableControl(); + virtual void GetDataFromUi() override; virtual void ApplyDataToUi() override; + virtual bool InitializeControls() override; + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 - DECLARE_MESSAGE_MAP() + DECLARE_MESSAGE_MAP() public: - virtual void OnOK(); - virtual BOOL OnInitDialog(); - afx_msg void OnBnClickedStopWhenError(); - afx_msg void OnBnClickedShowTaskbarProgress(); - afx_msg void OnCbnSelchangeOutputDeviceCombo(); - afx_msg void OnBnClickedAutoPlayWhenStartCheck(); - afx_msg void OnBnClickedShowPlayStateIconCheck(); - afx_msg void OnBnClickedSoundFadeCheck(); - afx_msg void OnBnClickedContinueWhenSwitchPlaylistCheck(); - afx_msg void OnBnClickedBassRadio(); - afx_msg void OnBnClickedMciRadio(); - afx_msg void OnBnClickedFfmpegRadio(); + virtual BOOL OnInitDialog(); + afx_msg void OnCbnSelchangeOutputDeviceCombo(); virtual BOOL PreTranslateMessage(MSG* pMsg); afx_msg void OnNMClickFfmpegDownSyslink(NMHDR* pNMHDR, LRESULT* pResult); - afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); afx_msg void OnBnClickedFfmpegEnableWasapi(); - afx_msg void OnBnClickedFfmpegEnableWasapiExclusive(); }; diff --git a/MusicPlayer2/PlayTrackDlg.cpp b/MusicPlayer2/PlayTrackDlg.cpp deleted file mode 100644 index 08be00993..000000000 --- a/MusicPlayer2/PlayTrackDlg.cpp +++ /dev/null @@ -1,68 +0,0 @@ -// PlayTrackDlg.cpp : 实现文件 -// - -#include "stdafx.h" -#include "MusicPlayer2.h" -#include "PlayTrackDlg.h" -#include "afxdialogex.h" - - -// CPlayTrackDlg 对话框 - -IMPLEMENT_DYNAMIC(CPlayTrackDlg, CDialogEx) - -CPlayTrackDlg::CPlayTrackDlg(CWnd* pParent /*=NULL*/) - : CDialogEx(IDD_PLAY_TRACK_DIALOG, pParent) -{ - -} - -CPlayTrackDlg::~CPlayTrackDlg() -{ -} - -void CPlayTrackDlg::DoDataExchange(CDataExchange* pDX) -{ - CDialogEx::DoDataExchange(pDX); - DDX_Control(pDX, IDC_EDIT_TRACK, m_track_edit); -} - - -BEGIN_MESSAGE_MAP(CPlayTrackDlg, CDialogEx) - ON_EN_CHANGE(IDC_EDIT_TRACK, &CPlayTrackDlg::OnEnChangeEditTrack) -END_MESSAGE_MAP() - - -// CPlayTrackDlg 消息处理程序 - - -int CPlayTrackDlg::GetTrack() const -{ - return m_track; -} - -void CPlayTrackDlg::OnEnChangeEditTrack() -{ - // TODO: 如果该控件是 RICHEDIT 控件,它将不 - // 发送此通知,除非重写 CDialogEx::OnInitDialog() - // 函数并调用 CRichEditCtrl().SetEventMask(), - // 同时将 ENM_CHANGE 标志“或”运算到掩码中。 - - // TODO: 在此添加控件通知处理程序代码 - CString str; - m_track_edit.GetWindowText(str); - m_track = _wtoi(str); -} - - -BOOL CPlayTrackDlg::OnInitDialog() -{ - CDialogEx::OnInitDialog(); - - // TODO: 在此添加额外的初始化 - m_track_edit.SetLimitText(6); - m_track_edit.SetFocus(); //初始时将焦点设置到编辑控件 - - return FALSE; // return TRUE unless you set the focus to a control - // 异常: OCX 属性页应返回 FALSE -} diff --git a/MusicPlayer2/PlayTrackDlg.h b/MusicPlayer2/PlayTrackDlg.h deleted file mode 100644 index 98b8d2abc..000000000 --- a/MusicPlayer2/PlayTrackDlg.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once -#include "afxwin.h" - - -// CPlayTrackDlg 对话框 - -class CPlayTrackDlg : public CDialogEx -{ - DECLARE_DYNAMIC(CPlayTrackDlg) - -public: - CPlayTrackDlg(CWnd* pParent = NULL); // 标准构造函数 - virtual ~CPlayTrackDlg(); - -// 对话框数据 -#ifdef AFX_DESIGN_TIME - enum { IDD = IDD_PLAY_TRACK_DIALOG }; -#endif - -protected: - int m_track; - - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 - - DECLARE_MESSAGE_MAP() -public: - CEdit m_track_edit; - - int GetTrack() const; - afx_msg void OnEnChangeEditTrack(); - virtual BOOL OnInitDialog(); -}; diff --git a/MusicPlayer2/Player.cpp b/MusicPlayer2/Player.cpp index d860dcf5b..d8fc1a4b8 100644 --- a/MusicPlayer2/Player.cpp +++ b/MusicPlayer2/Player.cpp @@ -11,6 +11,7 @@ #include "SongInfoHelper.h" #include "RecentFolderAndPlaylist.h" #include +#include "IniHelper.h" CPlayer CPlayer::m_instance; @@ -82,7 +83,6 @@ void CPlayer::IniPlayerCore() m_pCore->InitCore(); } - m_controls.SetEnabled(theApp.m_play_setting_data.use_media_trans_control); } void CPlayer::UnInitPlayerCore() @@ -102,7 +102,7 @@ void CPlayer::Create() LoadConfig(); LoadRecentPath(); CPlaylistMgr::Instance().LoadPlaylistData(); - m_controls.Init(); + m_controls.InitSMTC(theApp.m_play_setting_data.use_media_trans_control); bool change_to_default_playlist{ !m_playlist_mode && (m_recent_path.empty() || (!COSUPlayerHelper::IsOsuFolder(m_recent_path.front().path) && !CAudioCommon::IsPathContainsAudioFile(m_recent_path.front().path, m_recent_path.front().contain_sub_folder))) }; // 如果文件夹模式且当前文件夹没有音频文件那么切换到默认播放列表,清理无效(空)文件夹会在启动时更新媒体库进行(如果启用remove_file_not_exist_when_update) if (change_to_default_playlist) @@ -128,7 +128,7 @@ void CPlayer::CreateWithFiles(const vector& files) LoadConfig(); LoadRecentPath(); CPlaylistMgr::Instance().LoadPlaylistData(); - m_controls.Init(); + m_controls.InitSMTC(theApp.m_play_setting_data.use_media_trans_control); OpenFilesInDefaultPlaylist(files); } @@ -139,7 +139,7 @@ void CPlayer::CreateWithPath(const wstring& path) LoadConfig(); LoadRecentPath(); CPlaylistMgr::Instance().LoadPlaylistData(); - m_controls.Init(); + m_controls.InitSMTC(theApp.m_play_setting_data.use_media_trans_control); OpenFolder(path); } @@ -150,12 +150,12 @@ void CPlayer::CreateWithPlaylist(const wstring& playlist_path) LoadConfig(); LoadRecentPath(); CPlaylistMgr::Instance().LoadPlaylistData(); - m_controls.Init(); + m_controls.InitSMTC(theApp.m_play_setting_data.use_media_trans_control); wstring playlist_path_{ playlist_path }; OpenPlaylistFile(playlist_path_); } -void CPlayer::IniPlayList(bool play, bool refresh_info) +void CPlayer::IniPlayList(bool play, MediaLibRefreshMode refresh_mode) { m_no_use = SongInfo{}; // 安全起见,防止意外写入被应用 m_playlist.clear(); @@ -176,107 +176,103 @@ void CPlayer::IniPlayList(bool play, bool refresh_info) CAudioCommon::GetAudioFiles(m_path, m_playlist, MAX_SONG_NUM, m_contain_sub_folder); } - m_index_tmp = m_index; // 保存歌曲序号,cue未解析情况下当前的m_index有可能超过当前歌曲数目,临时存储待cue解析后恢复 + m_thread_info.refresh_mode = refresh_mode; + m_thread_info.play = play; + m_thread_info.playlist_mode = m_playlist_mode; + m_thread_info.play_index = m_index; + m_index = 0; // 在初始化期间为维持程序其他部分不报错(可能需要(但不应该需要))保持m_playlist[m_index]有效 if (m_playlist.empty()) m_playlist.push_back(SongInfo{}); // 没有歌曲时向播放列表插入一个空的SongInfo对象 - m_thread_info.refresh_info = refresh_info; - m_thread_info.play = play; - m_thread_info.play_index = m_index_tmp; - //创建初始化播放列表的工作线程 m_pThread = AfxBeginThread(IniPlaylistThreadFunc, &m_thread_info); } UINT CPlayer::IniPlaylistThreadFunc(LPVOID lpParam) { - CCommon::SetThreadLanguage(theApp.m_general_setting_data.language); + CCommon::SetThreadLanguageList(theApp.m_str_table.GetLanguageTag()); ThreadInfo* pInfo = (ThreadInfo*)lpParam; wstring remove_list_path{ pInfo->remove_list_path }; SendMessage(theApp.m_pMainWnd->GetSafeHwnd(), WM_PLAYLIST_INI_START, (WPARAM)&remove_list_path, 0); - // 解析原始cue文件,对于m_playlist内已切分的分轨(is_cue == true)GetCueTracks不做任何处理 - // m_playlist内含原始cue文件时(文件夹模式)强制刷新才会生效,执行后仅file_path、track、is_cue可用 - CAudioCommon::GetCueTracks(GetInstance().m_playlist, GetInstance().GetPlayerCore(), pInfo->play_index, pInfo->refresh_info); - - //获取播放列表中每一首歌曲的信息 - int song_num = GetInstance().m_playlist.size(); - for (int i{}; i < song_num; i++) + // 播放列表模式下且play_index有效时重新查找play_index指向曲目,文件夹模式下play_index本就描述初始化完成的播放列表故无须改动 + SongInfo cur_song; + vector& play_list = GetInstance().m_playlist; + if (pInfo->playlist_mode && pInfo->play_index >= 0 && pInfo->play_index < static_cast(play_list.size())) + cur_song = play_list[pInfo->play_index]; + + bool exit_flag{}; + int update_cnt{}; + // 解析cue并更新所有曲目到媒体库,执行后仅file_path、track、is_cue可用 + // 此处不应设置ignore_short为true,因为现在正在初始化播放列表,如果读取到短文件却不保存有可能导致列表每次打开耗时都很长 + CAudioCommon::GetAudioInfo(play_list, update_cnt, exit_flag, pInfo->process_percent, pInfo->refresh_mode); + // 将媒体库内信息更新到播放列表 + CSongDataManager::GetInstance().LoadSongsInfo(play_list); + + bool find_succeed{ cur_song.file_path.empty() }; // 为true说明不必继续查找cur_song + // 重新查找当前播放 + if (!find_succeed) + { + for (auto iter = play_list.begin(); iter != play_list.end(); ++iter) + { + if (cur_song.IsSameSong(*iter)) + { + pInfo->play_index = iter - play_list.begin(); + find_succeed = true; + break; + } + } + } + // 如果没有找到那么说明受到了cue解析影响,有以下情况 + if (!find_succeed && cur_song.is_cue) { - SongInfo& song{ GetInstance().m_playlist[i] }; - if (song.file_path.empty()) - continue; - - pInfo->process_percent = i * 100 / song_num + 1; - - // 直接将各种信息更新到CSongDataManager,最后再直接存入m_playlist - SongInfo song_info{ CSongDataManager::GetInstance().GetSongInfo3(song) }; - - if (song_info.modified_time == 0 || pInfo->refresh_info) - song_info.modified_time = CCommon::GetFileLastModified(song_info.file_path); - - //如果要求强制刷新或没有获取过歌曲信息,则在这里获取 - if (!song_info.info_acquired || !song_info.ChannelInfoAcquired() || pInfo->refresh_info) + // cue解析前就是cue条目时上面IsSameSong搜索失败的可能性很低,只有cue编辑等偏门条件能触发 + // 这里按cue_file_path和track匹配查找 + for (auto iter = play_list.begin(); iter != play_list.end(); ++iter) { - bool is_osu_file{ COSUPlayerHelper::IsOsuFile(song_info.file_path) }; - int flag = AF_BITRATE | AF_CHANNEL_INFO; - if (!song_info.is_cue) - flag |= AF_LENGTH; - if (!is_osu_file && !song_info.is_cue && (!song_info.info_acquired || pInfo->refresh_info)) - flag |= AF_TAG_INFO; - GetInstance().GetPlayerCore()->GetAudioInfo(song_info.file_path.c_str(), song_info, flag); - - //更新CUE信息 - if (pInfo->refresh_info && song_info.is_cue) + if (!iter->is_cue) continue; + if (cur_song.track == iter->track && cur_song.cue_file_path == iter->cue_file_path) { - CAudioTag audio_tag(song_info); - audio_tag.GetAudioTag(); - //更新最后一个音轨的结束位置 - if (song_info.IsLastTrack()) - { - //获取音频文件的长度 - SongInfo song_info_temp; - song_info_temp.file_path = song_info.file_path; - GetInstance().GetPlayerCore()->GetAudioInfo(song_info.file_path.c_str(), song_info_temp, AF_LENGTH); - song_info.end_pos = song_info_temp.length(); - } + pInfo->play_index = iter - play_list.begin(); + find_succeed = true; + break; } - - if (is_osu_file) - COSUPlayerHelper::GetOSUAudioTitleArtist(song_info); - - song_info.info_acquired = true; - song_info.SetChannelInfoAcquired(true); - - if (!song_info.is_cue && !is_osu_file) + } + // 没有找到的话下面实质上是将此cue条目退化为“已被cue使用的原始音频”进行搜索 + } + // cur_song是cue原始文件/已被cue使用的原始音频/含内嵌cue的原始音频,播放其(FILE标签中的)第一条音轨 + if (!find_succeed) + { + int track{ INT_MAX }; + const wstring& find_str = cur_song.file_path; + for (auto iter = play_list.begin(); iter != play_list.end(); ++iter) + { + if (!iter->is_cue) continue; // 先判断开销较小的条件 + if (iter->track > track) continue; + if (find_str == iter->cue_file_path || find_str == iter->file_path) { - // 从文件获取分级信息,仅限支持的文件 - CAudioTag audio_tag(song_info); - audio_tag.GetAudioRating(); + track = iter->track; + pInfo->play_index = iter - play_list.begin(); + find_succeed = true; + if (track <= 1) // cue不存在比1小的音轨号所以不必继续搜索 + break; } - - CSongDataManager::GetInstance().AddItem(song_info); } - // 将媒体库内信息更新到播放列表 - CSongDataManager::GetInstance().LoadSongInfo(song); } + PostMessage(theApp.m_pMainWnd->GetSafeHwnd(), WM_PLAYLIST_INI_COMPLATE, 0, 0); return 0; } void CPlayer::IniPlaylistComplate() { - // 如果是播放列表模式则m_index_tmp可能在cue解析后变化,需重新更新(文件夹模式下m_thread_info.play_index会被处理为错误结果) - if (m_playlist_mode) - m_index = m_thread_info.play_index; - else - m_index = m_index_tmp; + m_index = m_thread_info.play_index; if (m_index < 0 || m_index >= GetSongNum()) { m_index = 0; // 确保当前歌曲序号不会超过歌曲总数 - m_current_position.fromInt(0); // m_index失效时同时清除进度(这样略有不足,理论上只要m_index指向的歌曲改变就应当清除进度,不过这需要PathInfo和PlaylistInfo改track为SongInfo(SongDataMapKey)) + m_current_position.fromInt(0); // m_index失效时同时清除进度(这样略有不足,理论上只要m_index指向的歌曲改变就应当清除进度,不过这需要PathInfo和PlaylistInfo改track为SongInfo(SongKey)) } //统计列表总时长 m_total_time = 0; @@ -295,6 +291,16 @@ void CPlayer::IniPlaylistComplate() ASSERT(m_playing == 0); // 对播放列表排序 + if (m_playlist_mode) // 播放列表模式默认状态必须为未排序 + { + ASSERT(m_sort_mode == SM_UNSORT); + m_sort_mode = SM_UNSORT; + } + else if (m_sort_mode == SM_UNSORT) // 文件夹模式不允许为未排序 + { + ASSERT(FALSE); + m_sort_mode = SM_U_FILE; + } if (!m_playlist_mode && m_playlist.size() > 1) SortPlaylist(true); @@ -335,7 +341,7 @@ void CPlayer::IniPlaylistComplate() m_album_cover.Destroy(); m_album_cover_blur.Destroy(); m_Lyrics = CLyrics(); - UpdateControlsMetadata(SongInfo()); + m_controls.UpdateControlsMetadata(SongInfo()); MediaTransControlsLoadThumbnailDefaultImage(); } @@ -443,7 +449,7 @@ void CPlayer::MusicControl(Command command, int volume_step) // VOLUME_UP和VOLUME_DOWN可在无法播放时使用 // stop和close也可以在m_index失效无法播放时使用(RemoveSong(s)) - if (command != Command::VOLUME_UP && command != Command::VOLUME_DOWN && command != Command::STOP && command != Command::CLOSE) + if (command != Command::VOLUME_ADJ && command != Command::STOP && command != Command::CLOSE) { if (!CCommon::IsURL(GetCurrentFilePath()) && !CCommon::FileExist(GetCurrentFilePath())) { @@ -466,7 +472,7 @@ void CPlayer::MusicControl(Command command, int volume_step) m_pCore->Open(cur_song.file_path.c_str()); GetPlayerCoreError(L"Open"); if (m_pCore->GetCoreType() == PT_BASS && GetBassHandle() == 0) - m_error_state = ES_FILE_CONNOT_BE_OPEN; + m_error_state = ES_FILE_CANNOT_BE_OPEN; m_file_opend = true; //获取音频类型 m_current_file_type = m_pCore->GetAudioType(); // 根据通道信息获取当前音频文件的类型 @@ -475,12 +481,8 @@ void CPlayer::MusicControl(Command command, int volume_step) CFilePathHelper file_path{ cur_song.file_path }; m_current_file_type = file_path.GetFileExtension(true); } - if (!IsPlaylistEmpty()) + if (!cur_song.file_path.empty()) { - if (!cur_song.is_cue) - { - m_pCore->GetAudioInfo(m_playlist[m_index], AF_LENGTH); - } //打开时获取专辑封面 SearchAlbumCover(); //初始化歌词 @@ -500,8 +502,8 @@ void CPlayer::MusicControl(Command command, int volume_step) else m_pCore->ClearReverb(); PostMessage(theApp.m_pMainWnd->m_hWnd, WM_MUSIC_STREAM_OPENED, 0, 0); - UpdateControlsMetadata(GetCurrentSongInfo()); - m_controls.UpdateControls(Command::STOP); // OPEN时设置为停止,PLAY时再设置为PLAY + m_controls.UpdateControlsMetadata(GetCurrentSongInfo()); + m_controls.UpdateControls(PlaybackStatus::Closed); // OPEN时设置为停止,PLAY时再设置为PLAY m_enable_lastfm = theApp.m_media_lib_setting_data.enable_lastfm; if (m_enable_lastfm) { UpdateLastFMCurrentTrack(GetCurrentSongInfo()); @@ -513,7 +515,7 @@ void CPlayer::MusicControl(Command command, int volume_step) m_pCore->Play(); m_playing = PS_PLAYING; GetPlayerCoreError(L"Play"); - m_controls.UpdateControls(Command::PLAY); + m_controls.UpdateControls(PlaybackStatus::Playing); MediaTransControlsLoadThumbnailDefaultImage(); break; case Command::CLOSE: @@ -522,12 +524,12 @@ void CPlayer::MusicControl(Command command, int volume_step) m_pCore->Close(); m_playing = PS_STOPED; SendMessage(theApp.m_pMainWnd->GetSafeHwnd(), WM_AFTER_MUSIC_STREAM_CLOSED, 0, 0); - m_controls.UpdateControls(Command::STOP); + m_controls.UpdateControls(PlaybackStatus::Closed); break; case Command::PAUSE: m_pCore->Pause(); m_playing = PS_PAUSED; - m_controls.UpdateControls(Command::PAUSE); + m_controls.UpdateControls(PlaybackStatus::Paused); MediaTransControlsLoadThumbnailDefaultImage(); break; case Command::STOP: @@ -543,7 +545,7 @@ void CPlayer::MusicControl(Command command, int volume_step) m_playing = PS_STOPED; m_current_position = Time(); memset(m_spectral_data, 0, sizeof(m_spectral_data)); //停止时清除频谱分析的数据 - m_controls.UpdateControls(Command::STOP); + m_controls.UpdateControls(PlaybackStatus::Stopped); MediaTransControlsLoadThumbnailDefaultImage(); break; case Command::FF: //快进 @@ -566,7 +568,7 @@ void CPlayer::MusicControl(Command command, int volume_step) { m_pCore->Pause(); m_playing = PS_PAUSED; - m_controls.UpdateControls(Command::PAUSE); + m_controls.UpdateControls(PlaybackStatus::Paused); } else { @@ -574,27 +576,15 @@ void CPlayer::MusicControl(Command command, int volume_step) m_pCore->Play(); m_playing = PS_PLAYING; GetPlayerCoreError(L"Play"); - m_controls.UpdateControls(Command::PLAY); + m_controls.UpdateControls(PlaybackStatus::Playing); } MediaTransControlsLoadThumbnailDefaultImage(); break; - case Command::VOLUME_UP: - if (m_volume < 100) - { - m_volume += volume_step; - if (m_volume > 100) m_volume = 100; - SetVolume(); - //SaveConfig(); - } - break; - case Command::VOLUME_DOWN: - if (m_volume > 0) - { - m_volume -= volume_step; - if (m_volume < 0) m_volume = 0; - SetVolume(); - //SaveConfig(); - } + case Command::VOLUME_ADJ: + m_volume += volume_step; + if (m_volume > 100) m_volume = 100; + if (m_volume < 0) m_volume = 0; + SetVolume(); break; case Command::SEEK: //定位到m_current_position的位置 if (m_current_position > m_song_length) @@ -610,39 +600,11 @@ void CPlayer::MusicControl(Command command, int volume_step) bool CPlayer::SongIsOver() const { - const SongInfo& current_song{ GetCurrentSongInfo() }; - if ((current_song.is_cue && !current_song.IsLastTrack()) || IsMciCore()) - { + if (m_pCore->SongIsOver()) + return true; + if (GetCurrentSongInfo().is_cue || IsMciCore()) return (m_playing == PS_PLAYING && m_current_position >= m_song_length && m_current_position.toInt() != 0); - } - else - { - return m_pCore->SongIsOver(); - - //bool song_is_over{ false }; - //static int last_pos; - //if ((m_playing == PS_PLAYING && m_current_position.toInt() == last_pos && m_current_position.toInt() != 0 //如果正在播放且当前播放的位置没有发生变化且当前播放位置不为0, - // && m_current_position.toInt() > m_song_length.toInt() - 1000) //且播放进度到了最后1秒 - // || m_error_code == BASS_ERROR_ENDED) //或者出现BASS_ERROR_ENDED错误,则判断当前歌曲播放完了 - ////有时候会出现识别的歌曲长度超过实际歌曲长度的问题,这样会导致歌曲播放进度超过实际歌曲结尾时会出现BASS_ERROR_ENDED错误, - ////检测到这个错误时直接判断歌曲已经播放完了。 - // song_is_over = true; - - ////static int progress_no_change_cnt{}; - ////if (m_current_position.toInt() == last_pos) - //// progress_no_change_cnt++; - ////else - //// progress_no_change_cnt = 0; - - ////if (m_playing == 2 && progress_no_change_cnt > 10) //如果正在播放而且播放进度连续指定次数都没有变化,也判断歌曲播放完了。 - //// song_is_over = true; - - //last_pos = m_current_position.toInt(); - //return song_is_over; - ////这里本来直接使用return current_position_int>=m_song_length_int来判断歌曲播放完了, - ////但是BASS音频库在播放时可能会出现当前播放位置一直无法到达歌曲长度位置的问题, - ////这样函数就会一直返回false。 - } + return false; } void CPlayer::GetPlayerCoreCurrentPosition() @@ -979,7 +941,6 @@ void CPlayer::SaveRecentInfoToFiles(bool save_playlist) path_info.track = m_index; path_info.position = m_current_position.toInt(); path_info.sort_mode = m_sort_mode; - path_info.descending = m_descending; path_info.track_num = GetSongNum(); path_info.total_time = m_total_time; path_info.contain_sub_folder = m_contain_sub_folder; @@ -1020,7 +981,6 @@ bool CPlayer::SetPath(const PathInfo& path_info, bool play) m_playlist_path.clear(); m_playlist_mode = false; m_sort_mode = path_info.sort_mode; - m_descending = path_info.descending; m_contain_sub_folder = path_info.contain_sub_folder; m_index = path_info.track; m_current_position.fromInt(path_info.position); @@ -1038,8 +998,7 @@ bool CPlayer::OpenFolder(wstring path, bool contain_sub_folder, bool play) m_path = path; m_playlist_path.clear(); m_playlist_mode = false; - m_sort_mode = SM_FILE; - m_descending = false; + m_sort_mode = SM_U_FILE; m_contain_sub_folder = contain_sub_folder; m_index = 0; m_current_position.fromInt(0); @@ -1051,7 +1010,6 @@ bool CPlayer::OpenFolder(wstring path, bool contain_sub_folder, bool play) { const PathInfo& path_info = *iter; m_sort_mode = path_info.sort_mode; - m_descending = path_info.descending; m_index = path_info.track; m_current_position.fromInt(path_info.position); } @@ -1068,8 +1026,7 @@ bool CPlayer::SetPlaylist(const wstring& playlist_path, int track, int position, m_path.clear(); m_playlist_path = playlist_path; m_playlist_mode = true; - m_sort_mode = SM_FILE; - m_descending = false; + m_sort_mode = SM_UNSORT; // 播放列表模式下默认未排序 m_contain_sub_folder = false; m_index = track; m_current_position.fromInt(position); @@ -1119,8 +1076,7 @@ bool CPlayer::OpenSongsInDefaultPlaylist(const vector& songs, bool pla m_path.clear(); m_playlist_path = CPlaylistMgr::Instance().m_default_playlist.path; m_playlist_mode = true; - m_sort_mode = SM_FILE; - m_descending = false; + m_sort_mode = SM_UNSORT; // 播放列表模式下默认未排序 m_contain_sub_folder = false; m_index = 0; m_current_position.fromInt(0); @@ -1146,16 +1102,13 @@ bool CPlayer::OpenSongsInTempPlaylist(const vector& songs, int play_in m_path.clear(); m_playlist_path = CPlaylistMgr::Instance().m_temp_playlist.path; m_playlist_mode = true; - m_sort_mode = SM_FILE; - m_descending = false; + m_sort_mode = SM_UNSORT; // 播放列表模式下默认未排序 m_contain_sub_folder = false; m_index = play_index; m_current_position.fromInt(0); // 向播放列表文件覆写songs - CPlaylistFile playlist; - playlist.FromSongList(songs); - playlist.SaveToFile(m_playlist_path); + CPlaylistFile::SavePlaylistToFile(songs, m_playlist_path); IniPlayList(play); return true; @@ -1171,8 +1124,7 @@ bool CPlayer::OpenASongInFolderMode(const SongInfo& song, bool play) m_path = file_path.GetDir(); m_playlist_path.clear(); m_playlist_mode = false; - m_sort_mode = SM_FILE; - m_descending = false; + m_sort_mode = SM_U_FILE; m_contain_sub_folder = false; m_index = 0; m_current_position.fromInt(0); @@ -1184,7 +1136,6 @@ bool CPlayer::OpenASongInFolderMode(const SongInfo& song, bool play) { const PathInfo& path_info = *iter; m_sort_mode = path_info.sort_mode; - m_descending = path_info.descending; m_contain_sub_folder = path_info.contain_sub_folder; m_index = path_info.track; m_current_position.fromInt(path_info.position); @@ -1221,6 +1172,7 @@ int CPlayer::AddSongsToPlaylist(const vector& songs) int added = playlist.AddSongsToPlaylist(songs, theApp.m_media_lib_setting_data.insert_begin_of_playlist); playlist.SaveToFile(m_playlist_path); + m_sort_mode = SM_UNSORT; // 播放列表模式下的修改会失去排序状态 m_index = 0; m_current_position.fromInt(0); @@ -1228,15 +1180,16 @@ int CPlayer::AddSongsToPlaylist(const vector& songs) return added; } -bool CPlayer::ReloadPlaylist(bool refresh_info) +bool CPlayer::ReloadPlaylist(MediaLibRefreshMode refresh_mode) { if (!BeforeIniPlayList(true, true)) return false; + m_sort_mode = SM_UNSORT; // 播放列表模式默认未排序 m_index = 0; m_current_position.fromInt(0); - IniPlayList(false, refresh_info); + IniPlayList(false, refresh_mode); return true; } @@ -1245,7 +1198,7 @@ bool CPlayer::SetContainSubFolder() if (!IsPlaylistMode()) { m_contain_sub_folder = !m_contain_sub_folder; - if (ReloadPlaylist(false)) + if (ReloadPlaylist(MR_MIN_REQUIRED)) return true; else { @@ -1272,8 +1225,7 @@ bool CPlayer::RemoveCurPlaylistOrFolder() m_path.clear(); m_playlist_path = def_playlist.path; m_playlist_mode = true; - m_sort_mode = SM_FILE; - m_descending = false; + m_sort_mode = SM_UNSORT; // 播放列表模式默认未排序 m_contain_sub_folder = false; m_index = def_playlist.track; m_current_position.fromInt(def_playlist.position); @@ -1376,11 +1328,12 @@ std::wstring CPlayer::GetErrorInfo() { wstring error_info; if (m_error_state == ES_FILE_NOT_EXIST) - error_info = CCommon::LoadText(IDS_FILE_NOT_EXIST).GetString(); - else if (m_error_state == ES_FILE_CONNOT_BE_OPEN) - error_info = CCommon::LoadText(IDS_FILE_CONNOT_BE_OPEND).GetString(); + error_info = theApp.m_str_table.LoadText(L"UI_TXT_PLAYSTATUS_ERROR_FILE_NOT_EXIST"); + else if (m_error_state == ES_FILE_CANNOT_BE_OPEN) + error_info = theApp.m_str_table.LoadText(L"UI_TXT_PLAYSTATUS_ERROR_FILE_CANNOT_BE_OPEND"); else error_info = m_pCore->GetErrorInfo(); + error_info = theApp.m_str_table.LoadTextFormat(L"UI_TXT_PLAYSTATUS_ERROR_2", { error_info }); return error_info; } @@ -1556,11 +1509,11 @@ wstring CPlayer::GetCurrentFolderOrPlaylistName() const CFilePathHelper file_path{ m_playlist_path }; wstring playlist_name = file_path.GetFileName(); if (playlist_name == DEFAULT_PLAYLIST_NAME) - return wstring(CCommon::LoadText(_T("["), IDS_DEFAULT, _T("]"))); + return theApp.m_str_table.LoadText(L"TXT_PLAYLIST_NAME_DEFAULT"); else if (playlist_name == FAVOURITE_PLAYLIST_NAME) - return wstring(CCommon::LoadText(_T("["), IDS_MY_FAVURITE, _T("]"))); + return theApp.m_str_table.LoadText(L"TXT_PLAYLIST_NAME_FAVOURITE"); else if (playlist_name == TEMP_PLAYLIST_NAME) - return wstring(CCommon::LoadText(_T("["), IDS_TEMP_PLAYLIST, _T("]"))); + return theApp.m_str_table.LoadText(L"TXT_PLAYLIST_NAME_TEMP"); else return file_path.GetFileNameWithoutExtension(); } @@ -1583,22 +1536,17 @@ wstring CPlayer::GetCurrentFilePath() const return wstring(); } -wstring CPlayer::GetFileName() const -{ - wstring file_name{ GetCurrentSongInfo().GetFileName() }; - if (file_name.empty()) - return CCommon::LoadText(IDS_FILE_NOT_FOUND).GetString(); - return file_name; -} - wstring CPlayer::GetDisplayName() const { - if (GetCurrentSongInfo().is_cue && !GetCurrentSongInfo().IsArtistEmpty() && !GetCurrentSongInfo().IsTitleEmpty()) - return GetCurrentSongInfo().artist + L" - " + GetCurrentSongInfo().title; - if (IsOsuFile() && !GetCurrentSongInfo().comment.empty()) - return GetCurrentSongInfo().comment; - else - return GetFileName(); + const SongInfo& song = GetCurrentSongInfo(); + if (song.is_cue && !song.IsArtistEmpty() && !song.IsTitleEmpty()) + return song.artist + L" - " + song.title; + if (IsOsuFile() && !song.comment.empty()) + return song.comment; + wstring file_name = GetCurrentSongInfo().GetFileName(); + if (!file_name.empty()) + return file_name; + return theApp.m_str_table.LoadText(L"TXT_EMPTY_FILE_NAME"); } CImage& CPlayer::GetAlbumCover() @@ -1622,6 +1570,19 @@ bool CPlayer::AlbumCoverExist() return !m_album_cover.IsNull(); } +wstring CPlayer::GetAlbumCoverType() const +{ + // TagLibHelper.cpp中GetPicType的反向方法,之后需要重构,跳过int转手 + switch (m_album_cover_type) + { + case 0: return L"jpg"; + case 1: return L"png"; + case 2: return L"gif"; + case 3: return L"bmp"; + default: return L"other"; + } +} + void CPlayer::AfterRemoveSong(bool is_current) { if (is_current) @@ -1636,7 +1597,7 @@ void CPlayer::AfterRemoveSong(bool is_current) m_album_cover.Destroy(); m_album_cover_blur.Destroy(); m_Lyrics = CLyrics(); - UpdateControlsMetadata(SongInfo()); + m_controls.UpdateControlsMetadata(SongInfo()); MediaTransControlsLoadThumbnailDefaultImage(); } else // 播放列表不为空时先确保索引有效再打开/播放(最接近的曲目) @@ -1760,6 +1721,7 @@ int CPlayer::RemoveInvalidSongs() { if (!CCommon::FileExist(m_playlist[i].file_path) || m_playlist[i].length().isZero()) { + m_playlist.erase(m_playlist.begin() + i); if (i == m_index) rm_is_index = true; removed++; @@ -1770,6 +1732,7 @@ int CPlayer::RemoveInvalidSongs() if (removed) AfterRemoveSong(rm_is_index); + GetPlayStatusMutex().unlock(); return removed; } @@ -1806,6 +1769,7 @@ bool CPlayer::MoveUp(int first, int last) { std::swap(m_playlist[i - 1], m_playlist[i]); } + m_sort_mode = SM_UNSORT; // 修改会失去排序状态 OnPlaylistChange(); SaveCurrentPlaylist(); return true; @@ -1830,6 +1794,7 @@ bool CPlayer::MoveDown(int first, int last) { std::swap(m_playlist[i], m_playlist[i - 1]); } + m_sort_mode = SM_UNSORT; // 修改会失去排序状态 OnPlaylistChange(); SaveCurrentPlaylist(); return true; @@ -1903,6 +1868,7 @@ int CPlayer::MoveItems(std::vector indexes, int dest) else m_index = iter_play - m_playlist.begin(); + m_sort_mode = SM_UNSORT; // 修改会失去排序状态 OnPlaylistChange(); SaveCurrentPlaylist(); return dest_index; @@ -1954,22 +1920,23 @@ wstring CPlayer::GetTimeString() const wstring CPlayer::GetPlayingState() const { - static CString str_paly_error = CCommon::LoadText(IDS_PLAY_ERROR); - static CString str_stoped = CCommon::LoadText(IDS_STOPED); - static CString str_paused = CCommon::LoadText(IDS_PAUSED); - static CString str_playing = CCommon::LoadText(IDS_NOW_PLAYING); + static wstring str_paly_error = theApp.m_str_table.LoadText(L"UI_TXT_PLAYSTATUS_ERROR"); + static wstring str_stoped = theApp.m_str_table.LoadText(L"UI_TXT_PLAYSTATUS_STOPED"); + static wstring str_paused = theApp.m_str_table.LoadText(L"UI_TXT_PLAYSTATUS_PAUSED"); + static wstring str_playing = theApp.m_str_table.LoadText(L"UI_TXT_PLAYSTATUS_PLAYING"); if (m_error_code != 0) - return str_paly_error.GetString(); + return str_paly_error; switch (m_playing) { case PS_STOPED: - return str_stoped.GetString(); + return str_stoped; case PS_PAUSED: - return str_paused.GetString(); + return str_paused; case PS_PLAYING: - return str_playing.GetString(); + return str_playing; + default: + return wstring(); } - return wstring(); } const SongInfo& CPlayer::GetCurrentSongInfo() const @@ -2037,24 +2004,6 @@ SongInfo CPlayer::GetNextTrack() const } } -void CPlayer::SetRelatedSongID(wstring song_id) -{ - if (m_index >= 0 && m_index < GetSongNum()) - { - m_playlist[m_index].SetSongId(song_id); - CSongDataManager::GetInstance().SaveSongInfo(m_playlist[m_index]); - } -} - -void CPlayer::SetRelatedSongID(int index, wstring song_id) -{ - if (index >= 0 && index < GetSongNum()) - { - m_playlist[index].SetSongId(song_id); - CSongDataManager::GetInstance().SaveSongInfo(m_playlist[m_index]); - } -} - void CPlayer::SetFavourite(bool favourite) { if (IsError()) @@ -2062,10 +2011,6 @@ void CPlayer::SetFavourite(bool favourite) if (m_index >= 0 && m_index < GetSongNum()) { m_playlist[m_index].is_favourite = favourite; - //if (!m_playlist[m_index].is_cue) - //{ - // theApp.SaveSongInfo(m_playlist[m_index]); - //} } if (theApp.m_media_lib_setting_data.enable_lastfm) { theApp.UpdateLastFMFavourite(favourite); @@ -2088,7 +2033,7 @@ void CPlayer::AddListenTime(int sec) { if (m_index >= 0 && m_index < GetSongNum()) { - //m_playlist[m_index].listen_time += sec; + m_playlist[m_index].listen_time += sec; // m_playlist的信息不会保存到媒体库,此处仅为排序维护 SongInfo song_info{ CSongDataManager::GetInstance().GetSongInfo3(m_playlist[m_index]) }; song_info.listen_time += sec; CSongDataManager::GetInstance().AddItem(song_info); @@ -2157,58 +2102,28 @@ void CPlayer::SortPlaylist(bool is_init) if (m_loading && !is_init) return; CWaitCursor wait_cursor; SongInfo current_song = GetCurrentSongInfo(); + auto sort_fun = SongInfo::ByFileName; switch (m_sort_mode) { - case SM_FILE: - if (m_descending) - std::stable_sort(m_playlist.begin(), m_playlist.end(), SongInfo::ByFileNameDecending); - else - std::stable_sort(m_playlist.begin(), m_playlist.end(), SongInfo::ByFileName); - break; - case SM_PATH: - if (m_descending) - std::stable_sort(m_playlist.begin(), m_playlist.end(), SongInfo::ByPathDecending); - else - std::stable_sort(m_playlist.begin(), m_playlist.end(), SongInfo::ByPath); - break; - case SM_TITLE: - if (m_descending) - std::stable_sort(m_playlist.begin(), m_playlist.end(), SongInfo::ByTitleDecending); - else - std::stable_sort(m_playlist.begin(), m_playlist.end(), SongInfo::ByTitle); - break; - case SM_ARTIST: - if (m_descending) - std::stable_sort(m_playlist.begin(), m_playlist.end(), SongInfo::ByArtistDecending); - else - std::stable_sort(m_playlist.begin(), m_playlist.end(), SongInfo::ByArtist); - break; - case SM_ALBUM: - if (m_descending) - std::stable_sort(m_playlist.begin(), m_playlist.end(), SongInfo::ByAlbumDecending); - else - std::stable_sort(m_playlist.begin(), m_playlist.end(), SongInfo::ByAlbum); - break; - case SM_TRACK: - if (m_descending) - std::stable_sort(m_playlist.begin(), m_playlist.end(), SongInfo::ByTrackDecending); - else - std::stable_sort(m_playlist.begin(), m_playlist.end(), SongInfo::ByTrack); - break; - case SM_TIME: - std::stable_sort(m_playlist.begin(), m_playlist.end(), [&](const SongInfo& a, const SongInfo& b) - { - unsigned __int64 file_time_a = a.modified_time; - unsigned __int64 file_time_b = b.modified_time; - if (m_descending) - return file_time_a > file_time_b; - else - return file_time_a < file_time_b; - }); - break; - default: - break; - } + case SM_U_FILE: sort_fun = SongInfo::ByFileName; break; + case SM_D_FILE: sort_fun = SongInfo::ByFileNameDecending; break; + case SM_U_PATH: sort_fun = SongInfo::ByPath; break; + case SM_D_PATH: sort_fun = SongInfo::ByPathDecending; break; + case SM_U_TITLE: sort_fun = SongInfo::ByTitle; break; + case SM_D_TITLE: sort_fun = SongInfo::ByTitleDecending; break; + case SM_U_ARTIST: sort_fun = SongInfo::ByArtist; break; + case SM_D_ARTIST: sort_fun = SongInfo::ByArtistDecending; break; + case SM_U_ALBUM: sort_fun = SongInfo::ByAlbum; break; + case SM_D_ALBUM: sort_fun = SongInfo::ByAlbumDecending; break; + case SM_U_TRACK: sort_fun = SongInfo::ByTrack; break; + case SM_D_TRACK: sort_fun = SongInfo::ByTrackDecending; break; + case SM_U_LISTEN: sort_fun = SongInfo::ByListenTime; break; + case SM_D_LISTEN: sort_fun = SongInfo::ByListenTimeDecending; break; + case SM_U_TIME: sort_fun = SongInfo::ByModifiedTime; break; + case SM_D_TIME: sort_fun = SongInfo::ByModifiedTimeDecending; break; + default: ASSERT(FALSE); break; + } + std::stable_sort(m_playlist.begin(), m_playlist.end(), sort_fun); if (!is_init) // 由初始化完成方法调用时不重新查找index { @@ -2226,20 +2141,6 @@ void CPlayer::SortPlaylist(bool is_init) SaveCurrentPlaylist(); } - -void CPlayer::InvertPlaylist() -{ - if (m_loading) return; - - //播放列表倒序 - std::reverse(m_playlist.begin(), m_playlist.end()); - //当前播放曲目更改 - m_index = m_playlist.size() - m_index - 1; - - OnPlaylistChange(); - SaveCurrentPlaylist(); -} - void CPlayer::SaveRecentPath() const { // 打开或者新建文件 @@ -2253,7 +2154,7 @@ void CPlayer::SaveRecentPath() const // 构造CArchive对象 CArchive ar(&file, CArchive::store); // 写数据 - const unsigned int version{ 3u }; + const unsigned int version{ 4u }; ar << static_cast(m_recent_path.size()); //写入m_recent_path容器的大小 ar << version; //写入文件的版本 for (auto& path_info : m_recent_path) @@ -2262,7 +2163,6 @@ void CPlayer::SaveRecentPath() const << path_info.track << path_info.position << static_cast(path_info.sort_mode) - << static_cast(path_info.descending) << path_info.track_num << path_info.total_time << static_cast(path_info.contain_sub_folder) @@ -2321,11 +2221,21 @@ void CPlayer::LoadRecentPath() ar >> path_info.position; ar >> sort_mode; path_info.sort_mode = static_cast(sort_mode); - if (version >= 2) + if (version >= 2 && version <= 3) // 在版本4变量descending不再独立存储,功能整合到sort_mode内,这里做读取兼容 { BYTE descending; ar >> descending; - path_info.descending = (descending != 0); + switch (sort_mode) + { + case 0: path_info.sort_mode = descending ? SM_D_FILE : SM_U_FILE; break; + case 1: path_info.sort_mode = descending ? SM_D_PATH : SM_U_PATH; break; + case 2: path_info.sort_mode = descending ? SM_D_TITLE : SM_U_TITLE; break; + case 3: path_info.sort_mode = descending ? SM_D_ARTIST : SM_U_ARTIST; break; + case 4: path_info.sort_mode = descending ? SM_D_ALBUM : SM_U_ALBUM; break; + case 5: path_info.sort_mode = descending ? SM_D_TRACK : SM_U_TRACK; break; + case 6: path_info.sort_mode = descending ? SM_D_TIME : SM_U_TIME; break; + default: break; + } } ar >> path_info.track_num; ar >> path_info.total_time; @@ -2347,9 +2257,8 @@ void CPlayer::LoadRecentPath() catch (CArchiveException* exception) { //捕获序列化时出现的异常 - CString info; - info = CCommon::LoadTextFormat(IDS_RECENT_PATH_SERIALIZE_ERROR_LOG, { exception->m_cause }); - theApp.WriteLog(wstring{ info }); + wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_SERIALIZE_ERROR", { theApp.m_recent_path_dat_path, exception->m_cause }); + theApp.WriteLog(info); } // 关闭对象 ar.Close(); @@ -2360,11 +2269,7 @@ void CPlayer::LoadRecentPath() void CPlayer::SaveCurrentPlaylist() { if (m_playlist_mode) - { - CPlaylistFile playlist; - playlist.FromSongList(m_playlist); - playlist.SaveToFile(m_playlist_path); - } + CPlaylistFile::SavePlaylistToFile(m_playlist, m_playlist_path); } //void CPlayer::SetFXHandle() @@ -2531,7 +2436,7 @@ void CPlayer::SearchAlbumCover() { m_album_cover.Load(m_album_cover_path.c_str()); AlbumCoverResize(); - MediaTransControlsLoadThumbnail(m_album_cover_path); + MediaTransControlsLoadThumbnail(); } } m_inner_cover = !m_album_cover.IsNull(); @@ -2651,7 +2556,7 @@ void CPlayer::SearchOutAlbumCover() m_album_cover.Destroy(); m_album_cover.Load(m_album_cover_path.c_str()); AlbumCoverResize(); - MediaTransControlsLoadThumbnail(m_album_cover_path); + MediaTransControlsLoadThumbnail(); } bool CPlayer::IsOsuFile() const @@ -2688,28 +2593,22 @@ bool CPlayer::IsFfmpegCore() const { return m_pCore ? m_pCore->GetCoreType() == PT_FFMPEG : false; } -void CPlayer::UpdateControlsMetadata(SongInfo info) -{ - m_controls.UpdateDuration(info.length().toInt()); - m_controls.UpdateControlsMetadata(info); -} - -void CPlayer::MediaTransControlsLoadThumbnail(std::wstring& file_path) +void CPlayer::MediaTransControlsLoadThumbnail() { - if (CCommon::FileExist(file_path)) + if (CCommon::FileExist(m_album_cover_path)) { - if (CCommon::IsFileHidden(file_path)) + if (CCommon::IsFileHidden(m_album_cover_path)) { //如果专辑封面图片文件已隐藏,先将文件复制到Temp目录,再取消隐藏属性 wstring temp_img_path{ CCommon::GetTemplatePath() + ALBUM_COVER_TEMP_NAME2 }; - CopyFile(file_path.c_str(), temp_img_path.c_str(), FALSE); + CopyFile(m_album_cover_path.c_str(), temp_img_path.c_str(), FALSE); CCommon::SetFileHidden(temp_img_path, false); m_controls.loadThumbnail(temp_img_path); } else { //专辑封面图片文件未隐藏 - m_controls.loadThumbnail(file_path); + m_controls.loadThumbnail(m_album_cover_path); } } else @@ -2723,13 +2622,13 @@ void CPlayer::MediaTransControlsLoadThumbnailDefaultImage() if (m_album_cover.IsNull()) { if (IsPlaying()) - m_controls.loadThumbnail((const BYTE*)theApp.m_image_set.default_cover_data.data(), theApp.m_image_set.default_cover_data.size()); + m_controls.loadThumbnail((const BYTE*)theApp.m_image_set.default_cover_img_data.data(), theApp.m_image_set.default_cover_img_data.size()); else - m_controls.loadThumbnail((const BYTE*)theApp.m_image_set.default_cover_not_played_data.data(), theApp.m_image_set.default_cover_not_played_data.size()); + m_controls.loadThumbnail((const BYTE*)theApp.m_image_set.default_cover_not_played_img_data.data(), theApp.m_image_set.default_cover_not_played_img_data.size()); } } -void CPlayer::UpdateLastFMCurrentTrack(SongInfo info) { +void CPlayer::UpdateLastFMCurrentTrack(const SongInfo& info) { LastFMTrack track; track.ReadDataFrom(info); auto& current = theApp.m_lastfm.CurrentTrack(); diff --git a/MusicPlayer2/Player.h b/MusicPlayer2/Player.h index d00aba5b5..56eadd8cf 100644 --- a/MusicPlayer2/Player.h +++ b/MusicPlayer2/Player.h @@ -1,18 +1,15 @@ #pragma once #include"Common.h" #include"Lyric.h" -#include"SetPathDlg.h" #include"AudioTag.h" #include "FilePathHelper.h" #include "BASSMidiLibrary.h" -//#include"MusicPlayerDlg.h" #include "GaussBlur.h" #include "PlaylistMgr.h" #include "IPlayerCore.h" #include "BassCore.h" #include "SpectralDataHelper.h" #include "MediaTransControls.h" -#include #define WM_PLAYLIST_INI_START (WM_USER+104) // 播放列表开始加载时的消息 #define WM_PLAYLIST_INI_COMPLATE (WM_USER+105) // 播放列表加载完成消息 @@ -52,8 +49,9 @@ class CPlayer //用于向初始化播放列表传递信息的结构体 struct ThreadInfo { - bool refresh_info{}; + MediaLibRefreshMode refresh_mode{}; bool play{}; // 加载完播放列表后是否立即播放 + bool playlist_mode{}; // 是否为播放列表模式 int play_index{}; // 播放索引,播放列表模式下需要在cue解析时维持其指向 int process_percent{}; wstring remove_list_path{}; // 进入初始化线程后通知主窗口移除此播放列表/文件夹 @@ -66,7 +64,7 @@ class CPlayer { ES_NO_ERROR, ES_FILE_NOT_EXIST, - ES_FILE_CONNOT_BE_OPEN + ES_FILE_CANNOT_BE_OPEN }; enum ABRepeatMode //AB循环的模式 @@ -137,7 +135,6 @@ class CPlayer CLyrics m_Lyrics; //歌词 SortMode m_sort_mode; //排序方式 - bool m_descending{}; //是否降序排列 bool m_loading{ false }; //如果正在载入播放列表,则为true @@ -172,8 +169,8 @@ class CPlayer // 此方法进行重新填充m_playlist以及一些共有操作,最后会启动初始化播放列表线程函数,调用前必须停止播放 // 调用完此方法后请尽快返回并且尽量不要执行任何操作,应当提前进行或安排在IniPlaylistComplate中进行 // 此方法返回后的任何修改数据的操作都应视为(实际上也是如此)与IniPlaylistThreadFunc及IniPlaylistComplate处于竞争状态 - // play参数会传递到IniPlaylistComplate指示是否播放,refresh_info指示初始化线程总是重新从文件读取信息 - void IniPlayList(bool play = false, bool refresh_info = false); + // play参数会传递到IniPlaylistComplate指示是否播放,refresh_info指示初始化线程刷新级别 + void IniPlayList(bool play = false, MediaLibRefreshMode refresh_mode = MR_MIN_REQUIRED); //应用一个均衡器通道的增益 void ApplyEqualizer(int channel, int gain); @@ -255,7 +252,7 @@ class CPlayer //使用指定播放列表文件来初始化CPlayer类 void CreateWithPlaylist(const wstring& playlist_path); //控制音乐播放 - void MusicControl(Command command, int volume_step = 2); + void MusicControl(Command command, int volume_step = 0); //判断当前音乐是否播放完毕 bool SongIsOver() const; //从播放内核获取当前播放到的位置(更新m_current_position),调用需要取得播放状态锁 @@ -324,7 +321,7 @@ class CPlayer int AddSongsToPlaylist(const vector& songs); // 重新载入播放列表(没能取得播放状态锁返回false) - bool ReloadPlaylist(bool refresh_info = true); + bool ReloadPlaylist(MediaLibRefreshMode refresh_mode); // 翻转是否包含子文件夹设置,如果当前为文件夹模式则直接重新加载播放列表(没能取得播放状态锁返回false) bool SetContainSubFolder(); @@ -342,12 +339,16 @@ class CPlayer void SlowDown(); void SetOrignalSpeed(); void SetSpeed(float speed); - float GetSpeed() { return m_speed; } + float GetSpeed() const { return m_speed; } - //获取BASS音频库的错误 +private: + // 获取CPlayer操作播放内核时产生的错误写入错误日志 bool GetPlayerCoreError(const wchar_t* function_name); + +public: //有错误时返回ture,否则返回false bool IsError() const; + // IsError()为true时获取状态栏显示的错误字符串 std::wstring GetErrorInfo(); // 通知主窗口当前播放歌曲改变需要更新显示(向主窗口发送消息)(原SetTitle) @@ -388,8 +389,6 @@ class CPlayer wstring GetCurrentFilePath() const; //获取当前播放的曲目序号 int GetIndex() const { return m_index; } - //获取正在播放文件的文件名(当前播放文件名为空时返回"没有找到文件" IDS_FILE_NOT_FOUND) - wstring GetFileName() const; //获取正在播放文件的显示名称 wstring GetDisplayName() const; int GetVolume() const { return m_volume; } @@ -397,7 +396,7 @@ class CPlayer CImage& GetAlbumCoverBlur(); bool AlbumCoverExist(); wstring GetAlbumCoverPath() const { return m_album_cover_path; } - int GetAlbumCoverType() const { return m_album_cover_type; } + wstring GetAlbumCoverType() const; private: // 下方播放列表移除歌曲方法中的共有部分 @@ -454,10 +453,6 @@ class CPlayer SongInfo& GetCurrentSongInfo2(); //获取下一个要播放的曲目。如果返回的是空的SongInfo对象,则说明没有下一个曲目或下一个曲目不确定 SongInfo GetNextTrack() const; - //为当前歌曲设置关联的网易云音乐歌曲ID - void SetRelatedSongID(wstring song_id); - //为第index首歌曲设置关联的网易云音乐歌曲ID - void SetRelatedSongID(int index, wstring song_id); //为当前歌曲设置“我喜欢”标记 void SetFavourite(bool favourite); bool IsFavourite(); @@ -484,8 +479,6 @@ class CPlayer //播放列表按照m_sort_mode排序(当is_init为false时,排序后重新查找正在播放的歌曲) void SortPlaylist(bool is_init = false); - //将整个播放列表倒序 - void InvertPlaylist(); //获取专辑封面 void SearchAlbumCover(); private: @@ -518,11 +511,11 @@ class CPlayer MediaTransControls m_controls; - void UpdateControlsMetadata(SongInfo info); - void UpdateLastFMCurrentTrack(SongInfo info); + void UpdateLastFMCurrentTrack(const SongInfo& info); + // 更新SMTC封面,从路径为m_album_cover_path的图片文件 + void MediaTransControlsLoadThumbnail(); private: - void MediaTransControlsLoadThumbnail(std::wstring& file_path); void MediaTransControlsLoadThumbnailDefaultImage(); public: diff --git a/MusicPlayer2/PlayerProgressBar.cpp b/MusicPlayer2/PlayerProgressBar.cpp index 0de08debe..4b550260e 100644 --- a/MusicPlayer2/PlayerProgressBar.cpp +++ b/MusicPlayer2/PlayerProgressBar.cpp @@ -62,7 +62,7 @@ void CPlayerProgressBar::OnPaint() //双缓冲绘图 CDrawDoubleBuffer drawDoubleBuffer(&dc, rect); CDrawCommon drawer; - drawer.Create(drawDoubleBuffer.GetMemDC(), this); + drawer.Create(drawDoubleBuffer.GetMemDC()); //开始绘图 int gap_width = rect.Width() / m_bar_count / 4; diff --git a/MusicPlayer2/PlayerToolBar.cpp b/MusicPlayer2/PlayerToolBar.cpp index 036c56023..10b762592 100644 --- a/MusicPlayer2/PlayerToolBar.cpp +++ b/MusicPlayer2/PlayerToolBar.cpp @@ -19,12 +19,12 @@ CPlayerToolBar::~CPlayerToolBar() { } -void CPlayerToolBar::AddToolButton(IconRes icon, LPCTSTR strText, LPCTSTR strToolTip, UINT cmdId, bool showText) +void CPlayerToolBar::AddToolButton(IconMgr::IconType icon_type, LPCTSTR strText, LPCTSTR strToolTip, UINT cmdId, bool showText) { ToolBtn btn; btn.cmd_id = cmdId; btn.is_cmd = true; - btn.icon = icon; + btn.icon_type = icon_type; if (strText != nullptr) btn.text = strText; btn.show_text = showText; @@ -33,12 +33,12 @@ void CPlayerToolBar::AddToolButton(IconRes icon, LPCTSTR strText, LPCTSTR strToo m_buttons.push_back(btn); } -void CPlayerToolBar::AddToolButton(IconRes icon, LPCTSTR strText, LPCTSTR strToolTip, CMenu * pMenu, bool showText) +void CPlayerToolBar::AddToolButton(IconMgr::IconType icon_type, LPCTSTR strText, LPCTSTR strToolTip, CMenu * pMenu, bool showText) { ToolBtn btn; btn.pMenu = pMenu; btn.is_cmd = false; - btn.icon = icon; + btn.icon_type = icon_type; if (strText != nullptr) btn.text = strText; btn.show_text = showText; @@ -47,14 +47,14 @@ void CPlayerToolBar::AddToolButton(IconRes icon, LPCTSTR strText, LPCTSTR strToo m_buttons.push_back(btn); } -void CPlayerToolBar::ModifyToolButton(int index, IconRes icon, LPCTSTR strText, LPCTSTR strToolTip, CMenu* pMenu, bool showText /*= false*/) +void CPlayerToolBar::ModifyToolButton(int index, IconMgr::IconType icon_type, LPCTSTR strText, LPCTSTR strToolTip, CMenu* pMenu, bool showText /*= false*/) { if (index >= 0 && index < static_cast(m_buttons.size())) { ToolBtn& btn{ m_buttons[index] }; btn.pMenu = pMenu; btn.is_cmd = false; - btn.icon = icon; + btn.icon_type = icon_type; if (strText != nullptr) btn.text = strText; btn.show_text = showText; @@ -67,14 +67,14 @@ void CPlayerToolBar::ModifyToolButton(int index, IconRes icon, LPCTSTR strText, } } -void CPlayerToolBar::ModifyToolButton(int index, IconRes icon, LPCTSTR strText, LPCTSTR strToolTip, UINT cmdId, bool showText /*= false*/) +void CPlayerToolBar::ModifyToolButton(int index, IconMgr::IconType icon_type, LPCTSTR strText, LPCTSTR strToolTip, UINT cmdId, bool showText /*= false*/) { if (index >= 0 && index < static_cast(m_buttons.size())) { ToolBtn& btn{ m_buttons[index] }; btn.cmd_id = cmdId; btn.is_cmd = true; - btn.icon = icon; + btn.icon_type = icon_type; if (strText != nullptr) btn.text = strText; btn.show_text = showText; @@ -156,7 +156,7 @@ void CPlayerToolBar::OnPaint() { CDrawDoubleBuffer drawDoubleBuffer(&dc, rect); CDrawCommon drawer; - drawer.Create(drawDoubleBuffer.GetMemDC(), this); + drawer.Create(drawDoubleBuffer.GetMemDC(), GetFont()); //绘制背景 if(!theApp.m_app_setting_data.button_round_corners) @@ -211,9 +211,10 @@ void CPlayerToolBar::OnPaint() } } - CRect rc_tmp = rc_icon; + HICON hIcon= theApp.m_icon_mgr.GetHICON(iter->icon_type, IconMgr::IconStyle::IS_OutlinedDark, IconMgr::IconSize::IS_DPI_16); + CSize icon_size = IconMgr::GetIconSize(IconMgr::IconSize::IS_DPI_16); //使图标在矩形中居中 - CSize icon_size = iter->icon.GetSize(); + CRect rc_tmp = rc_icon; if (draw_text) rc_tmp.left = rc_icon.left + theApp.DPI(2); else @@ -227,7 +228,7 @@ void CPlayerToolBar::OnPaint() rc_tmp.MoveToY(rc_tmp.top + theApp.DPI(1)); } drawer.SetDrawArea(rc_tmp); - drawer.DrawIcon(iter->icon.GetIcon(true), rc_tmp.TopLeft(), rc_tmp.Size()); + drawer.DrawIcon(hIcon, rc_tmp.TopLeft(), rc_tmp.Size()); //绘制文本 if (draw_text) { diff --git a/MusicPlayer2/PlayerToolBar.h b/MusicPlayer2/PlayerToolBar.h index e803d47ce..fbaa9dbd0 100644 --- a/MusicPlayer2/PlayerToolBar.h +++ b/MusicPlayer2/PlayerToolBar.h @@ -1,5 +1,6 @@ #pragma once #include "CommonData.h" +#include "IconMgr.h" // CPlayerToolBar // 自绘的工具栏 @@ -12,23 +13,23 @@ class CPlayerToolBar : public CStatic virtual ~CPlayerToolBar(); // 添加一个按钮,点击后执行一个命令 - // IconRes icon: 图标资源 + // IconMgr::IconType icon_type: 图标类型 // LPCTSTR strText: 图标右侧的文本 // LPCTSTR strToolTip: 鼠标提示的文本 // UINT cmdId: 点击后执行的命令ID // bool showText: 是否在图标右侧显示文本 - void AddToolButton(IconRes icon, LPCTSTR strText, LPCTSTR strToolTip, UINT cmdId, bool showText = false); + void AddToolButton(IconMgr::IconType icon_type, LPCTSTR strText, LPCTSTR strToolTip, UINT cmdId, bool showText = false); // 添加一个按钮,点击后弹出菜单 - // IconRes icon: 图标资源 + // IconMgr::IconType icon_type: 图标类型 // LPCTSTR strText: 图标右侧的文本 // LPCTSTR strToolTip: 鼠标提示的文本 // CMenu * pMenu: 点击后弹出的菜单 // bool showText: 是否在图标右侧显示文本 - void AddToolButton(IconRes icon, LPCTSTR strText, LPCTSTR strToolTip, CMenu* pMenu, bool showText = false); + void AddToolButton(IconMgr::IconType icon_type, LPCTSTR strText, LPCTSTR strToolTip, CMenu* pMenu, bool showText = false); - void ModifyToolButton(int index, IconRes icon, LPCTSTR strText, LPCTSTR strToolTip, UINT cmdId, bool showText = false); - void ModifyToolButton(int index, IconRes icon, LPCTSTR strText, LPCTSTR strToolTip, CMenu* pMenu, bool showText = false); + void ModifyToolButton(int index, IconMgr::IconType icon_type, LPCTSTR strText, LPCTSTR strToolTip, UINT cmdId, bool showText = false); + void ModifyToolButton(int index, IconMgr::IconType icon_type, LPCTSTR strText, LPCTSTR strToolTip, CMenu* pMenu, bool showText = false); void SetIconSize(int size); void SetCmdReciveWindow(CWnd* pWnd); //设置响应工具按钮命令的窗口,如果不设置,则为工具栏的父窗口 @@ -36,7 +37,7 @@ class CPlayerToolBar : public CStatic protected: struct ToolBtn { - IconRes icon; //图标 + IconMgr::IconType icon_type; //图标类型 CString text; //显示文本 bool show_text = false; //是否显示文本 UINT cmd_id; //点击后发送的命令ID diff --git a/MusicPlayer2/Playlist.cpp b/MusicPlayer2/Playlist.cpp index 17d3610ef..17fc53a31 100644 --- a/MusicPlayer2/Playlist.cpp +++ b/MusicPlayer2/Playlist.cpp @@ -3,15 +3,16 @@ #include "Common.h" #include "FilePathHelper.h" #include "SongDataManager.h" -#include -const vector CPlaylistFile::m_surpported_playlist{ PLAYLIST_EXTENSION, L".m3u", L".m3u8" }; +const vector CPlaylistFile::m_surpported_playlist{ PLAYLIST_EXTENSION_2, L"m3u", L"m3u8" }; /* 播放列表文件格式说明 每行一个曲目,每一行的格式为: -文件路径|是否为cue音轨|cue音轨起始时间|cue音轨结束时间|标题|艺术家|唱片集|曲目序号|比特率|流派|年份|注释 +文件路径|是否为cue音轨|cue音轨起始时间|cue音轨结束时间|标题|艺术家|唱片集|曲目序号|比特率|流派|年份|注释|cue文件路径 +播放列表至少要保存能够在song_data.dat清空时原样恢复特定歌曲的项目 目前除了cue音轨外,其他曲目只保存文件路径 +列表cue条目必要保存的项目有“文件路径”、“音轨号”、“cue文件路径”,但出于向后兼容考虑仍然保留其他项目(实际上不以这些项目为准,外部编辑会被忽略) */ CPlaylistFile::CPlaylistFile() @@ -51,25 +52,36 @@ void CPlaylistFile::LoadFromFile(const wstring & file_path) stream.close(); } -void CPlaylistFile::SaveToFile(const wstring & file_path, Type type) const +void CPlaylistFile::SaveToFile(const wstring& file_path, Type type) const +{ + SavePlaylistToFile(m_playlist, file_path, type); +} + +void CPlaylistFile::SavePlaylistToFile(const vector& song_list, const wstring& file_path, Type type) { ofstream stream{ file_path }; - if(type == PL_PLAYLIST) + if (!stream.is_open()) + return; + if (type == PL_PLAYLIST) { - for (const auto& item : m_playlist) + for (const auto& item : song_list) { if (item.file_path.empty()) continue; // 不保存没有音频路径的项目 stream << CCommon::UnicodeToStr(item.file_path, CodeType::UTF8_NO_BOM); if (item.is_cue) { + // 出于向后兼容考虑必要这行代码,当song_list来自LoadFromFile加载的不记录cue_file_path的播放列表时item需要从媒体库加载cue_file_path + SongInfo song = CSongDataManager::GetInstance().GetSongInfo3(item); // 从媒体库载入数据,媒体库不存在的话会原样返回item CString buff; - buff.Format(L"|%d|%d|%d|%s|%s|%s|%d|%d|%s|%s|%s", item.is_cue, item.start_pos.toInt(), item.end_pos.toInt(), - DeleteInvalidCh(item.title).c_str(), DeleteInvalidCh(item.artist).c_str(), DeleteInvalidCh(item.album).c_str(), - item.track, item.bitrate, - DeleteInvalidCh(item.genre).c_str(), DeleteInvalidCh(item.get_year()).c_str(), DeleteInvalidCh(item.comment).c_str()); + buff.Format(L"|%d|%d|%d|%s|%s|%s|%d|%d|%s|%s|%s|%s", song.is_cue, song.start_pos.toInt(), song.end_pos.toInt(), + DeleteInvalidCh(song.title).c_str(), DeleteInvalidCh(song.artist).c_str(), DeleteInvalidCh(song.album).c_str(), + song.track, song.bitrate, + DeleteInvalidCh(song.genre).c_str(), DeleteInvalidCh(song.get_year()).c_str(), DeleteInvalidCh(song.comment).c_str(), + song.cue_file_path.c_str() + ); stream << CCommon::UnicodeToStr(buff.GetString(), CodeType::UTF8_NO_BOM); } - stream << std::endl; + stream << "\n"; // 使用std::endl会触发flush影响效率 } } else if (type == PL_M3U || type == PL_M3U8) @@ -78,28 +90,29 @@ void CPlaylistFile::SaveToFile(const wstring & file_path, Type type) const if (type == PL_M3U8) code_type = CodeType::UTF8_NO_BOM; - stream << "#EXTM3U" << std::endl; + stream << "#EXTM3U" << '\n'; std::set saved_cue_path; //已经保存过的cue文件的路径 - for (const auto& item : m_playlist) + for (const auto& item : song_list) { if (item.file_path.empty()) continue; // 不保存没有音频路径的项目 - if (item.is_cue) + // song_list可能来自LoadFromFile含有信息不足,此处先从媒体库载入最新数据,媒体库不存在的话会原样返回item + SongInfo song = CSongDataManager::GetInstance().GetSongInfo3(item); + if (song.is_cue) { //如果播放列表中的项目是cue,且该cue文件没有保存过,则将其保存 - if (!item.cue_file_path.empty() && saved_cue_path.find(item.cue_file_path) == saved_cue_path.end()) + if (!song.cue_file_path.empty() && saved_cue_path.find(song.cue_file_path) == saved_cue_path.end()) { - stream << "#" << std::endl; - stream << CCommon::UnicodeToStr(item.cue_file_path, code_type); - saved_cue_path.insert(item.cue_file_path); + stream << "#" << '\n'; + stream << CCommon::UnicodeToStr(song.cue_file_path, code_type) << '\n'; + saved_cue_path.insert(song.cue_file_path); } } else { CString buff; - SongInfo song = CSongDataManager::GetInstance().GetSongInfo(item.file_path); // m_playlist中只有file_path buff.Format(_T("#EXTINF:%d,%s - %s"), song.length().toInt() / 1000, song.GetArtist().c_str(), song.GetTitle().c_str()); - stream << CCommon::UnicodeToStr(buff.GetString(), code_type) << std::endl; - stream << CCommon::UnicodeToStr(song.file_path, code_type) << std::endl; + stream << CCommon::UnicodeToStr(buff.GetString(), code_type) << '\n'; + stream << CCommon::UnicodeToStr(song.file_path, code_type) << '\n'; } } } @@ -126,11 +139,6 @@ int CPlaylistFile::AddSongsToPlaylist(const vector& songs, bool insert return added; } -void CPlaylistFile::FromSongList(const vector& song_list) -{ - m_playlist = song_list; -} - void CPlaylistFile::MoveToSongList(vector& song_list) { song_list = std::move(m_playlist); @@ -170,7 +178,7 @@ void CPlaylistFile::RemoveSong(const SongInfo& song) bool CPlaylistFile::IsPlaylistFile(const wstring& file_path) { - wstring file_extension = CFilePathHelper(file_path).GetFileExtension(false, true); + wstring file_extension = CFilePathHelper(file_path).GetFileExtension(); return CCommon::IsItemInVector(m_surpported_playlist, file_extension); } @@ -178,8 +186,8 @@ bool CPlaylistFile::IsPlaylistExt(wstring ext) { if (ext.empty()) return false; - if (ext.front() != L'.') - ext = L'.' + ext; + if (ext.front() == L'.') + ext = ext.substr(1); return CCommon::IsItemInVector(m_surpported_playlist, ext); } @@ -217,10 +225,7 @@ void CPlaylistFile::DisposePlaylistFileLine(const string& str_current_line, bool item.end_pos.fromInt(_wtoi(result[3].c_str())); //item.lengh = item.end_pos - item.start_pos; if (result.size() >= 5) - { item.title = result[4]; - item.info_acquired = true; - } if (result.size() >= 6) item.artist = result[5]; if (result.size() >= 7) @@ -235,6 +240,8 @@ void CPlaylistFile::DisposePlaylistFileLine(const string& str_current_line, bool item.SetYear(result[10].c_str()); if (result.size() >= 12) item.comment = result[11]; + if (result.size() >= 13) + item.cue_file_path = result[12]; } if(CCommon::IsPath(item.file_path)) // 绝对路径的语法检查 { diff --git a/MusicPlayer2/Playlist.h b/MusicPlayer2/Playlist.h index 6f10da882..a85db0e04 100644 --- a/MusicPlayer2/Playlist.h +++ b/MusicPlayer2/Playlist.h @@ -16,7 +16,6 @@ class CPlaylistFile void SaveToFile(const wstring& file_path, Type type = PL_PLAYLIST) const; const vector& GetPlaylist() const; int AddSongsToPlaylist(const vector& songs, bool insert_begin = false); - void FromSongList(const vector& song_list); // 使用移动语义覆盖参数song_list,调用后此CPlaylistFile对象不再可用 void MoveToSongList(vector& song_list); bool IsSongInPlaylist(const SongInfo& song); @@ -26,6 +25,7 @@ class CPlaylistFile static bool IsPlaylistFile(const wstring& file_path); static bool IsPlaylistExt(wstring ext); + static void SavePlaylistToFile(const vector& song_list, const wstring& file_path, Type type = PL_PLAYLIST); public: const static vector m_surpported_playlist; //支持的播放列表文件的扩展名列表 diff --git a/MusicPlayer2/PlaylistMgr.cpp b/MusicPlayer2/PlaylistMgr.cpp index 89e07f72b..900feb155 100644 --- a/MusicPlayer2/PlaylistMgr.cpp +++ b/MusicPlayer2/PlaylistMgr.cpp @@ -1,8 +1,8 @@ #include "stdafx.h" #include "PlaylistMgr.h" #include "MusicPlayer2.h" -#include #include "Playlist.h" +#include "FilePathHelper.h" CPlaylistMgr CPlaylistMgr::m_instance; @@ -270,9 +270,8 @@ void CPlaylistMgr::LoadPlaylistData() catch (CArchiveException* exception) { //捕获序列化时出现的异常 - CString info; - info = CCommon::LoadTextFormat(IDS_SERIALIZE_ERROR, { theApp.m_recent_playlist_data_path, exception->m_cause }); - theApp.WriteLog(wstring{ info }); + wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_SERIALIZE_ERROR", { theApp.m_recent_playlist_data_path, exception->m_cause }); + theApp.WriteLog(info); } // 关闭对象 ar.Close(); diff --git a/MusicPlayer2/PropertyAdvancedDlg.cpp b/MusicPlayer2/PropertyAdvancedDlg.cpp index cf125e328..091fab3f9 100644 --- a/MusicPlayer2/PropertyAdvancedDlg.cpp +++ b/MusicPlayer2/PropertyAdvancedDlg.cpp @@ -4,7 +4,7 @@ #include "stdafx.h" #include "MusicPlayer2.h" #include "PropertyAdvancedDlg.h" -#include "afxdialogex.h" +#include "AudioTag.h" // CPropertyAdvancedDlg 对话框 @@ -123,12 +123,10 @@ BOOL CPropertyAdvancedDlg::OnInitDialog() // TODO: 在此添加额外的初始化 - CCommon::SetDialogFont(this, theApp.m_pMainWnd->GetFont()); //由于此对话框资源由不同语言共用,所以这里要设置一下字体 - //初始化列表 m_list_ctrl.SetExtendedStyle(m_list_ctrl.GetExtendedStyle() | LVS_EX_GRIDLINES); - m_list_ctrl.InsertColumn(0, CCommon::LoadText(IDS_ITEM), LVCFMT_LEFT, theApp.DPI(100)); - m_list_ctrl.InsertColumn(1, CCommon::LoadText(IDS_VLAUE), LVCFMT_LEFT, theApp.DPI(200)); + m_list_ctrl.InsertColumn(0, theApp.m_str_table.LoadText(L"TXT_ITEM").c_str(), LVCFMT_LEFT, theApp.DPI(100)); + m_list_ctrl.InsertColumn(1, theApp.m_str_table.LoadText(L"TXT_VALUE").c_str(), LVCFMT_LEFT, theApp.DPI(200)); return TRUE; // return TRUE unless you set the focus to a control // 异常: OCX 属性页应返回 FALSE @@ -139,7 +137,7 @@ void CPropertyAdvancedDlg::OnCopyText() { // TODO: 在此添加命令处理程序代码 if (!CCommon::CopyStringToClipboard(m_selected_string)) - MessageBox(CCommon::LoadText(IDS_COPY_CLIPBOARD_FAILED), NULL, MB_ICONWARNING); + MessageBox(theApp.m_str_table.LoadText(L"MSG_COPY_CLIPBOARD_FAILED").c_str(), NULL, MB_ICONWARNING); } @@ -151,7 +149,7 @@ void CPropertyAdvancedDlg::OnNMRClickList1(NMHDR *pNMHDR, LRESULT *pResult) m_item_selected = pNMItemActivate->iItem; //弹出右键菜单 - CMenu* pMenu = theApp.m_menu_set.m_property_menu.GetSubMenu(0); + CMenu* pMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::PropertyAdvMenu); ASSERT(pMenu != nullptr); if (pMenu != nullptr) { diff --git a/MusicPlayer2/PropertyAdvancedDlg.h b/MusicPlayer2/PropertyAdvancedDlg.h index 3add30edf..66096f9da 100644 --- a/MusicPlayer2/PropertyAdvancedDlg.h +++ b/MusicPlayer2/PropertyAdvancedDlg.h @@ -1,6 +1,6 @@ #pragma once #include "IPropertyTabDlg.h" - +#include "ListCtrlEx.h" // CPropertyAdvancedDlg 对话框 diff --git a/MusicPlayer2/PropertyAlbumCoverDlg.cpp b/MusicPlayer2/PropertyAlbumCoverDlg.cpp index 97cdf931f..331c4f0f4 100644 --- a/MusicPlayer2/PropertyAlbumCoverDlg.cpp +++ b/MusicPlayer2/PropertyAlbumCoverDlg.cpp @@ -3,11 +3,14 @@ #include "stdafx.h" #include "MusicPlayer2.h" +#include "Player.h" #include "PropertyAlbumCoverDlg.h" #include "COSUPlayerHelper.h" #include "DrawCommon.h" #include "MusicPlayerCmdHelper.h" #include "PropertyDlgHelper.h" +#include "CommonDialogMgr.h" +#include "FilterHelper.h" #define PROPERTY_COVER_IMG_FILE_NAME L"PropertyCoverImg_U6V19HODcJ2p11FM" @@ -137,12 +140,12 @@ void CPropertyAlbumCoverDlg::ShowInfo() if (HasAlbumCover()) { //路径 - CString str_path; + wstring str_path; if (IsShowOutAlbumCover()) - str_path = m_out_img_path.c_str(); + str_path = m_out_img_path; else - str_path = CCommon::LoadText(_T("<"), IDS_INNER_ALBUM_COVER, L">"); - m_list_ctrl.SetItemText(RI_COVER_PATH, 1, str_path); + str_path = theApp.m_str_table.LoadText(L"TXT_INNER_COVER"); + m_list_ctrl.SetItemText(RI_COVER_PATH, 1, str_path.c_str()); //文件类型 CString str_type; @@ -191,18 +194,6 @@ void CPropertyAlbumCoverDlg::ShowInfo() { m_list_ctrl.SetItemText(RI_SIZE, 1, CCommon::DataSizeToString(cover_size)); } - - // //已压缩尺寸过大的专辑封面 - // if (!m_cover_changed && !m_batch_edit && IsCurrentSong()) - // { - // m_list_ctrl.SetItemText(RI_COMPRESSED, 0, CCommon::LoadText(IDS_ALBUM_COVER_COMPRESSED)); - // m_list_ctrl.SetItemText(RI_COMPRESSED, 1, (CPlayer::GetInstance().GetAlbumCoverInfo().size_exceed ? CCommon::LoadText(IDS_YES) : CCommon::LoadText(IDS_NO))); - // } - // else - // { - // m_list_ctrl.SetItemText(RI_COMPRESSED, 0, _T("")); - // m_list_ctrl.SetItemText(RI_COMPRESSED, 1, _T("")); - // } } else { @@ -382,7 +373,7 @@ void CPropertyAlbumCoverDlg::DeleteLinkedPic(const wstring& file_path, const wst wstring file_name = CFilePathHelper(file_path).GetFilePathWithoutExtension(); if (file_name == album_cover_file_name) { - CCommon::DeleteAFile(theApp.m_pMainWnd->GetSafeHwnd(), album_cover_path); + CommonDialogMgr::DeleteAFile(theApp.m_pMainWnd->GetSafeHwnd(), album_cover_path); } } @@ -391,6 +382,26 @@ void CPropertyAlbumCoverDlg::OnTabEntered() ShowInfo(); } +bool CPropertyAlbumCoverDlg::InitializeControls() +{ + wstring temp; + // IDC_LIST1 + temp = theApp.m_str_table.LoadText(L"TXT_COVER_PROPERTY_BROWSE"); + SetDlgItemTextW(IDC_BROWSE_BUTTON, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_COVER_PROPERTY_DELETE"); + SetDlgItemTextW(IDC_DELETE_BUTTON, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_COVER_PROPERTY_SHOW_OUT_COVER"); + SetDlgItemTextW(IDC_SHOW_OUT_ALBUM_COVER_CHK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_COVER_PROPERTY_DO_INNER_COVER"); + SetDlgItemTextW(IDC_SAVE_ALBUM_COVER_BUTTON, temp.c_str()); + + RepositionTextBasedControls({ + { CtrlTextInfo::L1, IDC_BROWSE_BUTTON, CtrlTextInfo::W32 }, + { CtrlTextInfo::L2, IDC_DELETE_BUTTON, CtrlTextInfo::W32 } + }); + return true; +} + void CPropertyAlbumCoverDlg::DoDataExchange(CDataExchange* pDX) { CTabDlg::DoDataExchange(pDX); @@ -423,8 +434,8 @@ BOOL CPropertyAlbumCoverDlg::OnInitDialog() CTabDlg::OnInitDialog(); // TODO: 在此添加额外的初始化 - SetButtonIcon(IDC_BROWSE_BUTTON, theApp.m_icon_set.folder_explore.GetIcon(true)); - SetButtonIcon(IDC_DELETE_BUTTON, theApp.m_icon_set.close.GetIcon(true)); + SetButtonIcon(IDC_BROWSE_BUTTON, IconMgr::IconType::IT_Folder_Explore); + SetButtonIcon(IDC_DELETE_BUTTON, IconMgr::IconType::IT_Cancel); //初始化列表 //初始化列表 @@ -433,18 +444,17 @@ BOOL CPropertyAlbumCoverDlg::OnInitDialog() m_list_ctrl.SetExtendedStyle(m_list_ctrl.GetExtendedStyle() | LVS_EX_GRIDLINES); int width0 = theApp.DPI(85); int width1 = rect.Width() - width0 - theApp.DPI(20) - 1; - m_list_ctrl.InsertColumn(0, CCommon::LoadText(IDS_ITEM), LVCFMT_LEFT, width0); - m_list_ctrl.InsertColumn(1, CCommon::LoadText(IDS_VLAUE), LVCFMT_LEFT, width1); + m_list_ctrl.InsertColumn(0, theApp.m_str_table.LoadText(L"TXT_ITEM").c_str(), LVCFMT_LEFT, width0); + m_list_ctrl.InsertColumn(1, theApp.m_str_table.LoadText(L"TXT_VALUE").c_str(), LVCFMT_LEFT, width1); - m_list_ctrl.InsertItem(RI_FILE_PATH, CCommon::LoadText(IDS_FILE_PATH)); //文件路径 - m_list_ctrl.InsertItem(RI_COVER_PATH, CCommon::LoadText(IDS_PATH)); //封面路径 - m_list_ctrl.InsertItem(RI_FORMAT, CCommon::LoadText(IDS_FORMAT)); //封面类型 - m_list_ctrl.InsertItem(RI_WIDTH, CCommon::LoadText(IDS_WIDTH)); //宽度 - m_list_ctrl.InsertItem(RI_HEIGHT, CCommon::LoadText(IDS_HEIGHT)); //高度 - m_list_ctrl.InsertItem(RI_BPP, CCommon::LoadText(IDS_BPP)); //每像素位数 - m_list_ctrl.InsertItem(RI_SIZE, CCommon::LoadText(IDS_FILE_SIZE)); //文件大小 - //m_list_ctrl.InsertItem(RI_COMPRESSED, CCommon::LoadText(IDS_ALBUM_COVER_COMPRESSED)); //已压缩尺寸过大的专辑封面 + m_list_ctrl.InsertItem(RI_FILE_PATH, theApp.m_str_table.LoadText(L"TXT_FILE_PATH").c_str()); //文件路径 + m_list_ctrl.InsertItem(RI_COVER_PATH, theApp.m_str_table.LoadText(L"TXT_PATH").c_str()); //封面路径 + m_list_ctrl.InsertItem(RI_FORMAT, theApp.m_str_table.LoadText(L"TXT_COVER_PROPERTY_FORMAT").c_str()); //封面类型 + m_list_ctrl.InsertItem(RI_WIDTH, theApp.m_str_table.LoadText(L"TXT_COVER_PROPERTY_WIDTH").c_str()); //宽度 + m_list_ctrl.InsertItem(RI_HEIGHT, theApp.m_str_table.LoadText(L"TXT_COVER_PROPERTY_HEIGHT").c_str()); //高度 + m_list_ctrl.InsertItem(RI_BPP, theApp.m_str_table.LoadText(L"TXT_COVER_PROPERTY_BPP").c_str()); //每像素位数 + m_list_ctrl.InsertItem(RI_SIZE, theApp.m_str_table.LoadText(L"TXT_COVER_PROPERTY_FILE_SIZE").c_str()); //文件大小 CheckDlgButton(IDC_SHOW_OUT_ALBUM_COVER_CHK, m_show_out_album_cover); @@ -479,12 +489,6 @@ void CPropertyAlbumCoverDlg::OnPaint() rect.right = rect_list.left; rect.DeflateRect(theApp.DPI(16), theApp.DPI(16)); - CRect rect_tmp; - ::GetWindowRect(GetDlgItem(IDC_SHOW_OUT_ALBUM_COVER_CHK)->GetSafeHwnd(), rect_tmp); - ScreenToClient(rect_tmp); - if (!rect_tmp.IsRectEmpty()) - rect.bottom = rect_tmp.top - theApp.DPI(8); - if (HasAlbumCover()) //有专辑封面时绘制专辑封面 { CImage& img{ GetCoverImage() }; @@ -520,11 +524,14 @@ void CPropertyAlbumCoverDlg::OnBnClickedDeleteButton() // TODO: 在此添加控件通知处理程序代码 if (IsShowOutAlbumCover() && !m_batch_edit) { - CString str_info = CCommon::LoadTextFormat(IDS_DELETE_SINGLE_FILE_INQUIRY, { m_out_img_path }); - if (MessageBox(str_info, NULL, MB_ICONQUESTION | MB_OKCANCEL) == IDOK) + wstring inquary_info = theApp.m_str_table.LoadTextFormat(L"MSG_DELETE_SINGLE_FILE_INQUARY", { m_out_img_path }); + if (MessageBox(inquary_info.c_str(), NULL, MB_ICONQUESTION | MB_OKCANCEL) == IDOK) { - if (CCommon::DeleteAFile(theApp.m_pMainWnd->GetSafeHwnd(), m_out_img_path) != 0) - MessageBox(CCommon::LoadText(IDS_CONNOT_DELETE_FILE), NULL, MB_ICONWARNING); + if (CommonDialogMgr::DeleteAFile(theApp.m_pMainWnd->GetSafeHwnd(), m_out_img_path) != 0) + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_DELETE_FILE_FAILED"); + MessageBox(info.c_str(), NULL, MB_ICONWARNING); + } } } else @@ -539,8 +546,8 @@ void CPropertyAlbumCoverDlg::OnBnClickedBrowseButton() { // TODO: 在此添加控件通知处理程序代码 - CString filter = CCommon::LoadText(IDS_IMAGE_FILE_FILTER); - CFileDialog fileDlg(TRUE, NULL, NULL, 0, filter, this); + wstring filter = FilterHelper::GetImageFileFilter(); + CFileDialog fileDlg(TRUE, NULL, NULL, 0, filter.c_str(), this); if (IDOK == fileDlg.DoModal()) { m_out_img_path = fileDlg.GetPathName().GetString(); @@ -555,7 +562,7 @@ void CPropertyAlbumCoverDlg::OnRButtonUp(UINT nFlags, CPoint point) // TODO: 在此添加消息处理程序代码和/或调用默认值 CPoint point1; GetCursorPos(&point1); - CMenu* pMenu = theApp.m_menu_set.m_property_cover_menu.GetSubMenu(0); + CMenu* pMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::PropertyCoverMenu); if (pMenu != NULL) pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point1.x, point1.y, this); @@ -581,7 +588,7 @@ void CPropertyAlbumCoverDlg::OnCoverSaveAs() { // TODO: 在此添加命令处理程序代码 //设置过滤器 - CString szFilter = CCommon::LoadText(IDS_ALL_FILES, _T("(*.*)|*.*||")); + wstring szFilter = theApp.m_str_table.LoadText(L"TXT_FILTER_ALL_FILES") + L"(*.*)|*.*||"; //设置另存为时的默认文件名 CString file_name; CString extension = m_list_ctrl.GetItemText(RI_FORMAT, 1); @@ -589,7 +596,7 @@ void CPropertyAlbumCoverDlg::OnCoverSaveAs() wstring file_name_wcs{ file_name }; CCommon::FileNameNormalize(file_name_wcs); //替换掉文件名中的无效字符 //构造保存文件对话框 - CFileDialog fileDlg(FALSE, NULL, file_name_wcs.c_str(), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter, this); + CFileDialog fileDlg(FALSE, NULL, file_name_wcs.c_str(), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter.c_str(), this); //显示保存文件对话框 if (IDOK == fileDlg.DoModal()) { diff --git a/MusicPlayer2/PropertyAlbumCoverDlg.h b/MusicPlayer2/PropertyAlbumCoverDlg.h index 5dee67e79..5670bedf2 100644 --- a/MusicPlayer2/PropertyAlbumCoverDlg.h +++ b/MusicPlayer2/PropertyAlbumCoverDlg.h @@ -8,12 +8,12 @@ class CPropertyAlbumCoverDlg : public CTabDlg, public IPropertyTabDlg { - DECLARE_DYNAMIC(CPropertyAlbumCoverDlg) + DECLARE_DYNAMIC(CPropertyAlbumCoverDlg) public: - CPropertyAlbumCoverDlg(vector& all_song_info, int& index, bool show_out_album_cover = false, bool read_only = false, CWnd* pParent = nullptr); // 标准构造函数 - CPropertyAlbumCoverDlg(vector& all_song_info, CWnd* pParent = nullptr); //批量编辑 - virtual ~CPropertyAlbumCoverDlg(); + CPropertyAlbumCoverDlg(vector& all_song_info, int& index, bool show_out_album_cover = false, bool read_only = false, CWnd* pParent = nullptr); // 标准构造函数 + CPropertyAlbumCoverDlg(vector& all_song_info, CWnd* pParent = nullptr); //批量编辑 + virtual ~CPropertyAlbumCoverDlg(); virtual void PagePrevious() override; virtual void PageNext() override; @@ -22,7 +22,7 @@ class CPropertyAlbumCoverDlg : public CTabDlg, public IPropertyTabDlg // 对话框数据 #ifdef AFX_DESIGN_TIME - enum { IDD = IDD_PROPERTY_ALBUM_COVER_DIALOG }; + enum { IDD = IDD_PROPERTY_ALBUM_COVER_DIALOG }; #endif protected: @@ -41,7 +41,7 @@ class CPropertyAlbumCoverDlg : public CTabDlg, public IPropertyTabDlg CListCtrlEx m_list_ctrl; - int& m_index; //当前显示项目的曲目序号 + int& m_index; //当前显示项目的曲目序号 vector& m_all_song_info; bool m_read_only{}; bool m_show_out_album_cover{}; @@ -75,9 +75,10 @@ class CPropertyAlbumCoverDlg : public CTabDlg, public IPropertyTabDlg void DeleteLinkedPic(const wstring& file_path, const wstring& album_cover_path); virtual void OnTabEntered() override; //当标签切换到当前窗口时被调用 + virtual bool InitializeControls() override; virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 - DECLARE_MESSAGE_MAP() + DECLARE_MESSAGE_MAP() public: virtual BOOL OnInitDialog(); afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt); diff --git a/MusicPlayer2/PropertyDlg.cpp b/MusicPlayer2/PropertyDlg.cpp index 7db0505be..ccc7bda8b 100644 --- a/MusicPlayer2/PropertyDlg.cpp +++ b/MusicPlayer2/PropertyDlg.cpp @@ -3,8 +3,8 @@ #include "stdafx.h" #include "MusicPlayer2.h" +#include "Player.h" #include "PropertyDlg.h" -#include "afxdialogex.h" // CPropertyDlg 对话框 @@ -59,6 +59,32 @@ CString CPropertyDlg::GetDialogName() const return _T("PropertyDlg"); } +bool CPropertyDlg::InitializeControls() +{ + wstring temp; + temp = theApp.m_str_table.LoadText(L"TITLE_PROPERTY_PARENT"); + SetWindowTextW(temp.c_str()); + // IDC_TAB1 + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_PARENT_PREVIOUS"); + SetDlgItemTextW(IDC_PREVIOUS_BUTTON, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_PARENT_NEXT"); + SetDlgItemTextW(IDC_NEXT_BUTTON, temp.c_str()); + // IDC_ITEM_STATIC + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_PARENT_SAVE_TO_FILE"); + SetDlgItemTextW(IDC_SAVE_TO_FILE_BUTTON, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_CLOSE"); + SetDlgItemTextW(IDCANCEL, temp.c_str()); + + RepositionTextBasedControls({ + { CtrlTextInfo::L2, IDC_PREVIOUS_BUTTON, CtrlTextInfo::W32 }, + { CtrlTextInfo::L1, IDC_NEXT_BUTTON, CtrlTextInfo::W32 }, + { CtrlTextInfo::C0, IDC_ITEM_STATIC }, + { CtrlTextInfo::R1, IDC_SAVE_TO_FILE_BUTTON, CtrlTextInfo::W32 }, + { CtrlTextInfo::R2, IDCANCEL, CtrlTextInfo::W32 } + }); + return true; +} + void CPropertyDlg::DoDataExchange(CDataExchange* pDX) { CBaseDialog::DoDataExchange(pDX); @@ -87,11 +113,10 @@ BOOL CPropertyDlg::OnInitDialog() // TODO: 在此添加额外的初始化 - SetIcon(theApp.m_icon_set.info.GetIcon(true), FALSE); - - m_previous_btn.SetIcon(theApp.m_icon_set.lyric_delay.GetIcon(true)); - m_next_btn.SetIcon(theApp.m_icon_set.lyric_forward.GetIcon(true)); - SetButtonIcon(IDC_SAVE_TO_FILE_BUTTON, theApp.m_icon_set.save_new); + SetIcon(IconMgr::IconType::IT_Info, FALSE); + SetButtonIcon(IDC_PREVIOUS_BUTTON, IconMgr::IconType::IT_Triangle_Left); + SetButtonIcon(IDC_NEXT_BUTTON, IconMgr::IconType::IT_Triangle_Right); + SetButtonIcon(IDC_SAVE_TO_FILE_BUTTON, IconMgr::IconType::IT_Save); //创建子对话框 m_property_dlg.Create(IDD_PROPERTY_DIALOG); @@ -100,20 +125,10 @@ BOOL CPropertyDlg::OnInitDialog() m_advanced_dlg.Create(IDD_PROPERTY_ADVANCED_DIALOG); //添加对话框 - m_tab_ctrl.AddWindow(&m_property_dlg, CCommon::LoadText(IDS_FILE_PROPERTY)); - m_tab_ctrl.AddWindow(&m_album_cover_dlg, CCommon::LoadText(IDS_ALBUM_COVER)); + m_tab_ctrl.AddWindow(&m_property_dlg, theApp.m_str_table.LoadText(L"TITLE_PROPERTY_DLG").c_str(), IconMgr::IconType::IT_File_Relate); + m_tab_ctrl.AddWindow(&m_album_cover_dlg, theApp.m_str_table.LoadText(L"TITLE_COVER_PROPERTY").c_str(), IconMgr::IconType::IT_Album_Cover); if (!m_batch_edit) - m_tab_ctrl.AddWindow(&m_advanced_dlg, CCommon::LoadText(IDS_ADVANCED_PROPERTY)); - - //为每个标签添加图标 - CImageList ImageList; - ImageList.Create(theApp.DPI(16), theApp.DPI(16), ILC_COLOR32 | ILC_MASK, 2, 2); - ImageList.Add(theApp.m_icon_set.file_relate); - ImageList.Add(theApp.m_icon_set.album_cover); - if (!m_batch_edit) - ImageList.Add(theApp.m_icon_set.tag); - m_tab_ctrl.SetImageList(&ImageList); - ImageList.Detach(); + m_tab_ctrl.AddWindow(&m_advanced_dlg, theApp.m_str_table.LoadText(L"TITLE_ADVANCED_PROPERTY").c_str(), IconMgr::IconType::IT_Tag); m_tab_ctrl.SetItemSize(CSize(theApp.DPI(60), theApp.DPI(24))); m_tab_ctrl.AdjustTabWindowSize(); @@ -135,14 +150,10 @@ BOOL CPropertyDlg::OnInitDialog() if (m_batch_edit) { + SetWindowText(theApp.m_str_table.LoadTextFormat(L"TITLE_PROPERTY_PARENT_BATCH", { m_song_num }).c_str()); ShowDlgCtrl(IDC_PREVIOUS_BUTTON, false); ShowDlgCtrl(IDC_NEXT_BUTTON, false); ShowDlgCtrl(IDC_ITEM_STATIC, false); - - CString str_title; - GetWindowText(str_title); - str_title += CCommon::LoadTextFormat(IDS_PROPERTY_TITLE_INFO, { m_song_num }); - SetWindowText(str_title); } return TRUE; // return TRUE unless you set the focus to a control @@ -163,17 +174,23 @@ void CPropertyDlg::OnBnClickedSaveToFileButton() m_modified = true; if (m_batch_edit) { - CString info = CCommon::LoadTextFormat(IDS_TAG_BATCH_EDIT_INFO, { saved_num }); - MessageBox(info, NULL, MB_ICONINFORMATION | MB_OK); + wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_PROPERTY_PARENT_TAG_BATCH_EDIT_SAVE_INFO", { saved_num }); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); } else { if (saved_num == 0) - MessageBox(CCommon::LoadText(IDS_CANNOT_WRITE_TO_FILE), NULL, MB_ICONWARNING | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_FILE_WRITE_FAILED"); + MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK); + } } } else - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } } } diff --git a/MusicPlayer2/PropertyDlg.h b/MusicPlayer2/PropertyDlg.h index ace4504a4..fb2b60b2d 100644 --- a/MusicPlayer2/PropertyDlg.h +++ b/MusicPlayer2/PropertyDlg.h @@ -45,6 +45,7 @@ class CPropertyDlg : public CBaseDialog void ShowPageNum(); virtual CString GetDialogName() const override; + virtual bool InitializeControls() override; virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() diff --git a/MusicPlayer2/PropertyDlgHelper.cpp b/MusicPlayer2/PropertyDlgHelper.cpp index 8c65449d7..4935ec83c 100644 --- a/MusicPlayer2/PropertyDlgHelper.cpp +++ b/MusicPlayer2/PropertyDlgHelper.cpp @@ -5,6 +5,7 @@ #include "COSUPlayerHelper.h" #include "AudioTag.h" #include "SongInfoHelper.h" +#include "MusicPlayer2.h" CPropertyDlgHelper::CPropertyDlgHelper(const vector& songs) : m_song_info{ songs } @@ -46,8 +47,6 @@ wstring CPropertyDlgHelper::GetMultiLength() { return song.length().toString2(); }, m_song_info); - if (multi_length == L"-:--") - multi_length = CCommon::LoadText(IDS_CANNOT_GET_SONG_LENGTH); return multi_length; } @@ -72,7 +71,7 @@ wstring CPropertyDlgHelper::GetMultiChannels() { return GetMultiValue([](const SongInfo& song) { - return wstring(CSongInfoHelper::GetChannelsString(song).GetString()); + return CSongInfoHelper::GetChannelsString(song.channels); }, m_song_info); } @@ -240,7 +239,7 @@ wstring CPropertyDlgHelper::GetMultiValue(std::function return false; } -void CPropertyDlgHelper::GetTagFromFileName(const wstring& file_name, const wstring& formular, SongInfo& song_info) -{ - std::map identifiers; //保存标识符,int为标识符在formualr中的索引 - - //查找每个标识符的位置,并保存在identifers中,FORMULAR_ORIGINAL不参与推测 - const vector FORMULARS{ FORMULAR_TITLE, FORMULAR_ARTIST, FORMULAR_ALBUM, FORMULAR_TRACK, FORMULAR_YEAR, FORMULAR_GENRE, FORMULAR_COMMENT }; - for (const auto& f : FORMULARS) - { - size_t index = formular.find(f); - if (index != wstring::npos) - { - identifiers[index] = f; - } - } - - wstring str_format = formular; - - const wchar_t* SPLITER = L"|"; - - //将标识符全部替换成| - for (const auto& item : identifiers) - { - CCommon::StringReplace(str_format, item.second.c_str(), SPLITER); - } - //取得分割符 - vector seprators; - CCommon::StringSplit(str_format, SPLITER, seprators, true, false); - - //用分割符分割文件名 - vector results; - CCommon::StringSplitWithSeparators(file_name, seprators, results); - - //获取分割结果 - if (results.empty()) - { - song_info.title = file_name; - } - else - { - size_t index{}; - for (const auto& item : identifiers) - { - if (index < results.size()) - { - wstring result = results[index]; - if (item.second == FORMULAR_TITLE) - song_info.title = result; - else if (item.second == FORMULAR_ARTIST) - song_info.artist = result; - else if (item.second == FORMULAR_ALBUM) - song_info.album = result; - else if (item.second == FORMULAR_TRACK) - song_info.track = _wtoi(result.c_str()); - else if (item.second == FORMULAR_YEAR) - song_info.SetYear(result.c_str()); - else if (item.second == FORMULAR_GENRE) - song_info.genre = result; - else if (item.second == FORMULAR_COMMENT) - song_info.comment = result; - } - index++; - } - } -} - -wstring CPropertyDlgHelper::FileNameFromTag(const wstring& formular, const SongInfo& song_info) -{ - wstring result = formular; - CFilePathHelper song_path{ song_info.file_path }; - CCommon::StringReplace(result, FORMULAR_TITLE, song_info.GetTitle()); - CCommon::StringReplace(result, FORMULAR_ARTIST, song_info.GetArtist()); - CCommon::StringReplace(result, FORMULAR_ALBUM, song_info.GetAlbum()); - CCommon::StringReplace(result, FORMULAR_TRACK, std::to_wstring(song_info.track)); - CCommon::StringReplace(result, FORMULAR_GENRE, song_info.GetGenre()); - CCommon::StringReplace(result, FORMULAR_YEAR, song_info.GetYear()); - CCommon::StringReplace(result, FORMULAR_COMMENT, song_info.comment); - CCommon::StringReplace(result, FORMULAR_ORIGINAL, song_path.GetFileNameWithoutExtension()); - CCommon::FileNameNormalize(result); - return result; -} - -bool CPropertyDlgHelper::IsStringContainsFormular(const wstring & str) -{ - std::vector formular_list{ FORMULAR_TITLE, FORMULAR_ARTIST, FORMULAR_ALBUM, FORMULAR_TRACK, FORMULAR_GENRE, FORMULAR_YEAR, FORMULAR_COMMENT, FORMULAR_ORIGINAL }; - for (const auto& formular : formular_list) - { - if (str.find(formular) != wstring::npos) - return true; - } - return false; -} diff --git a/MusicPlayer2/PropertyDlgHelper.h b/MusicPlayer2/PropertyDlgHelper.h index d2bb287b7..fd728bd45 100644 --- a/MusicPlayer2/PropertyDlgHelper.h +++ b/MusicPlayer2/PropertyDlgHelper.h @@ -1,15 +1,5 @@ #pragma once #include "SongInfo.h" -#include - -#define FORMULAR_TITLE L"%(Title)" -#define FORMULAR_ARTIST L"%(Artist)" -#define FORMULAR_ALBUM L"%(Album)" -#define FORMULAR_TRACK L"%(Track)" -#define FORMULAR_YEAR L"%(Year)" -#define FORMULAR_GENRE L"%(Genre)" -#define FORMULAR_COMMENT L"%(Comment)" -#define FORMULAR_ORIGINAL L"%(Original)" class CPropertyDlgHelper { @@ -55,16 +45,4 @@ class CPropertyDlgHelper private: const vector& m_song_info; - -public: - - //从文件名猜测标签 - //file_name: 文件名(不含扩展名) - //formular: 猜测的方案,比如“<%artist%> - <%title%>” - //song_info: 接收猜测结果 - static void GetTagFromFileName(const wstring& file_name, const wstring& formular, SongInfo& song_info); - - static wstring FileNameFromTag(const wstring& formular, const SongInfo& song_info); - - static bool IsStringContainsFormular(const wstring& str); }; diff --git a/MusicPlayer2/PropertyTabDlg.cpp b/MusicPlayer2/PropertyTabDlg.cpp index cf9272bf9..6b85beb55 100644 --- a/MusicPlayer2/PropertyTabDlg.cpp +++ b/MusicPlayer2/PropertyTabDlg.cpp @@ -3,21 +3,21 @@ #include "stdafx.h" #include "MusicPlayer2.h" +#include "Player.h" #include "PropertyTabDlg.h" -#include "afxdialogex.h" #include "COSUPlayerHelper.h" #include "PropertyDlgHelper.h" #include "SongDataManager.h" #include "GetTagOnlineDlg.h" #include "MusicPlayerCmdHelper.h" -#include "TagFromFileNameDlg.h" +#include "TagFromNameDlg.h" #include "SongInfoHelper.h" // CPropertyTabDlg 对话框 static void CopyMultiTagInfo(const wstring& str_src, wstring& str_dest) { - static wstring str_multi_value = CCommon::LoadText(IDS_MULTI_VALUE).GetString(); + static wstring str_multi_value = theApp.m_str_table.LoadText(L"TXT_MULTI_VALUE"); if (str_src != str_multi_value) str_dest = str_src; } @@ -64,7 +64,10 @@ void CPropertyTabDlg::ShowInfo() m_file_name_edit.SetWindowText(helper.GetMultiFileName().c_str()); m_file_path_edit.SetWindowText(helper.GetMultiFilePath().c_str()); m_file_type_edit.SetWindowText(helper.GetMultiType().c_str()); - m_song_length_edit.SetWindowText(helper.GetMultiLength().c_str()); + wstring multi_length = helper.GetMultiLength(); + if (multi_length == L"-:--") + multi_length = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_FILE_DURATION_UNKNOWN"); + m_song_length_edit.SetWindowText(multi_length.c_str()); m_file_size_edit.SetWindowText(helper.GetMultiSize().c_str()); m_bit_rate_edit.SetWindowText(helper.GetMultiBitrate().c_str()); SetDlgItemText(IDC_SAMPLE_FREQ, helper.GetMultiFreq().c_str()); @@ -92,26 +95,12 @@ void CPropertyTabDlg::ShowInfo() wstring file_type; CFilePathHelper file_path{ m_all_song_info[m_index].file_path }; file_type = file_path.GetFileExtension(); - //if (file_type == _T("mp3")) - // m_file_type_edit.SetWindowText(_T("MP3音频文件")); - //else if (file_type == _T("wma")) - // m_file_type_edit.SetWindowText(_T("Windows Media 音频文件")); - //else if (file_type == _T("wav")) - // m_file_type_edit.SetWindowText(_T("WAV音频文件")); - //else if (file_type == _T("mid")) - // m_file_type_edit.SetWindowText(_T("MIDI序列")); - //else if (file_type == _T("ogg")) - // m_file_type_edit.SetWindowText(_T("OGG音频文件")); - //else if (file_type == _T("m4a")) - // m_file_type_edit.SetWindowText(_T("MPEG-4 音频文件")); - //else - // m_file_type_edit.SetWindowText((file_type + _T("文件")).c_str()); m_file_type_edit.SetWindowText((CAudioCommon::GetAudioDescriptionByExtension(file_type)).c_str()); //显示文件长度 wstring song_length; if (m_all_song_info[m_index].length().isZero()) - song_length = CCommon::LoadText(IDS_CANNOT_GET_SONG_LENGTH); + song_length = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_FILE_DURATION_UNKNOWN"); else song_length = m_all_song_info[m_index].length().toString2(); m_song_length_edit.SetWindowText(song_length.c_str()); @@ -131,15 +120,15 @@ void CPropertyTabDlg::ShowInfo() SetDlgItemText(IDC_BITS_DIPTH, CSongInfoHelper::GetBitsString(m_all_song_info[m_index])); //显示位声道数 - SetDlgItemText(IDC_CHANNELS, CSongInfoHelper::GetChannelsString(m_all_song_info[m_index])); + SetDlgItemText(IDC_CHANNELS, CSongInfoHelper::GetChannelsString(m_all_song_info[m_index].channels).c_str()); //显示歌词路径 if(m_all_song_info[m_index].IsSameSong(CPlayer::GetInstance().GetCurrentSongInfo()) && CPlayer::GetInstance().IsInnerLyric()) - m_lyric_file_edit.SetWindowText(CCommon::LoadText(IDS_INNER_LYRIC)); + m_lyric_file_edit.SetWindowText(theApp.m_str_table.LoadText(L"TXT_INNER_LYRIC").c_str()); else if(!m_all_song_info[m_index].lyric_file.empty()) m_lyric_file_edit.SetWindowText(m_all_song_info[m_index].lyric_file.c_str()); else - m_lyric_file_edit.SetWindowText(CCommon::LoadText(IDS_NO_MATCHED_LYRIC)); + m_lyric_file_edit.SetWindowText(theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_FILE_LRC_FILE_NO_LINK").c_str()); //显示音频信息 //CString info; @@ -160,13 +149,7 @@ void CPropertyTabDlg::ShowInfo() auto tag_type = m_all_song_info[m_index].tag_type; if (tag_type != 0) { - CString tag_type_str{ CCommon::LoadText(IDS_MP3_TAG_TYPE) }; - //if (tag_type == 0) - //{ - // tag_type_str += CCommon::LoadText(IDS_OTHER); - //} - //else - //{ + wstring tag_type_str; if (tag_type & T_ID3V1) tag_type_str += _T("ID3v1 "); if (tag_type & T_ID3V2) @@ -177,8 +160,9 @@ void CPropertyTabDlg::ShowInfo() tag_type_str += _T("RIFF "); if (tag_type & T_MP4) tag_type_str += _T("MP4 "); - //} - SetDlgItemText(IDC_TAG_TYPE_STATIC, tag_type_str); + tag_type_str.pop_back(); + tag_type_str = theApp.m_str_table.LoadTextFormat(L"TXT_PROPERTY_DLG_TAG_TYPE", { tag_type_str }); + SetDlgItemText(IDC_TAG_TYPE_STATIC, tag_type_str.c_str()); } else { @@ -251,6 +235,123 @@ void CPropertyTabDlg::OnTabEntered() ShowInfo(); } +bool CPropertyTabDlg::InitializeControls() +{ + wstring temp; + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_FILE_INFO"); + SetDlgItemTextW(IDC_TXT_PROPERTY_DLG_FILE_INFO_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_FILE_NAME"); + SetDlgItemTextW(IDC_TXT_PROPERTY_DLG_FILE_NAME_STATIC, temp.c_str()); + // IDC_FILE_NAME_EDIT + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_FILE_PATH"); + SetDlgItemTextW(IDC_TXT_PROPERTY_DLG_FILE_PATH_STATIC, temp.c_str()); + // IDC_FILE_PATH_EDIT + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_FILE_TYPE"); + SetDlgItemTextW(IDC_TXT_PROPERTY_DLG_FILE_TYPE_STATIC, temp.c_str()); + // IDC_FILE_TYPE_EDIT + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_FILE_DURATION"); + SetDlgItemTextW(IDC_TXT_PROPERTY_DLG_FILE_DURATION_STATIC, temp.c_str()); + // IDC_SONG_LENGTH_EDIT + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_FILE_SIZE"); + SetDlgItemTextW(IDC_TXT_PROPERTY_DLG_FILE_SIZE_STATIC, temp.c_str()); + // IDC_FILE_SIZE_EDIT + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_FILE_BIT_RATE"); + SetDlgItemTextW(IDC_TXT_PROPERTY_DLG_FILE_BIT_RATE_STATIC, temp.c_str()); + // IDC_BIT_RATE_EDIT + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_FILE_CHANNELS"); + SetDlgItemTextW(IDC_TXT_PROPERTY_DLG_FILE_CHANNELS_STATIC, temp.c_str()); + // IDC_CHANNELS + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_FILE_FREQ"); + SetDlgItemTextW(IDC_TXT_PROPERTY_DLG_FILE_FREQ_STATIC, temp.c_str()); + // IDC_SAMPLE_FREQ + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_FILE_BIT_DEPTH"); + SetDlgItemTextW(IDC_TXT_PROPERTY_DLG_FILE_BIT_DEPTH_STATIC, temp.c_str()); + // IDC_BITS_DIPTH + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_FILE_LRC_FILE"); + SetDlgItemTextW(IDC_LYRIC_FILE_STATIC, temp.c_str()); + // IDC_LYRIC_FILE_EDIT + + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_TAG_INFO"); + SetDlgItemTextW(IDC_TXT_PROPERTY_DLG_TAG_INFO_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_TAG_TITLE"); + SetDlgItemTextW(IDC_TXT_PROPERTY_DLG_TAG_TITLE_STATIC, temp.c_str()); + // IDC_TITEL_EDIT + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_TAG_ARTIST"); + SetDlgItemTextW(IDC_TXT_PROPERTY_DLG_TAG_ARTIST_STATIC, temp.c_str()); + // IDC_ARTIST_EDIT + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_TAG_ALBUM"); + SetDlgItemTextW(IDC_TXT_PROPERTY_DLG_TAG_ALBUM_STATIC, temp.c_str()); + // IDC_ALBUM_EDIT + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_TAG_TRACK"); + SetDlgItemTextW(IDC_TXT_PROPERTY_DLG_TAG_TRACK_STATIC, temp.c_str()); + // IDC_TRACK_EDIT + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_TAG_YEAR"); + SetDlgItemTextW(IDC_TXT_PROPERTY_DLG_TAG_YEAR_STATIC, temp.c_str()); + // IDC_YEAR_EDIT + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_TAG_GENRE"); + SetDlgItemTextW(IDC_TXT_PROPERTY_DLG_TAG_GENRE_STATIC, temp.c_str()); + // IDC_GENRE_COMBO + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_TAG_COMMENT"); + SetDlgItemTextW(IDC_TXT_PROPERTY_DLG_TAG_COMMENT_STATIC, temp.c_str()); + // IDC_COMMENT_EDIT + // IDC_TAG_TYPE_STATIC + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_FROM_FILE_NAME"); + SetDlgItemTextW(IDC_GET_TAG_FROM_FILE_NAME_BUTTON, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_FROM_LRC"); + SetDlgItemTextW(IDC_GET_TAG_FROM_LYRIC_BUTTON, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_FROM_ONLINE"); + SetDlgItemTextW(IDC_GET_TAG_ONLINE_BUTTON, temp.c_str()); + + RepositionTextBasedControls({ + { CtrlTextInfo::L1, IDC_TXT_PROPERTY_DLG_FILE_NAME_STATIC }, + { CtrlTextInfo::C0, IDC_FILE_NAME_EDIT }, + { CtrlTextInfo::L1, IDC_TXT_PROPERTY_DLG_FILE_PATH_STATIC }, + { CtrlTextInfo::C0, IDC_FILE_PATH_EDIT }, + { CtrlTextInfo::L1, IDC_TXT_PROPERTY_DLG_FILE_TYPE_STATIC }, + { CtrlTextInfo::C0, IDC_FILE_TYPE_EDIT }, + { CtrlTextInfo::L1, IDC_TXT_PROPERTY_DLG_FILE_DURATION_STATIC }, + { CtrlTextInfo::C0, IDC_SONG_LENGTH_EDIT }, + { CtrlTextInfo::L1, IDC_TXT_PROPERTY_DLG_FILE_BIT_RATE_STATIC }, + { CtrlTextInfo::C0, IDC_BIT_RATE_EDIT }, + { CtrlTextInfo::L1, IDC_TXT_PROPERTY_DLG_FILE_FREQ_STATIC }, + { CtrlTextInfo::C0, IDC_SAMPLE_FREQ }, + { CtrlTextInfo::L1, IDC_LYRIC_FILE_STATIC }, + { CtrlTextInfo::C0, IDC_LYRIC_FILE_EDIT } + }, CtrlTextInfo::W64); + RepositionTextBasedControls({ + { CtrlTextInfo::L1, IDC_TXT_PROPERTY_DLG_FILE_SIZE_STATIC }, + { CtrlTextInfo::C0, IDC_FILE_SIZE_EDIT }, + { CtrlTextInfo::L1, IDC_TXT_PROPERTY_DLG_FILE_CHANNELS_STATIC }, + { CtrlTextInfo::C0, IDC_CHANNELS }, + { CtrlTextInfo::L1, IDC_TXT_PROPERTY_DLG_FILE_BIT_DEPTH_STATIC }, + { CtrlTextInfo::C0, IDC_BITS_DIPTH } + }, CtrlTextInfo::W60); + RepositionTextBasedControls({ + { CtrlTextInfo::L1, IDC_TXT_PROPERTY_DLG_TAG_TITLE_STATIC }, + { CtrlTextInfo::C0, IDC_TITEL_EDIT }, + { CtrlTextInfo::L1, IDC_TXT_PROPERTY_DLG_TAG_ARTIST_STATIC }, + { CtrlTextInfo::C0, IDC_ARTIST_EDIT }, + { CtrlTextInfo::L1, IDC_TXT_PROPERTY_DLG_TAG_ALBUM_STATIC }, + { CtrlTextInfo::C0, IDC_ALBUM_EDIT }, + { CtrlTextInfo::L1, IDC_TXT_PROPERTY_DLG_TAG_TRACK_STATIC }, + { CtrlTextInfo::C0, IDC_TRACK_EDIT }, + { CtrlTextInfo::L1, IDC_TXT_PROPERTY_DLG_TAG_GENRE_STATIC }, + { CtrlTextInfo::C0, IDC_GENRE_COMBO }, + { CtrlTextInfo::L1, IDC_TXT_PROPERTY_DLG_TAG_COMMENT_STATIC }, + { CtrlTextInfo::C0, IDC_COMMENT_EDIT } + }, CtrlTextInfo::W32); + RepositionTextBasedControls({ + { CtrlTextInfo::L1, IDC_TXT_PROPERTY_DLG_TAG_YEAR_STATIC }, + { CtrlTextInfo::C0, IDC_YEAR_EDIT } + }, CtrlTextInfo::W40); + RepositionTextBasedControls({ + { CtrlTextInfo::L3, IDC_GET_TAG_FROM_FILE_NAME_BUTTON, CtrlTextInfo::W32 }, + { CtrlTextInfo::L2, IDC_GET_TAG_FROM_LYRIC_BUTTON, CtrlTextInfo::W32 }, + { CtrlTextInfo::L1, IDC_GET_TAG_ONLINE_BUTTON, CtrlTextInfo::W32 } + }); + return true; +} + void CPropertyTabDlg::DoDataExchange(CDataExchange* pDX) { CTabDlg::DoDataExchange(pDX); @@ -265,7 +366,6 @@ void CPropertyTabDlg::DoDataExchange(CDataExchange* pDX) DDX_Control(pDX, IDC_ALBUM_EDIT, m_album_edit); DDX_Control(pDX, IDC_TRACK_EDIT, m_track_edit); DDX_Control(pDX, IDC_YEAR_EDIT, m_year_edit); - //DDX_Control(pDX, IDC_GENRE_EDIT, m_genre_edit); DDX_Control(pDX, IDC_COMMENT_EDIT, m_comment_edit); DDX_Control(pDX, IDC_LYRIC_FILE_EDIT, m_lyric_file_edit); DDX_Control(pDX, IDC_GENRE_COMBO, m_genre_combo); @@ -490,13 +590,13 @@ int CPropertyTabDlg::SaveModified() CopyMultiTagInfo(song_info.title, cur_song.title); CopyMultiTagInfo(song_info.artist, cur_song.artist); CopyMultiTagInfo(song_info.album, cur_song.album); - if (str_year != CCommon::LoadText(IDS_MULTI_VALUE)) + if (str_year != theApp.m_str_table.LoadText(L"TXT_MULTI_VALUE").c_str()) { cur_song.SetYear(str_year); } CopyMultiTagInfo(song_info.genre, cur_song.genre); CopyMultiTagInfo(song_info.comment, cur_song.comment); - if (str_track != CCommon::LoadText(IDS_MULTI_VALUE)) + if (str_track != theApp.m_str_table.LoadText(L"TXT_MULTI_VALUE").c_str()) { cur_song.track = static_cast(_wtoi(str_track)); } @@ -629,7 +729,10 @@ void CPropertyTabDlg::OnBnClickedGetTagFromLyricButton() if (GetTagFromLyrics(song, result)) ModifyTagInfo(result); else - MessageBox(CCommon::LoadText(IDS_NO_LYRICS_FOUND_INFO), NULL, MB_ICONWARNING | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_PROPERTY_DLG_NO_LYRICS_FOUND"); + MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK); + } } else { @@ -665,17 +768,16 @@ void CPropertyTabDlg::OnBnClickedGetTagFromLyricButton() void CPropertyTabDlg::OnBnClickedGetTagFromFileNameButton() { // TODO: 在此添加控件通知处理程序代码 - CTagFromFileNameDlg dlg; - dlg.HideOriginalBtn(true); + CTagFromNameDlg dlg; if (dlg.DoModal() == IDOK) { + wstring formular = dlg.GetFormularSelected(); CWaitCursor wait_cursor; - wstring str_formular = dlg.GetFormularSelected(); if (!m_batch_edit) { SongInfo song; wstring file_name = CFilePathHelper(m_all_song_info[m_index].file_path).GetFileNameWithoutExtension(); - CPropertyDlgHelper::GetTagFromFileName(file_name, str_formular, song); + CTagFromNameDlg::GetTagFromFileName(formular, file_name, song); ModifyTagInfo(song); } else @@ -684,7 +786,7 @@ void CPropertyTabDlg::OnBnClickedGetTagFromFileNameButton() for (auto& song : m_all_song_info) { wstring file_name = CFilePathHelper(song.file_path).GetFileNameWithoutExtension(); - CPropertyDlgHelper::GetTagFromFileName(file_name, str_formular, song); + CTagFromNameDlg::GetTagFromFileName(formular, file_name, song); } ShowInfo(); m_modified = true; diff --git a/MusicPlayer2/PropertyTabDlg.h b/MusicPlayer2/PropertyTabDlg.h index b0c6ad239..5ab494254 100644 --- a/MusicPlayer2/PropertyTabDlg.h +++ b/MusicPlayer2/PropertyTabDlg.h @@ -1,13 +1,8 @@ #pragma once -#include "Time.h" -#include "Common.h" -#include "Player.h" -#include "EditEx.h" -#include "afxwin.h" -#include "MyComboBox.h" -#include "FilePathHelper.h" #include "TabDlg.h" #include "IPropertyTabDlg.h" +#include "EditEx.h" +#include "MyComboBox.h" // CPropertyTabDlg 对话框 @@ -68,6 +63,7 @@ class CPropertyTabDlg : public CTabDlg, public IPropertyTabDlg void ResetEditModified(); virtual void OnTabEntered() override; //当标签切换到当前窗口时被调用 + virtual bool InitializeControls() override; virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 void ModifyTagInfo(const SongInfo& song); diff --git a/MusicPlayer2/RecentFolderAndPlaylist.cpp b/MusicPlayer2/RecentFolderAndPlaylist.cpp index 2f683788e..28f51821a 100644 --- a/MusicPlayer2/RecentFolderAndPlaylist.cpp +++ b/MusicPlayer2/RecentFolderAndPlaylist.cpp @@ -2,6 +2,7 @@ #include "RecentFolderAndPlaylist.h" #include "FilePathHelper.h" #include "Player.h" +#include "MusicPlayer2.h" CRecentFolderAndPlaylist CRecentFolderAndPlaylist::m_instance; @@ -85,11 +86,11 @@ std::wstring CRecentFolderAndPlaylist::Item::GetName() const CFilePathHelper path_helper{ playlist_info->path }; wstring playlist_name = path_helper.GetFileName(); if (playlist_name == DEFAULT_PLAYLIST_NAME) - playlist_name = CCommon::LoadText(_T("["), IDS_DEFAULT, _T("]")); + playlist_name = theApp.m_str_table.LoadText(L"TXT_PLAYLIST_NAME_DEFAULT"); else if (playlist_name == FAVOURITE_PLAYLIST_NAME) - playlist_name = CCommon::LoadText(_T("["), IDS_MY_FAVURITE, _T("]")); + playlist_name = theApp.m_str_table.LoadText(L"TXT_PLAYLIST_NAME_FAVOURITE"); else if (playlist_name == TEMP_PLAYLIST_NAME) - playlist_name = CCommon::LoadText(_T("["), IDS_TEMP_PLAYLIST, _T("]")); + playlist_name = theApp.m_str_table.LoadText(L"TXT_PLAYLIST_NAME_TEMP"); else playlist_name = path_helper.GetFileNameWithoutExtension(); return playlist_name; diff --git a/MusicPlayer2/RecorderDlg.cpp b/MusicPlayer2/RecorderDlg.cpp deleted file mode 100644 index 0cebec23d..000000000 --- a/MusicPlayer2/RecorderDlg.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// CRecorderDlg.cpp: 实现文件 -// - -#include "stdafx.h" -#include "MusicPlayer2.h" -#include "RecorderDlg.h" -#include "afxdialogex.h" - - -// CRecorderDlg 对话框 - -IMPLEMENT_DYNAMIC(CRecorderDlg, CDialog) - -CRecorderDlg::CRecorderDlg(CWnd* pParent /*=nullptr*/) - : CDialog(IDD_RECORDER_DIALOG, pParent) -{ - -} - -CRecorderDlg::~CRecorderDlg() -{ -} - -void CRecorderDlg::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); -} - - -BEGIN_MESSAGE_MAP(CRecorderDlg, CDialog) -END_MESSAGE_MAP() - - -// CRecorderDlg 消息处理程序 - - -BOOL CRecorderDlg::OnInitDialog() -{ - CDialog::OnInitDialog(); - - // TODO: 在此添加额外的初始化 - - return TRUE; // return TRUE unless you set the focus to a control - // 异常: OCX 属性页应返回 FALSE -} diff --git a/MusicPlayer2/RecorderDlg.h b/MusicPlayer2/RecorderDlg.h deleted file mode 100644 index 17d2ecfb5..000000000 --- a/MusicPlayer2/RecorderDlg.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - - -// CRecorderDlg 对话框 - -class CRecorderDlg : public CDialog -{ - DECLARE_DYNAMIC(CRecorderDlg) - -public: - CRecorderDlg(CWnd* pParent = nullptr); // 标准构造函数 - virtual ~CRecorderDlg(); - -// 对话框数据 -#ifdef AFX_DESIGN_TIME - enum { IDD = IDD_RECORDER_DIALOG }; -#endif - -protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 - - DECLARE_MESSAGE_MAP() -public: - virtual BOOL OnInitDialog(); -}; diff --git a/MusicPlayer2/RenameDlg.cpp b/MusicPlayer2/RenameDlg.cpp new file mode 100644 index 000000000..09f8be68f --- /dev/null +++ b/MusicPlayer2/RenameDlg.cpp @@ -0,0 +1,63 @@ +// RenameDlg.cpp: 实现文件 +// + +#include "stdafx.h" +#include "MusicPlayer2.h" +#include "RenameDlg.h" + + +// CRenameDlg 对话框 + +IMPLEMENT_DYNAMIC(CRenameDlg, CTagSelBaseDlg) + +CRenameDlg::CRenameDlg(CWnd* pParent) + : CTagSelBaseDlg(false, pParent) +{ +} + +CRenameDlg::~CRenameDlg() +{ +} + +CString CRenameDlg::GetDialogName() const +{ + return L"RenameDlg"; +} + +bool CRenameDlg::InitializeControls() +{ + wstring temp; + temp = theApp.m_str_table.LoadText(L"TITLE_RENAME_SONG"); + SetWindowTextW(temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_RENAME_SONG_INFO"); + SetDlgItemTextW(IDC_INFO_STATIC, temp.c_str()); + + return CTagSelBaseDlg::InitializeControls(); +} + +void CRenameDlg::DoDataExchange(CDataExchange* pDX) +{ + CTagSelBaseDlg::DoDataExchange(pDX); +} + +BEGIN_MESSAGE_MAP(CRenameDlg, CTagSelBaseDlg) +END_MESSAGE_MAP() + + +BOOL CRenameDlg::OnInitDialog() +{ + CTagSelBaseDlg::OnInitDialog(); + + // TODO: 在此添加额外的初始化 + SetIcon(IconMgr::IconType::IT_Rename, FALSE); + + if (!m_init_insert_formular.empty()) + { + m_format_combo.SetEditSel(0, -1); + m_format_combo.SetFocus(); + return FALSE; // 对控件设置了焦点所以返回FALSE + } + + return TRUE; // return TRUE unless you set the focus to a control + // 异常: OCX 属性页应返回 FALSE +} diff --git a/MusicPlayer2/RenameDlg.h b/MusicPlayer2/RenameDlg.h new file mode 100644 index 000000000..b427cb538 --- /dev/null +++ b/MusicPlayer2/RenameDlg.h @@ -0,0 +1,22 @@ +#pragma once +#include "TagSelBaseDlg.h" + +// CRenameDlg 对话框 + +class CRenameDlg : public CTagSelBaseDlg +{ + DECLARE_DYNAMIC(CRenameDlg) +public: + CRenameDlg(CWnd* pParent = nullptr); // 标准构造函数 + virtual ~CRenameDlg(); + +protected: + virtual CString GetDialogName() const; + virtual bool InitializeControls() override; + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 + + DECLARE_MESSAGE_MAP() +public: + virtual BOOL OnInitDialog(); +}; + diff --git a/MusicPlayer2/ReverbDlg.cpp b/MusicPlayer2/ReverbDlg.cpp index 404a994f4..d6ddd06d9 100644 --- a/MusicPlayer2/ReverbDlg.cpp +++ b/MusicPlayer2/ReverbDlg.cpp @@ -3,16 +3,16 @@ #include "stdafx.h" #include "MusicPlayer2.h" +#include "Player.h" #include "ReverbDlg.h" -#include "afxdialogex.h" // CReverbDlg 对话框 -IMPLEMENT_DYNAMIC(CReverbDlg, CDialogEx) +IMPLEMENT_DYNAMIC(CReverbDlg, CTabDlg) CReverbDlg::CReverbDlg(CWnd* pParent /*=NULL*/) - : CDialogEx(IDD_REVERB_DIALOG, pParent) + : CTabDlg(IDD_REVERB_DIALOG, pParent) { } @@ -23,32 +23,56 @@ CReverbDlg::~CReverbDlg() void CReverbDlg::EnableControls(bool enable) { - m_reverb_mix_slider.EnableWindow(enable); - m_reverb_time_slider.EnableWindow(enable); + m_reverb_mix_slider.EnableWindow(enable); + m_reverb_time_slider.EnableWindow(enable); } void CReverbDlg::UpdateStaticText(int mix, int time) { - wchar_t buff[16]; - swprintf_s(buff, L"%d%%", mix); - SetDlgItemText(IDC_REVERB_MIX_STATIC, buff); - swprintf_s(buff, L"%.2fs", static_cast(time) / 100); - SetDlgItemText(IDC_REVERB_TIME_STATIC, buff); + wchar_t buff[16]; + swprintf_s(buff, L"%d%%", mix); + SetDlgItemText(IDC_REVERB_MIX_STATIC, buff); + swprintf_s(buff, L"%.2fs", static_cast(time) / 100); + SetDlgItemText(IDC_REVERB_TIME_STATIC, buff); +} + +bool CReverbDlg::InitializeControls() +{ + wstring temp; + temp = theApp.m_str_table.LoadText(L"TXT_REVERB_ENABLE"); + SetDlgItemTextW(IDC_ENABLE_REVERB_CHECK, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_REVERB_STRENGTH"); + SetDlgItemTextW(IDC_TXT_REVERB_STRENGTH_STATIC, temp.c_str()); + // IDC_REVERB_MIX_SLIDER + // IDC_REVERB_MIX_STATIC + temp = theApp.m_str_table.LoadText(L"TXT_REVERB_TIME"); + SetDlgItemTextW(IDC_TXT_REVERB_TIME_STATIC, temp.c_str()); + // IDC_REVERB_TIME_SLIDER + // IDC_REVERB_TIME_STATIC + + RepositionTextBasedControls({ + { CtrlTextInfo::L3, IDC_TXT_REVERB_STRENGTH_STATIC }, + { CtrlTextInfo::L2, IDC_REVERB_MIX_SLIDER }, + { CtrlTextInfo::L1, IDC_REVERB_MIX_STATIC }, + { CtrlTextInfo::L3, IDC_TXT_REVERB_TIME_STATIC }, + { CtrlTextInfo::L2, IDC_REVERB_TIME_SLIDER }, + { CtrlTextInfo::L1, IDC_REVERB_TIME_STATIC } + }); + + return true; } void CReverbDlg::DoDataExchange(CDataExchange* pDX) { - CDialogEx::DoDataExchange(pDX); - DDX_Control(pDX, IDC_REVERB_MIX_SLIDER, m_reverb_mix_slider); - DDX_Control(pDX, IDC_REVERB_TIME_SLIDER, m_reverb_time_slider); - DDX_Control(pDX, IDC_ENABLE_REVERB_CHECK, m_enable_reverb_chk); + CTabDlg::DoDataExchange(pDX); + DDX_Control(pDX, IDC_REVERB_MIX_SLIDER, m_reverb_mix_slider); + DDX_Control(pDX, IDC_REVERB_TIME_SLIDER, m_reverb_time_slider); } -BEGIN_MESSAGE_MAP(CReverbDlg, CDialogEx) - ON_WM_HSCROLL() - ON_WM_CTLCOLOR() - ON_BN_CLICKED(IDC_ENABLE_REVERB_CHECK, &CReverbDlg::OnBnClickedEnableReverbCheck) +BEGIN_MESSAGE_MAP(CReverbDlg, CTabDlg) + ON_WM_HSCROLL() + ON_BN_CLICKED(IDC_ENABLE_REVERB_CHECK, &CReverbDlg::OnBnClickedEnableReverbCheck) ON_WM_DESTROY() END_MESSAGE_MAP() @@ -58,72 +82,56 @@ END_MESSAGE_MAP() BOOL CReverbDlg::OnInitDialog() { - CDialogEx::OnInitDialog(); + CTabDlg::OnInitDialog(); - // TODO: 在此添加额外的初始化 - //设置背景色为白色 - SetBackgroundColor(RGB(255, 255, 255)); + // TODO: 在此添加额外的初始化 - //初始化滑动条 - m_reverb_mix_slider.SetRange(0, 100); - m_reverb_mix_slider.SetPos(CPlayer::GetInstance().GetReverbMix()); - m_reverb_time_slider.SetRange(1, 300); - m_reverb_time_slider.SetPos(CPlayer::GetInstance().GetReverbTime()); + //初始化滑动条 + m_reverb_mix_slider.SetRange(0, 100); + m_reverb_mix_slider.SetPos(CPlayer::GetInstance().GetReverbMix()); + m_reverb_time_slider.SetRange(1, 300); + m_reverb_time_slider.SetPos(CPlayer::GetInstance().GetReverbTime()); - //初始化静态控件的文本 - UpdateStaticText(m_reverb_mix_slider.GetPos(), m_reverb_time_slider.GetPos()); + //初始化静态控件的文本 + UpdateStaticText(m_reverb_mix_slider.GetPos(), m_reverb_time_slider.GetPos()); - //初始化混响开关复选框 - m_enable_reverb_chk.SetCheck(CPlayer::GetInstance().GetReverbEnable()); + //初始化混响开关复选框 + CheckDlgButton(IDC_ENABLE_REVERB_CHECK, CPlayer::GetInstance().GetReverbEnable()); if (CPlayer::GetInstance().IsFfmpegCore() || CPlayer::GetInstance().IsMciCore()) { EnableControls(false); - m_enable_reverb_chk.EnableWindow(FALSE); + EnableDlgCtrl(IDC_ENABLE_REVERB_CHECK, false); } else { //初始化控件的启用状态 EnableControls(CPlayer::GetInstance().GetReverbEnable()); } - return TRUE; // return TRUE unless you set the focus to a control - // 异常: OCX 属性页应返回 FALSE + return TRUE; // return TRUE unless you set the focus to a control + // 异常: OCX 属性页应返回 FALSE } void CReverbDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { - // TODO: 在此添加消息处理程序代码和/或调用默认值 - if (pScrollBar->GetDlgCtrlID() == IDC_REVERB_MIX_SLIDER || pScrollBar->GetDlgCtrlID() == IDC_REVERB_TIME_SLIDER) - { - int mix{ m_reverb_mix_slider.GetPos() }; - int time{ m_reverb_time_slider.GetPos() }; - CPlayer::GetInstance().GetPlayerCore()->SetReverb(mix, time); - UpdateStaticText(mix, time); - } - - CDialogEx::OnHScroll(nSBCode, nPos, pScrollBar); -} - + // TODO: 在此添加消息处理程序代码和/或调用默认值 + if (pScrollBar->GetDlgCtrlID() == IDC_REVERB_MIX_SLIDER || pScrollBar->GetDlgCtrlID() == IDC_REVERB_TIME_SLIDER) + { + int mix{ m_reverb_mix_slider.GetPos() }; + int time{ m_reverb_time_slider.GetPos() }; + CPlayer::GetInstance().GetPlayerCore()->SetReverb(mix, time); + UpdateStaticText(mix, time); + } -HBRUSH CReverbDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) -{ - HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor); - - // TODO: 在此更改 DC 的任何特性 - if (pWnd == &m_reverb_mix_slider || pWnd == &m_reverb_time_slider) //设置滑动条控件的背景色为白色 - { - return (HBRUSH)::GetStockObject(WHITE_BRUSH); - } - // TODO: 如果默认的不是所需画笔,则返回另一个画笔 - return hbr; + CTabDlg::OnHScroll(nSBCode, nPos, pScrollBar); } void CReverbDlg::OnBnClickedEnableReverbCheck() { - // TODO: 在此添加控件通知处理程序代码 - bool enable = (m_enable_reverb_chk.GetCheck() != 0); - CPlayer::GetInstance().EnableReverb(enable); - EnableControls(enable); + // TODO: 在此添加控件通知处理程序代码 + bool enable = (IsDlgButtonChecked(IDC_ENABLE_REVERB_CHECK) != FALSE); + CPlayer::GetInstance().EnableReverb(enable); + EnableControls(enable); } @@ -132,5 +140,5 @@ void CReverbDlg::OnDestroy() CPlayer::GetInstance().SetReverbMix(m_reverb_mix_slider.GetPos()); CPlayer::GetInstance().SetReverbTime(m_reverb_time_slider.GetPos()); - CDialogEx::OnDestroy(); + CTabDlg::OnDestroy(); } diff --git a/MusicPlayer2/ReverbDlg.h b/MusicPlayer2/ReverbDlg.h index 06538988b..9f646d6c7 100644 --- a/MusicPlayer2/ReverbDlg.h +++ b/MusicPlayer2/ReverbDlg.h @@ -1,38 +1,35 @@ #pragma once -#include "afxcmn.h" -#include "afxwin.h" - +#include "TabDlg.h" // CReverbDlg 对话框 -class CReverbDlg : public CDialogEx +class CReverbDlg : public CTabDlg { - DECLARE_DYNAMIC(CReverbDlg) + DECLARE_DYNAMIC(CReverbDlg) public: - CReverbDlg(CWnd* pParent = NULL); // 标准构造函数 - virtual ~CReverbDlg(); + CReverbDlg(CWnd* pParent = NULL); // 标准构造函数 + virtual ~CReverbDlg(); // 对话框数据 #ifdef AFX_DESIGN_TIME - enum { IDD = IDD_REVERB_DIALOG }; + enum { IDD = IDD_REVERB_DIALOG }; #endif protected: - CSliderCtrl m_reverb_mix_slider; - CSliderCtrl m_reverb_time_slider; + CSliderCtrl m_reverb_mix_slider; + CSliderCtrl m_reverb_time_slider; - void EnableControls(bool enable); //启用或禁用控件 - void UpdateStaticText(int mix, int time); //更新静态控件上的文本 + void EnableControls(bool enable); //启用或禁用控件 + void UpdateStaticText(int mix, int time); //更新静态控件上的文本 - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 + virtual bool InitializeControls() override; + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 - DECLARE_MESSAGE_MAP() + DECLARE_MESSAGE_MAP() public: - virtual BOOL OnInitDialog(); - afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); - afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); - CButton m_enable_reverb_chk; - afx_msg void OnBnClickedEnableReverbCheck(); + virtual BOOL OnInitDialog(); + afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); + afx_msg void OnBnClickedEnableReverbCheck(); afx_msg void OnDestroy(); }; diff --git a/MusicPlayer2/ScintillaEditView.cpp b/MusicPlayer2/ScintillaEditView.cpp index 758a9cbee..350ad5e56 100644 --- a/MusicPlayer2/ScintillaEditView.cpp +++ b/MusicPlayer2/ScintillaEditView.cpp @@ -4,6 +4,7 @@ #include "stdafx.h" #include "ScintillaEditView.h" #include "Common.h" +#include "MusicPlayer2.h" // CScintillaEditView @@ -441,6 +442,9 @@ void CScintillaEditView::SetContextMenu(CMenu* pMenu, CWnd* pMenuOwner) { if (pMenu != nullptr) { + // 这里当前没有使用,使用的是Scintilla的默认右键菜单 + // 我改了SCI_USEPOPUP的处理,使用lParam传递string table + // 如果真的要SendMessage(SCI_USEPOPUP, SC_POPUP_NEVER);记得改回去 m_pMenu = pMenu; m_pContextMenuOwner = pMenuOwner; SendMessage(SCI_USEPOPUP, SC_POPUP_NEVER); @@ -529,7 +533,9 @@ void CScintillaEditView::OnInitialUpdate() { CView::OnInitialUpdate(); - // TODO: 在此添加专用代码和/或调用基类 + const auto& str_table = theApp.m_str_table.GetScintillaStrMap(); + SendMessage(SCI_USEPOPUP, SC_POPUP_ALL, reinterpret_cast(&str_table)); // 设置右键菜单为启用,并传递string table + SendMessage(SCI_SETCODEPAGE, SC_CP_UTF8); //总是使用Unicode SendMessage(SCI_SETMARGINTYPEN, SCINTILLA_MARGIN_LINENUMBER, SC_MARGIN_NUMBER); diff --git a/MusicPlayer2/SearchEditCtrl.cpp b/MusicPlayer2/SearchEditCtrl.cpp index 58d104528..8bdafbb57 100644 --- a/MusicPlayer2/SearchEditCtrl.cpp +++ b/MusicPlayer2/SearchEditCtrl.cpp @@ -34,7 +34,7 @@ void CSearchEditCtrl::OnDrawBrowseButton(CDC * pDC, CRect rect, BOOL bIsButtonPr //使用双缓冲绘图 CDrawDoubleBuffer drawDoubleBuffer(pDC, rect); CDrawCommon drawer; - drawer.Create(drawDoubleBuffer.GetMemDC(), this); + drawer.Create(drawDoubleBuffer.GetMemDC()); CRect rc_draw{ rect }; rc_draw.MoveToXY(0, 0); @@ -78,12 +78,15 @@ void CSearchEditCtrl::OnDrawBrowseButton(CDC * pDC, CRect rect, BOOL bIsButtonPr drawer.GetDC()->FillSolidRect(rc_draw, btn_color); } - auto& icon{ m_draw_clear_btn ? theApp.m_icon_set.close : theApp.m_icon_set.find_songs }; //文本框为空时显示搜索图标,否则显示关闭图标 - CSize icon_size = icon.GetSize(); + IconMgr::IconType icon_type = IconMgr::IconType::IT_Find; + if (m_draw_clear_btn) // 文本框为空时显示搜索图标,否则显示关闭图标 + icon_type = IconMgr::IconType::IT_Cancel; + HICON hIcon = theApp.m_icon_mgr.GetHICON(icon_type, IconMgr::IconStyle::IS_OutlinedDark, IconMgr::IconSize::IS_DPI_16); + CSize icon_size = IconMgr::GetIconSize(IconMgr::IconSize::IS_DPI_16); CPoint icon_top_left; icon_top_left.x = rc_draw.left + (rc_draw.Width() - icon_size.cx) / 2; icon_top_left.y = rc_draw.top + (rc_draw.Height() - icon_size.cy) / 2; - drawer.DrawIcon(icon.GetIcon(true), icon_top_left, icon_size); + drawer.DrawIcon(hIcon, icon_top_left, icon_size); static bool last_draw_clear_btn{ false }; if (last_draw_clear_btn != m_draw_clear_btn) @@ -159,8 +162,8 @@ void CSearchEditCtrl::PreSubclassWindow() // TODO: 在此添加专用代码和/或调用基类 m_tool_tip.Create(this, TTS_ALWAYSTIP); m_tool_tip.SetMaxTipWidth(theApp.DPI(400)); - m_tool_tip.AddTool(this, CCommon::LoadText(IDS_CLEAR_SEARCH_RESULT), CRect(), 1); - m_tool_tip.AddTool(this, CCommon::LoadText(IDS_INPUT_KEY_WORD), CRect(), 2); + m_tool_tip.AddTool(this, theApp.m_str_table.LoadText(L"TIP_SEARCH_EDIT_CLEAN").c_str(), CRect(), 1); + m_tool_tip.AddTool(this, theApp.m_str_table.LoadText(L"TIP_SEARCH_EDIT_INPUT").c_str(), CRect(), 2); UpdateToolTipPosition(); CMFCEditBrowseCtrl::PreSubclassWindow(); diff --git a/MusicPlayer2/SelectItemDlg.cpp b/MusicPlayer2/SelectItemDlg.cpp index dfc15d2fc..406f6fa2d 100644 --- a/MusicPlayer2/SelectItemDlg.cpp +++ b/MusicPlayer2/SelectItemDlg.cpp @@ -4,7 +4,6 @@ #include "stdafx.h" #include "MusicPlayer2.h" #include "SelectItemDlg.h" -#include "afxdialogex.h" // CSelectItemDlg 对话框 @@ -12,7 +11,7 @@ IMPLEMENT_DYNAMIC(CSelectItemDlg, CBaseDialog) CSelectItemDlg::CSelectItemDlg(const vector& items, CWnd* pParent /*=nullptr*/) - : CBaseDialog(IDD_SELECT_ITEM_DIALOG, pParent), m_items(items) + : CBaseDialog(IDD_SELECT_ITEM_DIALOG, pParent), m_items(items) { } @@ -26,9 +25,9 @@ void CSelectItemDlg::SetTitle(LPCTSTR title) m_title = title; } -void CSelectItemDlg::SetDlgIcon(HICON icon) +void CSelectItemDlg::SetDlgIcon(IconMgr::IconType icon_type) { - m_icon = icon; + m_icon_type = icon_type; } wstring CSelectItemDlg::GetSelectedItem() const @@ -38,16 +37,29 @@ wstring CSelectItemDlg::GetSelectedItem() const return wstring(); } -void CSelectItemDlg::DoDataExchange(CDataExchange* pDX) +CString CSelectItemDlg::GetDialogName() const { - CBaseDialog::DoDataExchange(pDX); - DDX_Control(pDX, IDC_LIST1, m_list_ctrl); + return _T("SelectItemDlg"); } +bool CSelectItemDlg::InitializeControls() +{ + SetWindowTextW(m_title); + // IDC_LIST1 + // IDOK + // IDCANCEL + + RepositionTextBasedControls({ + { CtrlTextInfo::R1, IDOK, CtrlTextInfo::W32 }, + { CtrlTextInfo::R2, IDCANCEL, CtrlTextInfo::W32 } + }); + return true; +} -CString CSelectItemDlg::GetDialogName() const +void CSelectItemDlg::DoDataExchange(CDataExchange* pDX) { - return _T("SelectItemDlg"); + CBaseDialog::DoDataExchange(pDX); + DDX_Control(pDX, IDC_LIST1, m_list_ctrl); } BEGIN_MESSAGE_MAP(CSelectItemDlg, CBaseDialog) @@ -63,11 +75,10 @@ BOOL CSelectItemDlg::OnInitDialog() CBaseDialog::OnInitDialog(); // TODO: 在此添加额外的初始化 - SetWindowText(m_title); - if (m_icon == NULL) - SetIcon(theApp.m_icon_set.app.GetIcon(), FALSE); + if (m_icon_type == IconMgr::IconType::IT_NO_ICON) + SetIcon(IconMgr::IconType::IT_App, FALSE); else - SetIcon(m_icon, FALSE); + SetIcon(m_icon_type, FALSE); for (const auto& str : m_items) m_list_ctrl.AddString(str.c_str()); diff --git a/MusicPlayer2/SelectItemDlg.h b/MusicPlayer2/SelectItemDlg.h index 8d7c0321b..e085c7abf 100644 --- a/MusicPlayer2/SelectItemDlg.h +++ b/MusicPlayer2/SelectItemDlg.h @@ -1,41 +1,40 @@ #pragma once -#include "CListBoxEnhanced.h" #include "BaseDialog.h" +#include "CListBoxEnhanced.h" // CSelectItemDlg 对话框 class CSelectItemDlg : public CBaseDialog { - DECLARE_DYNAMIC(CSelectItemDlg) + DECLARE_DYNAMIC(CSelectItemDlg) public: - CSelectItemDlg(const vector& items, CWnd* pParent = nullptr); // 标准构造函数 - virtual ~CSelectItemDlg(); - - void SetTitle(LPCTSTR title); - void SetDlgIcon(HICON icon); - - wstring GetSelectedItem() const; + CSelectItemDlg(const vector& items, CWnd* pParent = nullptr); // 标准构造函数 + virtual ~CSelectItemDlg(); // 对话框数据 #ifdef AFX_DESIGN_TIME - enum { IDD = IDD_SELECT_ITEM_DIALOG }; + enum { IDD = IDD_SELECT_ITEM_DIALOG }; #endif +public: + void SetTitle(LPCTSTR title); + void SetDlgIcon(IconMgr::IconType icon_type); + wstring GetSelectedItem() const; + private: CListBoxEnhanced m_list_ctrl; CString m_title; const vector& m_items; int m_item_selected{ -1 }; - HICON m_icon{}; + IconMgr::IconType m_icon_type{ IconMgr::IconType::IT_NO_ICON }; protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 - - DECLARE_MESSAGE_MAP() - virtual CString GetDialogName() const override; + virtual bool InitializeControls() override; + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 + DECLARE_MESSAGE_MAP() public: virtual BOOL OnInitDialog(); afx_msg void OnLvnItemchangedList1(NMHDR *pNMHDR, LRESULT *pResult); diff --git a/MusicPlayer2/SetPathDlg.cpp b/MusicPlayer2/SetPathDlg.cpp index 46833839a..3c112c96e 100644 --- a/MusicPlayer2/SetPathDlg.cpp +++ b/MusicPlayer2/SetPathDlg.cpp @@ -3,8 +3,8 @@ #include "stdafx.h" #include "MusicPlayer2.h" +#include "Player.h" #include "SetPathDlg.h" -#include "afxdialogex.h" #include "MusicPlayerCmdHelper.h" #include "RecentFolderAndPlaylist.h" @@ -104,7 +104,7 @@ void CSetPathDlg::ShowPathList() if (m_search_result.empty()) { m_path_list.InsertItem(0, _T("")); - m_path_list.SetItemText(0, 1, CCommon::LoadText(IDS_NO_RESULT_TO_SHOW)); + m_path_list.SetItemText(0, 1, theApp.m_str_table.LoadText(L"TXT_PLAYLIST_CTRL_NO_RESULT_TO_SHOW").c_str()); m_path_list.EnableWindow(FALSE); return; } @@ -140,7 +140,7 @@ void CSetPathDlg::SetListRowData(int index, const PathInfo & path_info) m_path_list.SetItemText(index, 2, path_info.path.c_str()); if (path_info.contain_sub_folder) - m_path_list.SetItemText(index, 3, CCommon::LoadText(IDS_YES)); + m_path_list.SetItemText(index, 3, theApp.m_str_table.LoadText(L"TXT_LIB_PAHT_IS_CONTAIN_SUB_FOLDER_YES").c_str()); else m_path_list.SetItemText(index, 3, _T("")); @@ -164,6 +164,25 @@ void CSetPathDlg::OnTabEntered() SetButtonsEnable(); } +bool CSetPathDlg::InitializeControls() +{ + wstring temp; + temp = theApp.m_str_table.LoadText(L"TXT_LIB_PATH_CURRENT_FOLDER"); + SetDlgItemTextW(IDC_TXT_LIB_PATH_CURRENT_FOLDER_STATIC, temp.c_str()); + // IDC_PATH_EDIT + temp = theApp.m_str_table.LoadText(L"TXT_LIB_PATH_OPEN_NEW_FOLDER"); + SetDlgItemTextW(IDC_OPEN_FOLDER, temp.c_str()); + // IDC_SEARCH_EDIT + // IDC_PATH_LIST + + RepositionTextBasedControls({ + { CtrlTextInfo::L1, IDC_TXT_LIB_PATH_CURRENT_FOLDER_STATIC }, + { CtrlTextInfo::C0, IDC_PATH_EDIT }, + { CtrlTextInfo::R1, IDC_OPEN_FOLDER, CtrlTextInfo::W32 } + }); + return true; +} + void CSetPathDlg::DoDataExchange(CDataExchange* pDX) { CTabDlg::DoDataExchange(pDX); @@ -208,20 +227,16 @@ BOOL CSetPathDlg::OnInitDialog() vector width; CalculateColumeWidth(width); m_path_list.SetExtendedStyle(m_path_list.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_LABELTIP); - m_path_list.InsertColumn(0, CCommon::LoadText(IDS_NUMBER), LVCFMT_LEFT, width[0]); - m_path_list.InsertColumn(1, CCommon::LoadText(IDS_FOLDER), LVCFMT_LEFT, width[1]); - m_path_list.InsertColumn(2, CCommon::LoadText(IDS_PATH), LVCFMT_LEFT, width[2]); - m_path_list.InsertColumn(3, CCommon::LoadText(IDS_CONTAIN_SUB_FOLDER), LVCFMT_LEFT, width[3]); - m_path_list.InsertColumn(4, CCommon::LoadText(IDS_TRACK_PLAYED), LVCFMT_LEFT, width[4]); - m_path_list.InsertColumn(5, CCommon::LoadText(IDS_TRACK_TOTAL_NUM), LVCFMT_LEFT, width[5]); - m_path_list.InsertColumn(6, CCommon::LoadText(IDS_TOTAL_LENGTH), LVCFMT_LEFT, width[6]); + m_path_list.InsertColumn(0, theApp.m_str_table.LoadText(L"TXT_SERIAL_NUMBER").c_str(), LVCFMT_LEFT, width[0]); + m_path_list.InsertColumn(1, theApp.m_str_table.LoadText(L"TXT_FOLDER").c_str(), LVCFMT_LEFT, width[1]); + m_path_list.InsertColumn(2, theApp.m_str_table.LoadText(L"TXT_PATH").c_str(), LVCFMT_LEFT, width[2]); + m_path_list.InsertColumn(3, theApp.m_str_table.LoadText(L"TXT_LIB_PAHT_IS_CONTAIN_SUB_FOLDER").c_str(), LVCFMT_LEFT, width[3]); + m_path_list.InsertColumn(4, theApp.m_str_table.LoadText(L"TXT_LAST_PLAYED_TRACK").c_str(), LVCFMT_LEFT, width[4]); + m_path_list.InsertColumn(5, theApp.m_str_table.LoadText(L"TXT_NUM_OF_TRACK").c_str(), LVCFMT_LEFT, width[5]); + m_path_list.InsertColumn(6, theApp.m_str_table.LoadText(L"TXT_TOTAL_LENGTH").c_str(), LVCFMT_LEFT, width[6]); - m_search_edit.SetCueBanner(CCommon::LoadText(IDS_SEARCH_HERE), TRUE); - - ////初始化提示信息 - //m_Mytip.Create(this, TTS_ALWAYSTIP); - //m_Mytip.AddTool(GetDlgItem(IDC_CLEAR_BUTTON), CCommon::LoadText(IDS_CLEAR_SEARCH_RESULT)); - //m_Mytip.AddTool(&m_search_edit, CCommon::LoadText(IDS_INPUT_KEY_WORD)); + wstring prompt_str = theApp.m_str_table.LoadText(L"TXT_SEARCH_PROMPT") + L"(F)"; + m_search_edit.SetCueBanner(prompt_str.c_str(), TRUE); ////设置列表控件的提示总是置顶,用于解决如果弹出此窗口的父窗口具有置顶属性时,提示信息在窗口下面的问题 //m_path_list.GetToolTips()->SetWindowPos(&CWnd::wndTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); @@ -251,7 +266,7 @@ void CSetPathDlg::OnNMRClickPathList(NMHDR *pNMHDR, LRESULT *pResult) SetButtonsEnable(); //弹出右键菜单 - CMenu* pContextMenu = theApp.m_menu_set.m_media_lib_folder_menu.GetSubMenu(0); //获取第一个弹出菜单 + CMenu* pContextMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::LibSetPathMenu); m_path_list.ShowPopupMenu(pContextMenu, pNMItemActivate->iItem, this); *pResult = 0; @@ -284,7 +299,10 @@ void CSetPathDlg::OnOK() { PathInfo path_info = GetSelPath(); if (!CPlayer::GetInstance().SetPath(path_info)) - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } else { CTabDlg::OnOK(); @@ -300,14 +318,17 @@ void CSetPathDlg::OnBnClickedOpenFolder() { // TODO: 在此添加控件通知处理程序代码 static bool include_sub_dir{ false }; + static CString include_sub_dir_str{ theApp.m_str_table.LoadText(L"TXT_FOLDER_BROWSER_INCLUDE_SUB_DIR").c_str() }; + const wstring& title = theApp.m_str_table.LoadText(L"TITLE_FOLDER_BROWSER_SONG_SOURCE"); // 这里原来使用WM_COMMAND, ID_FILE_OPEN_FOLDER但菜单命令无法返回用户是否点击“取消” #ifdef COMPILE_IN_WIN_XP CFolderBrowserDlg folderPickerDlg(this->GetSafeHwnd()); - folderPickerDlg.SetInfo(CCommon::LoadText(IDS_OPEN_FOLDER_INFO)); + folderPickerDlg.SetInfo(title.c_str()); #else CFilePathHelper current_path(CPlayer::GetInstance().GetCurrentDir()); CFolderPickerDialog folderPickerDlg(current_path.GetParentDir().c_str()); - folderPickerDlg.AddCheckButton(IDC_OPEN_CHECKBOX, CCommon::LoadText(IDS_INCLUDE_SUB_DIR), include_sub_dir); //在打开对话框中添加一个复选框 + folderPickerDlg.m_ofn.lpstrTitle = title.c_str(); + folderPickerDlg.AddCheckButton(IDC_OPEN_CHECKBOX, include_sub_dir_str, include_sub_dir); //在打开对话框中添加一个复选框 #endif if (folderPickerDlg.DoModal() == IDOK) { @@ -317,7 +338,10 @@ void CSetPathDlg::OnBnClickedOpenFolder() include_sub_dir = (checked != FALSE); #endif if (!CPlayer::GetInstance().OpenFolder(wstring(folderPickerDlg.GetPathName()), include_sub_dir)) - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } else { CTabDlg::OnOK(); @@ -346,7 +370,10 @@ void CSetPathDlg::OnDeletePath() if (!CPlayer::GetInstance().IsPlaylistMode() && CPlayer::GetInstance().GetCurrentDir2() == del_path) { if (!CPlayer::GetInstance().RemoveCurPlaylistOrFolder()) - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } } else { @@ -371,14 +398,14 @@ void CSetPathDlg::OnBrowsePath() void CSetPathDlg::OnClearInvalidPath() { // TODO: 在此添加命令处理程序代码 - if (MessageBox(CCommon::LoadText(IDS_CLEAR_PATH_INQUARY), NULL, MB_ICONQUESTION | MB_OKCANCEL) == IDCANCEL) + const wstring& inquary_info = theApp.m_str_table.LoadText(L"MSG_LIB_PATH_CLEAR_INQUARY"); + if (MessageBox(inquary_info.c_str(), NULL, MB_ICONQUESTION | MB_OKCANCEL) == IDCANCEL) return; int cleard_cnt = CMusicPlayerCmdHelper::CleanUpRecentFolders(); ShowPathList(); // 重新显示路径列表 CRecentFolderAndPlaylist::Instance().Init(); - CString info; - info = CCommon::LoadTextFormat(IDS_PATH_CLEAR_COMPLETE, { cleard_cnt }); - MessageBox(info, NULL, MB_ICONINFORMATION | MB_OK); + wstring complete_info = theApp.m_str_table.LoadTextFormat(L"MSG_LIB_PATH_CLEAR_COMPLETE", { cleard_cnt }); + MessageBox(complete_info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); } @@ -457,7 +484,10 @@ void CSetPathDlg::OnContainSubFolder() if (!CPlayer::GetInstance().IsPlaylistMode() && CPlayer::GetInstance().GetCurrentDir2() == sel_path) { if (!CPlayer::GetInstance().SetContainSubFolder()) - MessageBox(CCommon::LoadText(IDS_WAIT_AND_RETRY), NULL, MB_ICONINFORMATION | MB_OK); + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY"); + MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK); + } } else { diff --git a/MusicPlayer2/SetPathDlg.h b/MusicPlayer2/SetPathDlg.h index 7845cc7a4..76b0af109 100644 --- a/MusicPlayer2/SetPathDlg.h +++ b/MusicPlayer2/SetPathDlg.h @@ -1,5 +1,4 @@ #pragma once -#include "afxwin.h" #include "Common.h" #include "AudioCommon.h" #include "ListCtrlEx.h" @@ -52,8 +51,9 @@ class CSetPathDlg : public CTabDlg // 计算列宽 void CalculateColumeWidth(vector& width); void SetListRowData(int index, const PathInfo& path_info); - virtual void OnTabEntered() override; + virtual void OnTabEntered() override; + virtual bool InitializeControls() override; virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() diff --git a/MusicPlayer2/SongDataManager.cpp b/MusicPlayer2/SongDataManager.cpp index e9fd64912..1a135bac5 100644 --- a/MusicPlayer2/SongDataManager.cpp +++ b/MusicPlayer2/SongDataManager.cpp @@ -1,6 +1,7 @@ #include "stdafx.h" #include "SongDataManager.h" #include "MusicPlayer2.h" +#include "FilePathHelper.h" CSongDataManager CSongDataManager::m_instance; @@ -33,7 +34,7 @@ void CSongDataManager::SaveSongData(std::wstring path) // 写数据 ar << CString(_T("2.751")); //写入数据版本 ar << static_cast(m_song_data.size()); //写入映射容器的大小 - for (auto& song_data : m_song_data) + for (const auto& song_data : m_song_data) { ar << CString(song_data.first.path.c_str()) << song_data.second.start_pos.toInt() @@ -109,6 +110,7 @@ void CSongDataManager::LoadSongData(std::wstring path) } // LoadSongData执行时主窗口还未启动应该没有其他线程,不过还是加上 std::unique_lock writeLock(m_shared_mutex); + m_song_data.reserve(size); for (int i{}; i < size; i++) { ar >> temp; @@ -245,9 +247,8 @@ void CSongDataManager::LoadSongData(std::wstring path) } catch (CArchiveException* exception) { - CString info; - info = CCommon::LoadTextFormat(IDS_SERIALIZE_ERROR, { path, exception->m_cause }); - theApp.WriteLog(wstring{ info }); + wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_SERIALIZE_ERROR", { path, exception->m_cause }); + theApp.WriteLog(info); } // 关闭对象 ar.Close(); @@ -255,11 +256,6 @@ void CSongDataManager::LoadSongData(std::wstring path) file.Close(); } -void CSongDataManager::SetSongDataModified() -{ - m_song_data_modified = true; -} - bool CSongDataManager::IsSongDataModified() const { return m_song_data_modified; @@ -270,29 +266,55 @@ CString CSongDataManager::GetDataVersion() const return m_data_version; } -void CSongDataManager::SaveSongInfo(const SongInfo& song_info) +bool CSongDataManager::SetSongID(const SongKey& key, const unsigned __int64 id) { - if (song_info.file_path.empty()) - return; std::unique_lock writeLock(m_shared_mutex); - SongInfo& song = m_song_data[song_info]; - song.file_path = song_info.file_path; - song.cue_file_path = song_info.cue_file_path; - song.CopyAudioTag(song_info); - song.start_pos = song_info.start_pos; - song.end_pos = song_info.end_pos; - song.bitrate = song_info.bitrate; - song.song_id = song_info.song_id; - song.is_cue = song_info.is_cue; - song.rating = song_info.rating; - song.freq = song_info.freq; - song.channels = song_info.channels; - song.bits = song_info.bits; - - SetSongDataModified(); + ASSERT(!key.path.empty()); + auto iter = m_song_data.find(key); + if (iter == m_song_data.end()) + return false; // 为避免问题,仅能为媒体库已存在的条目设置id + iter->second.song_id = id; + + m_song_data_modified = true; + return true; +} + +bool CSongDataManager::GetSongID(const SongKey& key, unsigned __int64& id) const +{ + std::shared_lock readLock(m_shared_mutex); + ASSERT(!key.path.empty()); + id = 0; + auto iter = m_song_data.find(key); + if (iter == m_song_data.end()) + return false; + id = iter->second.song_id; + return true; +} + +void CSongDataManager::SaveCueSongInfo(const vector& songs_info) +{ + std::unique_lock writeLock(m_shared_mutex); + for (const auto& song_info : songs_info) + { + SongInfo& song = m_song_data[song_info]; + song.file_path = song_info.file_path; + song.cue_file_path = song_info.cue_file_path; + song.modified_time = song_info.modified_time; + song.CopyAudioTag(song_info); + song.start_pos = song_info.start_pos; + song.end_pos = song_info.end_pos; + song.bitrate = song_info.bitrate; + song.freq = song_info.freq; + song.bits = song_info.bits; + song.channels = song_info.channels; + song.is_cue = true; + song.info_acquired = true; + song.SetChannelInfoAcquired(true); + } + m_song_data_modified = true; } -void CSongDataManager::LoadSongInfo(SongInfo& song_info) +void CSongDataManager::LoadSongInfo(SongInfo& song_info) const { std::shared_lock readLock(m_shared_mutex); auto iter = m_song_data.find(song_info); @@ -304,16 +326,15 @@ void CSongDataManager::LoadSongInfo(SongInfo& song_info) song_info.start_pos = temp.start_pos; song_info.end_pos = temp.end_pos; song_info.bitrate = temp.bitrate; - song_info.song_id = temp.song_id; - song_info.info_acquired = temp.info_acquired;// 以后会更改为仅媒体库内使用,之后删掉这行 song_info.modified_time = temp.modified_time; + song_info.listen_time = temp.listen_time; song_info.freq = temp.freq; song_info.channels = temp.channels; song_info.bits = temp.bits; } } -void CSongDataManager::LoadSongsInfo(vector& songs_info) +void CSongDataManager::LoadSongsInfo(vector& songs_info) const { std::shared_lock readLock(m_shared_mutex); for (SongInfo& song_info : songs_info) @@ -327,9 +348,8 @@ void CSongDataManager::LoadSongsInfo(vector& songs_info) song_info.start_pos = temp.start_pos; song_info.end_pos = temp.end_pos; song_info.bitrate = temp.bitrate; - song_info.song_id = temp.song_id; - song_info.info_acquired = temp.info_acquired;// 以后会更改为仅媒体库内使用,之后删掉这行 song_info.modified_time = temp.modified_time; + song_info.listen_time = temp.listen_time; song_info.freq = temp.freq; song_info.channels = temp.channels; song_info.bits = temp.bits; @@ -337,22 +357,7 @@ void CSongDataManager::LoadSongsInfo(vector& songs_info) } } -SongInfo CSongDataManager::GetSongInfo(const SongDataMapKey& key) -{ - std::shared_lock readLock(m_shared_mutex); - SongInfo song; - auto iter = m_song_data.find(key); - if (iter != m_song_data.end()) - song = iter->second; - if (key.cue_track != 0) - { - song.track = key.cue_track; - song.is_cue = true; - } - return song; -} - -SongInfo CSongDataManager::GetSongInfo3(const SongInfo& song) +SongInfo CSongDataManager::GetSongInfo3(const SongInfo& song) const { std::shared_lock readLock(m_shared_mutex); if (song.IsEmpty()) @@ -367,13 +372,13 @@ SongInfo CSongDataManager::GetSongInfo3(const SongInfo& song) return tmp; } -void CSongDataManager::GetSongData(const std::function& func) +void CSongDataManager::GetSongData(const std::function& func) const { std::shared_lock readLock(m_shared_mutex); func(m_song_data); } -bool CSongDataManager::IsItemExist(const SongDataMapKey& key) +bool CSongDataManager::IsItemExist(const SongKey& key) const { std::shared_lock readLock(m_shared_mutex); auto iter = m_song_data.find(key); @@ -385,16 +390,17 @@ void CSongDataManager::AddItem(const SongInfo& song) std::unique_lock writeLock(m_shared_mutex); ASSERT(!song.file_path.empty()); m_song_data[song] = song; - SetSongDataModified(); + m_song_data_modified = true; } -bool CSongDataManager::RemoveItem(const SongDataMapKey& key) +bool CSongDataManager::RemoveItem(const SongKey& key) { std::unique_lock writeLock(m_shared_mutex); auto iter = m_song_data.find(key); if (iter != m_song_data.end()) { m_song_data.erase(iter); + m_song_data_modified = true; return true; } return false; @@ -404,17 +410,21 @@ int CSongDataManager::RemoveItemIf(std::function& fun_con { std::unique_lock writeLock(m_shared_mutex); // 遍历映射容器,删除不必要的条目。 - vector remove; - for (const auto& data: m_song_data) + int removedCount{}; + auto iter = m_song_data.begin(); + while (iter != m_song_data.end()) { - if (fun_condition(data.second)) - remove.push_back(data.first); - } - for (const auto& key : remove) - { - m_song_data.erase(key); + if (fun_condition(iter->second)) + { + iter = m_song_data.erase(iter); + ++removedCount; + } + else + ++iter; } - return remove.size(); + if (removedCount > 0) + m_song_data_modified = true; + return removedCount; } void CSongDataManager::ClearPlayTime() @@ -424,7 +434,7 @@ void CSongDataManager::ClearPlayTime() { data.second.listen_time = 0; } - SetSongDataModified(); + m_song_data_modified = true; } void CSongDataManager::ClearLastPlayedTime() @@ -434,7 +444,7 @@ void CSongDataManager::ClearLastPlayedTime() { item.second.last_played_time = 0; } - SetSongDataModified(); + m_song_data_modified = true; } void CSongDataManager::ChangeFilePath(const wstring& file_path, const wstring& new_path) @@ -466,7 +476,7 @@ static int CalcualteStringRightMatchedCharNum(const std::wstring& str1, const st return char_matched; } -bool CSongDataManager::FixWrongFilePath(wstring& file_path) +bool CSongDataManager::FixWrongFilePath(wstring& file_path) const { std::wstring file_name{ CFilePathHelper(file_path).GetFileName() }; bool fixed{ false }; diff --git a/MusicPlayer2/SongDataManager.h b/MusicPlayer2/SongDataManager.h index c0f8aa301..4cd70249d 100644 --- a/MusicPlayer2/SongDataManager.h +++ b/MusicPlayer2/SongDataManager.h @@ -1,87 +1,54 @@ #pragma once #include "SongInfo.h" -#include -#include class CSongDataManager { public: ~CSongDataManager(); - struct SongDataMapKey - { - wstring path; - int cue_track{}; // 当存储cue时用来保存音轨号,其他情况为0 - - SongDataMapKey() {} - SongDataMapKey(const wstring& path) :path(path) - { - ASSERT(!path.empty()); - } - SongDataMapKey(const wstring& path, const int& cue_track) :path(path), cue_track(cue_track) - { - ASSERT(!path.empty()); - } - SongDataMapKey(const SongInfo& song_info) - { - ASSERT(!song_info.file_path.empty()); - path = song_info.file_path; - if (song_info.is_cue) - cue_track = song_info.track; - } - - bool operator==(const SongDataMapKey& b) const - { - return path == b.path && cue_track == b.cue_track; - } - }; - - struct SongDataMapKey_Hash - { - size_t operator()(const SongDataMapKey& key) const - { - return std::hash()(key.path) ^ std::hash()(key.cue_track); - } - }; - - using SongDataMap = std::unordered_map; + using SongDataMap = std::unordered_map; static CSongDataManager& GetInstance(); void SaveSongData(std::wstring path); //将所有歌曲信息以序列化的方式保存到文件 void LoadSongData(std::wstring path); //从文件中以序列化的方式读取所有歌曲信息 - void SetSongDataModified(); bool IsSongDataModified() const; CString GetDataVersion() const; - // 将一个歌曲信息保存到m_song_data中 - void SaveSongInfo(const SongInfo& song_info); - // 从媒体库加载信息更新到播放列表项目 - void LoadSongInfo(SongInfo& song_info); - void LoadSongsInfo(vector& song_info); - SongInfo GetSongInfo(const SongDataMapKey& key); + // 设置歌曲ID + bool SetSongID(const SongKey& key, const unsigned __int64 id); + // 获取歌曲ID + bool GetSongID(const SongKey& key, unsigned __int64& id) const; + + // CAudioCommon::GetCueTracks用来将获取的信息存入媒体库(专用,其他位置多半不合适) + void SaveCueSongInfo(const vector& songs_info); + // 从媒体库加载信息更新到播放列表项目(仅加载播放列表需要的属性) + void LoadSongInfo(SongInfo& song_info) const; + void LoadSongsInfo(vector& song_info) const; + // 获取一个媒体库歌曲信息(不存在会返回和参数song一致的SongInfo) // 至少要保证用于查询的file_path,is_cue,track是正确的 // 用于修改媒体库的歌曲属性,修改后需使用CSongDataManager::AddItem保存 - SongInfo GetSongInfo3(const SongInfo& song); + SongInfo GetSongInfo3(const SongInfo& song) const; // 用于外部读取m_song_data,加读锁后以const m_song_data&为参数调用func // 请勿在func中试图修改媒体库以避免未定义行为 - void GetSongData(const std::function& func); + void GetSongData(const std::function& func) const; - bool IsItemExist(const SongDataMapKey& key); + bool IsItemExist(const SongKey& key) const; void AddItem(const SongInfo& song); - bool RemoveItem(const SongDataMapKey& key); + bool RemoveItem(const SongKey& key); int RemoveItemIf(std::function& fun_condition); //删除符合条件的项目,返回已删除个数 void ClearPlayTime(); //清除播放时间统计数据 void ClearLastPlayedTime(); //清除上次播放时间 + // 创建旧媒体库条目的新路径副本(不能用于cue文件) void ChangeFilePath(const wstring& file_path, const wstring& new_path); //如果file_path不存在,则从媒体库中查找文件名相同的最佳匹配的项目,并将file_path更改为正确的路径 - bool FixWrongFilePath(wstring& file_path); + bool FixWrongFilePath(wstring& file_path) const; private: CSongDataManager(); @@ -90,9 +57,9 @@ class CSongDataManager private: SongDataMap m_song_data; //储存所有歌曲信息数据的映射容器,键是每一个音频文件的绝对路径,对象是每一个音频文件的信息 - bool m_song_data_modified{}; + std::atomic m_song_data_modified{ false }; CString m_data_version; // 用于保证m_song_data读写的线程安全,遍历/查找加读锁,添加/删除加写锁 - std::shared_mutex m_shared_mutex; // 线程同步对象 + mutable std::shared_mutex m_shared_mutex; // 线程同步对象 std::unordered_map> m_song_file_name_map; //保存文件名与SongInfo对象的对应关系 }; diff --git a/MusicPlayer2/SongInfo.cpp b/MusicPlayer2/SongInfo.cpp new file mode 100644 index 000000000..86c1e53ac --- /dev/null +++ b/MusicPlayer2/SongInfo.cpp @@ -0,0 +1,385 @@ +#include "stdafx.h" +#include "SongInfo.h" +#include "MusicPlayer2.h" + + +bool SongInfo::NoOnlineLyric() const +{ + return CCommon::GetNumberBit(flags, 0); +} + +void SongInfo::SetNoOnlineLyric(bool val) +{ + CCommon::SetNumberBit(flags, 0, val); +} + +bool SongInfo::NoOnlineAlbumCover() const +{ + return CCommon::GetNumberBit(flags, 1); +} + +void SongInfo::SetNoOnlineAlbumCover(bool val) +{ + CCommon::SetNumberBit(flags, 1, val); +} + +bool SongInfo::AlwaysUseExternalAlbumCover() const +{ + return CCommon::GetNumberBit(flags, 2); +} + +void SongInfo::SetAlwaysUseExternalAlbumCover(bool val) +{ + CCommon::SetNumberBit(flags, 2, val); +} + +bool SongInfo::ChannelInfoAcquired() const +{ + return CCommon::GetNumberBit(flags, 3); +} + +void SongInfo::SetChannelInfoAcquired(bool val) +{ + CCommon::SetNumberBit(flags, 3, val); +} + + +bool SongInfo::ByFileName(const SongInfo& a, const SongInfo& b) +{ + return CCommon::StringCompareInLocalLanguage(a.GetFileName(), b.GetFileName()) < 0; +} + +bool SongInfo::ByFileNameDecending(const SongInfo& a, const SongInfo& b) +{ + return CCommon::StringCompareInLocalLanguage(a.GetFileName(), b.GetFileName()) > 0; +} + +bool SongInfo::ByPath(const SongInfo& a, const SongInfo& b) +{ + return CCommon::StringCompareInLocalLanguage(a.file_path, b.file_path) < 0; +} + +bool SongInfo::ByPathDecending(const SongInfo& a, const SongInfo& b) +{ + return CCommon::StringCompareInLocalLanguage(a.file_path, b.file_path) > 0; +} + +bool SongInfo::ByTitle(const SongInfo& a, const SongInfo& b) +{ + return CCommon::StringCompareInLocalLanguage(a.title, b.title) < 0; +} + +bool SongInfo::ByTitleDecending(const SongInfo& a, const SongInfo& b) +{ + return CCommon::StringCompareInLocalLanguage(a.title, b.title) > 0; +} + +bool SongInfo::ByArtist(const SongInfo& a, const SongInfo& b) +{ + int compare_album = CCommon::StringCompareInLocalLanguage(a.album, b.album); + int compare_artist = CCommon::StringCompareInLocalLanguage(a.artist, b.artist); + if (compare_artist != 0) + return compare_artist < 0; + else if (compare_album != 0) + return compare_album < 0; + else return ByTrack(a, b); +} + +bool SongInfo::ByArtistDecending(const SongInfo& a, const SongInfo& b) +{ + return ByArtist(b, a); +} + +bool SongInfo::ByAlbum(const SongInfo& a, const SongInfo& b) +{ + int compare_album = CCommon::StringCompareInLocalLanguage(a.album, b.album); + int compare_artist = CCommon::StringCompareInLocalLanguage(a.artist, b.artist); + if (compare_album != 0) + return compare_album < 0; + else if (a.track != b.track || a.disc_num != b.disc_num) //唱片集相同的情况下比较音轨号 + return ByTrack(a, b); + else //音轨号仍然相同,比较艺术家 + return compare_artist < 0; +} + +bool SongInfo::ByAlbumDecending(const SongInfo& a, const SongInfo& b) +{ + return ByAlbum(b, a); +} + +bool SongInfo::ByTrack(const SongInfo& a, const SongInfo& b) +{ + if (a.disc_num != b.disc_num) + return a.disc_num < b.disc_num; + else + return a.track < b.track; +} + +bool SongInfo::ByTrackDecending(const SongInfo& a, const SongInfo& b) +{ + return ByTrack(b, a); +} + +bool SongInfo::ByGenre(const SongInfo& a, const SongInfo& b) +{ + return CCommon::StringCompareInLocalLanguage(a.genre, b.genre) < 0; +} + +bool SongInfo::ByGenreDecending(const SongInfo& a, const SongInfo& b) +{ + return CCommon::StringCompareInLocalLanguage(a.genre, b.genre) > 0; +} + +bool SongInfo::ByBitrate(const SongInfo& a, const SongInfo& b) +{ + return a.bitrate < b.bitrate; +} + +bool SongInfo::ByBitrateDecending(const SongInfo& a, const SongInfo& b) +{ + return a.bitrate > b.bitrate; +} + +bool SongInfo::ByYear(const SongInfo& a, const SongInfo& b) +{ + return a.year < b.year; +} + +bool SongInfo::ByYearDecending(const SongInfo& a, const SongInfo& b) +{ + return a.year > b.year; +} + +bool SongInfo::ByListenTime(const SongInfo& a, const SongInfo& b) +{ + return a.listen_time < b.listen_time; +} + +bool SongInfo::ByListenTimeDecending(const SongInfo& a, const SongInfo& b) +{ + return a.listen_time > b.listen_time; +} + +bool SongInfo::ByModifiedTime(const SongInfo& a, const SongInfo& b) +{ + return a.modified_time < b.modified_time; +} + +bool SongInfo::ByModifiedTimeDecending(const SongInfo& a, const SongInfo& b) +{ + return a.modified_time > b.modified_time; +} + +bool SongInfo::ByLastPlay(const SongInfo& a, const SongInfo& b) +{ + return a.last_played_time < b.last_played_time; +} + +bool SongInfo::ByLastPlayDecending(const SongInfo& a, const SongInfo& b) +{ + return a.last_played_time > b.last_played_time; +} + +void SongInfo::CopyAudioTag(const SongInfo& song_info) +{ + title = song_info.title; + artist = song_info.artist; + album = song_info.album; + year = song_info.year; + comment = song_info.comment; + genre = song_info.genre; + genre_idx = song_info.genre_idx; + track = song_info.track; + album_artist = song_info.album_artist; + total_tracks = song_info.total_tracks; + disc_num = song_info.disc_num; + total_discs = song_info.total_discs; + tag_type = song_info.tag_type; +} + +bool SongInfo::IsTitleEmpty() const +{ + static const wstring& default_title = theApp.m_str_table.LoadText(L"TXT_EMPTY_TITLE"); + return title.empty() || title == default_title; +} + +bool SongInfo::IsArtistEmpty() const +{ + static const wstring& default_artist = theApp.m_str_table.LoadText(L"TXT_EMPTY_ARTIST"); + return artist.empty() || artist == default_artist; +} + +bool SongInfo::IsAlbumEmpty() const +{ + static const wstring& default_album = theApp.m_str_table.LoadText(L"TXT_EMPTY_ALBUM"); + return album.empty() || album == default_album; +} + +bool SongInfo::IsYearEmpty() const +{ + return year == 0; +} + +bool SongInfo::IsGenreEmpty() const +{ + static const wstring& default_genre = theApp.m_str_table.LoadText(L"TXT_EMPTY_GENRE"); + return genre.empty() || genre == default_genre; +} + +void SongInfo::GetArtistList(vector& artist_list) const +{ + artist_list.clear(); + if (artist.empty()) + return; + static const wstring split_char = L"/;&、"; + if (artist.find_first_of(split_char) == wstring::npos) // 不含分割字符的字符串不需要处理,直接返回 + { + artist_list.push_back(artist); + return; + } + // 现在是保守分割方案,理论上有可能少切分但不会多,处理后艺术家仍然按照原顺序排列 + vector char_flag(artist.size(), false); + for (size_t i{}; i < artist.size(); ++i) + { + if (split_char.find(artist[i]) == wstring::npos) + char_flag[i] = true; + } + const vector& split_ext = theApp.m_media_lib_setting_data.artist_split_ext; + for (const wstring& str : split_ext) + { + size_t index{ artist.find(str) }; + while (index != wstring::npos) + { + for (size_t i{}; i < str.size(); ++i) + char_flag[index + i] = true; + index = artist.find(str, index + 1); + } + } + auto push_back_artist = [&](size_t _Off, size_t _Count = std::wstring::npos) + { + wstring temp = artist.substr(_Off, _Count); + CCommon::StringNormalize(temp); + if (!temp.empty()) + artist_list.push_back(temp); + }; + size_t start_pos{}; + for (size_t i{}; i < artist.size(); ++i) + { + if (char_flag[i]) + continue; + push_back_artist(start_pos, i - start_pos); + start_pos = i + 1; + } + push_back_artist(start_pos); // 处理最后一项艺术家 +} + +wstring SongInfo::GetFirstArtist() const +{ + vector artist_list; + GetArtistList(artist_list); + if (artist_list.empty()) + return GetArtist(); + return artist_list.at(0); +} + +wstring SongInfo::GetTitle() const +{ + static const wstring& default_title = theApp.m_str_table.LoadText(L"TXT_EMPTY_TITLE"); + return title.empty() ? default_title : title; +} + +wstring SongInfo::GetArtist() const +{ + static const wstring& default_artist = theApp.m_str_table.LoadText(L"TXT_EMPTY_ARTIST"); + return artist.empty() ? default_artist : artist; +} + +wstring SongInfo::GetAlbum() const +{ + static const wstring& default_album = theApp.m_str_table.LoadText(L"TXT_EMPTY_ALBUM"); + return album.empty() ? default_album : album; +} + +wstring SongInfo::GetYear() const +{ + static const wstring& default_year = theApp.m_str_table.LoadText(L"TXT_EMPTY_YEAR"); + if (year == 0) + return default_year; + else + return std::to_wstring(year); +} + +wstring SongInfo::get_year() const +{ + if (year == 0) + return wstring(); + else + return std::to_wstring(year); +} + +wstring SongInfo::GetGenre() const +{ + static const wstring& default_genre = theApp.m_str_table.LoadText(L"TXT_EMPTY_GENRE"); + return genre.empty() ? default_genre : genre; +} + +wstring SongInfo::GetFileName() const +{ + wstring file_name; + size_t index = file_path.rfind(L'\\'); + if (index == wstring::npos) + index = file_path.rfind(L'/'); + if (index == wstring::npos) + return file_path; + + file_name = file_path.substr(index + 1); + return file_name; +} + +wstring SongInfo::GetSongId() const +{ + return std::to_wstring(song_id); +} + +void SongInfo::SetYear(const wchar_t* str_year) +{ + year = static_cast(_wtoi(str_year)); +} + +void SongInfo::SetSongId(const wstring& id) +{ + song_id = _wtoi64(id.c_str()); +} + +bool SongInfo::IsEmpty() const +{ + return file_path.empty() && title.empty() && artist.empty() && album.empty() && comment.empty() && genre.empty() && year == 0 && length().isZero(); +} + +Time SongInfo::length() const +{ + return Time(end_pos - start_pos); +} + +bool SongInfo::IsSameSong(const SongInfo& song) const +{ // 存在file_path和track相同但is_cue不同的情况(分立曲目被播放后又打开一个描述这些歌曲的cue),此时应返回false + if (is_cue != song.is_cue) + return false; + if (file_path != song.file_path) + return false; + if (is_cue && track != song.track) + return false; + return true; +} + +void SongInfo::Normalize() +{ + if (theApp.m_str_table.LoadText(L"TXT_EMPTY_TITLE") == title) + title.clear(); + if (theApp.m_str_table.LoadText(L"TXT_EMPTY_ARTIST") == artist) + artist.clear(); + if (theApp.m_str_table.LoadText(L"TXT_EMPTY_ALBUM") == album) + album.clear(); + if (theApp.m_str_table.LoadText(L"TXT_EMPTY_GENRE") == genre) + genre.clear(); +} diff --git a/MusicPlayer2/SongInfo.h b/MusicPlayer2/SongInfo.h index 55da32595..edaa0f8f3 100644 --- a/MusicPlayer2/SongInfo.h +++ b/MusicPlayer2/SongInfo.h @@ -1,8 +1,5 @@ #pragma once -#include "stdafx.h" #include "Time.h" -#include "Common.h" -#include "Resource.h" enum eTagType { @@ -26,13 +23,12 @@ struct SongInfo wstring genre; // 流派 wstring cue_file_path; // cue文件的路径 wstring album_artist; // 唱片集艺术家 - unsigned __int64 song_id{}; // 歌曲对应的网易云音乐中的歌曲ID + unsigned __int64 song_id{}; // 歌曲对应的网易云音乐中的歌曲ID<仅在媒体库内使用> __int64 last_played_time{}; // 上次播放的时间<仅在媒体库内使用> unsigned __int64 modified_time{}; // 修改时间 int track{}; // 音轨序号 int listen_time{}; // 歌曲累计听的时间(单位为秒)<仅在媒体库内使用> int freq{}; // 采样频率 - //Time lengh{}; // 歌曲的长度,计划移除 Time start_pos{}; // 音频的起始位置 Time end_pos{}; // 音频的结束位置 unsigned short year{}; // 年份 @@ -40,7 +36,7 @@ struct SongInfo WORD flags{}; // 保存一些标志<仅在媒体库内使用> BYTE tag_type{}; // 标签的类型(0:其他;1:ID3v1;2:ID3v2;3:APE) BYTE genre_idx{ 255 }; // 以字节表示的流派号 - bool info_acquired{ false }; // 如果已经获取到了信息,则为ture + bool info_acquired{ false }; // 如果已经获取到了信息,则为ture (实际上已完全没有作用,可以被modified_time==0和ChannelInfoAcquired代替,考虑移除) bool is_favourite{ false }; // 是否在我喜欢的音乐列表内<仅在播放列表内使用> bool is_cue{ false }; // 如果曲目是cue分轨,则为true BYTE rating{ 255 }; // 歌曲分级<仅在媒体库内使用> @@ -50,321 +46,135 @@ struct SongInfo BYTE disc_num{}; // CD序号 BYTE total_discs{}; // CD总数 - //定义一组获取和设置一个标志位的方法。 - //func_name:方法的名称(获取标志位的方法名称为func_name,设置标志位的方法名称为Set+func_name) - //flag_bit:标志位在flags的第几个bit -#define DECLARE_SONG_INFO_FLAGS(func_name, flag_bit) \ - bool func_name() const { return CCommon::GetNumberBit(flags, flag_bit);} \ - void Set##func_name(bool val) { CCommon::SetNumberBit(flags, flag_bit, val); } - - DECLARE_SONG_INFO_FLAGS(NoOnlineLyric, 0) //bit0, 如果为true,则不在线下载歌词 - DECLARE_SONG_INFO_FLAGS(NoOnlineAlbumCover, 1) //bit1, 如果为true,则不在线下载专辑封面 - DECLARE_SONG_INFO_FLAGS(AlwaysUseExternalAlbumCover, 2) //bit2, 如果为true,则总是使用外部封面 - DECLARE_SONG_INFO_FLAGS(ChannelInfoAcquired, 3); //采样率、位深度、声道数信息是否已获取 + // 如果为true,则不在线下载歌词 + bool NoOnlineLyric() const; + // 如果为true,则不在线下载歌词 + void SetNoOnlineLyric(bool val); + // 如果为true,则不在线下载专辑封面 + bool NoOnlineAlbumCover() const; + // 如果为true,则不在线下载专辑封面 + void SetNoOnlineAlbumCover(bool val); + // 如果为true,则总是使用外部封面 + bool AlwaysUseExternalAlbumCover() const; + // 如果为true,则总是使用外部封面 + void SetAlwaysUseExternalAlbumCover(bool val); + // 采样率、位深度、声道数信息是否已获取 + bool ChannelInfoAcquired() const; + // 采样率、位深度、声道数信息是否已获取 + void SetChannelInfoAcquired(bool val); //根据文件名的比较函数,用于以文件名排序 - static bool ByFileName(const SongInfo& a, const SongInfo& b) - { - return CCommon::StringCompareInLocalLanguage(a.GetFileName(), b.GetFileName()) < 0; - } - static bool ByFileNameDecending(const SongInfo& a, const SongInfo& b) - { - return CCommon::StringCompareInLocalLanguage(a.GetFileName(), b.GetFileName()) > 0; - } + static bool ByFileName(const SongInfo& a, const SongInfo& b); + static bool ByFileNameDecending(const SongInfo& a, const SongInfo& b); //根据文件路径的比较函数,用于以文件路径排序 - static bool ByPath(const SongInfo& a, const SongInfo& b) - { - return CCommon::StringCompareInLocalLanguage(a.file_path, b.file_path) < 0; - } - static bool ByPathDecending(const SongInfo& a, const SongInfo& b) - { - return CCommon::StringCompareInLocalLanguage(a.file_path, b.file_path) > 0; - } + static bool ByPath(const SongInfo& a, const SongInfo& b); + static bool ByPathDecending(const SongInfo& a, const SongInfo& b); //根据标题的比较函数,用于以标题排序 - static bool ByTitle(const SongInfo& a, const SongInfo& b) - { - return CCommon::StringCompareInLocalLanguage(a.title, b.title) < 0; - } - static bool ByTitleDecending(const SongInfo& a, const SongInfo& b) - { - return CCommon::StringCompareInLocalLanguage(a.title, b.title) > 0; - } + static bool ByTitle(const SongInfo& a, const SongInfo& b); + static bool ByTitleDecending(const SongInfo& a, const SongInfo& b); //根据艺术家的比较函数,用于以艺术家排序 - static bool ByArtist(const SongInfo& a, const SongInfo& b) - { - int compare_album = CCommon::StringCompareInLocalLanguage(a.album, b.album); - int compare_artist = CCommon::StringCompareInLocalLanguage(a.artist, b.artist); - if (compare_artist != 0) - return compare_artist < 0; - else if (compare_album != 0) - return compare_album < 0; - else return ByTrack(a, b); - } - static bool ByArtistDecending(const SongInfo& a, const SongInfo& b) - { - return ByArtist(b, a); - } + static bool ByArtist(const SongInfo& a, const SongInfo& b); + static bool ByArtistDecending(const SongInfo& a, const SongInfo& b); //根据唱片集的比较函数,用于以唱片集排序 - static bool ByAlbum(const SongInfo& a, const SongInfo& b) - { - int compare_album = CCommon::StringCompareInLocalLanguage(a.album, b.album); - int compare_artist = CCommon::StringCompareInLocalLanguage(a.artist, b.artist); - if (compare_album != 0) - return compare_album < 0; - else if (a.track != b.track || a.disc_num != b.disc_num) //唱片集相同的情况下比较音轨号 - return ByTrack(a, b); - else //音轨号仍然相同,比较艺术家 - return compare_artist < 0; - } - static bool ByAlbumDecending(const SongInfo& a, const SongInfo& b) - { - return ByAlbum(b, a); - } + static bool ByAlbum(const SongInfo& a, const SongInfo& b); + static bool ByAlbumDecending(const SongInfo& a, const SongInfo& b); //根据音轨序号的比较函数,用于以音轨序号排序 - static bool ByTrack(const SongInfo& a, const SongInfo& b) - { - if (a.disc_num != b.disc_num) - return a.disc_num < b.disc_num; - else - return a.track < b.track; - } - static bool ByTrackDecending(const SongInfo& a, const SongInfo& b) - { - return ByTrack(b, a); - } + static bool ByTrack(const SongInfo& a, const SongInfo& b); + static bool ByTrackDecending(const SongInfo& a, const SongInfo& b); //根据流派的比较函数,用于以流派排序 - static bool ByGenre(const SongInfo& a, const SongInfo& b) - { - return CCommon::StringCompareInLocalLanguage(a.genre, b.genre) < 0; - } - static bool ByGenreDecending(const SongInfo& a, const SongInfo& b) - { - return CCommon::StringCompareInLocalLanguage(a.genre, b.genre) > 0; - } + static bool ByGenre(const SongInfo& a, const SongInfo& b); + static bool ByGenreDecending(const SongInfo& a, const SongInfo& b); //根据比特率的比较函数,用于以比特率排序 - static bool ByBitrate(const SongInfo& a, const SongInfo& b) - { - return a.bitrate < b.bitrate; - } - static bool ByBitrateDecending(const SongInfo& a, const SongInfo& b) - { - return a.bitrate > b.bitrate; - } + static bool ByBitrate(const SongInfo& a, const SongInfo& b); + static bool ByBitrateDecending(const SongInfo& a, const SongInfo& b); //根据年份的比较函数,用于以年份排序 - static bool ByYear(const SongInfo& a, const SongInfo& b) - { - return a.year < b.year; - } - static bool ByYearDecending(const SongInfo& a, const SongInfo& b) - { - return a.year > b.year; - } + static bool ByYear(const SongInfo& a, const SongInfo& b); + static bool ByYearDecending(const SongInfo& a, const SongInfo& b); + //根据累计播放时间的比较函数,用于以累计播放时间排序 + static bool ByListenTime(const SongInfo& a, const SongInfo& b); + static bool ByListenTimeDecending(const SongInfo& a, const SongInfo& b); + //根据文件修改时间的比较函数,用于以文件修改时间排序 + static bool ByModifiedTime(const SongInfo& a, const SongInfo& b); + static bool ByModifiedTimeDecending(const SongInfo& a, const SongInfo& b); //根据最后播放时间的比较函数,用于以最后播放时间排序 - static bool ByLastPlay(const SongInfo& a, const SongInfo& b) - { - return a.last_played_time < b.last_played_time; - } - static bool ByLastPlayDecending(const SongInfo& a, const SongInfo& b) - { - return a.last_played_time > b.last_played_time; - } + static bool ByLastPlay(const SongInfo& a, const SongInfo& b); + static bool ByLastPlayDecending(const SongInfo& a, const SongInfo& b); //从另一个SongInfo对象复制标签信息 - void CopyAudioTag(const SongInfo& song_info) - { - title = song_info.title; - artist = song_info.artist; - album = song_info.album; - year = song_info.year; - comment = song_info.comment; - genre = song_info.genre; - genre_idx = song_info.genre_idx; - track = song_info.track; - album_artist = song_info.album_artist; - total_tracks = song_info.total_tracks; - disc_num = song_info.disc_num; - total_discs = song_info.total_discs; - tag_type = song_info.tag_type; - } - - void CopySongInfo(const SongInfo& song_info) - { - CopyAudioTag(song_info); - //lengh = song_info.lengh; // 计划移除 - start_pos = song_info.start_pos; - end_pos = song_info.end_pos; - bitrate = song_info.bitrate; - //listen_time = song_info.listen_time; - song_id = song_info.song_id; - is_favourite = song_info.is_favourite; - info_acquired = song_info.info_acquired; - modified_time = song_info.modified_time; - freq = song_info.freq; - channels = song_info.channels; - bits = song_info.bits; - is_cue = song_info.is_cue; - cue_file_path = song_info.cue_file_path; - } - - bool IsTitleEmpty() const - { - static wstring default_title = wstring(CCommon::LoadText(IDS_DEFAULT_TITLE)); - return title.empty() || title == default_title; - } - - bool IsArtistEmpty() const - { - static wstring default_artist = wstring(CCommon::LoadText(IDS_DEFAULT_ARTIST)); - return artist.empty() || artist == default_artist; - } + void CopyAudioTag(const SongInfo& song_info); + + bool IsTitleEmpty() const; + bool IsArtistEmpty() const; + bool IsAlbumEmpty() const; + bool IsYearEmpty() const; + bool IsGenreEmpty() const; + + // 获取艺术家列表(可能存在多个艺术家) + void GetArtistList(vector& artist_list) const; + // TODO: 迁移所有用于文件名的艺术家字符串从这里获取 + // 获取首个艺术家(作为文件名时请从这里获取以限制长度) + wstring GetFirstArtist() const; + + wstring GetTitle() const; + wstring GetArtist() const; + wstring GetAlbum() const; + wstring GetYear() const; + wstring get_year() const; + wstring GetGenre() const; + wstring GetFileName() const; + wstring GetSongId() const; + + void SetYear(const wchar_t* str_year); + void SetSongId(const wstring& id); + + bool IsEmpty() const; + Time length() const; + // 判断是否为相同歌曲,原比较代码有漏洞,请迁移所有比较到使用此方法 + bool IsSameSong(const SongInfo& song) const; + // 清除歌曲信息中的<>内的默认字符串 + void Normalize(); +}; - bool IsAlbumEmpty() const - { - static wstring default_album = wstring(CCommon::LoadText(IDS_DEFAULT_ALBUM)); - return album.empty() || album == default_album; - } +struct SongKey +{ + wstring path; + int cue_track{}; // 当存储cue时用来保存音轨号,其他情况为0 - bool IsYearEmpty() const + SongKey() {} + SongKey(const wstring& path) : path(path) { - //static wstring default_year = wstring(CCommon::LoadText(IDS_DEFAULT_YEAR)); - //return year.empty() || year == default_year; - return year == 0; + ASSERT(!path.empty()); } - - bool IsGenreEmpty() const + SongKey(const wstring& path, const int& cue_track) : path(path), cue_track(cue_track) { - static wstring default_genre = wstring(CCommon::LoadText(IDS_DEFAULT_GENRE)); - return genre.empty() || genre == default_genre; + ASSERT(!path.empty()); } - - wstring GetTitle() const + SongKey(const SongInfo& song_info) { - static wstring default_title = wstring(CCommon::LoadText(IDS_DEFAULT_TITLE)); - return title.empty() ? default_title : title; + ASSERT(!song_info.file_path.empty()); + path = song_info.file_path; + if (song_info.is_cue) + cue_track = song_info.track; } - - wstring GetArtist() const + bool operator<(const SongKey& key) const { - static wstring default_artist = wstring(CCommon::LoadText(IDS_DEFAULT_ARTIST)); - return artist.empty() ? default_artist : artist; + if (int pathComparison = path.compare(key.path)) + return pathComparison < 0; + return cue_track < key.cue_track; } +}; - // 获取艺术家列表(可能存在多个艺术家),参数传入theApp.m_media_lib_setting_data.artist_split_ext设置 - void GetArtistList(vector& artist_list, const vector& artist_split_ext) const - { - wstring artist_{ artist }; - vector tmp; - for (const wstring& str : artist_split_ext) - { - size_t index{ artist_.find(str) }; - // 这里有点问题,如果有artist是“222/77”那么会出现“22/7”与“27”,但处理有些繁琐不做了 - if (index != wstring::npos) - { - artist_ = artist_.substr(0, index) + artist_.substr(index + str.size()); - tmp.push_back(str); - } +namespace std { + template <> + struct hash { + std::size_t operator()(const SongKey& key) const { + return std::hash()(key.path) ^ std::hash()(key.cue_track); } - CCommon::StringSplitWithMulitChars(artist_, L"/;&、", artist_list); - if (!tmp.empty()) - artist_list.insert(artist_list.begin(), tmp.begin(), tmp.end()); - } - - wstring GetAlbum() const - { - static wstring default_album = wstring(CCommon::LoadText(IDS_DEFAULT_ALBUM)); - return album.empty() ? default_album : album; - } - - wstring GetYear() const - { - static wstring default_year = wstring(CCommon::LoadText(IDS_DEFAULT_YEAR)); - if (year == 0) - return default_year; - else - return std::to_wstring(year); - } - - wstring GetGenre() const - { - static wstring default_genre = wstring(CCommon::LoadText(IDS_DEFAULT_GENRE)); - return genre.empty() ? default_genre : genre; - } - - wstring GetFileName() const - { - wstring file_name; - size_t index = file_path.rfind(L'\\'); - if (index == wstring::npos) - index = file_path.rfind(L'/'); - if (index == wstring::npos) - return file_path; - - file_name = file_path.substr(index + 1); - return file_name; - } - - bool IsSameSong(const SongInfo& song) const - { - if (!is_cue && !song.is_cue) - return file_path == song.file_path; - else - return file_path == song.file_path && track == song.track; - } - - Time length() const - { - return Time(end_pos - start_pos); - } - - void setLength(Time length) - { - end_pos = start_pos + length.toInt(); - } - - void Normalize() - { - if (title == CCommon::LoadText(IDS_DEFAULT_TITLE).GetString()) - title.clear(); - if (artist == CCommon::LoadText(IDS_DEFAULT_ARTIST).GetString()) - artist.clear(); - if (album == CCommon::LoadText(IDS_DEFAULT_ALBUM).GetString()) - album.clear(); - //if (year == CCommon::LoadText(IDS_DEFAULT_YEAR).GetString()) - // year.clear(); - if (genre == CCommon::LoadText(IDS_DEFAULT_GENRE).GetString()) - genre.clear(); - } - - void SetYear(const wchar_t* str_year) - { - year = static_cast(_wtoi(str_year)); - } - - wstring get_year() const - { - if (year == 0) - return wstring(); - else - return std::to_wstring(year); - } - - void SetSongId(const wstring& id) - { - song_id = _wtoi64(id.c_str()); - } - - wstring GetSongId() const - { - return std::to_wstring(song_id); - } - - bool IsEmpty() const - { - return file_path.empty() && title.empty() && artist.empty() && album.empty() && comment.empty() && genre.empty() && year == 0 && length().isZero(); - } - - bool IsLastTrack() const - { - return track == total_tracks; - } -}; + }; + template <> + struct equal_to { + bool operator()(const SongKey& lhs, const SongKey& rhs) const { + return lhs.path == rhs.path && lhs.cue_track == rhs.cue_track; + } + }; +} diff --git a/MusicPlayer2/SongInfoHelper.cpp b/MusicPlayer2/SongInfoHelper.cpp index 7ead02163..367ab0e20 100644 --- a/MusicPlayer2/SongInfoHelper.cpp +++ b/MusicPlayer2/SongInfoHelper.cpp @@ -18,21 +18,21 @@ CString CSongInfoHelper::GetBitrateString(const SongInfo& song) return str; } -CString CSongInfoHelper::GetChannelsString(const SongInfo& song) +wstring CSongInfoHelper::GetChannelsString(BYTE channels) { - CString chans_str; - if (song.channels == 0) - chans_str = _T("-"); - if (song.channels == 1) - chans_str = CCommon::LoadText(IDS_MONO); - else if (song.channels == 2) - chans_str = CCommon::LoadText(IDS_STEREO); - else if (song.channels == 6) - chans_str = CCommon::LoadText(_T("5.1 "), IDS_CHANNEL); - else if (song.channels == 8) - chans_str = CCommon::LoadText(_T("7.1 "), IDS_CHANNEL); - else if (song.channels > 2) - chans_str.Format(CCommon::LoadText(_T("%d "), IDS_CHANNEL), song.channels); + wstring chans_str; + if (channels == 0) + chans_str = L"-"; + if (channels == 1) + chans_str = theApp.m_str_table.LoadText(L"UI_TXT_CHANNEL_MONO"); + else if (channels == 2) + chans_str = theApp.m_str_table.LoadText(L"UI_TXT_CHANNEL_STEREO"); + else if (channels == 6) + chans_str = theApp.m_str_table.LoadText(L"UI_TXT_CHANNEL_5_1"); + else if (channels == 8) + chans_str = theApp.m_str_table.LoadText(L"UI_TXT_CHANNEL_7_1"); + else if (channels > 2) + chans_str = theApp.m_str_table.LoadTextFormat(L"UI_TXT_CHANNEL_OTHER", { channels }); return chans_str; } @@ -50,7 +50,7 @@ CString CSongInfoHelper::GetBitsString(const SongInfo& song) { CString bits; if (song.bits == 0) - bits = CCommon::LoadText(IDS_UNDEFINED); + bits = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_FILE_BIT_DEPTH_UNDEFINED").c_str(); else bits.Format(_T("%d Bit"), song.bits); return bits; @@ -108,37 +108,17 @@ std::wstring CSongInfoHelper::GetDisplayStr(const SongInfo& song_info, DisplayFo std::wstring CSongInfoHelper::GetPlaylistItemToolTip(const SongInfo& song_info, bool show_title, bool show_full_path) { std::wstring str_tip; - if (show_title) - { - str_tip += GetDisplayStr(song_info, theApp.m_media_lib_setting_data.display_format); - str_tip += _T("\r\n"); - } + if (show_title) + str_tip += GetDisplayStr(song_info, theApp.m_media_lib_setting_data.display_format) + L"\r\n"; if (show_full_path) - { - str_tip += CCommon::LoadText(IDS_PATH, _T(": ")); - str_tip += song_info.file_path.c_str(); - } + str_tip += theApp.m_str_table.LoadText(L"TXT_PATH") + L": " + song_info.file_path + L"\r\n"; else - { - str_tip += CCommon::LoadText(IDS_FILE_NAME, _T(": ")); - str_tip += song_info.GetFileName().c_str(); - } - str_tip += _T("\r\n"); - - str_tip += CCommon::LoadText(IDS_TITLE, _T(": ")); - str_tip += song_info.GetTitle().c_str(); - str_tip += _T("\r\n"); - - str_tip += CCommon::LoadText(IDS_ARTIST, _T(": ")); - str_tip += song_info.GetArtist().c_str(); - str_tip += _T("\r\n"); + str_tip += theApp.m_str_table.LoadText(L"TXT_FILE_NAME") + L": " + song_info.GetFileName() + L"\r\n"; - str_tip += CCommon::LoadText(IDS_ALBUM, _T(": ")); - str_tip += song_info.GetAlbum().c_str(); - str_tip += _T("\r\n"); + str_tip += theApp.m_str_table.LoadText(L"TXT_TITLE") + L": " + song_info.GetTitle() + L"\r\n"; + str_tip += theApp.m_str_table.LoadText(L"TXT_ARTIST") + L": " + song_info.GetArtist() + L"\r\n"; + str_tip += theApp.m_str_table.LoadText(L"TXT_ALBUM") + L": " + song_info.GetAlbum() + L"\r\n"; + str_tip += theApp.m_str_table.LoadText(L"TXT_BITRATE") + L": " + std::to_wstring(song_info.bitrate) + L"kbps"; - CString str_bitrate; - str_bitrate.Format(CCommon::LoadText(IDS_BITRATE, _T(": %dkbps")), song_info.bitrate); - str_tip += str_bitrate; return str_tip; } diff --git a/MusicPlayer2/SongInfoHelper.h b/MusicPlayer2/SongInfoHelper.h index 2301ec191..bf7aa8938 100644 --- a/MusicPlayer2/SongInfoHelper.h +++ b/MusicPlayer2/SongInfoHelper.h @@ -5,7 +5,7 @@ class CSongInfoHelper { public: static CString GetBitrateString(const SongInfo& song); - static CString GetChannelsString(const SongInfo& song); + static wstring GetChannelsString(BYTE channels); static CString GetFreqString(const SongInfo& song); static CString GetBitsString(const SongInfo& song); diff --git a/MusicPlayer2/SoundEffectDlg.cpp b/MusicPlayer2/SoundEffectDlg.cpp index 445b06109..5737b1da4 100644 --- a/MusicPlayer2/SoundEffectDlg.cpp +++ b/MusicPlayer2/SoundEffectDlg.cpp @@ -4,15 +4,14 @@ #include "stdafx.h" #include "MusicPlayer2.h" #include "SoundEffectDlg.h" -#include "afxdialogex.h" // CSoundEffectDlg 对话框 -IMPLEMENT_DYNAMIC(CSoundEffectDlg, CDialog) +IMPLEMENT_DYNAMIC(CSoundEffectDlg, CBaseDialog) CSoundEffectDlg::CSoundEffectDlg(CWnd* pParent /*=NULL*/) - : CDialog(IDD_SOUND_EFFECT_DIALOG, pParent) + : CBaseDialog(IDD_SOUND_EFFECT_DIALOG, pParent) { } @@ -21,14 +20,33 @@ CSoundEffectDlg::~CSoundEffectDlg() { } +CString CSoundEffectDlg::GetDialogName() const +{ + return L"SoundEffectDlg"; +} + +bool CSoundEffectDlg::InitializeControls() +{ + wstring temp; + temp = theApp.m_str_table.LoadText(L"TITLE_SOUND_EFFECT"); + SetWindowTextW(temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_CLOSE"); + SetDlgItemTextW(IDCANCEL, temp.c_str()); + + RepositionTextBasedControls({ + { CtrlTextInfo::R1, IDCANCEL, CtrlTextInfo::W32 } + }); + return false; +} + void CSoundEffectDlg::DoDataExchange(CDataExchange* pDX) { - CDialog::DoDataExchange(pDX); - DDX_Control(pDX, IDC_TAB1, m_tab); + CBaseDialog::DoDataExchange(pDX); + DDX_Control(pDX, IDC_TAB1, m_tab); } -BEGIN_MESSAGE_MAP(CSoundEffectDlg, CDialog) +BEGIN_MESSAGE_MAP(CSoundEffectDlg, CBaseDialog) END_MESSAGE_MAP() @@ -37,28 +55,19 @@ END_MESSAGE_MAP() BOOL CSoundEffectDlg::OnInitDialog() { - CDialog::OnInitDialog(); + CBaseDialog::OnInitDialog(); - // TODO: 在此添加额外的初始化 - CenterWindow(); + // TODO: 在此添加额外的初始化 + CenterWindow(); //创建子对话框 m_equ_dlg.Create(IDD_EQUALIZER_DIALOG, &m_tab); m_reverb_dlg.Create(IDD_REVERB_DIALOG, &m_tab); //添加对话框 - m_tab.AddWindow(&m_equ_dlg, CCommon::LoadText(IDS_EQUALIZER)); - m_tab.AddWindow(&m_reverb_dlg, CCommon::LoadText(IDS_REVERB)); - - //为每个标签添加图标 - CImageList ImageList; - ImageList.Create(theApp.DPI(16), theApp.DPI(16), ILC_COLOR32 | ILC_MASK, 2, 2); - ImageList.Add(theApp.m_icon_set.eq.GetIcon(true)); - ImageList.Add(theApp.m_icon_set.reverb); - m_tab.SetImageList(&ImageList); - ImageList.Detach(); - - m_tab.SetItemSize(CSize(theApp.DPI(60), theApp.DPI(24))); + m_tab.AddWindow(&m_equ_dlg, theApp.m_str_table.LoadText(L"TITLE_EQ").c_str(), IconMgr::IconType::IT_Equalizer); + m_tab.AddWindow(&m_reverb_dlg, theApp.m_str_table.LoadText(L"TITLE_REVERB").c_str(), IconMgr::IconType::IT_Reverb); + m_tab.AdjustTabWindowSize(); //设置默认选中的标签 @@ -66,15 +75,15 @@ BOOL CSoundEffectDlg::OnInitDialog() m_tab_selected = 0; m_tab.SetCurTab(m_tab_selected); - return TRUE; // return TRUE unless you set the focus to a control - // 异常: OCX 属性页应返回 FALSE + return TRUE; // return TRUE unless you set the focus to a control + // 异常: OCX 属性页应返回 FALSE } void CSoundEffectDlg::OnCancel() { - // TODO: 在此添加专用代码和/或调用基类 - DestroyWindow(); + // TODO: 在此添加专用代码和/或调用基类 + DestroyWindow(); - //CDialog::OnCancel(); + //CDialog::OnCancel(); } diff --git a/MusicPlayer2/SoundEffectDlg.h b/MusicPlayer2/SoundEffectDlg.h index 28295f917..e43e4ba22 100644 --- a/MusicPlayer2/SoundEffectDlg.h +++ b/MusicPlayer2/SoundEffectDlg.h @@ -1,36 +1,39 @@ #pragma once +#include "BaseDialog.h" #include "EqualizerDlg.h" #include "ReverbDlg.h" -#include "afxcmn.h" #include "CTabCtrlEx.h" // CSoundEffectDlg 对话框 -class CSoundEffectDlg : public CDialog +class CSoundEffectDlg : public CBaseDialog { - DECLARE_DYNAMIC(CSoundEffectDlg) + DECLARE_DYNAMIC(CSoundEffectDlg) public: - CSoundEffectDlg(CWnd* pParent = NULL); // 标准构造函数 - virtual ~CSoundEffectDlg(); + CSoundEffectDlg(CWnd* pParent = NULL); // 标准构造函数 + virtual ~CSoundEffectDlg(); // 对话框数据 #ifdef AFX_DESIGN_TIME - enum { IDD = IDD_SOUND_EFFECT_DIALOG }; + enum { IDD = IDD_SOUND_EFFECT_DIALOG }; #endif private: - CEqualizerDlg m_equ_dlg; //均衡器对话框 - CReverbDlg m_reverb_dlg; //混响对话框 + CEqualizerDlg m_equ_dlg; //均衡器对话框 + CReverbDlg m_reverb_dlg; //混响对话框 - int m_tab_selected{}; + int m_tab_selected{}; CTabCtrlEx m_tab; protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 + virtual CString GetDialogName() const; + virtual bool IsRememberDialogSizeEnable() const { return false; }; + virtual bool InitializeControls() override; + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 - DECLARE_MESSAGE_MAP() + DECLARE_MESSAGE_MAP() public: - virtual BOOL OnInitDialog(); - virtual void OnCancel(); + virtual BOOL OnInitDialog(); + virtual void OnCancel(); }; diff --git a/MusicPlayer2/SpinEdit.cpp b/MusicPlayer2/SpinEdit.cpp index 0220d9dec..f27dc38bd 100644 Binary files a/MusicPlayer2/SpinEdit.cpp and b/MusicPlayer2/SpinEdit.cpp differ diff --git a/MusicPlayer2/SpinEdit.h b/MusicPlayer2/SpinEdit.h index 508a069eb..22458d8f7 100644 Binary files a/MusicPlayer2/SpinEdit.h and b/MusicPlayer2/SpinEdit.h differ diff --git a/MusicPlayer2/StaticEx.cpp b/MusicPlayer2/StaticEx.cpp index d8b82bd27..cce802f72 100644 --- a/MusicPlayer2/StaticEx.cpp +++ b/MusicPlayer2/StaticEx.cpp @@ -37,10 +37,9 @@ CString CStaticEx::GetWindowText() const return str; } -void CStaticEx::SetIcon(HICON hIcon, CSize size) +void CStaticEx::SetIcon(IconMgr::IconType icon_type) { - m_hIcon = hIcon; - m_icon_size = size; + m_icon_type = icon_type; } BEGIN_MESSAGE_MAP(CStaticEx, CStatic) @@ -55,7 +54,7 @@ void CStaticEx::OnPaint() // 不为绘图消息调用 CStatic::OnPaint() CDrawCommon draw; - draw.Create(&dc, this); + draw.Create(&dc, GetFont()); CRect rect; GetClientRect(rect); @@ -70,17 +69,18 @@ void CStaticEx::OnPaint() CRect rc_text = rect; //绘制图标 - bool draw_icon = (m_hIcon != NULL && m_icon_size.cx > 0 && m_icon_size.cy > 0); - if (draw_icon) + if (m_icon_type != IconMgr::IconType::IT_NO_ICON) { + HICON hIcon = theApp.m_icon_mgr.GetHICON(m_icon_type, IconMgr::IconStyle::IS_OutlinedDark, IconMgr::IconSize::IS_DPI_16); + CSize icon_size = IconMgr::GetIconSize(IconMgr::IconSize::IS_DPI_16); CRect rc_tmp = rect; - rc_tmp.right = rc_tmp.left + m_icon_size.cx + theApp.DPI(4); + rc_tmp.right = rc_tmp.left + icon_size.cx + theApp.DPI(4); rc_text.left = rc_tmp.right; CPoint icon_left_top; - icon_left_top.x = rc_tmp.left + (rc_tmp.Width() - m_icon_size.cx) / 2; - icon_left_top.y = rc_tmp.top + (rc_tmp.Height() - m_icon_size.cy) / 2; + icon_left_top.x = rc_tmp.left + (rc_tmp.Width() - icon_size.cx) / 2; + icon_left_top.y = rc_tmp.top + (rc_tmp.Height() - icon_size.cy) / 2; draw.SetDrawArea(rc_tmp); - draw.DrawIcon(m_hIcon, icon_left_top, m_icon_size); + draw.DrawIcon(hIcon, icon_left_top, icon_size); } //绘制文本 diff --git a/MusicPlayer2/StaticEx.h b/MusicPlayer2/StaticEx.h index 93cb805ef..4db056ad9 100644 --- a/MusicPlayer2/StaticEx.h +++ b/MusicPlayer2/StaticEx.h @@ -1,5 +1,6 @@ #pragma once -#include +#include "IconMgr.h" + class CStaticEx : public CStatic { @@ -11,14 +12,13 @@ class CStaticEx : void SetBackgroundColor(COLORREF back_color); void SetWindowText(LPCTSTR lpszString); CString GetWindowText() const; - void SetIcon(HICON hIcon, CSize size); //设置在文本前面的图标 + void SetIcon(IconMgr::IconType icon_type); //设置在文本前面的图标 private: COLORREF m_text_color{ GRAY(0) }; COLORREF m_back_color{ GRAY(255) }; bool m_transparent{ true }; - HICON m_hIcon{}; - CSize m_icon_size{}; + IconMgr::IconType m_icon_type = IconMgr::IconType::IT_NO_ICON; public: DECLARE_MESSAGE_MAP() diff --git a/MusicPlayer2/StrTable.cpp b/MusicPlayer2/StrTable.cpp new file mode 100644 index 000000000..33d8a2f0e --- /dev/null +++ b/MusicPlayer2/StrTable.cpp @@ -0,0 +1,174 @@ +#include "stdafx.h" +#include "StrTable.h" +#include "Common.h" +#include "IniHelper.h" +#include "resource.h" + +StrTable::StrTable() +{ +} + +StrTable::~StrTable() +{ +} + +const wstring StrTable::error_str = { L"" }; + +bool StrTable::Init(const wstring& language_dir, wstring& language_tag_setting) +{ + bool expected = false; + if (!initialized.compare_exchange_strong(expected, true)) + return false; + + auto InitMapFromIniHelper = [this](const CIniHelper& ini) + { + static const wstring MenuAppName = L"menu."; + ini.GetAllKeyValues(L"text", m_text_string_table); + ini.GetAllKeyValues(L"scintlla", m_scintilla_string_table); + const auto& list = ini.GetAllAppName(MenuAppName); + for (const auto& item : list) + ini.GetAllKeyValues(MenuAppName + item, m_menu_string_table[item]); + }; + + std::map list; // 使用map自动去重与排序 + + { // 加载内嵌资源作为默认值确保外部翻译文件不完整/不存在时的正常使用 + // 存在外部en-US文件时这里设置的list项目会被覆写(下面根据LanguageInfo.file_name是否为空判断是否存在外部英文翻译) + list.emplace(L"en-US", LanguageInfo{ L"", L"English ", L"en-US", L"Segoe UI", { L"" } }); + CIniHelper default_ini(IDR_STRING_TABLE); + InitMapFromIniHelper(default_ini); + } // 即使最终决定是en-US接下来也再加载一次外部翻译,使文本无须重新编译即可修改 + + bool succeed{}; + vector files; + CCommon::GetFiles(language_dir + L"*.ini", files); + for (const wstring& file_name : files) + { + CIniHelper file(language_dir + file_name); + wstring tag = file.GetString(L"general", L"BCP_47", L""); + if (tag.empty()) continue; + auto& item = list[tag]; + item.file_name = file_name; + item.display_name = file.GetString(L"general", L"DISPLAY_NAME", file_name.c_str()); + item.bcp_47 = tag; + item.default_font_name = file.GetString(L"general", L"DEFAULT_FONT", L""); // 字体默认值为空(跟随系统) + file.GetStringList(L"general", L"TRANSLATOR", item.translator, vector{ L"" }); + if (language_tag_setting == tag) + { + InitMapFromIniHelper(file); + m_default_font_name = item.default_font_name; + m_language_tag.push_back(tag); // 此处的tag可能不存在于当前系统,设置线程语言的api会略过完全不支持的语言(可以自动匹配相近的语言) + succeed = true; + } + } + + if (!succeed) // 设置是"跟随系统"或之前的语言配置文件没有找到 + { + language_tag_setting.clear(); // 更改设置为“跟随系统” + vector user_language_list; + CCommon::GetThreadLanguageList(user_language_list); + // 在系统已安装的语言列表中优先匹配一个程序已有的语言 + for (const wstring& tag : user_language_list) + { + auto iter = list.find(tag); + if (iter == list.end()) + continue; + CIniHelper file(language_dir + iter->second.file_name); + InitMapFromIniHelper(file); + m_default_font_name = iter->second.default_font_name; + m_language_tag.push_back(tag); + succeed = true; + break; + } + // TODO: 添加模糊匹配近似语言(不清楚安装了不同语言包的windows的默认语言列表会是什么) + } + if (!succeed) // 系统语言列表中没有找到程序支持的语言 + { + // 如果仍然没有匹配的语言那么加载en-US的语言文件(如果存在) + const LanguageInfo& en = list[L"en-US"]; + if (!en.file_name.empty()) // 如果没有加载到外部en-US翻译那么这里会为空 + { + CIniHelper file(language_dir + en.file_name); + InitMapFromIniHelper(file); + m_default_font_name = en.default_font_name; + m_language_tag.push_back(L"en-US"); + succeed = true; + } + } + + // TODO: 检查系统是否已安装此字体(未测试:我担心其中使用的字体枚举API当系统字体非常多时出现严重的效率问题) + if (m_default_font_name.empty() || m_default_font_name.size() > LF_FACESIZE - 1/* || !CCommon::IsFontInstalled(m_default_font_name)*/) + m_default_font_name = CCommon::GetSystemDefaultUIFont(); + // 将map去重又排序的结果装入m_language_list + std::transform(list.begin(), list.end(), std::back_inserter(m_language_list), + [](const auto& pair) { return std::move(pair.second); }); + return succeed; +} + +const wstring& StrTable::LoadText(const wstring& key) const +{ + // 查找key而不是使用[]是为了避免发生任何写入,这样不使用读写锁也有线程安全 + auto iter = m_text_string_table.find(key); + if (iter != m_text_string_table.end()) + return iter->second; + else // 程序中试图读取不存在于.ini中的键或当前还未进行初始化 + { + std::lock_guard lock(error_mutex); + m_unknown_key.insert(key); + return error_str; + } +} + +wstring StrTable::LoadTextFormat(const wstring& key, const std::initializer_list& paras) const +{ + // 查找key而不是使用[]是为了避免发生任何写入,这样不使用读写锁也有线程安全 + auto iter = m_text_string_table.find(key); + if (iter == m_text_string_table.end()) // 程序中试图读取不存在于.ini中的键或当前还未进行初始化 + { + std::lock_guard lock(error_mutex); + m_unknown_key.insert(key); + return error_str; + } + wstring str{ iter->second }; // 复制以避免原始字符串修改 + int index{ 1 }; + for (const auto& para : paras) + { + wstring format_str{ L"<%" + std::to_wstring(index) + L"%>" }; + size_t pos = str.find(format_str); + if (pos == wstring::npos) // 当前取得的翻译字符串中缺少paras指定的<%序号%>占位符 + { + std::lock_guard lock(error_mutex); + m_error_para_key.insert(key); + continue; + } + str.replace(pos, format_str.size(), para.ToString()); + ++index; + } + return str; +} + +const wstring& StrTable::LoadMenuText(const wstring& menu_name, const wstring& key) const +{ + // 查找key而不是使用[]是为了避免发生任何写入,这样不使用读写锁也有线程安全 + auto iter_name = m_menu_string_table.find(menu_name); + if (iter_name == m_menu_string_table.end()) + { + std::lock_guard lock(error_mutex); + m_unknown_key.insert(menu_name); + return error_str; + } + const auto& key_map = iter_name->second; + auto iter_key = key_map.find(key); + if (iter_key == key_map.end()) + { + std::lock_guard lock(error_mutex); + m_unknown_key.insert(key); + return error_str; + } + return iter_key->second; +} + +const std::map& StrTable::GetScintillaStrMap() const +{ + return m_scintilla_string_table; +} diff --git a/MusicPlayer2/StrTable.h b/MusicPlayer2/StrTable.h new file mode 100644 index 000000000..c96dbf24b --- /dev/null +++ b/MusicPlayer2/StrTable.h @@ -0,0 +1,59 @@ +#pragma once +#include "CVariant.h" +class StrTable +{ +public: + StrTable(); + ~StrTable(); + + static const wstring error_str; // 键不存在时会返回此字符串常引用 + + struct LanguageInfo + { + wstring file_name; // ini文件名(与theApp.m_local_dir + L"language\\"拼接得到路径) + wstring display_name; // 在语言设置下拉菜单显示的字符串 + wstring bcp_47; // BCP-47代码 + wstring default_font_name; // 默认字体 + vector translator; + }; +public: + // 初始化string table,同时也负责处理语言相关设置 + // 第二个参数传入语言设置引用,如果没有找到匹配的ini会被清空(恢复到“跟随系统”) + bool Init(const wstring& language_dir, wstring& language_tag_setting); + + // 载入翻译字符串 + const wstring& LoadText(const wstring& key) const; + // 载入翻译字符串,并将字符串中形如<%序号%>的字符串替换成可变参数列表中的参数 + wstring LoadTextFormat(const wstring& key, const std::initializer_list& paras) const; + // 载入翻译字符串(菜单文本) + const wstring& LoadMenuText(const wstring& menu_name, const wstring& key) const; + // 获取scintilla使用的string table + const std::map& GetScintillaStrMap() const; + + // 获取默认字体名称 + const wstring& GetDefaultFontName() const { return m_default_font_name; }; + // 获取CCommon::SetThreadLanguageList参数(无匹配语言时为空,对api来说表示重置线程语言设置) + const vector& GetLanguageTag() const { return m_language_tag; }; + // 获取ini列表(即使完全没有ini时也会含有en-US) + const vector& GetLanguageList() const { return m_language_list; }; + // 当前语言是否为简体中文(选择默认更新源以及更新信息语言) + bool IsSimplifiedChinese() const { return !m_language_tag.empty() && m_language_tag.front() == L"zh-CN"; }; + + // 这里记录的不一定完全,只能发现此次运行中执行到的代码发生的错误 + const std::set& GetUnKnownKey() const { return m_unknown_key; }; + const std::set& GetErrorParaKey() const { return m_error_para_key; }; + +private: + std::atomic initialized; + wstring m_default_font_name; // 存储默认字体名 + vector m_language_tag; // 存储CCommon::SetThreadLanguageList使用的参数 + vector m_language_list; // 下拉菜单需要vector的索引访问所以不使用map + map m_text_string_table; // 初始化之后保持只读(对外提供静态引用),不需要锁保护 + map> m_menu_string_table; + map m_scintilla_string_table; + // 记录程序运行中的错误,程序退出时写入日志 + mutable std::mutex error_mutex; // 存储错误的set不是只读的,写入需要使用锁保护 + mutable std::set m_unknown_key; + mutable std::set m_error_para_key; +}; + diff --git a/MusicPlayer2/SupportedFormatDlg.cpp b/MusicPlayer2/SupportedFormatDlg.cpp index 9f964ca9b..f7c3d7961 100644 --- a/MusicPlayer2/SupportedFormatDlg.cpp +++ b/MusicPlayer2/SupportedFormatDlg.cpp @@ -4,7 +4,6 @@ #include "stdafx.h" #include "MusicPlayer2.h" #include "SupportedFormatDlg.h" -#include "afxdialogex.h" #include "AudioCommon.h" @@ -13,7 +12,7 @@ IMPLEMENT_DYNAMIC(CSupportedFormatDlg, CBaseDialog) CSupportedFormatDlg::CSupportedFormatDlg(CWnd* pParent /*=nullptr*/) - : CBaseDialog(IDD_SUPPORT_FORMAT_DIALOG, pParent) + : CBaseDialog(IDD_SUPPORT_FORMAT_DIALOG, pParent) { } @@ -27,15 +26,28 @@ CString CSupportedFormatDlg::GetDialogName() const return _T("SupportedFormatDlg"); } +bool CSupportedFormatDlg::InitializeControls() +{ + SetWindowTextW(theApp.m_str_table.LoadText(L"TITLE_SUPPORTTED_FORMAT").c_str()); + // IDC_INFO_STATIC + // IDC_FORMAT_LIST + // IDOK + + RepositionTextBasedControls({ + { CtrlTextInfo::R1, IDOK, CtrlTextInfo::W32 } + }); + return true; +} + void CSupportedFormatDlg::DoDataExchange(CDataExchange* pDX) { - CBaseDialog::DoDataExchange(pDX); - DDX_Control(pDX, IDC_FORMAT_LIST, m_format_list); + CBaseDialog::DoDataExchange(pDX); + DDX_Control(pDX, IDC_FORMAT_LIST, m_format_list); } BEGIN_MESSAGE_MAP(CSupportedFormatDlg, CBaseDialog) - ON_WM_GETMINMAXINFO() + ON_WM_GETMINMAXINFO() END_MESSAGE_MAP() @@ -44,69 +56,61 @@ END_MESSAGE_MAP() BOOL CSupportedFormatDlg::OnInitDialog() { - CBaseDialog::OnInitDialog(); + CBaseDialog::OnInitDialog(); - // TODO: 在此添加额外的初始化 + // TODO: 在此添加额外的初始化 - SetIcon(AfxGetApp()->LoadIcon(IDR_MAINFRAME), FALSE); // 设置小图标 - PlayerCoreType core_type{}; - if (CPlayer::GetInstance().GetPlayerCore() != nullptr) - core_type = CPlayer::GetInstance().GetPlayerCore()->GetCoreType(); - switch (core_type) - { - case PT_BASS: - SetDlgItemText(IDC_INFO_STATIC, CCommon::LoadText(IDS_SUPPORTTED_FORMAT_INFO)); - break; - case PT_MCI: - SetDlgItemText(IDC_INFO_STATIC, CCommon::LoadText(IDS_SUPPORTTED_FORMAT_INFO_MCI)); - break; - case PT_FFMPEG: - SetDlgItemText(IDC_INFO_STATIC, CCommon::LoadText(IDS_SUPPORTTED_FORMAT_INFO_FFMPEG)); - break; - } + SetIcon(IconMgr::IconType::IT_App, FALSE); // 设置小图标 + if (theApp.m_play_setting_data.use_ffmpeg) + SetDlgItemTextW(IDC_INFO_STATIC, theApp.m_str_table.LoadText(L"TXT_SUPPORTTED_FORMAT_CORE_INFO_FFMPEG").c_str()); + else if (theApp.m_play_setting_data.use_mci) + SetDlgItemTextW(IDC_INFO_STATIC, theApp.m_str_table.LoadText(L"TXT_SUPPORTTED_FORMAT_CORE_INFO_MCI").c_str()); + else + SetDlgItemTextW(IDC_INFO_STATIC, theApp.m_str_table.LoadText(L"TXT_SUPPORTTED_FORMAT_CORE_INFO_BASS").c_str()); - //初始化列表 - //m_format_list.SetColor(theApp.m_app_setting_data.theme_color); - CRect rect; - m_format_list.GetWindowRect(rect); - int width0, width1, width2; + //初始化列表 + //m_format_list.SetColor(theApp.m_app_setting_data.theme_color); + CRect rect; + m_format_list.GetWindowRect(rect); + int width0, width1, width2; m_format_list.SetExtendedStyle(m_format_list.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_LABELTIP); - - if (core_type == PT_BASS) + + bool is_bass = !theApp.m_play_setting_data.use_ffmpeg && !theApp.m_play_setting_data.use_mci; + if (is_bass) { width0 = theApp.DPI(100); width1 = rect.Width() / 3; width2 = rect.Width() - width1 - width0 - theApp.DPI(20) - 1; - m_format_list.InsertColumn(0, CCommon::LoadText(IDS_PLUGIN_FILE_NAME), LVCFMT_LEFT, width0); - m_format_list.InsertColumn(1, CCommon::LoadText(IDS_FORMAT_SUPPORTED), LVCFMT_LEFT, width1); - m_format_list.InsertColumn(2, CCommon::LoadText(IDS_FILE_EXTENSION), LVCFMT_LEFT, width2); + m_format_list.InsertColumn(0, theApp.m_str_table.LoadText(L"TXT_SUPPORTTED_FORMAT_PLUGIN_FILE_NAME").c_str(), LVCFMT_LEFT, width0); + m_format_list.InsertColumn(1, theApp.m_str_table.LoadText(L"TXT_SUPPORTTED_FORMAT_PLUGIN_FORMAT_PROVIDED").c_str(), LVCFMT_LEFT, width1); + m_format_list.InsertColumn(2, theApp.m_str_table.LoadText(L"TXT_SUPPORTTED_FORMAT_PLUGIN_FILE_EXTENSION").c_str(), LVCFMT_LEFT, width2); } else { width0 = rect.Width() / 2; width1 = rect.Width() - width0 - theApp.DPI(20) - 1; - m_format_list.InsertColumn(0, CCommon::LoadText(IDS_FORMAT_SUPPORTED), LVCFMT_LEFT, width0); - m_format_list.InsertColumn(1, CCommon::LoadText(IDS_FILE_EXTENSION), LVCFMT_LEFT, width1); + m_format_list.InsertColumn(0, theApp.m_str_table.LoadText(L"TXT_SUPPORTTED_FORMAT_PLUGIN_FORMAT_PROVIDED").c_str(), LVCFMT_LEFT, width0); + m_format_list.InsertColumn(1, theApp.m_str_table.LoadText(L"TXT_SUPPORTTED_FORMAT_PLUGIN_FILE_EXTENSION").c_str(), LVCFMT_LEFT, width1); } - int index = 0; - for (const auto support_format : CAudioCommon::m_surpported_format) - { - if (core_type == PT_BASS) - { - m_format_list.InsertItem(index, support_format.file_name.c_str()); - m_format_list.SetItemText(index, 1, support_format.description.c_str()); - m_format_list.SetItemText(index, 2, support_format.extensions_list.c_str()); + int index = 0; + for (const auto support_format : CAudioCommon::m_surpported_format) + { + if (is_bass) + { + m_format_list.InsertItem(index, support_format.file_name.c_str()); + m_format_list.SetItemText(index, 1, support_format.description.c_str()); + m_format_list.SetItemText(index, 2, support_format.extensions_list.c_str()); } else { m_format_list.InsertItem(index, support_format.description.c_str()); m_format_list.SetItemText(index, 1, support_format.extensions_list.c_str()); } - index++; - } + index++; + } - return TRUE; // return TRUE unless you set the focus to a control - // 异常: OCX 属性页应返回 FALSE + return TRUE; // return TRUE unless you set the focus to a control + // 异常: OCX 属性页应返回 FALSE } diff --git a/MusicPlayer2/SupportedFormatDlg.h b/MusicPlayer2/SupportedFormatDlg.h index 40068c69c..923862021 100644 --- a/MusicPlayer2/SupportedFormatDlg.h +++ b/MusicPlayer2/SupportedFormatDlg.h @@ -1,30 +1,30 @@ #pragma once -#include "ListCtrlEx.h" #include "BaseDialog.h" +#include "ListCtrlEx.h" // CSupportedFormatDlg 对话框 class CSupportedFormatDlg : public CBaseDialog { - DECLARE_DYNAMIC(CSupportedFormatDlg) + DECLARE_DYNAMIC(CSupportedFormatDlg) public: - CSupportedFormatDlg(CWnd* pParent = nullptr); // 标准构造函数 - virtual ~CSupportedFormatDlg(); + CSupportedFormatDlg(CWnd* pParent = nullptr); // 标准构造函数 + virtual ~CSupportedFormatDlg(); // 对话框数据 #ifdef AFX_DESIGN_TIME - enum { IDD = IDD_SUPPORT_FORMAT_DIALOG }; + enum { IDD = IDD_SUPPORT_FORMAT_DIALOG }; #endif protected: - CListCtrlEx m_format_list; + CListCtrlEx m_format_list; virtual CString GetDialogName() const override; + virtual bool InitializeControls() override; virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 - DECLARE_MESSAGE_MAP() - + DECLARE_MESSAGE_MAP() public: - virtual BOOL OnInitDialog(); + virtual BOOL OnInitDialog(); }; diff --git a/MusicPlayer2/TabDlg.cpp b/MusicPlayer2/TabDlg.cpp index 4c0c59966..538a8c8d6 100644 --- a/MusicPlayer2/TabDlg.cpp +++ b/MusicPlayer2/TabDlg.cpp @@ -1,13 +1,12 @@ #include "stdafx.h" #include "TabDlg.h" #include "MusicPlayer2.h" +#include "WinVersionHelper.h" -IMPLEMENT_DYNAMIC(CTabDlg, CDialogEx) +IMPLEMENT_DYNAMIC(CTabDlg, CBaseDialog) -CTabDlg::CTabDlg(UINT nIDTemplate, CWnd * pParent) : CDialogEx(nIDTemplate, pParent) +CTabDlg::CTabDlg(UINT nIDTemplate, CWnd * pParent) : CBaseDialog(nIDTemplate, pParent) { - m_pParent = pParent; - m_background_color = CWinVersionHelper::IsWindows11OrLater() ? RGB(249, 249, 249) : RGB(255, 255, 255); } @@ -15,39 +14,6 @@ CTabDlg::~CTabDlg() { } - -BOOL CTabDlg::PreTranslateMessage(MSG* pMsg) -{ - // TODO: 在此添加专用代码和/或调用基类 - if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE) - { - //if (m_pParent != nullptr) - // m_pParent->SendMessage(WM_COMMAND, IDCANCEL); - return TRUE; - } - if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN) - { - //if (m_pParent != nullptr) - // m_pParent->SendMessage(WM_COMMAND, IDOK); - return TRUE; - } - - return CDialogEx::PreTranslateMessage(pMsg); -} - - -BOOL CTabDlg::OnInitDialog() -{ - CDialogEx::OnInitDialog(); - - // TODO: 在此添加额外的初始化 - //将窗口背景设置成白色 - SetBackgroundColor(m_background_color); - - return TRUE; // return TRUE unless you set the focus to a control - // 异常: OCX 属性页应返回 FALSE -} - CWnd* CTabDlg::GetParentWindow() { CWnd* pParent = GetParent(); @@ -60,154 +26,174 @@ CWnd* CTabDlg::GetParentWindow() void CTabDlg::SetScrollbarInfo(int nPage, int nMax) { - //初始化滚动条 - SCROLLINFO scrollinfo; - GetScrollInfo(SB_VERT, &scrollinfo, SIF_ALL); - scrollinfo.nPage = nPage; //设置滑块大小 - scrollinfo.nMin = 0; - scrollinfo.nMax = nMax; //设置滚动条的最大位置 - if (scrollinfo.nMax < 0) - scrollinfo.nMax = 0; - scrollinfo.nPos = scrollinfo.nMin; - m_last_pos = scrollinfo.nPos; - SetScrollInfo(SB_VERT, &scrollinfo, SIF_ALL); - - m_scroll_enable = true; + // 获取滚动条状态 + SCROLLINFO scrollinfo; + GetScrollInfo(SB_VERT, &scrollinfo, SIF_ALL); + if (m_scroll_enable) + m_last_pos = scrollinfo.nPos - scrollinfo.nMin; // 如果已启用滚动则记录当前滚动位置 + else + m_scroll_enable = true; // 否则启用滚动 + int reset_pos = m_last_pos; + // 父窗口OnSize后的新滚动状态边界检查 + if (nMax < 0) nMax = 0; + if (m_last_pos > nMax - nPage) m_last_pos = nMax - nPage; + if (m_last_pos < 0) m_last_pos = 0; + // 设置滚动条状态 + scrollinfo.nMin = 0; // 设置滚动内容起点在窗口中的pos + scrollinfo.nMax = nMax; // 设置滚动内容终点在窗口中的pos + scrollinfo.nPage = nPage; // 设置实际显示内容区域高度 + scrollinfo.nPos = m_last_pos; // 设置当前实际显示内容区域顶端pos + SetScrollInfo(SB_VERT, &scrollinfo, SIF_ALL); + // 复位滚动 + if (reset_pos != 0) + ScrollWindow(0, reset_pos); + // 代替框架做出OnSize的响应 (在SetScrollInfo决定并设置滚动条是否在新状态下显示之后) + CBaseDialog::ResizeDynamicLayout(); // 这个方法会无视滚动更新控件位置导致控件错位,在滚动为0时调用避开这个问题 + // 执行滚动 + if (m_last_pos != 0) + ScrollWindow(0, -m_last_pos); } -void CTabDlg::ResetScroll() +void CTabDlg::ScrollWindowSimple(int step, bool absolute) { - if (m_scroll_enable) - { - SCROLLINFO scrollinfo; - GetScrollInfo(SB_VERT, &scrollinfo, SIF_ALL); - int step = scrollinfo.nPos - scrollinfo.nMin; - scrollinfo.nPos = scrollinfo.nMin; - m_last_pos = scrollinfo.nPos; - SetScrollInfo(SB_VERT, &scrollinfo, SIF_ALL); - ScrollWindow(0, step); - } + SCROLLINFO scrollinfo; + GetScrollInfo(SB_VERT, &scrollinfo, SIF_ALL); + if (step == INT_MAX) + step = scrollinfo.nPage; + if (step == INT_MIN) + step = -static_cast(scrollinfo.nPage); + if (!absolute) + scrollinfo.nPos -= step; + else + { + if (step < 0) // 绝对位置时step为-1表示滚动到底部 + step = scrollinfo.nMax - scrollinfo.nPage; + scrollinfo.nPos = step; // 此时的stpe为目标绝对位置 + step = m_last_pos - step; // 将参数的绝对位置转换为偏移量继续处理 + } + if (scrollinfo.nPos < scrollinfo.nMin) // 限制nPos不小于最小值nMin + { + step -= scrollinfo.nMin - scrollinfo.nPos; + scrollinfo.nPos = scrollinfo.nMin; + } + if (scrollinfo.nPos > scrollinfo.nMax - static_cast(scrollinfo.nPage)) // 限制nPos不大于最大值nMax - nPage + { + step += scrollinfo.nPos - (scrollinfo.nMax - scrollinfo.nPage); + scrollinfo.nPos = scrollinfo.nMax - scrollinfo.nPage; + } + SetScrollInfo(SB_VERT, &scrollinfo, SIF_ALL); + m_last_pos = scrollinfo.nPos; + ScrollWindow(0, step); } -void CTabDlg::ScrollWindowSimple(int step) +BEGIN_MESSAGE_MAP(CTabDlg, CBaseDialog) + ON_WM_VSCROLL() + ON_WM_MOUSEWHEEL() +END_MESSAGE_MAP() + + +void CTabDlg::ResizeDynamicLayout() { - SCROLLINFO scrollinfo; - GetScrollInfo(SB_VERT, &scrollinfo, SIF_ALL); - scrollinfo.nPos -= step; - if (scrollinfo.nPos < scrollinfo.nMin) - { - step = scrollinfo.nPos + step - scrollinfo.nMin; //如果向上滚动一个距离后小于滚动条的最小位置了,则修正step的值,使窗口滚动到最上方 - scrollinfo.nPos = scrollinfo.nMin; - } - if (scrollinfo.nPos + static_cast(scrollinfo.nPage) > scrollinfo.nMax) //此处一定要注意加上滑块的长度,再作判断 - { - step -= (scrollinfo.nMax - (scrollinfo.nPos + scrollinfo.nPage)); //如果向上滚动一个距离后大于滚动条的最大位置了,则修正step的值,使窗口滚动到最下方 - if (step > 0) - step = 0; - scrollinfo.nPos = scrollinfo.nMax; - } - SetScrollInfo(SB_VERT, &scrollinfo, SIF_ALL); - ScrollWindow(0, step); + // m_pDynamicLayout->Adjust()会无视窗口滚动更新控件位置 + // 之前在父窗口OnSize后重置不可靠(进入退出最大化和贴靠时没能正常工作),也没找到检出这两种特殊OnSize的方法 + // 框架内部调用ResizeDynamicLayout太早,来不及先复位滚动,故覆写此虚方法介入 + // 如果已启用滚动那么此处不调用基类使框架的处理无效,改为在父窗口的OnSize后自行调用 + if (!m_scroll_enable) + CBaseDialog::ResizeDynamicLayout(); } -void CTabDlg::EnableDlgCtrl(UINT id, bool enable) +BOOL CTabDlg::OnInitDialog() { - CWnd* pCtrl = GetDlgItem(id); - if (pCtrl != nullptr) - pCtrl->EnableWindow(enable); + CBaseDialog::OnInitDialog(); + + // TODO: 在此添加额外的初始化 + + // 设置窗口背景色 + SetBackgroundColor(CWinVersionHelper::IsWindows11OrLater() ? RGB(249, 249, 249) : RGB(255, 255, 255)); + // SetBackgroundColor(RGB(255, 240, 244)); // 测试用 + + return TRUE; // return TRUE unless you set the focus to a control + // 异常: OCX 属性页应返回 FALSE } -void CTabDlg::SetButtonIcon(UINT id, HICON icon) + +BOOL CTabDlg::PreTranslateMessage(MSG* pMsg) { - CButton* btn = (CButton*)(GetDlgItem(id)); - if (btn != nullptr) - btn->SetIcon(icon); + // TODO: 在此添加专用代码和/或调用基类 + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE) + { + return TRUE; + } + if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN) + { + return TRUE; + } + + return CBaseDialog::PreTranslateMessage(pMsg); } -void CTabDlg::ShowDlgCtrl(UINT id, bool show) + +void CTabDlg::OnOK() { - CWnd* pCtrl = GetDlgItem(id); - if (pCtrl != nullptr) - pCtrl->ShowWindow(show); + // 此处将CDialog原本protected的默认OnOK重写为Public + // 这是为了对外提供统一调用标签页(此类的派生类)OnOK的方式 + // 而不必区分具体是哪个派生类(dynamic_cast) + CBaseDialog::OnOK(); } -BEGIN_MESSAGE_MAP(CTabDlg, CDialogEx) - ON_WM_VSCROLL() - ON_WM_MOUSEWHEEL() -END_MESSAGE_MAP() - void CTabDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { - // TODO: 在此添加消息处理程序代码和/或调用默认值 - //参考资料:https://www.cnblogs.com/ranjiewen/p/6013922.html - - if (m_scroll_enable) - { - SCROLLINFO scrollinfo; - GetScrollInfo(SB_VERT, &scrollinfo, SIF_ALL); - int unit = 1; - int step = theApp.DPI(16); - switch (nSBCode) - { - case SB_LINEUP: //Scroll one line up - ScrollWindowSimple(unit * step); - break; - case SB_LINEDOWN: //Scroll one line down - ScrollWindowSimple(-unit * step); - break; - case SB_PAGEUP: //Scroll one page up. - ScrollWindowSimple(unit * step * 5); - break; - case SB_PAGEDOWN: //Scroll one page down - ScrollWindowSimple(-unit * step * 5); - break; - case SB_ENDSCROLL: //End scroll - break; - case SB_THUMBPOSITION: //Scroll to the absolute position. The current position is provided in nPos - break; - case SB_THUMBTRACK: //Drag scroll box to specified position. The current position is provided in nPos + // TODO: 在此添加消息处理程序代码和/或调用默认值 + //参考资料:https://www.cnblogs.com/ranjiewen/p/6013922.html + + if (m_scroll_enable) + { + int step = theApp.DPI(16); + switch (nSBCode) { - int y_amount = (m_last_pos - nPos)*unit; - ScrollWindow(0, y_amount); - scrollinfo.nPos = nPos; - SetScrollInfo(SB_VERT, &scrollinfo, SIF_ALL); + case SB_LINEUP: //Scroll one line up + ScrollWindowSimple(step); + break; + case SB_LINEDOWN: //Scroll one line down + ScrollWindowSimple(-step); + break; + case SB_PAGEUP: //Scroll one page up. + ScrollWindowSimple(INT_MAX); + break; + case SB_PAGEDOWN: //Scroll one page down + ScrollWindowSimple(INT_MIN); + break; + case SB_THUMBPOSITION: //Scroll to the absolute position. The current position is provided in nPos + break; + case SB_THUMBTRACK: //Drag scroll box to specified position. The current position is provided in nPos + ScrollWindowSimple(nPos, true); + break; + case SB_TOP: // 顶部 + ScrollWindowSimple(0, true); + break; + case SB_BOTTOM: // 底部 + ScrollWindowSimple(-1, true); + break; + case SB_ENDSCROLL: //End scroll + break; + default: + break; } - break; - } - m_last_pos = scrollinfo.nPos; - } - CDialogEx::OnVScroll(nSBCode, nPos, pScrollBar); + } + CBaseDialog::OnVScroll(nSBCode, nPos, pScrollBar); } BOOL CTabDlg::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) { - // TODO: 在此添加消息处理程序代码和/或调用默认值 - if (m_scroll_enable) - { - int step = theApp.DPI(64); - if (zDelta > 0) - { - ScrollWindowSimple(step); - } - if (zDelta < 0) - { - ScrollWindowSimple(-step); - } - SCROLLINFO scrollinfo; - GetScrollInfo(SB_VERT, &scrollinfo, SIF_ALL); - m_last_pos = scrollinfo.nPos; + // TODO: 在此添加消息处理程序代码和/或调用默认值 + if (m_scroll_enable) + { + int step = theApp.DPI(64) * zDelta / 120; + ScrollWindowSimple(step); } - return CDialogEx::OnMouseWheel(nFlags, zDelta, pt); -} - - -void CTabDlg::OnOK() -{ - // TODO: 在此添加专用代码和/或调用基类 - - CDialogEx::OnOK(); + return CBaseDialog::OnMouseWheel(nFlags, zDelta, pt); } diff --git a/MusicPlayer2/TabDlg.h b/MusicPlayer2/TabDlg.h index f5a0da2ab..0e2254402 100644 --- a/MusicPlayer2/TabDlg.h +++ b/MusicPlayer2/TabDlg.h @@ -1,39 +1,46 @@ //这是用于Tab标签中的子对话框类 +#include "BaseDialog.h" + #pragma once -class CTabDlg : public CDialogEx +class CTabDlg : public CBaseDialog { - DECLARE_DYNAMIC(CTabDlg) + DECLARE_DYNAMIC(CTabDlg) public: - CTabDlg(UINT nIDTemplate, CWnd *pParent = NULL); - ~CTabDlg(); - virtual BOOL PreTranslateMessage(MSG* pMsg); - virtual BOOL OnInitDialog(); + CTabDlg(UINT nIDTemplate, CWnd *pParent = NULL); + ~CTabDlg(); + + // 当标签切换到当前窗口时被调用 + virtual void OnTabEntered() {} + // 需要从界面获取数据时被调用 + virtual void GetDataFromUi() {} + // 需要从数据更新界面时被调用 + virtual void ApplyDataToUi() {} + CWnd* GetParentWindow(); - void SetScrollbarInfo(int nPage, int nMax); - void ResetScroll(); - virtual void OnTabEntered() {} //当标签切换到当前窗口时被调用 - virtual void OnOK(); - // 需要从界面获取数据时被调用 - virtual void GetDataFromUi() {} - // 需要从数据更新界面时被调用 - virtual void ApplyDataToUi() {} - void SetScrollEnable(bool enable) { m_scroll_enable = enable; } -protected: - void ScrollWindowSimple(int step); + // 如果此标签页子窗口需要滚动那么父窗口需要调用此方法设置滚动信息并保证在父窗口OnSize后重新调用 + void SetScrollbarInfo(int nPage, int nMax); - void EnableDlgCtrl(UINT id, bool enable); - void SetButtonIcon(UINT id, HICON icon); - void ShowDlgCtrl(UINT id, bool show); +private: + void ScrollWindowSimple(int step, bool absolute = false); -protected: - CWnd* m_pParent; - bool m_scroll_enable{ false }; + bool m_scroll_enable{ false }; int m_last_pos{}; - COLORREF m_background_color{}; +protected: + // 从CBaseDialog继承并阻止派生类继承,标签页由父窗口管理,不使用CBaseDialog提供的此功能 + virtual CString GetDialogName() const override final { return CString(); }; + virtual bool IsRememberDialogSizeEnable() const override final { return false; }; + + // CWnd的虚方法,声明在afxwin.h,实现在wincore.cpp,在WM_SIZE消息处理时被CWnd调用 + // 内部在一些判断之后使用CWnd持有的CMFCDynamicLayout指针执行m_pDynamicLayout->Adjust() + virtual void ResizeDynamicLayout() override final; // 这里重写是为了改变调用时机,从默认的窗口OnSize之前改为父窗口OnSize之后 + + DECLARE_MESSAGE_MAP() public: - DECLARE_MESSAGE_MAP() - afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); - afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt); + virtual BOOL OnInitDialog(); + virtual BOOL PreTranslateMessage(MSG* pMsg); + virtual void OnOK(); + afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); + afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt); }; diff --git a/MusicPlayer2/TagEditDlg.cpp b/MusicPlayer2/TagEditDlg.cpp index 346d1d481..cf49275b3 100644 --- a/MusicPlayer2/TagEditDlg.cpp +++ b/MusicPlayer2/TagEditDlg.cpp @@ -4,15 +4,15 @@ #include "stdafx.h" #include "MusicPlayer2.h" #include "TagEditDlg.h" -#include "afxdialogex.h" +#include "AudioCommon.h" // CTagEditDlg 对话框 -IMPLEMENT_DYNAMIC(CTagEditDlg, CDialog) +IMPLEMENT_DYNAMIC(CTagEditDlg, CBaseDialog) CTagEditDlg::CTagEditDlg(vector& file_list, int index, CWnd* pParent /*=nullptr*/) - : CDialog(IDD_TAG_EDIT_DIALOG, pParent), m_file_list{ file_list }, m_index{ index } + : CBaseDialog(IDD_TAG_EDIT_DIALOG, pParent), m_file_list{ file_list }, m_index{ index } { } @@ -23,32 +23,109 @@ CTagEditDlg::~CTagEditDlg() void CTagEditDlg::DoDataExchange(CDataExchange* pDX) { - CDialog::DoDataExchange(pDX); - DDX_Control(pDX, IDC_GENRE_COMBO, m_genre_combo); + CBaseDialog::DoDataExchange(pDX); + DDX_Control(pDX, IDC_GENRE_COMBO, m_genre_combo); } void CTagEditDlg::ShowInfo() { - if (m_index < 0 || m_index >= static_cast(m_file_list.size())) - return; - const SongInfo& item{ m_file_list[m_index] }; - SetDlgItemText(IDC_PATH_EDIT, item.file_path.c_str()); - SetDlgItemText(IDC_TITEL_EDIT, item.title.c_str()); - SetDlgItemText(IDC_ARTIST_EDIT, item.artist.c_str()); - SetDlgItemText(IDC_ALBUM_EDIT, item.album.c_str()); - SetDlgItemText(IDC_TRACK_EDIT, CAudioCommon::TrackToString(item.track)); - SetDlgItemText(IDC_GENRE_COMBO, item.genre.c_str()); - SetDlgItemText(IDC_COMMENT_EDIT, item.comment.c_str()); - CString info_str; - info_str.Format(_T("%d/%d"), m_index + 1, m_file_list.size()); - SetDlgItemText(IDC_ITEM_STATIC, info_str); + if (m_index < 0 || m_index >= static_cast(m_file_list.size())) + return; + const SongInfo& item{ m_file_list[m_index] }; + SetDlgItemTextW(IDC_PATH_EDIT, item.file_path.c_str()); + SetDlgItemTextW(IDC_TITEL_EDIT, item.title.c_str()); + SetDlgItemTextW(IDC_ARTIST_EDIT, item.artist.c_str()); + SetDlgItemTextW(IDC_ALBUM_EDIT, item.album.c_str()); + SetDlgItemTextW(IDC_TRACK_EDIT, CAudioCommon::TrackToString(item.track)); + SetDlgItemTextW(IDC_YEAR_EDIT, item.get_year().c_str()); + SetDlgItemTextW(IDC_GENRE_COMBO, item.genre.c_str()); + SetDlgItemTextW(IDC_COMMENT_EDIT, item.comment.c_str()); + CString info_str; + info_str.Format(_T("%d/%d"), m_index + 1, m_file_list.size()); + SetDlgItemTextW(IDC_ITEM_STATIC, info_str); } +CString CTagEditDlg::GetDialogName() const +{ + return L"EditAudioTagDlg"; +} -BEGIN_MESSAGE_MAP(CTagEditDlg, CDialog) - ON_BN_CLICKED(IDC_PREVIOUS_BUTTON, &CTagEditDlg::OnBnClickedPreviousButton) - ON_BN_CLICKED(IDC_NEXT_BUTTON, &CTagEditDlg::OnBnClickedNextButton) - ON_BN_CLICKED(IDC_SAVE_BUTTON, &CTagEditDlg::OnBnClickedSaveButton) +bool CTagEditDlg::InitializeControls() +{ + // 这里部分使用 IDD_PROPERTY_DIALOG / IDD_PROPERTY_PARENT_DIALOG 的字符串 + wstring temp; + temp = theApp.m_str_table.LoadText(L"TITLE_TAG_EDIT"); + SetWindowTextW(temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_TAG_EDIT_PATH"); + SetDlgItemTextW(IDC_TXT_TAG_EDIT_PATH_STATIC, temp.c_str()); + // IDC_PATH_EDIT + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_TAG_TITLE"); + SetDlgItemTextW(IDC_TXT_PROPERTY_DLG_TAG_TITLE_STATIC, temp.c_str()); + // IDC_TITEL_EDIT + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_TAG_ARTIST"); + SetDlgItemTextW(IDC_TXT_PROPERTY_DLG_TAG_ARTIST_STATIC, temp.c_str()); + // IDC_ARTIST_EDIT + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_TAG_ALBUM"); + SetDlgItemTextW(IDC_TXT_PROPERTY_DLG_TAG_ALBUM_STATIC, temp.c_str()); + // IDC_ALBUM_EDIT + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_TAG_TRACK"); + SetDlgItemTextW(IDC_TXT_PROPERTY_DLG_TAG_TRACK_STATIC, temp.c_str()); + // IDC_TRACK_EDIT + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_TAG_YEAR"); + SetDlgItemTextW(IDC_TXT_PROPERTY_DLG_TAG_YEAR_STATIC, temp.c_str()); + // IDC_YEAR_EDIT + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_TAG_GENRE"); + SetDlgItemTextW(IDC_TXT_PROPERTY_DLG_TAG_GENRE_STATIC, temp.c_str()); + // IDC_GENRE_COMBO + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_TAG_COMMENT"); + SetDlgItemTextW(IDC_TXT_PROPERTY_DLG_TAG_COMMENT_STATIC, temp.c_str()); + // IDC_COMMENT_EDIT + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_PARENT_PREVIOUS"); + SetDlgItemTextW(IDC_PREVIOUS_BUTTON, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_PARENT_NEXT"); + SetDlgItemTextW(IDC_NEXT_BUTTON, temp.c_str()); + temp = L"0/0"; + SetDlgItemTextW(IDC_ITEM_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_TAG_EDIT_SAVE"); + SetDlgItemTextW(IDC_SAVE_BUTTON, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_CLOSE"); + SetDlgItemTextW(IDCANCEL, temp.c_str()); + + RepositionTextBasedControls({ + { CtrlTextInfo::L1, IDC_TXT_TAG_EDIT_PATH_STATIC }, + { CtrlTextInfo::C0, IDC_PATH_EDIT }, + { CtrlTextInfo::L1, IDC_TXT_PROPERTY_DLG_TAG_TITLE_STATIC }, + { CtrlTextInfo::C0, IDC_TITEL_EDIT }, + { CtrlTextInfo::L1, IDC_TXT_PROPERTY_DLG_TAG_ARTIST_STATIC }, + { CtrlTextInfo::C0, IDC_ARTIST_EDIT }, + { CtrlTextInfo::L1, IDC_TXT_PROPERTY_DLG_TAG_ALBUM_STATIC }, + { CtrlTextInfo::C0, IDC_ALBUM_EDIT }, + { CtrlTextInfo::L1, IDC_TXT_PROPERTY_DLG_TAG_TRACK_STATIC }, + { CtrlTextInfo::C0, IDC_TRACK_EDIT }, + { CtrlTextInfo::L1, IDC_TXT_PROPERTY_DLG_TAG_GENRE_STATIC }, + { CtrlTextInfo::C0, IDC_GENRE_COMBO }, + { CtrlTextInfo::L1, IDC_TXT_PROPERTY_DLG_TAG_COMMENT_STATIC }, + { CtrlTextInfo::C0, IDC_COMMENT_EDIT } + }, CtrlTextInfo::W32); + RepositionTextBasedControls({ + { CtrlTextInfo::L1, IDC_TXT_PROPERTY_DLG_TAG_YEAR_STATIC }, + { CtrlTextInfo::C0, IDC_YEAR_EDIT } + }, CtrlTextInfo::W40); + RepositionTextBasedControls({ + { CtrlTextInfo::L2, IDC_PREVIOUS_BUTTON, CtrlTextInfo::W32 }, + { CtrlTextInfo::L1, IDC_NEXT_BUTTON, CtrlTextInfo::W32 }, + { CtrlTextInfo::C0, IDC_ITEM_STATIC }, + { CtrlTextInfo::R1, IDC_SAVE_BUTTON, CtrlTextInfo::W32 }, + { CtrlTextInfo::R2, IDCANCEL, CtrlTextInfo::W32 } + }); + return true; +} + + +BEGIN_MESSAGE_MAP(CTagEditDlg, CBaseDialog) + ON_BN_CLICKED(IDC_PREVIOUS_BUTTON, &CTagEditDlg::OnBnClickedPreviousButton) + ON_BN_CLICKED(IDC_NEXT_BUTTON, &CTagEditDlg::OnBnClickedNextButton) + ON_BN_CLICKED(IDC_SAVE_BUTTON, &CTagEditDlg::OnBnClickedSaveButton) END_MESSAGE_MAP() @@ -57,63 +134,71 @@ END_MESSAGE_MAP() BOOL CTagEditDlg::OnInitDialog() { - CDialog::OnInitDialog(); + CBaseDialog::OnInitDialog(); + + // TODO: 在此添加额外的初始化 - // TODO: 在此添加额外的初始化 + SetButtonIcon(IDC_PREVIOUS_BUTTON, IconMgr::IconType::IT_Triangle_Left); + SetButtonIcon(IDC_NEXT_BUTTON, IconMgr::IconType::IT_Triangle_Right); + SetButtonIcon(IDC_SAVE_BUTTON, IconMgr::IconType::IT_Save); - //初始化流派列表 + //初始化流派列表 CAudioCommon::EmulateGenre([&](const wstring& genre_str) { m_genre_combo.AddString(genre_str.c_str()); }, true); CRect rect; - m_genre_combo.SetMinVisibleItems(15); //设置下拉列表的高度 + m_genre_combo.SetMinVisibleItems(15); //设置下拉列表的高度 - ShowInfo(); + ShowInfo(); - return TRUE; // return TRUE unless you set the focus to a control - // 异常: OCX 属性页应返回 FALSE + return TRUE; // return TRUE unless you set the focus to a control + // 异常: OCX 属性页应返回 FALSE } void CTagEditDlg::OnBnClickedPreviousButton() { - // TODO: 在此添加控件通知处理程序代码 - if (m_file_list.size() <= 1) - return; - m_index--; - if (m_index < 0) m_index = m_file_list.size() - 1; - if (m_index < 0) m_index = 0; - ShowInfo(); + // TODO: 在此添加控件通知处理程序代码 + if (m_file_list.size() <= 1) + return; + m_index--; + if (m_index < 0) m_index = m_file_list.size() - 1; + if (m_index < 0) m_index = 0; + ShowInfo(); } void CTagEditDlg::OnBnClickedNextButton() { - // TODO: 在此添加控件通知处理程序代码 - if (m_file_list.size() <= 1) - return; - m_index++; - if (m_index >= static_cast(m_file_list.size())) m_index = 0; - ShowInfo(); + // TODO: 在此添加控件通知处理程序代码 + if (m_file_list.size() <= 1) + return; + m_index++; + if (m_index >= static_cast(m_file_list.size())) m_index = 0; + ShowInfo(); } void CTagEditDlg::OnBnClickedSaveButton() { - // TODO: 在此添加控件通知处理程序代码 - SongInfo& item{ m_file_list[m_index] }; - CString temp; - GetDlgItemText(IDC_TITEL_EDIT, temp); - item.title = temp; - GetDlgItemText(IDC_ARTIST_EDIT, temp); - item.artist = temp; - GetDlgItemText(IDC_ALBUM_EDIT, temp); - item.album = temp; - GetDlgItemText(IDC_TRACK_EDIT, temp); - item.track = _ttoi(temp); - GetDlgItemText(IDC_GENRE_COMBO, temp); - item.genre = temp; - GetDlgItemText(IDC_COMMENT_EDIT, temp); - item.comment = temp; + // TODO: 在此添加控件通知处理程序代码 + if (m_index < 0 || m_index >= static_cast(m_file_list.size())) + return; + SongInfo& item{ m_file_list[m_index] }; + CString temp; + GetDlgItemTextW(IDC_TITEL_EDIT, temp); + item.title = temp; + GetDlgItemTextW(IDC_ARTIST_EDIT, temp); + item.artist = temp; + GetDlgItemTextW(IDC_ALBUM_EDIT, temp); + item.album = temp; + GetDlgItemTextW(IDC_TRACK_EDIT, temp); + item.track = _ttoi(temp); + GetDlgItemTextW(IDC_YEAR_EDIT, temp); + item.SetYear(temp); + GetDlgItemTextW(IDC_GENRE_COMBO, temp); + item.genre = temp; + GetDlgItemTextW(IDC_COMMENT_EDIT, temp); + item.comment = temp; } diff --git a/MusicPlayer2/TagEditDlg.h b/MusicPlayer2/TagEditDlg.h index c1391f426..1a8e1672c 100644 --- a/MusicPlayer2/TagEditDlg.h +++ b/MusicPlayer2/TagEditDlg.h @@ -1,48 +1,36 @@ #pragma once +#include "BaseDialog.h" // CTagEditDlg 对话框 -class CTagEditDlg : public CDialog +class CTagEditDlg : public CBaseDialog { - DECLARE_DYNAMIC(CTagEditDlg) + DECLARE_DYNAMIC(CTagEditDlg) public: - //struct ItemInfo - //{ - // wstring file_path; - // SongInfo song_info; - // bool operator==(const ItemInfo& a) const - // { - // if (!a.song_info.is_cue) - // return file_path == a.file_path; - // else - // return (file_path == a.file_path && song_info.track == a.song_info.track); - // } - //}; - - - CTagEditDlg(vector& file_list, int index, CWnd* pParent = nullptr); // 标准构造函数 - virtual ~CTagEditDlg(); + CTagEditDlg(vector& file_list, int index, CWnd* pParent = nullptr); // 标准构造函数 + virtual ~CTagEditDlg(); // 对话框数据 #ifdef AFX_DESIGN_TIME - enum { IDD = IDD_TAG_EDIT_DIALOG }; + enum { IDD = IDD_TAG_EDIT_DIALOG }; #endif protected: - vector& m_file_list; - int m_index; + vector& m_file_list; + int m_index; + CComboBox m_genre_combo; - CComboBox m_genre_combo; + void ShowInfo(); - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 + virtual CString GetDialogName() const override; + virtual bool InitializeControls() override; + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 - void ShowInfo(); - - DECLARE_MESSAGE_MAP() + DECLARE_MESSAGE_MAP() public: - virtual BOOL OnInitDialog(); - afx_msg void OnBnClickedPreviousButton(); - afx_msg void OnBnClickedNextButton(); - afx_msg void OnBnClickedSaveButton(); + virtual BOOL OnInitDialog(); + afx_msg void OnBnClickedPreviousButton(); + afx_msg void OnBnClickedNextButton(); + afx_msg void OnBnClickedSaveButton(); }; diff --git a/MusicPlayer2/TagFromFileNameDlg.cpp b/MusicPlayer2/TagFromFileNameDlg.cpp deleted file mode 100644 index 19d59a6ff..000000000 --- a/MusicPlayer2/TagFromFileNameDlg.cpp +++ /dev/null @@ -1,309 +0,0 @@ -// TagFromFileNameDlg.cpp: 实现文件 -// - -#include "stdafx.h" -#include "MusicPlayer2.h" -#include "TagFromFileNameDlg.h" -#include "afxdialogex.h" -#include "PropertyDlgHelper.h" - - -// CTagFromFileNameDlg 对话框 - -IMPLEMENT_DYNAMIC(CTagFromFileNameDlg, CDialog) - -static const vector default_formular{ FORMULAR_ARTIST L" - " FORMULAR_TITLE, FORMULAR_TITLE L" - " FORMULAR_ARTIST, FORMULAR_TRACK L"." FORMULAR_ARTIST L" - " FORMULAR_TITLE }; - -CTagFromFileNameDlg::CTagFromFileNameDlg(CWnd* pParent /*=nullptr*/) - : CDialog(IDD_TAG_FROM_FILE_NAME_DIALOG, pParent) -{ - -} - -CTagFromFileNameDlg::~CTagFromFileNameDlg() -{ -} - -void CTagFromFileNameDlg::SetDialogTitle(LPCTSTR str_title) -{ - m_dlg_title = str_title; -} - -void CTagFromFileNameDlg::SetInitInsertFormular(const wstring& str_formular) -{ - m_init_insert_formular = str_formular; -} - -wstring CTagFromFileNameDlg::GetFormularSelected() const -{ - return m_formular_selected; -} - -void CTagFromFileNameDlg::HideOriginalBtn(bool hide) -{ - m_hide_original_btn = hide; -} - -void CTagFromFileNameDlg::SaveConfig() const -{ - CIniHelper ini(theApp.m_config_path); - ini.WriteBool(L"tag_edit", L"insert_when_clicked", IsInsertWhenClicked()); - ini.WriteStringList(L"tag_edit", L"default_formular", m_default_formular); - ini.Save(); -} - -void CTagFromFileNameDlg::LoadConfig() -{ - CIniHelper ini(theApp.m_config_path); - m_insert_when_clicked = ini.GetBool(L"tag_edit", L"insert_when_clicked", true); - ini.GetStringList(L"tag_edit", L"default_formular", m_default_formular, default_formular); -} - -wstring CTagFromFileNameDlg::InitComboList() -{ - wstring first_item; - m_format_combo.ResetContent(); - for (const auto& formular : m_default_formular) - { - //如果隐藏了“原文件名”按钮,则不在下拉列表中添加含有“原文件名”的项 - if (m_hide_original_btn) - { - if (formular.find(FORMULAR_ORIGINAL) != std::wstring::npos) - continue; - } - if (first_item.empty()) - first_item = formular; - m_format_combo.AddString(formular.c_str()); - } - m_format_combo.AddString(CCommon::LoadText(IDS_CLEAR_HISTORY)); - return first_item; -} - -void CTagFromFileNameDlg::InsertTag(const wchar_t* tag) -{ - CString str; - m_format_combo.GetWindowText(str); - //CEdit* pEdit = m_format_combo.GetEditCtrl(); - //int start, end; - //pEdit->GetSel(start, end); - //pEdit->SetSel(end, end); - //pEdit->ReplaceSel(tag); - str += tag; - m_format_combo.SetWindowText(str); -} - -void CTagFromFileNameDlg::SetInsertWhenClicked(bool insert) -{ - if (insert) - CheckDlgButton(IDC_INSERT_RADIO, TRUE); - else - CheckDlgButton(IDC_COPY_RADIO, TRUE); -} - -bool CTagFromFileNameDlg::IsInsertWhenClicked() const -{ - return (IsDlgButtonChecked(IDC_INSERT_RADIO) != 0); -} - -void CTagFromFileNameDlg::InsertFormular(const wstring& str_formular) -{ - if (!CPropertyDlgHelper::IsStringContainsFormular(str_formular)) - return; - - //向m_default_formular中插入一项 - auto iter = std::find(m_default_formular.begin(), m_default_formular.end(), str_formular); - if (iter == m_default_formular.begin()) //如果要插入的就在第一项,则直接返回 - return; - - if (iter != m_default_formular.end()) //如果列表中包含要插入的项,就将其和第一项交换 - { - std::swap(*iter, *m_default_formular.begin()); - } - else //列表中没有包含要插入的项,就将其插入到最前面 - { - m_default_formular.insert(m_default_formular.begin(), str_formular); - } -} - -void CTagFromFileNameDlg::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - DDX_Control(pDX, IDC_COMBO1, m_format_combo); -} - - -BEGIN_MESSAGE_MAP(CTagFromFileNameDlg, CDialog) - ON_BN_CLICKED(IDC_TITLE_BUTTON, &CTagFromFileNameDlg::OnBnClickedTitleButton) - ON_BN_CLICKED(IDC_ARTIST_BUTTON, &CTagFromFileNameDlg::OnBnClickedArtistButton) - ON_BN_CLICKED(IDC_ALBUM_BUTTON, &CTagFromFileNameDlg::OnBnClickedAlbumButton) - ON_BN_CLICKED(IDC_TRACK_BUTTON, &CTagFromFileNameDlg::OnBnClickedTrackButton) - ON_BN_CLICKED(IDC_YEAR_BUTTON, &CTagFromFileNameDlg::OnBnClickedYearButton) - ON_BN_CLICKED(IDC_GENRE_BUTTON, &CTagFromFileNameDlg::OnBnClickedGenreButton) - ON_WM_DESTROY() - ON_CBN_SELCHANGE(IDC_COMBO1, &CTagFromFileNameDlg::OnCbnSelchangeCombo1) - ON_BN_CLICKED(IDC_COMMENT_BUTTON, &CTagFromFileNameDlg::OnBnClickedCommentButton) - ON_BN_CLICKED(IDC_ORIGINAL_BUTTON, &CTagFromFileNameDlg::OnBnClickedOriginalButton) -END_MESSAGE_MAP() - - -// CTagFromFileNameDlg 消息处理程序 - - -BOOL CTagFromFileNameDlg::OnInitDialog() -{ - CDialog::OnInitDialog(); - - // TODO: 在此添加额外的初始化 - LoadConfig(); - - if (!m_dlg_title.IsEmpty()) - { - SetWindowText(m_dlg_title); - } - - if (!m_init_insert_formular.empty()) - { - InsertFormular(m_init_insert_formular); - } - - SetInsertWhenClicked(m_insert_when_clicked); - - SetDlgItemText(IDC_TITLE_BUTTON, FORMULAR_TITLE); - SetDlgItemText(IDC_ARTIST_BUTTON, FORMULAR_ARTIST); - SetDlgItemText(IDC_ALBUM_BUTTON, FORMULAR_ALBUM); - SetDlgItemText(IDC_TRACK_BUTTON, FORMULAR_TRACK); - SetDlgItemText(IDC_GENRE_BUTTON, FORMULAR_GENRE); - SetDlgItemText(IDC_YEAR_BUTTON, FORMULAR_YEAR); - SetDlgItemText(IDC_COMMENT_BUTTON, FORMULAR_COMMENT); - SetDlgItemText(IDC_ORIGINAL_BUTTON, FORMULAR_ORIGINAL); - - wstring first_item = InitComboList(); - if (!first_item.empty()) - m_format_combo.SetWindowText(first_item.c_str()); - - if (m_hide_original_btn) - { - GetDlgItem(IDC_ORIGINAL_STATIC)->ShowWindow(SW_HIDE); - GetDlgItem(IDC_ORIGINAL_BUTTON)->ShowWindow(SW_HIDE); - } - - return TRUE; // return TRUE unless you set the focus to a control - // 异常: OCX 属性页应返回 FALSE -} - - -void CTagFromFileNameDlg::OnBnClickedTitleButton() -{ - if (IsInsertWhenClicked()) - InsertTag(FORMULAR_TITLE); - else - CCommon::CopyStringToClipboard(FORMULAR_TITLE); -} - - -void CTagFromFileNameDlg::OnBnClickedArtistButton() -{ - if (IsInsertWhenClicked()) - InsertTag(FORMULAR_ARTIST); - else - CCommon::CopyStringToClipboard(FORMULAR_ARTIST); -} - - -void CTagFromFileNameDlg::OnBnClickedAlbumButton() -{ - if (IsInsertWhenClicked()) - InsertTag(FORMULAR_ALBUM); - else - CCommon::CopyStringToClipboard(FORMULAR_ALBUM); -} - - -void CTagFromFileNameDlg::OnBnClickedTrackButton() -{ - if (IsInsertWhenClicked()) - InsertTag(FORMULAR_TRACK); - else - CCommon::CopyStringToClipboard(FORMULAR_TRACK); -} - - -void CTagFromFileNameDlg::OnBnClickedYearButton() -{ - if (IsInsertWhenClicked()) - InsertTag(FORMULAR_YEAR); - else - CCommon::CopyStringToClipboard(FORMULAR_YEAR); -} - - -void CTagFromFileNameDlg::OnBnClickedGenreButton() -{ - if (IsInsertWhenClicked()) - InsertTag(FORMULAR_GENRE); - else - CCommon::CopyStringToClipboard(FORMULAR_GENRE); -} - - -void CTagFromFileNameDlg::OnDestroy() -{ - CDialog::OnDestroy(); - - // TODO: 在此处添加消息处理程序代码 - CString str; - m_format_combo.GetWindowText(str); - m_formular_selected = str.GetString(); - SaveConfig(); -} - - -void CTagFromFileNameDlg::OnCbnSelchangeCombo1() -{ - // TODO: 在此添加控件通知处理程序代码 - int cur_sel = m_format_combo.GetCurSel(); - if (cur_sel == m_format_combo.GetCount() - 1) - { - if (MessageBox(CCommon::LoadText(IDS_CLEAR_HISTORY_INFO), NULL, MB_ICONINFORMATION | MB_OKCANCEL) == IDOK) - { - m_default_formular = default_formular; - InitComboList(); - } - m_format_combo.SetCurSel(0); - } - else - { - CString str; - m_format_combo.GetWindowText(str); - InsertFormular(str.GetString()); - } -} - - -void CTagFromFileNameDlg::OnOK() -{ - // TODO: 在此添加专用代码和/或调用基类 - CString str; - m_format_combo.GetWindowText(str); - InsertFormular(str.GetString()); - - CDialog::OnOK(); -} - - -void CTagFromFileNameDlg::OnBnClickedCommentButton() -{ - if (IsInsertWhenClicked()) - InsertTag(FORMULAR_COMMENT); - else - CCommon::CopyStringToClipboard(FORMULAR_COMMENT); -} - - -void CTagFromFileNameDlg::OnBnClickedOriginalButton() -{ - if (IsInsertWhenClicked()) - InsertTag(FORMULAR_ORIGINAL); - else - CCommon::CopyStringToClipboard(FORMULAR_ORIGINAL); -} diff --git a/MusicPlayer2/TagFromFileNameDlg.h b/MusicPlayer2/TagFromFileNameDlg.h deleted file mode 100644 index c40aeecdf..000000000 --- a/MusicPlayer2/TagFromFileNameDlg.h +++ /dev/null @@ -1,64 +0,0 @@ -#pragma once - - -// CTagFromFileNameDlg 对话框 - -class CTagFromFileNameDlg : public CDialog -{ - DECLARE_DYNAMIC(CTagFromFileNameDlg) - -public: - CTagFromFileNameDlg(CWnd* pParent = nullptr); // 标准构造函数 - virtual ~CTagFromFileNameDlg(); - - void SetDialogTitle(LPCTSTR str_title); - void SetInitInsertFormular(const wstring& str_formular); - wstring GetFormularSelected() const; - void HideOriginalBtn(bool hide); //设置隐藏“Original”按钮 - -// 对话框数据 -#ifdef AFX_DESIGN_TIME - enum { IDD = IDD_TAG_FROM_FILE_NAME_DIALOG }; -#endif - -protected: - void SaveConfig() const; - void LoadConfig(); - - //初始化列表下拉列表,返回列表中添加的第一个项目 - wstring InitComboList(); - - void InsertTag(const wchar_t* tag); - - void SetInsertWhenClicked(bool insert); - bool IsInsertWhenClicked() const; - - void InsertFormular(const wstring& str_formular); - - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 - -protected: - bool m_insert_when_clicked{}; - vector m_default_formular; - wstring m_formular_selected; - - CString m_dlg_title; - wstring m_init_insert_formular; - bool m_hide_original_btn{ false }; //是否隐藏“Original”按钮 - - DECLARE_MESSAGE_MAP() -public: - virtual BOOL OnInitDialog(); - afx_msg void OnBnClickedTitleButton(); - afx_msg void OnBnClickedArtistButton(); - afx_msg void OnBnClickedAlbumButton(); - afx_msg void OnBnClickedTrackButton(); - afx_msg void OnBnClickedYearButton(); - afx_msg void OnBnClickedGenreButton(); - CComboBox m_format_combo; - afx_msg void OnDestroy(); - afx_msg void OnCbnSelchangeCombo1(); - virtual void OnOK(); - afx_msg void OnBnClickedCommentButton(); - afx_msg void OnBnClickedOriginalButton(); -}; diff --git a/MusicPlayer2/TagFromNameDlg.cpp b/MusicPlayer2/TagFromNameDlg.cpp new file mode 100644 index 000000000..4ee849c07 --- /dev/null +++ b/MusicPlayer2/TagFromNameDlg.cpp @@ -0,0 +1,56 @@ +// TagFromNameDlg.cpp: 实现文件 +// + +#include "stdafx.h" +#include "MusicPlayer2.h" +#include "TagFromNameDlg.h" + + +// CTagFromNameDlg 对话框 + +IMPLEMENT_DYNAMIC(CTagFromNameDlg, CTagSelBaseDlg) + +CTagFromNameDlg::CTagFromNameDlg(CWnd* pParent) + : CTagSelBaseDlg(true, pParent) +{ +} + +CTagFromNameDlg::~CTagFromNameDlg() +{ +} + +CString CTagFromNameDlg::GetDialogName() const +{ + return L"TagFromNameDlg"; +} + +bool CTagFromNameDlg::InitializeControls() +{ + wstring temp; + temp = theApp.m_str_table.LoadText(L"TITLE_TAG_FROM_NAME"); + SetWindowTextW(temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_TAG_FROM_NAME_INFO"); + SetDlgItemTextW(IDC_INFO_STATIC, temp.c_str()); + + return CTagSelBaseDlg::InitializeControls(); +} + +void CTagFromNameDlg::DoDataExchange(CDataExchange* pDX) +{ + CTagSelBaseDlg::DoDataExchange(pDX); +} + +BEGIN_MESSAGE_MAP(CTagFromNameDlg, CTagSelBaseDlg) +END_MESSAGE_MAP() + + +BOOL CTagFromNameDlg::OnInitDialog() +{ + CTagSelBaseDlg::OnInitDialog(); + + // TODO: 在此添加额外的初始化 + SetIcon(IconMgr::IconType::IT_Info, FALSE); + + return TRUE; // return TRUE unless you set the focus to a control + // 异常: OCX 属性页应返回 FALSE +} diff --git a/MusicPlayer2/TagFromNameDlg.h b/MusicPlayer2/TagFromNameDlg.h new file mode 100644 index 000000000..5135049d7 --- /dev/null +++ b/MusicPlayer2/TagFromNameDlg.h @@ -0,0 +1,22 @@ +#pragma once +#include "TagSelBaseDlg.h" + +// CTagFromNameDlg 对话框 + +class CTagFromNameDlg : public CTagSelBaseDlg +{ + DECLARE_DYNAMIC(CTagFromNameDlg) +public: + CTagFromNameDlg(CWnd* pParent = nullptr); // 标准构造函数 + virtual ~CTagFromNameDlg(); + +protected: + virtual CString GetDialogName() const; + virtual bool InitializeControls() override; + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 + + DECLARE_MESSAGE_MAP() +public: + virtual BOOL OnInitDialog(); +}; + diff --git a/MusicPlayer2/TagSelBaseDlg.cpp b/MusicPlayer2/TagSelBaseDlg.cpp new file mode 100644 index 000000000..6ef17ef1d --- /dev/null +++ b/MusicPlayer2/TagSelBaseDlg.cpp @@ -0,0 +1,438 @@ +// TagModeSelectBaseDlg.cpp: 实现文件 +// + +#include "stdafx.h" +#include "MusicPlayer2.h" +#include "TagSelBaseDlg.h" +#include "FilePathHelper.h" +#include "IniHelper.h" + + +// CTagSelBaseDlg 对话框 + +IMPLEMENT_DYNAMIC(CTagSelBaseDlg, CBaseDialog) + +const wstring CTagSelBaseDlg::FORMULAR_TITLE = L"%(Title)"; +const wstring CTagSelBaseDlg::FORMULAR_ARTIST = L"%(Artist)"; +const wstring CTagSelBaseDlg::FORMULAR_ALBUM = L"%(Album)"; +const wstring CTagSelBaseDlg::FORMULAR_TRACK = L"%(Track)"; +const wstring CTagSelBaseDlg::FORMULAR_YEAR = L"%(Year)"; +const wstring CTagSelBaseDlg::FORMULAR_GENRE = L"%(Genre)"; +const wstring CTagSelBaseDlg::FORMULAR_COMMENT = L"%(Comment)"; +const wstring CTagSelBaseDlg::FORMULAR_ORIGINAL = L"%(Original)"; +const vector CTagSelBaseDlg::default_formular{ FORMULAR_ARTIST + L" - " + FORMULAR_TITLE, FORMULAR_TITLE + L" - " + FORMULAR_ARTIST, FORMULAR_TRACK + L"." + FORMULAR_ARTIST + L" - " + FORMULAR_TITLE }; + +CTagSelBaseDlg::CTagSelBaseDlg(bool original_str_disable, CWnd* pParent /*=nullptr*/) + : CBaseDialog(IDD_TAG_MODE_SELECT_DIALOG, pParent), m_original_str_disable{ original_str_disable } +{ + +} + +CTagSelBaseDlg::~CTagSelBaseDlg() +{ +} + +void CTagSelBaseDlg::GetTagFromFileName(const wstring& formular, const wstring& file_name, SongInfo& song_info) +{ + wstring str_format = formular; + std::map identifiers; //保存标识符,int为标识符在formualr中的索引 + + //查找每个标识符的位置,并保存在identifers中,FORMULAR_ORIGINAL不参与推测 + const vector FORMULARS{ FORMULAR_TITLE, FORMULAR_ARTIST, FORMULAR_ALBUM, FORMULAR_TRACK, FORMULAR_YEAR, FORMULAR_GENRE, FORMULAR_COMMENT }; + for (const auto& f : FORMULARS) + { + size_t index = str_format.find(f); + if (index != wstring::npos) + { + identifiers[index] = f; + } + } + + const wchar_t* SPLITER = L"|"; + + //将标识符全部替换成| + for (const auto& item : identifiers) + { + CCommon::StringReplace(str_format, item.second.c_str(), SPLITER); + } + //取得分割符 + vector seprators; + CCommon::StringSplit(str_format, SPLITER, seprators, true, false); + + //用分割符分割文件名 + vector results; + CCommon::StringSplitWithSeparators(file_name, seprators, results); + + //获取分割结果 + if (results.empty()) + { + song_info.title = file_name; + } + else + { + size_t index{}; + for (const auto& item : identifiers) + { + if (index < results.size()) + { + wstring result = results[index]; + if (item.second == FORMULAR_TITLE) + song_info.title = result; + else if (item.second == FORMULAR_ARTIST) + song_info.artist = result; + else if (item.second == FORMULAR_ALBUM) + song_info.album = result; + else if (item.second == FORMULAR_TRACK) + song_info.track = _wtoi(result.c_str()); + else if (item.second == FORMULAR_YEAR) + song_info.SetYear(result.c_str()); + else if (item.second == FORMULAR_GENRE) + song_info.genre = result; + else if (item.second == FORMULAR_COMMENT) + song_info.comment = result; + } + index++; + } + } +} + +wstring CTagSelBaseDlg::FileNameFromTag(wstring formular, const SongInfo& song_info) +{ + vector> replacements = { + { FORMULAR_TITLE, song_info.GetTitle() }, + { FORMULAR_ARTIST, song_info.GetFirstArtist() }, + { FORMULAR_ALBUM, song_info.GetAlbum() }, + { FORMULAR_TRACK, std::to_wstring(song_info.track) }, + { FORMULAR_GENRE, song_info.GetGenre() }, + { FORMULAR_YEAR, song_info.GetYear() }, + { FORMULAR_COMMENT, song_info.comment }, + { FORMULAR_ORIGINAL, CFilePathHelper(song_info.file_path).GetFileNameWithoutExtension() } + }; + // 这里的先查找出所有格式字符串再替换是为了彻底规避普通的替换被来自song_info的字符串干扰(虽然几乎不可能发生) + std::map find_result; // 键是pos,值是replacements的索引 + size_t item_index{}; + for (const auto& item : replacements) + { + size_t pos = 0; + while ((pos = formular.find(item.first, pos)) != wstring::npos) + { + find_result.emplace(pos, item_index); // 这里的pos一定不会重复(除非FORMULAR_*有问题) + pos += item.first.size(); + } + ++item_index; + } + // 逆序遍历以免需要修改first中存储的pos + for (auto riter = find_result.rbegin(); riter != find_result.rend(); ++riter) + { + formular.replace(riter->first, replacements[riter->second].first.size(), replacements[riter->second].second); + } + CCommon::FileNameNormalize(formular); + // 这里给出的文件名可能太长,调用方可能需要截断(不应在这里进行) + return formular; +} + +void CTagSelBaseDlg::SaveConfig() const +{ + CIniHelper ini(theApp.m_config_path); + ini.WriteBool(L"tag_edit", L"insert_when_clicked", m_insert_when_clicked); + ini.WriteStringList(L"tag_edit", L"default_formular", m_default_formular); + ini.Save(); +} + +void CTagSelBaseDlg::LoadConfig() +{ + CIniHelper ini(theApp.m_config_path); + m_insert_when_clicked = ini.GetBool(L"tag_edit", L"insert_when_clicked", true); + ini.GetStringList(L"tag_edit", L"default_formular", m_default_formular, default_formular); +} + +void CTagSelBaseDlg::InitComboList() +{ + wstring first_item; + m_format_combo.ResetContent(); + for (const auto& formular : m_default_formular) + { + //如果隐藏了“原文件名”按钮,则不在下拉列表中添加含有“原文件名”的项 + if (m_original_str_disable) + { + if (formular.find(FORMULAR_ORIGINAL) != std::wstring::npos) + continue; + } + if (first_item.empty()) + first_item = formular; + m_format_combo.AddString(formular.c_str()); + } + if (m_format_combo.GetCount() == 0) // 如果为空那么添加一个作为默认 + m_format_combo.AddString(default_formular[0].c_str()); + m_format_combo.AddString(theApp.m_str_table.LoadText(L"TXT_TAG_SEL_CLEAR_HISTORY").c_str()); + m_format_combo.SetCurSel(0); +} + +bool CTagSelBaseDlg::IsStringContainsFormular(const wstring& str) const +{ + const vector formular_list{ FORMULAR_TITLE, FORMULAR_ARTIST, FORMULAR_ALBUM, FORMULAR_TRACK, FORMULAR_GENRE, FORMULAR_YEAR, FORMULAR_COMMENT, FORMULAR_ORIGINAL }; + for (const auto& formular : formular_list) + { + if (str.find(formular) != wstring::npos) + return true; + } + return false; +} + +void CTagSelBaseDlg::InsertFormular(const wstring& str_formular) +{ + if (str_formular.empty()) + return; + //向m_default_formular中插入一项 + auto iter = std::find(m_default_formular.begin(), m_default_formular.end(), str_formular); + if (iter != m_default_formular.end()) // 如果列表中包含要插入的项,将其移动到第一项 + std::rotate(m_default_formular.begin(), iter, iter + 1); + else // 列表中没有包含要插入的项(或列表为空),就将其插入到最前面 + m_default_formular.insert(m_default_formular.begin(), str_formular); +} + +void CTagSelBaseDlg::OnTagBtnClicked(const wstring& tag) +{ + if (m_insert_when_clicked) + { + CString str; + m_format_combo.GetWindowText(str); + str += tag.c_str(); + m_format_combo.SetWindowText(str); + } + else + CCommon::CopyStringToClipboard(tag); +} + +bool CTagSelBaseDlg::InitializeControls() +{ + // IDC_INFO_STATIC + // IDC_COMBO1 + wstring temp; + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_TAG_TITLE"); + SetDlgItemTextW(IDC_TXT_PROPERTY_DLG_TAG_TITLE_STATIC, temp.c_str()); + SetDlgItemTextW(IDC_TITLE_BUTTON, FORMULAR_TITLE.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_TAG_ARTIST"); + SetDlgItemTextW(IDC_TXT_PROPERTY_DLG_TAG_ARTIST_STATIC, temp.c_str()); + SetDlgItemTextW(IDC_ARTIST_BUTTON, FORMULAR_ARTIST.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_TAG_ALBUM"); + SetDlgItemTextW(IDC_TXT_PROPERTY_DLG_TAG_ALBUM_STATIC, temp.c_str()); + SetDlgItemTextW(IDC_ALBUM_BUTTON, FORMULAR_ALBUM.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_TAG_TRACK"); + SetDlgItemTextW(IDC_TXT_PROPERTY_DLG_TAG_TRACK_STATIC, temp.c_str()); + SetDlgItemTextW(IDC_TRACK_BUTTON, FORMULAR_TRACK.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_TAG_YEAR"); + SetDlgItemTextW(IDC_TXT_PROPERTY_DLG_TAG_YEAR_STATIC, temp.c_str()); + SetDlgItemTextW(IDC_YEAR_BUTTON, FORMULAR_YEAR.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_TAG_GENRE"); + SetDlgItemTextW(IDC_TXT_PROPERTY_DLG_TAG_GENRE_STATIC, temp.c_str()); + SetDlgItemTextW(IDC_GENRE_BUTTON, FORMULAR_GENRE.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_PROPERTY_DLG_TAG_COMMENT"); + SetDlgItemTextW(IDC_TXT_PROPERTY_DLG_TAG_COMMENT_STATIC, temp.c_str()); + SetDlgItemTextW(IDC_COMMENT_BUTTON, FORMULAR_COMMENT.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_TAG_SEL_ORIGINAL"); + SetDlgItemTextW(IDC_ORIGINAL_STATIC, temp.c_str()); + SetDlgItemTextW(IDC_ORIGINAL_BUTTON, FORMULAR_ORIGINAL.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_TAG_SEL_CLICK_BTN_SEL"); + SetDlgItemTextW(IDC_TXT_TAG_SEL_CLICK_BTN_SEL_STATIC, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_TAG_SEL_CLICK_BTN_INS"); + SetDlgItemTextW(IDC_INSERT_RADIO, temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_TAG_SEL_CLICK_BTN_COPY"); + SetDlgItemTextW(IDC_COPY_RADIO, temp.c_str()); + // IDOK + // IDCANCEL + + RepositionTextBasedControls({ + { CtrlTextInfo::L1, IDC_TXT_PROPERTY_DLG_TAG_TITLE_STATIC }, + { CtrlTextInfo::C0, IDC_TITLE_BUTTON }, + { CtrlTextInfo::L1, IDC_TXT_PROPERTY_DLG_TAG_ALBUM_STATIC }, + { CtrlTextInfo::C0, IDC_ALBUM_BUTTON }, + { CtrlTextInfo::L1, IDC_TXT_PROPERTY_DLG_TAG_YEAR_STATIC }, + { CtrlTextInfo::C0, IDC_YEAR_BUTTON }, + { CtrlTextInfo::L1, IDC_TXT_PROPERTY_DLG_TAG_COMMENT_STATIC }, + { CtrlTextInfo::C0, IDC_COMMENT_BUTTON } + }, CtrlTextInfo::W96); + RepositionTextBasedControls({ + { CtrlTextInfo::L1, IDC_TXT_PROPERTY_DLG_TAG_ARTIST_STATIC }, + { CtrlTextInfo::C0, IDC_ARTIST_BUTTON }, + { CtrlTextInfo::L1, IDC_TXT_PROPERTY_DLG_TAG_TRACK_STATIC }, + { CtrlTextInfo::C0, IDC_TRACK_BUTTON }, + { CtrlTextInfo::L1, IDC_TXT_PROPERTY_DLG_TAG_GENRE_STATIC }, + { CtrlTextInfo::C0, IDC_GENRE_BUTTON }, + { CtrlTextInfo::L1, IDC_ORIGINAL_STATIC }, + { CtrlTextInfo::C0, IDC_ORIGINAL_BUTTON } + }, CtrlTextInfo::W96); + RepositionTextBasedControls({ + { CtrlTextInfo::L3, IDC_TXT_TAG_SEL_CLICK_BTN_SEL_STATIC }, + { CtrlTextInfo::L2, IDC_INSERT_RADIO, CtrlTextInfo::W16 }, + { CtrlTextInfo::L1, IDC_COPY_RADIO, CtrlTextInfo::W16 } + }); + RepositionTextBasedControls({ + { CtrlTextInfo::R1, IDOK, CtrlTextInfo::W32 }, + { CtrlTextInfo::R2, IDCANCEL, CtrlTextInfo::W32 } + }); + return true; +} + +void CTagSelBaseDlg::DoDataExchange(CDataExchange* pDX) +{ + CBaseDialog::DoDataExchange(pDX); + DDX_Control(pDX, IDC_COMBO1, m_format_combo); +} + + +BEGIN_MESSAGE_MAP(CTagSelBaseDlg, CBaseDialog) + ON_BN_CLICKED(IDC_TITLE_BUTTON, &CTagSelBaseDlg::OnBnClickedTitleButton) + ON_BN_CLICKED(IDC_ARTIST_BUTTON, &CTagSelBaseDlg::OnBnClickedArtistButton) + ON_BN_CLICKED(IDC_ALBUM_BUTTON, &CTagSelBaseDlg::OnBnClickedAlbumButton) + ON_BN_CLICKED(IDC_TRACK_BUTTON, &CTagSelBaseDlg::OnBnClickedTrackButton) + ON_BN_CLICKED(IDC_YEAR_BUTTON, &CTagSelBaseDlg::OnBnClickedYearButton) + ON_BN_CLICKED(IDC_GENRE_BUTTON, &CTagSelBaseDlg::OnBnClickedGenreButton) + ON_BN_CLICKED(IDC_COMMENT_BUTTON, &CTagSelBaseDlg::OnBnClickedCommentButton) + ON_BN_CLICKED(IDC_ORIGINAL_BUTTON, &CTagSelBaseDlg::OnBnClickedOriginalButton) + ON_CBN_SELCHANGE(IDC_COMBO1, &CTagSelBaseDlg::OnCbnSelchangeCombo1) + ON_BN_CLICKED(IDC_INSERT_RADIO, &CTagSelBaseDlg::OnBnClickedInsertRadio) + ON_BN_CLICKED(IDC_COPY_RADIO, &CTagSelBaseDlg::OnBnClickedCopyRadio) + ON_WM_DESTROY() +END_MESSAGE_MAP() + + +// CTagModeSelectDlg 消息处理程序 + + +BOOL CTagSelBaseDlg::OnInitDialog() +{ + CBaseDialog::OnInitDialog(); + + // TODO: 在此添加额外的初始化 + LoadConfig(); + + if (m_insert_when_clicked) + CheckDlgButton(IDC_INSERT_RADIO, TRUE); + else + CheckDlgButton(IDC_COPY_RADIO, TRUE); + + InsertFormular(m_init_insert_formular); + InitComboList(); + + if (m_original_str_disable) + { + ShowDlgCtrl(IDC_ORIGINAL_STATIC, false); + ShowDlgCtrl(IDC_ORIGINAL_BUTTON, false); + } + + return TRUE; // return TRUE unless you set the focus to a control + // 异常: OCX 属性页应返回 FALSE +} + + +void CTagSelBaseDlg::OnBnClickedTitleButton() +{ + OnTagBtnClicked(FORMULAR_TITLE); +} + + +void CTagSelBaseDlg::OnBnClickedArtistButton() +{ + OnTagBtnClicked(FORMULAR_ARTIST); +} + + +void CTagSelBaseDlg::OnBnClickedAlbumButton() +{ + OnTagBtnClicked(FORMULAR_ALBUM); +} + + +void CTagSelBaseDlg::OnBnClickedTrackButton() +{ + OnTagBtnClicked(FORMULAR_TRACK); +} + + +void CTagSelBaseDlg::OnBnClickedYearButton() +{ + OnTagBtnClicked(FORMULAR_YEAR); +} + + +void CTagSelBaseDlg::OnBnClickedGenreButton() +{ + OnTagBtnClicked(FORMULAR_GENRE); +} + + +void CTagSelBaseDlg::OnBnClickedCommentButton() +{ + OnTagBtnClicked(FORMULAR_COMMENT); +} + + +void CTagSelBaseDlg::OnBnClickedOriginalButton() +{ + OnTagBtnClicked(FORMULAR_ORIGINAL); +} + + +void CTagSelBaseDlg::OnCbnSelchangeCombo1() +{ + // TODO: 在此添加控件通知处理程序代码 + int cur_sel = m_format_combo.GetCurSel(); + if (cur_sel == m_format_combo.GetCount() - 1) + { + const wstring& info = theApp.m_str_table.LoadText(L"MSG_TAG_SEL_CLEAR_HISTORY_INQUARY"); + if (MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OKCANCEL) == IDOK) + { + m_default_formular = default_formular; + InitComboList(); + } + m_format_combo.SetCurSel(0); + } + else + { + CString str; + m_format_combo.GetWindowText(str); + InsertFormular(str.GetString()); + } +} + + +void CTagSelBaseDlg::OnBnClickedInsertRadio() +{ + // TODO: 在此添加控件通知处理程序代码 + m_insert_when_clicked = true; +} + + +void CTagSelBaseDlg::OnBnClickedCopyRadio() +{ + // TODO: 在此添加控件通知处理程序代码 + m_insert_when_clicked = false; +} + + +void CTagSelBaseDlg::OnDestroy() +{ + CBaseDialog::OnDestroy(); + + // TODO: 在此处添加消息处理程序代码 + CString str; + m_format_combo.GetWindowText(str); + m_formular_selected = str.GetString(); + // 不保存没有formular的项目(因为没有复用可能性) + auto new_end = std::remove_if(m_default_formular.begin(), m_default_formular.end(), + [this](const wstring& item) { return !IsStringContainsFormular(item); }); + m_default_formular.erase(new_end, m_default_formular.end()); + SaveConfig(); +} + + +void CTagSelBaseDlg::OnOK() +{ + // TODO: 在此添加专用代码和/或调用基类 + CString str; + m_format_combo.GetWindowText(str); + InsertFormular(str.GetString()); + + CBaseDialog::OnOK(); +} diff --git a/MusicPlayer2/TagSelBaseDlg.h b/MusicPlayer2/TagSelBaseDlg.h new file mode 100644 index 000000000..596736862 --- /dev/null +++ b/MusicPlayer2/TagSelBaseDlg.h @@ -0,0 +1,81 @@ +#pragma once +#include "BaseDialog.h" + +// CTagSelBaseDlg 对话框 + +class CTagSelBaseDlg : public CBaseDialog +{ + DECLARE_DYNAMIC(CTagSelBaseDlg) + +public: + CTagSelBaseDlg(bool original_str_disable, CWnd* pParent = nullptr); // 标准构造函数 + virtual ~CTagSelBaseDlg(); + + // DoModal之前外部设置一个Formular(可选),窗口初始化时会被设为当前选中 + void SetInitInsertFormular(const wstring& formular) { m_init_insert_formular = formular; }; + // DoModal之后获取当前选中的Formular + wstring GetFormularSelected() const { return m_formular_selected; }; + + // 根据formular从文件名(参数不要输入扩展名)猜测标签 + static void GetTagFromFileName(const wstring& formular, const wstring& file_name, SongInfo& song_info); + // 根据formular字符串从标签生成文件名(不含扩展名) + static wstring FileNameFromTag(wstring formular, const SongInfo& song_info); + + static const wstring FORMULAR_TITLE; + static const wstring FORMULAR_ARTIST; + static const wstring FORMULAR_ALBUM; + static const wstring FORMULAR_TRACK; + static const wstring FORMULAR_YEAR; + static const wstring FORMULAR_GENRE; + static const wstring FORMULAR_COMMENT; + static const wstring FORMULAR_ORIGINAL; + static const vector default_formular; + + // 对话框数据 +#ifdef AFX_DESIGN_TIME + enum { IDD = IDD_TAG_MODE_SELECT_DIALOG }; +#endif + +private: + void SaveConfig() const; + void LoadConfig(); + + // 使用m_default_formular初始化列表下拉列表,并选中第一项 + void InitComboList(); + bool IsStringContainsFormular(const wstring& str) const; + void InsertFormular(const wstring& str_formular); + void OnTagBtnClicked(const wstring& tag); + + wstring m_formular_selected; + bool m_original_str_disable{}; // 不显示此窗口的所有%(Original)相关功能 + + bool m_insert_when_clicked{}; + vector m_default_formular; +protected: + wstring m_init_insert_formular; + CComboBox m_format_combo; + + // 从CBaseDialog继承的虚方法 + // virtual CString GetDialogName() const = 0; + virtual bool IsRememberDialogSizeEnable() const override final { return false; }; + // 派生类需要覆写InitializeControls设置标题和IDC_INFO_STATIC控件文本后调用基类 + virtual bool InitializeControls() override; + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 + + DECLARE_MESSAGE_MAP() +public: + virtual BOOL OnInitDialog(); + afx_msg void OnBnClickedTitleButton(); + afx_msg void OnBnClickedArtistButton(); + afx_msg void OnBnClickedAlbumButton(); + afx_msg void OnBnClickedTrackButton(); + afx_msg void OnBnClickedYearButton(); + afx_msg void OnBnClickedGenreButton(); + afx_msg void OnBnClickedCommentButton(); + afx_msg void OnBnClickedOriginalButton(); + afx_msg void OnCbnSelchangeCombo1(); + afx_msg void OnBnClickedInsertRadio(); + afx_msg void OnBnClickedCopyRadio(); + afx_msg void OnDestroy(); + virtual void OnOK(); +}; diff --git a/MusicPlayer2/TestDlg.cpp b/MusicPlayer2/TestDlg.cpp index 3ae91e20e..a59e4cbcc 100644 --- a/MusicPlayer2/TestDlg.cpp +++ b/MusicPlayer2/TestDlg.cpp @@ -4,14 +4,14 @@ #include "stdafx.h" #include "MusicPlayer2.h" #include "TestDlg.h" -#include "afxdialogex.h" +#include "FilterHelper.h" // CTestDlg 对话框 -IMPLEMENT_DYNAMIC(CTestDlg, CDialog) +IMPLEMENT_DYNAMIC(CTestDlg, CBaseDialog) CTestDlg::CTestDlg(CWnd* pParent /*=nullptr*/) - : CDialog(IDD_TEST_DIALOG, pParent) + : CBaseDialog(IDD_TEST_DIALOG, pParent) { } @@ -21,16 +21,26 @@ CTestDlg::~CTestDlg() SAFE_DELETE(m_pImage); } +CString CTestDlg::GetDialogName() const +{ + return L"TestDlg"; +} + +bool CTestDlg::InitializeControls() +{ + return false; +} + void CTestDlg::DoDataExchange(CDataExchange* pDX) { - CDialog::DoDataExchange(pDX); + CBaseDialog::DoDataExchange(pDX); DDX_Control(pDX, IDC_TEST_TOOLBAR, m_toolbar); DDX_Control(pDX, IDC_TEST_PROGRESS_BAR, m_progress_bar); DDX_Control(pDX, IDC_MFCEDITBROWSE1, m_browse_edit); } -BEGIN_MESSAGE_MAP(CTestDlg, CDialog) +BEGIN_MESSAGE_MAP(CTestDlg, CBaseDialog) ON_WM_TIMER() ON_WM_PAINT() END_MESSAGE_MAP() @@ -41,15 +51,15 @@ END_MESSAGE_MAP() BOOL CTestDlg::OnInitDialog() { - CDialog::OnInitDialog(); + CBaseDialog::OnInitDialog(); // TODO: 在此添加额外的初始化 m_toolbar.SetIconSize(theApp.DPI(20)); - m_toolbar.AddToolButton(theApp.m_icon_set.media_lib, _T("添加"), _T("打开文件"), ID_SET_PATH, false); - m_toolbar.AddToolButton(theApp.m_icon_set.setting, _T("添加"), _T("测试文本"), (UINT)0, true); - m_toolbar.AddToolButton(theApp.m_icon_set.eq, _T("删除"), _T("测试文本1"), (UINT)0, true); - m_toolbar.AddToolButton(theApp.m_icon_set.menu, _T("菜单"), _T("显示菜单"), theApp.m_menu_set.m_main_menu.GetSubMenu(0), true); - m_toolbar.AddToolButton(theApp.m_icon_set.edit, nullptr, _T("显示菜单"), nullptr, true); + m_toolbar.AddToolButton(IconMgr::IconType::IT_Media_Lib, _T("添加"), _T("打开文件"), ID_MEDIA_LIB, false); + m_toolbar.AddToolButton(IconMgr::IconType::IT_Setting, _T("添加"), _T("测试文本"), (UINT)0, true); + m_toolbar.AddToolButton(IconMgr::IconType::IT_Equalizer, _T("删除"), _T("测试文本1"), (UINT)0, true); + m_toolbar.AddToolButton(IconMgr::IconType::IT_Menu, _T("菜单"), _T("显示菜单"), theApp.m_menu_mgr.GetMenu(MenuMgr::MainFileMenu), true); + m_toolbar.AddToolButton(IconMgr::IconType::IT_Edit, nullptr, _T("显示菜单"), nullptr, true); //进度条 m_progress_bar.SetProgress(18); @@ -57,8 +67,8 @@ BOOL CTestDlg::OnInitDialog() SetTimer(82373, 80, NULL); - CString szFilter = CCommon::LoadText(IDS_SOUND_FONT_FILTER); - m_browse_edit.EnableFileBrowseButton(_T("SF2"), szFilter); + wstring sf2_filter = FilterHelper::GetSF2FileFilter();; + m_browse_edit.EnableFileBrowseButton(_T("SF2"), sf2_filter.c_str()); m_image.Load(_T("D:\\Temp\\Desktop\\AlbumCover - 曲婉婷 - Love Birds.jpg")); int width = m_image.GetWidth(); @@ -104,7 +114,7 @@ void CTestDlg::OnTimer(UINT_PTR nIDEvent) m_progress_bar.SetProgress(m_timer_cnt % 100); } - CDialog::OnTimer(nIDEvent); + CBaseDialog::OnTimer(nIDEvent); } @@ -112,14 +122,14 @@ void CTestDlg::OnPaint() { CPaintDC dc(this); // device context for painting // TODO: 在此处添加消息处理程序代码 - // 不为绘图消息调用 CDialog::OnPaint() + // 不为绘图消息调用 CBaseDialog::OnPaint() const int START_X{ theApp.DPI(16) }; const int START_Y{ theApp.DPI(120) }; CRect img_rect{ CPoint(START_X, START_Y), CSize(theApp.DPI(250), theApp.DPI(150)) }; CDrawCommon draw; - draw.Create(&dc, this); + draw.Create(&dc, &theApp.m_font_set.dlg.GetFont()); //draw.DrawImage(m_image, img_rect.TopLeft(), img_rect.Size(), CDrawCommon::StretchMode::FIT); //Gdiplus::Bitmap bm(m_image, NULL); diff --git a/MusicPlayer2/TestDlg.h b/MusicPlayer2/TestDlg.h index 3ecb5d585..c50ae1f3c 100644 --- a/MusicPlayer2/TestDlg.h +++ b/MusicPlayer2/TestDlg.h @@ -1,28 +1,31 @@ #pragma once +#include "BaseDialog.h" #include "PlayerToolBar.h" #include "PlayerProgressBar.h" #include "BrowseEdit.h" // CTestDlg 对话框 -class CTestDlg : public CDialog +class CTestDlg : public CBaseDialog { - DECLARE_DYNAMIC(CTestDlg) + DECLARE_DYNAMIC(CTestDlg) public: - CTestDlg(CWnd* pParent = nullptr); // 标准构造函数 - virtual ~CTestDlg(); + CTestDlg(CWnd* pParent = nullptr); // 标准构造函数 + virtual ~CTestDlg(); // 对话框数据 #ifdef AFX_DESIGN_TIME - enum { IDD = IDD_TEST_DIALOG }; + enum { IDD = IDD_TEST_DIALOG }; #endif protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 + virtual CString GetDialogName() const override; + virtual bool InitializeControls() override; + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 - DECLARE_MESSAGE_MAP() + DECLARE_MESSAGE_MAP() private: CPlayerToolBar m_toolbar; diff --git a/MusicPlayer2/TinyXml2Helper.h b/MusicPlayer2/TinyXml2Helper.h index a3a44283a..89b1fb620 100644 --- a/MusicPlayer2/TinyXml2Helper.h +++ b/MusicPlayer2/TinyXml2Helper.h @@ -1,7 +1,5 @@ #pragma once #include "tinyxml2/tinyxml2.h" -#include -#include class CTinyXml2Helper { diff --git a/MusicPlayer2/TreeCtrlEx.h b/MusicPlayer2/TreeCtrlEx.h index 3ebbcbd8c..6c2d2dcb5 100644 --- a/MusicPlayer2/TreeCtrlEx.h +++ b/MusicPlayer2/TreeCtrlEx.h @@ -1,5 +1,4 @@ #pragma once -#include #include "ColorConvert.h" diff --git a/MusicPlayer2/UIElement.cpp b/MusicPlayer2/UIElement.cpp index 5ffeb6a74..f81b902e4 100644 --- a/MusicPlayer2/UIElement.cpp +++ b/MusicPlayer2/UIElement.cpp @@ -616,20 +616,19 @@ void UiElement::Rectangle::Draw() void UiElement::Button::Draw() { CalculateRect(); - const IconRes& icon{ ui->GetBtnIcon(key, big_icon) }; switch (key) { case CPlayerUIBase::BTN_TRANSLATE: ui->DrawTranslateButton(rect); break; case CPlayerUIBase::BTN_LRYIC: - ui->DrawTextButton(rect, ui->m_buttons[key], CCommon::LoadText(IDS_LRC), theApp.m_lyric_setting_data.show_desktop_lyric); + ui->DrawDesktopLyricButton(rect); break; case CPlayerUIBase::BTN_AB_REPEAT: ui->DrawABRepeatButton(rect); break; default: - ui->DrawUIButton(rect, ui->m_buttons[key], icon); + ui->DrawUIButton(rect, key, big_icon); break; } ui->ResetDrawArea(); @@ -642,6 +641,8 @@ void UiElement::Button::FromString(const std::string& key_type) key = CPlayerUIBase::BTN_MENU; else if (key_type == "miniMode") key = CPlayerUIBase::BTN_MINI; + else if (key_type == "miniModeClose") + key = CPlayerUIBase::BTN_CLOSE; else if (key_type == "fullScreen") key = CPlayerUIBase::BTN_FULL_SCREEN; else if (key_type == "repeatMode") @@ -673,7 +674,7 @@ void UiElement::Button::FromString(const std::string& key_type) else if (key_type == "favorite") key = CPlayerUIBase::BTN_FAVOURITE; else if (key_type == "mediaLib") - key = CPlayerUIBase::BTN_SELECT_FOLDER; + key = CPlayerUIBase::BTN_MEDIA_LIB; else if (key_type == "showPlaylist") key = CPlayerUIBase::BTN_SHOW_PLAYLIST; else if (key_type == "addToPlaylist") @@ -792,13 +793,16 @@ std::wstring UiElement::Text::GetText() const case UiElement::Text::PlayTimeAndVolume: if (show_volume) { - CString str; - str.Format(CCommon::LoadText(IDS_VOLUME, _T(": %d%%")), CPlayer::GetInstance().GetVolume()); - draw_text = str; + static const wstring& mute_str = theApp.m_str_table.LoadText(L"UI_TXT_VOLUME_MUTE"); + int volume = CPlayer::GetInstance().GetVolume(); + if(volume <= 0) + draw_text = theApp.m_str_table.LoadTextFormat(L"UI_TXT_VOLUME", { mute_str, L"" }); + else + draw_text = theApp.m_str_table.LoadTextFormat(L"UI_TXT_VOLUME", { volume, L"%" }); } else { - draw_text = CPlayer::GetInstance().GetTimeString().c_str(); + draw_text = CPlayer::GetInstance().GetTimeString(); } break; default: @@ -892,15 +896,45 @@ void UiElement::ProgressBar::Draw() void UiElement::Lyrics::Draw() { CalculateRect(); - if (IsParentRectangle()) //如果父元素中包含了矩形元素,则即使在“外观设置”中勾选了“歌词界面背景”,也不再为歌词区域绘制半透明背景 - { - if (rect.Height() >= ui->DPI(4)) - ui->m_draw.DrawLryicCommon(rect, theApp.m_lyric_setting_data.lyric_align); - } - else + + CFont* lyric_font = &theApp.m_font_set.lyric.GetFont(theApp.m_ui_data.full_screen); + CFont* lyric_tr_font = &theApp.m_font_set.lyric_translate.GetFont(theApp.m_ui_data.full_screen); + + if (use_default_font) // 目前这个bool有些冗余,当字体与字号在m_font_set中解耦后有用 { - ui->DrawLyrics(rect); + bool big_font = theApp.m_ui_data.full_screen; + switch (font_size) + { + case 8: + lyric_font = &theApp.m_font_set.font8.GetFont(big_font); + lyric_tr_font = &theApp.m_font_set.font8.GetFont(big_font); + break; + case 9: + lyric_font = &theApp.m_font_set.font9.GetFont(big_font); + lyric_tr_font = &theApp.m_font_set.font8.GetFont(big_font); + break; + case 10: + lyric_font = &theApp.m_font_set.font10.GetFont(big_font); + lyric_tr_font = &theApp.m_font_set.font9.GetFont(big_font); + break; + case 11: + lyric_font = &theApp.m_font_set.font11.GetFont(big_font); + lyric_tr_font = &theApp.m_font_set.font10.GetFont(big_font); + break; + case 12: + lyric_font = &theApp.m_font_set.font12.GetFont(big_font); + lyric_tr_font = &theApp.m_font_set.font11.GetFont(big_font); + break; + default: + lyric_font = &theApp.m_font_set.font9.GetFont(big_font); + lyric_tr_font = &theApp.m_font_set.font8.GetFont(big_font); + break; + } } + + //如果父元素中包含了矩形元素,则即使在“外观设置”中勾选了“歌词界面背景”,也不再为歌词区域绘制半透明背景 + ui->DrawLyrics(rect, lyric_font, lyric_tr_font, (!no_background && !IsParentRectangle())); + ui->ResetDrawArea(); ui->m_draw_data.lyric_rect = rect; Element::Draw(); @@ -1024,9 +1058,9 @@ bool UiElement::Playlist::RButtunUp(CPoint point) mouse_pressed = false; CMenu* menu{}; if (item_selected >= 0 && !scrollbar_rect.PtInRect(point)) - menu = theApp.m_menu_set.m_list_popup_menu.GetSubMenu(0); + menu = theApp.m_menu_mgr.GetMenu(MenuMgr::PlaylistMenu); else - menu = &theApp.m_menu_set.m_playlist_toolbar_popup_menu; + menu = theApp.m_menu_mgr.GetMenu(MenuMgr::PlaylistToolBarMenu); if (menu != nullptr) { CPoint cursor_pos; @@ -1196,53 +1230,53 @@ void UiElement::ClassicalControlBar::Draw() //////////////////////////////////////////////////////////////////////////////////////// std::shared_ptr CElementFactory::CreateElement(const std::string& name, CPlayerUIBase* ui) { - UiElement::Element* element{}; + std::shared_ptr element; if (name == "verticalLayout") { - UiElement::Layout* layout = new UiElement::Layout(); + auto layout = std::make_shared(); layout->type = UiElement::Layout::Vertical; element = layout; } else if (name == "horizontalLayout") { - UiElement::Layout* layout = new UiElement::Layout(); + auto layout = std::make_shared(); layout->type = UiElement::Layout::Horizontal; element = layout; } else if (name == "stackElement") - element = new UiElement::StackElement(); + element = std::make_shared(); else if (name == "rectangle") - element = new UiElement::Rectangle(); + element = std::make_shared(); else if (name == "button") - element = new UiElement::Button(); + element = std::make_shared(); else if (name == "text") - element = new UiElement::Text(); + element = std::make_shared(); else if (name == "albumCover") - element = new UiElement::AlbumCover(); + element = std::make_shared(); else if (name == "spectrum") - element = new UiElement::Spectrum(); + element = std::make_shared(); else if (name == "trackInfo") - element = new UiElement::TrackInfo(); + element = std::make_shared(); else if (name == "toolbar") - element = new UiElement::Toolbar(); + element = std::make_shared(); else if (name == "progressBar") - element = new UiElement::ProgressBar(); + element = std::make_shared(); else if (name == "lyrics") - element = new UiElement::Lyrics(); + element = std::make_shared(); else if (name == "volume") - element = new UiElement::Volume(); + element = std::make_shared(); else if (name == "beatIndicator") - element = new UiElement::BeatIndicator(); + element = std::make_shared(); else if (name == "playlist") - element = new UiElement::Playlist(); + element = std::make_shared(); else if (name == "playlistIndicator") - element = new UiElement::PlaylistIndicator(); + element = std::make_shared(); else if (name == "classicalControlBar") - element = new UiElement::ClassicalControlBar(); + element = std::make_shared(); else if (name == "ui" || name == "root" || name == "placeHolder") - element = new UiElement::Element(); + element = std::make_shared(); if (element != nullptr) element->SetUi(ui); - return std::shared_ptr(element); + return element; } diff --git a/MusicPlayer2/UIElement.h b/MusicPlayer2/UIElement.h index 06af8d65e..a04097430 100644 --- a/MusicPlayer2/UIElement.h +++ b/MusicPlayer2/UIElement.h @@ -209,6 +209,9 @@ namespace UiElement class Lyrics : public Element { public: + bool no_background = false; // 总是不使用歌词背景 + bool use_default_font = false; // 固定使用默认字体 + int font_size{ 9 }; // 使用默认字体时的字号 virtual void Draw() override; protected: bool IsParentRectangle() const; //判断父元素中是否有矩形元素 diff --git a/MusicPlayer2/UIWindow.cpp b/MusicPlayer2/UIWindow.cpp index 4cef223b2..804fa17bd 100644 --- a/MusicPlayer2/UIWindow.cpp +++ b/MusicPlayer2/UIWindow.cpp @@ -55,7 +55,7 @@ void CUIWindow::OnLButtonUp(UINT nFlags, CPoint point) SLayoutData lyout; point1.y = lyout.titlabar_height; ClientToScreen(&point1); - theApp.m_menu_set.m_main_menu_popup.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point1.x, point1.y, theApp.m_pMainWnd); + theApp.m_menu_mgr.GetMenu(MenuMgr::MainPopupMenu)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point1.x, point1.y, theApp.m_pMainWnd); } else { @@ -175,13 +175,13 @@ void CUIWindow::OnRButtonUp(UINT nFlags, CPoint point) { CPoint point1; GetCursorPos(&point1); - theApp.m_menu_set.m_main_menu_popup.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point1.x, point1.y, theApp.m_pMainWnd); + theApp.m_menu_mgr.GetMenu(MenuMgr::MainPopupMenu)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point1.x, point1.y, theApp.m_pMainWnd); } else if (nFlags == MK_SHIFT) //按住Shift键点击鼠标右键时,弹出系统菜单 { CPoint point1; GetCursorPos(&point1); - theApp.m_menu_set.m_main_menu_popup.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point1.x, point1.y, theApp.m_pMainWnd); + theApp.m_menu_mgr.GetMenu(MenuMgr::MainPopupMenu)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point1.x, point1.y, theApp.m_pMainWnd); } else { diff --git a/MusicPlayer2/UIWindow.h b/MusicPlayer2/UIWindow.h index e34f96e54..5f71d3ca6 100644 --- a/MusicPlayer2/UIWindow.h +++ b/MusicPlayer2/UIWindow.h @@ -1,6 +1,6 @@ #pragma once -#include #include "IPlayerUI.h" + class CUIWindow : public CStatic { diff --git a/MusicPlayer2/UserUi.cpp b/MusicPlayer2/UserUi.cpp index 50160749a..1ecf2f663 100644 --- a/MusicPlayer2/UserUi.cpp +++ b/MusicPlayer2/UserUi.cpp @@ -10,9 +10,11 @@ CUserUi::CUserUi(CWnd* pMainWnd, const std::wstring& xml_path) delete[] xml_contents; } -CUserUi::CUserUi(CWnd* pMainWnd) +CUserUi::CUserUi(CWnd* pMainWnd, UINT id) : CPlayerUIBase(theApp.m_ui_data, pMainWnd) { + string xml = CCommon::GetTextResourceRawData(id); + LoadFromContents(xml); } @@ -27,7 +29,7 @@ void CUserUi::LoadFromContents(const std::string& xml_contents) xml_doc.Parse(xml_contents.c_str()); tinyxml2::XMLElement* root = xml_doc.RootElement(); m_ui_name = CCommon::StrToUnicode(CTinyXml2Helper::ElementAttribute(root, "name"), CodeType::UTF8_NO_BOM); - CCommon::ReplaceUiStringRes(m_ui_name); + ReplaceUiStringRes(m_ui_name); std::string ui_index = CTinyXml2Helper::ElementAttribute(root, "index"); if (!ui_index.empty()) m_index = atoi(ui_index.c_str()); @@ -102,15 +104,15 @@ void CUserUi::ResetVolumeToPlayTime() }); } -void CUserUi::PlaylistLocateToCurrent() +void CUserUi::PlaylistLocateToIndex(int index) { //遍历Playlist元素 - IterateAllElements([this](UiElement::Element* element) ->bool + IterateAllElements([&](UiElement::Element* element) ->bool { UiElement::Playlist* playlist_element{ dynamic_cast(element) }; if (playlist_element != nullptr) { - playlist_element->EnsureItemVisible(CPlayer::GetInstance().GetIndex()); + playlist_element->EnsureItemVisible(index); } return false; }); @@ -206,9 +208,9 @@ std::shared_ptr CUserUi::GetCurrentTypeUi() const return draw_element; } -CString CUserUi::GetUIName() +wstring CUserUi::GetUIName() { - return m_ui_name.c_str(); + return m_ui_name; } bool CUserUi::LButtonUp(CPoint point) @@ -436,7 +438,7 @@ bool CUserUi::DoubleClick(CPoint point) void CUserUi::UiSizeChanged() { - PlaylistLocateToCurrent(); + PlaylistLocateToIndex(INT_MAX); } int CUserUi::GetUiIndex() @@ -556,7 +558,7 @@ std::shared_ptr CUserUi::BuildUiElementFromXmlNode(tinyxml2: //text std::string str_text = CTinyXml2Helper::ElementAttribute(xml_node, "text"); text->text = CCommon::StrToUnicode(str_text, CodeType::UTF8_NO_BOM); - CCommon::ReplaceUiStringRes(text->text); + ReplaceUiStringRes(text->text); //alignment std::string str_alignment = CTinyXml2Helper::ElementAttribute(xml_node, "alignment"); if (str_alignment == "left") @@ -726,6 +728,17 @@ std::shared_ptr CUserUi::BuildUiElementFromXmlNode(tinyxml2: CTinyXml2Helper::GetElementAttributeBool(xml_node, "show_switch_display_btn", classicalControlBar->show_switch_display_btn); } } + //歌词 + else if (item_name == "lyrics") + { + UiElement::Lyrics* lyrics = dynamic_cast(element.get()); + if (lyrics != nullptr) + { + CTinyXml2Helper::GetElementAttributeBool(xml_node, "no_background", lyrics->no_background); + CTinyXml2Helper::GetElementAttributeBool(xml_node, "use_default_font", lyrics->use_default_font); + CTinyXml2Helper::GetElementAttributeInt(xml_node, "font_size", lyrics->font_size); + } + } //递归调用此函数创建子节点 CTinyXml2Helper::IterateChildNode(xml_node, [&](tinyxml2::XMLElement* xml_child) diff --git a/MusicPlayer2/UserUi.h b/MusicPlayer2/UserUi.h index 93c328f62..356c2a620 100644 --- a/MusicPlayer2/UserUi.h +++ b/MusicPlayer2/UserUi.h @@ -8,7 +8,7 @@ class CUserUi : { public: CUserUi(CWnd* pMainWnd, const std::wstring& xml_path); - CUserUi(CWnd* pMainWnd); //此构造函数不传递xml文件的路径,需要使用LoadFromContents函数直接读取xml文件的内容 + CUserUi(CWnd* pMainWnd, UINT id); //此构造函数不传递xml文件的路径,id为xml界面资源ID ~CUserUi(); void LoadFromContents(const std::string& xml_contents); @@ -19,7 +19,7 @@ class CUserUi : void IterateAllElementsInAllUi(std::function func); //遍历每一个界面中的所有元素(包含big、narrow、small三个界面) void VolumeAdjusted(); //当音量调整时需要调用此函数 void ResetVolumeToPlayTime(); //定时器SHOW_VOLUME_TIMER_ID响应时需要调用此函数 - void PlaylistLocateToCurrent(); //播放列表控件使正在播放的曲目可见 + void PlaylistLocateToIndex(int index); // 播放列表控件使此索引的条目可见 void SaveStatackElementIndex(CArchive& archive); void LoadStatackElementIndex(CArchive& archive); @@ -27,7 +27,7 @@ class CUserUi : // 通过 CPlayerUIBase 继承 virtual void _DrawInfo(CRect draw_rect, bool reset = false) override; - virtual CString GetUIName() override; + virtual wstring GetUIName() override; virtual bool LButtonUp(CPoint point) override; virtual bool LButtonDown(CPoint point) override; virtual void MouseMove(CPoint point) override; diff --git a/MusicPlayer2/WIC.cpp b/MusicPlayer2/WIC.cpp deleted file mode 100644 index 6a974bbf3..000000000 --- a/MusicPlayer2/WIC.cpp +++ /dev/null @@ -1,165 +0,0 @@ -#include "stdafx.h" -#include "WIC.h" - -CWICFactory CWICFactory::m_instance; - -CWICFactory::CWICFactory() -{ -#ifndef COMPILE_IN_WIN_XP - //ʼm_pWICFactory - _hrOleInit = ::OleInitialize(NULL); - CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&m_pWICFactory)); - if (m_pWICFactory == nullptr) - CoCreateInstance(CLSID_WICImagingFactory1, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&m_pWICFactory)); -#endif -} - -CWICFactory::~CWICFactory() -{ - if (m_pWICFactory) - { - m_pWICFactory->Release(); - m_pWICFactory = NULL; - } - - if (SUCCEEDED(_hrOleInit)) - { - OleUninitialize(); - } -} - - -////////////////////////////////////////////////////////// - -typedef DWORD ARGB; -std::map CMenuIcon::m_icon_map; - -CMenuIcon::CMenuIcon() -{ -} - -CMenuIcon::~CMenuIcon() -{ -} - -HRESULT CMenuIcon::AddIconToMenuItem(HMENU hmenu, int iMenuItem, BOOL fByPosition, HICON hicon) -{ -#ifndef COMPILE_IN_WIN_XP - HBITMAP hbmp{}; - HRESULT hr = GetBitmapByIcon(hicon, hbmp); - - if (SUCCEEDED(hr)) - { - hr = AddBitmapToMenuItem(hmenu, iMenuItem, fByPosition, hbmp); - } - - return hr; -#else - return 0; -#endif // !COMPILE_IN_WIN_XP -} - -HRESULT CMenuIcon::AddBitmapToMenuItem(HMENU hmenu, int iItem, BOOL fByPosition, HBITMAP hbmp) -{ - HRESULT hr = E_FAIL; - - MENUITEMINFO mii = { sizeof(mii) }; - mii.fMask = MIIM_BITMAP; - mii.hbmpItem = hbmp; - if (SetMenuItemInfo(hmenu, iItem, fByPosition, &mii)) - { - hr = S_OK; - } - - return hr; -} - -void CMenuIcon::InitBitmapInfo(BITMAPINFO * pbmi, ULONG cbInfo, LONG cx, LONG cy, WORD bpp) -{ - ZeroMemory(pbmi, cbInfo); - pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - pbmi->bmiHeader.biPlanes = 1; - pbmi->bmiHeader.biCompression = BI_RGB; - - pbmi->bmiHeader.biWidth = cx; - pbmi->bmiHeader.biHeight = cy; - pbmi->bmiHeader.biBitCount = bpp; -} - -HRESULT CMenuIcon::Create32BitHBITMAP(HDC hdc, const SIZE * psize, void ** ppvBits, HBITMAP * phBmp) -{ - *phBmp = NULL; - - BITMAPINFO bmi; - InitBitmapInfo(&bmi, sizeof(bmi), psize->cx, psize->cy, 32); - - HDC hdcUsed = hdc ? hdc : GetDC(NULL); - if (hdcUsed) - { - *phBmp = CreateDIBSection(hdcUsed, &bmi, DIB_RGB_COLORS, ppvBits, NULL, 0); - if (hdc != hdcUsed) - { - ReleaseDC(NULL, hdcUsed); - } - } - return (NULL == *phBmp) ? E_OUTOFMEMORY : S_OK; -} - -HRESULT CMenuIcon::GetBitmapByIcon(HICON hicon, HBITMAP& hbmp) -{ - auto iter = m_icon_map.find(hicon); - if (iter != m_icon_map.end()) - { - hbmp = iter->second; - return ERROR_SUCCESS; - } - else - { - if (CWICFactory::GetWIC() == nullptr) - return 0; - hbmp = NULL; - - IWICBitmap* pBitmap; - HRESULT hr = CWICFactory::GetWIC()->CreateBitmapFromHICON(hicon, &pBitmap); - if (SUCCEEDED(hr)) - { - IWICFormatConverter* pConverter; - hr = CWICFactory::GetWIC()->CreateFormatConverter(&pConverter); - if (SUCCEEDED(hr)) - { - hr = pConverter->Initialize(pBitmap, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, NULL, 0.0f, WICBitmapPaletteTypeCustom); - if (SUCCEEDED(hr)) - { - UINT cx, cy; - hr = pConverter->GetSize(&cx, &cy); - if (SUCCEEDED(hr)) - { - const SIZE sizIcon = { (int)cx, -(int)cy }; - BYTE* pbBuffer; - hr = Create32BitHBITMAP(NULL, &sizIcon, reinterpret_cast(&pbBuffer), &hbmp); - if (SUCCEEDED(hr)) - { - const UINT cbStride = cx * sizeof(ARGB); - const UINT cbBuffer = cy * cbStride; - hr = pConverter->CopyPixels(NULL, cbStride, cbBuffer, pbBuffer); - } - } - } - - pConverter->Release(); - } - - pBitmap->Release(); - } - if (SUCCEEDED(hr)) - { - m_icon_map[hicon] = hbmp; - } - if (FAILED(hr)) - { - DeleteObject(hbmp); - hbmp = NULL; - } - return hr; - } -} diff --git a/MusicPlayer2/WIC.h b/MusicPlayer2/WIC.h deleted file mode 100644 index c7f77dbaa..000000000 --- a/MusicPlayer2/WIC.h +++ /dev/null @@ -1,38 +0,0 @@ -//ʹ Windows ӳWICͼ꣨HICONתΪ͸ȵPARGB32λͼӵ˵ -//https://docs.microsoft.com/en-us/previous-versions/bb757020(v=msdn.10) - -#pragma once -class CWICFactory -{ -public: - ~CWICFactory(); - static IWICImagingFactory* GetWIC() { return m_instance.m_pWICFactory; } - -private: - HRESULT _hrOleInit{}; - IWICImagingFactory *m_pWICFactory{}; - - static CWICFactory m_instance; //CWICFactoryΨһĶ - -private: - CWICFactory(); -}; - -class CMenuIcon -{ -public: - CMenuIcon(); - ~CMenuIcon(); - - //һ˵ͼ - static HRESULT AddIconToMenuItem(HMENU hmenu, int iMenuItem, BOOL fByPosition, HICON hicon); - -private: - static HRESULT AddBitmapToMenuItem(HMENU hmenu, int iItem, BOOL fByPosition, HBITMAP hbmp); - static void InitBitmapInfo(__out_bcount(cbInfo) BITMAPINFO *pbmi, ULONG cbInfo, LONG cx, LONG cy, WORD bpp); - static HRESULT Create32BitHBITMAP(HDC hdc, const SIZE *psize, __deref_opt_out void **ppvBits, __out HBITMAP* phBmp); - static HRESULT GetBitmapByIcon(HICON hicon, HBITMAP& hbmp); - - static std::map m_icon_map; -}; - diff --git a/MusicPlayer2/WmaEncodeCfgDlg.cpp b/MusicPlayer2/WmaEncodeCfgDlg.cpp index aa1c5331e..4a5ce7ea4 100644 --- a/MusicPlayer2/WmaEncodeCfgDlg.cpp +++ b/MusicPlayer2/WmaEncodeCfgDlg.cpp @@ -4,15 +4,14 @@ #include "stdafx.h" #include "MusicPlayer2.h" #include "WmaEncodeCfgDlg.h" -#include "afxdialogex.h" // CWmaEncodeCfgDlg 对话框 -IMPLEMENT_DYNAMIC(CWmaEncodeCfgDlg, CDialog) +IMPLEMENT_DYNAMIC(CWmaEncodeCfgDlg, CBaseDialog) CWmaEncodeCfgDlg::CWmaEncodeCfgDlg(CWnd* pParent /*=nullptr*/) - : CDialog(IDD_WMA_ENCODE_CFG_DIALOG, pParent) + : CBaseDialog(IDD_WMA_ENCODE_CFG_DIALOG, pParent) { } @@ -23,25 +22,49 @@ CWmaEncodeCfgDlg::~CWmaEncodeCfgDlg() void CWmaEncodeCfgDlg::SetControlEnable() { - m_bitrate_combo.EnableWindow(m_encode_para.cbr); - m_vbr_quality_combo.EnableWindow(!m_encode_para.cbr); + m_bitrate_combo.EnableWindow(m_encode_para.cbr); + m_vbr_quality_combo.EnableWindow(!m_encode_para.cbr); +} + +CString CWmaEncodeCfgDlg::GetDialogName() const +{ + return L"WmaEncodeOptDlg"; +} + +bool CWmaEncodeCfgDlg::InitializeControls() +{ + wstring temp; + temp = theApp.m_str_table.LoadText(L"TITLE_ENCODE_OPT_WMA"); + SetWindowTextW(temp.c_str()); + temp = theApp.m_str_table.LoadText(L"TXT_ENCODE_OPT_WMA_CBR"); + SetDlgItemTextW(IDC_CBR_RADIO, temp.c_str()); + // IDC_BITRATE_COMBO + temp = theApp.m_str_table.LoadText(L"TXT_ENCODE_OPT_WMA_VBR"); + SetDlgItemTextW(IDC_CBR_RADIO2, temp.c_str()); + // IDC_VBR_QUALITY_COMBO + // IDOK + // IDCANCEL + + RepositionTextBasedControls({ + { CtrlTextInfo::R1, IDOK, CtrlTextInfo::W32 }, + { CtrlTextInfo::R2, IDCANCEL, CtrlTextInfo::W32 } + }); + return true; } void CWmaEncodeCfgDlg::DoDataExchange(CDataExchange* pDX) { - CDialog::DoDataExchange(pDX); - DDX_Control(pDX, IDC_BITRATE_COMBO, m_bitrate_combo); - DDX_Control(pDX, IDC_CBR_RADIO, m_cbr_radio); - DDX_Control(pDX, IDC_CBR_RADIO2, m_vbr_radio); - DDX_Control(pDX, IDC_VBR_QUALITY_COMBO, m_vbr_quality_combo); + CBaseDialog::DoDataExchange(pDX); + DDX_Control(pDX, IDC_BITRATE_COMBO, m_bitrate_combo); + DDX_Control(pDX, IDC_VBR_QUALITY_COMBO, m_vbr_quality_combo); } -BEGIN_MESSAGE_MAP(CWmaEncodeCfgDlg, CDialog) - ON_CBN_SELCHANGE(IDC_BITRATE_COMBO, &CWmaEncodeCfgDlg::OnCbnSelchangeBitrateCombo) - ON_CBN_SELCHANGE(IDC_VBR_QUALITY_COMBO, &CWmaEncodeCfgDlg::OnCbnSelchangeVbrQualityCombo) - ON_BN_CLICKED(IDC_CBR_RADIO, &CWmaEncodeCfgDlg::OnBnClickedCbrRadio) - ON_BN_CLICKED(IDC_CBR_RADIO2, &CWmaEncodeCfgDlg::OnBnClickedCbrRadio2) +BEGIN_MESSAGE_MAP(CWmaEncodeCfgDlg, CBaseDialog) + ON_CBN_SELCHANGE(IDC_BITRATE_COMBO, &CWmaEncodeCfgDlg::OnCbnSelchangeBitrateCombo) + ON_CBN_SELCHANGE(IDC_VBR_QUALITY_COMBO, &CWmaEncodeCfgDlg::OnCbnSelchangeVbrQualityCombo) + ON_BN_CLICKED(IDC_CBR_RADIO, &CWmaEncodeCfgDlg::OnBnClickedCbrRadio) + ON_BN_CLICKED(IDC_CBR_RADIO2, &CWmaEncodeCfgDlg::OnBnClickedCbrRadio2) END_MESSAGE_MAP() @@ -50,81 +73,86 @@ END_MESSAGE_MAP() BOOL CWmaEncodeCfgDlg::OnInitDialog() { - CDialog::OnInitDialog(); - - // TODO: 在此添加额外的初始化 - m_bitrate_combo.AddString(_T("16")); - m_bitrate_combo.AddString(_T("24")); - m_bitrate_combo.AddString(_T("32")); - m_bitrate_combo.AddString(_T("48")); - m_bitrate_combo.AddString(_T("64")); - m_bitrate_combo.AddString(_T("80")); - m_bitrate_combo.AddString(_T("96")); - m_bitrate_combo.AddString(_T("128")); - m_bitrate_combo.AddString(_T("160")); - m_bitrate_combo.AddString(_T("192")); - m_bitrate_combo.AddString(_T("224")); - m_bitrate_combo.AddString(_T("256")); - m_bitrate_combo.AddString(_T("320")); - - m_vbr_quality_combo.AddString(_T("10")); - m_vbr_quality_combo.AddString(_T("25")); - m_vbr_quality_combo.AddString(_T("50")); - m_vbr_quality_combo.AddString(_T("75")); - m_vbr_quality_combo.AddString(_T("90")); - m_vbr_quality_combo.AddString(_T("98")); - - if (m_encode_para.cbr) - m_cbr_radio.SetCheck(TRUE); - else - m_vbr_radio.SetCheck(TRUE); - - CString str; - str.Format(_T("%d"), m_encode_para.cbr_bitrate); - int index; - index = m_bitrate_combo.FindStringExact(0, str); - m_bitrate_combo.SetCurSel(index); - - str.Format(_T("%d"), m_encode_para.vbr_quality); - index = m_vbr_quality_combo.FindStringExact(0, str); - m_vbr_quality_combo.SetCurSel(index); - - SetControlEnable(); - - return TRUE; // return TRUE unless you set the focus to a control - // 异常: OCX 属性页应返回 FALSE + CBaseDialog::OnInitDialog(); + + // TODO: 在此添加额外的初始化 + m_bitrate_list.emplace_back(L"16 kbps", 16); + m_bitrate_list.emplace_back(L"24 kbps", 24); + m_bitrate_list.emplace_back(L"32 kbps", 32); + m_bitrate_list.emplace_back(L"48 kbps", 48); + m_bitrate_list.emplace_back(L"64 kbps", 64); + m_bitrate_list.emplace_back(L"80 kbps", 80); + m_bitrate_list.emplace_back(L"96 kbps", 96); + m_bitrate_list.emplace_back(L"128 kbps", 128); + m_bitrate_list.emplace_back(L"160 kbps", 160); + m_bitrate_list.emplace_back(L"192 kbps", 192); + m_bitrate_list.emplace_back(L"224 kbps", 224); + m_bitrate_list.emplace_back(L"256 kbps", 256); + m_bitrate_list.emplace_back(L"320 kbps", 320); + m_quality_list.emplace_back(L"10 %", 10); + m_quality_list.emplace_back(L"25 %", 25); + m_quality_list.emplace_back(L"50 %", 50); + m_quality_list.emplace_back(L"75 %", 75); + m_quality_list.emplace_back(L"90 %", 90); + m_quality_list.emplace_back(L"98 %", 98); + + if (m_encode_para.cbr) + CheckDlgButton(IDC_CBR_RADIO, TRUE); + else + CheckDlgButton(IDC_CBR_RADIO2, TRUE); + + int index{}; + for (size_t i{}; i < m_bitrate_list.size(); ++i) + { + m_bitrate_combo.AddString(m_bitrate_list[i].first.c_str()); + if (m_bitrate_list[i].second >= m_encode_para.cbr_bitrate) + index = i; // 选择最接近的项目 + } + m_bitrate_combo.SetCurSel(index); + for (size_t i{}; i < m_quality_list.size(); ++i) + { + m_vbr_quality_combo.AddString(m_quality_list[i].first.c_str()); + if (m_quality_list[i].second >= m_encode_para.vbr_quality) + index = i; // 选择最接近的项目 + } + m_vbr_quality_combo.SetCurSel(index); + + SetControlEnable(); + + return TRUE; // return TRUE unless you set the focus to a control + // 异常: OCX 属性页应返回 FALSE } void CWmaEncodeCfgDlg::OnCbnSelchangeBitrateCombo() { - // TODO: 在此添加控件通知处理程序代码 - CString str; - m_bitrate_combo.GetLBText(m_bitrate_combo.GetCurSel(), str); - m_encode_para.cbr_bitrate = _ttoi(str); + // TODO: 在此添加控件通知处理程序代码 + int index = m_bitrate_combo.GetCurSel(); + if (index >= 0 && index < static_cast(m_bitrate_list.size())) + m_encode_para.cbr_bitrate = m_bitrate_list[index].second; } void CWmaEncodeCfgDlg::OnCbnSelchangeVbrQualityCombo() { - // TODO: 在此添加控件通知处理程序代码 - CString str; - m_vbr_quality_combo.GetLBText(m_vbr_quality_combo.GetCurSel(), str); - m_encode_para.vbr_quality = _ttoi(str); + // TODO: 在此添加控件通知处理程序代码 + int index = m_vbr_quality_combo.GetCurSel(); + if (index >= 0 && index < static_cast(m_quality_list.size())) + m_encode_para.vbr_quality = m_quality_list[index].second; } void CWmaEncodeCfgDlg::OnBnClickedCbrRadio() { - // TODO: 在此添加控件通知处理程序代码 - m_encode_para.cbr = true; - SetControlEnable(); + // TODO: 在此添加控件通知处理程序代码 + m_encode_para.cbr = true; + SetControlEnable(); } void CWmaEncodeCfgDlg::OnBnClickedCbrRadio2() { - // TODO: 在此添加控件通知处理程序代码 - m_encode_para.cbr = false; - SetControlEnable(); + // TODO: 在此添加控件通知处理程序代码 + m_encode_para.cbr = false; + SetControlEnable(); } diff --git a/MusicPlayer2/WmaEncodeCfgDlg.h b/MusicPlayer2/WmaEncodeCfgDlg.h index f1c90ca91..5f010dd3e 100644 --- a/MusicPlayer2/WmaEncodeCfgDlg.h +++ b/MusicPlayer2/WmaEncodeCfgDlg.h @@ -1,39 +1,44 @@ #pragma once +#include "BaseDialog.h" #include "IPlayerCore.h" // CWmaEncodeCfgDlg 对话框 -class CWmaEncodeCfgDlg : public CDialog +class CWmaEncodeCfgDlg : public CBaseDialog { - DECLARE_DYNAMIC(CWmaEncodeCfgDlg) + DECLARE_DYNAMIC(CWmaEncodeCfgDlg) public: - CWmaEncodeCfgDlg(CWnd* pParent = nullptr); // 标准构造函数 - virtual ~CWmaEncodeCfgDlg(); + CWmaEncodeCfgDlg(CWnd* pParent = nullptr); // 标准构造函数 + virtual ~CWmaEncodeCfgDlg(); // 对话框数据 #ifdef AFX_DESIGN_TIME - enum { IDD = IDD_WMA_ENCODE_CFG_DIALOG }; + enum { IDD = IDD_WMA_ENCODE_CFG_DIALOG }; #endif - WmaEncodePara m_encode_para; + WmaEncodePara m_encode_para; protected: - //控件变量 - CButton m_cbr_radio; - CButton m_vbr_radio; - CComboBox m_bitrate_combo; - CComboBox m_vbr_quality_combo; + //控件变量 + CComboBox m_bitrate_combo; + CComboBox m_vbr_quality_combo; - void SetControlEnable(); + vector>m_bitrate_list; + vector>m_quality_list; - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 + void SetControlEnable(); - DECLARE_MESSAGE_MAP() + virtual CString GetDialogName() const override; + virtual bool IsRememberDialogSizeEnable() const override { return false; }; + virtual bool InitializeControls() override; + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 + + DECLARE_MESSAGE_MAP() public: - virtual BOOL OnInitDialog(); - afx_msg void OnCbnSelchangeBitrateCombo(); - afx_msg void OnCbnSelchangeVbrQualityCombo(); - afx_msg void OnBnClickedCbrRadio(); - afx_msg void OnBnClickedCbrRadio2(); + virtual BOOL OnInitDialog(); + afx_msg void OnCbnSelchangeBitrateCombo(); + afx_msg void OnCbnSelchangeVbrQualityCombo(); + afx_msg void OnBnClickedCbrRadio(); + afx_msg void OnBnClickedCbrRadio2(); }; diff --git a/MusicPlayer2/crashtool.cpp b/MusicPlayer2/crashtool.cpp index ca84cf711..e427a7b65 100644 --- a/MusicPlayer2/crashtool.cpp +++ b/MusicPlayer2/crashtool.cpp @@ -35,7 +35,7 @@ class CCrashReport return; } - m_dumpFile = szDumpFile; + m_dumpFile = szDumpFile; MINIDUMP_EXCEPTION_INFORMATION ExpParam; ExpParam.ThreadId = ::GetCurrentThreadId(); @@ -47,30 +47,28 @@ class CCrashReport ::CloseHandle(hDumpFile); } - void ShowCrashInfo() - { - //写入错误日志 - CString log_info = CCommon::LoadTextFormat(IDS_CRASH_ERROR_LOG_INFO, { m_dumpFile }); - theApp.WriteLog(wstring(log_info)); - - //显示错误信息对话框 - CMessageDlg dlg; - dlg.SetWindowTitle(CCommon::LoadText(IDS_ERROR1)); - dlg.SetInfoText(CCommon::LoadText(IDS_ERROR_MESSAGE)); - - CString info = CCommon::LoadTextFormat(IDS_CRASH_INFO, { m_dumpFile }); - info += _T("\r\n"); - info += theApp.GetSystemInfoString(); - dlg.SetMessageText(info); - - //设置图标 - HICON hIcon; - HRESULT hr = LoadIconWithScaleDown(NULL, IDI_ERROR, theApp.DPI(32), theApp.DPI(32), &hIcon); - if (SUCCEEDED(hr)) - dlg.SetMessageIcon(hIcon); - - dlg.DoModal(); - } + void ShowCrashInfo() + { + // 写入错误日志 + wstring log_info = theApp.m_str_table.LoadTextFormat(L"LOG_CRASH_ERROR", { m_dumpFile }); + theApp.WriteLog(log_info); + + // 显示错误信息对话框 + // 之后应改用独立的对话框,不依赖CMessageDlg + CMessageDlg dlg(L"CrashDlg"); + dlg.SetWindowTitle(theApp.m_str_table.LoadText(L"TITLE_CRASH_REPOART")); + dlg.SetInfoText(theApp.m_str_table.LoadText(L"TXT_CRASH_REPOART_ERROR_MESSAGE")); + wstring info = theApp.m_str_table.LoadTextFormat(L"TXT_CRASH_REPOART_CRASH_INFO", { m_dumpFile, theApp.GetSystemInfoString() }); + dlg.SetMessageText(info); + + //设置图标(此功能已从CMessageDlg移除) + // HICON hIcon; + // HRESULT hr = LoadIconWithScaleDown(NULL, IDI_ERROR, theApp.DPI(32), theApp.DPI(32), &hIcon); + // if (SUCCEEDED(hr)) + // dlg.SetMessageIcon(hIcon); + + dlg.DoModal(); + } private: void GetAppPath() @@ -99,7 +97,7 @@ class CCrashReport wchar_t m_szDumpFilePath[MAX_PATH]; wchar_t m_szModuleFileName[MAX_PATH]; - CString m_dumpFile; + CString m_dumpFile; }; namespace CRASHREPORT @@ -109,7 +107,7 @@ namespace CRASHREPORT ::SetErrorMode(0); //使用默认的 CCrashReport cr; cr.CreateMiniDump(pEP); - cr.ShowCrashInfo(); + cr.ShowCrashInfo(); return EXCEPTION_CONTINUE_SEARCH; } diff --git a/MusicPlayer2/language/English.ini b/MusicPlayer2/language/English.ini new file mode 100644 index 000000000..4d44235ff --- /dev/null +++ b/MusicPlayer2/language/English.ini @@ -0,0 +1,1470 @@ +[general] +BCP_47 = "en-US" +DISPLAY_NAME = "English" +TRANSLATOR = "MusicPlayer2" +DEFAULT_FONT = "Segoe UI" + +[text] +# User UI String +TXT_UI_NAME_DEFAULT = "UI <%1%>" +TXT_UI_NAME_MINI_DEFAULT = "Mini mode <%1%>" +TXT_UI_NAME_SIMPLE_UI = "Simple UI" +TXT_UI_NAME_GROOVE_MUSIC_STYLE = "Groove Style" +TXT_UI_LYRIC_SHOW = "Lyric Show" +TXT_UI_FORMAT = "Format" + +# Column Header / Tab title +TXT_SERIAL_NUMBER = "No." +TXT_ITEM = "Item" +TXT_VALUE = "Value" +TXT_FILE_NAME = "File name" +TXT_FILE_PATH = "File path" +TXT_PATH = "Path" +TXT_TITLE = "Title" +TXT_TRACK = "Track" +TXT_NUM_OF_TRACK = "Number of Tracks" +TXT_LENGTH = "Duration" +TXT_TOTAL_LENGTH = "Total Duration" +TXT_TRACK_NUM = "Track number" +TXT_LAST_PLAYED_TRACK = "Last played track" +TXT_LAST_PLAYED_TIME = "Last played time" + +TXT_FOLDER = "Folder" +TXT_PLAYLIST = "Playlist" +TXT_ARTIST = "Artist" +TXT_ALBUM = "Album" +TXT_GENRE = "Genre" +TXT_YEAR = "Year" +TXT_FILE_TYPE = "File Type" +TXT_BITRATE = "Bit rate" +TXT_RATING = "Rating" +TXT_ALL_TRACKS = "All tracks" +TXT_RECENT_PLAYED = "Recently played" +TXT_FOLDER_EXPLORE = "Folder explore" + +# MessageBox +MSG_APP_RUNING_INFO = "MusicPlayer2 is still running, please wait for the process to exit, or end the process through the task manager." +MSG_WAIT_AND_RETRY = "Please wait and try again after the current operation is completed." +MSG_UNICODE_WARNING = "The content to be saved contains Unicode characters that will be lost if saved in ANSI format. If you want to keep these characters, select Save As UTF-8 format. Are you sure you want to save it?" +MSG_SERIALIZE_ERROR = "A serialization exception occurred while reading the data file \"<%1%>\", the exception type: Carchiveexception,m_cause = <%2%>. It may be caused by the corruption of data file or a version mismatch." +MSG_BASS_VERSION_WARNING = "The bass.dll file version does not match, the version is <%1%>, and the expected version is <%2%>. The mismatched version may cause an exception when playing. Do you still want to continue?" +MSG_SCI_NOT_LOADED_ERROR = "This dialog box cannot be opened because SciLexer.dll is not loaded correctly, please check whether SciLexer.dll is missing!" +MSG_MCI_NO_THIS_FUNCTION_WARNING = "This function cannot be used in the MCI kernel!" +MSG_FFMPEG_NO_THIS_FUNCTION_WARNING = "This function is not currently supported in the FFMPEG kernel!" +MSG_UPDATE_CHECK_FAILED = "Check for update failed, please check your network connection!" +MSG_UPDATE_CHECK_ERROR = "Check for update failed and get the wrong information from the remote update file, please contact the author!\r\n<%1%>" +MSG_UPDATE_AVLIABLE = "New version V<%1%> detected, do you want to go to update?" +MSG_UPDATE_AVLIABLE_2 = "New version V<%1%> detected, update content: \r\n<%2%>\r\ndo you want to go to update?" +MSG_UPDATE_ALREADY = "Already updated to the latest version." +MSG_SHORTCUT_INQUARY_FIRST = "You may be running this program for the first time, do you want to create a shortcut to the program on the desktop?" +MSG_SHORTCUT_INQUARY_DESKTOP = "Do you want to create a desktop shortcut?" +MSG_SHORTCUT_INQUARY_MINIMODE = "This command will create a mini mode shortcut in the program directory. The player will always be launched in mini mode by this shortcut. Do you want to create a mini mode shortcut?" +MSG_SHORTCUT_INQUARY_PLAY_CONTROL = "This command will create the playback control shortcuts in the directory where the program is located. When the player is running, you can control the playback of the music through these shortcuts. You can also pin them to the taskbar. Do you want to create the playback control shortcuts?" +MSG_SHORTCUT_CREATED = "A shortcut to the program has been created under the \"<%1%>\" path." +MSG_SHORTCUT_FAILED = "Shortcut create failed!" +MSG_DELETE_SEL_AUDIO_FILE_INQUARY = "Are you sure you want to delete the selected <%1%> songs?" +MSG_DELETE_INNER_COVER_INQUERY = "The current album cover is embedded in the audio file and cannot be restored after deletion. Are you sure you want to delete the embedded album cover?" +MSG_DELETE_SINGLE_FILE_INQUARY = "Are you sure you want to delete the file \"<%1%>\"?" +MSG_DELETE_FILE_FAILED = "Unable to delete file!" +MSG_FILE_WRITE_FAILED = "Unable to write to file!" +MSG_COPY_CLIPBOARD_FAILED = "Copy to clipboard failed!" +MSG_COPY_CLIPBOARD_ALL_LYRIC = "All lyrics have been copied to the Clipboard." +MSG_NO_MIDI_SF2_WARNING = "You are playing MIDI music, but you will not hear any sound because the MIDI sound font is not loaded correctly. Please select the correct MIDI sound font in the menu \"Tools\"--\"options\"--\"General settings\"-- \"MIDI sound font path\", and select the correct MIDI sound font path. Click \"Cancel\" will no longer prompt." +MSG_LYRIC_SAVE_INRUARY = "The lyrics have changed, do you want to save them?" +MSG_LYRIC_SAVE_FAILED = "The lyric failed to save, please check if the target folder has write permission!" +MSG_LYRIC_FOLDER_NOT_EXIST = "The lyrics folder does not exist, please reset the lyrics folder!" +MSG_PLAYLIST_REMOVE_SONGS = "Complete, <%1%> item(s) removed." +MSG_PLAYLIST_CLEAR_WARNING = "Are you sure you want to clear the playlist?" +MSG_REMOVE_FAVOURITE_WARNING = "Canceling \"My Favourite\" will remove the track being played from the current playlist. Do you want to continue?" +MSG_PLAYLIST_NAME_EMPTY_WARNING = "The playlist name cannot be empty!" +MSG_FILE_NAME_INVALID_WARNING = "The following characters cannot be included in the name:\r\n\\\"/:*?<>|" +MSG_PLAYLIST_EXIST_WARNING = "Playlist \"<%1%>\" already exists!" +MSG_FILE_EXIST_IN_PLAYLIST = "The file(s) already exists in the playlist." +MSG_PLAYLIST_REMANE_FAILED = "Playlist rename failed!" +MSG_PLAYLIST_ADD_SONGS_FAILED = "Add failed, playlist \"<%1%>\" does not exist!" +MSG_PLAYLIST_FIX_ERROR_PATH_INQUARY = "This feature will check for tracks that do not exist in the playlist and fix the incorrect path by looking for a match item in the media library. Do you want to fix the incorrect path in the playlist?" +MSG_PLAYLIST_FIX_ERROR_PATH_COMPLETE = "Finished, <%1%> incorrect path(s) have been fixed." +MSG_HIDE_MENU_BAR_INFO = "Tip: After you hide the menu bar, you can right-click the window title bar, or click the main menu \"≡\" button on the top right, and select \"View\" - \"Show Menu Bar\" in the pop-up menu to re-display the menu bar. \r\n Click \"Cancel\" to no longer prompt." +MSG_CANNOT_FIND_ARTIST_WARNING = "Could not find artist <%1%> in the media library!" +MSG_CANNOT_FIND_ALBUM_WARNING = "Could not find album <%1%> in the media library!" + +MSG_NETWORK_CONNECTION_FAILED = "Network connection failed or timed out!" +MSG_NETWORK_CANNOT_FIND_THIS_SONG = "This song could not be found!" +MSG_NETWORK_LYRIC_DOWNLOAD_FAILED = "Lyrics download failed!" +MSG_NETWORK_SONG_NO_LYRIC = "The song has no lyrics!" +MSG_NETWORK_DOWNLOAD_COMPLETE = "Download complete." +MSG_NETWORK_SEARCH_FAILED = "Search failed, please check your network connection!" +MSG_NETWORK_SEARCH_TIME_OUT = "Search Timeout!" +MSG_NETWORK_COVER_DOWNLOAD_FAILED = "Album cover download failed, please check your network connection!" +MSG_LYRIC_OVERWRITE_INQUARY = "The lyrics file already exists, do you want to replace it?" +MSG_LYRIC_DOWNLOAD_COMPLETE_SAVED = "Lyrics download completed, saved as \"<%1%>\"." + +# error.log +LOG_RESTART_EXIT = "The program has been restarted by Windows Restartmanager, restart parameters: <%1%>, the program has exited." +LOG_CRASH_ERROR = "The program crashed, the dump file has been saved to \"<%1%>\"." +LOG_BASS_FORMAT_CONVERT_ERROR = "Error converting file \"<%1%>\" to <%2%> using BASS core, BASS error code: <%3%>." +LOG_BASS_ERROR = "An error occurred with the Bass Audio library, error code: <%1%>. File name: <%2%>" +LOG_SF2_LOAD_FAILED = "Sound font \"<%1%>\" load failed!" +LOG_MCI_INIT_FAILED = "MCI initialization failed!" +LOG_FFMPEG_INIT_FAILED = "FFMPEG kernel initialization failed!" +LOG_STRING_TABLE_UNKNOWN_KEY = "String table error, the program attempted to read the following non-existent key: " +LOG_STRING_TABLE_PARA_ERROR = "String table error, missing required placeholders when formatting the following key: " + +# UI button tooltip +UI_TIP_BTN_PLAY = "Play" +UI_TIP_BTN_PAUSE = "Pause" +UI_TIP_BTN_PLAY_PAUSE = "Play/Pause" +UI_TIP_BTN_PREVIOUS = "Previous" +UI_TIP_BTN_NEXT = "Next" +UI_TIP_BTN_STOP = "Stop" +UI_TIP_BTN_MINIMODE = "Mini mode" +UI_TIP_BTN_MINIMODE_RTN = "Back to normal mode" +UI_TIP_BTN_PLAYLIST_SHOW_HIDE = "Show/hide playlist" +UI_TIP_BTN_PROPETRY = "Song Info" +UI_TIP_BTN_LOCATE_TO_CURRENT = "Locate the track is playing" +UI_TIP_BTN_TRANSLATION = "Show lyric translation" +UI_TIP_BTN_SWITCH_UI = "Switch UI" +UI_TIP_BTN_SOUND_EFFECT_SETTING = "Sound effect settings" +UI_TIP_BTN_OPTION_SETTING = "Settings" +UI_TIP_BTN_CLOSE = "Close" +UI_TIP_BTN_FIND_SONGS = "Find songs" +UI_TIP_BTN_FULL_SCREEN = "Full Screen" +UI_TIP_BTN_FULL_SCREEN_EXIT = "Exit Full Screen" +UI_TIP_BTN_MAIN_MENU = "Main Menu" +UI_TIP_BTN_MEDIA_LIB = "Open media library" +UI_TIP_BTN_FAVOURITE = "Add to \"My Favourite\"" +UI_TIP_BTN_DESKTOP_LYRIC = "Show desktop lyric" +UI_TIP_BTN_AB_REPEAT = "AB Repeat" +UI_TIP_BTN_MINIMIZE = "Minimize" +UI_TIP_BTN_MAXIMIZE = "Maximize" +UI_TIP_BTN_RESTORE = "Restore" +UI_TIP_BTN_ADD_TO_PLAYLIST = "Add to playlist" +UI_TIP_BTN_SWITCH_DISPLAY = "Switch display" +UI_TIP_BTN_DARK_LIGHT_TO_DARK_MODE = "Switch to dark mode" +UI_TIP_BTN_DARK_LIGHT_TO_LIGHT_MODE = "Switch to light mode" +UI_TIP_BTN_PLAYLIST_MENU = "Playlist menu" +UI_TIP_BTN_RECENT_FOLDER_OR_PLAYLIST = "Recently played folder/playlist" + +UI_TIP_SEEK_TO_MINUTE_SECOND = "Seek to <%1%> minute <%2%> second" +UI_TIP_VOLUME_MOUSE_WHEEL_ADJUST = "Use mouse wheel to adjust volume" +UI_TIP_COVER_INNER = "Album cover: Inner image\r\nImage format: " +UI_TIP_COVER_OUT = "Album cover: External image\r\nPath: <%1%>" +UI_TIP_COVER_MINI_MODE = "Now Playing: <%1%>\r\nTitle: <%2%>\r\nArtist: <%3%>\r\nAlbum: <%4%>" + +UI_TIP_BTN_DESKTOP_LYRIC_LOCK = "Lock desktop lyric" +UI_TIP_BTN_DESKTOP_LYRIC_UNLOCK = "Unlock desktop lyric" +UI_TIP_BTN_DESKTOP_LYRIC_CLOSE = "Close desktop lyric window" +UI_TIP_BTN_DESKTOP_LYRIC_DOUBLE_LINE = "Lyrics displayed in &double line" +UI_TIP_BTN_DESKTOP_LYRIC_BACKGROUND_PENETRATE = "Lyrics background penetrate" +UI_TIP_BTN_DESKTOP_LYRIC_DEFAULT_STYLE = "Default style" +UI_TIP_BTN_DESKTOP_LYRIC_FORWARD = "Lyrics 0.5 Seconds in Advance" +UI_TIP_BTN_DESKTOP_LYRIC_DELAY = "Lyrics 0.5 Seconds Delayed" + +UI_TIP_REPEAT_MODE = "Repeat mode" +UI_TIP_REPEAT_OREDE = "Play in order" +UI_TIP_REPEAT_SHUFFLE = "Play shuffle" +UI_TIP_REPEAT_RANDOM = "Play random" +UI_TIP_REPEAT_PLAYLIST = "Loop playlist" +UI_TIP_REPEAT_TRACK = "Loop track" +UI_TIP_REPEAT_ONCE = "Play once" + +# Title +UI_TITLE_DEBUG_MODE = "DEBUG Mode" +UI_TITLE_EXCLUSIVE_MODE = "Exclusive mode" + +# UI_TXT* is used directly on the UI, please pay attention to the length +UI_TXT_BTN_TRANSLATE = "Tr" +UI_TXT_BTN_DESKTOP_LYRIC = "Lrc" +UI_TXT_VOLUME = "Volume: <%1%><%2%>" +UI_TXT_VOLUME_MUTE = "Mute" +UI_TXT_PLAYSTATUS_STOPED = "Stopped" +UI_TXT_PLAYSTATUS_PAUSED = "Paused" +UI_TXT_PLAYSTATUS_PLAYING = "Now Playing" +UI_TXT_PLAYSTATUS_ERROR = "Play error" +UI_TXT_PLAYSTATUS_ERROR_2 = "Play error: <%1%>" +UI_TXT_PLAYSTATUS_ERROR_FILE_NOT_EXIST = "File does not exist" +UI_TXT_PLAYSTATUS_ERROR_FILE_CANNOT_BE_OPEND = "File cannot be opened" +UI_TXT_PLAYSTATUS_ERROR_CORE_BASS = "Error code(<%1%>)" +UI_TXT_NEXT_TRACK = "Next track: " +UI_TXT_NEXT_TRACK_NONE = "None" +UI_TXT_NEXT_TRACK_RANDOM = "Random track" +UI_TXT_PLAYLIST_INIT_INFO = "Find <%1%> songs, reading audio file information, please wait ..." +UI_TXT_MEDIA_LIB_UPDATING_INFO = "Updating media library... <%1%> tracks updated. <%2%>%" +UI_TXT_AB_REPEAT_A_SELECTED = "AB Repeat: Point A selected (<%1%>)" +UI_TXT_AB_REPEAT_ON = "AB Repeat: On (<%1%>-<%2%>)" +UI_TXT_CHANNEL_MONO = "Mono" +UI_TXT_CHANNEL_STEREO = "Stereo" +UI_TXT_CHANNEL_5_1 = "5.1 Channels" +UI_TXT_CHANNEL_7_1 = "7.1 Channels" +UI_TXT_CHANNEL_OTHER = "<%1%> Channels" +UI_TXT_SF2_NAME_NONE = "" +UI_TXT_SF2_NAME_FAILDE = "" + +UI_TXT_PLAYLIST = "Playlist:" +UI_TXT_FOLDER = "Folder:" +UI_TXT_BTN_MEDIA_LIB = "Media Library..." + +UI_LYRIC_EMPTY_LINE = "..." +UI_LYRIC_EMPTY_LINE_2 = "Music ..." +UI_LYRIC_MUSIC_SYMBOL = "♪♪♪" +UI_LYRIC_NONE = "The current song has no lyrics" +UI_LYRIC_NO_TRACKS_TIP = "There are currently no tracks playing, you can:\r\nPress <%1%> to open playlist and add songs to the playlist\;\r\nClick \"Main Menu\" > \"File\" > \"Open File\" or shortcut <%2%> to open an audio file\;\r\nClick \"Main Menu\" > \"File\" > \"Open Folder\" or shortcut <%3%> to open and play a folder\;\r\nPress <%4%> to open the media library and find the song you want to play in the media library." +UI_PLAYLIST_EMPTY_INFO = "The playlist is empty." + +# Here is a version of the menu text without the mnemonic key +UI_TXT_MENU_FILE = "File" +UI_TXT_MENU_PLAY_CONTROL = "Play Control" +UI_TXT_MENU_PLAYLIST = "Playlist" +UI_TXT_MENU_LYRICS = "Lyrics" +UI_TXT_MENU_VIEW = "View" +UI_TXT_MENU_TOOLS = "Tool" +UI_TXT_MENU_HELP = "Help" +UI_TXT_PLAYLIST_TOOLBAR_ADD = "Add" +UI_TXT_PLAYLIST_TOOLBAR_DELETE = "Delete" +UI_TXT_PLAYLIST_TOOLBAR_SORT = "Sort" +UI_TXT_PLAYLIST_TOOLBAR_LIST = "Playlist" +UI_TXT_PLAYLIST_TOOLBAR_EDIT = "Edit" +UI_TXT_PLAYLIST_TOOLBAR_FOLDER = "Folder" +UI_TXT_PLAYLIST_TOOLBAR_LOCATE = "Locate" + +# Values below should not be repeated +TXT_PLAYLIST_NAME_DEFAULT = "[Default]" +TXT_PLAYLIST_NAME_FAVOURITE = "[My Favourite]" +TXT_PLAYLIST_NAME_TEMP = "[Temporary playlist]" +TXT_EMPTY_FILE_NAME = "" +TXT_EMPTY_TITLE = "" +TXT_EMPTY_ARTIST = "" +TXT_EMPTY_ALBUM = "" +TXT_EMPTY_YEAR = "" +TXT_EMPTY_GENRE = "" +TXT_EMPTY_RATED = "" +TXT_MULTI_VALUE = "" +TXT_CLASSIFY_OTHER = "" +TXT_INNER_LYRIC = "" +TXT_INNER_COVER = "" + +# File type description +TXT_FILE_TYPE_BASE = "Basic audio formats" +TXT_FILE_TYPE_FFMPEG_USER_DEFINE = "Other audio formats" +TXT_FILE_TYPE_UNKNOWN = "Unknown" +TXT_FILE_TYPE_MP3 = "MPEG Audio Layer 3" +TXT_FILE_TYPE_MP1_MP2 = "MPEG Audio" +TXT_FILE_TYPE_WMA = "Windows Media Audio" +TXT_FILE_TYPE_ASF = "Advanced Streaming Format" +TXT_FILE_TYPE_WAV = "WAV Audio file" +TXT_FILE_TYPE_OGG_OGA = "OGG Vorbis Audio file" +TXT_FILE_TYPE_M4A_MP4 = "MPEG-4 Audio file" +TXT_FILE_TYPE_APE = "Monkey's Audio (APE)" +TXT_FILE_TYPE_ACC = "Advanced Audio Coding (AAC)" +TXT_FILE_TYPE_AIF_AIFF = "Audio Interchange File" +TXT_FILE_TYPE_CDA = "CD Audio file (CDA)" +TXT_FILE_TYPE_PLAYLIST = "MusicPlayer2 Playlist" +TXT_FILE_TYPE_M3U = "M3U Playlist" +TXT_FILE_TYPE_M3U8 = "M3U8 Playlist" +TXT_FILE_TYPE_CUE = "CUE Sheets" +TXT_FILE_TYPE_OTHER = "<%1%> Audio file" + +# CAcceleratorRes / Used to assemble shortcut key strings +TXT_SHORCUT_LEFT = "Left" +TXT_SHOTCUT_RIGHT = "Right" +TXT_SHOTCUT_UP = "Up" +TXT_SHOTCUT_DOWN = "Down" +TXT_SHOTCUT_SPACE = "Space" + +# BTN +TXT_OK = "OK" +TXT_CANCEL = "Cancel" +TXT_CLOSE = "Close" +TXT_APPLY = "Apply" + +# CFolderBrowserDlg / CFolderPickerDialog / CBrowseEdit +TITLE_FOLDER_BROWSER_SONG_SOURCE = "Select the audio folder" +TITLE_FOLDER_BROWSER_COPY_TARGET = "Select the copy destination folder" +TITLE_FOLDER_BROWSER_MOVE_TARGET = "Select the move destination folder" +TITLE_FOLDER_BROWSER_OUTPUT_FOLDER = "Select output folder" +TXT_FOLDER_BROWSER_INCLUDE_SUB_DIR = "Include subfolders" +MSG_FOLDER_BROWSER_INVALID_DIR_WARNING = "Invalid directory, please reselect!" + +# CommonDialogMgr +TITLE_FILE_DELETE = "Delete" +TITLE_FILE_COPY = "Copy" +TITLE_FILE_MOVE = "Move" + +# CFileDialog +TXT_SAVE_AS_ANSI = "Save as ANSI format" +TXT_SAVE_AS_UTF8 = "Save as UTF8 format" + +# filter / FilterHelper.cpp +TXT_FILTER_ALL_FILES = "All file" +TXT_FILTER_ALL_SUPPORTED_AUDIO_FORMAT = "All supported audio formats" +TXT_FILTER_LYRIC_FILE = "Lyric file" +TXT_FILTER_TXT_FILE = "Text file" +TXT_FILTER_SF2_FILE = "Sound font files" +TXT_FILTER_CSV_FILE = "Csv Files" +TXT_FILTER_ALL_SUPPORTED_PLAYLIST_FILE = "All surpported playlist files" +TXT_FILTER_PLAYLIST_FILE = "MusicPlayer2 playlist files" +TXT_FILTER_M3U_FILE = "m3u playlist files" +TXT_FILTER_M3U8_FILE = "m3u8 playlist files" +TXT_FILTER_IMAGE_FILE = "Image files" + +# CSearchEditCtrl +TIP_SEARCH_EDIT_CLEAN = "Clear search results" +TIP_SEARCH_EDIT_INPUT = "Input the keyword to search" +TXT_SEARCH_PROMPT = "Type here to search" +TXT_SEARCH_PROMPT_ARTIST = "Type here to search artist" +TXT_SEARCH_PROMPT_ALBUM = "Type here to search album" +TXT_SEARCH_PROMPT_GENRE = "Type here to search genre" +TXT_SEARCH_PROMPT_YEAR = "Type here to search year" +TXT_SEARCH_PROMPT_FILE_TYPE = "Type here to search file type" +TXT_SEARCH_PROMPT_BITRATE = "Type here to search bitrate" +TXT_SEARCH_PROMPT_FORDER = "Type here to search folder" + +# CPlayListCtrl +TXT_PLAYLIST_CTRL_NO_RESULT_TO_SHOW = "No results to be shown" + +# CBrowseEdit +TITLE_BROWSE_EDIT_SET_MULTI_OUT_ALBUM_COVER_FILE_NAME = "Set multiple external album cover file names" +TITLE_BROWSE_EDIT_SET_MULTI_ARTIST_SPLIT_EXT = "Set multiple artist recognition exceptions" +TXT_BROWSE_EDIT_EDIT = "Edit..." +TXT_BROWSE_EDIT_BROWSE = "Browse..." + +# IDD_FIND_DIALOG +TITLE_FIND = "Find File" +TXT_FIND_KEY_WORD_INPUT = "Enter the keyword to find:" +TXT_FIND_FIND = "Find" +TXT_FIND_FIND_RANGE = "Find Range" +TXT_FIND_CURRENT_PLAYLIST = "Find the current playlist" +TXT_FIND_MEDIA_LIB = "Find entire media library" +TXT_FIND_OPT = "Find options" +TXT_FIND_OPT_FILE_NAME = "Find file name" +TXT_FIND_OPT_TITLE = "Find title" +TXT_FIND_OPT_ARTIST = "Find artist" +TXT_FIND_OPT_ALBUM = "Find album" +TXT_FIND_RESULT_NONE = "No results found!" +TXT_FIND_RESULT_LAST = "Last find results: " +TXT_FIND_RESULT_CURRENT = "Find result: " +TXT_FIND_RESULT_INFO = "Find keyword <%1%>, <%2%> results." +TXT_FIND_PLAY_SELECTED = "Play the selected track" + +# IDD_LYRIC_EDIT_DIALOG +TITLE_LYRIC_EDIT = "Edit Lyric" +TXT_LYRIC_EDIT_LYRIC_PATH = "Lyric path:" +MSG_LYRIC_EDIT_STRING_REPLACE_COMPLETE = "Replace complete with <%1%> strings." +MSG_LYRIC_EDIT_STRING_CANNOT_FIND = "Can't find \"<%1%>\"" +TXT_LYRIC_EDIT_TOTAL_CHARACTER = "<%1%> characters" +TXT_LYRIC_EDIT_MODIFIED = "Modified" +TXT_LYRIC_EDIT_UNMODIFIED = "Unmodified" +TXT_LYRIC_EDIT_ENCODE_FORMAT = "Encode format: <%1%>" +TXT_LYRIC_EDIT_UTF8NOBOM = "UTF8 no BOM" +TIP_LYRIC_EDIT_INSERT_TIME_TAG = "Insert time tag" +TIP_LYRIC_EDIT_REPLACE_TIME_TAG = "Replace time tag" +TIP_LYRIC_EDIT_DELETE_TIME_TAG = "Delete time tag" +TIP_LYRIC_EDIT_SAVE = "Save" +TIP_LYRIC_EDIT_PLAY_PAUSE = "Play/Pause" +TIP_LYRIC_EDIT_REWIND = "Rewind" +TIP_LYRIC_EDIT_FAST_FOWARD = "Fast forward" +TIP_LYRIC_EDIT_FIND = "Find" +TIP_LYRIC_EDIT_REPLACE = "Replace" +TIP_LYRIC_EDIT_SEEK_TO_LINE = "Seek to current line" + +# IDD_PROPERTY_PARENT_DIALOG +TITLE_PROPERTY_PARENT = "Properties" +TITLE_PROPERTY_PARENT_BATCH = "Properties (<%1%> Files)" +TXT_PROPERTY_PARENT_PREVIOUS = "Previous" +TXT_PROPERTY_PARENT_NEXT = "Next" +TXT_PROPERTY_PARENT_SAVE_TO_FILE = "Save to file" +MSG_PROPERTY_PARENT_TAG_BATCH_EDIT_SAVE_INFO = "Saved to <%1%> file(s)." +# IDD_PROPERTY_DIALOG +TITLE_PROPERTY_DLG = "File Properties" +TXT_PROPERTY_DLG_FILE_INFO = "File information" +TXT_PROPERTY_DLG_FILE_NAME = "File name:" +TXT_PROPERTY_DLG_FILE_PATH = "File path:" +TXT_PROPERTY_DLG_FILE_TYPE = "File type:" +TXT_PROPERTY_DLG_FILE_DURATION = "Duration:" +TXT_PROPERTY_DLG_FILE_DURATION_UNKNOWN = "Song duration not obtained" +TXT_PROPERTY_DLG_FILE_SIZE = "File size:" +TXT_PROPERTY_DLG_FILE_BIT_RATE = "Bit rate:" +TXT_PROPERTY_DLG_FILE_CHANNELS = "Channels:" +TXT_PROPERTY_DLG_FILE_FREQ = "Frequency:" +TXT_PROPERTY_DLG_FILE_BIT_DEPTH = "Bit depth:" +TXT_PROPERTY_DLG_FILE_BIT_DEPTH_UNDEFINED = "Undefined" +TXT_PROPERTY_DLG_FILE_LRC_FILE = "Lyric file:" +TXT_PROPERTY_DLG_FILE_LRC_FILE_NO_LINK = "No linked lyric file" +TXT_PROPERTY_DLG_TAG_INFO = "Tag information" +TXT_PROPERTY_DLG_TAG_TITLE = "Title:" +TXT_PROPERTY_DLG_TAG_ARTIST = "Artist:" +TXT_PROPERTY_DLG_TAG_ALBUM = "Album:" +TXT_PROPERTY_DLG_TAG_TRACK = "Track:" +TXT_PROPERTY_DLG_TAG_YEAR = "Year:" +TXT_PROPERTY_DLG_TAG_GENRE = "Genre:" +TXT_PROPERTY_DLG_TAG_COMMENT = "Comment:" +TXT_PROPERTY_DLG_TAG_TYPE = "Tag type: <%1%>" +TXT_PROPERTY_DLG_FROM_FILE_NAME = "Get tag from file name..." +TXT_PROPERTY_DLG_FROM_LRC = "Get tag from lyrics" +MSG_PROPERTY_DLG_NO_LYRICS_FOUND = "No lyrics found!" +TXT_PROPERTY_DLG_FROM_ONLINE = "Get tag online..." +# IDD_PROPERTY_ALBUM_COVER_DIALOG +TITLE_COVER_PROPERTY = "Album cover" +TXT_COVER_PROPERTY_FORMAT = "Album cover format" +TXT_COVER_PROPERTY_WIDTH = "Width" +TXT_COVER_PROPERTY_HEIGHT = "Height" +TXT_COVER_PROPERTY_BPP = "Bits per pixel" +TXT_COVER_PROPERTY_FILE_SIZE = "File size" +TXT_COVER_PROPERTY_BROWSE = "Browse..." +TXT_COVER_PROPERTY_DELETE = "Delete" +TXT_COVER_PROPERTY_SHOW_OUT_COVER = "Show external album cover" +TXT_COVER_PROPERTY_DO_INNER_COVER = "Embed external album cover into the audio file" +# IDD_PROPERTY_ADVANCED_DIALOG +TITLE_ADVANCED_PROPERTY = "Advanced tag info" + +# IDD_LYRIC_DOWNLOAD_DIALOG / IDD_COVER_DOWNLOAD_DIALOG +TXT_LYRIC_DL_TITLE = "Title:" +TXT_LYRIC_DL_SEARCH = "Search" +TXT_LYRIC_DL_ARTIST = "Artist:" +TXT_LYRIC_DL_INFO = "Search results: " +TXT_LYRIC_DL_INFO_SEARCHING = "Searching..." +TXT_LYRIC_DL_INFO_SEARCH_NO_SONG = "Search results: (No songs found)" +TXT_LYRIC_DL_INFO_SEARCH_NO_MATCHED = "Search results: (Seems to no best match for this item)" +TXT_LYRIC_DL_INFO_SEARCH_RELATED = "Search results: (Linked item:<%1%>)" +TXT_LYRIC_DL_INFO_SEARCH_BEST_MATCHED = "Search results: (Best batched item: <%1%>)" +TXT_LYRIC_DL_UNLINK = "Cancel Link" +TXT_LYRIC_DL_OPT = "Download options" +TXT_LYRIC_DL_SEL_DL = "Download selected" +# IDD_COVER_DOWNLOAD_DIALOG +TITLE_COVER_DL = "Download album cover (From NetEase cloud music)" +TXT_COVER_DL_LOCATION_SEL = "Album Cover Save Location:" +TXT_COVER_DL_LOCATION_FOLDER_SONG = "Save to the same directory as the song" +TXT_COVER_DL_LOCATION_FOLDER_COVER = "Save to album cover directory" +# IDD_LYRIC_DOWNLOAD_DIALOG +TITLE_LYRIC_DL = "Lyric download (From NetEase cloud music)" +TXT_LYRIC_DL_WITH_TRANSLATION = "Download translated lyrics (If any)" +TXT_LYRIC_DL_SAVE_ENCODE_SEL = "Saved encoding format:" +TXT_LYRIC_DL_SAVE_DIR_SEL = "Lyrics Save Location:" +TXT_LYRIC_DL_SAVE_DIR_LYRIC = "Save to lyrics directory" +TXT_LYRIC_DL_SAVE_DIR_SONG = "Save to the same directory as the song" +TXT_LYRIC_DL_SEL_SAVE_AS = "Selected save as..." +# CGetTagOnlineDlg +TITLE_GET_TAG_ONLINE = "Get tag information online" +TXT_GET_TAG_ONLINE_GET_THIS = "Get this item" + +# IDD_LYRIC_BATCH_DOWN_DIALOG +TITLE_LYRIC_BDL = "Lyrics batch download (From NetEase cloud music)" +TXT_LYRIC_BDL_DL_OPT = "Download Options" +TXT_LYRIC_BDL_SKIP_ALREADY = "Skip songs that already have lyrics" +TXT_LYRIC_BDL_SAVE_ENCODE_SEL = "Saved encoding format:" +TXT_LYRIC_BDL_WITH_TRANSLATION = "Download translated lyrics (If any)" +TXT_LYRIC_BDL_SAVE_DIR_SEL = "Lyrics Save Location:" +TXT_LYRIC_BDL_SAVE_DIR_LYRIC = "Save to lyrics directory" +TXT_LYRIC_BDL_SAVE_DIR_SONG = "Save to the same directory as the song" +TXT_LYRIC_BDL_SONG_LIST = "Song list:" +TXT_LYRIC_BDL_STATUS = "State" +TXT_LYRIC_BDL_STATUS_DOWNLOADING = "Downloading..." +TXT_LYRIC_BDL_STATUS_SKIPED = "Skipped" +TXT_LYRIC_BDL_STATUS_NETWORK_FAILED = "Network connection failed or timed out" +TXT_LYRIC_BDL_STATUS_CANNOT_FIND_THIS_SONG = "This song could not be found" +TXT_LYRIC_BDL_STATUS_NO_MATCHED_LYRIC = "No matched lyrics" +TXT_LYRIC_BDL_STATUS_DOWNLOAD_FAILED = "Lyrics download failed" +TXT_LYRIC_BDL_STATUS_SONG_NO_LYRIC = "The song has no lyrics" +TXT_LYRIC_BDL_STATUS_ENCODE_WARNING = "Successful, but there are Unicode characters in the lyrics that cannot be converted, it is recommended to save them in UTF-8 format" +TXT_LYRIC_BDL_STATUS_SUCCESSED = "Succeed" +TXT_LYRIC_BDL_STATUS_FILE_WRITE_FAILED = "Unable to write to file" +TXT_LYRIC_BDL_INFO_DOWNLOADING_INFO = "Downloading, <%1%>% completed, please wait..." +TXT_LYRIC_BDL_INFO_COMPLETE = "Lyrics download complete." +TXT_LYRIC_BDL_DL_START = "Start download" + +# IDD_SOUND_EFFECT_DIALOG +TITLE_SOUND_EFFECT = "Sound Effect Settings" +# IDD_EQUALIZER_DIALOG +TITLE_EQ = "Equalizer" +TXT_EQ_ENABLE = "Enable equalizer" +TXT_EQ_PRESET = "Equalizer Presets" +TXT_EQ_NONE = "None" +TXT_EQ_CLASSICAL = "Classical" +TXT_EQ_POP = "Popular" +TXT_EQ_JAZZ = "Jazz" +TXT_EQ_ROCK = "Rock" +TXT_EQ_SOFT = "Soft" +TXT_EQ_BASS = "Heavy bass" +TXT_EQ_ELIMINATE_BASS = "Eliminate bass" +TXT_EQ_WEAKENING_TREBLE = "Weakening treble" +TXT_EQ_USER_DEFINE = "Custom" +TXT_EQ_CHANNEL_SETTING = "Channel Settings" +# IDD_REVERB_DIALOG +TITLE_REVERB = "Reverb" +TXT_REVERB_ENABLE = "Enable reverb" +TXT_REVERB_STRENGTH = "Reverb strength:" +TXT_REVERB_TIME = "Reverb time:" + +# IDD_SUPPORT_FORMAT_DIALOG +TITLE_SUPPORTTED_FORMAT = "Supported Formats" +TXT_SUPPORTTED_FORMAT_CORE_INFO_BASS = "MusicPlayer2 supports multiple playback cores, the currently used playback core is BASS audio library.\r\n More audio format support depends on the bass engine plug-in (located in the \".\\Plugins\" directory)." +TXT_SUPPORTTED_FORMAT_CORE_INFO_MCI = "MusicPlayer2 supports multiple playback cores, and the currently used playback core is MCI. Only supports mp3, wma, wav, mid format, if you need to support the playback of more audio formats, please switch to BASS or FFMPEG core." +TXT_SUPPORTTED_FORMAT_CORE_INFO_FFMPEG = "MusicPlayer2 supports multiple playback cores. The currently used playback core is FFMPEG." +TXT_SUPPORTTED_FORMAT_PLUGIN_FILE_NAME = "Plug-in file name" +TXT_SUPPORTTED_FORMAT_PLUGIN_FORMAT_PROVIDED = "Format support provided" +TXT_SUPPORTTED_FORMAT_PLUGIN_FILE_EXTENSION = "File extension" + +# IDD_FORMAT_CONVERT_DIALOG +TITLE_FORMAT_CONVERT = "Convert Format" +TXT_FORMAT_CONVERT_OUT_FORMAT_SEL = "Output encoding format:" +TXT_FORMAT_CONVERT_ENCODER_NAME_MP3_LAME = "MP3 (lame Encoder)" +TXT_FORMAT_CONVERT_SETTING = "Config..." +TXT_FORMAT_CONVERT_FILE_LIST = "File list:" +TXT_FORMAT_CONVERT_STAUS = "Conversion state" +TXT_FORMAT_CONVERT_STAUS_ERROR_FILE_CANNOT_OPEN = "Error: The source file cannot be read" +TXT_FORMAT_CONVERT_STAUS_ERROR_ENCODE_CHANNEL_FAILED = "Error: Failed to create the encoding channel" +TXT_FORMAT_CONVERT_STAUS_ERROR_ENCODE_PARA_ERROR = "Error: Cannot find encoder or encoder parameter error" +TXT_FORMAT_CONVERT_STAUS_ERROR_MIDI_NO_SF2 = "Error: No MIDI sound font" +TXT_FORMAT_CONVERT_STAUS_ERROR_NO_WMP9_OR_LATER = "Error: Failed to create the encoding channel, Windows Media Player 9 or later is not installed" +TXT_FORMAT_CONVERT_STAUS_ERROR_NO_SUPPORTED_ENCODER = "Error: Failed to create the encoding channel, The codec that supports the requested sampling format and bit rate could not be found" +TXT_FORMAT_CONVERT_STAUS_ERROR_OTHER = "Error code: <%1%>" +TXT_FORMAT_CONVERT_STAUS_COMPLEATE = "Complete" +TXT_FORMAT_CONVERT_STAUS_SKIPED = "Skipped" +TXT_FORMAT_CONVERT_OPT = "Options" +TXT_FORMAT_CONVERT_CHANGE_FREQ = "Convert sampling frequency:" +TXT_FORMAT_CONVERT_COPY_TAG = "Write tag information" +TXT_FORMAT_CONVERT_COPY_COVER = "Write album cover" +TXT_FORMAT_CONVERT_OUT_FILE_NAME = "Destination file name:" +TXT_FORMAT_CONVERT_ADD_SERIAL_NUMBER = "Add a number to each destination file" +TXT_FORMAT_CONVERT_FILE_EXIST_SEL = "When the destination file exists:" +TXT_FORMAT_CONVERT_FILE_EXIST_AUTO_RENAME = "Auto rename" +TXT_FORMAT_CONVERT_FILE_EXIST_IGNORE = "Skip" +TXT_FORMAT_CONVERT_FILE_EXIST_OVERWRITE = "Overwrite" +TXT_FORMAT_CONVERT_OUT_DIR = "Output directory:" +TXT_FORMAT_CONVERT_OUT_DIR_OPEN_WHEN_COMPLETE = "Open output directory after the conversion is complete" +TXT_FORMAT_CONVERT_PROGRESS_INFO = "<%1%>% completed, please wait..." +TXT_FORMAT_CONVERT_PROGRESS_INFO_COMPLEATE = "Completed" +TXT_FORMAT_CONVERT_START_CONVERT = "Start convert" +MSG_FORMAT_CONVERT_BASS_MIX_LOAD_ERROR = "BASSmix load failed, file \"<%1%>\" may be lost or corrupted!" +MSG_FORMAT_CONVERT_INIT_ERROR = "Encoder initialization failed!" +MSG_FORMAT_CONVERT_BASS_LOAD_ERROR = "BASS Encoder load failed, file \"<%1%>\" may be lost or corrupted!" +MSG_FORMAT_CONVERT_SET_OUTPUT_DIR = "Please set the output directory!" +MSG_FORMAT_CONVERT_OUTPUT_DIR_NOT_EXIST = "Output directory \"<%1%>\" does not exist!" +# IDD_MP3_ENCODE_CFG_DIALOG +TITLE_ENCODE_OPT_MP3 = "MP3 Encode Options" +TXT_ENCODE_OPT_MP3_CBR = "Constant bit rate (CBR):" +TXT_ENCODE_OPT_MP3_ABR = "Average bit rate (ABR):" +TXT_ENCODE_OPT_MP3_VBR = "Variable bit rate (VBR) (recommended)" +TXT_ENCODE_OPT_MP3_VBR_QUALITY_SEL = "Compression quality:" +TXT_ENCODE_OPT_MP3_VBR_QUALITY_LOW = "Low" +TXT_ENCODE_OPT_MP3_VBR_QUALITY_HIGH = "High" +TXT_ENCODE_OPT_MP3_JOINT_STEREO = "Joint stereo encoding for dual channels" +TXT_ENCODE_OPT_MP3_SPECIFY_PARA = "Custom lame parameters:" +# IDD_WMA_ENCODE_CFG_DIALOG +TITLE_ENCODE_OPT_WMA = "WMA Encode Options" +TXT_ENCODE_OPT_WMA_CBR = "Constant bit rate (CBR):" +TXT_ENCODE_OPT_WMA_VBR = "Quality-based VBR:" +# IDD_OGG_ENCODE_CFG_DIALOG +TITLE_ENCODE_OPT_OGG = "OGG Encode Options" +TXT_ENCODE_OPT_OGG_ENCODE_QUALITY_SEL = "Encoding quality:" +TXT_ENCODE_OPT_OGG_ENCODE_QUALITY_LOW = "Low" +TXT_ENCODE_OPT_OGG_ENCODE_QUALITY_HIGH = "High" +# IDD_FLAC_ENCODE_CFG_DIALOG +TITLE_ENCODE_OPT_FLAC = "Flac Encode Options" +TXT_ENCODE_OPT_FLAC_CMP_LEVEL = "Compression level" +TXT_ENCODE_OPT_FLAC_CMP_LEVEL_LOW = "Low" +TXT_ENCODE_OPT_FLAC_CMP_LEVEL_HIGH = "High" +TXT_ENCODE_OPT_FLAC_SPECIFY_PARA = "Custom flac parameters" +# IDD_TAG_EDIT_DIALOG (other from IDD_PROPERTY_DIALOG) +TITLE_TAG_EDIT = "Edit Audio Tags" +TXT_TAG_EDIT_PATH = "Path:" +TXT_TAG_EDIT_SAVE = "Save" + +# IDD_CLEAN_UP_RANGE_DIALOG +TITLE_CLEAN_UP_RANGE = "Clean up the media library" +TXT_CLEAN_UP_RANGE_SEL = "Please select the range you want to clean:" +TXT_CLEAN_UP_RANGE_FILES_THAT_NOT_EXIST = "Files not exist" +TXT_CLEAN_UP_RANGE_FILES_NOT_IN_MEDIA_LIB_DIR = "Files not in the media library directory" +TXT_CLEAN_UP_RANGE_FILES_THAT_ERROR = "The wrong files" +TXT_CLEAN_UP_RANGE_FILES_TOO_SHORT = "Too short files" +TXT_CLEAN_UP_RANGE_FILES_NON_MAIN_IN_OSU = "Non-main files in the osu! folder" +MSG_CLEAN_UP_RANGE_NOT_SELECT_WARNING = "Please select a clean-up range!" + +# IDD_OPTIONS_DIALOG +TITLE_OPT = "Option Settings" + +# IDD_LYRIC_SETTING_DIALOG +TITLE_OPT_LRC = "Lyrics Settings" + +TXT_OPT_LRC_OPT = "Lyric Options" +TXT_OPT_LRC_USE_INNER_FIRST = "Use the Internal lyrics first" +TXT_OPT_LRC_FUZZY_MATCH = "Lyrics fuzzy match" +TIP_OPT_LRC_FUZZY_MATCH = "If you remove the check of this check box, it will only match the lyrics file that is exactly the same as the song file name; \r\n If you select this check box, the lyrics file that contains the artist and song title in the file name will match when it cannot find the exact same lyrics file for the file name. \r\n(You may need to restart the program to take it effect.) " +TXT_OPT_LRC_SHOW_TRANSLATION = "Show lyrics translation (If any)" +TXT_OPT_LRC_SONG_INFO_IF_NO_LRC = "Show song Info when no lyrics" +TIP_OPT_LRC_SONG_INFO_IF_NO_LRC = "When this option is checked, information such as the artist, album and song title of the song will be displayed if there are no lyrics, instead of \"<%1%>\"." +TXT_OPT_LRC_LRC_FOLDER = "Lyrics folder:" +TIP_OPT_LRC_LRC_FOLDER_PATH = "Description: If it can't find a matching lyrics file in the directory where the song is located, it will looking for the lyrics file in this folder." +TXT_OPT_LRC_SAVE_POLICY_SEL = "After lyrics modified:" +TXT_OPT_LRC_SAVE_POLICY_DO_NOT_SAVE = "Do not save" +TXT_OPT_LRC_SAVE_POLICY_AUTO_SAVE = "Auto save" +TXT_OPT_LRC_SAVE_POLICY_INQUIRY = "Inquiry" +TXT_OPT_LRC_KARAOKE_DISP = "Lyrics displayed in karaoke style" +TXT_OPT_LRC_USE_MUSIC_SYMBOL = "Do not display empty lines for lyrics" +TIP_OPT_LRC_USE_MUSIC_SYMBOL = "After checking this option, when the lyrics are displayed in a single line or double line, if there is a blank line, \"<%1%>\" or \"<%2%>\" will not be displayed. Instead, the lyrics will be displayed in advance, and if \"Show lyrics karaoke style\" is also checked, blank lines longer than a certain length will be replaced with music progress symbols \"<%3%>\". This option also affects the display of desktop lyrics." + +TXT_OPT_LRC_WINDOW_LRC = "Window Lyrics" +TXT_OPT_LRC_WINDOW_LRC_LINE_SPACING = "Lyrics line spacing (pixel):" +TXT_OPT_LRC_ALIGN_SEL = "Lyrics alignment:" +TXT_OPT_LRC_ALIGN_LEFT = "Left alignment" +TXT_OPT_LRC_ALIGN_RIGHT = "Right alignment" +TXT_OPT_LRC_ALIGN_AUTO = "Auto" +TXT_OPT_LRC_ALIGN_CENTER = "Center" +TXT_OPT_LRC_FONT_SEL = "Set Font..." +TIP_OPT_LRC_FONT_INFO_BOLD = "bold" +TIP_OPT_LRC_FONT_INFO_ITALIC = "italic" + +TXT_OPT_LRC_DESKTOP_LRC = "Desktop Lyrics" +TXT_OPT_LRC_DESKTOP_LRC_ENABLE = "Show desktop lyrics" +TXT_OPT_LRC_DESKTOP_LRC_BG_PENETRATE = "Lyrics background penetrate" +TXT_OPT_LRC_DESKTOP_LRC_HIDE_NO_LRC = "Hide lyrics window without lyrics" +TXT_OPT_LRC_DESKTOP_LRC_HIDE_PAUSE = "Hide lyrics window when paused" +TXT_OPT_LRC_DESKTOP_LRC_LOCK = "Lock desktop lyrics" +TXT_OPT_LRC_DESKTOP_LRC_SHOW_UNLOCK_WHEN_LOCK = "Show unlock button when locked" +TXT_OPT_LRC_DOUBLE_LINE = "Lyrics displayed in double line" +TXT_OPT_LRC_DESKTOP_LRC_COLOR_TEXT = "Text color:" +TXT_OPT_LRC_DESKTOP_LRC_COLOR_HIGHLIGHT = "Highlight color:" +TXT_OPT_LRC_DESKTOP_LRC_COLOR_GRADIENT_NONE = "No gradient" +TXT_OPT_LRC_DESKTOP_LRC_COLOR_GRADIENT_TWO = "Two-color gradient" +TXT_OPT_LRC_DESKTOP_LRC_COLOR_GRADIENT_THREE = "Three-color gradient" +TXT_OPT_LRC_DESKTOP_LRC_DEFAULT_STYLE = "Styles Preset" +MSG_OPT_LRC_DESKTOP_LRC_DEFAULT_STYLE_MODIFY_WARNING = "Are you sure you want to override \"Default <%1%>\" with the current color setting?" +MSG_OPT_LRC_DESKTOP_LRC_DEFAULT_STYLE_RESTORE_WARNING = "All the modified default style will be restored, do you want to continue?" +TXT_OPT_LRC_DESKTOP_LRC_TRANSPARENCY = "Lyrics opacity:" + +TXT_OPT_LRC_SEARCH_BOX_FUNCTION = "Show play information in taskbar search box" +TXT_OPT_LRC_SEARCH_BOX_FUNCTION_ENABLE = "Enable taskbar search box function" +TIP_OPT_LRC_SEARCH_BOX_FUNCTION_ENABLE = "After the check option, it can display lyrics, song names, and album covers in the Cortana search box. After you turn on this feature, you may need to restart the program to take effect." +TXT_OPT_LRC_SEARCH_BOX_COMPATIBLE_MODE = "Display lyrics using compatibility mode" +TXT_OPT_LRC_SEARCH_BOX_SHOW_WHEN_PAUSE = "Keep on display when paused" +TXT_OPT_LRC_SEARCH_BOX_BG_COLOR_SEL = "Search box background color:" +TXT_OPT_LRC_SEARCH_BOX_BG_COLOR_FOLLOWING_SYSTEM = "Following system" +TXT_OPT_LRC_SEARCH_BOX_BG_COLOR_DARK = "Dark" +TXT_OPT_LRC_SEARCH_BOX_BG_COLOR_LIGHT = "Light" +TXT_OPT_LRC_SEARCH_BOX_BG_TRANSPARENCY_IN_WHITE_MODE = "The search box background is transparent in Windows 10 light mode" +TXT_OPT_LRC_SEARCH_BOX_SHOW_COVER = "Show album cover in search box" +TXT_OPT_LRC_SEARCH_BOX_NO_COVER_SHOW_DEFAULT_COVER = "Show phonograph icon in the search box when there is no album cover" +TXT_OPT_LRC_SEARCH_BOX_NO_COVER_BEATS_CORTANA_ICON = "Cortana icon beats following the music rhythm" +TXT_OPT_LRC_SEARCH_BOX_SHOW_SPECTRUM = "Show spectrum analysis in search box" +TXT_OPT_LRC_SEARCH_BOX_SHOW_LRC = "Show lyrics in search box" + +# IDD_APPEREANCE_SETTING_DLG +TITLE_OPT_APC = "Appearance Settings" + +TXT_OPT_APC_VISUAL_EFFECTS = "Visual Effects" +TXT_OPT_APC_SPECTRUM_SHOW = "Show spectrum analysis" +TXT_OPT_APC_SPECTRUM_LOW_FREQ_IN_CENTER = "Low-frequency parts appears in the middle" +TXT_OPT_APC_SPECTRUM_HEIGHT = "Spectrum height:" +TXT_OPT_APC_COVER_SHOW = "Show album cover" +TXT_OPT_APC_COVER_FIT = "Album cover fit:" +TXT_OPT_APC_COVER_FIT_STRETCH = "Stretch" +TXT_OPT_APC_COVER_FIT_FILL = "Fill" +TXT_OPT_APC_COVER_FIT_ADAPT = "Adapt" +TIP_OPT_APC_COVER_FIT = "Stretch: Will change the aspect ratio.\r\nFill: Will not change the aspect ratio, will crop the long edge.\r\nAdatp: will not change the aspect ratio, not crop." +TXT_OPT_APC_LYRIC_BG = "Lyric background" +TXT_OPT_APC_ROUND_CORNERS = "Use rounded corner style" +TXT_OPT_APC_DARK_MODE = "Dark mode" +TXT_OPT_APC_MAIN_WINDOW_TRANSPARENCY = "Main Window Opacity:" + +TXT_OPT_APC_BG_SETTING = "Background Settings" +TXT_OPT_APC_BG_ENABLE = "Enable background" +TXT_OPT_APC_BG_USE_DESKTOP = "Use desktop background" +TXT_OPT_APC_BG_TRANSPARENCY = "Background opacity:" +TXT_OPT_APC_BG_USE_COVER = "Use album cover as background" +TXT_OPT_APC_BG_GAUSS_BLUR = "Background Gaussian blur" +TXT_OPT_APC_BG_GAUSS_BLUR_RADIUS = "Gaussian blur radius:" +TXT_OPT_APC_BG_DEFAULT_IMAGE = "Default background image:" + +TXT_OPT_APC_COVER_OPT = "Album Cover Options" +TXT_OPT_APC_COVER_USE_INNER_FIRST = "Use the Internal album cover first" +TXT_OPT_APC_COVER_OUT_IMAGE_ALLOW = "Use external picture when album cover not exist" +TIP_OPT_APC_COVER_OUT_IMAGE_ALLOW = "If the album cover can't be get from the audio file, it will try to looking for the specified file name for the album cover in the directory where the audio file located." +TXT_OPT_APC_COVER_OUT_IMAGE_FILE_NAME = "External picture file name:" +TIP_OPT_APC_COVER_OUT_IMAGE_FILE_NAME = "Set the default album cover file name here, separated by a comma between multiple file names, support wildcards and relative paths, setting absolute paths will make the cover search always successful and not automatically download the album cover." +TXT_OPT_APC_COVER_OUT_FOLDER = "Album cover folder:" +TIP_OPT_APC_COVER_OUT_FOLDER = "If the album cover is not found in the directory where the song is located then the cover file will be searched for in this folder." + +TXT_OPT_APC_COLOR_THEME = "Theme Color" +TIP_OPT_APC_COLOR_CURRENT = "Current color" +TXT_OPT_APC_COLOR_PRESET = "Preset color" +TIP_OPT_APC_COLOR_LIGNT_BLUE = "Azure" +TIP_OPT_APC_COLOR_GREEN = "Green" +TIP_OPT_APC_COLOR_ORANGE = "Orange" +TIP_OPT_APC_COLOR_CYAN_GREEN = "Turquoise" +TIP_OPT_APC_COLOR_PINK = "Pink" +TIP_OPT_APC_COLOR_LIGHT_PURPLE = "Pale purple" +TXT_OPT_APC_COLOR_MORE = "More Color..." +TXT_OPT_APC_COLOR_FOLLOW_SYSTEM = "Follow the system theme color" + +TXT_OPT_APC_STATUS_BAR = "Status bar" +TXT_OPT_APC_ALWAYS_SHOW_STATUS_BAR = "Always show status bar" +TXT_OPT_APC_SHOW_NEXT_TRACK = "Show next track" +TXT_OPT_APC_SHOW_FPS = "Show fps" + +TXT_OPT_APC_TITLE_BAR = "Title bar" +TXT_OPT_APC_USE_SYSTEM_TITLE_BAR = "Use system standard title bar" +TXT_OPT_APC_TITLE_BAR_BTN_SEL = "Buttons displayed in the title bar(only available when \"Use system standard title bar\" is not checked):" +TXT_OPT_APC_TITLE_BAR_BTN_SETTING = "Settings" +TXT_OPT_APC_TITLE_BAR_BTN_SKIN = "Switch UI" +TXT_OPT_APC_TITLE_BAR_BTN_MINI_MODE = "Mini mode" +TXT_OPT_APC_TITLE_BAR_BTN_FULLSCREEN = "Full screen" +TXT_OPT_APC_TITLE_BAR_BTN_MINIMIZE = "Minimize" +TXT_OPT_APC_TITLE_BAR_BTN_MAXIMIZE = "Maximize/Restore" + +TXT_OPT_APC_NOTIFY_ICON = "Notification Area Icon" +TXT_OPT_APC_NOTIFY_ICON_PREVIEW = "Preview:" +TXT_OPT_APC_NOTIFY_ICON_SEL = "Select notification area icon:" +TXT_OPT_APC_NOTIFY_ICON_DEFAULT = "Default icon" +TXT_OPT_APC_NOTIFY_ICON_LIGHT = "Light icon" +TXT_OPT_APC_NOTIFY_ICON_DARK = "Dark icon" +TXT_OPT_APC_NOTIFY_ICON_AUTO_ADAPT = "Automatically adapt to Windows 10 dark/light mode when using the monochrome icons." + +TXT_OPT_APC_ADVANCED = "Advanced" +TXT_OPT_APC_UI_REFRESH_INTERVAL = "Interface refresh interval (ms):" +TXT_OPT_APC_UI_REFRESH_INTERVAL_RESTORE = "Restore Defaults" +TXT_OPT_APC_COVER_HQ = "Album covers use GDI+ drawing (higher quality but will take up more CPU resources)" + +# IDD_DATA_SETTINGS_DIALOG +TITLE_OPT_DATA = "General Settings" +TXT_OPT_DATA_APP_SETTING = "Application Settings" +TXT_OPT_DATA_UPDATE_AUTO_CHECK = "Check for update at startup" +TXT_OPT_DATA_UPDATE_SOURCE_SEL = "Update source:" +TXT_OPT_DATA_UPDATE_SOURCE_GITHUB = "Github" +TXT_OPT_DATA_UPDATE_SOURCE_GITEE = "Gitee" +TXT_OPT_DATA_AUTO_RUN = "Auto run when Windows starts" +TXT_OPT_DATA_LANGUAGE_SEL = "Language:" +TXT_OPT_DATA_LANGUAGE_FOLLOWING_SYSTEM = "Following system" +TXT_OPT_DATA_DATA_FILE_CFG = "Configuration and data files" +TXT_OPT_DATA_DATA_FILE_SAVE_DIR_APPDATA = "Save to Appdata directory" +TXT_OPT_DATA_DATA_FILE_SAVE_DIR_PROGRAM = "Save to the program directory" +TXT_OPT_DATA_DATA_FILE_DIR_OPEN = "Open configuration file directory" +TXT_OPT_DATA_CLOSE_MAIN_WINDOW = "Close Main Window" +TXT_OPT_DATA_CLOSE_MAIN_WINDOW_MINIMIZE_NOTIFY_AREA = "Minimize to notification area" +TXT_OPT_DATA_CLOSE_MAIN_WINDOW_EXIT = "Exit the program" +TXT_OPT_DATA_AUTO_DL_SETTING = "Automatic Download Settings" +TXT_OPT_DATA_AUTO_DL_LYRIC = "Automatically download when lyric is not exist" +TXT_OPT_DATA_AUTO_DL_LYRIC_SAVE_SEL = "Automatically Download Lyrics Save Location:" +TXT_OPT_DATA_AUTO_DL_LYRIC_SAVE_SONG_DIR = "Save to the same directory as the song" +TXT_OPT_DATA_AUTO_DL_LYRIC_SAVE_LYRIC_DIR = "Save to lyrics directory" +TXT_OPT_DATA_AUTO_DL_COVER = "Automatically download when album cover is not exist" +TXT_OPT_DATA_AUTO_DL_COVER_SAVE_SEL = "Automatically Download Album Cover Save Location:" +TXT_OPT_DATA_AUTO_DL_COVER_SAVE_SONG_DIR = "Save to the same directory as the song" +TXT_OPT_DATA_AUTO_DL_COVER_SAVE_COVER_DIR = "Save to album cover directory" +TXT_OPT_DATA_AUTO_DL_ONLY_WHEN_TAG_FULL = "Download automatically only when the song information is complete" +TIP_OPT_DATA_AUTO_DL_ONLY_WHEN_TAG_FULL = "After checking this item, the lyrics and album covers are automatically downloaded only if neither the title nor the artist information of the song is empty." +TXT_OPT_DATA_MIDI_SETTING = "MIDI Setting" +TXT_OPT_DATA_MIDI_INNER_LYRIC_FIRST = "Display the inner lyric in MIDI music first" +TIP_OPT_DATA_MIDI_INNER_LYRIC_FIRSR = "Some MIDI music contains lyrics, and when you check this item, it will give priority to displaying the lyrics embedded in MIDI music." +TXT_OPT_DATA_MIDI_SF2_PATH = "MIDI sound font path:" +MSG_OPT_DATA_LANGUAGE_CHANGE_INFO = "Please restart the application to apply the language setting." +MSG_OPT_DATA_CFG_DIR_CHANGED_INFO = "You have changed the location where the configuration and data files saved. It will take effect after restarted. You may need to transfer the configuration and data files to the new location manually." + +# IDD_PLAY_SETTING_DIALOG +TITLE_OPT_PLAY = "Play Settings" + +TXT_OPT_PLAY_PLAY_OPT = "Play Options" +TXT_OPT_PLAY_STOP_WHEN_ERROR = "Stop playing when an error occurs" +TXT_OPT_PLAY_AUTO_PLAY_WHEN_START = "Auto play when the program starts" +TXT_OPT_PLAY_SHOW_TASKBAR_PROGRESS = "Show playing progress in the taskbar" +TXT_OPT_PLAY_SHOW_TASKBAR_PLAY_STATE_ICON = "Show playing status icon in the taskbar" +TXT_OPT_PLAY_SOUND_FADE = "Sound fade in and out effect" +TXT_OPT_PLAY_CONTINUE_WHEN_SWITCH_PLAYLIST = "Continue playing when switch playlist" +TIP_OPT_PLAY_CONTINUE_WHEN_SWITCH_PLAYLIST = "When this option is selected, if the playing track exists in the new playlist, the playing track will continue to be played after the playlist is switched." +TXT_OPT_PLAY_USE_MEDIA_TRANS_CONTORL = "Use system media transport controls" + +TXT_OPT_PLAY_CORE = "Player Kernal" +TXT_OPT_PLAY_CORE_BASS = "BASS" +TXT_OPT_PLAY_CORE_MCI = "MCI (Media Control Interface)" +TIP_OPT_PLAY_CORE_MCI = "Using the MCI kernel will result in format conversion and sound effect settings being unavailable and some audio will not be played. It is recommended to switch to this kernel only when needed." +TXT_OPT_PLAY_CORE_FFMPEG = "FFMPEG" +TIP_OPT_PLAY_CORE_FFMPEG = "Using the FFMPEG kernel will result in revertb sound effect and format conversion settings being unavailable and MIDI file will not be played. ffmpeg_core.dll is needed." +TXT_OPT_PLAY_CORE_FFMPEG_DL_INFO = "Click here to download" +MSG_OPT_PLAY_CORE_FFMPEG_DL_INFO = "The FFMPEG core needs to be downloaded separately. After downloaded, please put all the dll files obtained by decompression into the program directory. Do you want to download FFMPEG core?" + +TXT_OPT_PLAY_DEVICE = "Play Device" +TXT_OPT_PLAY_DEVICE_SEL = "Select play device:" +TXT_OPT_PLAY_DEVICE_NAME = "Name" +TXT_OPT_PLAY_DEVICE_NAME_BASS_DEFAULT = "Default output device" +TXT_OPT_PLAY_DEVICE_NAME_SDL_DEFAULT = "SDL default audio device" +TXT_OPT_PLAY_DEVICE_DRIVER = "Driver" +TXT_OPT_PLAY_DEVICE_TYPE = "Device type" +TXT_OPT_PLAY_DEVICE_TYPE_BASS_NETWORK = "An audio endpoint device that the user accesses remotely through a network." +TXT_OPT_PLAY_DEVICE_TYPE_BASS_SPEAKERS = "Speakers" +TXT_OPT_PLAY_DEVICE_TYPE_BASS_LINE = "An audio endpoint device that sends a line-level analog signal to a line-input jack on an audio adapter or that receives a line-level analog signal from a line-output jack on the adapter." +TXT_OPT_PLAY_DEVICE_TYPE_BASS_HEADPHONES = "Headphones" +TXT_OPT_PLAY_DEVICE_TYPE_BASS_MICROPHONE = "Microphone" +TXT_OPT_PLAY_DEVICE_TYPE_BASS_HEADSET = "An earphone or a pair of earphones with an attached mouthpiece for two-way communication." +TXT_OPT_PLAY_DEVICE_TYPE_BASS_HANDSET = "The part of a telephone that is held in the hand and that contains a speaker and a microphone for two-way communication." +TXT_OPT_PLAY_DEVICE_TYPE_BASS_DIGITAL = "An audio endpoint device that connects to an audio adapter through a connector for a digital interface of unknown type." +TXT_OPT_PLAY_DEVICE_TYPE_BASS_SPDIF = "An audio endpoint device that connects to an audio adapter through a Sony/Philips Digital Interface (S/PDIF) connector." +TXT_OPT_PLAY_DEVICE_TYPE_BASS_HDMI = "An audio endpoint device that connects to an audio adapter through a High-Definition Multimedia Interface (HDMI) connector." +TXT_OPT_PLAY_DEVICE_TYPE_BASS_DISPLAYPORT = "An audio endpoint device that connects to an audio adapter through a DisplayPort connector." + +TXT_OPT_PLAY_FFMPEG_CORE_SETTING = "FFMPEG Core Settings" +TXT_OPT_PLAY_FFMPEG_CORE_CACHE_LENGTH = "Cache duration (sec):" +TXT_OPT_PLAY_FFMPEG_CORE_MAX_RETRY_COUNT = "Max retry attempts (-1 for unlimited):" +TXT_OPT_PLAY_FFMPEG_CORE_URL_RETRY_INTERVAL = "Non-local file retry interval (sec):" +TXT_OPT_PLAY_FFMPEG_CORE_MAX_WAIT_TIME = "Max wait time for seeking (ms):" +TXT_OPT_PLAY_FFMPEG_CORE_ENABLE_WASAPI = "Enable WASAPI" +TXT_OPT_PLAY_FFMPEG_CORE_ENABLE_WASAPI_EXCLUSIVE = "Enable exclusive mode" + +# IDD_MEDIA_LIB_SETTING_DIALOG +TITLE_OPT_MEDIA_LIB = "Media Library" + +TXT_OPT_MEDIA_LIB_MEDIA_LIB_OPT = "Media Library Options" +TXT_OPT_MEDIA_LIB_DISABLE_DEL = "Disable delete from disk" +TXT_OPT_MEDIA_LIB_USE_CLASSIFY_OTHER = "Classify only-one items into others" +TXT_OPT_MEDIA_LIB_TOO_SHORT_SEC = "Low duration threshold (sec):" +TXT_OPT_MEDIA_LIB_ARTIST_SPLIT_EXT_SEL = "Artist recognition exception:" +TIP_OPT_MEDIA_LIB_ARTIST_SPLIT_EXT = "Add all artists whose names contain \"/\;&&、\" as exceptions to prevent inadvertent recognition errors." +TXT_OPT_MEDIA_LIB_MEDIA_LIB_UPDATE_OPT = "Media Library Update Options" +TXT_OPT_MEDIA_LIB_REMOVE_FILE_NOT_EXIST = "Remove non-existing files" +TXT_OPT_MEDIA_LIB_IGNORE_TOO_SHORT = "Ignore files with durations below the threshold" +TXT_OPT_MEDIA_LIB_AUTO_UPDATE_WHEN_STARTUP = "Auto-update media library on startup" +TIP_OPT_MEDIA_LIB_AUTO_UPDATE_WHEN_STARTUP = "When this option is checked, the program will automatically scan the audio files in the \"Media Library Directory\" at startup." +TXT_OPT_MEDIA_LIB_FORCE_RELOAD = "Force reload" +MSG_OPT_MEDIA_LIB_UPDATING_INFO = "The media library is being updated, please try again later!" +TXT_OPT_MEDIA_LIB_MEDIA_LIB_DIR = "Media Library Directory" +TXT_OPT_MEDIA_LIB_MEDIA_LIB_DIR_ADD = "Add..." +TXT_OPT_MEDIA_LIB_MEDIA_LIB_DIR_DEL = "Delete" +TXT_OPT_MEDIA_LIB_MEDIA_LIB_DISP_TAB = "Items Displayed in the Media Library" +TXT_OPT_MEDIA_LIB_PLAYLIST_OPT = "Playlist Options" +TXT_OPT_MEDIA_LIB_DISABLE_DRAGE_SORT = "Disable drag-and-drop sorting of tracks in the playlist" +TXT_OPT_MEDIA_LIB_INS_BEGIN = "Insert at the start of the playlist when adding songs, not at the end" +TXT_OPT_MEDIA_LIB_FLOAT_PLAYLIST_BY_DEFAULT = "Use floating playlist by default" +TXT_OPT_MEDIA_LIB_FLOAT_PLAYLIST_FOLLOW_MAIN_WND = "Floating playlist follows main window" +TXT_OPT_MEDIA_LIB_SHOW_TOOLTIP = "Show playlist tool tip" +TXT_OPT_MEDIA_LIB_PLAYLIST_DISPLAY_MODE = "Playlist display mode:" +TXT_OPT_MEDIA_LIB_PLAYLIST_ITEM_HEIGHT = "Playlist item height (pixel):" +TXT_OPT_MEDIA_LIB_RECENT_PLAY = "Recently played" +TXT_OPT_MEDIA_LIB_RECENT_PLAY_RANGE_SEL = "Recently played display range:" +TXT_OPT_MEDIA_LIB_RECENT_PLAY_RANGE_ALL = "All" +TXT_OPT_MEDIA_LIB_RECENT_PLAY_RANGE_TODAY = "Today" +TXT_OPT_MEDIA_LIB_RECENT_PLAY_RANGE_LAST_THREE_DAYS = "Last three days" +TXT_OPT_MEDIA_LIB_RECENT_PLAY_RANGE_LAST_WEEK = "Last week" +TXT_OPT_MEDIA_LIB_RECENT_PLAY_RANGE_LAST_MONTH = "Last month" +TXT_OPT_MEDIA_LIB_RECENT_PLAY_RANGE_LAST_HALF_YEAR = "Last six months" +TXT_OPT_MEDIA_LIB_RECENT_PLAY_RANGE_LAST_YEAR = "Last year" +TXT_OPT_MEDIA_LIB_RECENT_PLAY_CLEAR = "Clear recently played tracks list..." +MSG_OPT_MEDIA_LIB_RECENT_PLAY_CLEAR_INQUARY = "Are you sure you want to clear the recently played tracks list?" +TXT_OPT_MEDIA_LIB_CLEAN_MEDIA_LIB = "Clean up the Media library" +TXT_OPT_MEDIA_LIB_CURRENT_DATA_FILE_SIZE_BYTE = "Current data file size: <%1%> Bytes" +TXT_OPT_MEDIA_LIB_CURRENT_DATA_FILE_SIZE_KB = "Current data file size: <%2%> KB (<%1%> Bytes)" +TXT_OPT_MEDIA_LIB_CURRENT_DATA_FILE_SIZE_MB = "Current data file size: <%2%> MB (<%1%> Bytes)" +TXT_OPT_MEDIA_LIB_DATA_FILE_CLEAN = "Clean up..." +TIP_OPT_MEDIA_LIB_DATA_FILE_CLEAN = "Description: The song_data.dat file in the program directory holds all loaded song information to speed up the loading of the playlist. Click this button to choose the cleaning range." +MSG_OPT_MEDIA_LIB_DATA_FILE_CLEAR_COMPLETE = "Cleanup completed, <%1%> items have been deleted, and the data file size is reduced by <%2%> bytes." +TXT_OPT_MEDIA_LIB_TAG_EDIT = "Music tag reading and writing" +TXT_OPT_MEDIA_LIB_TAG_ID3V2_WRITE_TYPE = "ID3v2 write type:" + +TXT_OPT_LAST_FM = "Last.fm" +TXT_OPT_LAST_FM_ENABLE = "Enable last.fm support" +TXT_OPT_LAST_FM_STATUS_LOGIN_REQUIRED = "Current status: Login required" +TXT_OPT_LAST_FM_STATUS_LOGIN_LOGGED = "Current status: Already logged in (<%1%>)" +TXT_OPT_LAST_FM_USE_HTTPS = "Use HTTPS when communicating with the last.fm server" +TXT_OPT_LAST_FM_LOGIN = "Log in" +MSG_OPT_LAST_FM_LOGIN_PROMPT = "Please complete the login in the opened browser window and click OK after successful login." +MSG_OPT_LAST_FM_LOGIN_FAILED = "Login failed!" +TXT_OPT_LAST_FM_UPLOAD_NOW_PLAYING = "Upload now playing track" +TXT_OPT_LAST_FM_CACHE_CONDITION = "Cache Scrobble Conditions" +TXT_OPT_LAST_FM_CACHE_CONDITION_PERCENT = "At least played percentage:" +TXT_OPT_LAST_FM_CACHE_CONDITION_DURATION = "At least played duration (sec):" +TXT_OPT_LAST_FM_CACHE_STATUS = "Cache status: <%1%> scrobbles" +TXT_OPT_LAST_FM_CACHE_UPLOAD = "Upload cache" +TXT_OPT_LAST_FM_UPLOAD_WHEN_REACH_THRESHOLD = "Upload scrobbles when cached scrobbles reach the threshold" +TXT_OPT_LAST_FM_AUTO_UPLOAD_THRESHOLD = "Auto upload threshold:" + +# IDD_HOT_KEY_SETTINGS_DIALOG +TITLE_OPT_HOT_KEY = "Global Shortcut Keys" +TXT_OPT_HOT_KEY_HOOK_SHORTCUT_KEY_ENABLE = "Enable global hot keys" +TXT_OPT_HOT_KEY_HOOK_MULTI_MEDIA_KEY_ENABLE = "Enable global multimedia keys" +TIP_OPT_HOT_KEY_HOOK_MULTI_MEDIA_KEY = "When this option is checked, even if the program is running in the background, you can still control the playing of the music by the multimedia keys on your keyboard. It would be taken effect after the program is restarted." +TXT_OPT_HOT_KEY_FUNCTION = "Function" +TXT_OPT_HOT_KEY_SHORTCUT_KEY = "Shortcut key" +TXT_OPT_HOT_KEY_PLAY_PAUSE = "Play/Pause" +TXT_OPT_HOT_KEY_STOP = "Stop" +TXT_OPT_HOT_KEY_FAST_FORWARD = "Fast forward" +TXT_OPT_HOT_KEY_REWIND = "Rewind" +TXT_OPT_HOT_KEY_PREVIOUS = "Previous" +TXT_OPT_HOT_KEY_NEXT = "Next" +TXT_OPT_HOT_KEY_VOLUME_UP = "Volume up" +TXT_OPT_HOT_KEY_VOLUME_DOWN = "Volume down" +TXT_OPT_HOT_KEY_EXIT = "Exit" +TXT_OPT_HOT_KEY_PLAYER_SHOW_HIDE = "Show/hide player" +TXT_OPT_HOT_KEY_DESKTOP_LYRIC_SHOW_HIDE = "Show/hide desktop lyric" +TXT_OPT_HOT_KEY_SHORTCUT_KEY_SEL = "Shortcut key:" +TXT_OPT_HOT_KEY_SHORTCUT_KEY_SET = "Set" +MSG_OPT_HOT_KEY_GLOBLE_HOT_KEY_WARNING = "Global shortcuts need to contain at least one of Ctrl, Shift, and Alt!" + +# IDD_MEDIA_LIB_DIALOG +TITLE_LIB = "Media Library" +TXT_LIB_MEDIA_LIB_SETTING = "Media Library Settings..." +TXT_LIB_STATISTICS_INFO = "Statistics..." +TXT_LIB_PLAY_SEL = "Play Selected" +# IDD_SET_PATH_DIALOG +TXT_LIB_PATH_CURRENT_FOLDER = "Current folder:" +TXT_LIB_PATH_OPEN_NEW_FOLDER = "Open New Folder..." +TXT_LIB_PAHT_IS_CONTAIN_SUB_FOLDER = "Include subfolders" +TXT_LIB_PAHT_IS_CONTAIN_SUB_FOLDER_YES = "Yes" +MSG_LIB_PATH_CLEAR_INQUARY = "Are you sure you want to clear the invalid folder in the list?" +MSG_LIB_PATH_CLEAR_COMPLETE = "Complete, <%1%> invalid folder cleared." +# IDD_SELECT_PLAYLIST_DIALOG +TXT_LIB_PLAYLIST_NEW_PLAYLIST = "New Playlist..." +# CMediaLibStatisticsDlg +TITLE_LIB_STATISTICS = "Media library statistics" +TXT_LIB_STATISTICS_TOTAL_NUM_OF_TRACK = "Total number of tracks" +TXT_LIB_STATISTICS_NUM_OF_TRACK_PLAYED = "Number of tracks played" + +# IDD_LYRIC_RELATE_DIALOG +TITLE_LRC_RELATE = "Link local lyrics" +TXT_LRC_RELATE_LRC_TITLE = "Lyrics title:" +TXT_LRC_RELATE_FUZZY_MATCH = "Partial match" +TXT_LRC_RELATE_SEARCH_LOCAL = "Local Search" +TXT_LRC_RELATE_SEARCH_RESULT = "Search results:" +TXT_LRC_RELATE_IS_RELATED = "Linked" +TXT_LRC_RELATE_IS_RELATED_YES = "Yes" +TXT_LRC_RELATE_BROWSE = "Browse..." +TXT_LRC_RELATE_DEL_FILE = "Delete File" +TXT_LRC_RELATE_UNLINK = "Unlink lyrics" +TXT_LRC_RELATE_SEL_LINK = "Link selected lyrics" + +# IDD_FILE_RELATE_DIALOG +TITLE_FILE_RELATE = "File Relate" +TXT_FILE_RELATE_SEL_DEFAULT = "Default" +TXT_FILE_RELATE_SEL_ALL = "Select All" +TXT_FILE_RELATE_FORMAT = "Format" +TXT_FILE_RELATE_DESCRIPTION = "Description" + +# IDD_LISTEN_TIME_STATISTICS_DLG +TITLE_LISTEN_TIME = "Total Play Time Statistics" +TXT_LISTEN_TIME_TOTAL_TIME = "Total play time" +TXT_LISTEN_TIME_TOTAL_COUNT = "Total play count" +TXT_LISTEN_TIME_EXPORT = "Export..." +TXT_LISTEN_TIME_CLEAR = "Clear" +MSG_LISTEN_TIME_CLEAR_WARNING = "Are you sure you want to clear all the statistics?" + +# IDD_ABOUTBOX +TITLE_ABOUTBOX = "About MusicPlayer2" +TXT_ABOUTBOX_LAST_BUILD_DATE = "Last compiled date: <%1%>" +TXT_ABOUTBOX_THIRD_PARTY_LIB = "The third-party libraries used in this project:" +TXT_ABOUTBOX_OTHER_SOFTWARE = "The author's other software:" +TXT_ABOUTBOX_CONTRACT_AUTHOR = "Contract author" +TXT_ABOUTBOX_CHECK_UPDATE = "Check for update" +TXT_ABOUTBOX_GITHUB = "Github" +TXT_ABOUTBOX_LICENSE = "License" +TXT_ABOUTBOX_DONATE = "Donate" +TXT_ABOUTBOX_ACKNOWLEDGEMENT = "Acknowledgement" +TIP_ABOUTBOX_SEND_EMAIL_TO_ATHOUR = "Send an e-mail to the author." +TIP_ABOUTBOX_GOTO_GITHUB = "Go to the page on GitHub for this project." +TIP_ABOUTBOX_TRAFFICMONITOR_DESCRIPTION = "TrafficMonitor: A powerful net speed monitoring software for Windows." +TIP_ABOUTBOX_SIMPLENOTEPAD_DESCRIPTION = "SimpleNotePad: A simple text editor for Windows." + +# IDD_ADD_TO_PLAYLIST_DIALOG +TITLE_ADD_TO_PLAYLIST = "Select Playlist" + +# IDD_DONATE_DIALOG +TITLE_DONATE = "Donate" +TXT_DONATE_INFO = "If you think this software is helpful to you, you can scan the following QR code through Alipay or WeChart Pay to donate the author to help the author to make this software better. Please feel free for the amount." + +# IDD_TAG_MODE_SELECT_DIALOG / CTagSelBaseDlg +TXT_TAG_SEL_CLEAR_HISTORY = "Clear history..." +MSG_TAG_SEL_CLEAR_HISTORY_INQUARY = "Are you sure you want to clear the history?" +TXT_TAG_SEL_ORIGINAL = "Original:" +TXT_TAG_SEL_CLICK_BTN_SEL = "When click the button:" +TXT_TAG_SEL_CLICK_BTN_INS = "Insert" +TXT_TAG_SEL_CLICK_BTN_COPY = "Copy to clipboard" +# CRenameDlg +TITLE_RENAME_SONG = "Rename" +TXT_RENAME_SONG_INFO = "Please choose a rename template or enter a new file name:" +MSG_RENAME_SONG_COMPLETED_INFO = "Rename <%1%> files, <%2%> succeeded, <%3%> ignored, <%4%> failed." +# CTagFromNameDlg +TITLE_TAG_FROM_NAME = "Get tag from file name" +TXT_TAG_FROM_NAME_INFO = "Please choose a tag extraction template:" +# CFileNameFormDlg +TITLE_FILE_NAME_FORM = "Set file name template" +TXT_FILE_NAME_FORM_INFO = "Please choose or input file name template:" + +# CMusicPlayerCmdHelper::OnViewArtist / CSelectItemDlg +TITLE_SELECT_ARTIST = "Select artist" + +# CSelectPlaylistDlg::DoNewPlaylist / CMusicPlayerCmdHelper::OnAddToNewPlaylist / CInputDlg +TITLE_NEW_PLAYLIST = "New Playlist" +TXT_NEW_PLAYLIST_INPUT_PLAYLIST_NAME = "Input the playlist name:" + +# CSelectPlaylistDlg::OnRenamePlaylist / CInputDlg +TITLE_RENAME_PLAYLIST = "Rename Playlist" +TXT_RENAME_PLAYLIST_INPUT_PLAYLIST_NAME = "Input the playlist name:" + +# CMusicPlayerDlg::OnFileOpenUrl / CMusicPlayerDlg::OnPlaylistAddUrl / CInputDlg +TITLE_INPUT_URL_OPEN_URL = "Open URL" +TITLE_INPUT_URL_ADD_URL = "Add URL" +TXT_INPUT_URL_INPUT_URL = "Please input the URL:" +MSG_INPUT_URL_INVALID_WARNING = "Please input the correct URL!" + +# CLyricDownloadDlg::OnLdPreview / CMessageDlg +TITLE_LYRIC_PREVIEW = "Lyric Preview" + +# CCrashReport::ShowCrashInfo / CMessageDlg +TITLE_CRASH_REPOART = "Error" +TXT_CRASH_REPOART_ERROR_MESSAGE = "Error Message:" +TXT_CRASH_REPOART_CRASH_INFO = "Sorry, the program has crashed. Please email this file \"<%1%>\" to zhongyang219@hotmail.com to help the author locate the problem. And add the following to the body of the message:\r\n<%2%>" + +# CAboutDlg::OnNMClickLicenseSyslink / CMessageDlg +TITLE_LICENSE = "License" +TXT_LICENSE_EXPLAIN = "Please follow the following open source license when using the source code of this software." + +# CAboutDlg::OnNMClickAcknowledgementSyslink / CMessageDlg +TITLE_ACKNOWLEDGEMENT = "Acknowledgement" +TXT_ACKNOWLEDGEMENT_INFO = "Thanks to the following GitHub users for their contributions to this project!" + +# CMusicPlayerApp::OnHelp / CMessageDlg +TITLE_HELP_DLG = "Help" +TXT_HELP_DLG_WELCOM_TO_USE = "Welcome to use MusicPlayer2!" +TXT_HELP_DLG_SHOW_ONLINE_HELP = "Click here for detailed online help documentation." +TXT_HELP_DLG_HELP_INFO = "[Feature Introduction]\r\nMusicPlayer2 is an audio player which with a collection of music playback, lyrics display, format conversion and many other functions. It supports lyrics display, lyrics karaoke style display, lyrics online download, lyrics editing, song tag recognition, album cover display, album cover online download, spectrum analysis, sound effect settings, taskbar thumbnail button, theme color, format conversion and other functions.\r\nThe playback kernel is the Bass Audio Library (V2.4).\r\nThe player supports almost all common audio formats. A detailed list of supported files is shown in the \"Supported Formats\" of the \"Help\" menu.\r\n\r\n[Operating Instructions]\r\nYou have the following ways to open and play a song:\r\n1. Select the \"Open File\" or \"Open Folder\" command in the \"File\" menu.\r\n2. In the \"Media Library\" dialog box, choose a previously played folder in the \"Folder\" tab, or click the \"Open New Folder\" button to play a new folder.\r\n3. In the \"Media Library\" dialog box, select a previously played playlist in the \"Playlist\" tab, or click the \"New Playlist\" button to create a new playlist.\r\n4. Drag and drop the file or folder directly into the program's main window.\r\n5. Drag and drop the file or folder directly onto the program's icon or its shortcut icon.\r\n\r\n[Media Library]\r\nClick the \"Media Library\" button in the upper right corner of the main interface, or use the shortcut key \"Ctrl+T\" to open the Media Library dialog box.\r\nThe media library provides two modes of folder and playlist to manage and organize music.\r\nIn the folder mode, each time you open a folder for playback, the player will automatically search the audio files in the folder and load them into the playlist. At this time, you cannot add, delete, move up, and down on the items in the list.\r\nIn playlist mode, you can create a playlist and freely add audio files to the playlist. In this mode, you can freely edit the items in the list, and add, delete, move up, move down and other commands are alse in the available status.\r\nThere are two special playlists in playlist mode: \"Default\" and \"My favourite\", you can't perform renaming and deleting on these two playlists. Among them, the audio file opened from the Explorer will be added to the \"default\" playlist. Clicking the \"Favourite\" button in the main interface will add the current song to the \"My favourite\" playlist.\r\n\r\n[Switch interface]\r\nCurrently MusicPlayer2 provides 2 built-in UI layouts and several user-defined UI layouts.\r\nAll UI layouts can be switched through the main menu \"View\" - \"Switch UI\" submenu. Use the shortcut \"Ctrl+U\" to switch all available UI layouts in turn, or use the shortcut \"Ctrl+number\" keys to switch to the specified interface.\r\n\r\n【User-defined UI】\r\nMusicPlayer2 supports custom UI layout through xml files. User-defined UI files are placed in the \"skins\" directory under the directory where the program is located.\r\nThe UI 1 to 2 that under the \"Switch UI\" submenu are the UI layouts built into the program, and the other UI are provided by the xml files in the skins directory. To learn how to edit the user-defined UI layout, click \"Help\" - \"Custom UI\" in the main menu to view detailed instructions on the user-defined UI.\r\n\r\n[Shortcut key description]\r\nPlay/Pause: Spaces\r\nPrevious Song: V\r\nNext Song: N\r\nFast Forward for 5 sec: Right\r\nRewind for 5 Seconds: Left\r\nVolume Up: Up\r\nVolume Down: Down\r\nSwitch Repeat Mode: M\r\nQuick Find: F\r\nSelect Folder: Ctrl+T\r\nFind Songs: Ctrl+F\r\nOpen File Location: Ctrl+B\r\nOption Settings: Ctrl+I\r\nOpen File: Ctrl+O\r\nOpen Folder: Ctrl+D\r\nLyrics Adjustment: Ctrl+PgUp/Ctrl+PgDn\r\nSave Lyrics Adjustment: Ctrl+S\r\nMini Mode: Ctrl+M\r\nTrack Information: Ctrl+N\r\nSound Effect Settings: Ctrl+E\r\nFull Screen: F11\r\nShow/Hide playlist: Ctrl+L\r\nFloat playlist: Ctrl+K\r\nAB Repeat: Ctrl+R\r\nSwitch UI: Ctrl+U/Ctrl+Num key\r\n\r\n[Mouse Action]\r\n- Use mouse wheel to adjust volume.\r\n- Hold Shift and click the right mouse button to pop up the system menu." + +[scintlla] +TXT_SCI_UNDO = "Undo" +TXT_SCI_REDO = "Redo" +TXT_SCI_CUT = "Cut" +TXT_SCI_COPY = "Copy" +TXT_SCI_PASTE = "Paste" +TXT_SCI_DELETE = "Clear" +TXT_SCI_SELECT_ALL = "Select All" + +[menu.MAIN_POP] +MAIN_FILE = "&File" +MAIN_PLAYCTRL = "Play &Control" +MAIN_PLAYLIST = "&Playlist" +MAIN_LRC = "&Lyrics" +MAIN_VIEW = "&View" +MAIN_TOOL = "&Tool" +MAIN_HELP = "&Help" +ID_MENU_EXIT = "E&xit" +; DEBUG only +ID_TEST = "Test Command" +ID_TEST_DIALOG = "Test Dialog" + +[menu.MAIN] +MAIN_FILE = "&File" +MAIN_PLAYCTRL = "Play &Control" +MAIN_PLAYLIST = "&Playlist" +MAIN_LRC = "&Lyrics" +MAIN_VIEW = "&View" +MAIN_TOOL = "&Tool" +MAIN_HELP = "&Help" + +[menu.MAIN_FILE] +ID_FILE_OPEN = "&Open File..." +ID_FILE_OPEN_FOLDER = "Open &Folder..." +ID_FILE_OPEN_URL = "Open &URL..." +ID_FILE_OPEN_PLAYLIST = "Open &Playlist..." +ID_MENU_EXIT = "E&xit" + +[menu.MAIN_PLAYCTRL] +ID_PLAY_PAUSE = "&Play/Pause" +ID_STOP = "&Stop" +ID_PREVIOUS = "Pre&vious" +ID_NEXT = "&Next" +ID_REW = "&Rewind for 5 Seconds" +ID_FF = "&Fast forward for 5 Seconds" +ID_SPEED_UP = "Speed &Up Playback" +ID_SLOW_DOWN = "Slow &Down Playback" +ID_ORIGINAL_SPEED = "&Original Speed Playback" +MAIN_PLAYCTRL_REPEAT_MODE = "Repeat &Mode" +MAIN_PLAYCTRL_AB = "AB R&epeat" + +[menu.MAIN_PLAYCTRL_REPEAT_MODE] +ID_PLAY_ORDER = "Play in &Order" +ID_PLAY_SHUFFLE = "Play &Shuffle" +ID_PLAY_RANDOM = "Play &Random" +ID_LOOP_PLAYLIST = "&Loop Playlist" +ID_LOOP_TRACK = "Loop &Track" +ID_PLAY_TRACK = "&Play Once" + +[menu.MAIN_PLAYCTRL_AB] +ID_AB_REPEAT = "AB &Repeat" +ID_SET_A_POINT = "Set &A Point" +ID_SET_B_POINT = "Set &B Point" +ID_NEXT_AB_REPEAT = "Continue &Next AB Repeat" +ID_RESET_AB_REPEAT = "&Cancel AB Repeat" + +[menu.MAIN_PLAYLIST] +MAIN_PLAYLIST_ADD = "&Add" +MAIN_PLAYLIST_DEL = "&Delete" +ID_RELOAD_PLAYLIST = "&Reload Playlist" +ID_SAVE_AS_NEW_PLAYLIST = "Save As &New Playlist..." +ID_SAVE_CURRENT_PLAYLIST_AS = "&Save Current Playlist As..." +MAIN_PLAYLIST_SORT = "S&ort" +MAIN_PLAYLIST_DISP_MODE = "Playlist Display &Mode" +ID_LOCATE_TO_CURRENT = "&Locate the track is playing" + +[menu.MAIN_PLAYLIST_ADD] +ID_PLAYLIST_ADD_FILE = "&Add Files..." +ID_PLAYLIST_ADD_FOLDER = "Add &Folder..." +ID_PLAYLIST_ADD_URL = "Add &URL..." + +[menu.MAIN_PLAYLIST_DEL] +ID_REMOVE_FROM_PLAYLIST = "Remo&ve from Playlist" +ID_DELETE_FROM_DISK = "&Delete from Disk" +ID_EMPTY_PLAYLIST = "Cl&ear Playlist" +ID_REMOVE_SAME_SONGS = "Remove &Same Items" +ID_REMOVE_INVALID_ITEMS = "Remove &Invalid Items" + +[menu.MAIN_PLAYLIST_SORT] +ID_SORT_BY_FILE = "Sort by File Name" +ID_SORT_BY_PATH = "Sort by Path" +ID_SORT_BY_TITLE = "Sort by Title" +ID_SORT_BY_ARTIST = "Sort by Artist" +ID_SORT_BY_ALBUM = "Sort by Album" +ID_SORT_BY_TRACK = "Sort by Track" +ID_SORT_BY_LISTEN_TIME = "Sort by Listen Time" +ID_SORT_BY_MODIFIED_TIME = "Sort by Modified Time" + +[menu.MAIN_PLAYLIST_DISP_MODE] +ID_DISP_FILE_NAME = "File Name" +ID_DISP_TITLE = "Title" +ID_DISP_ARTIST_TITLE = "Artist - Title" +ID_DISP_TITLE_ARTIST = "Title - Artist" + +[menu.MAIN_LRC] +ID_RELOAD_LYRIC = "&Reload Lyrics" +ID_COPY_CURRENT_LYRIC = "&Copy Current Lyric" +ID_COPY_ALL_LYRIC = "Copy &All Lyrics" +ID_EDIT_LYRIC = "&Edit Lyrics..." +MAIN_LRC_CH_CONV = "Chinese Con&version" +ID_SHOW_LYRIC_TRANSLATE = "Show Lyrics &Translation" +ID_SHOW_DESKTOP_LYRIC = "S&how Desktop Lyrics" +ID_LYRIC_FORWARD = "Lyrics 0.5 Seconds in Adva&nce" +ID_LYRIC_DELAY = "Lyrics 0.5 Seconds Dela&yed" +ID_SAVE_MODIFIED_LYRIC = "&Save Lyrics Changes" +ID_RELATE_LOCAL_LYRIC = "Lin&k local lyrics..." +ID_DELETE_LYRIC = "&Delete Lyrics" +ID_UNLINK_LYRIC = "&Unlink Lyrics" +ID_BROWSE_LYRIC = "O&pen Lyrics File Location" +MAIN_LRC_INNER_LRC = "&Internal Lyrics" +ID_DOWNLOAD_LYRIC = "Down&load Lyrics..." +ID_LYRIC_BATCH_DOWNLOAD = "Lyrics &Batch Download..." +MAIN_VIEW_SWITCH_UI = "S&witch UI" +ID_OPTION_SETTINGS = "&Options..." + +[menu.MAIN_LRC_CH_CONV] +ID_TRANSLATE_TO_SIMPLIFIED_CHINESE = "Convert to &Simplified Chinese" +ID_TRANSLATE_TO_TRANDITIONAL_CHINESE = "Convert to &Traditional Chinese" + +[menu.MAIN_LRC_INNER_LRC] +ID_EMBED_LYRIC_TO_AUDIO_FILE = "&Embed Into Audio File" +ID_DELETE_LYRIC_FROM_AUDIO_FILE = "&Remove From Audio File" + +[menu.MAIN_VIEW] +ID_SHOW_PLAYLIST = "Show &Playlist" +ID_FLOAT_PLAYLIST = "F&loating Playlist" +ID_USE_STANDARD_TITLE_BAR = "Use System Standard Title &Bar" +ID_SHOW_MENU_BAR = "Show Me&nu Bar" +ID_ALWAYS_SHOW_STATUS_BAR = "Always Show &Status Bar" +ID_ALWAYS_ON_TOP = "Always on &Top" +ID_MINI_MODE = "&Mini Mode" +ID_FULL_SCREEN = "&Full Screen" +ID_DARK_MODE = "&Dark Mode" +MAIN_VIEW_SWITCH_UI = "Switch &UI" + +[menu.MAIN_VIEW_SWITCH_UI] +ID_SWITCH_UI = "Switch &UI" + +[menu.MAIN_TOOL] +ID_MEDIA_LIB = "&Media Library..." +ID_FIND = "&Find Songs..." +ID_EXPLORE_PATH = "Open File &Location" +ID_SONG_INFO = "Song &Info..." +ID_EQUALIZER = "Sound &Effect Settings..." +ID_FORMAT_CONVERT1 = "Format &Convert..." +ID_CURRENT_EXPLORE_ONLINE = "&View Online" +ID_RE_INI_BASS = "&Reinitialize the Player" +MAIN_TOOL_SHORTCUT = "Create &Shortcut" +MAIN_TOOL_ALBUM_COVER = "&Album Cover" +MAIN_TOOL_DEL_CUR_PLAYING = "Delete Current Playing Track" +ID_LISTEN_STATISTICS = "Play Time Statistics..." +ID_TOOL_FILE_RELATE = "File Relate..." +ID_OPTION_SETTINGS = "&Options..." + +[menu.MAIN_TOOL_SHORTCUT] +ID_CREATE_DESKTOP_SHORTCUT = "Create &Desktop Shortcut" +ID_CREATE_PLAY_SHORTCUT = "Create Play Control &Shortcut" +ID_CREATE_MINI_MODE_SHORT_CUT = "Create &Mini Mode Shortcut" + +[menu.MAIN_TOOL_ALBUM_COVER] +ID_DOWNLOAD_ALBUM_COVER = "Download &Album Cover..." +ID_ALBUM_COVER_SAVE_AS = "Album Cover &Save As..." +ID_DELETE_ALBUM_COVER = "&Delete Album Cover" +ID_ALBUM_COVER_INFO = "Album &Cover Details..." + +[menu.MAIN_TOOL_DEL_CUR_PLAYING] +ID_REMOVE_CURRENT_FROM_PLAYLIST = "Remove from &Playlist" +ID_DELETE_CURRENT_FROM_DISK = "Delete from &Disk" + +[menu.MAIN_HELP] +ID_HELP = "&Help" +ID_ONLINE_HELP = "&Online Help" +ID_HELP_FAQ = "&FAQ" +ID_HELP_CUSTOM_UI = "Custom &UI" +ID_HELP_UPDATE_LOG = "Update &Log" +ID_SUPPORTED_FORMAT = "Supproted &Format" +ID_APP_ABOUT = "&About..." + +[menu.PLAYLIST_TOOLBAR] +MAIN_PLAYLIST_ADD = "&Add" +MAIN_PLAYLIST_DEL = "&Delete" +MAIN_PLAYLIST_SORT = "&Sort" +PLAYLIST_TOOLBAR_LIST = "&Playlist" +PLAYLIST_TOOLBAR_EDIT = "&Edit" +PLAYLIST_TOOLBAR_FOLDER = "&Folder" +ID_LOCATE_TO_CURRENT = "&Locate" + +[menu.PLAYLIST_TOOLBAR_LIST] +ID_RELOAD_PLAYLIST = "&Reload Playlist" +ID_SAVE_AS_NEW_PLAYLIST = "Save As &New Playlist..." +ID_SAVE_CURRENT_PLAYLIST_AS = "&Save Current Playlist As..." +ID_PLAYLIST_FIX_PATH_ERROR = "&Fix the wrong file path" +MAIN_PLAYLIST_DISP_MODE = "&Playlist Display Mode" +ID_PLAYLIST_OPTIONS = "&Options..." + +[menu.PLAYLIST_TOOLBAR_EDIT] +ADD_TO_PLAYLIST = "Add to Playlis&t" +ID_COPY_FILE_TO = "&Copy File to..." +ID_MOVE_FILE_TO = "&Move File to..." +ID_MOVE_PLAYLIST_ITEM_UP = "Move &Up" +ID_MOVE_PLAYLIST_ITEM_DOWN = "Move Do&wn" +ID_PLAYLIST_SELECT_ALL = "Select &All" +ID_PLAYLIST_SELECT_NONE = "Select N&one" +ID_PLAYLIST_SELECT_REVERT = "Select &Reverse" + +[menu.PLAYLIST_TOOLBAR_FOLDER] +ID_FILE_OPEN_FOLDER = "Open &Folder..." +ID_CONTAIN_SUB_FOLDER = "Contains &Subfolders" + +[menu.MAIN_AREA] +ID_SONG_INFO = "Song &Info..." +MAIN_PLAYCTRL_REPEAT_MODE = "Repeat &Mode" +ADD_TO_PLAYLIST = "Add to Playlis&t" +RATE = "R&ate" +ID_MEDIA_LIB = "Media &Library..." +ID_FIND = "&Find Songs..." +ID_EXPLORE_PATH = "O&pen File Location" +ID_EQUALIZER = "Sound &Effect Settings..." +ID_CURRENT_EXPLORE_ONLINE = "&View Online" +ID_DOWNLOAD_ALBUM_COVER = "Download &Album Cover..." +ID_ALBUM_COVER_SAVE_AS = "Album Cover &Save As..." +ID_DELETE_ALBUM_COVER = "&Delete Album Cover" +ID_ALWAYS_USE_EXTERNAL_ALBUM_COVER = "Always Use Exter&nal Album Cover" +ID_ALBUM_COVER_INFO = "Album &Cover Details..." +ID_VIEW_ARTIST = "View A&rtist..." +ID_VIEW_ALBUM = "View Al&bum..." +MAIN_VIEW_SWITCH_UI = "Switch &UI" +ID_OPTION_SETTINGS = "&Options..." + +[menu.MAIN_AREA_PLAYLIST_BTN] +ID_DOCKED_PLAYLIST = "&Docked Playlist" +ID_FLOATED_PLAYLIST = "&Floating Playlist" + +[menu.DLRC] +ID_PLAY_PAUSE = "&Play/Pause" +ID_STOP = "&Stop" +ID_PREVIOUS = "Pre&vious" +ID_NEXT = "&Next" +MAIN_PLAYCTRL_REPEAT_MODE = "Repeat &Mode" +ID_SHOW_MAIN_WINDOW = "Show Main &Window" +ID_LYRIC_DISPLAYED_DOUBLE_LINE = "Lyrics Displayed in &Double Line" +ID_LYRIC_BACKGROUND_PENETRATE = "Lyric &Background Penetrate" +ID_LOCK_DESKTOP_LRYIC = "&Lock Desktop Lyric" +DLRC_DEFAULT_STYLE = "D&efault Style" +ID_OPTION_SETTINGS = "&Options..." +ID_CLOSE_DESKTOP_LYRIC = "&Close Desktop Lyric" + +[menu.DLRC_DEFAULT_STYLE] +ID_LYRIC_DEFAULT_STYLE1 = "Default &1" +ID_LYRIC_DEFAULT_STYLE2 = "Default &2" +ID_LYRIC_DEFAULT_STYLE3 = "Default &3" + +[menu.RECENT_FOLDER_PLAYLIST] +ID_MEDIA_LIB = "Media &Library..." + +[menu.PLAYLIST] +ID_PLAY_ITEM = "&Play" +ID_PLAY_AS_NEXT = "Play &Next" +ID_EXPLORE_ONLINE = "View &Online" +ID_FORMAT_CONVERT = "&Format Convert..." +RATE = "R&ate" +ID_RELOAD_PLAYLIST = "&Reload Playlist" +ID_REMOVE_FROM_PLAYLIST = "Remo&ve from Playlist" +ID_DELETE_FROM_DISK = "&Delete from Disk" +ADD_TO_PLAYLIST = "Add to Playlis&t" +ID_COPY_FILE_TO = "&Copy File to..." +ID_MOVE_FILE_TO = "&Move File to..." +ID_MOVE_PLAYLIST_ITEM_UP = "Move &Up" +ID_MOVE_PLAYLIST_ITEM_DOWN = "Move Do&wn" +ID_PLAYLIST_VIEW_ARTIST = "View Art&ist..." +ID_PLAYLIST_VIEW_ALBUM = "View Al&bum...." +ID_RENAME = "Renam&e..." +ID_EXPLORE_TRACK = "Open File &Location" +ID_ITEM_PROPERTY = "Propert&y..." + +[menu.RATE] +ID_RATING_1 = "&1 star" +ID_RATING_2 = "&2 stars" +ID_RATING_3 = "&3 stars" +ID_RATING_4 = "&4 stars" +ID_RATING_5 = "&5 stars" +ID_RATING_NONE = "&Unrated" + +[menu.ADD_TO_PLAYLIST] +ID_ADD_TO_NEW_PLAYLIST = "&New Playlist..." +ID_ADD_TO_DEFAULT_PLAYLIST = "Default" +ID_ADD_TO_MY_FAVOURITE = "My Favourite" +ID_ADD_TO_OTHER_PLAYLIST = "&More Playlist..." + +[menu.MINI_AREA] +ID_SONG_INFO = "Song &Info..." +MAIN_PLAYCTRL_REPEAT_MODE = "Repeat &Mode" +ADD_TO_PLAYLIST = "Add to Playlis&t" +ID_DOWNLOAD_LYRIC = "&Download Lyrics..." +ID_DOWNLOAD_ALBUM_COVER = "Download &Album Cover..." +ID_ADD_REMOVE_FROM_FAVOURITE = "Add to My Fa&vourite" +ID_MEDIA_LIB = "Media &Library..." +ID_FIND = "&Find Songs..." +ID_EXPLORE_PATH = "Open File Lo&cation" +ID_EQUALIZER = "Sound &Effect Settings..." +ID_OPTION_SETTINGS = "&Options..." +ID_SHOW_PLAY_LIST = "Sho&w Playlist" +ID_MINI_MODE_ALWAYS_ON_TOP = "Always on &Top" +MINI_SWITCH_UI = "Switch &UI" +ID_MINI_MIDE_MINIMIZE = "Minimi&ze" +IDOK = "Back to &Normal" +ID_MINI_MODE_EXIT = "E&xit" + +[menu.MINI_SWITCH_UI] +ID_MINIMODE_UI_DEFAULT = "&Default UI" + +[menu.NOTIFY] +ID_PLAY_PAUSE = "&Play/Pause" +ID_PREVIOUS = "Pre&vious" +ID_NEXT = "&Next" +MAIN_PLAYCTRL_REPEAT_MODE = "Repeat &Mode" +ID_MINIMODE_RESTORE = "Mini Mode/&Restore" +ID_SHOW_DESKTOP_LYRIC = "&Show Desktop Lyrics" +ID_LOCK_DESKTOP_LRYIC = "&Lock Desktop Lyrics" +ID_OPTION_SETTINGS = "&Options..." +ID_MENU_EXIT = "E&xit" + +[menu.LIB_SET_PATH] +ID_PLAY_PATH = "&Play Folder" +ID_DELETE_PATH = "&Delete From List" +ID_BROWSE_PATH = "&Open Folder Location" +ID_CONTAIN_SUB_FOLDER = "Contains &Subfolders" +ID_CLEAR_INVALID_PATH = "&Clear Invalid Folder" + +[menu.LIB_PLAYLIST] +ID_PLAY_PLAYLIST = "&Play" +ID_RENAME_PLAYLIST = "&Rename..." +ID_DELETE_PLAYLIST = "&Delete..." +ID_SAVE_AS_NEW_PLAYLIST = "Save As &New Playlist..." +ID_PLAYLIST_SAVE_AS = "Save &As..." +ID_PLAYLIST_BROWSE_FILE = "&Open playlist file location" +ID_PLAYLIST_FIX_PATH_ERROR = "&Fix the wrong file path" +ID_NEW_PLAYLIST = "&New Playlist..." + +[menu.LIB_LEFT] +ID_PLAY_ITEM = "&Play" +ADD_TO_PLAYLIST = "Add to Playlis&t" +ID_ADD_TO_NEW_PLAYLIST_AND_PLAY = "Add to &New Playlist And Play..." +ID_COPY_TEXT = "&Copy Text" + +[menu.LIB_RIGHT] +ID_PLAY_ITEM = "&Play" +ID_PLAY_AS_NEXT = "Play &Next" +ID_PLAY_ITEM_IN_FOLDER_MODE = "Play in &Folder Mode" +ADD_TO_PLAYLIST = "Add to Playlis&t" +ID_ADD_TO_NEW_PLAYLIST_AND_PLAY = "Add to &New Playlist And Play..." +ID_EXPLORE_ONLINE = "View &Online" +ID_FORMAT_CONVERT = "Format Con&vert..." +ID_EXPLORE_TRACK = "Open File &Location" +ID_DELETE_FROM_DISK = "&Delete from Disk" +ID_ITEM_PROPERTY = "Propert&y..." +ID_COPY_TEXT = "&Copy Text" + +[menu.LE] +LE_FILE = "&File" +LE_EDIT = "&Edit" +LE_PLAY_CTRL = "&Play Control" + +[menu.LE_FILE] +ID_LYRIC_OPEN = "&Open..." +ID_LYRIC_SAVE = "&Save" +ID_LYRIC_SAVE_AS = "Save &As..." +IDCANCEL = "E&xit" + +[menu.LE_EDIT] +ID_LYRIC_INSERT_TAG = "&Insert Time Tag" +ID_LYRIC_REPLACE_TAG = "&Replace Time Tag" +ID_LYRIC_DELETE_TAG = "&Delete Time Tag" +ID_LYRIC_FIND = "&Find..." +ID_LYRIC_REPLACE = "&Replace..." +ID_FIND_NEXT = "Find &Next" +LE_EDIT_CH_CONV = "Chinese &Conversion" +ID_LRYIC_MERGE_SAME_TIME_TAG = "&Merge lyrics with the same time tag" +ID_LYRIC_SWAP_TEXT_AND_TRANSLATION = "&Swap the lyric text and translation" +LE_EDIT_TAG_DISLOC = "Time tag dis&location" + +[menu.LE_EDIT_CH_CONV] +ID_LE_TRANSLATE_TO_SIMPLIFIED_CHINESE = "Convert to &Simplified Chinese" +ID_LE_TRANSLATE_TO_TRANDITIONAL_CHINESE = "Convert to &Traditional Chinese" + +[menu.LE_EDIT_TAG_DISLOC] +ID_LYRIC_TIME_TAG_FORWARD = "One sentence &ahead of time tag" +ID_LYRIC_TIME_TAG_DELAY = "One sentence &postponed of time tag" + +[menu.LE_PLAY_CTRL] +ID_PLAY_PAUSE = "&Play/Pause" +ID_REW = "&Rewind" +ID_FF = "&Fast Forward" +ID_SEEK_TO_CUR_LINE = "&Seek to current line" + +[menu.FC_LIST] +ID_ADD_FILE = "&Add File..." +ID_CLEAR_LIST = "&Clear List" +ID_EDIT_TAG_INFO = "&Edit Tag Info..." +ID_DELETE_SELECT = "&Delete" +ID_MOVE_UP = "Move &Up" +ID_MOVE_DOWN = "Move Do&wn" + +[menu.LD_LIST] +ID_LD_LYRIC_DOWNLOAD = "&Download" +ID_LD_PREVIEW = "&Preview" +ID_LD_LYRIC_SAVEAS = "&Save As..." +ID_LD_COPY_TITLE = "Copy Song &Title" +ID_LD_COPY_ARTIST = "Copy &Artist" +ID_LD_COPY_ALBUM = "Copy Al&bum" +ID_LD_COPY_ID = "Copy Song &ID" +ID_LD_RELATE = "&Link This Item" +ID_LD_VIEW_ONLINE = "&View Online" + +[menu.OPT_DLRC_DEFAULT_STYLE] +ID_LYRIC_DEFAULT_STYLE1 = "Preset &1" +ID_LYRIC_DEFAULT_STYLE2 = "Preset &2" +ID_LYRIC_DEFAULT_STYLE3 = "Preset &3" +OPT_DLRC_MOD_DEF_STYLE = "&Modify Style Preset" + +[menu.OPT_DLRC_MOD_DEF_STYLE] +ID_LYRIC_DEFAULT_STYLE1_MODIFY = "Save as Preset &1" +ID_LYRIC_DEFAULT_STYLE2_MODIFY = "Save as Preset &2" +ID_LYRIC_DEFAULT_STYLE3_MODIFY = "Save as Preset &3" +ID_RESTORE_DEFAULT_STYLE = "&Restore Default" + +[menu.PROPERTY_ADV] +ID_COPY_TEXT = "&Copy Text" +ID_COPY_ALL_TEXT = "Copy &All Text" + +[menu.PROPERTY_COVER] +ID_COVER_BROWSE = "&Browse..." +ID_COVER_DELETE = "&Delete" +ID_COVER_SAVE_AS = "&Save As..." +ID_COMPRESS_SIZE = "&Compress Size" diff --git a/MusicPlayer2/language/Simplified_Chinese.ini b/MusicPlayer2/language/Simplified_Chinese.ini new file mode 100644 index 000000000..94d0f922d --- /dev/null +++ b/MusicPlayer2/language/Simplified_Chinese.ini @@ -0,0 +1,1470 @@ +[general] +BCP_47 = "zh-CN" +DISPLAY_NAME = "简体中文" +TRANSLATOR = "MusicPlayer2" +;DEFAULT_FONT = "Microsoft YaHei UI" + +[text] +# User UI String +TXT_UI_NAME_DEFAULT = "界面 <%1%>" +TXT_UI_NAME_MINI_DEFAULT = "迷你模式 <%1%>" +TXT_UI_NAME_SIMPLE_UI = "简洁UI" +TXT_UI_NAME_GROOVE_MUSIC_STYLE = "Groove音乐风格" +TXT_UI_LYRIC_SHOW = "歌词秀" +TXT_UI_FORMAT = "格式" + +# Column Header / Tab title +TXT_SERIAL_NUMBER = "序号" +TXT_ITEM = "项目" +TXT_VALUE = "值" +TXT_FILE_NAME = "文件名" +TXT_FILE_PATH = "文件路径" +TXT_PATH = "路径" +TXT_TITLE = "标题" +TXT_TRACK = "曲目" +TXT_NUM_OF_TRACK = "曲目数" +TXT_LENGTH = "时长" +TXT_TOTAL_LENGTH = "总时长" +TXT_TRACK_NUM = "音轨号" +TXT_LAST_PLAYED_TRACK = "上次播放" +TXT_LAST_PLAYED_TIME = "上次播放时间" + +TXT_FOLDER = "文件夹" +TXT_PLAYLIST = "播放列表" +TXT_ARTIST = "艺术家" +TXT_ALBUM = "唱片集" +TXT_GENRE = "流派" +TXT_YEAR = "年份" +TXT_FILE_TYPE = "文件类型" +TXT_BITRATE = "比特率" +TXT_RATING = "分级" +TXT_ALL_TRACKS = "所有曲目" +TXT_RECENT_PLAYED = "最近播放" +TXT_FOLDER_EXPLORE = "文件夹浏览" + +# MessageBox +MSG_APP_RUNING_INFO = "MusicPlayer2 还在进行,请等待进程退出,或者通过任务管理器结束进程。" +MSG_WAIT_AND_RETRY = "请等待当前操作完成后重试。" +MSG_UNICODE_WARNING = "要保存的内容含有Unicode字符,如果以ANSI格式保存,这些字符将会丢失。如果要保留这些字符,请选择保存为UTF-8格式。确实要保存吗?" +MSG_SERIALIZE_ERROR = "读取数据文件“<%1%>”时发生了序列化异常,异常类型:CArchiveException,m_cause = <%2%>。可能是数据文件被损坏或版本不匹配造成的。" +MSG_BASS_VERSION_WARNING = "bass.dll文件版本不匹配,版本为<%1%>,期望的版本为<%2%>。不匹配的版本可能会导致播放异常,仍要继续吗?" +MSG_SCI_NOT_LOADED_ERROR = "无法打开此对话框,因为 SciLexer.dll 没有正确加载,请检查 SciLexer.dll 是否丢失!" +MSG_MCI_NO_THIS_FUNCTION_WARNING = "MCI内核无法使用此功能!" +MSG_FFMPEG_NO_THIS_FUNCTION_WARNING = "FFMPEG内核下暂不支持此功能!" +MSG_UPDATE_CHECK_FAILED = "检查更新失败,请检查你的网络连接!" +MSG_UPDATE_CHECK_ERROR = "检查更新出错,从远程获取到了错误的信息,请联系作者!\r\n<%1%>" +MSG_UPDATE_AVLIABLE = "检测到新版本 V<%1%>,是否前往更新?" +MSG_UPDATE_AVLIABLE_2 = "检测到新版本 V<%1%>,更新内容:\r\n<%2%>\r\n是否前往更新?" +MSG_UPDATE_ALREADY = "当前已经是最新版本。" +MSG_SHORTCUT_INQUARY_FIRST = "你可能是第一次运行此程序,是否要在桌面上创建程序的快捷方式?" +MSG_SHORTCUT_INQUARY_DESKTOP = "确实要创建程序的桌面快捷方式吗?" +MSG_SHORTCUT_INQUARY_MINIMODE = "此命令将会在程序所在目录下创建一个迷你模式的快捷方式,通过此快捷方式将总是以迷你模式启动播放器。要创建迷你模式快捷方式吗?" +MSG_SHORTCUT_INQUARY_PLAY_CONTROL = "此命令将会在程序所在目录下创建播放控制快捷方式,当播放器正在运行时,你可以通过这些快捷方式来控制音乐的播放。你也可以将它们固定到任务栏。要创建播放控制快捷方式吗?" +MSG_SHORTCUT_CREATED = "已经在“<%1%>”路径下创建了程序的快捷方式。" +MSG_SHORTCUT_FAILED = "快捷方式创建失败!" +MSG_DELETE_SEL_AUDIO_FILE_INQUARY = "确实要删除选中的 <%1%> 首歌曲吗?" +MSG_DELETE_INNER_COVER_INQUERY = "当前专辑封面是内嵌在音频文件里的,删除后将不可恢复,确实要删除内嵌的专辑封面吗?" +MSG_DELETE_SINGLE_FILE_INQUARY = "确实要删除文件“<%1%>”吗?" +MSG_DELETE_FILE_FAILED = "无法删除文件!" +MSG_FILE_WRITE_FAILED = "无法写入文件!" +MSG_COPY_CLIPBOARD_FAILED = "复制到剪贴板失败!" +MSG_COPY_CLIPBOARD_ALL_LYRIC = "已复制全部歌词到剪贴板。" +MSG_NO_MIDI_SF2_WARNING = "你正在播放 MIDI 音乐,但是由于没有正确载入 MIDI 音色库,因此你将听不到任何声音。 请在菜单“工具”——“选项”——“常规设置”的“MIDI 音色库路径”中选择正确的MIDI 音色库路径。 点击“取消”不再提示。" +MSG_LYRIC_SAVE_INRUARY = "歌词已更改,是否要保存?" +MSG_LYRIC_SAVE_FAILED = "歌词保存失败,请检查目标文件夹是否有写入权限!" +MSG_LYRIC_FOLDER_NOT_EXIST = "歌词文件夹不存在,请重新设置歌词文件夹!" +MSG_PLAYLIST_REMOVE_SONGS = "完成,已删除 <%1%> 个项目。" +MSG_PLAYLIST_CLEAR_WARNING = "确实要清空播放列表吗?" +MSG_REMOVE_FAVOURITE_WARNING = "取消“我喜欢”会将正在播放的曲目从当前播放列表中移除,要继续吗?" +MSG_PLAYLIST_NAME_EMPTY_WARNING = "播放列表名称不能为空!" +MSG_FILE_NAME_INVALID_WARNING = "名称中不能包含以下字符:\r\n\\\"/:*?<>|" +MSG_PLAYLIST_EXIST_WARNING = "播放列表“<%1%>”已存在!" +MSG_FILE_EXIST_IN_PLAYLIST = "文件已存在于播放列表中。" +MSG_PLAYLIST_REMANE_FAILED = "播放列表重命名失败!" +MSG_PLAYLIST_ADD_SONGS_FAILED = "添加失败,播放列表“<%1%>”不存在!" +MSG_PLAYLIST_FIX_ERROR_PATH_INQUARY = "此功能将会检查播放列表中不存在的曲目,通过在媒体库中寻找匹配的曲目来修复错误的路径。需要修复播放列表中错误的路径吗?" +MSG_PLAYLIST_FIX_ERROR_PATH_COMPLETE = "完成,已修复<%1%>个错误的路径。" +MSG_HIDE_MENU_BAR_INFO = "提示:隐藏菜单栏后可以右击窗口标题栏,或者点击右上角的主菜单“≡”按钮,在弹出的菜单中选择“视图”——“显示菜单栏”以重新显示菜单栏。\r\n点击“取消”不再提示。" +MSG_CANNOT_FIND_ARTIST_WARNING = "无法在媒体库中找到艺术家 <%1%>!" +MSG_CANNOT_FIND_ALBUM_WARNING = "无法在媒体库中找到唱片集 <%1%>!" + +MSG_NETWORK_CONNECTION_FAILED = "网络连接失败或超时!" +MSG_NETWORK_CANNOT_FIND_THIS_SONG = "找不到此歌曲!" +MSG_NETWORK_LYRIC_DOWNLOAD_FAILED = "歌词下载失败!" +MSG_NETWORK_SONG_NO_LYRIC = "该歌曲没有歌词!" +MSG_NETWORK_DOWNLOAD_COMPLETE = "下载完成。" +MSG_NETWORK_SEARCH_FAILED = "搜索失败,请检查你的网络连接!" +MSG_NETWORK_SEARCH_TIME_OUT = "搜索超时!" +MSG_NETWORK_COVER_DOWNLOAD_FAILED = "专辑封面下载失败,请检查你的网络连接!" +MSG_LYRIC_OVERWRITE_INQUARY = "歌词文件已存在,要替换它吗?" +MSG_LYRIC_DOWNLOAD_COMPLETE_SAVED = "歌词下载完成,保存为“<%1%>”。" + +# error.log +LOG_RESTART_EXIT = "程序已被Windows的RestartManager重启,重启参数:<%1%>,程序已退出。" +LOG_CRASH_ERROR = "程序崩溃了,dump文件已经保存到“<%1%>”。" +LOG_BASS_FORMAT_CONVERT_ERROR = "文件 “<%1%>” 使用BASS内核格式转换到<%2%>出错,BASS错误代码: <%3%>。" +LOG_BASS_ERROR = "BASS音频库发生了错误,错误代码:<%1%>,文件:<%2%>" +LOG_SF2_LOAD_FAILED = "音色库“<%1%>”加载失败!" +LOG_MCI_INIT_FAILED = "MCI初始化失败!" +LOG_FFMPEG_INIT_FAILED = "FFMPEG内核初始化失败!" +LOG_STRING_TABLE_UNKNOWN_KEY = "字符串表错误,程序错误读取以下不存在的键: " +LOG_STRING_TABLE_PARA_ERROR = "字符串表错误,格式化以下键时缺少所需占位符: " + +# UI button tooltip +UI_TIP_BTN_PLAY = "播放" +UI_TIP_BTN_PAUSE = "暂停" +UI_TIP_BTN_PLAY_PAUSE = "播放/暂停" +UI_TIP_BTN_PREVIOUS = "上一曲" +UI_TIP_BTN_NEXT = "下一曲" +UI_TIP_BTN_STOP = "停止" +UI_TIP_BTN_MINIMODE = "迷你模式" +UI_TIP_BTN_MINIMODE_RTN = "返回正常模式" +UI_TIP_BTN_PLAYLIST_SHOW_HIDE = "显示/隐藏播放列表" +UI_TIP_BTN_PROPETRY = "曲目信息" +UI_TIP_BTN_LOCATE_TO_CURRENT = "定位到正在播放曲目" +UI_TIP_BTN_TRANSLATION = "显示歌词翻译" +UI_TIP_BTN_SWITCH_UI = "切换界面" +UI_TIP_BTN_SOUND_EFFECT_SETTING = "音效设定" +UI_TIP_BTN_OPTION_SETTING = "设置" +UI_TIP_BTN_CLOSE = "关闭" +UI_TIP_BTN_FIND_SONGS = "查找歌曲" +UI_TIP_BTN_FULL_SCREEN = "全屏显示" +UI_TIP_BTN_FULL_SCREEN_EXIT = "退出全屏" +UI_TIP_BTN_MAIN_MENU = "主菜单" +UI_TIP_BTN_MEDIA_LIB = "打开媒体库" +UI_TIP_BTN_FAVOURITE = "添加到“我喜欢的音乐”" +UI_TIP_BTN_DESKTOP_LYRIC = "显示桌面歌词" +UI_TIP_BTN_AB_REPEAT = "AB重复" +UI_TIP_BTN_MINIMIZE = "最小化" +UI_TIP_BTN_MAXIMIZE = "最大化" +UI_TIP_BTN_RESTORE = "还原" +UI_TIP_BTN_ADD_TO_PLAYLIST = "添加到播放列表" +UI_TIP_BTN_SWITCH_DISPLAY = "切换显示" +UI_TIP_BTN_DARK_LIGHT_TO_DARK_MODE = "切换到深色模式" +UI_TIP_BTN_DARK_LIGHT_TO_LIGHT_MODE = "切换到浅色模式" +UI_TIP_BTN_PLAYLIST_MENU = "播放列表菜单" +UI_TIP_BTN_RECENT_FOLDER_OR_PLAYLIST = "最近播放的文件夹/播放列表" + +UI_TIP_SEEK_TO_MINUTE_SECOND = "定位到<%1%>分<%2%>秒" +UI_TIP_VOLUME_MOUSE_WHEEL_ADJUST = "鼠标滚轮调整音量" +UI_TIP_COVER_INNER = "专辑封面: 内嵌图片\r\n图片格式: <%1%>" +UI_TIP_COVER_OUT = "专辑封面: 外部图片\r\n路径: <%1%>" +UI_TIP_COVER_MINI_MODE = "正在播放: <%1%>\r\n标题: <%2%>\r\n艺术家: <%3%>\r\n唱片集: <%4%>" + +UI_TIP_BTN_DESKTOP_LYRIC_LOCK = "锁定桌面歌词" +UI_TIP_BTN_DESKTOP_LYRIC_UNLOCK = "解锁桌面歌词" +UI_TIP_BTN_DESKTOP_LYRIC_CLOSE = "关闭桌面歌词窗口" +UI_TIP_BTN_DESKTOP_LYRIC_DOUBLE_LINE = "歌词双行显示" +UI_TIP_BTN_DESKTOP_LYRIC_BACKGROUND_PENETRATE = "歌词背景穿透" +UI_TIP_BTN_DESKTOP_LYRIC_DEFAULT_STYLE = "预设方案" +UI_TIP_BTN_DESKTOP_LYRIC_FORWARD = "歌词提前0.5秒" +UI_TIP_BTN_DESKTOP_LYRIC_DELAY = "歌词延后0.5秒" + +UI_TIP_REPEAT_MODE = "循环模式" +UI_TIP_REPEAT_OREDE = "顺序播放" +UI_TIP_REPEAT_SHUFFLE = "无序播放" +UI_TIP_REPEAT_RANDOM = "随机播放" +UI_TIP_REPEAT_PLAYLIST = "列表循环" +UI_TIP_REPEAT_TRACK = "单曲循环" +UI_TIP_REPEAT_ONCE = "单曲播放" + +# Title +UI_TITLE_DEBUG_MODE = "DEBUG模式" +UI_TITLE_EXCLUSIVE_MODE = "独占模式" + +# UI_TXT* is used directly on the UI, please pay attention to the length +UI_TXT_BTN_TRANSLATE = "译" +UI_TXT_BTN_DESKTOP_LYRIC = "词" +UI_TXT_VOLUME = "音量: <%1%><%2%>" +UI_TXT_VOLUME_MUTE = "静音" +UI_TXT_PLAYSTATUS_STOPED = "已停止" +UI_TXT_PLAYSTATUS_PAUSED = "已暂停" +UI_TXT_PLAYSTATUS_PLAYING = "正在播放" +UI_TXT_PLAYSTATUS_ERROR = "播放出错" +UI_TXT_PLAYSTATUS_ERROR_2 = "播放出错: <%1%>" +UI_TXT_PLAYSTATUS_ERROR_FILE_NOT_EXIST = "文件不存在" +UI_TXT_PLAYSTATUS_ERROR_FILE_CANNOT_BE_OPEND = "文件无法打开" +UI_TXT_PLAYSTATUS_ERROR_CORE_BASS = "错误代码(<%1%>)" +UI_TXT_NEXT_TRACK = "下一曲: " +UI_TXT_NEXT_TRACK_NONE = "无" +UI_TXT_NEXT_TRACK_RANDOM = "随机曲目" +UI_TXT_PLAYLIST_INIT_INFO = "找到<%1%>首歌曲,正在读取音频文件信息,请稍候……" +UI_TXT_MEDIA_LIB_UPDATING_INFO = "正在更新媒体库……已更新 <%1%> 个曲目 <%2%>%" +UI_TXT_AB_REPEAT_A_SELECTED = "AB重复:已选择A点 (<%1%>)" +UI_TXT_AB_REPEAT_ON = "AB重复:开 (<%1%>-<%2%>)" +UI_TXT_CHANNEL_MONO = "单声道" +UI_TXT_CHANNEL_STEREO = "立体声" +UI_TXT_CHANNEL_5_1 = "5.1 声道" +UI_TXT_CHANNEL_7_1 = "7.1 声道" +UI_TXT_CHANNEL_OTHER = "<%1%> 声道" +UI_TXT_SF2_NAME_NONE = "<无>" +UI_TXT_SF2_NAME_FAILDE = "<加载失败>" + +UI_TXT_PLAYLIST = "播放列表:" +UI_TXT_FOLDER = "文件夹:" +UI_TXT_BTN_MEDIA_LIB = "媒体库..." + +UI_LYRIC_EMPTY_LINE = "……" +UI_LYRIC_EMPTY_LINE_2 = "Music …" +UI_LYRIC_MUSIC_SYMBOL = "♪♪♪" +UI_LYRIC_NONE = "当前歌曲没有歌词" +UI_LYRIC_NO_TRACKS_TIP = "当前没有正在播放的曲目,你可以:\r\n按下<%1%>打开播放列表,并向播放列表中添加歌曲;\r\n点击“主菜单”——“文件”——“打开文件”或者快捷键<%2%>来打开一个音频文件;\r\n点击“主菜单”——“文件”——“打开文件夹”或者快捷键<%3%>打开并播放一个文件夹;\r\n按下<%4%>打开媒体库,在媒体库中寻找要播放的歌曲。" +UI_PLAYLIST_EMPTY_INFO = "播放列表为空。" + +# Here is a version of the menu text without the mnemonic key +UI_TXT_MENU_FILE = "文件" +UI_TXT_MENU_PLAY_CONTROL = "播放控制" +UI_TXT_MENU_PLAYLIST = "播放列表" +UI_TXT_MENU_LYRICS = "歌词" +UI_TXT_MENU_VIEW = "视图" +UI_TXT_MENU_TOOLS = "工具" +UI_TXT_MENU_HELP = "帮助" +UI_TXT_PLAYLIST_TOOLBAR_ADD = "添加" +UI_TXT_PLAYLIST_TOOLBAR_DELETE = "删除" +UI_TXT_PLAYLIST_TOOLBAR_SORT = "排序" +UI_TXT_PLAYLIST_TOOLBAR_LIST = "列表" +UI_TXT_PLAYLIST_TOOLBAR_EDIT = "编辑" +UI_TXT_PLAYLIST_TOOLBAR_FOLDER = "文件夹" +UI_TXT_PLAYLIST_TOOLBAR_LOCATE = "定位" + +# Values below should not be repeated +TXT_PLAYLIST_NAME_DEFAULT = "[默认]" +TXT_PLAYLIST_NAME_FAVOURITE = "[我喜欢的音乐]" +TXT_PLAYLIST_NAME_TEMP = "[临时的播放列表]" +TXT_EMPTY_FILE_NAME = "<没有找到文件>" +TXT_EMPTY_TITLE = "<未知标题>" +TXT_EMPTY_ARTIST = "<未知艺术家>" +TXT_EMPTY_ALBUM = "<未知唱片集>" +TXT_EMPTY_YEAR = "<未知年份>" +TXT_EMPTY_GENRE = "<未知流派>" +TXT_EMPTY_RATED = "<未分级>" +TXT_MULTI_VALUE = "<多个数值>" +TXT_CLASSIFY_OTHER = "<其他>" +TXT_INNER_LYRIC = "<内嵌歌词>" +TXT_INNER_COVER = "<内嵌专辑封面>" + +# File type description +TXT_FILE_TYPE_BASE = "基本音频格式" +TXT_FILE_TYPE_FFMPEG_USER_DEFINE = "其他音频格式" +TXT_FILE_TYPE_UNKNOWN = "未知" +TXT_FILE_TYPE_MP3 = "MPEG Audio Layer 3" +TXT_FILE_TYPE_MP1_MP2 = "MPEG Audio" +TXT_FILE_TYPE_WMA = "Windows Media Audio" +TXT_FILE_TYPE_ASF = "Advanced Streaming Format" +TXT_FILE_TYPE_WAV = "WAV 音频文件" +TXT_FILE_TYPE_OGG_OGA = "OGG Vorbis 音频文件" +TXT_FILE_TYPE_M4A_MP4 = "MPEG-4 音频文件" +TXT_FILE_TYPE_APE = "Monkey's Audio (APE)" +TXT_FILE_TYPE_ACC = "Advanced Audio Coding (AAC)" +TXT_FILE_TYPE_AIF_AIFF = "Audio Interchange File" +TXT_FILE_TYPE_CDA = "CD 音频文件 (CDA)" +TXT_FILE_TYPE_PLAYLIST = "MusicPlayer2 播放列表" +TXT_FILE_TYPE_M3U = "M3U 播放列表" +TXT_FILE_TYPE_M3U8 = "M3U8 播放列表" +TXT_FILE_TYPE_CUE = "CUE Sheets" +TXT_FILE_TYPE_OTHER = "<%1%> 音频文件" + +# CAcceleratorRes / Used to assemble shortcut key strings +TXT_SHORCUT_LEFT = "←" +TXT_SHOTCUT_RIGHT = "→" +TXT_SHOTCUT_UP = "↑" +TXT_SHOTCUT_DOWN = "↓" +TXT_SHOTCUT_SPACE = "空格" + +# BTN +TXT_OK = "确定" +TXT_CANCEL = "取消" +TXT_CLOSE = "关闭" +TXT_APPLY = "应用" + +# CFolderBrowserDlg / CFolderPickerDialog / CBrowseEdit +TITLE_FOLDER_BROWSER_SONG_SOURCE = "选择音频文件夹" +TITLE_FOLDER_BROWSER_COPY_TARGET = "选择复制的目标文件夹" +TITLE_FOLDER_BROWSER_MOVE_TARGET = "选择移动的目标文件夹" +TITLE_FOLDER_BROWSER_OUTPUT_FOLDER = "选择输出文件夹" +TXT_FOLDER_BROWSER_INCLUDE_SUB_DIR = "包含子文件夹" +MSG_FOLDER_BROWSER_INVALID_DIR_WARNING = "无效的目录,请重新选择!" + +# CommonDialogMgr +TITLE_FILE_DELETE = "删除" +TITLE_FILE_COPY = "复制" +TITLE_FILE_MOVE = "移动" + +# CFileDialog +TXT_SAVE_AS_ANSI = "以ANSI格式保存" +TXT_SAVE_AS_UTF8 = "以UTF-8格式保存" + +# filter / FilterHelper.cpp +TXT_FILTER_ALL_FILES = "所有文件" +TXT_FILTER_ALL_SUPPORTED_AUDIO_FORMAT = "所有支持的音频格式" +TXT_FILTER_LYRIC_FILE = "歌词文件" +TXT_FILTER_TXT_FILE = "文本文件" +TXT_FILTER_SF2_FILE = "音色库文件" +TXT_FILTER_CSV_FILE = "csv文件" +TXT_FILTER_ALL_SUPPORTED_PLAYLIST_FILE = "全部支持的播放列表文件" +TXT_FILTER_PLAYLIST_FILE = "MusicPlayer2播放列表文件" +TXT_FILTER_M3U_FILE = "m3u播放列表文件" +TXT_FILTER_M3U8_FILE = "m3u8播放列表文件" +TXT_FILTER_IMAGE_FILE = "图片文件" + +# CSearchEditCtrl +TIP_SEARCH_EDIT_CLEAN = "清除搜索结果" +TIP_SEARCH_EDIT_INPUT = "键入要搜索的关键词" +TXT_SEARCH_PROMPT = "在此处键入搜索" +TXT_SEARCH_PROMPT_ARTIST = "在此处键入搜索艺术家" +TXT_SEARCH_PROMPT_ALBUM = "在此处键入搜索唱片集" +TXT_SEARCH_PROMPT_GENRE = "在此处键入搜索流派" +TXT_SEARCH_PROMPT_YEAR = "在此处键入搜索年份" +TXT_SEARCH_PROMPT_FILE_TYPE = "在此处键入搜索文件类型" +TXT_SEARCH_PROMPT_BITRATE = "在此处键入搜索比特率" +TXT_SEARCH_PROMPT_FORDER = "在此处键入搜索文件夹" + +# CPlayListCtrl +TXT_PLAYLIST_CTRL_NO_RESULT_TO_SHOW = "没有结果可以显示" + +# CBrowseEdit +TITLE_BROWSE_EDIT_SET_MULTI_OUT_ALBUM_COVER_FILE_NAME = "设置多个外部专辑封面的文件名" +TITLE_BROWSE_EDIT_SET_MULTI_ARTIST_SPLIT_EXT = "设置多个艺术家识别例外" +TXT_BROWSE_EDIT_EDIT = "编辑..." +TXT_BROWSE_EDIT_BROWSE = "浏览..." + +# IDD_FIND_DIALOG +TITLE_FIND = "查找文件" +TXT_FIND_KEY_WORD_INPUT = "输入要查找的关键字:" +TXT_FIND_FIND = "查找" +TXT_FIND_FIND_RANGE = "查找范围" +TXT_FIND_CURRENT_PLAYLIST = "查找当前播放列表" +TXT_FIND_MEDIA_LIB = "查找整个媒体库" +TXT_FIND_OPT = "查找选项" +TXT_FIND_OPT_FILE_NAME = "查找文件名" +TXT_FIND_OPT_TITLE = "查找标题" +TXT_FIND_OPT_ARTIST = "查找艺术家" +TXT_FIND_OPT_ALBUM = "查找唱片集" +TXT_FIND_RESULT_NONE = "没有找到结果!" +TXT_FIND_RESULT_LAST = "上次的查找结果: " +TXT_FIND_RESULT_CURRENT = "查找结果: " +TXT_FIND_RESULT_INFO = "查找关键字: <%1%>,结果数: <%2%>" +TXT_FIND_PLAY_SELECTED = "播放选中曲目" + +# IDD_LYRIC_EDIT_DIALOG +TITLE_LYRIC_EDIT = "编辑歌词" +TXT_LYRIC_EDIT_LYRIC_PATH = "歌词路径:" +MSG_LYRIC_EDIT_STRING_REPLACE_COMPLETE = "替换完成,共替换<%1%>个字符串。" +MSG_LYRIC_EDIT_STRING_CANNOT_FIND = "找不到“<%1%>”" +TXT_LYRIC_EDIT_TOTAL_CHARACTER = "共<%1%>个字符" +TXT_LYRIC_EDIT_MODIFIED = "已修改" +TXT_LYRIC_EDIT_UNMODIFIED = "未修改" +TXT_LYRIC_EDIT_ENCODE_FORMAT = "编码格式: <%1%>" +TXT_LYRIC_EDIT_UTF8NOBOM = "UTF8无BOM" +TIP_LYRIC_EDIT_INSERT_TIME_TAG = "插入时间标签" +TIP_LYRIC_EDIT_REPLACE_TIME_TAG = "替换时间标签" +TIP_LYRIC_EDIT_DELETE_TIME_TAG = "删除时间标签" +TIP_LYRIC_EDIT_SAVE = "保存" +TIP_LYRIC_EDIT_PLAY_PAUSE = "播放/暂停" +TIP_LYRIC_EDIT_REWIND = "快退" +TIP_LYRIC_EDIT_FAST_FOWARD = "快进" +TIP_LYRIC_EDIT_FIND = "查找" +TIP_LYRIC_EDIT_REPLACE = "替换" +TIP_LYRIC_EDIT_SEEK_TO_LINE = "定位到当前行" + +# IDD_PROPERTY_PARENT_DIALOG +TITLE_PROPERTY_PARENT = "属性" +TITLE_PROPERTY_PARENT_BATCH = "属性 (<%1%>个文件)" +TXT_PROPERTY_PARENT_PREVIOUS = "上一页" +TXT_PROPERTY_PARENT_NEXT = "下一页" +TXT_PROPERTY_PARENT_SAVE_TO_FILE = "保存到文件" +MSG_PROPERTY_PARENT_TAG_BATCH_EDIT_SAVE_INFO = "已保存到 <%1%> 个文件。" +# IDD_PROPERTY_DIALOG +TITLE_PROPERTY_DLG = "文件属性" +TXT_PROPERTY_DLG_FILE_INFO = "文件信息" +TXT_PROPERTY_DLG_FILE_NAME = "文件名:" +TXT_PROPERTY_DLG_FILE_PATH = "文件路径:" +TXT_PROPERTY_DLG_FILE_TYPE = "文件类型:" +TXT_PROPERTY_DLG_FILE_DURATION = "时长:" +TXT_PROPERTY_DLG_FILE_DURATION_UNKNOWN = "暂未获取或无法获取音频的长度" +TXT_PROPERTY_DLG_FILE_SIZE = "文件大小:" +TXT_PROPERTY_DLG_FILE_BIT_RATE = "比特率:" +TXT_PROPERTY_DLG_FILE_CHANNELS = "声道数:" +TXT_PROPERTY_DLG_FILE_FREQ = "采样频率:" +TXT_PROPERTY_DLG_FILE_BIT_DEPTH = "位深度:" +TXT_PROPERTY_DLG_FILE_BIT_DEPTH_UNDEFINED = "未定义" +TXT_PROPERTY_DLG_FILE_LRC_FILE = "歌词文件:" +TXT_PROPERTY_DLG_FILE_LRC_FILE_NO_LINK = "没有关联的歌词文件" +TXT_PROPERTY_DLG_TAG_INFO = "标签信息" +TXT_PROPERTY_DLG_TAG_TITLE = "标题:" +TXT_PROPERTY_DLG_TAG_ARTIST = "艺术家:" +TXT_PROPERTY_DLG_TAG_ALBUM = "唱片集:" +TXT_PROPERTY_DLG_TAG_TRACK = "音轨号:" +TXT_PROPERTY_DLG_TAG_YEAR = "年份:" +TXT_PROPERTY_DLG_TAG_GENRE = "流派:" +TXT_PROPERTY_DLG_TAG_COMMENT = "注释:" +TXT_PROPERTY_DLG_TAG_TYPE = "标签类型: <%1%>" +TXT_PROPERTY_DLG_FROM_FILE_NAME = "从文件名获取标签..." +TXT_PROPERTY_DLG_FROM_LRC = "从歌词获取标签" +MSG_PROPERTY_DLG_NO_LYRICS_FOUND = "没有找到歌词!" +TXT_PROPERTY_DLG_FROM_ONLINE = "在线获取标签..." +# IDD_PROPERTY_ALBUM_COVER_DIALOG +TITLE_COVER_PROPERTY = "专辑封面" +TXT_COVER_PROPERTY_FORMAT = "封面格式" +TXT_COVER_PROPERTY_WIDTH = "宽度" +TXT_COVER_PROPERTY_HEIGHT = "高度" +TXT_COVER_PROPERTY_BPP = "每像素位数" +TXT_COVER_PROPERTY_FILE_SIZE = "文件大小" +TXT_COVER_PROPERTY_BROWSE = "浏览..." +TXT_COVER_PROPERTY_DELETE = "删除" +TXT_COVER_PROPERTY_SHOW_OUT_COVER = "显示外部专辑封面" +TXT_COVER_PROPERTY_DO_INNER_COVER = "将外部专辑封面嵌入到音频文件" +# IDD_PROPERTY_ADVANCED_DIALOG +TITLE_ADVANCED_PROPERTY = "高级标签信息" + +# IDD_LYRIC_DOWNLOAD_DIALOG / IDD_COVER_DOWNLOAD_DIALOG +TXT_LYRIC_DL_TITLE = "标题:" +TXT_LYRIC_DL_SEARCH = "搜索" +TXT_LYRIC_DL_ARTIST = "艺术家:" +TXT_LYRIC_DL_INFO = "搜索结果: " +TXT_LYRIC_DL_INFO_SEARCHING = "正在搜索……" +TXT_LYRIC_DL_INFO_SEARCH_NO_SONG = "搜索结果: (没有找到歌曲)" +TXT_LYRIC_DL_INFO_SEARCH_NO_MATCHED = "搜索结果: (似乎没有最佳匹配的项)" +TXT_LYRIC_DL_INFO_SEARCH_RELATED = "搜索结果: (已关联项:<%1%>)" +TXT_LYRIC_DL_INFO_SEARCH_BEST_MATCHED = "搜索结果: (最佳匹配项: <%1%>)" +TXT_LYRIC_DL_UNLINK = "取消关联" +TXT_LYRIC_DL_OPT = "下载选项" +TXT_LYRIC_DL_SEL_DL = "下载选中项" +# IDD_COVER_DOWNLOAD_DIALOG +TITLE_COVER_DL = "下载专辑封面(通过网易云音乐的API)" +TXT_COVER_DL_LOCATION_SEL = "封面保存位置:" +TXT_COVER_DL_LOCATION_FOLDER_SONG = "保存到歌曲所在目录" +TXT_COVER_DL_LOCATION_FOLDER_COVER = "保存到封面文件夹" +# IDD_LYRIC_DOWNLOAD_DIALOG +TITLE_LYRIC_DL = "下载歌词(通过网易云音乐的API)" +TXT_LYRIC_DL_WITH_TRANSLATION = "下载翻译歌词(如果有)" +TXT_LYRIC_DL_SAVE_ENCODE_SEL = "保存的编码格式:" +TXT_LYRIC_DL_SAVE_DIR_SEL = "歌词保存位置:" +TXT_LYRIC_DL_SAVE_DIR_LYRIC = "保存到歌词文件夹" +TXT_LYRIC_DL_SAVE_DIR_SONG = "保存到歌曲所在目录" +TXT_LYRIC_DL_SEL_SAVE_AS = "选中项另存为..." +# CGetTagOnlineDlg +TITLE_GET_TAG_ONLINE = "在线获取标签信息" +TXT_GET_TAG_ONLINE_GET_THIS = "获取此项" + +# IDD_LYRIC_BATCH_DOWN_DIALOG +TITLE_LYRIC_BDL = "歌词批量下载(通过网易云音乐的API)" +TXT_LYRIC_BDL_DL_OPT = "下载选项" +TXT_LYRIC_BDL_SKIP_ALREADY = "跳过已经有歌词的歌曲" +TXT_LYRIC_BDL_SAVE_ENCODE_SEL = "保存的编码格式:" +TXT_LYRIC_BDL_WITH_TRANSLATION = "下载翻译歌词(如果有)" +TXT_LYRIC_BDL_SAVE_DIR_SEL = "歌词保存位置:" +TXT_LYRIC_BDL_SAVE_DIR_LYRIC = "保存到歌词文件夹" +TXT_LYRIC_BDL_SAVE_DIR_SONG = "保存到歌曲所在目录" +TXT_LYRIC_BDL_SONG_LIST = "歌曲列表:" +TXT_LYRIC_BDL_STATUS = "状态" +TXT_LYRIC_BDL_STATUS_DOWNLOADING = "正在下载…" +TXT_LYRIC_BDL_STATUS_SKIPED = "已跳过" +TXT_LYRIC_BDL_STATUS_NETWORK_FAILED = "网络连接失败或超时" +TXT_LYRIC_BDL_STATUS_CANNOT_FIND_THIS_SONG = "找不到此歌曲" +TXT_LYRIC_BDL_STATUS_NO_MATCHED_LYRIC = "没有匹配的歌词" +TXT_LYRIC_BDL_STATUS_DOWNLOAD_FAILED = "歌词下载失败" +TXT_LYRIC_BDL_STATUS_SONG_NO_LYRIC = "该歌曲没有歌词" +TXT_LYRIC_BDL_STATUS_ENCODE_WARNING = "成功,但是歌词中有无法转换的Unicode字符,建议保存为UTF-8格式" +TXT_LYRIC_BDL_STATUS_SUCCESSED = "成功" +TXT_LYRIC_BDL_STATUS_FILE_WRITE_FAILED = "无法写入文件" +TXT_LYRIC_BDL_INFO_DOWNLOADING_INFO = "正在下载,已完成 <%1%>%,请稍候..." +TXT_LYRIC_BDL_INFO_COMPLETE = "歌词下载完成。" +TXT_LYRIC_BDL_DL_START = "开始下载" + +# IDD_SOUND_EFFECT_DIALOG +TITLE_SOUND_EFFECT = "音效设定" +# IDD_EQUALIZER_DIALOG +TITLE_EQ = "均衡器" +TXT_EQ_ENABLE = "启用均衡器" +TXT_EQ_PRESET = "均衡器预设" +TXT_EQ_NONE = "无" +TXT_EQ_CLASSICAL = "古典" +TXT_EQ_POP = "流行" +TXT_EQ_JAZZ = "爵士" +TXT_EQ_ROCK = "摇滚" +TXT_EQ_SOFT = "柔和" +TXT_EQ_BASS = "重低音" +TXT_EQ_ELIMINATE_BASS = "消除低音" +TXT_EQ_WEAKENING_TREBLE = "弱化高音" +TXT_EQ_USER_DEFINE = "自定义" +TXT_EQ_CHANNEL_SETTING = "通道设定" +# IDD_REVERB_DIALOG +TITLE_REVERB = "混响" +TXT_REVERB_ENABLE = "启用混响" +TXT_REVERB_STRENGTH = "混响强度:" +TXT_REVERB_TIME = "混响时间:" + +# IDD_SUPPORT_FORMAT_DIALOG +TITLE_SUPPORTTED_FORMAT = "支持的格式" +TXT_SUPPORTTED_FORMAT_CORE_INFO_BASS = "MusicPlayer2支持多种播放内核,当前使用的播放内核为BASS音频库。\r\n更多音频格式支持依赖于BASS引擎插件(位于 “.\\Plugins” 目录下)。" +TXT_SUPPORTTED_FORMAT_CORE_INFO_MCI = "MusicPlayer2支持多种播放内核,当前使用的播放内核为MCI。仅支持mp3、wma、wav、mid格式,需要支持更多音频格式的播放,请切换到BASS或FFMPEG内核。" +TXT_SUPPORTTED_FORMAT_CORE_INFO_FFMPEG = "MusicPlayer2支持多种播放内核,当前使用的播放内核为FFMPEG。" +TXT_SUPPORTTED_FORMAT_PLUGIN_FILE_NAME = "插件文件名" +TXT_SUPPORTTED_FORMAT_PLUGIN_FORMAT_PROVIDED = "提供的格式支持" +TXT_SUPPORTTED_FORMAT_PLUGIN_FILE_EXTENSION = "文件的扩展名" + +# IDD_FORMAT_CONVERT_DIALOG +TITLE_FORMAT_CONVERT = "转换格式" +TXT_FORMAT_CONVERT_OUT_FORMAT_SEL = "输出编码格式:" +TXT_FORMAT_CONVERT_ENCODER_NAME_MP3_LAME = "MP3 (lame编码器)" +TXT_FORMAT_CONVERT_SETTING = "配置..." +TXT_FORMAT_CONVERT_FILE_LIST = "文件列表:" +TXT_FORMAT_CONVERT_STAUS = "转换状态" +TXT_FORMAT_CONVERT_STAUS_ERROR_FILE_CANNOT_OPEN = "错误: 源文件无法读取" +TXT_FORMAT_CONVERT_STAUS_ERROR_ENCODE_CHANNEL_FAILED = "错误: 编码通道创建失败" +TXT_FORMAT_CONVERT_STAUS_ERROR_ENCODE_PARA_ERROR = "错误: 找不到编码器或编码器参数错误" +TXT_FORMAT_CONVERT_STAUS_ERROR_MIDI_NO_SF2 = "错误: 没有MIDI音色库" +TXT_FORMAT_CONVERT_STAUS_ERROR_NO_WMP9_OR_LATER = "错误: 编码通道创建失败,没有安装 Windows Media Player 9 或更高版本" +TXT_FORMAT_CONVERT_STAUS_ERROR_NO_SUPPORTED_ENCODER = "错误: 编码通道创建失败,无法找到可支持请求的采样格式和比特率的编解码器" +TXT_FORMAT_CONVERT_STAUS_ERROR_OTHER = "错误代码: <%1%>" +TXT_FORMAT_CONVERT_STAUS_COMPLEATE = "完成" +TXT_FORMAT_CONVERT_STAUS_SKIPED = "已跳过" +TXT_FORMAT_CONVERT_OPT = "选项" +TXT_FORMAT_CONVERT_CHANGE_FREQ = "转换采样频率:" +TXT_FORMAT_CONVERT_COPY_TAG = "写入标签信息" +TXT_FORMAT_CONVERT_COPY_COVER = "写入专辑封面" +TXT_FORMAT_CONVERT_OUT_FILE_NAME = "目标文件名:" +TXT_FORMAT_CONVERT_ADD_SERIAL_NUMBER = "目标文件名添加数字编号" +TXT_FORMAT_CONVERT_FILE_EXIST_SEL = "当目标文件存在时:" +TXT_FORMAT_CONVERT_FILE_EXIST_AUTO_RENAME = "自动重命名" +TXT_FORMAT_CONVERT_FILE_EXIST_IGNORE = "跳过" +TXT_FORMAT_CONVERT_FILE_EXIST_OVERWRITE = "覆盖" +TXT_FORMAT_CONVERT_OUT_DIR = "输出目录:" +TXT_FORMAT_CONVERT_OUT_DIR_OPEN_WHEN_COMPLETE = "转换完成后打开输出目录" +TXT_FORMAT_CONVERT_PROGRESS_INFO = "已完成 <%1%>%,请稍候……" +TXT_FORMAT_CONVERT_PROGRESS_INFO_COMPLEATE = "已完成" +TXT_FORMAT_CONVERT_START_CONVERT = "开始转换" +MSG_FORMAT_CONVERT_BASS_MIX_LOAD_ERROR = "BASSmix 加载失败,文件 “<%1%>” 可能丢失或已经损坏!" +MSG_FORMAT_CONVERT_INIT_ERROR = "编码器初始化失败!" +MSG_FORMAT_CONVERT_BASS_LOAD_ERROR = "BASS 编码器加载失败,文件 “<%1%>” 可能丢失或已经损坏!" +MSG_FORMAT_CONVERT_SET_OUTPUT_DIR = "请设置输出目录!" +MSG_FORMAT_CONVERT_OUTPUT_DIR_NOT_EXIST = "输出目录 “<%1%>” 不存在!" +# IDD_MP3_ENCODE_CFG_DIALOG +TITLE_ENCODE_OPT_MP3 = "MP3 编码选项" +TXT_ENCODE_OPT_MP3_CBR = "恒定比特率 (CBR):" +TXT_ENCODE_OPT_MP3_ABR = "平均比特率 (ABR):" +TXT_ENCODE_OPT_MP3_VBR = "动态比特率 (VBR) (推荐)" +TXT_ENCODE_OPT_MP3_VBR_QUALITY_SEL = "压缩品质:" +TXT_ENCODE_OPT_MP3_VBR_QUALITY_LOW = "低" +TXT_ENCODE_OPT_MP3_VBR_QUALITY_HIGH = "高" +TXT_ENCODE_OPT_MP3_JOINT_STEREO = "对于双声道采用联合立体声编码" +TXT_ENCODE_OPT_MP3_SPECIFY_PARA = "自定义 lame 参数:" +# IDD_WMA_ENCODE_CFG_DIALOG +TITLE_ENCODE_OPT_WMA = "WMA 编码选项" +TXT_ENCODE_OPT_WMA_CBR = "恒定比特率(CBR):" +TXT_ENCODE_OPT_WMA_VBR = "基于质量的 VBR:" +# IDD_OGG_ENCODE_CFG_DIALOG +TITLE_ENCODE_OPT_OGG = "OGG 编码选项" +TXT_ENCODE_OPT_OGG_ENCODE_QUALITY_SEL = "编码质量:" +TXT_ENCODE_OPT_OGG_ENCODE_QUALITY_LOW = "低" +TXT_ENCODE_OPT_OGG_ENCODE_QUALITY_HIGH = "高" +# IDD_FLAC_ENCODE_CFG_DIALOG +TITLE_ENCODE_OPT_FLAC = "Flac 编码选项" +TXT_ENCODE_OPT_FLAC_CMP_LEVEL = "压缩级别" +TXT_ENCODE_OPT_FLAC_CMP_LEVEL_LOW = "低" +TXT_ENCODE_OPT_FLAC_CMP_LEVEL_HIGH = "高" +TXT_ENCODE_OPT_FLAC_SPECIFY_PARA = "自定义 Flac 编码参数" +# IDD_TAG_EDIT_DIALOG (other from IDD_PROPERTY_DIALOG) +TITLE_TAG_EDIT = "编辑音频标签" +TXT_TAG_EDIT_PATH = "路径:" +TXT_TAG_EDIT_SAVE = "保存" + +# IDD_CLEAN_UP_RANGE_DIALOG +TITLE_CLEAN_UP_RANGE = "清理媒体库" +TXT_CLEAN_UP_RANGE_SEL = "请选择要清理的范围:" +TXT_CLEAN_UP_RANGE_FILES_THAT_NOT_EXIST = "不存在的文件" +TXT_CLEAN_UP_RANGE_FILES_NOT_IN_MEDIA_LIB_DIR = "不在媒体库目录中的文件" +TXT_CLEAN_UP_RANGE_FILES_THAT_ERROR = "错误的文件" +TXT_CLEAN_UP_RANGE_FILES_TOO_SHORT = "过短的文件" +TXT_CLEAN_UP_RANGE_FILES_NON_MAIN_IN_OSU = "osu! 文件夹中的非主要文件" +MSG_CLEAN_UP_RANGE_NOT_SELECT_WARNING = "清选择一个清理范围!" + +# IDD_OPTIONS_DIALOG +TITLE_OPT = "选项设置" + +# IDD_LYRIC_SETTING_DIALOG +TITLE_OPT_LRC = "歌词设置" + +TXT_OPT_LRC_OPT = "歌词选项" +TXT_OPT_LRC_USE_INNER_FIRST = "优先使用内嵌歌词" +TXT_OPT_LRC_FUZZY_MATCH = "歌词模糊匹配" +TIP_OPT_LRC_FUZZY_MATCH = "如果去掉此复选框的勾选,则只会匹配和歌曲文件名完全一样的歌词文件;\r\n如果选中此复选框,当找不到文件名完全一样的歌词文件时,会匹配文件名中包含艺术家和歌曲标题的歌词文件。\r\n(可能需要重新启动程序才能生效。)" +TXT_OPT_LRC_SHOW_TRANSLATION = "显示歌词翻译(如果有)" +TXT_OPT_LRC_SONG_INFO_IF_NO_LRC = "没有歌词时显示歌曲信息" +TIP_OPT_LRC_SONG_INFO_IF_NO_LRC = "勾选此项后,如果没有歌词,会显示歌曲的艺术家、唱片集和歌曲标题等信息,而不是显示“<%1%>”。" +TXT_OPT_LRC_LRC_FOLDER = "歌词文件夹:" +TIP_OPT_LRC_LRC_FOLDER_PATH = "说明:如果歌曲所在目录下找不到匹配的歌词文件,就会在此文件夹下寻找歌词文件。" +TXT_OPT_LRC_SAVE_POLICY_SEL = "歌词调整后:" +TXT_OPT_LRC_SAVE_POLICY_DO_NOT_SAVE = "不保存" +TXT_OPT_LRC_SAVE_POLICY_AUTO_SAVE = "自动保存" +TXT_OPT_LRC_SAVE_POLICY_INQUIRY = "询问" +TXT_OPT_LRC_KARAOKE_DISP = "歌词卡拉OK样式显示" +TXT_OPT_LRC_USE_MUSIC_SYMBOL = "不显示歌词空行" +TIP_OPT_LRC_USE_MUSIC_SYMBOL = "勾选此选项后,在歌词单行显示和双行显示时,如果遇到空白行,则不再显示“<%1%>”或“<%2%>”,而是会提前显示之后的歌词,若同时勾选了“歌词卡拉OK样式显示”则会将大于一定时长的空白行替换为音乐进度符号“<%3%>”。此选项也会影响桌面歌词的显示。" + +TXT_OPT_LRC_WINDOW_LRC = "窗口歌词" +TXT_OPT_LRC_WINDOW_LRC_LINE_SPACING = "歌词行间距 (像素):" +TXT_OPT_LRC_ALIGN_SEL = "歌词对齐方式:" +TXT_OPT_LRC_ALIGN_LEFT = "左对齐" +TXT_OPT_LRC_ALIGN_RIGHT = "右对齐" +TXT_OPT_LRC_ALIGN_AUTO = "自动" +TXT_OPT_LRC_ALIGN_CENTER = "居中" +TXT_OPT_LRC_FONT_SEL = "设置字体..." +TIP_OPT_LRC_FONT_INFO_BOLD = "加粗" +TIP_OPT_LRC_FONT_INFO_ITALIC = "倾斜" + +TXT_OPT_LRC_DESKTOP_LRC = "桌面歌词" +TXT_OPT_LRC_DESKTOP_LRC_ENABLE = "显示桌面歌词" +TXT_OPT_LRC_DESKTOP_LRC_BG_PENETRATE = "歌词背景穿透" +TXT_OPT_LRC_DESKTOP_LRC_HIDE_NO_LRC = "没有歌词时隐藏歌词窗口" +TXT_OPT_LRC_DESKTOP_LRC_HIDE_PAUSE = "暂停时隐藏歌词窗口" +TXT_OPT_LRC_DESKTOP_LRC_LOCK = "锁定桌面歌词" +TXT_OPT_LRC_DESKTOP_LRC_SHOW_UNLOCK_WHEN_LOCK = "锁定时显示解锁按钮" +TXT_OPT_LRC_DOUBLE_LINE = "歌词双行显示" +TXT_OPT_LRC_DESKTOP_LRC_COLOR_TEXT = "文字颜色:" +TXT_OPT_LRC_DESKTOP_LRC_COLOR_HIGHLIGHT = "高亮颜色:" +TXT_OPT_LRC_DESKTOP_LRC_COLOR_GRADIENT_NONE = "无渐变" +TXT_OPT_LRC_DESKTOP_LRC_COLOR_GRADIENT_TWO = "两色渐变" +TXT_OPT_LRC_DESKTOP_LRC_COLOR_GRADIENT_THREE = "三色渐变" +TXT_OPT_LRC_DESKTOP_LRC_DEFAULT_STYLE = "预设方案" +MSG_OPT_LRC_DESKTOP_LRC_DEFAULT_STYLE_MODIFY_WARNING = "确实要用当前颜色方案覆盖“预设 <%1%>”吗?" +MSG_OPT_LRC_DESKTOP_LRC_DEFAULT_STYLE_RESTORE_WARNING = "所有修改过的预设方案都将被恢复,要继续吗?" +TXT_OPT_LRC_DESKTOP_LRC_TRANSPARENCY = "歌词不透明度:" + +TXT_OPT_LRC_SEARCH_BOX_FUNCTION = "任务栏搜索框显示播放信息" +TXT_OPT_LRC_SEARCH_BOX_FUNCTION_ENABLE = "启用任务栏搜索框功能" +TIP_OPT_LRC_SEARCH_BOX_FUNCTION_ENABLE = "勾选项后,可以在 Cortana 搜索框中显示歌词、歌曲名称和专辑封面。开启此功能后可能需要重新启动软件才能生效。" +TXT_OPT_LRC_SEARCH_BOX_COMPATIBLE_MODE = "使用兼容模式显示歌词" +TXT_OPT_LRC_SEARCH_BOX_SHOW_WHEN_PAUSE = "暂停时保持显示" +TXT_OPT_LRC_SEARCH_BOX_BG_COLOR_SEL = "搜索框背景颜色:" +TXT_OPT_LRC_SEARCH_BOX_BG_COLOR_FOLLOWING_SYSTEM = "跟随系统" +TXT_OPT_LRC_SEARCH_BOX_BG_COLOR_DARK = "深色" +TXT_OPT_LRC_SEARCH_BOX_BG_COLOR_LIGHT = "浅色" +TXT_OPT_LRC_SEARCH_BOX_BG_TRANSPARENCY_IN_WHITE_MODE = "Windows10浅色模式下搜索框背景透明" +TXT_OPT_LRC_SEARCH_BOX_SHOW_COVER = "搜索框中显示专辑封面" +TXT_OPT_LRC_SEARCH_BOX_NO_COVER_SHOW_DEFAULT_COVER = "没有专辑封面时显示黑胶唱片图标" +TXT_OPT_LRC_SEARCH_BOX_NO_COVER_BEATS_CORTANA_ICON = "Cortana图标跟随音乐节奏跳动" +TXT_OPT_LRC_SEARCH_BOX_SHOW_SPECTRUM = "搜索框中显示频谱分析" +TXT_OPT_LRC_SEARCH_BOX_SHOW_LRC = "搜索框中显示歌词" + +# IDD_APPEREANCE_SETTING_DLG +TITLE_OPT_APC = "外观设置" + +TXT_OPT_APC_VISUAL_EFFECTS = "视觉效果" +TXT_OPT_APC_SPECTRUM_SHOW = "显示频谱分析" +TXT_OPT_APC_SPECTRUM_LOW_FREQ_IN_CENTER = "低频部分显示在中间" +TXT_OPT_APC_SPECTRUM_HEIGHT = "频谱分析高度:" +TXT_OPT_APC_COVER_SHOW = "显示专辑封面" +TXT_OPT_APC_COVER_FIT = "专辑封面契合度:" +TXT_OPT_APC_COVER_FIT_STRETCH = "拉伸" +TXT_OPT_APC_COVER_FIT_FILL = "填充" +TXT_OPT_APC_COVER_FIT_ADAPT = "适应" +TIP_OPT_APC_COVER_FIT = "拉伸: 会改变长宽比\r\n填充: 不会改变长宽比,会裁剪长边\r\n适应: 不会改变长宽比,不裁剪" +TXT_OPT_APC_LYRIC_BG = "歌词界面背景" +TXT_OPT_APC_ROUND_CORNERS = "使用圆角风格" +TXT_OPT_APC_DARK_MODE = "深色模式" +TXT_OPT_APC_MAIN_WINDOW_TRANSPARENCY = "主窗口不透明度:" + +TXT_OPT_APC_BG_SETTING = "背景设置" +TXT_OPT_APC_BG_ENABLE = "启用背景" +TXT_OPT_APC_BG_USE_DESKTOP = "使用桌面背景" +TXT_OPT_APC_BG_TRANSPARENCY = "背景不透明度:" +TXT_OPT_APC_BG_USE_COVER = "使用专辑封面作为背景" +TXT_OPT_APC_BG_GAUSS_BLUR = "背景高斯模糊" +TXT_OPT_APC_BG_GAUSS_BLUR_RADIUS = "高斯模糊半径:" +TXT_OPT_APC_BG_DEFAULT_IMAGE = "默认背景图片:" + +TXT_OPT_APC_COVER_OPT = "封面选项" +TXT_OPT_APC_COVER_USE_INNER_FIRST = "优先使用内嵌专辑封面" +TXT_OPT_APC_COVER_OUT_IMAGE_ALLOW = "没有专辑封面时使用外部图片" +TIP_OPT_APC_COVER_OUT_IMAGE_ALLOW = "如果无法从音频文件获取专辑封面,则尝试在音频文件所在目录下查找下面指定的文件名为专辑封面" +TXT_OPT_APC_COVER_OUT_IMAGE_FILE_NAME = "外部图片文件名:" +TIP_OPT_APC_COVER_OUT_IMAGE_FILE_NAME = "在此设置默认的专辑封面文件名,多个文件名之间使用半角逗号隔开,支持通配符与相对路径,设置绝对路径会使封面查找总是成功无法自动下载专辑封面" +TXT_OPT_APC_COVER_OUT_FOLDER = "封面文件夹:" +TIP_OPT_APC_COVER_OUT_FOLDER = "如果歌曲所在目录下没有找到专辑封面则会在此文件夹下寻找封面文件。" + +TXT_OPT_APC_COLOR_THEME = "主题颜色" +TIP_OPT_APC_COLOR_CURRENT = "当前的颜色" +TXT_OPT_APC_COLOR_PRESET = "预置" +TIP_OPT_APC_COLOR_LIGNT_BLUE = "天蓝色" +TIP_OPT_APC_COLOR_GREEN = "绿色" +TIP_OPT_APC_COLOR_ORANGE = "橙色" +TIP_OPT_APC_COLOR_CYAN_GREEN = "青绿色" +TIP_OPT_APC_COLOR_PINK = "浅红色" +TIP_OPT_APC_COLOR_LIGHT_PURPLE = "淡紫色" +TXT_OPT_APC_COLOR_MORE = "更多颜色..." +TXT_OPT_APC_COLOR_FOLLOW_SYSTEM = "跟随系统主题色" + +TXT_OPT_APC_STATUS_BAR = "状态栏" +TXT_OPT_APC_ALWAYS_SHOW_STATUS_BAR = "总是显示状态栏" +TXT_OPT_APC_SHOW_NEXT_TRACK = "显示下一曲" +TXT_OPT_APC_SHOW_FPS = "显示帧率" + +TXT_OPT_APC_TITLE_BAR = "标题栏" +TXT_OPT_APC_USE_SYSTEM_TITLE_BAR = "使用系统标准标题栏" +TXT_OPT_APC_TITLE_BAR_BTN_SEL = "在标题栏中显示的按钮(仅当未勾选“使用系统标准标题栏”时有效):" +TXT_OPT_APC_TITLE_BAR_BTN_SETTING = "设置" +TXT_OPT_APC_TITLE_BAR_BTN_SKIN = "切换界面" +TXT_OPT_APC_TITLE_BAR_BTN_MINI_MODE = "迷你模式" +TXT_OPT_APC_TITLE_BAR_BTN_FULLSCREEN = "全屏显示" +TXT_OPT_APC_TITLE_BAR_BTN_MINIMIZE = "最小化" +TXT_OPT_APC_TITLE_BAR_BTN_MAXIMIZE = "最大化/还原" + +TXT_OPT_APC_NOTIFY_ICON = "通知区图标" +TXT_OPT_APC_NOTIFY_ICON_PREVIEW = "预览:" +TXT_OPT_APC_NOTIFY_ICON_SEL = "选择通知区图标:" +TXT_OPT_APC_NOTIFY_ICON_DEFAULT = "默认图标" +TXT_OPT_APC_NOTIFY_ICON_LIGHT = "浅色图标" +TXT_OPT_APC_NOTIFY_ICON_DARK = "深色图标" +TXT_OPT_APC_NOTIFY_ICON_AUTO_ADAPT = "使用单色图标时根据Windows10深色/浅色模式自动适应" + +TXT_OPT_APC_ADVANCED = "高级" +TXT_OPT_APC_UI_REFRESH_INTERVAL = "界面刷新时间间隔 (毫秒):" +TXT_OPT_APC_UI_REFRESH_INTERVAL_RESTORE = "恢复默认" +TXT_OPT_APC_COVER_HQ = "专辑封面使用GDI+绘图(质量更高但是会占用更多的CPU资源)" + +# IDD_DATA_SETTINGS_DIALOG +TITLE_OPT_DATA = "常规设置" +TXT_OPT_DATA_APP_SETTING = "应用程序设置" +TXT_OPT_DATA_UPDATE_AUTO_CHECK = "启动时检查更新" +TXT_OPT_DATA_UPDATE_SOURCE_SEL = "更新源:" +TXT_OPT_DATA_UPDATE_SOURCE_GITHUB = "Github" +TXT_OPT_DATA_UPDATE_SOURCE_GITEE = "Gitee" +TXT_OPT_DATA_AUTO_RUN = "开机自动运行" +TXT_OPT_DATA_LANGUAGE_SEL = "语言 (Language):" +TXT_OPT_DATA_LANGUAGE_FOLLOWING_SYSTEM = "跟随系统" +TXT_OPT_DATA_DATA_FILE_CFG = "配置和数据文件" +TXT_OPT_DATA_DATA_FILE_SAVE_DIR_APPDATA = "保存到 Appdata 目录" +TXT_OPT_DATA_DATA_FILE_SAVE_DIR_PROGRAM = "保存到程序所在目录" +TXT_OPT_DATA_DATA_FILE_DIR_OPEN = "打开配置文件所在目录" +TXT_OPT_DATA_CLOSE_MAIN_WINDOW = "关闭主窗口" +TXT_OPT_DATA_CLOSE_MAIN_WINDOW_MINIMIZE_NOTIFY_AREA = "最小化到通知区" +TXT_OPT_DATA_CLOSE_MAIN_WINDOW_EXIT = "退出程序" +TXT_OPT_DATA_AUTO_DL_SETTING = "自动下载设置" +TXT_OPT_DATA_AUTO_DL_LYRIC = "没有歌词时自动下载" +TXT_OPT_DATA_AUTO_DL_LYRIC_SAVE_SEL = "自动下载歌词保存位置:" +TXT_OPT_DATA_AUTO_DL_LYRIC_SAVE_SONG_DIR = "保存到歌曲所在目录" +TXT_OPT_DATA_AUTO_DL_LYRIC_SAVE_LYRIC_DIR = "保存到歌词文件夹" +TXT_OPT_DATA_AUTO_DL_COVER = "没有专辑封面时自动下载" +TXT_OPT_DATA_AUTO_DL_COVER_SAVE_SEL = "自动下载封面保存位置:" +TXT_OPT_DATA_AUTO_DL_COVER_SAVE_SONG_DIR = "保存到歌曲所在目录" +TXT_OPT_DATA_AUTO_DL_COVER_SAVE_COVER_DIR = "保存到封面文件夹" +TXT_OPT_DATA_AUTO_DL_ONLY_WHEN_TAG_FULL = "只有歌曲信息完整时才自动下载" +TIP_OPT_DATA_AUTO_DL_ONLY_WHEN_TAG_FULL = "勾选此项后,只有当歌曲的“标题”和“艺术家”信息都不为空时,才自动下载歌词和专辑封面。" +TXT_OPT_DATA_MIDI_SETTING = "MIDI 设置" +TXT_OPT_DATA_MIDI_INNER_LYRIC_FIRST = "优先显示 MIDI 音乐内嵌的歌词" +TIP_OPT_DATA_MIDI_INNER_LYRIC_FIRSR = "有些 MIDI 音乐包含歌词,勾选此项后,会优先显示 MIDI 音乐内嵌的歌词。" +TXT_OPT_DATA_MIDI_SF2_PATH = "MIDI 音色库路径:" +MSG_OPT_DATA_LANGUAGE_CHANGE_INFO = "请重新启动程序使语言设置生效。" +MSG_OPT_DATA_CFG_DIR_CHANGED_INFO = "你更改了配置文件和数据文件的保存位置,重启后生效。你可能需要手动将配置文件和数据文件转移到新的位置。" + +# IDD_PLAY_SETTING_DIALOG +TITLE_OPT_PLAY = "播放设置" + +TXT_OPT_PLAY_PLAY_OPT = "播放选项" +TXT_OPT_PLAY_STOP_WHEN_ERROR = "出现错误时停止播放" +TXT_OPT_PLAY_AUTO_PLAY_WHEN_START = "程序启动时自动播放" +TXT_OPT_PLAY_SHOW_TASKBAR_PROGRESS = "在任务栏显示播放进度" +TXT_OPT_PLAY_SHOW_TASKBAR_PLAY_STATE_ICON = "在任务栏显示播放状态图标" +TXT_OPT_PLAY_SOUND_FADE = "声音淡入淡出效果" +TXT_OPT_PLAY_CONTINUE_WHEN_SWITCH_PLAYLIST = "切换播放列表时继续播放" +TIP_OPT_PLAY_CONTINUE_WHEN_SWITCH_PLAYLIST = "勾选此项后,在切换播放列表时,如果新的播放列表中存在正在播放的曲目,则在切换播放列表后继续播放当前播放的曲目。" +TXT_OPT_PLAY_USE_MEDIA_TRANS_CONTORL = "使用系统媒体控件" + +TXT_OPT_PLAY_CORE = "播放内核" +TXT_OPT_PLAY_CORE_BASS = "BASS" +TXT_OPT_PLAY_CORE_MCI = "MCI (Media Control Interface)" +TIP_OPT_PLAY_CORE_MCI = "使用MCI内核将导致格式转换和音效设置功能无法使用,且部分音频无法播放。建议仅在需要的时候切换为此内核。" +TXT_OPT_PLAY_CORE_FFMPEG = "FFMPEG" +TIP_OPT_PLAY_CORE_FFMPEG = "使用FFMPEG内核将导致混响功能和格式转换无法使用,且不支持播放MIDI文件。需要有 ffmpeg_core.dll。" +TXT_OPT_PLAY_CORE_FFMPEG_DL_INFO = "点击此处下载" +MSG_OPT_PLAY_CORE_FFMPEG_DL_INFO = "FFMPEG内核需要单独下载,下载后请将解压得到的所有dll文件放到程序所在目录下。要下载FFMPEG内核吗?" + +TXT_OPT_PLAY_DEVICE = "播放设备" +TXT_OPT_PLAY_DEVICE_SEL = "选择播放设备:" +TXT_OPT_PLAY_DEVICE_NAME = "名称" +TXT_OPT_PLAY_DEVICE_NAME_BASS_DEFAULT = "默认输出设备" +TXT_OPT_PLAY_DEVICE_NAME_SDL_DEFAULT = "SDL 默认音频设备" +TXT_OPT_PLAY_DEVICE_DRIVER = "驱动程序" +TXT_OPT_PLAY_DEVICE_TYPE = "设备类型" +TXT_OPT_PLAY_DEVICE_TYPE_BASS_NETWORK = "用户通过网络远程访问的音频端点设备。" +TXT_OPT_PLAY_DEVICE_TYPE_BASS_SPEAKERS = "扬声器" +TXT_OPT_PLAY_DEVICE_TYPE_BASS_LINE = "音频端点设备,用于将线路级模拟信号发送到音频适配器上的线路输入插孔,或从适配器上的输出插孔接收线路级模拟信号。" +TXT_OPT_PLAY_DEVICE_TYPE_BASS_HEADPHONES = "耳机" +TXT_OPT_PLAY_DEVICE_TYPE_BASS_MICROPHONE = "麦克风" +TXT_OPT_PLAY_DEVICE_TYPE_BASS_HEADSET = "用于双向通信的带话筒的单个或一对耳机。" +TXT_OPT_PLAY_DEVICE_TYPE_BASS_HANDSET = "包含用于双向通信的扬声器和麦克风的手持电话的一部分。" +TXT_OPT_PLAY_DEVICE_TYPE_BASS_DIGITAL = "通过用于未知类型数字接口的连接器连接到音频适配器的音频端点设备。" +TXT_OPT_PLAY_DEVICE_TYPE_BASS_SPDIF = "通过索尼/飞利浦数字接口 (PDIF) 连接器连接到音频适配器的音频端点设备。" +TXT_OPT_PLAY_DEVICE_TYPE_BASS_HDMI = "通过高清晰度多媒体接口 (HDMI) 连接器连接到音频适配器的音频端点设备。" +TXT_OPT_PLAY_DEVICE_TYPE_BASS_DISPLAYPORT = "通过 DisplayPort 连接器连接到音频适配器的音频端点设备。" + +TXT_OPT_PLAY_FFMPEG_CORE_SETTING = "FFMPEG 核心设置" +TXT_OPT_PLAY_FFMPEG_CORE_CACHE_LENGTH = "缓存时长 (秒):" +TXT_OPT_PLAY_FFMPEG_CORE_MAX_RETRY_COUNT = "最大重试次数 (-1为无限制):" +TXT_OPT_PLAY_FFMPEG_CORE_URL_RETRY_INTERVAL = "非本地文件重试间隔 (秒):" +TXT_OPT_PLAY_FFMPEG_CORE_MAX_WAIT_TIME = "定位等操作最大等待时间 (毫秒):" +TXT_OPT_PLAY_FFMPEG_CORE_ENABLE_WASAPI = "启用WASAPI" +TXT_OPT_PLAY_FFMPEG_CORE_ENABLE_WASAPI_EXCLUSIVE = "启用独占模式" + +# IDD_MEDIA_LIB_SETTING_DIALOG +TITLE_OPT_MEDIA_LIB = "媒体库" + +TXT_OPT_MEDIA_LIB_MEDIA_LIB_OPT = "媒体库选项" +TXT_OPT_MEDIA_LIB_DISABLE_DEL = "禁用从磁盘删除" +TXT_OPT_MEDIA_LIB_USE_CLASSIFY_OTHER = "将只有一项的分类归到其他类中" +TXT_OPT_MEDIA_LIB_TOO_SHORT_SEC = "音频文件低时长阈值 (秒):" +TXT_OPT_MEDIA_LIB_ARTIST_SPLIT_EXT_SEL = "艺术家识别例外:" +TIP_OPT_MEDIA_LIB_ARTIST_SPLIT_EXT = "添加所有名称本身含有“/\;&&、”的艺术家作为例外,避免程序误识别。" +TXT_OPT_MEDIA_LIB_MEDIA_LIB_UPDATE_OPT = "媒体库更新选项" +TXT_OPT_MEDIA_LIB_REMOVE_FILE_NOT_EXIST = "移除不存在的音频文件" +TXT_OPT_MEDIA_LIB_IGNORE_TOO_SHORT = "忽略时长低于阈值的文件" +TXT_OPT_MEDIA_LIB_AUTO_UPDATE_WHEN_STARTUP = "启动时自动更新媒体库" +TIP_OPT_MEDIA_LIB_AUTO_UPDATE_WHEN_STARTUP = "勾选此项时,程序会在启动时自动扫描“媒体库目录”中的音频文件。" +TXT_OPT_MEDIA_LIB_FORCE_RELOAD = "强制重新加载" +MSG_OPT_MEDIA_LIB_UPDATING_INFO = "媒体库正在更新,请稍后再试!" +TXT_OPT_MEDIA_LIB_MEDIA_LIB_DIR = "媒体库目录" +TXT_OPT_MEDIA_LIB_MEDIA_LIB_DIR_ADD = "添加..." +TXT_OPT_MEDIA_LIB_MEDIA_LIB_DIR_DEL = "删除" +TXT_OPT_MEDIA_LIB_MEDIA_LIB_DISP_TAB = "在媒体库中显示的项目" +TXT_OPT_MEDIA_LIB_PLAYLIST_OPT = "播放列表选项" +TXT_OPT_MEDIA_LIB_DISABLE_DRAGE_SORT = "禁用播放列表曲目拖放排序" +TXT_OPT_MEDIA_LIB_INS_BEGIN = "向播放列表中添加曲目时插入到开头而不是末尾" +TXT_OPT_MEDIA_LIB_FLOAT_PLAYLIST_BY_DEFAULT = "默认使用浮动播放列表" +TXT_OPT_MEDIA_LIB_FLOAT_PLAYLIST_FOLLOW_MAIN_WND = "浮动播放列表跟随主窗口" +TXT_OPT_MEDIA_LIB_SHOW_TOOLTIP = "显示播放列表鼠标提示" +TXT_OPT_MEDIA_LIB_PLAYLIST_DISPLAY_MODE = "播放列表显示方式:" +TXT_OPT_MEDIA_LIB_PLAYLIST_ITEM_HEIGHT = "播放列表项目高度 (像素):" +TXT_OPT_MEDIA_LIB_RECENT_PLAY = "最近播放" +TXT_OPT_MEDIA_LIB_RECENT_PLAY_RANGE_SEL = "最近播放显示范围:" +TXT_OPT_MEDIA_LIB_RECENT_PLAY_RANGE_ALL = "全部" +TXT_OPT_MEDIA_LIB_RECENT_PLAY_RANGE_TODAY = "今天" +TXT_OPT_MEDIA_LIB_RECENT_PLAY_RANGE_LAST_THREE_DAYS = "最近三天" +TXT_OPT_MEDIA_LIB_RECENT_PLAY_RANGE_LAST_WEEK = "最近一星期" +TXT_OPT_MEDIA_LIB_RECENT_PLAY_RANGE_LAST_MONTH = "最近一个月" +TXT_OPT_MEDIA_LIB_RECENT_PLAY_RANGE_LAST_HALF_YEAR = "最近半年" +TXT_OPT_MEDIA_LIB_RECENT_PLAY_RANGE_LAST_YEAR = "最近一年" +TXT_OPT_MEDIA_LIB_RECENT_PLAY_CLEAR = "清空最近播放曲目列表..." +MSG_OPT_MEDIA_LIB_RECENT_PLAY_CLEAR_INQUARY = "确实要清空最近播放曲目列表吗?" +TXT_OPT_MEDIA_LIB_CLEAN_MEDIA_LIB = "清理媒体库" +TXT_OPT_MEDIA_LIB_CURRENT_DATA_FILE_SIZE_BYTE = "当前数据文件大小: <%1%> 字节" +TXT_OPT_MEDIA_LIB_CURRENT_DATA_FILE_SIZE_KB = "当前数据文件大小: <%2%> KB (<%1%> 字节)" +TXT_OPT_MEDIA_LIB_CURRENT_DATA_FILE_SIZE_MB = "当前数据文件大小: <%2%> MB (<%1%> 字节)" +TXT_OPT_MEDIA_LIB_DATA_FILE_CLEAN = "清理..." +TIP_OPT_MEDIA_LIB_DATA_FILE_CLEAN = "说明: 程序目录下的 song_data.dat 文件保存了所有加载过的歌曲信息,用于加快播放列表的载入速度。点击此按钮选择清理范围。" +MSG_OPT_MEDIA_LIB_DATA_FILE_CLEAR_COMPLETE = "清理完成,已删除 <%1%> 个项目,数据文件大小减小 <%2%> 个字节。" +TXT_OPT_MEDIA_LIB_TAG_EDIT = "标签读写" +TXT_OPT_MEDIA_LIB_TAG_ID3V2_WRITE_TYPE = "ID3v2写入类型:" + +TXT_OPT_LAST_FM = "Last.fm" +TXT_OPT_LAST_FM_ENABLE = "启用 last.fm 相关功能" +TXT_OPT_LAST_FM_STATUS_LOGIN_REQUIRED = "当前状态: 需要登录" +TXT_OPT_LAST_FM_STATUS_LOGIN_LOGGED = "当前状态: 已登录 (<%1%>)" +TXT_OPT_LAST_FM_USE_HTTPS = "使用 HTTPS 与 last.fm 服务器通信" +TXT_OPT_LAST_FM_LOGIN = "登录" +MSG_OPT_LAST_FM_LOGIN_PROMPT = "请您在打开的浏览器窗口内完成登录并在登录成功后单击确定。" +MSG_OPT_LAST_FM_LOGIN_FAILED = "登录失败!" +TXT_OPT_LAST_FM_UPLOAD_NOW_PLAYING = "上传当前播放歌曲" +TXT_OPT_LAST_FM_CACHE_CONDITION = "播放进度满足以下条件时计入缓存" +TXT_OPT_LAST_FM_CACHE_CONDITION_PERCENT = "至少播放的百分比:" +TXT_OPT_LAST_FM_CACHE_CONDITION_DURATION = "至少播放的时长 (秒):" +TXT_OPT_LAST_FM_CACHE_STATUS = "缓存状态: <%1%> 条记录" +TXT_OPT_LAST_FM_CACHE_UPLOAD = "上传缓存" +TXT_OPT_LAST_FM_UPLOAD_WHEN_REACH_THRESHOLD = "当缓存中记录数达到阈值时上传记录" +TXT_OPT_LAST_FM_AUTO_UPLOAD_THRESHOLD = "自动上传阈值:" + +# IDD_HOT_KEY_SETTINGS_DIALOG +TITLE_OPT_HOT_KEY = "全局快捷键" +TXT_OPT_HOT_KEY_HOOK_SHORTCUT_KEY_ENABLE = "启用全局快捷键" +TXT_OPT_HOT_KEY_HOOK_MULTI_MEDIA_KEY_ENABLE = "启用全局多媒体快捷键" +TIP_OPT_HOT_KEY_HOOK_MULTI_MEDIA_KEY = "勾选此选项后,即使程序在后台运行,你仍然可以使用键盘上的多媒体按键控制音乐的播放。需要重新启动程序才能生效。" +TXT_OPT_HOT_KEY_FUNCTION = "功能" +TXT_OPT_HOT_KEY_SHORTCUT_KEY = "快捷键" +TXT_OPT_HOT_KEY_PLAY_PAUSE = "播放/暂停" +TXT_OPT_HOT_KEY_STOP = "停止" +TXT_OPT_HOT_KEY_FAST_FORWARD = "快进" +TXT_OPT_HOT_KEY_REWIND = "快退" +TXT_OPT_HOT_KEY_PREVIOUS = "上一曲" +TXT_OPT_HOT_KEY_NEXT = "下一曲" +TXT_OPT_HOT_KEY_VOLUME_UP = "增大音量" +TXT_OPT_HOT_KEY_VOLUME_DOWN = "减小音量" +TXT_OPT_HOT_KEY_EXIT = "退出" +TXT_OPT_HOT_KEY_PLAYER_SHOW_HIDE = "显示/隐藏播放器" +TXT_OPT_HOT_KEY_DESKTOP_LYRIC_SHOW_HIDE = "显示/隐藏桌面歌词" +TXT_OPT_HOT_KEY_SHORTCUT_KEY_SEL = "快捷键:" +TXT_OPT_HOT_KEY_SHORTCUT_KEY_SET = "设置" +MSG_OPT_HOT_KEY_GLOBLE_HOT_KEY_WARNING = "全局快捷键至少需要包含Ctrl、Shift、Alt中的一个!" + +# IDD_MEDIA_LIB_DIALOG +TITLE_LIB = "媒体库" +TXT_LIB_MEDIA_LIB_SETTING = "媒体库设置..." +TXT_LIB_STATISTICS_INFO = "统计信息..." +TXT_LIB_PLAY_SEL = "播放选中" +# IDD_SET_PATH_DIALOG +TXT_LIB_PATH_CURRENT_FOLDER = "当前文件夹:" +TXT_LIB_PATH_OPEN_NEW_FOLDER = "打开新文件夹..." +TXT_LIB_PAHT_IS_CONTAIN_SUB_FOLDER = "包含子文件夹" +TXT_LIB_PAHT_IS_CONTAIN_SUB_FOLDER_YES = "是" +MSG_LIB_PATH_CLEAR_INQUARY = "确实要清除列表中无效的文件夹吗?" +MSG_LIB_PATH_CLEAR_COMPLETE = "完成,清除了 <%1%> 个无效的文件夹。" +# IDD_SELECT_PLAYLIST_DIALOG +TXT_LIB_PLAYLIST_NEW_PLAYLIST = "新建播放列表..." +# CMediaLibStatisticsDlg +TITLE_LIB_STATISTICS = "媒体库统计" +TXT_LIB_STATISTICS_TOTAL_NUM_OF_TRACK = "曲目总数" +TXT_LIB_STATISTICS_NUM_OF_TRACK_PLAYED = "播放过的曲目数" + +# IDD_LYRIC_RELATE_DIALOG +TITLE_LRC_RELATE = "关联本地歌词" +TXT_LRC_RELATE_LRC_TITLE = "歌词标题:" +TXT_LRC_RELATE_FUZZY_MATCH = "部分匹配" +TXT_LRC_RELATE_SEARCH_LOCAL = "本地搜索" +TXT_LRC_RELATE_SEARCH_RESULT = "搜索结果:" +TXT_LRC_RELATE_IS_RELATED = "是否关联" +TXT_LRC_RELATE_IS_RELATED_YES = "是" +TXT_LRC_RELATE_BROWSE = "浏览..." +TXT_LRC_RELATE_DEL_FILE = "删除文件" +TXT_LRC_RELATE_UNLINK = "不关联歌词" +TXT_LRC_RELATE_SEL_LINK = "关联选中歌词" + +# IDD_FILE_RELATE_DIALOG +TITLE_FILE_RELATE = "文件关联" +TXT_FILE_RELATE_SEL_DEFAULT = "默认" +TXT_FILE_RELATE_SEL_ALL = "全选" +TXT_FILE_RELATE_FORMAT = "格式" +TXT_FILE_RELATE_DESCRIPTION = "说明" + +# IDD_LISTEN_TIME_STATISTICS_DLG +TITLE_LISTEN_TIME = "累计播放时间统计" +TXT_LISTEN_TIME_TOTAL_TIME = "累计时间" +TXT_LISTEN_TIME_TOTAL_COUNT = "累计次数" +TXT_LISTEN_TIME_EXPORT = "导出..." +TXT_LISTEN_TIME_CLEAR = "清空" +MSG_LISTEN_TIME_CLEAR_WARNING = "确实要清空所有统计数据吗?" + +# IDD_ABOUTBOX +TITLE_ABOUTBOX = "关于 MusicPlayer2" +TXT_ABOUTBOX_LAST_BUILD_DATE = "最后编译日期: <%1%>" +TXT_ABOUTBOX_THIRD_PARTY_LIB = "本项目使用的第三方库:" +TXT_ABOUTBOX_OTHER_SOFTWARE = "作者的其他软件:" +TXT_ABOUTBOX_CONTRACT_AUTHOR = "联系作者" +TXT_ABOUTBOX_CHECK_UPDATE = "检查更新" +TXT_ABOUTBOX_GITHUB = "Github" +TXT_ABOUTBOX_LICENSE = "开源协议" +TXT_ABOUTBOX_DONATE = "捐助" +TXT_ABOUTBOX_ACKNOWLEDGEMENT = "鸣谢" +TIP_ABOUTBOX_SEND_EMAIL_TO_ATHOUR = "向作者发送电子邮件" +TIP_ABOUTBOX_GOTO_GITHUB = "转到此项目在GitHub上的页面" +TIP_ABOUTBOX_TRAFFICMONITOR_DESCRIPTION = "TrafficMonitor: 功能强大的Windows网速监控软件" +TIP_ABOUTBOX_SIMPLENOTEPAD_DESCRIPTION = "SimpleNotePad: 简洁的 Windows 文本编辑器" + +# IDD_ADD_TO_PLAYLIST_DIALOG +TITLE_ADD_TO_PLAYLIST = "选择播放列表" + +# IDD_DONATE_DIALOG +TITLE_DONATE = "捐助" +TXT_DONATE_INFO = "如果你觉得这个软件对你有帮助,你可以扫描下方的二维码通过支付宝或微信捐助作者,以帮助作者把这个软件做得更好。金额请随意。" + +# IDD_TAG_MODE_SELECT_DIALOG / CTagSelBaseDlg +TXT_TAG_SEL_CLEAR_HISTORY = "清除历史记录..." +MSG_TAG_SEL_CLEAR_HISTORY_INQUARY = "确实要清除历史记录吗?" +TXT_TAG_SEL_ORIGINAL = "原文件名:" +TXT_TAG_SEL_CLICK_BTN_SEL = "点击按钮时:" +TXT_TAG_SEL_CLICK_BTN_INS = "插入" +TXT_TAG_SEL_CLICK_BTN_COPY = "复制到剪贴板" +# CRenameDlg +TITLE_RENAME_SONG = "重命名" +TXT_RENAME_SONG_INFO = "选择重命名模板或输入新文件名:" +MSG_RENAME_SONG_COMPLETED_INFO = "重命名 <%1%> 个文件,成功 <%2%> 个,忽略 <%3%> 个,失败 <%4%> 个。" +# CTagFromNameDlg +TITLE_TAG_FROM_NAME = "从文件名获取标签" +TXT_TAG_FROM_NAME_INFO = "请选择标签提取模板:" +# CFileNameFormDlg +TITLE_FILE_NAME_FORM = "设置文件名模板" +TXT_FILE_NAME_FORM_INFO = "请选择或输入文件名模板:" + +# CMusicPlayerCmdHelper::OnViewArtist / CSelectItemDlg +TITLE_SELECT_ARTIST = "选择艺术家" + +# CSelectPlaylistDlg::DoNewPlaylist / CMusicPlayerCmdHelper::OnAddToNewPlaylist / CInputDlg +TITLE_NEW_PLAYLIST = "新建播放列表" +TXT_NEW_PLAYLIST_INPUT_PLAYLIST_NAME = "输入播放列表名称:" + +# CSelectPlaylistDlg::OnRenamePlaylist / CInputDlg +TITLE_RENAME_PLAYLIST = "重命名播放列表" +TXT_RENAME_PLAYLIST_INPUT_PLAYLIST_NAME = "输入播放列表名称:" + +# CMusicPlayerDlg::OnFileOpenUrl / CMusicPlayerDlg::OnPlaylistAddUrl / CInputDlg +TITLE_INPUT_URL_OPEN_URL = "打开URL" +TITLE_INPUT_URL_ADD_URL = "添加URL" +TXT_INPUT_URL_INPUT_URL = "请输入URL:" +MSG_INPUT_URL_INVALID_WARNING = "请输入正确的URL!" + +# CLyricDownloadDlg::OnLdPreview / CMessageDlg +TITLE_LYRIC_PREVIEW = "歌词预览" + +# CCrashReport::ShowCrashInfo / CMessageDlg +TITLE_CRASH_REPOART = "错误" +TXT_CRASH_REPOART_ERROR_MESSAGE = "错误信息:" +TXT_CRASH_REPOART_CRASH_INFO = "很抱歉,程序出现了错误,请将此文件 “<%1%>” 通过电子邮件发送到 zhongyang219@hotmail.com,以帮助作者确定问题所在。并将以下内容添加到邮件正文中:\r\n<%2%>" + +# CAboutDlg::OnNMClickLicenseSyslink / CMessageDlg +TITLE_LICENSE = "开源协议" +TXT_LICENSE_EXPLAIN = "使用本软件的源代码时请遵守以下开源协议。" + +# CAboutDlg::OnNMClickAcknowledgementSyslink / CMessageDlg +TITLE_ACKNOWLEDGEMENT = "鸣谢" +TXT_ACKNOWLEDGEMENT_INFO = "感谢以下GitHub用户为本项目做出的贡献!" + +# CMusicPlayerApp::OnHelp / CMessageDlg +TITLE_HELP_DLG = "帮助" +TXT_HELP_DLG_WELCOM_TO_USE = "欢迎使用MusicPlayer2!" +TXT_HELP_DLG_SHOW_ONLINE_HELP = "点击此处查看详细在线帮助文档。" +TXT_HELP_DLG_HELP_INFO = "【功能介绍】\r\nMusicPlayer2是一款集音乐播放、歌词显示、格式转换等众多功能于一身的音频播放软件。支持歌词显示、歌词卡拉OK样式显示、歌词在线下载、歌词编辑、歌曲标签识别、专辑封面显示、专辑封面在线下载、频谱分析、音效设置、任务栏缩略图按钮、主题颜色、格式转换等功能。\r\n播放内核为BASS音频库(V2.4)。\r\n播放器支持几乎所有常见的音频格式。详细的支持的文件列表参见帮助菜单——支持的格式。\r\n\r\n【操作说明】\r\n你有以下多种方法可以打开并播放歌曲:\r\n1、选择“文件”菜单中的“打开文件”或“打开文件夹”命令。\r\n2、在“媒体库”对话框的“文件夹”选项卡中选择播放过的文件夹,或点击“打开新文件夹”按钮播放一个新的文件夹。\r\n3、在“媒体库”对话框的“播放列表”选项卡中选择播放过的播放列表,或点击“新建播放列表”按钮创建一个新的播放列表。\r\n4、直接将文件或文件夹拖放到程序主窗口。\r\n5、直接将文件或文件夹拖放到程序的图标或其快捷方式图标上。\r\n\r\n【媒体库】\r\n点击主界面右上角的“媒体库”按钮,或使用快捷键Ctrl+T可以打开媒体库对话框。\r\n媒体库提供文件夹和播放列表两种模式来管理组织音乐。\r\n在文件夹模式下,每次打开一个文件夹进行播放,播放器会自动搜索文件夹内的音频文件并加载到播放列表,此时你无法对列表中的项目执行添加、删除、上移、下移等操作。\r\n在播放列表模式下,你可以建立播放列表,并在播放列表中自由添加音频文件。此模式下,你可以对列表中的项目自由编辑,添加、删除、上移、下移等命令也处理可用状态。\r\n播放列表模式下有两个特殊的播放列表:“默认”和“我喜欢的音乐”,你无法对这两个播放列表执行重命名和删除操作。其中,从资源管理器中打开的音频文件将添加到“默认”播放列表。在主界面中点击“我喜欢”按钮会将当前歌曲添加到“我喜欢的音乐”播放列表。\r\n\r\n【切换界面】\r\n目前MusicPlayer2提供了2种内置界面布局和若干用户自定义界面布局。\r\n可以通过主菜单“视图”——“切换界面”子菜单来切换所有的界面布局。使用快捷Ctrl+U可以依次切换所有可用的界面布局,或者使用快捷键Ctrl+数字键切换到指定的界面。\r\n\r\n【用户自定义界面】\r\nMusicPlayer2支持通过xml文件来自定义界面布局。用户自定义界面文件放在程序所在目录下的skins目录下。\r\n“切换界面”子菜单下可以看到的界面1~界面2为程序内置的界面布局,除此之外的界面由skins目录下的xml文件提供。要了解如何编辑用户自定义界面布局,请点击菜单栏“帮助”——“自定义界面”以查看关于用户自定义界面的详细说明。\r\n\r\n【快捷键说明】\r\n播放/暂停:空格\r\n上一曲:V\r\n下一曲:N\r\n快进5秒:→\r\n快退5秒:←\r\n音量加:↑\r\n音量减:↓\r\n切换循环模式:M\r\n快速查找:F\r\n选择文件夹:Ctrl+T\r\n查找歌曲:Ctrl+F\r\n打开文件位置:Ctrl+B\r\n选项设置:Ctrl+I\r\n打开文件:Ctrl+O\r\n打开文件夹:Ctrl+D\r\n歌词调整:Ctrl+PgUp/Ctrl+PgDn\r\n保存歌词调整:Ctrl+S\r\n迷你模式:Ctrl+M\r\n曲目信息:Ctrl+N\r\n音效设定:Ctrl+E\r\n全屏:F11\r\n显示/隐藏播放列表:Ctrl+L\r\n浮动播放列表:Ctrl+K\r\nAB重复:Ctrl+R\r\n重新初始化播放器:Ctrl+Q\r\n切换界面:Ctrl+U/Ctrl+数字键\r\n\r\n【鼠标动作】\r\n· 鼠标滚轮可以调整音量\r\n· 按住Shift点击鼠标右键可以弹出系统菜单" + +[scintlla] +TXT_SCI_UNDO = "撤销" +TXT_SCI_REDO = "重做" +TXT_SCI_CUT = "剪切" +TXT_SCI_COPY = "复制" +TXT_SCI_PASTE = "粘贴" +TXT_SCI_DELETE = "删除" +TXT_SCI_SELECT_ALL = "全选" + +[menu.MAIN_POP] +MAIN_FILE = "文件(&F)" +MAIN_PLAYCTRL = "播放控制(&P)" +MAIN_PLAYLIST = "播放列表(&L)" +MAIN_LRC = "歌词(&C)" +MAIN_VIEW = "视图(&V)" +MAIN_TOOL = "工具(&T)" +MAIN_HELP = "帮助(&H)" +ID_MENU_EXIT = "退出(&X)" +; DEBUG only +ID_TEST = "测试命令" +ID_TEST_DIALOG = "测试对话框" + +[menu.MAIN] +MAIN_FILE = "文件(&F)" +MAIN_PLAYCTRL = "播放控制(&P)" +MAIN_PLAYLIST = "播放列表(&L)" +MAIN_LRC = "歌词(&C)" +MAIN_VIEW = "视图(&V)" +MAIN_TOOL = "工具(&T)" +MAIN_HELP = "帮助(&H)" + +[menu.MAIN_FILE] +ID_FILE_OPEN = "打开文件(&O)..." +ID_FILE_OPEN_FOLDER = "打开文件夹(&F)..." +ID_FILE_OPEN_URL = "打开&URL..." +ID_FILE_OPEN_PLAYLIST = "打开播放列表(&P)..." +ID_MENU_EXIT = "退出(&X)" + +[menu.MAIN_PLAYCTRL] +ID_PLAY_PAUSE = "播放/暂停(&P)" +ID_STOP = "停止(&S)" +ID_PREVIOUS = "上一曲(&V)" +ID_NEXT = "下一曲(&N)" +ID_REW = "快退5秒(&R)" +ID_FF = "快进5秒(&F)" +ID_SPEED_UP = "加速播放" +ID_SLOW_DOWN = "减速播放" +ID_ORIGINAL_SPEED = "恢复原速" +MAIN_PLAYCTRL_REPEAT_MODE = "循环模式(&M)" +MAIN_PLAYCTRL_AB = "AB重复(&E)" + +[menu.MAIN_PLAYCTRL_REPEAT_MODE] +ID_PLAY_ORDER = "顺序播放(&O)" +ID_PLAY_SHUFFLE = "无序播放(&S)" +ID_PLAY_RANDOM = "随机播放(&R)" +ID_LOOP_PLAYLIST = "列表循环(&L)" +ID_LOOP_TRACK = "单曲循环(&T)" +ID_PLAY_TRACK = "单曲播放(&P)" + +[menu.MAIN_PLAYCTRL_AB] +ID_AB_REPEAT = "AB重复(&R)" +ID_SET_A_POINT = "设置A点(&A)" +ID_SET_B_POINT = "设置B点(&B)" +ID_NEXT_AB_REPEAT = "继续下一句AB重复(&N)" +ID_RESET_AB_REPEAT = "取消AB重复(&C)" + +[menu.MAIN_PLAYLIST] +MAIN_PLAYLIST_ADD = "添加(&A)" +MAIN_PLAYLIST_DEL = "删除(&D)" +ID_RELOAD_PLAYLIST = "重新载入播放列表(&R)" +ID_SAVE_AS_NEW_PLAYLIST = "保存为新播放列表(&N)..." +ID_SAVE_CURRENT_PLAYLIST_AS = "当前播放列表另存为(&S)..." +MAIN_PLAYLIST_SORT = "排序方式" +MAIN_PLAYLIST_DISP_MODE = "播放列表显示方式" +ID_LOCATE_TO_CURRENT = "定位到正在播放曲目(&L)" + +[menu.MAIN_PLAYLIST_ADD] +ID_PLAYLIST_ADD_FILE = "添加文件(&A)..." +ID_PLAYLIST_ADD_FOLDER = "添加文件夹(&F)..." +ID_PLAYLIST_ADD_URL = "添加&URL..." + +[menu.MAIN_PLAYLIST_DEL] +ID_REMOVE_FROM_PLAYLIST = "从列表中删除(&L)" +ID_DELETE_FROM_DISK = "从磁盘删除(&D)" +ID_EMPTY_PLAYLIST = "清空播放列表(&E)" +ID_REMOVE_SAME_SONGS = "删除相同项(&S)" +ID_REMOVE_INVALID_ITEMS = "删除无效项(&I)" + +[menu.MAIN_PLAYLIST_SORT] +ID_SORT_BY_FILE = "按文件名排序" +ID_SORT_BY_PATH = "按路径排序" +ID_SORT_BY_TITLE = "按标题排序" +ID_SORT_BY_ARTIST = "按艺术家排序" +ID_SORT_BY_ALBUM = "按唱片集排序" +ID_SORT_BY_TRACK = "按音轨序号排序" +ID_SORT_BY_LISTEN_TIME = "按播放时长排序" +ID_SORT_BY_MODIFIED_TIME = "按修改时间排序" + +[menu.MAIN_PLAYLIST_DISP_MODE] +ID_DISP_FILE_NAME = "文件名" +ID_DISP_TITLE = "标题" +ID_DISP_ARTIST_TITLE = "艺术家 - 标题" +ID_DISP_TITLE_ARTIST = "标题 - 艺术家" + +[menu.MAIN_LRC] +ID_RELOAD_LYRIC = "重新载入歌词(&R)" +ID_COPY_CURRENT_LYRIC = "复制当前歌词(&C)" +ID_COPY_ALL_LYRIC = "复制所有歌词(&A)" +ID_EDIT_LYRIC = "编辑歌词(&E)..." +MAIN_LRC_CH_CONV = "繁简转换(&V)" +ID_SHOW_LYRIC_TRANSLATE = "显示歌词翻译(&T)" +ID_SHOW_DESKTOP_LYRIC = "显示桌面歌词(&H)" +ID_LYRIC_FORWARD = "歌词提前0.5秒(&N)" +ID_LYRIC_DELAY = "歌词延后0.5秒(&Y)" +ID_SAVE_MODIFIED_LYRIC = "保存歌词更改(&S)" +ID_RELATE_LOCAL_LYRIC = "关联本地歌词(&K)..." +ID_DELETE_LYRIC = "删除歌词(&D)" +ID_UNLINK_LYRIC = "撤消歌词关联(&U)" +ID_BROWSE_LYRIC = "打开歌词文件位置(&P)" +MAIN_LRC_INNER_LRC = "内嵌歌词(&I)" +ID_DOWNLOAD_LYRIC = "下载歌词(&L)..." +ID_LYRIC_BATCH_DOWNLOAD = "歌词批量下载(&B)..." +MAIN_VIEW_SWITCH_UI = "切换界面(&W)" +ID_OPTION_SETTINGS = "选项(&O)..." + +[menu.MAIN_LRC_CH_CONV] +ID_TRANSLATE_TO_SIMPLIFIED_CHINESE = "转换为简体中文(&S)" +ID_TRANSLATE_TO_TRANDITIONAL_CHINESE = "转换为繁体中文(&T)" + +[menu.MAIN_LRC_INNER_LRC] +ID_EMBED_LYRIC_TO_AUDIO_FILE = "嵌入到音频文件(&E)" +ID_DELETE_LYRIC_FROM_AUDIO_FILE = "从音频文件中删除(&D)" + +[menu.MAIN_VIEW] +ID_SHOW_PLAYLIST = "显示播放列表(&L)" +ID_FLOAT_PLAYLIST = "浮动播放列表(&P)" +ID_USE_STANDARD_TITLE_BAR = "使用系统标准标题栏(&B)" +ID_SHOW_MENU_BAR = "显示菜单栏(&N)" +ID_ALWAYS_SHOW_STATUS_BAR = "总是显示状态栏(&S)" +ID_ALWAYS_ON_TOP = "总是置顶(&T)" +ID_MINI_MODE = "迷你模式(&M)" +ID_FULL_SCREEN = "全屏显示(&F)" +ID_DARK_MODE = "深色模式(&D)" +MAIN_VIEW_SWITCH_UI = "切换界面(&U)" + +[menu.MAIN_VIEW_SWITCH_UI] +ID_SWITCH_UI = "切换界面(&U)" + +[menu.MAIN_TOOL] +ID_MEDIA_LIB = "媒体库(&M)..." +ID_FIND = "查找歌曲(&F)..." +ID_EXPLORE_PATH = "打开文件位置(&B)" +ID_SONG_INFO = "曲目信息(&I)..." +ID_EQUALIZER = "音效设定(&E)..." +ID_FORMAT_CONVERT1 = "转换格式(&C)..." +ID_CURRENT_EXPLORE_ONLINE = "在线查看(&L)" +ID_RE_INI_BASS = "重新初始化播放器(&N)" +MAIN_TOOL_SHORTCUT = "创建快捷方式(&H)" +MAIN_TOOL_ALBUM_COVER = "专辑封面(&A)" +MAIN_TOOL_DEL_CUR_PLAYING = "删除正在播放的曲目" +ID_LISTEN_STATISTICS = "播放时间统计(&S)..." +ID_TOOL_FILE_RELATE = "文件关联(&R)..." +ID_OPTION_SETTINGS = "选项(&O)..." + +[menu.MAIN_TOOL_SHORTCUT] +ID_CREATE_DESKTOP_SHORTCUT = "创建桌面快捷方式(&D)" +ID_CREATE_PLAY_SHORTCUT = "创建播放控制快捷方式(&S)" +ID_CREATE_MINI_MODE_SHORT_CUT = "创建迷你模式快捷方式(&M)" + +[menu.MAIN_TOOL_ALBUM_COVER] +ID_DOWNLOAD_ALBUM_COVER = "下载专辑封面(&D)..." +ID_ALBUM_COVER_SAVE_AS = "专辑封面另存为(&S)..." +ID_DELETE_ALBUM_COVER = "删除专辑封面(&E)" +ID_ALBUM_COVER_INFO = "专辑封面详情(&C)..." + +[menu.MAIN_TOOL_DEL_CUR_PLAYING] +ID_REMOVE_CURRENT_FROM_PLAYLIST = "从播放列表删除(&P)" +ID_DELETE_CURRENT_FROM_DISK = "从磁盘删除(&D)" + +[menu.MAIN_HELP] +ID_HELP = "帮助(&H)" +ID_ONLINE_HELP = "在线帮助(&O)" +ID_HELP_FAQ = "常见问题(&F)" +ID_HELP_CUSTOM_UI = "自定义界面(&U)" +ID_HELP_UPDATE_LOG = "更新日志(&L)" +ID_SUPPORTED_FORMAT = "支持的格式(&F)" +ID_APP_ABOUT = "关于(&A)..." + +[menu.PLAYLIST_TOOLBAR] +MAIN_PLAYLIST_ADD = "添加(&A)" +MAIN_PLAYLIST_DEL = "删除(&D)" +MAIN_PLAYLIST_SORT = "排序(&S)" +PLAYLIST_TOOLBAR_LIST = "列表(&L)" +PLAYLIST_TOOLBAR_EDIT = "编辑(&E)" +PLAYLIST_TOOLBAR_FOLDER = "文件夹(&F)" +ID_LOCATE_TO_CURRENT = "定位(&G)" + +[menu.PLAYLIST_TOOLBAR_LIST] +ID_RELOAD_PLAYLIST = "重新载入播放列表(&R)" +ID_SAVE_AS_NEW_PLAYLIST = "保存为新播放列表(&N)..." +ID_SAVE_CURRENT_PLAYLIST_AS = "当前播放列表另存为(&S)..." +ID_PLAYLIST_FIX_PATH_ERROR = "修复错误的文件路径(&F)" +MAIN_PLAYLIST_DISP_MODE = "播放列表显示方式(&P)" +ID_PLAYLIST_OPTIONS = "选项(&O)..." + +[menu.PLAYLIST_TOOLBAR_EDIT] +ADD_TO_PLAYLIST = "添加到播放列表(&T)" +ID_COPY_FILE_TO = "复制文件到(&C)..." +ID_MOVE_FILE_TO = "移动文件到(&M)..." +ID_MOVE_PLAYLIST_ITEM_UP = "上移(&U)" +ID_MOVE_PLAYLIST_ITEM_DOWN = "下移(&W)" +ID_PLAYLIST_SELECT_ALL = "全部选择(&A)" +ID_PLAYLIST_SELECT_NONE = "全部取消(&L)" +ID_PLAYLIST_SELECT_REVERT = "反向选择(&R)" + +[menu.PLAYLIST_TOOLBAR_FOLDER] +ID_FILE_OPEN_FOLDER = "打开文件夹(&F)..." +ID_CONTAIN_SUB_FOLDER = "包含子文件夹(&S)" + +[menu.MAIN_AREA] +ID_SONG_INFO = "曲目信息(&I)..." +MAIN_PLAYCTRL_REPEAT_MODE = "循环模式(&M)" +ADD_TO_PLAYLIST = "添加到播放列表(&T)" +RATE = "分级(&A)" +ID_MEDIA_LIB = "媒体库(&T)..." +ID_FIND = "查找歌曲(&F)..." +ID_EXPLORE_PATH = "打开文件位置(&X)" +ID_EQUALIZER = "音效设定(&E)..." +ID_CURRENT_EXPLORE_ONLINE = "在线查看(&L)" +ID_DOWNLOAD_ALBUM_COVER = "下载专辑封面(&A)..." +ID_ALBUM_COVER_SAVE_AS = "专辑封面另存为(&S)..." +ID_DELETE_ALBUM_COVER = "删除专辑封面(&D)" +ID_ALWAYS_USE_EXTERNAL_ALBUM_COVER = "总是使用外部专辑封面(&N)" +ID_ALBUM_COVER_INFO = "专辑封面详情(&C)..." +ID_VIEW_ARTIST = "查看艺术家(&R)..." +ID_VIEW_ALBUM = "查看唱片集(&B)..." +MAIN_VIEW_SWITCH_UI = "切换界面(&U)" +ID_OPTION_SETTINGS = "选项(&O)..." + +[menu.MAIN_AREA_PLAYLIST_BTN] +ID_DOCKED_PLAYLIST = "停靠的播放列表(&D)" +ID_FLOATED_PLAYLIST = "浮动的播放列表(&F)" + +[menu.DLRC] +ID_PLAY_PAUSE = "播放/暂停(&P)" +ID_STOP = "停止(&S)" +ID_PREVIOUS = "上一曲(&V)" +ID_NEXT = "下一曲(&N)" +MAIN_PLAYCTRL_REPEAT_MODE = "循环模式(&M)" +ID_SHOW_MAIN_WINDOW = "显示主窗口(&W)" +ID_LYRIC_DISPLAYED_DOUBLE_LINE = "歌词双行显示(&D)" +ID_LYRIC_BACKGROUND_PENETRATE = "歌词背景穿透(&B)" +ID_LOCK_DESKTOP_LRYIC = "锁定桌面歌词(&L)" +DLRC_DEFAULT_STYLE = "预设方案(&E)" +ID_OPTION_SETTINGS = "选项(&O)..." +ID_CLOSE_DESKTOP_LYRIC = "关闭桌面歌词(&X)" + +[menu.DLRC_DEFAULT_STYLE] +ID_LYRIC_DEFAULT_STYLE1 = "预设 &1" +ID_LYRIC_DEFAULT_STYLE2 = "预设 &2" +ID_LYRIC_DEFAULT_STYLE3 = "预设 &3" + +[menu.RECENT_FOLDER_PLAYLIST] +ID_MEDIA_LIB = "媒体库(&L)..." + +[menu.PLAYLIST] +ID_PLAY_ITEM = "播放(&P)" +ID_PLAY_AS_NEXT = "下一首播放(&N)" +ID_EXPLORE_ONLINE = "在线查看(&O)" +ID_FORMAT_CONVERT = "转换格式(&F)..." +RATE = "分级(&A)" +ID_RELOAD_PLAYLIST = "重新载入播放列表(&R)" +ID_REMOVE_FROM_PLAYLIST = "从列表中删除(&L)" +ID_DELETE_FROM_DISK = "从磁盘删除(&D)" +ADD_TO_PLAYLIST = "添加到播放列表(&T)" +ID_COPY_FILE_TO = "复制文件到(&C)..." +ID_MOVE_FILE_TO = "移动文件到(&M)..." +ID_MOVE_PLAYLIST_ITEM_UP = "上移(&U)" +ID_MOVE_PLAYLIST_ITEM_DOWN = "下移(&W)" +ID_PLAYLIST_VIEW_ARTIST = "查看艺术家(&I)..." +ID_PLAYLIST_VIEW_ALBUM = "查看唱片集(&V)..." +ID_RENAME = "重命名(&E)..." +ID_EXPLORE_TRACK = "打开文件位置(&B)" +ID_ITEM_PROPERTY = "属性(&Y)..." + +[menu.RATE] +ID_RATING_1 = "&1 星" +ID_RATING_2 = "&2 星" +ID_RATING_3 = "&3 星" +ID_RATING_4 = "&4 星" +ID_RATING_5 = "&5 星" +ID_RATING_NONE = "未分级(&U)" + +[menu.ADD_TO_PLAYLIST] +ID_ADD_TO_NEW_PLAYLIST = "新建播放列表(&N)..." +ID_ADD_TO_DEFAULT_PLAYLIST = "默认" +ID_ADD_TO_MY_FAVOURITE = "我喜欢的音乐" +ID_ADD_TO_OTHER_PLAYLIST = "更多播放列表(&M)..." + +[menu.MINI_AREA] +ID_SONG_INFO = "曲目信息(&I)..." +MAIN_PLAYCTRL_REPEAT_MODE = "循环模式(&M)" +ADD_TO_PLAYLIST = "添加到播放列表(&T)" +ID_DOWNLOAD_LYRIC = "下载歌词(&L)..." +ID_DOWNLOAD_ALBUM_COVER = "下载专辑封面(&D)..." +ID_ADD_REMOVE_FROM_FAVOURITE = "添加到我喜欢的音乐(&A)" +ID_MEDIA_LIB = "媒体库(&T)..." +ID_FIND = "查找歌曲(&F)..." +ID_EXPLORE_PATH = "打开文件位置(&B)" +ID_EQUALIZER = "音效设定(&E)..." +ID_OPTION_SETTINGS = "选项(&O)..." +ID_SHOW_PLAY_LIST = "显示播放列表(&P)" +ID_MINI_MODE_ALWAYS_ON_TOP = "总是置顶(&Y)" +MINI_SWITCH_UI = "切换界面(&U)" +ID_MINI_MIDE_MINIMIZE = "最小化(&N)" +IDOK = "返回正常模式(&R)" +ID_MINI_MODE_EXIT = "退出(&X)" + +[menu.MINI_SWITCH_UI] +ID_MINIMODE_UI_DEFAULT = "默认界面(&D)" + +[menu.NOTIFY] +ID_PLAY_PAUSE = "播放/暂停(&P)" +ID_PREVIOUS = "上一曲(&V)" +ID_NEXT = "下一曲(&N)" +MAIN_PLAYCTRL_REPEAT_MODE = "循环模式(&M)" +ID_MINIMODE_RESTORE = "迷你模式/还原(&R)" +ID_SHOW_DESKTOP_LYRIC = "显示桌面歌词(&S)" +ID_LOCK_DESKTOP_LRYIC = "锁定桌面歌词(&L)" +ID_OPTION_SETTINGS = "选项(&O)..." +ID_MENU_EXIT = "退出(&X)" + +[menu.LIB_SET_PATH] +ID_PLAY_PATH = "播放文件夹(&P)" +ID_DELETE_PATH = "从列表中删除(&D)" +ID_BROWSE_PATH = "打开文件夹位置(&B)" +ID_CONTAIN_SUB_FOLDER = "包含子文件夹(&S)" +ID_CLEAR_INVALID_PATH = "清除无效文件夹(&C)" + +[menu.LIB_PLAYLIST] +ID_PLAY_PLAYLIST = "播放(&P)" +ID_RENAME_PLAYLIST = "重命名(&R)..." +ID_DELETE_PLAYLIST = "删除(&D)" +ID_SAVE_AS_NEW_PLAYLIST = "保存为新播放列表(&S)..." +ID_PLAYLIST_SAVE_AS = "另存为(&A)..." +ID_PLAYLIST_BROWSE_FILE = "打开播放列表文件位置(&B)" +ID_PLAYLIST_FIX_PATH_ERROR = "修复错误的文件路径(&F)" +ID_NEW_PLAYLIST = "新建播放列表(&N)..." + +[menu.LIB_LEFT] +ID_PLAY_ITEM = "播放(&P)" +ADD_TO_PLAYLIST = "添加到播放列表(&T)" +ID_ADD_TO_NEW_PLAYLIST_AND_PLAY = "添加到新播放列表并播放(&N)..." +ID_COPY_TEXT = "复制文本(&C)" + +[menu.LIB_RIGHT] +ID_PLAY_ITEM = "播放(&P)" +ID_PLAY_AS_NEXT = "下一首播放(&N)" +ID_PLAY_ITEM_IN_FOLDER_MODE = "在文件夹模式中播放(&D)" +ADD_TO_PLAYLIST = "添加到播放列表(&T)" +ID_ADD_TO_NEW_PLAYLIST_AND_PLAY = "添加到新播放列表并播放(&N)..." +ID_EXPLORE_ONLINE = "在线查看(&O)" +ID_FORMAT_CONVERT = "转换格式(&F)..." +ID_EXPLORE_TRACK = "打开文件位置(&B)" +ID_DELETE_FROM_DISK = "从磁盘删除(&D)" +ID_ITEM_PROPERTY = "属性(&Y)..." +ID_COPY_TEXT = "复制文本(&C)" + +[menu.LE] +LE_FILE = "文件(&F)" +LE_EDIT = "编辑(&E)" +LE_PLAY_CTRL = "播放控制(&P)" + +[menu.LE_FILE] +ID_LYRIC_OPEN = "打开(&O)..." +ID_LYRIC_SAVE = "保存(&S)" +ID_LYRIC_SAVE_AS = "另存为(&A)..." +IDCANCEL = "退出(&X)" + +[menu.LE_EDIT] +ID_LYRIC_INSERT_TAG = "插入时间标签(&I)" +ID_LYRIC_REPLACE_TAG = "替换时间标签(&R)" +ID_LYRIC_DELETE_TAG = "删除时间标签(&D)" +ID_LYRIC_FIND = "查找(&F)..." +ID_LYRIC_REPLACE = "替换(&R)..." +ID_FIND_NEXT = "查找下一个(&N)" +LE_EDIT_CH_CONV = "繁简转换(&C)" +ID_LRYIC_MERGE_SAME_TIME_TAG = "合并时间标签相同的歌词(&M)" +ID_LYRIC_SWAP_TEXT_AND_TRANSLATION = "交换歌词原文和翻译(&S)" +LE_EDIT_TAG_DISLOC = "时间标签错位(&L)" + +[menu.LE_EDIT_CH_CONV] +ID_LE_TRANSLATE_TO_SIMPLIFIED_CHINESE = "转换为简体中文(&S)" +ID_LE_TRANSLATE_TO_TRANDITIONAL_CHINESE = "转换为繁体中文(&T)" + +[menu.LE_EDIT_TAG_DISLOC] +ID_LYRIC_TIME_TAG_FORWARD = "时间标签提前一句(&F)" +ID_LYRIC_TIME_TAG_DELAY = "时间标签延后一句(&D)" + +[menu.LE_PLAY_CTRL] +ID_PLAY_PAUSE = "播放/暂停(&P)" +ID_REW = "快退(&R)" +ID_FF = "快进(&F)" +ID_SEEK_TO_CUR_LINE = "定位到当前行(&G)" + +[menu.FC_LIST] +ID_ADD_FILE = "添加文件(&A)..." +ID_CLEAR_LIST = "清空列表(&C)" +ID_EDIT_TAG_INFO = "编辑标签信息(&E)..." +ID_DELETE_SELECT = "删除(&D)" +ID_MOVE_UP = "上移(&U)" +ID_MOVE_DOWN = "下移(&W)" + +[menu.LD_LIST] +ID_LD_LYRIC_DOWNLOAD = "下载(&D)" +ID_LD_PREVIEW = "预览(&P)" +ID_LD_LYRIC_SAVEAS = "另存为(&A)..." +ID_LD_COPY_TITLE = "复制歌曲标题(&T)" +ID_LD_COPY_ARTIST = "复制艺术家(&S)" +ID_LD_COPY_ALBUM = "复制唱片集(&B)" +ID_LD_COPY_ID = "复制歌曲 &ID" +ID_LD_RELATE = "关联此项(&R)" +ID_LD_VIEW_ONLINE = "在线查看(&L)" + +[menu.OPT_DLRC_DEFAULT_STYLE] +ID_LYRIC_DEFAULT_STYLE1 = "预设 &1" +ID_LYRIC_DEFAULT_STYLE2 = "预设 &2" +ID_LYRIC_DEFAULT_STYLE3 = "预设 &3" +OPT_DLRC_MOD_DEF_STYLE = "修改预设方案(&M)" + +[menu.OPT_DLRC_MOD_DEF_STYLE] +ID_LYRIC_DEFAULT_STYLE1_MODIFY = "保存为预设 &1" +ID_LYRIC_DEFAULT_STYLE2_MODIFY = "保存为预设 &2" +ID_LYRIC_DEFAULT_STYLE3_MODIFY = "保存为预设 &3" +ID_RESTORE_DEFAULT_STYLE = "恢复默认(&R)" + +[menu.PROPERTY_ADV] +ID_COPY_TEXT = "复制文本(&C)" +ID_COPY_ALL_TEXT = "复制全部(&A)" + +[menu.PROPERTY_COVER] +ID_COVER_BROWSE = "浏览(&B)..." +ID_COVER_DELETE = "删除(&D)" +ID_COVER_SAVE_AS = "另存为(&S)..." +ID_COMPRESS_SIZE = "压缩尺寸(&C)" diff --git a/MusicPlayer2/res/Acknowledgement.txt b/MusicPlayer2/res/Acknowledgement.txt index 87fce07e4..c585cb0ca 100644 --- a/MusicPlayer2/res/Acknowledgement.txt +++ b/MusicPlayer2/res/Acknowledgement.txt @@ -1,4 +1,3 @@ -感谢以下GitHub用户为本项目做出的贡献! @lrisora @lifegpc @VictoriousRaptor diff --git a/MusicPlayer2/res/Acknowledgement_en.txt b/MusicPlayer2/res/Acknowledgement_en.txt deleted file mode 100644 index 9442ff563..000000000 --- a/MusicPlayer2/res/Acknowledgement_en.txt +++ /dev/null @@ -1,5 +0,0 @@ -Thanks to the following GitHub users for their contributions to this project! -@lrisora -@lifegpc -@VictoriousRaptor -@hu3rror \ No newline at end of file diff --git a/MusicPlayer2/res/up_d.ico b/MusicPlayer2/res/up_d.ico new file mode 100644 index 000000000..339b17e94 Binary files /dev/null and b/MusicPlayer2/res/up_d.ico differ diff --git a/MusicPlayer2/resource.h b/MusicPlayer2/resource.h index 56ccec2b2..63f049f1b 100644 --- a/MusicPlayer2/resource.h +++ b/MusicPlayer2/resource.h @@ -2,807 +2,229 @@ // Microsoft Visual C++ 生成的包含文件。 // 供 MusicPlayer2.rc 使用 // -#define IDM_ABOUTBOX 0x0010 #define IDD_ABOUTBOX 100 -#define IDS_ABOUTBOX 101 #define IDD_MUSICPLAYER2_DIALOG 102 -#define IDS_STRING102 102 -#define IDS_HELP_INFO 103 -#define IDS_STRING103 103 -#define IDS_LYRIC_FOLDER_NOT_EXIST 104 -#define IDS_BASS_VERSION_WARNING 105 -#define IDS_CHECK_UPDATA_FAILED 106 -#define IDS_CHECK_UPDATA_ERROR 107 -#define IDS_UPDATE_AVLIABLE 108 -#define IDS_UPDATE_AVLIABLE2 109 -#define IDS_ALREADY_UPDATED 110 -#define IDS_RESTART_EXIT 111 -#define IDS_SERIALIZE_ERROR 112 -#define IDS_SEND_EMAIL_TO_ATHOUR 113 -#define IDS_GOTO_GITHUB 114 -#define IDS_DONATE_ATHOUR 115 -#define IDS_LANGUAGE_CODE 116 -#define IDS_DEFAULT_FONT 117 -#define IDS_PLAY 118 -#define IDS_PAUSE 119 -#define IDS_PREVIOUS 120 -#define IDS_NEXT 121 -#define IDS_PLAY2 122 -#define IDS_PAUSE2 123 -#define IDS_CREATE_SHORTCUT_INFO 124 -#define IDS_SHORTCUT_CREATED 125 -#define IDS_SHORTCUT_CREAT_FAILED 126 -#define IDS_MINI_MODE 127 #define IDR_MAINFRAME 128 -#define IDS_MINI_MODE2 128 -#define IDS_SELECT_RENENT_FOLDER 129 -#define IDR_MENU1 130 -#define IDS_PLAY_TIME 130 -#define IDS_CLEAR_SEARCH_RESULT 131 -#define IDS_INPUT_KEY_WORD 132 #define IDD_SET_PATH_DIALOG 133 -#define IDS_SEARCH_HERE 133 -#define IDS_NOW_PLAYING 134 -#define IDS_CONNOT_FIND_FILE 135 -#define IDD_DIALOG1 136 #define IDD_FIND_DIALOG 136 -#define IDS_ALL_SUPPORTED_FORMAT 136 -#define IDS_ALL_FILES 137 #define IDD_OPTIONS_DIALOG 138 -#define IDS_OPEN_FOLDER_INFO 138 -#define IDS_DELETE_FILE_INQUARY 139 #define IDD_LYRIC_SETTING_DIALOG 140 -#define IDS_CONNOT_DELETE_FILE 140 -#define IDS_COPY_CLIPBOARD_FAILED 141 -#define IDD_DIALOG2 142 #define IDD_APPEREANCE_SETTING_DLG 142 -#define IDS_ALL_LRYIC_COPIED 142 -#define IDS_DEBUG_MODE 143 -#define IDR_POPUP_MENU 144 -#define IDS_NO_MIDI_SF2_WARNING 144 #define IDD_PROPERTY_DIALOG 145 -#define IDS_SELECT_COPY_TARGET_FOLDER 145 -#define IDS_SELECT_MOVE_TARGET_FOLDER 146 -#define IDS_DEFAULT_TITLE 147 -#define IDS_DEFAULT_ARTIST 148 -#define IDS_DEFAULT_ALBUM 149 -#define IDS_DEFAULT_YEAR 150 #define IDI_PREVIOUS 151 -#define IDS_DEFAULT_GENRE 151 #define IDI_PLAY_PAUSE 152 -#define IDS_DEFAULT_LYRIC_TEXT 152 -#define IDS_DEFAULT_LYRIC_TEXT_CORTANA 153 #define IDI_NEXT1 154 -#define IDS_VOLUME 154 #define IDI_PLAY 155 -#define IDS_PLAY_ERROR 155 -#define IDI_ICON2 156 #define IDI_PAUSE 156 -#define IDS_SEEK_TO_MINUTE_SECOND 156 -#define IDS_SHOW_HIDE_PLAYLIST 157 -#define IDI_ICON1 158 #define IDI_STOP 158 -#define IDS_BACK_TO_NARMAL 158 #define IDD_MESSAGE_DIALOG 159 -#define IDS_EXIT_PROGRAM 159 -#define IDS_SEEK_TO 160 -#define IDS_TITLE 161 -#define IDS_RHYTHM 162 -#define IDR_TEXT1 163 -#define IDS_SOUND_FONT 163 #define IDD_MINI_DIALOG 164 -#define IDS_ARTIST 164 -#define IDS_ALBUM 165 -#define IDS_FORMAT 166 -#define IDR_MINI_MODE_MENU 167 -#define IDS_MONO 167 -#define IDS_STEREO 168 -#define IDS_CHANNEL 169 -#define IDR_LYRIC_POPUP_MENU 170 -#define IDS_NO_LYRIC_INFO 170 #define IDD_LYRIC_EDIT_DIALOG 171 -#define IDS_LYRIC_SHOW 171 -#define IDS_TRAS 172 #define IDD_DATA_SETTINGS_DIALOG 173 -#define IDS_ALBUM_COVER 173 -#define IDS_INNER_ALBUM_COVER_TIP_INFO 174 -#define IDS_OUT_IMAGE 175 #define IDD_LYRIC_DOWNLOAD_DIALOG 176 -#define IDS_PLAYLIST_INIT_INFO 176 -#define IDS_REPEAT_MODE 177 #define IDD_LYRIC_BATCH_DOWN_DIALOG 178 -#define IDS_PLAY_ODER 178 -#define IDS_LOOP_PLAYLIST 179 -#define IDR_LYRIC_EDIT_MENU 180 -#define IDS_LOOP_TRACK 180 #define IDD_EQUALIZER_DIALOG 181 -#define IDS_PLAY_SHUFFLE 181 -#define IDS_SHOW_LYRIC_TRANSLATION 182 #define IDD_SOUND_EFFECT_DIALOG 183 -#define IDS_MOUSE_WHEEL_ADJUST_VOLUME 183 -#define IDS_SWITCH_UI 184 #define IDD_REVERB_DIALOG 185 -#define IDS_SOUND_EFFECT_SETTING 185 -#define IDS_SETTINGS 186 -#define IDR_LYRIC_DOWNLOAD_MENU 187 -#define IDS_FIND_DLG_INFO 187 -#define IDR_FIND_POPUP_MENU 188 -#define IDS_FIND_RESULT 188 -#define IDR_MAIN_POPUP_MENU 189 -#define IDS_NO_RESULT 189 #define IDB_DEFAULT_COVER 190 -#define IDS_NUMBER 190 #define IDB_CORTANA_BLACK 191 -#define IDS_FILE_NAME 191 -#define IDB_BITMAP2 192 #define IDB_CORTANA_WHITE 192 -#define IDS_FILE_PATH 192 #define IDR_LYRIC_EDIT_TOOLBAR 193 -#define IDS_CHARACTER_TOTAL 193 -#define IDS_MODIFIED 194 #define IDI_ADD_TAG 195 -#define IDS_UNMODIFIED 195 #define IDI_REPLACE_TAG 196 -#define IDS_ENCODE_FORMAT 196 #define IDI_DELETE_TAG 197 -#define IDS_UTF8_NO_BOM 197 #define IDI_SAVE 198 -#define IDS_LYRIC_SAVE_INRUARY 198 #define IDI_FIND 199 -#define IDS_LYRIC_FILE_FILTER 199 -#define IDI_ICON4 200 #define IDI_REPLACE 200 -#define IDS_SAVE_AS_ANSI 200 #define IDI_FF 201 -#define IDS_SAVE_AS_UTF8 201 #define IDI_REW 202 -#define IDS_REPLACE_COMPLETE_INFO 202 -#define IDR_SET_PATH_POPUP_MENU 203 -#define IDS_CONNOT_FIND_STRING 203 -#define IDS_INSERT_TIME_TAG_TIP 204 -#define IDS_REPLACE_TIME_TAG_TIP 205 -#define IDD_DIALOG3 206 #define IDD_COVER_DOWNLOAD_DIALOG 206 -#define IDS_DELETE_TIME_TAG_TIP 206 -#define IDS_SAVE_TIP 207 #define IDD_FORMAT_CONVERT_DIALOG 208 -#define IDS_PLAY_PAUSE_TIP 208 -#define IDS_REWIND_TIP 209 -#define IDD_DIALOG4 210 #define IDD_MP3_ENCODE_CFG_DIALOG 210 -#define IDS_FAST_FOWARD_TIP 210 -#define IDS_FIND_TIP 211 #define IDD_OGG_ENCODE_CFG_DIALOG 212 -#define IDS_REPLACE_TIP 212 -#define IDS_CANNOT_GET_SONG_LENGTH 213 #define IDD_WMA_ENCODE_CFG_DIALOG 214 -#define IDS_NO_MATCHED_LYRIC 214 -#define IDS_MP3_TAG_TYPE 215 -#define IDR_FORMAT_CONVERT_POPUP_MENU 216 -#define IDS_UNKNOW 216 #define IDD_TAG_EDIT_DIALOG 217 -#define IDS_CANNOT_WRITE_TO_FILE 217 -#define IDS_FOLDER 218 -#define IDD_RECORDER_DIALOG 219 -#define IDS_PATH 219 -#define IDS_TRACK_PLAYED 220 #define IDD_PLAY_SETTING_DIALOG 221 -#define IDS_TRACK_TOTAL_NUM 221 #define IDD_SUPPORT_FORMAT_DIALOG 222 -#define IDS_TOTAL_LENGTH 222 -#define IDS_CLEAR_PATH_INQUARY 223 -#define IDI_ICON3 224 #define IDI_DEFAULT_COVER 224 -#define IDS_PATH_CLEAR_COMPLETE 224 #define IDI_SKIN 225 -#define IDS_NONE 225 #define IDI_EQ 226 -#define IDS_CLASSICAL 226 #define IDI_SETTING 227 -#define IDS_POP 227 #define IDI_LOOP_TRACK 228 -#define IDS_JAZZ 228 #define IDI_LOOP_PLAYLIST 229 -#define IDS_ROCK 229 #define IDI_PLAY_ORDER 230 -#define IDS_SOFT 230 #define IDI_PLAY_SHUFFLE 231 -#define IDS_BASS 231 #define IDI_SKIN_D 232 -#define IDS_ELIMINATE_BASS 232 #define IDI_EQ_D 233 -#define IDS_WEAKENING_TREBLE 233 #define IDI_SETTING_D 234 -#define IDS_USER_DEFINE 234 #define IDI_LOOP_TRACK_D 235 -#define IDS_EQUALIZER 235 #define IDI_LOOP_PLAYLIST_D 236 -#define IDS_REVERB 236 #define IDI_PLAY_ORDER_D 237 -#define IDS_PLUGIN_FILE_NAME 237 -#define IDI_ICON6 238 #define IDI_PLAY_SHUFFLE_D 238 -#define IDS_FORMAT_SUPPORTED 238 #define IDI_MINI 239 -#define IDS_FILE_EXTENSION 239 -#define IDI_ICON7 240 #define IDI_MINI_D 240 -#define IDS_STATE 240 #define IDD_HOT_KEY_SETTINGS_DIALOG 241 -#define IDS_LYRIC_BATCH_DOWNLOADING_INFO 241 -#define IDS_DOWNLOADING 242 -#define IDS_SKIPED 243 -#define IDR_MENU2 243 -#define IDR_NOTIFY_MENU 243 -#define IDS_NETWORK_CONNECTION_FAILED 244 #define IDI_SONG_INFO 244 -#define IDS_CANNOT_FIND_THIS_SONG 245 -#define IDI_ICON8 245 #define IDI_SONG_INFO_D 245 -#define IDS_LYRIC_DOWNLOAD_FAILED 246 #define IDI_SELECT_FOLDER 246 -#define IDS_SONG_NO_LYRIC 247 #define IDI_SELECT_FOLDER_D 247 -#define IDS_DOWNLOAD_ENCODE_WARNING 248 #define IDI_PLAYLIST 248 -#define IDS_SUCCESSED 249 #define IDI_PLAYLIST_D 249 -#define IDS_DOWNLOAD_COMPLETE 250 -#define IDS_RETURN_VALUE_OF_WAIT_FOR_SINGLE_OBJECT 251 -#define IDS_SEARCHING 252 -#define IDS_SEARCH_FAILED_INFO 253 -#define IDS_SEARCH_TIME_OUT 254 -#define IDS_SEARCH_NO_SONG 255 -#define IDS_SEARCH_NO_MATCHED 256 -#define IDS_SEARCH_RELATED 257 -#define IDS_SEARCH_BEST_MATCHED 258 -#define IDS_LYRIC_OVERWRITE_INQUARY 259 -#define IDS_DOWNLOAD_COMPLETE_SAVED 260 -#define IDS_CONVERTING_STATE 261 -#define IDS_MP3_LAME_ENCODER 262 -#define IDS_AUTO_RENAME 263 -#define IDS_IGNORE 264 -#define IDS_OVERWRITE 265 -#define IDS_CONVERT_WMA_ERROR 266 -#define IDS_NO_WMP9_OR_LATER 267 -#define IDS_NO_SUPPORTED_ENCODER_WARNING 268 -#define IDS_UNKNOW_ERROR 269 -#define IDS_BASS_ENCODER_LOAD_ERROR 270 -#define IDS_SET_OUTPUT_DIR_INFO 271 -#define IDS_OUTPUT_DIR_NOT_EXIST 272 -#define IDS_SELECT_OUTPUT_FOLDER 273 -#define IDS_ERROR 274 -#define IDS_COMPLEATE 275 -#define IDS_SKIPED1 276 -#define IDS_CURRENT_SELECTED 277 -#define IDS_CURRENT_COLOR 278 -#define IDS_LIGNT_BLUE 279 -#define IDS_GREEN 280 -#define IDS_ORANGE 281 -#define IDS_CYAN_GREEN 282 -#define IDS_PINK 283 -#define IDS_LIGHT_PURPLE 284 -#define IDS_STRETCH 285 -#define IDS_FILL 286 -#define IDS_ADAPT 287 -#define IDS_COVER_FIT_TIP_INFO 288 -#define IDS_USE_OUT_IMAGE_TIP_INFO 289 -#define IDS_DEFAULT_COVER_NAME_TIP_INFO 290 -#define IDS_WHITE_THEME_COLOR_WARNING 291 -#define IDS_FOLLOWING_SYSTEM 292 -#define IDS_CLEAR_DATA_FILE_TIP_INFO 293 -#define IDS_AUTO_DOWNLOAD_LYRIC_TIP_INFO 294 -#define IDS_MIDI_INNER_LYRIC_TIP_INFO 295 -#define IDS_CURRENT_DATA_FILE_SIZE 296 -#define IDS_BYTE 297 -#define IDS_CLEAR_COMPLETE_INFO 298 -#define IDS_SOUND_FONT_FILTER 299 -#define IDS_FUNCTION 300 -#define IDS_SHORTCUT_KEY 301 -#define IDS_PLAY_PAUSE 302 -#define IDS_STOP 303 -#define IDS_FAST_FORWARD 304 -#define IDS_REWIND 305 -#define IDS_VOLUME_UP 306 -#define IDS_VOLUME_DOWN 307 -#define IDS_EXIT 308 -#define IDS_GLOBLE_HOT_KEY_WARNING 309 -#define IDS_LYRIC_FUZZY_MATHC_TIP_INFO 310 -#define IDS_LYRIC_PATH_TIP_INFO 311 -#define IDS_CORTANA_SHOW_LYRIC_TIP_INFO 312 -#define IDS_BLACK 313 -#define IDS_WHITE 314 -#define IDS_SELECT_LYRIC_FOLDER 315 -#define IDS_LYRIC_SETTINGS 316 -#define IDS_APPEARANCE_SETTINGS 317 -#define IDS_GENERAL_SETTINGS 318 -#define IDS_PLAY_SETTINGS 319 -#define IDS_GLOBLE_HOTKEY 320 -#define IDS_DEVICE_TYPE_DIGITAL 321 -#define IDS_DEVICE_TYPE_DISPLAYPORT 322 -#define IDS_DEVICE_TYPE_HANDSET 323 -#define IDS_DEVICE_TYPE_HDMI 324 -#define IDS_DEVICE_TYPE_HEADPHONES 325 -#define IDS_DEVICE_TYPE_HEADSET 326 -#define IDS_DEVICE_TYPE_LINE 327 -#define IDS_DEVICE_TYPE_MICROPHONE 328 -#define IDS_DEVICE_TYPE_NETWORK 329 -#define IDS_DEVICE_TYPE_SPDIF 330 -#define IDS_DEVICE_TYPE_SPEAKERS 331 -#define IDS_ITEM 332 -#define IDS_VLAUE 333 -#define IDS_NAME 334 -#define IDS_DRIVER 335 -#define IDS_DEVICE_TYPE 336 -#define IDS_ALBUM_COVER_DOWNLOAD_FAILED_WARNING 337 -#define IDS_AUDIO_FILE 338 -#define IDS_MINI_SEQUENCE 339 -#define IDS_DELETE 340 -#define IDS_COPY 341 -#define IDS_MOVE 342 -#define IDS_INVALID_DIR_WARNING 343 -#define IDS_DEFAULT_OUTPUT_DEVICE 344 -#define IDS_BASIC_AUDIO_FORMAT 345 -#define IDS_SOUND_FONT_LOAD_FAILED 346 -#define IDS_LOAD_FAILED 347 -#define IDS_BASS_ERROR_LOG_INFO 348 -#define IDS_LANGUAGE_CHANGE_INFO 349 -#define IDS_STOPED 350 -#define IDS_PAUSED 351 -#define IDS_RECENT_PATH_SERIALIZE_ERROR_LOG 352 -#define IDS_NO_RESULT_TO_SHOW 353 -#define IDS_BITRATE 354 -#define IDS_TRACK 355 -#define IDS_STRING356 356 -#define IDS_LENGTH 356 -#define IDS_CLOSE_BTN 357 -#define IDS_TEST_STR 357 -#define IDS_CLOSE 358 -#define IDS_MULTI_MEDIA_KEY_TIP 359 -#define IDS_SONG_INFO 360 -#define IDS_SELECT_FOLDER 361 -#define IDS_FIND_SONGS 362 #define IDI_FIND_SONGS 362 #define IDI_FIND_SONGS_D 363 -#define IDS_EXIT_FULL_SCREEN 363 #define IDI_FULL_SCREEN 364 -#define IDS_FULL_SCREEN 364 #define IDI_FULL_SCREEN_D 365 -#define IDS_WELCOM_TO_USE 365 #define IDI_FULL_SCREEN1 366 -#define IDS_ERROR_MESSAGE 366 #define IDI_FULL_SCREEN1_D 367 -#define IDS_CRASH_INFO 367 -#define IDS_ERROR1 368 #define IDD_LISTEN_TIME_STATISTICS_DLG 368 -#define IDS_HELP 369 -#define IDS_FILE_NOT_FOUND 370 #define IDD_DONATE_DIALOG 370 -#define IDS_PLAY_SHORTCUT_CREATED 371 -#define IDS_CREATE_PLAY_SHORTCUT_INFO 372 #define IDB_DONATE 372 -#define IDS_LISTEN_TIME 373 -#define IDS_LISTEN_TIME_FILE_DLG_FILTER 374 -#define IDS_LISTEN_TIMES 375 #define IDI_MENU 375 -#define IDS_LISTEN_TIME_STATISTICS 376 #define IDI_MENU_D 376 -#define IDS_HIDE_MENU_BAR_TIP 377 -#define IDR_PLAYLIST_BTN_MENU 377 -#define IDS_LYRIC_PREVIEW 378 #define IDD_MEDIA_LIB_DIALOG 378 -#define IDS_CRASH_ERROR_LOG_INFO 379 -#define IDS_MAIN_MENU 380 -#define IDS_LYRIC_SAVE_FAILED 381 -#define IDS_IDS_FILE_WRITE_FAILED 382 -#define IDS_PLAYLIST 382 #define IDD_SELECT_PLAYLIST_DIALOG 382 -#define IDS_PLAYLIST_FILTER 383 #define IDD_INPUT_DLG 384 -#define IDS_CLEAR_PLAYLIST_WARNING 384 -#define IDS_DEFAULT 385 -#define IDR_SELETE_PLAYLIST_POPUP_MENU 385 -#define IDS_NEW_PLAYLIST 386 #define IDI_FILE_ICON 386 -#define IDS_INPUT_PLAYLIST_NAME 387 #define IDI_MEDIA_LIB 387 -#define IDS_RENAME_PLAYLIST 388 #define IDI_MEDIA_LIB_D 388 -#define IDS_CURRENT_FOLDER 389 #define IDD_FILE_RELATE_DIALOG 389 -#define IDS_PLAYLIST_EXIST_WARNING 390 -#define IDS_REMOVE_SAME_SONGS_INFO 391 #define IDD_TEST_DIALOG 391 -#define IDC_CURSOR1 391 #define IDC_DRAG_CURSOR 391 -#define IDS_MEDIA_LIB 392 #define IDI_FAVOURITE 392 -#define IDS_OPEN_MEDIA_LIB 393 #define IDI_FAVOURITE_D 393 -#define IDS_ADD_TO_PLAYLIST_FAILED_WARNING 394 #define IDI_HEART 394 -#define IDS_DESCRIPTION 395 -#define IDR_DESKTOP_LYRIC_POPUP_MENU 395 -#define IDS_INCLUDE_SUB_DIR 396 #define IDI_CLOSE_D 396 -#define IDS_MY_FAVURITE 397 #define IDI_LOCK_D 397 -#define IDS_ADD_TO_MA_FAVOURITE 398 #define IDI_DOUBLE_LINE_D 398 -#define IDS_REMANE_FAILED 399 -#define IDR_LRYIC_DEFAULT_STYLE_MENU 399 -#define IDS_REMOVE_MY_FAVOURITE_WARNING 400 -#define IDR_PLAYLIST_TOOLBAR_MENU 400 -#define IDS_FILE_NAME_INVALID_WARNING 401 #define IDI_EDIT_D 401 -#define IDS_OPEN_URL 402 #define IDI_ADD_D 402 -#define IDS_ADD_URL 403 -#define IDB_BITMAP1 403 -#define IDS_INPUT_URL_TIP 404 -#define IDS_MCI_INIT_FAILED 405 -#define IDS_MCI_NO_THIS_FUNCTION_WARNING 406 -#define IDS_MCI_KERNAL_TIP 407 -#define IDS_CLEAR_LISTEN_TIME_WARNING 408 -#define IDS_PLAYLIST_NAME_EMPTY_WARNING 409 -#define IDS_SEARCH_BOX_OPAQUE_TIP 410 -#define IDS_ALBUM_COVER_COMPRESSED 410 -#define IDS_TOW_COLOR_GRADIENT 411 -#define IDS_THREE_COLOR_GRADIENT 412 #define IDD_MEDIA_CLASSIFY_DIALOG 412 -#define IDS_NO_GRADIENT 413 -#define IDS_LRC 414 -#define IDS_SHOW_DESKTOP_LYRIC 415 -#define IDR_MEDIA_LIB_POPUP_MENU 415 -#define IDS_LOCK_DESKTOP_LYRIC 416 #define IDI_ALBUM_D 416 -#define IDS_CLOSE_DESKTOP_LYRIC 417 #define IDI_ARTIST_D 417 -#define IDS_LYRIC_DOUBLE_LINE 418 #define IDI_YEAR_D 418 -#define IDS_LYRIC_BACKGROUND_PENETRATE 419 #define IDD_FOLDER_EXPLORE_DIALOG 419 -#define IDS_ULOCK_DESKTOP_LYRIC 420 -#define IDS_ADD 421 -#define IDS_SORT 422 #define IDI_FOLDER_EXPLORE_D 422 -#define IDS_LIST 423 #define IDI_EXPLORE_FOLDER 423 -#define IDS_EDIT 424 #define IDD_MEDIA_LIB_SETTING_DIALOG 424 -#define IDS_DEFAULT_STYLE 425 -#define IDS_MODIFY_DEFAULT_STYLE_WARNING 426 #define IDD_ADD_TO_PLAYLIST_DIALOG 426 -#define IDS_RESTORE_DEFAULT_STYTLE_WARNING 427 -#define IDS_URL_INVALID_WARNING 428 #define IDD_ALL_MEDIA_DIALOG 428 -#define IDS_PROGRESS_INFO 429 -#define IDS_BASS_MIX_LOAD_ERROR 430 -#define IDS_BROWSE 431 #define IDI_GENRE_D 431 -#define IDS_OTHER 432 #define IDI_LYRIC_DELAY_D 432 -#define IDS_SEARCH_ARTIST 433 #define IDI_LYRIC_FORWARD_D 433 -#define IDS_SEARCH_ALBUM 434 #define IDI_RECENT_SONG_D 434 -#define IDS_TEMP_PLAYLIST 435 -#define IDI_ICON5 435 #define IDI_FILE_PLAYLIST 435 -#define IDS_GENRE 436 #define IDB_DONATE_WECHAT 436 -#define IDS_SEARCH_GENRE 437 #define IDI_STOP_NEW 437 -#define IDS_YEAR 438 #define IDI_STOP_NEW_D 438 -#define IDS_SEARCH_YEAR 439 #define IDI_PREVIOUS_NEW 439 -#define IDS_TRACK_NUM 440 #define IDI_PREVIOUS_NEW_D 440 -#define IDS_FOLDER_EXPLORE 441 #define IDI_PLAY_NEW 441 -#define IDS_SEARCH_FORDER 442 #define IDI_PLAY_NEW_D 442 -#define IDS_BTN_SETTINGS 443 #define IDI_PAUSE_NEW 443 -#define IDS_MORE_PLAYLIST 444 #define IDI_PAUSE_NEW_D 444 -#define IDS_SEARCH_RESULT 445 #define IDI_NEXT_NEW 445 -#define IDS_UPDATING_MEDIA_LIB_INFO 446 #define IDI_NEXT_NEW_D 446 -#define IDS_ERROR_CODE 447 -#define IDS_UPDATE_MEDIA_LIB_TIP 448 #define IDR_LICENSE 448 -#define IDS_FILE_NOT_EXIST 449 #define IDI_SAVE_NEW_D 449 -#define IDS_FILE_CONNOT_BE_OPEND 450 #define IDI_MUSIC_D 450 -#define IDS_ALIGN_LEFT 451 #define IDI_FILE_RELATE_D 451 -#define IDS_ALIGN_RIGHT 452 #define IDI_ONLINE_D 452 -#define IDS_CENTER 453 #define IDI_PLAY_PAUSE_D 453 -#define IDS_ALL_TRACKS 454 #define IDI_CONVERT_D 454 -#define IDS_DO_NOT_SAVE 455 #define IDI_DOWNLOAD_D 455 -#define IDS_AUTO_SAVE 456 #define IDI_DOWNLOAD1_D 456 -#define IDS_INQUIRY 457 #define IDI_HELP_D 457 -#define IDS_LYRIC_FORWARD 458 #define IDI_FF_NEW_D 458 -#define IDS_LYRIC_DELAY 459 #define IDI_REW_NEW_D 459 -#define IDS_RECENT_PLAYED 460 #define IDI_SAVE_AS_D 460 -#define IDS_LAST_PLAYED_TIME 461 #define IDI_PLAYLIST_FLOAT_D 461 -#define IDS_CLEAR_RECENT_PLAYLIST_INFO 462 #define IDI_PLAYLIST_DOCK_D 462 -#define IDS_AB_REPEAT_A_SELECTED 463 #define IDI_STATISTICS_D 463 -#define IDS_AB_REPEAT_ON_INFO 464 #define IDI_PIN_D 464 -#define IDS_AB_REPEAT 465 #define IDI_EXIT_D 465 -#define IDS_INNER_LYRIC 466 #define IDI_ALBUM_COVER_D 466 -#define IDS_SHOW_ONLINE_HELP_INFO 467 -#define IDI_ICON9 467 #define IDI_DARK_MODE_D 467 -#define IDS_PLAYLIST_FILE_FILTER 468 -#define IDS_SAVE_PLAYLIST_FILTER 469 -#define IDB_PNG1 469 #define IDB_DEFAULT_ALBUM_COVER 469 -#define IDS_CREATE_MINI_MODE_SHORTCUT_INFO 470 #define IDD_LYRIC_RELATE_DIALOG 470 -#define IDS_CREATE_DESKTOP_SHORTCUT_INFO 471 -#define IDS_DELETE_SINGLE_FILE_INQUIRY 472 -#define IDI_ICON10 472 #define IDI_LYRIC_D 472 -#define IDS_ALL 473 #define IDI_APP_DARK 473 -#define IDS_LAST_WEEK 474 -#define IDI_ICON12 474 #define IDI_APP_LIGHT 474 -#define IDS_LAST_MONTH 475 #define IDB_NOTIFY_ICON_PREVIEW 475 -#define IDS_LAST_HALF_YEAR 476 #define IDB_NOTIFY_ICON_PREVIEW_LIGHT 476 -#define IDS_LAST_YEAR 477 #define IDI_DEFAULT_COVER_NOT_PLAYED 477 -#define IDS_TODAY 478 -#define IDB_PNG2 478 #define IDB_DEFAULT_ALBUM_COVER_NOT_PLAYED 478 -#define IDS_LAST_THREE_DAYS 479 #define IDR_ACCELERATOR1 479 -#define IDS_LICENSE_EXPLAIN 480 -#define IDD_DIALOG5 480 #define IDD_CLEAN_UP_RANGE_DIALOG 480 -#define IDS_LICENSE 481 -#define IDS_FILE_EXIST_IN_PLAYLIST_INFO 482 -#define IDS_IS_RELATED 483 -#define IDS_YES 484 #define IDI_PLAY_RANDOM 484 -#define IDS_ALBUM_COVER_INFO 485 -#define IDI_ICON13 485 #define IDI_PLAY_RANDOM_D 485 -#define IDS_INNER_ALBUM_COVER 486 #define IDD_PROPERTY_PARENT_DIALOG 486 -#define IDS_WIDTH 487 -#define IDS_HEIGHT 488 #define IDD_PROPERTY_ALBUM_COVER_DIALOG 488 -#define IDS_BPP 489 -#define IDS_FILE_SIZE 490 -#define IDR_MENU3 490 -#define IDR_PROPERTY_COVER_MENU 490 -#define IDS_DEFAULT_ICON 491 -#define IDI_ICON11 491 #define IDI_OK_D 491 -#define IDS_LIGHT_ICON 492 -#define IDR_CONTROL_MENU 492 -#define IDS_DARK_ICON 493 -#define IDD_TAG_FROM_FILE_NAME_DIALOG 493 -#define IDS_NO 494 -#define IDS_CONVERT_ERROR_FILE_CONNOT_OPEN 495 -#define IDI_ICON14 495 +#define IDD_TAG_MODE_SELECT_DIALOG 493 #define IDI_RENAME_D 495 -#define IDS_CONVERT_ERROR_ENCODE_CHANNEL_FAILED 496 -#define IDS_CONVERT_ERROR_ENCODE_PARA_ERROR 497 -#define IDS_CONVERT_ERROR_MIDI_NO_SF2 498 #define IDI_PLAY_TRACK 498 -#define IDS_CONTAIN_SUB_FOLDER 499 #define IDI_PLAY_TRACK_D 499 -#define IDS_TYPE 500 -#define IDI_ICON15 500 #define IDI_APP_DEBUG 500 -#define IDS_FILE_TYPE 501 #define IDD_PROPERTY_ADVANCED_DIALOG 501 -#define IDS_CLEAN_UP_MEDIA_WARNING 502 -#define IDS_FILES_THAT_NOT_EXIST 503 -#define IDR_PROPERTY_MENU 503 -#define IDS_FILES_NOT_IN_MEDIA_LIB_DIR 504 -#define IDI_ICON16 504 #define IDI_TAG 504 -#define IDS_FILES_THAT_ERROR 505 #define IDD_SELECT_ITEM_DIALOG 505 -#define IDS_IMAGE_FILE_FILTER 506 -#define IDS_SEARCH_FILE_TYPE 507 -#define IDI_ICON17 507 #define IDI_LOCATE_D 507 -#define IDS_SEARCH_BITRATE 508 -#define IDI_ICON18 508 #define IDI_STAR 508 -#define IDS_PLAY_RANDOM 509 -#define IDS_FILE_PROPERTY 510 -#define IDS_PROPERTY_TITLE_INFO 511 -#define IDS_MULTI_VALUE 512 -#define IDS_TAG_BATCH_EDIT_INFO 513 -#define IDS_GET_TAG_ONLINE_TITLE 514 -#define IDS_GET_THIS 515 -#define IDS_NO_LYRICS_FOUND_INFO 516 -#define IDS_CLEAR_HISTORY 517 -#define IDS_CLEAR_HISTORY_INFO 518 -#define IDS_RENAME 519 -#define IDS_RENAME_INFO 520 -#define IDS_PLAY_TRACK 521 -#define IDS_ADVANCED_PROPERTY 522 -#define IDS_CONNOT_FIND_ARTIST_WARNING 523 -#define IDS_CONNOT_FIND_ALBUM_WARNING 524 -#define IDS_SCI_NOT_LOADED_ERROR_INFO 525 -#define IDS_SELECT_ARTIST 526 -#define IDS_LOCATE_TO_CURRENT 527 -#define IDS_UI 528 -#define IDS_RATING 529 -#define IDS_UNRATED 530 -#define IDS_RANDOM_TRACK 531 -#define IDS_NEXT_TRACK 532 -#define IDS_MEDIA_LIB_UPDATING_INFO 533 -#define IDS_MINIMIZE 534 #define IDI_CLOSE 534 -#define IDS_MAXIMIZE 535 #define IDI_MINIMIZE 535 -#define IDS_RESTORE 536 #define IDI_MINIMIZE_D 536 #define IDI_MAXIMIZE 537 -#define IDS_SET_FILENAME_FORM 537 #define IDI_MAXIMIZE_D 538 -#define IDS_SET_MULTI_OUT_ALBUM_COVER_FILE_NAME 538 #define IDI_RESTORE 539 -#define IDS_DARK 539 -#define IDI_ICON19 540 #define IDI_RESTORE_D 540 -#define IDS_LIGHT 540 -#define IDR_TEXT2 540 #define IDR_COMPILE_TIME 540 -#define IDS_SHOW_HIDE_PLAYER 541 #define IDI_VOLUME3_D 541 #define IDI_VOLUME2_D 542 -#define IDS_MUTE 542 #define IDI_VOLUME1_D 543 -#define IDS_UNDEFINED 543 #define IDI_VOLUME3 544 -#define IDS_DELETE_INNER_ALBUM_COVER_INQUERY 544 #define IDI_VOLUME2 545 -#define IDS_TOTAL_TRACKS 545 -#define IDI_ICON21 546 #define IDI_VOLUME1 546 -#define IDS_TRACKS_PLAYED 546 #define IDI_VOLUME0 547 -#define IDS_MEDIALIB_STATISTICS 547 -#define IDI_ICON22 548 #define IDI_VOLUME0_D 548 -#define IDS_CFG_DIR_CHANGED_INFO 548 -#define IDS_ADD_TO_PLAYLIST 549 -#define IDS_LYRICS_HIDE_BLANK_LINES_TIP 550 -#define IDI_ICON20 551 #define IDI_EXPAND_D 551 -#define IDS_BOLD 551 -#define IDI_ICON23 552 #define IDI_ADD 552 -#define IDS_ITALIC 552 -#define IDS_SDL_DEFAULT_DEVICE 553 -#define IDS_FFMPEG_CORE 554 -#define IDS_FFMPEG_INIT_FAILED 555 #define IDI_SORT 555 -#define IDS_FFMPEG_NO_THIS_FUNCTION 556 #define IDI_SORT_D 556 -#define IDS_SUPPORTTED_FORMAT_INFO 557 #define IDI_DISPLAY_MODE 557 -#define IDS_SUPPORTTED_FORMAT_INFO_MCI 558 #define IDI_DISPLAY_MODE_D 558 -#define IDS_SUPPORTTED_FORMAT_INFO_FFMPEG 559 #define IDI_LINK 559 -#define IDS_OTHER_FORMATS 560 #define IDI_LINK_D 560 -#define IDS_IDS_ENCODER_INIT_ERROR 561 #define IDI_UNLINK 561 -#define IDS_SEEK_TO_LINE_TIP 562 -#define IDI_ICON25 562 #define IDI_UNLINK_D 562 #define IDI_INTERNAL_LYRIC_D 563 -#define IDS_SWITCH_DISPLAY 563 #define IDI_SPEED_UP_D 564 -#define IDS_FILE 564 #define IDI_SLOW_DOWN_D 565 -#define IDS_PLAY_CONTROL 565 -#define IDI_ICON24 566 #define IDI_SHORTCUT_D 566 -#define IDS_LYRICS 566 #define IDI_SWITCH 567 -#define IDS_VIEW 567 -#define IDI_ICON26 568 #define IDI_SWITCH_D 568 -#define IDS_TOOLS 568 #define IDI_LYRIC 569 -#define IDS_DOWNLOAD_FFMPEG_CORE_INFO 569 -#define IDI_IDI_PLAYLIST_DOCK 570 #define IDI_PLAYLIST_DOCK 570 -#define IDS_TRAFFICMONITOR_DESCRIPTION 570 #define IDI_HELP 571 -#define IDS_SIMPLENOTEPAD_DESCRIPTION 571 -#define IDS_NO_TRACKS_TIP_INFO 572 -#define IDI_ICON27 573 #define IDI_LIGHT_MODE 573 -#define IDS_SWITHC_TO_DARK_MODE 573 #define IDD_FLAC_ENCODE_CFG_DIALOG 573 -#define IDS_SWITCH_TO_LIGHT_MODE 574 -#define IDS_SHORCUT_LEFT 575 #define IDI_PLAY_AS_NEXT 575 -#define IDS_SHOTCUT_RIGHT 576 #define IDI_PLAY_IN_PLAYLIST 576 -#define IDS_SHOTCUT_UP 577 #define IDI_COPY 577 -#define IDS_SHOTCUT_DOWN 578 #define IDI_PLAY_IN_FOLDER 578 -#define IDS_SPACE 579 #define IDI_BITRATE 579 -#define IDS_ALBUM_COVER_PATH_EDIT_TIP_INFO 580 -#define IDI_ICON29 580 #define IDI_REVERB 580 -#define IDS_LOGIN_REQUIRED 581 -#define IDI_ICON28 581 #define IDI_HOT_KEY 581 -#define IDS_LOGGED 582 #define IDI_MINI_RESTORE 582 -#define IDS_LASTFM_LOGIN 583 -#define IDS_LOGIN_FAILED 584 -#define IDI_ICON30 584 -#define IDI_IDI_MINI_RESTORE_D 584 -#define IDS_LASTFM_CACHE_STATUS 585 -#define IDI_ICON31 585 +#define IDI_MINI_RESTORE_D 584 #define IDI_LOCATE 585 -#define IDS_SHOW_HIDE_DESKTOP_LYRIC 586 -#define IDI_ICON32 586 #define IDI_EXPAND 586 -#define IDS_APP_RUNING_INFO 587 #define IDI_FIX_D 587 -#define IDS_SHOW_SONG_INFO_WHEN_LYRICS_NOT_EXIST_TIP 588 #define IDR_ACKNOWLEDGEMENT 588 -#define IDS_EXCLUSIVE_MODE 589 #define IDR_UI1 589 -#define IDS_PLAYLIST_FIX_PATH_ERROR_INFO 590 #define IDR_UI2 590 -#define IDS_PLAYLIST_FIX_PATH_ERROR_COMPLETE 591 -#define IDS_LOCATE 592 -#define IDS_PLAYLIST_MENU 593 -#define IDS_RECENT_FOLDER_OR_PLAYLIST 594 -#define IDS_PLAYLIST_EMPTY_INFO 595 -#define IDS_CONTINUE_WHEN_SWITCH_PLAYLIST_TIP 596 -#define IDS_ACKNOWLEDGEMENT 597 -#define IDS_SIMPLE_UI 598 -#define IDS_GROOVE_MUSIC_STYLE 599 -#define IDS_DEFAULT_UI 600 -#define IDS_ALIGN_AUTO 601 -#define IDS_SET_MULTI_ARTIST_SPLIT_EXT 602 -#define IDS_ARTIST_SPLIT_EXT_TIP_INFO 603 -#define IDS_FILES_TOO_SHORT 604 -#define IDS_FILES_NON_MAIN_IN_OSU 605 -#define IDS_WAIT_AND_RETRY 606 -#define IDC_STATIC_PATH 1001 +#define IDR_STRING_TABLE 591 +#define IDI_UP_D 592 +#define IDR_MINI_UI0 593 #define IDC_LIST1 1002 #define IDC_PATH_LIST 1002 #define IDC_LYRIC_DOWN_LIST1 1002 @@ -811,20 +233,11 @@ #define IDC_OUTPUT_DEVICE_INFO_LIST 1002 #define IDC_HOT_KEY_LIST 1002 #define IDC_STATIC_VERSION 1003 -#define IDC_LIST3 1003 -#define IDC_DELETE_PATH_BUTTON 1004 #define IDC_TRACK_EDIT 1009 -#define IDC_PLAY_TRACK_BUTTON 1010 -#define IDC_LIST_PREVIEW 1011 -#define IDC_LIST_NEXT 1012 -#define IDC_BUTTON1 1012 #define IDC_FIND_BUTTON 1012 #define IDC_PREVIOUS_BUTTON 1012 -#define IDC_INSERT_TAG_BUTTON 1012 #define IDC_CLEAN_DATA_FILE_BUTTON 1012 #define IDC_SEARCH_BUTTON2 1012 -#define IDC_SHOW_LIST_BUTTON 1012 -#define IDC_CLEAR_SEARCH_BUTTON 1012 #define IDC_ENCODER_CONFIG_BUTTON 1012 #define IDC_APPLY_BUTTON 1012 #define IDC_SET_BUTTON 1012 @@ -832,21 +245,17 @@ #define IDC_EXPORT_BUTTON 1012 #define IDC_PLAY_SELECTED 1012 #define IDC_NEW_PLAYLIST 1012 -#define IDC_SETTINGS_BUTTON 1012 #define IDC_DONOT_RELATE_BUTTON 1012 #define IDC_DEFAULT_BUTTON 1012 #define IDC_SAVE_ALBUM_COVER_BUTTON 1012 #define IDC_GET_TAG_ONLINE_BUTTON 1012 #define IDC_TITLE_BUTTON 1012 #define IDC_OPEN_CONFIG_PATH_BUTTON 1012 -#define IDC_VOLUME_UP 1013 #define IDC_NEXT_BUTTON 1013 #define IDC_SET_FONT2 1013 -#define IDC_PLAY_SELECTED2 1013 #define IDC_CLEAR_RECENT_PLAYED_LIST_BTN 1013 #define IDC_SHOW_OUT_ALBUM_COVER_CHK 1013 #define IDC_ARTIST_BUTTON 1013 -#define IDC_VOLUME_DOWN 1014 #define IDC_ALBUM_BUTTON 1014 #define IDC_SET_FONT_BUTTON 1014 #define IDC_PLAYLIST_LIST 1015 @@ -862,7 +271,6 @@ #define IDC_ORIGINAL_BUTTON 1019 #define IDC_PATH_STATIC 1020 #define IDC_OPTIONS_TAB 1024 -#define IDC_CHECK1 1025 #define IDC_STOP_WHEN_ERROR 1025 #define IDC_FOLLOW_SYSTEM_COLOR_CHECK 1025 #define IDC_FIND_FILE_CHECK 1025 @@ -870,7 +278,6 @@ #define IDC_DOWNLOAD_TRANSLATE_CHECK1 1025 #define IDC_ENABLE_EQU_CHECK 1025 #define IDC_ENABLE_REVERB_CHECK 1025 -#define IDC_ID3V2_FIRST_CHECK 1025 #define IDC_JOINT_STEREO_CHECK 1025 #define IDC_COPY_TAG_CHECK 1025 #define IDC_HOT_KEY_ENABLE_CHECK 1025 @@ -879,7 +286,6 @@ #define IDC_CLASSIFY_OTHER_CHECK 1025 #define IDC_FUZZY_MATCH_CHECK 1025 #define IDC_SPECIFY_PARA_CHECK 1025 -#define IDC_CHECK2 1026 #define IDC_KARAOKE_DISP 1026 #define IDC_FIND_TITLE_CHECK 1026 #define IDC_DOWNLOAD_TRASNLATE_CHECK2 1026 @@ -887,20 +293,14 @@ #define IDC_COVER_AUTO_DOWNLOAD_CHECK 1026 #define IDC_COPY_ALBUM_COVER_CHECK 1026 #define IDC_AUTO_PLAY_WHEN_START_CHECK 1026 -#define IDC_ENABLE_GLABOL_MULTIMEDIA_KEY_CHECK 1026 #define IDC_ENABLE_GLOBAL_MULTIMEDIA_KEY_CHECK 1026 -#define IDC_SHOW_TREE_TOOL_TIPS_CHECK 1026 #define IDC_UPDATE_MEDIA_LIB_CHK 1026 -#define IDC_FONT_NAME_EDIT 1027 #define IDC_FIND_ARTIST_CHECK 1027 -#define IDC_KARAOKE_DISP2 1027 #define IDC_LYRIC_FUZZY_MATCH 1027 #define IDC_SHOW_SPECTRUM_CHECK 1027 #define IDC_LYRIC_AUTO_DOWNLOAD_CHECK 1027 #define IDC_SHOW_PLAY_STATE_ICON_CHECK 1027 #define IDC_OPEN_TARGET_DIR_CHECK 1027 -#define IDC_FONT_SIZE_EDIT 1028 -#define IDC_CHECK5 1028 #define IDC_FIND_ALBUM_CHECK 1028 #define IDC_SHOW_LYRIC_IN_CORTANA 1028 #define IDC_DOWNLOAD_WHEN_TAG_FULL_CHECK 1028 @@ -909,17 +309,13 @@ #define IDC_CONTINUE_WHEN_SWITCH_PLAYLIST_CHECK 1028 #define IDC_LYRIC_PATH_EDIT 1029 #define IDC_BITRATE_CHECK 1029 -#define IDC_SHOW_NEXT_CHECK2 1029 #define IDC_SHOW_FPS_CHECK 1029 -#define IDC_EXPLORE_LYRIC_BUTTON 1030 #define IDC_ALL_CHECK 1030 #define IDC_FONT_SIZE_EDIT2 1030 #define IDC_SLIDER1 1031 #define IDC_TRANSPARENT_SLIDER 1031 #define IDC_RECENT_CHECK 1031 #define IDC_SLIDER2 1032 -#define IDC_RECENT_CHECK2 1032 -#define IDC_BITRATE_CHECK2 1032 #define IDC_RATING_CHECK 1032 #define IDC_TRANSPARENT_STATIC 1033 #define IDC_SLIDER3 1033 @@ -927,27 +323,20 @@ #define IDC_FILE_NAME_EDIT 1034 #define IDC_SLIDER4 1034 #define IDC_FILE_PATH_EDIT 1035 -#define IDC_CHECK3 1035 #define IDC_SHOW_TASKBAR_PROGRESS 1035 #define IDC_SLIDER5 1035 #define IDC_ALBUM_COVER_BACKGROUND_CHECK 1035 #define IDC_CHECK_UPDATE_CHECK 1035 #define IDC_ADD_NUMBER_CHECK 1035 -#define IDC_CORTANA_OPAQUE 1035 -#define IDC_SEARCH_BOX_OPAQUE_CHECK 1035 #define IDC_DISABLE_DRAGE_SORT_CHECK 1035 #define IDC_SHOW_LYRIC_TRANSLATE_CHECK 1035 #define IDC_FILE_TYPE_EDIT 1036 #define IDC_SLIDER6 1036 -#define IDC_EDIT4 1037 #define IDC_SONG_LENGTH_EDIT 1037 #define IDC_SYSLINK1 1037 #define IDC_SLIDER7 1037 -#define IDC_PROGRESS_STATIC 1038 #define IDC_FILE_SIZE_EDIT 1038 #define IDC_SLIDER8 1038 -#define IDC_TIME_STATIC 1039 -#define IDC_FILE_SIZE_EDIT2 1039 #define IDC_BIT_RATE_EDIT 1039 #define IDC_SLIDER9 1039 #define IDC_SET_PROGRESS_COLOR_BUTTON 1040 @@ -956,53 +345,26 @@ #define IDC_COLOR_STATIC 1041 #define IDC_ARTIST_EDIT 1041 #define IDC_COLOR_STATIC2 1042 -#define IDC_COLOR_STATIC1 1042 #define IDC_ITEM_STATIC 1042 #define IDC_SAMPLE_FREQ 1042 #define IDC_COLOR_STATIC3 1043 #define IDC_ALBUM_EDIT 1043 #define IDC_COLOR_STATIC4 1044 #define IDC_HELP_EDIT 1044 -#define IDC_BIT_RATE_EDIT2 1044 #define IDC_LYRIC_FILE_EDIT 1044 #define IDC_COLOR_STATIC5 1045 #define IDC_TAG_TYPE_STATIC 1045 #define IDC_COLOR_STATIC6 1046 -#define IDC_DEBUG_INFO_STATIC 1046 #define IDC_BITS_DIPTH 1046 #define IDC_COLOR_STATIC7 1047 -#define IDC_LYRIC_STATIC 1047 -#define IDC_SAMPLE_FREQ2 1047 #define IDC_CHANNELS 1047 -#define IDC_TIME_STATIC1 1048 -#define IDC_PROGRESS_STATIC1 1049 #define IDC_YEAR_EDIT 1050 -#define IDC_SPECTRAL_STATIC 1050 -#define IDC_GENRE_EDIT 1051 -#define ID_M_PLAY_PAUSE 1051 #define IDC_COMMENT_EDIT 1052 -#define ID_M_PREVIOUS 1052 -#define IDC_YEAR_EDIT2 1053 -#define ID_M_NEXT 1053 -#define IDC_STOP 1054 -#define IDC_PREVIOUS 1055 -#define IDC_PLAY_PAUSE 1056 -#define IDC_NEXT 1057 -#define IDC_SAVE_IN_OFFSET_TAG 1058 -#define IDC_SAVE_IN_TIME_TAG 1059 -#define IDC_REPLACE_TAG_BUTTON 1059 -#define IDC_SAVE_LYRIC_BUTTON 1060 #define IDC_EDIT1 1061 #define IDC_PLAYLIST_ITEM_HEIGHT_EDIT 1061 -#define IDC_DELETE_TAG__BUTTON 1062 -#define IDC_SAVE_AS_BUTTON5 1063 -#define IDC_OPEN_LYRIC_BUTTON 1064 -#define IDC_EDIT2 1065 #define IDC_LYRIC_PATH_EDIT2 1065 #define IDC_ARTIST_EDIT1 1065 -#define IDC_VBR_QUA_EDIT 1065 #define IDC_FILE_TOO_SHORT_SEC_EDIT 1065 -#define IDC_SPIN1 1066 #define IDC_SIZE_STATIC 1067 #define IDC_TITLE_EDIT1 1069 #define IDC_DOWNLOAD_SELECTED 1070 @@ -1015,7 +377,6 @@ #define IDC_LIST2 1075 #define IDC_STATIC1 1076 #define IDC_SAVE_TO_SONG_FOLDER 1077 -#define IDC_RADIO2 1078 #define IDC_SAVE_TO_LYRIC_FOLDER 1078 #define IDC_FIND_ALL_PLAYLIST_RADIO 1078 #define IDC_MCI_RADIO 1078 @@ -1026,7 +387,6 @@ #define IDC_SAVE_TO_SONG_FOLDER1 1080 #define IDC_SAVE_TO_ALBUM_FOLDER3 1080 #define IDC_SAVE_TO_LYRIC_FOLDER1 1081 -#define IDC_BUTTON2 1082 #define IDC_SELECTED_SAVE_AS 1082 #define IDC_SAVE_TO_FILE_BUTTON 1082 #define IDC_BROWSE_BUTTON 1082 @@ -1037,7 +397,6 @@ #define IDC_GET_TAG_FROM_FILE_NAME_BUTTON 1082 #define IDC_REFRESH_MEDIA_LIB_BUTTON 1082 #define IDC_TAB1 1083 -#define IDC_BROWSE_BUTTON2 1083 #define IDC_REVERB_MIX_SLIDER 1084 #define IDC_REVERB_TIME_SLIDER 1085 #define IDC_REVERB_MIX_STATIC 1086 @@ -1046,34 +405,26 @@ #define IDC_LICENSE_SYSLINK 1089 #define IDC_SPECTRUM_HEIGHT_SLIDER 1090 #define IDC_SPECTRUM_HEIGHT_STATIC 1091 -#define IDC_MINI_PROGRESS_STATIC 1092 #define IDC_BACKGROUND_TRANSPARENCY_SLIDER 1092 #define IDC_FIND_CURRENT_PLAYLIST_RADIO 1093 -#define IDC_SPECTRUM_HEIGHT_STATIC2 1093 #define IDC_BACKGROUND_TRANSPARENCY_STATIC 1093 #define IDC_GENRE_COMBO 1094 #define IDC_GAUSS_BLURE_RADIUS_SLIDER 1094 -#define IDC_CHECK4 1095 #define IDC_LYRIC_DOUBLE_LINE_CHECK 1095 #define IDC_USE_OUT_IMAGE_CHECK 1095 #define IDC_MIDI_USE_INNER_LYRIC_CHECK 1095 #define IDC_SOUND_FADE_CHECK 1095 #define IDC_CHANGE_FREQ_CHECK 1095 #define IDC_INSERT_BEGIN_CHECK 1095 -#define IDC_BUTTON3 1096 #define IDC_START_CONVERT_BUTTON 1096 -#define IDC_BACKGROUND_TRANSPARENCY_STATIC2 1096 #define IDC_GAUSS_BLUR_RADIUS_STATIC 1096 -#define IDC_RECORD_BUTTON 1096 #define IDC_KEEP_DISPLAY_CHECK 1096 #define IDC_BROWSE_BUTTON1 1096 #define IDC_GET_TAG_FROM_LYRIC_BUTTON 1096 #define IDC_STATISTICS_INFO_BUTTON 1096 #define IDC_ALBUM_FIT_COMBO 1097 -#define IDC_PAUSE_RESUME_BUTTON 1097 #define IDC_LYRIC_DOUBLE_LINE_CHECK2 1097 #define IDC_OPEN_FOLDER 1098 -#define IDC_STOP_BUTTON 1098 #define IDC_LOCK_DESKTOP_LYRIC_CHECK 1098 #define IDC_CORTANA_COLOR_COMBO 1099 #define IDC_SHOW_ALBUM_COVER_IN_CORTANA 1101 @@ -1094,7 +445,7 @@ #define IDC_ABR_RADIO 1113 #define IDC_CBR_RADIO2 1113 #define IDC_VBR_RADIO 1114 -#define IDC_USER_RADIO 1115 +#define IDC_USER_CHECK 1115 #define IDC_CBR_RATE_COMBO 1116 #define IDC_ENCODE_CMDLINE_EDIT 1117 #define IDC_QUALITY_SLIDER 1119 @@ -1105,33 +456,24 @@ #define IDC_DELETE_BUTTON 1123 #define IDC_CLEAR_BUTTON 1124 #define IDC_BACKGROUND_GAUSS_BLUR_CHECK 1124 -#define IDC_MOVE_UP_BUTTON 1125 #define IDC_LYRIC_BACKGROUND_CHECK 1125 -#define IDC_BUTTON8 1126 -#define IDC_MOVE_DOWN_BUTTON 1126 #define IDC_SAVE_BUTTON 1126 -#define IDC_CHECK6 1126 #define IDC_DARK_MODE_CHECK 1126 #define IDC_SHOW_DESKTOP_LYRIC 1126 -#define IDC_CLEAN_NOT_EXIST_CHECK 1126 #define IDC_AUTO_RUN_CHECK 1126 #define IDC_DISABLE_DELETE_FROM_DISK_CHECK 1126 #define IDC_FFMPEG_ENABLE_WASAPI 1126 -#define IDC_RECORDE_INPUT_COMBO 1127 -#define IDC_CLEAN_NOT_IN_MEDIA_LIB_DIR_CHECK 1127 #define IDC_OUTPUT_DEVICE_COMBO 1128 #define IDC_FORMAT_LIST 1129 #define IDC_HOTKEY1 1130 #define IDC_STATIC_COPYRIGHT 1131 #define IDC_MINIMIZE_TO_NOTIFY_RADIO 1132 -#define IDC_RADIO3 1133 #define IDC_EXIT_PROGRAM_RADIO 1133 #define IDC_USE_INNER_IMAGE_FIRST_CHECK 1133 #define IDC_LYRIC_COMPATIBLE_MODE 1134 #define IDC_UNASSOCIATE_LINK 1135 #define IDC_SHOW_DEFAULT_ALBUM_ICON_CHK 1135 #define IDC_DONATE_STATIC 1136 -#define IDC_LYRIC_COMPATIBLE_MODE2 1136 #define IDC_SEARCH_BOX_TRANSPARENT_IN_WHITE_MODE 1136 #define IDC_INPUT_EDIT 1138 #define IDC_BASS_RADIO 1139 @@ -1143,7 +485,6 @@ #define IDC_LYRIC_OPACITY_STATIC 1146 #define IDC_LYRIC_OPACITY_SLIDER 1147 #define IDC_HIDE_LYRIC_WITHOUT_LYRIC_CHECK 1148 -#define IDC_HIDE_LYRIC_WITHOUT_LYRIC_CHECK2 1149 #define IDC_HIDE_LYRIC_PAUSE_CHECK 1149 #define IDC_TEST_TOOLBAR 1149 #define IDC_HIDE_LYRIC_WITHOUT_LYRIC_CHECK3 1150 @@ -1166,7 +507,6 @@ #define IDC_LYRIC_FILE_STATIC 1166 #define IDC_ALIGNMENT_COMBO2 1166 #define IDC_PLAYLIST_DISPLAY_MODE_OMBO 1167 -#define IDC_ALIGNMENT_COMBO3 1167 #define IDC_DESKTOP_LYRIC_ALIGNMENT_COMBO 1167 #define IDC_RECENT_PLAYED_RANGE_OMBO 1168 #define IDC_DEFAULT_ALBUM_COVER_HQ 1168 @@ -1175,12 +515,10 @@ #define IDC_DELETE_FILE_BUTTON 1171 #define IDC_LYRIC_NAME_EDIT 1172 #define IDC_PREVIEW_STATIC 1173 -#define IDC_CHECK7 1174 #define IDC_NOTIFY_ICON_AUTO_ADAPT_CHECK 1174 #define IDC_SHOW_PLAYLIST_TOOLTIP_CHECK 1174 #define IDC_LYRIC_HIDE_BLANK_LINE_CHECK 1174 #define IDC_FFMPEG_ENABLE_WASAPI_EXCLUSIVE 1174 -#define IDC_CHECK8 1175 #define IDC_BTN_ROUND_CORNERS_CHECK 1175 #define IDC_FLOAT_PLAYLIST_FOLLOW_MAIN_WND_CHECK 1175 #define IDC_SHOW_SONG_INFO_IF_LYRIC_NOT_EXIST_CHECK 1175 @@ -1234,201 +572,216 @@ #define IDC_COMP_LEVEL_STATIC 1221 #define IDC_DOWNLOAD_OPTION_GROUPBOX 1221 #define IDC_COVER_LOCATION_STATIC 1222 -#define IDC_CHECK9 1223 #define IDC_REMOVE_FILE_NOT_EXIST_WHEN_UPDATE_CHECK 1223 #define IDC_FFMPEG_MAX_WAIT_TIME 1224 #define IDC_ACKNOWLEDGEMENT_SYSLINK 1225 #define IDC_HSPLITER_STATIC 1226 #define IDC_ARTIST_SPLIT_EXT_EDIT 1227 #define IDC_IGNORE_TOO_SHORT_CHECK 1228 -#define ID_32771 32771 -#define ID_32772 32772 -#define ID_OPEN 32773 +#define IDC_STATIC_THIRD_PARTY_LIB 1229 +#define IDC_STATIC_OTHER_SOFTWARE 1230 +#define IDC_VISUAL_EFFECTS_STATIC 1231 +#define IDC_TXT_SPECTRUM_HIGHT_STATIC 1232 +#define IDC_TXT_COVER_FIT_STATIC 1233 +#define IDC_TXT_TRANSPARENT_STATIC 1234 +#define IDC_TXT_BG_SETTING_STATIC 1235 +#define IDC_TXT_BG_TRANSPARENCY_STATIC 1236 +#define IDC_TXT_GAUSS_BLUR_RADIUS_STATIC 1237 +#define IDC_TXT_DEFAULT_BG_PATH_EDIT_STATIC 1238 +#define IDC_TXT_COVER_OPT_STATIC 1239 +#define IDC_TXT_EXT_COVER_FILE_NAME_STATIC 1240 +#define IDC_TXT_EXT_COVER_FOLDER_STATIC 1241 +#define IDC_TXT_THEME_COLOR_STATIC 1242 +#define IDC_PRESET_COLOR_STATIC 1243 +#define IDC_TXT_STATUS_BAR_STATIC 1244 +#define IDC_TXT_TITLE_BAR_STATIC 1245 +#define IDC_TXT_TITLE_BAR_BTN_SEL_STATIC 1246 +#define IDC_NA_ICO_STATIC 1247 +#define IDC_TXT_NA_ICO_SEL_STATIC 1248 +#define IDC_TXT_ADV_STATIC 1249 +#define IDC_TXT_UI_INTERVAL_STATIC 1250 +#define IDC_TXT_CLEAN_UP_RANGE_SEL_STATIC 1251 +#define IDC_TXT_COVER_DL_TITLE_STATIC 1252 +#define IDC_TXT_COVER_DL_ARTIST_STATIC 1253 +#define IDC_TXT_OPT_DATA_APP_SETTING_STATIC 1254 +#define IDC_TXT_OPT_DATA_UPDATE_SOURCE_SEL_STATIC 1255 +#define IDC_TXT_OPT_DATA_LANGUAGE_SEL_STATIC 1256 +#define IDC_TXT_OPT_DATA_DATA_FILE_CFG_STATIC 1257 +#define IDC_TXT_OPT_DATA_CLOSE_MAIN_WINDOW_STATIC 1258 +#define IDC_TXT_OPT_DATA_AUTO_DL_SETTING_STATIC 1259 +#define IDC_TXT_OPT_DATA_AUTO_DL_LYRIC_SAVE_SEL_STATIC 1260 +#define IDC_TXT_OPT_DATA_AUTO_DL_COVER_SAVE_SEL_STATIC 1261 +#define IDC_TXT_OPT_DATA_MIDI_SETTING_STATIC 1262 +#define IDC_TXT_OPT_DATA_MIDI_SF2_PATH_STATIC 1263 +#define IDC_TXT_EQ_PRESET_STATIC 1264 +#define IDC_TXT_EQ_CHANNEL_SETTING_STATIC 1265 +#define IDC_TXT_FIND_KEY_WORD_INPUT_STATIC 1266 +#define IDC_TXT_FIND_FIND_RANGE_STATIC 1267 +#define IDC_TXT_FIND_OPT_STATIC 1268 +#define IDC_TXT_ENCODE_OPT_FLAC_CMP_LEVEL_STATIC 1269 +#define IDC_TXT_ENCODE_OPT_FLAC_CMP_LEVEL_LOW_STATIC 1270 +#define IDC_TXT_ENCODE_OPT_FLAC_CMP_LEVEL_HIGH_STATIC 1271 +#define IDC_TXT_FORMAT_CONVERT_OUT_FORMAT_SEL_STATIC 1272 +#define IDC_TXT_FORMAT_CONVERT_FILE_LIST_STATIC 1273 +#define IDC_TXT_FORMAT_CONVERT_OPT_STATIC 1274 +#define IDC_TXT_FORMAT_CONVERT_OUT_FILE_NAME_STATIC 1275 +#define IDC_TXT_FORMAT_CONVERT_FILE_EXIST_SEL_STATIC 1276 +#define IDC_TXT_FORMAT_CONVERT_OUT_DIR_STATIC 1277 +#define IDC_TXT_OPT_HOT_KEY_SHORTCUT_KEY_SEL_STATIC 1278 +#define IDC_TXT_LYRIC_BDL_DL_OPT_STATIC 1279 +#define IDC_TXT_LYRIC_BDL_SAVE_ENCODE_SEL_STATIC 1280 +#define IDC_TXT_LYRIC_BDL_SAVE_DIR_SEL_STATIC 1281 +#define IDC_TXT_LYRIC_BDL_SONG_LIST_STATIC 1282 +#define IDC_TXT_LYRIC_DL_TITLE_STATIC 1283 +#define IDC_TXT_LYRIC_DL_ARTIST_STATIC 1284 +#define IDC_TXT_LYRIC_DL_OPT_STATIC 1285 +#define IDC_TXT_LYRIC_DL_SAVE_ENCODE_SEL_STATIC 1286 +#define IDC_TXT_LYRIC_DL_SAVE_DIR_SEL_STATIC 1287 +#define IDC_TXT_LRC_RELATE_LRC_TITLE_STATIC 1288 +#define IDC_TXT_LRC_RELATE_SEARCH_RESULT_STATIC 1289 +#define IDC_TXT_OPT_LRC_OPT_STATIC 1290 +#define IDC_TXT_OPT_LRC_LRC_FOLDER_STATIC 1291 +#define IDC_TXT_OPT_LRC_SAVE_POLICY_SEL_STATIC 1292 +#define IDC_TXT_OPT_LRC_WINDOW_LRC_STATIC 1293 +#define IDC_TXT_OPT_LRC_WINDOW_LRC_LINE_SPACING_STATIC 1294 +#define IDC_TXT_OPT_LRC_WINDOW_LRC_ALIGN_SEL_STATIC 1295 +#define IDC_TXT_OPT_LRC_DESKTOP_LRC_STATIC 1296 +#define IDC_TXT_OPT_LRC_DESKTOP_LRC_COLOR_TEXT_STATIC 1297 +#define IDC_TXT_OPT_LRC_DESKTOP_LRC_COLOR_HIGHLIGHT_STATIC 1298 +#define IDC_TXT_OPT_LRC_DESKTOP_LRC_TRANSPARENCY_STATIC 1299 +#define IDC_TXT_OPT_LRC_DESKTOP_LRC_ALIGN_SEL_STATIC 1300 +#define IDC_TXT_OPT_LRC_SEARCH_BOX_FUNCTION_STATIC 1301 +#define IDC_TXT_OPT_LRC_SEARCH_BOX_BG_COLOR_SEL_STATIC 1302 +#define IDC_TXT_OPT_LRC_SEARCH_BOX_ALIGN_SEL_STATIC 1303 +#define IDC_TXT_OPT_MEDIA_LIB_MEDIA_LIB_OPT_STATIC 1304 +#define IDC_TXT_OPT_MEDIA_LIB_TOO_SHORT_SEC_STATIC 1305 +#define IDC_TXT_OPT_MEDIA_LIB_ARTIST_SPLIT_EXT_SEL_STATIC 1306 +#define IDC_TXT_OPT_MEDIA_LIB_MEDIA_LIB_UPDATE_OPT_STATIC 1307 +#define IDC_TXT_OPT_MEDIA_LIB_MEDIA_LIB_DIR_STATIC 1308 +#define IDC_TXT_OPT_MEDIA_LIB_MEDIA_LIB_DISP_TAB_STATIC 1309 +#define IDC_TXT_OPT_MEDIA_LIB_PLAYLIST_OPT_STATIC 1310 +#define IDC_TXT_OPT_MEDIA_LIB_PLAYLIST_DISPLAY_MODE_STATIC 1311 +#define IDC_TXT_OPT_MEDIA_LIB_PLAYLIST_ITEM_HEIGHT_STATIC 1312 +#define IDC_TXT_OPT_MEDIA_LIB_RECENT_PLAY_STATIC 1313 +#define IDC_TXT_OPT_MEDIA_LIB_RECENT_PLAY_RANGE_SEL_STATIC 1314 +#define IDC_TXT_OPT_MEDIA_LIB_CLEAN_MEDIA_LIB_STATIC 1315 +#define IDC_TXT_OPT_MEDIA_LIB_TAG_EDIT_STATIC 1316 +#define IDC_TXT_OPT_MEDIA_LIB_TAG_ID3V2_WRITE_TYPE_STATIC 1317 +#define IDC_TXT_OPT_LAST_FM_STATIC 1318 +#define IDC_TXT_OPT_LAST_FM_AUTO_UPLOAD_THRESHOLD_STATIC 1319 +#define IDC_TXT_OPT_LAST_FM_CACHE_CONDITION_STATIC 1320 +#define IDC_TXT_OPT_LAST_FM_CACHE_CONDITION_PERCENT_STATIC 1321 +#define IDC_TXT_OPT_LAST_FM_CACHE_CONDITION_DURATION_STATIC 1322 +#define IDC_TXT_ENCODE_OPT_MP3_VBR_QUALITY_SEL_STATIC 1323 +#define IDC_TXT_ENCODE_OPT_MP3_VBR_QUALITY_LOW_STATIC 1324 +#define IDC_TXT_ENCODE_OPT_MP3_VBR_QUALITY_HIGH_STATIC 1325 +#define IDC_TXT_ENCODE_OPT_OGG_ENCODE_QUALITY_SEL_STATIC 1326 +#define IDC_TXT_ENCODE_OPT_OGG_ENCODE_QUALITY_LOW_STATIC 1327 +#define IDC_TXT_ENCODE_OPT_OGG_ENCODE_QUALITY_HIGH_STATIC 1328 +#define IDC_TXT_OPT_PLAY_PLAY_OPT_STATIC 1329 +#define IDC_TXT_OPT_PLAY_CORE_STATIC 1330 +#define IDC_TXT_OPT_PLAY_DEVICE_STATIC 1331 +#define IDC_TXT_OPT_PLAY_DEVICE_SEL_STATIC 1332 +#define IDC_TXT_OPT_PLAY_FFMPEG_CORE_SETTING_STATIC 1333 +#define IDC_TXT_OPT_PLAY_FFMPEG_CORE_CACHE_LENGTH_STATIC 1334 +#define IDC_TXT_OPT_PLAY_FFMPEG_CORE_MAX_RETRY_COUNT_STATIC 1335 +#define IDC_TXT_OPT_PLAY_FFMPEG_CORE_URL_RETRY_INTERVAL_STATIC 1336 +#define IDC_TXT_OPT_PLAY_FFMPEG_CORE_MAX_WAIT_TIME_STATIC 1337 +#define IDC_TXT_PROPERTY_DLG_FILE_INFO_STATIC 1338 +#define IDC_TXT_PROPERTY_DLG_FILE_NAME_STATIC 1339 +#define IDC_TXT_PROPERTY_DLG_FILE_PATH_STATIC 1340 +#define IDC_TXT_PROPERTY_DLG_FILE_TYPE_STATIC 1341 +#define IDC_TXT_PROPERTY_DLG_FILE_DURATION_STATIC 1342 +#define IDC_TXT_PROPERTY_DLG_FILE_SIZE_STATIC 1343 +#define IDC_TXT_PROPERTY_DLG_FILE_BIT_RATE_STATIC 1344 +#define IDC_TXT_PROPERTY_DLG_FILE_CHANNELS_STATIC 1345 +#define IDC_TXT_PROPERTY_DLG_FILE_FREQ_STATIC 1346 +#define IDC_TXT_PROPERTY_DLG_FILE_BIT_DEPTH_STATIC 1347 +#define IDC_TXT_PROPERTY_DLG_TAG_INFO_STATIC 1348 +#define IDC_TXT_PROPERTY_DLG_TAG_TITLE_STATIC 1349 +#define IDC_TXT_PROPERTY_DLG_TAG_ARTIST_STATIC 1350 +#define IDC_TXT_PROPERTY_DLG_TAG_ALBUM_STATIC 1351 +#define IDC_TXT_PROPERTY_DLG_TAG_TRACK_STATIC 1352 +#define IDC_TXT_PROPERTY_DLG_TAG_YEAR_STATIC 1353 +#define IDC_TXT_PROPERTY_DLG_TAG_GENRE_STATIC 1354 +#define IDC_TXT_PROPERTY_DLG_TAG_COMMENT_STATIC 1355 +#define IDC_TXT_REVERB_STRENGTH_STATIC 1356 +#define IDC_TXT_REVERB_TIME_STATIC 1357 +#define IDC_TXT_LIB_PATH_CURRENT_FOLDER_STATIC 1358 +#define IDC_TXT_TAG_EDIT_PATH_STATIC 1359 +#define IDC_TXT_TAG_SEL_CLICK_BTN_SEL_STATIC 1360 +#define IDC_FLOAT_PLAYLIST_BY_DEFAULT_CHECK 1361 #define ID_FILE_OPEN_FOLDER 32774 -#define ID_32775 32775 -#define ID_32776 32776 -#define ID_32777 32777 #define ID_PLAY_PAUSE 32778 #define ID_STOP 32779 -#define ID_32780 32780 #define ID_PREVIOUS 32781 -#define ID_32782 32782 #define ID_NEXT 32783 -#define ID_32784 32784 -#define ID_32785 32785 -#define ID_32786 32786 #define ID_REW 32787 #define ID_FF 32788 #define ID_PLAY 32789 #define ID_PAUSE 32790 -#define ID_32791 32791 -#define ID_32792 32792 -#define ID_SET_PATH 32793 +#define ID_MEDIA_LIB 32793 #define ID_FIND 32794 #define ID_EXPLORE_PATH 32795 -#define ID_32796 32796 -#define ID_32797 32797 -#define ID_32798 32798 -#define ID_32799 32799 -#define ID_32800 32800 -#define ID_32801 32801 -#define ID_32802 32802 -#define ID_32803 32803 #define ID_PLAY_ORDER 32804 #define ID_PLAY_SHUFFLE 32805 #define ID_PLAY_RANDOM 32806 #define ID_LOOP_PLAYLIST 32807 #define ID_LOOP_TRACK 32808 #define ID_PLAY_TRACK 32809 -#define ID_SET_FONT 32810 -#define ID_STOP_WHEN_ERROR 32811 -#define ID_32812 32812 -#define ID_32813 32813 -#define ID_32814 32814 -#define ID_32815 32815 -#define ID_TRANSPARENCY_100 32816 -#define ID_TRANSPARENCY_80 32817 -#define ID_TRANSPARENCY_60 32818 -#define ID_TRANSPARENCY_40 32819 -#define ID_32820 32820 -#define ID_KARAOKE_DISP 32821 -#define ID_32822 32822 -#define ID_REFRESH_PLAYLIST 32823 -#define ID_32824 32824 #define ID_OPTION_SETTINGS 32825 -#define ID_OPTION_SETTINGS2 32826 #define ID_RELOAD_PLAYLIST 32827 -#define ID_32828 32828 -#define ID_Menu 32829 #define ID_PLAY_ITEM 32830 #define ID_TEST 32831 -#define ID_PROPERTY 32832 #define ID_ITEM_PROPERTY 32833 #define ID_TEST_DIALOG 32834 #define ID_REMOVE_FROM_PLAYLIST 32835 -#define ID_32836 32836 -#define ID_32837 32837 -#define ID_CLEAR_PLAYLIST 32838 -#define ID_32839 32839 #define ID_EXPLORE_TRACK 32840 -#define ID_32841 32841 -#define ID_32842 32842 #define ID_RE_INI_BASS 32843 -#define ID_32844 32844 -#define ID_32845 32845 -#define ID_32846 32846 -#define ID_32847 32847 -#define ID_32848 32848 -#define ID_32849 32849 #define ID_SORT_BY_FILE 32850 #define ID_SORT_BY_PATH 32851 #define ID_SORT_BY_TITLE 32852 #define ID_SORT_BY_ARTIST 32853 #define ID_SORT_BY_ALBUM 32854 #define ID_SORT_BY_TRACK 32855 -#define ID_SORT_BY_MODIFIED_TIME 32856 -#define ID_DELETE_FROM_DISK 32857 -#define ID_32858 32858 -#define ID_32859 32859 -#define ID_32860 32860 -#define ID_32861 32861 +#define ID_SORT_BY_LISTEN_TIME 32856 +#define ID_SORT_BY_MODIFIED_TIME 32857 +#define ID_DELETE_FROM_DISK 32861 #define ID_DISP_FILE_NAME 32862 #define ID_DISP_TITLE 32863 #define ID_DISP_ARTIST_TITLE 32864 #define ID_DISP_TITLE_ARTIST 32865 -#define ID_32866 32866 -#define ID_MINI_DOEDE 32867 -#define ID_32868 32868 -#define ID_32869 32869 #define ID_MINI_MODE_EXIT 32870 #define ID_SONG_INFO 32871 #define ID_MINI_MODE 32872 -#define ID_32873 32873 -#define ID_SET_TEXT_COLOR 32874 -#define ID_32875 32875 #define ID_RELOAD_LYRIC 32876 -#define ID_SONG_INFO1 32877 -#define ID_32878 32878 -#define ID_32879 32879 #define ID_COPY_CURRENT_LYRIC 32880 #define ID_COPY_ALL_LYRIC 32881 -#define ID_32882 32882 -#define ID_32883 32883 -#define ID_LYRIC_FORWARD_0_5_SEC 32884 #define ID_LYRIC_FORWARD 32885 #define ID_LYRIC_DELAY 32886 -#define ID_32887 32887 #define ID_SAVE_MODIFIED_LYRIC 32888 -#define ID_32889 32889 #define ID_EDIT_LYRIC 32890 -#define ID_32891 32891 #define ID_DOWNLOAD_LYRIC 32892 -#define ID_32893 32893 #define ID_LYRIC_BATCH_DOWNLOAD 32894 -#define ID_32895 32895 -#define ID_32896 32896 #define ID_DELETE_LYRIC 32897 -#define ID_32898 32898 -#define ID_32899 32899 #define ID_DARK_MODE 32900 -#define ID_32901 32901 -#define ID_32902 32902 -#define ID_FOLLOW_MAIN_COLOR 32903 -#define ID_32904 32904 -#define ID_32905 32905 -#define ID_32906 32906 -#define ID_32907 32907 -#define ID_32908 32908 -#define ID_32909 32909 -#define ID_32910 32910 #define ID_LYRIC_OPEN 32911 -#define ID_LRYIC_SAVE 32912 #define ID_LYRIC_SAVE_AS 32913 -#define ID_LYRIC_EXIT 32914 -#define ID_INSERT_TAG_BUTTON 32915 -#define ID_INSERT_TAG 32916 -#define ID_REPLACE_TAG 32917 -#define ID_DELETE_TAG 32918 -#define ID_32919 32919 -#define ID_32920 32920 -#define ID_32921 32921 -#define ID_32922 32922 -#define ID_32923 32923 #define ID_LYRIC_FIND 32924 #define ID_LYRIC_REPLACE 32925 -#define IDC_LYRIC_OPEN 32926 #define ID_LYRIC_SAVE 32927 -#define ID_32928 32928 #define ID_FIND_NEXT 32929 -#define ID_32930 32930 #define ID_EQUALIZER 32931 -#define ID_32932 32932 #define ID_EXPLORE_ONLINE 32933 -#define ID_32934 32934 -#define ID_32935 32935 -#define ID_LYRIC_DOWNLOAD 32936 #define ID_LD_LYRIC_DOWNLOAD 32937 #define ID_LD_LYRIC_SAVEAS 32938 -#define ID_32939 32939 -#define ID_32940 32940 -#define ID_32941 32941 -#define ID_32942 32942 -#define ID_32943 32943 #define ID_LD_COPY_TITLE 32944 #define ID_LD_COPY_ALBUM 32945 #define ID_LD_COPY_ID 32946 #define ID_LD_VIEW_ONLINE 32947 #define ID_LD_COPY_ARTIST 32948 -#define ID_32949 32949 -#define ID_32950 32950 -#define ID_FD_PLAY 32951 -#define ID_FD_OPEN_FILE_LOCATION 32952 -#define ID_32953 32953 -#define ID_FD_COPY_TEXT 32954 #define ID_BROWSE_LYRIC 32955 -#define ID_32956 32956 #define ID_TRANSLATE_TO_SIMPLIFIED_CHINESE 32957 -#define ID_32958 32958 #define ID_TRANSLATE_TO_TRANDITIONAL_CHINESE 32959 #define ID_LE_TRANSLATE_TO_SIMPLIFIED_CHINESE 32960 #define ID_LE_TRANSLATE_TO_TRANDITIONAL_CHINESE 32961 @@ -1436,204 +789,111 @@ #define ID_LYRIC_INSERT_TAG 32963 #define ID_LYRIC_REPLACE_TAG 32964 #define ID_LYRIC_DELETE_TAG 32965 -#define ID_32967 32967 #define ID_PLAY_PATH 32968 -#define ID_32969 32969 #define ID_DELETE_PATH 32970 -#define ID_32971 32971 #define ID_BROWSE_PATH 32972 -#define ID_32973 32973 #define ID_CLEAR_INVALID_PATH 32974 #define ID_DOWNLOAD_ALBUM_COVER 32975 -#define ID_32976 32976 #define ID_CURRENT_EXPLORE_ONLINE 32977 -#define ID_32978 32978 #define ID_DELETE_ALBUM_COVER 32979 -#define ID_32980 32980 -#define ID_32981 32981 #define ID_COPY_FILE_TO 32982 #define ID_MOVE_FILE_TO 32983 #define ID_FORMAT_CONVERT 32984 -#define ID_32985 32985 #define ID_FORMAT_CONVERT1 32986 -#define ID_32987 32987 #define ID_ADD_FILE 32988 -#define ID_32989 32989 #define ID_DELETE_SELECT 32990 #define ID_CLEAR_LIST 32991 #define ID_MOVE_UP 32992 #define ID_MOVE_DOWN 32993 -#define ID_32994 32994 #define ID_EDIT_TAG_INFO 32995 -#define ID_32996 32996 -#define ID_RECORDER 32997 #define ID_SUPPORTED_FORMAT 32998 -#define ID_32999 32999 #define ID_VOLUME_UP 33000 #define ID_VOLUME_DOWN 33001 #define ID_SHOW_PLAY_LIST 33002 #define ID_MENU_EXIT 33003 -#define ID_33004 33004 #define ID_MINIMODE_RESTORE 33005 -#define ID_33006 33006 -#define ID_MINI_MIDE_MINI 33007 #define ID_MINI_MIDE_MINIMIZE 33008 -#define ID_33009 33009 #define ID_SHOW_PLAYLIST 33010 -#define ID_33011 33011 #define ID_SHOW_MENU_BAR 33012 -#define ID_33013 33013 #define ID_FULL_SCREEN 33014 -#define ID_33015 33015 #define ID_CREATE_PLAY_SHORTCUT 33016 -#define ID_33017 33017 #define ID_LISTEN_STATISTICS 33018 -#define ID_33019 33019 #define ID_LD_PREVIEW 33020 -#define ID_33021 33021 -#define ID_33022 33022 #define ID_ALWAYS_ON_TOP 33023 -#define ID_33024 33024 -#define ID_33025 33025 #define ID_FLOAT_PLAYLIST 33026 -#define ID_33027 33027 -#define ID_33028 33028 #define ID_DOCKED_PLAYLIST 33029 #define ID_FLOATED_PLAYLIST 33030 -#define ID_33031 33031 -#define ID_FILE_OPEN_PALYLIST 33032 -#define ID_33033 33033 -#define ID_33034 33034 -#define ID_33035 33035 #define ID_PLAYLIST_ADD_FILE 33036 #define ID_EMPTY_PLAYLIST 33037 -#define ID_33038 33038 -#define ID_33039 33039 -#define ID_33040 33040 #define ID_PLAY_PLAYLIST 33041 #define ID_RENAME_PLAYLIST 33042 #define ID_DELETE_PLAYLIST 33043 -#define ID_33044 33044 #define ID_MOVE_PLAYLIST_ITEM_UP 33045 #define ID_MOVE_PLAYLIST_ITEM_DOWN 33046 -#define ID_33047 33047 #define ID_REMOVE_SAME_SONGS 33048 -#define ID_33049 33049 #define ID_ADD_TO_NEW_PLAYLIST 33050 #define ID_ADD_TO_DEFAULT_PLAYLIST 33051 #define ID_ADD_TO_MY_FAVOURITE 33052 -#define ID_FILE_RELATE 33095 #define ID_TOOL_FILE_RELATE 33096 #define ID_ADD_TO_OTHER_PLAYLIST 33097 -#define ID_33098 33098 -#define ID_MENU_ADD 33099 -#define ID_MENU_DELETE 33100 -#define ID_33101 33101 #define ID_PLAYLIST_ADD_FOLDER 33102 #define ID_ADD_REMOVE_FROM_FAVOURITE 33103 -#define ID_REMOVE_INVALID_ITEM 33104 #define ID_REMOVE_INVALID_ITEMS 33105 -#define ID_33106 33106 #define ID_NEW_PLAYLIST 33107 -#define ID_33108 33108 #define ID_FILE_OPEN_URL 33109 -#define ID_33110 33110 #define ID_PLAYLIST_ADD_URL 33111 -#define ID_33112 33112 #define ID_LYRIC_DISPLAYED_DOUBLE_LINE 33113 #define ID_LOCK_DESKTOP_LRYIC 33114 -#define ID_33115 33115 #define ID_CLOSE_DESKTOP_LYRIC 33116 -#define ID_33117 33117 -#define ID_33118 33118 -#define ID_33119 33119 -#define ID_33120 33120 #define ID_LYRIC_DEFAULT_STYLE1 33121 #define ID_LYRIC_DEFAULT_STYLE2 33122 #define ID_LYRIC_DEFAULT_STYLE3 33123 -#define ID_LYRIC_USER_DEFINE 33124 -#define ID_33125 33125 #define ID_LYRIC_BACKGROUND_PENETRATE 33126 #define ID_PLAYLIST_SELECT_ALL 33127 #define ID_PLAYLIST_SELECT_NONE 33128 #define ID_PLAYLIST_SELECT_REVERT 33129 -#define ID_33130 33130 -#define ID_2_33131 33131 #define ID_LYRIC_DEFAULT_STYLE1_MODIFY 33132 #define ID_LYRIC_DEFAULT_STYLE2_MODIFY 33133 #define ID_LYRIC_DEFAULT_STYLE3_MODIFY 33134 -#define ID_33135 33135 #define ID_RESTORE_DEFAULT_STYLE 33136 -#define ID_33137 33137 #define ID_ONLINE_HELP 33138 -#define ID_33139 33139 -#define ID_33140 33140 -#define ID_33141 33141 #define ID_SPEED_UP 33142 #define ID_SLOW_DOWN 33143 #define ID_ORIGINAL_SPEED 33144 -#define ID_ADD_TO_NEW_PALYLIST_AND_PLAY 33145 -#define ID_33146 33146 +#define ID_ADD_TO_NEW_PLAYLIST_AND_PLAY 33145 #define ID_PLAY_ITEM_IN_FOLDER_MODE 33147 #define ID_COPY_TEXT 33148 #define ID_ALWAYS_SHOW_STATUS_BAR 33149 #define ID_SHOW_MAIN_WINDOW 33150 #define ID_AB_REPEAT 33151 -#define ID_33152 33152 #define ID_SET_A_POINT 33153 #define ID_SET_B_POINT 33154 #define ID_RESET_AB_REPEAT 33155 -#define ID_AB33156 33156 #define ID_NEXT_AB_REPEAT 33157 #define ID_SAVE_CURRENT_PLAYLIST_AS 33158 -#define ID_33159 33159 #define ID_FILE_OPEN_PLAYLIST 33160 -#define ID_33161 33161 -#define ID_EXPORT_CURRENT_PLAYLIST 33162 -#define ID_33163 33163 #define ID_SAVE_AS_NEW_PLAYLIST 33164 #define ID_CREATE_DESKTOP_SHORTCUT 33165 #define ID_CREATE_MINI_MODE_SHORT_CUT 33166 #define ID_REMOVE_CURRENT_FROM_PLAYLIST 33167 #define ID_DELETE_CURRENT_FROM_DISK 33168 -#define ID_33169 33169 #define ID_MINI_MODE_ALWAYS_ON_TOP 33170 #define ID_ALWAYS_USE_EXTERNAL_ALBUM_COVER 33171 -#define ID_33173 33173 #define ID_LRYIC_MERGE_SAME_TIME_TAG 33174 #define ID_LYRIC_SWAP_TEXT_AND_TRANSLATION 33175 -#define ID_33176 33176 #define ID_LYRIC_TIME_TAG_FORWARD 33177 -#define ID_ 33178 #define ID_LYRIC_TIME_TAG_DELAY 33179 -#define ID_33180 33180 #define ID_RELATE_LOCAL_LYRIC 33181 -#define ID_33182 33182 #define ID_ALBUM_COVER_INFO 33183 #define ID_UNLINK_LYRIC 33184 #define ID_SHOW_DESKTOP_LYRIC 33185 -#define ID_33186 33186 -#define ID_33187 33187 #define ID_CONTAIN_SUB_FOLDER 33188 -#define ID_33189 33189 -#define ID_33190 33190 -#define ID_ACCENDING_ORDER 33191 -#define ID_DESENDING_ORDER 33192 -#define ID_33193 33193 -#define ID_INVERT_PLAYLIST 33194 -#define ID_33195 33195 #define ID_HELP_UPDATE_LOG 33196 #define ID_LD_RELATE 33197 #define ID_COVER_BROWSE 33198 #define ID_COVER_DELETE 33199 -#define ID_1_33200 33200 #define ID_COVER_SAVE_AS 33201 -#define ID_LISTCTRL_33202 33202 -#define ID_33203 33203 #define ID_RENAME 33204 -#define ID_33205 33205 -#define ID_33206 33206 -#define ID_33207 33207 #define ID_EMBED_LYRIC_TO_AUDIO_FILE 33208 #define ID_DELETE_LYRIC_FROM_AUDIO_FILE 33209 #define ID_SWITCH_UI 33210 @@ -1652,20 +912,12 @@ #define ID_VIEW_ARTIST 33322 #define ID_LOCATE_TO_CURRENT 33323 #define ID_VIEW_ALBUM 33324 -#define ID_33325 33325 -#define ID_33326 33326 -#define ID_33327 33327 -#define ID_33328 33328 -#define ID_33329 33329 -#define ID_33330 33330 -#define ID_33331 33331 #define ID_RATING_1 33332 #define ID_RATING_2 33333 #define ID_RATING_3 33334 #define ID_RATING_4 33335 #define ID_RATING_5 33336 #define ID_RATING_NONE 33337 -#define ID_33338 33338 #define ID_USE_STANDARD_TITLE_BAR 33339 #define ID_PLAYLIST_VIEW_ARTIST 33340 #define ID_PLAYLIST_VIEW_ALBUM 33341 @@ -1673,30 +925,25 @@ #define ID_PLAYLIST_OPTIONS 33343 #define ID_RECENT_FOLDER_PLAYLIST_MENU_START 33344 #define ID_RECENT_FOLDER_PLAYLIST_MENU_END 33384 -#define ID_33385 33385 #define ID_HELP_CUSTOM_UI 33386 #define ID_COMPRESS_SIZE 33387 -#define ID_33388 33388 #define ID_PLAYLIST_SAVE_AS 33389 #define ID_HELP_FAQ 33390 -#define ID_33391 33391 #define ID_SEEK_TO_CUR_LINE 33392 #define ID_REPEAT_MODE 33393 #define ID_PLAY_AS_NEXT 33394 -#define ID_Menu33395 33395 #define ID_MINIMODE_UI_DEFAULT 33396 #define ID_MINIMODE_UI_MAX 33460 #define ID_PLAYLIST_FIX_PATH_ERROR 33461 -#define ID_33462 33462 #define ID_PLAYLIST_BROWSE_FILE 33463 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 591 +#define _APS_NEXT_RESOURCE_VALUE 594 #define _APS_NEXT_COMMAND_VALUE 33464 -#define _APS_NEXT_CONTROL_VALUE 1229 +#define _APS_NEXT_CONTROL_VALUE 1362 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/MusicPlayer2/skins/01_simple.xml b/MusicPlayer2/skins/01_simple.xml index cc4f360e5..ef914966d 100644 --- a/MusicPlayer2/skins/01_simple.xml +++ b/MusicPlayer2/skins/01_simple.xml @@ -1,4 +1,4 @@ - diff --git a/MusicPlayer2/skins/02_grooveMusic.xml b/MusicPlayer2/skins/02_grooveMusic.xml index 7c030e775..4259388be 100644 --- a/MusicPlayer2/skins/02_grooveMusic.xml +++ b/MusicPlayer2/skins/02_grooveMusic.xml @@ -1,4 +1,4 @@ - diff --git a/MusicPlayer2/skins/03_grooveMusicWin11.xml b/MusicPlayer2/skins/03_grooveMusicWin11.xml index 85919719c..c8e0bed12 100644 --- a/MusicPlayer2/skins/03_grooveMusicWin11.xml +++ b/MusicPlayer2/skins/03_grooveMusicWin11.xml @@ -1,4 +1,4 @@ - diff --git a/MusicPlayer2/skins/miniMode/miniMode00.xml b/MusicPlayer2/skins/miniMode/miniMode00.xml new file mode 100644 index 000000000..669552e51 --- /dev/null +++ b/MusicPlayer2/skins/miniMode/miniMode00.xml @@ -0,0 +1,26 @@ + + + + + + +