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