1 // LyricDownloadDlg.cpp : 实现文件
2 //
3
4 #include "stdafx.h"
5 #include "MusicPlayer2.h"
6 #include "Player.h"
7 #include "LyricDownloadDlg.h"
8 #include "MessageDlg.h"
9 #include "SongInfoHelper.h"
10 #include "SongDataManager.h"
11 #include "FilterHelper.h"
12 #include "IniHelper.h"
13
14
15 // CLyricDownloadDlg 对话框
16
IMPLEMENT_DYNAMIC(CLyricDownloadDlg,CBaseDialog)17 IMPLEMENT_DYNAMIC(CLyricDownloadDlg, CBaseDialog)
18
19 CLyricDownloadDlg::CLyricDownloadDlg(CWnd* pParent /*=NULL*/)
20 : CBaseDialog(IDD_LYRIC_DOWNLOAD_DIALOG, pParent)
21 {
22
23 }
24
~CLyricDownloadDlg()25 CLyricDownloadDlg::~CLyricDownloadDlg()
26 {
27 }
28
29
ShowDownloadList()30 void CLyricDownloadDlg::ShowDownloadList()
31 {
32 m_down_list_ctrl.DeleteAllItems();
33 for (size_t i{}; i < m_down_list.size(); i++)
34 {
35 CString tmp;
36 tmp.Format(_T("%d"), i + 1);
37 m_down_list_ctrl.InsertItem(i, tmp);
38 m_down_list_ctrl.SetItemText(i, 1, m_down_list[i].title.c_str());
39 m_down_list_ctrl.SetItemText(i, 2, m_down_list[i].artist.c_str());
40 m_down_list_ctrl.SetItemText(i, 3, m_down_list[i].album.c_str());
41 m_down_list_ctrl.SetItemText(i, 4, Time(m_down_list[i].duration).toString().c_str());
42 }
43 }
44
SaveLyric(const wchar_t * path,CodeType code_type)45 bool CLyricDownloadDlg::SaveLyric(const wchar_t * path, CodeType code_type)
46 {
47 bool char_connot_convert;
48 string lyric_str = CCommon::UnicodeToStr(m_lyric_str, code_type, &char_connot_convert);
49 if (char_connot_convert) //当文件中包含Unicode字符时,询问用户是否要选择一个Unicode编码格式再保存
50 {
51 const wstring& info = theApp.m_str_table.LoadText(L"MSG_UNICODE_WARNING"); // 从string table载入字符串
52 if (MessageBox(info.c_str(), NULL, MB_OKCANCEL | MB_ICONWARNING) != IDOK)
53 return false; // 如果用户点击了取消按钮,则返回false
54 }
55
56 ofstream out_put{ path, std::ios::binary };
57 if (!out_put.is_open())
58 {
59 out_put.close();
60 const wstring& info = theApp.m_str_table.LoadText(L"MSG_LYRIC_SAVE_FAILED");
61 MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK);
62 return false;
63 }
64 out_put << lyric_str;
65 out_put.close();
66 return true;
67 }
68
SetID(wstring id)69 void CLyricDownloadDlg::SetID(wstring id)
70 {
71 m_song.SetSongId(id);
72 CSongDataManager::GetInstance().SetSongID(m_song, m_song.song_id);
73 }
74
SaveConfig() const75 void CLyricDownloadDlg::SaveConfig() const
76 {
77 CIniHelper ini(theApp.m_config_path);
78 ini.WriteBool(L"lyric_download", L"download_translate", m_download_translate);
79 ini.WriteInt(L"lyric_download", L"save_as_utf8", static_cast<int>(m_save_code));
80 ini.WriteBool(L"lyric_download", L"save_to_song_folder", m_save_to_song_folder);
81 ini.WriteInt(L"lyric_download", L"search_max_item", m_search_max_item);
82 ini.Save();
83 }
84
LoadConfig()85 void CLyricDownloadDlg::LoadConfig()
86 {
87 CIniHelper ini(theApp.m_config_path);
88 m_download_translate = ini.GetBool(L"lyric_download", L"download_translate", true);
89 m_save_code = static_cast<CodeType>(ini.GetInt(L"lyric_download", L"save_as_utf8", 1));
90 m_save_to_song_folder = ini.GetBool(L"lyric_download", L"save_to_song_folder", true);
91 m_search_max_item = ini.GetInt(L"lyric_download", L"search_max_item", 30);
92 }
93
GetSavedDir()94 wstring CLyricDownloadDlg::GetSavedDir()
95 {
96 if (m_save_to_song_folder || !CCommon::FolderExist(theApp.m_lyric_setting_data.lyric_path))
97 return CFilePathHelper(m_song.file_path).GetDir();
98 else
99 return theApp.m_lyric_setting_data.lyric_path;
100 }
101
GetSavedPath()102 wstring CLyricDownloadDlg::GetSavedPath()
103 {
104 return GetSavedDir() + m_lyric_name + L".lrc";
105 }
106
GetDialogName() const107 CString CLyricDownloadDlg::GetDialogName() const
108 {
109 return _T("LyricDownloadDlg");
110 }
111
InitializeControls()112 bool CLyricDownloadDlg::InitializeControls()
113 {
114 wstring temp;
115 temp = theApp.m_str_table.LoadText(L"TITLE_LYRIC_DL");
116 SetWindowTextW(temp.c_str());
117 temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_TITLE");
118 SetDlgItemTextW(IDC_TXT_LYRIC_DL_TITLE_STATIC, temp.c_str());
119 // IDC_TITLE_EDIT1
120 temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_SEARCH");
121 SetDlgItemTextW(IDC_SEARCH_BUTTON2, temp.c_str());
122 temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_ARTIST");
123 SetDlgItemTextW(IDC_TXT_LYRIC_DL_ARTIST_STATIC, temp.c_str());
124 // IDC_ARTIST_EDIT1
125 temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_INFO");
126 SetDlgItemTextW(IDC_STATIC_INFO, temp.c_str());
127 temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_UNLINK");
128 SetDlgItemTextW(IDC_UNASSOCIATE_LINK, temp.c_str());
129 // IDC_LYRIC_DOWN_LIST1
130 temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_OPT");
131 SetDlgItemTextW(IDC_TXT_LYRIC_DL_OPT_STATIC, temp.c_str());
132 temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_WITH_TRANSLATION");
133 SetDlgItemTextW(IDC_DOWNLOAD_TRANSLATE_CHECK1, temp.c_str());
134 temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_SAVE_ENCODE_SEL");
135 SetDlgItemTextW(IDC_TXT_LYRIC_DL_SAVE_ENCODE_SEL_STATIC, temp.c_str());
136 // IDC_COMBO2
137 temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_SAVE_DIR_SEL");
138 SetDlgItemTextW(IDC_TXT_LYRIC_DL_SAVE_DIR_SEL_STATIC, temp.c_str());
139 temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_SAVE_DIR_LYRIC");
140 SetDlgItemTextW(IDC_SAVE_TO_LYRIC_FOLDER1, temp.c_str());
141 temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_SAVE_DIR_SONG");
142 SetDlgItemTextW(IDC_SAVE_TO_SONG_FOLDER1, temp.c_str());
143 temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_SEL_DL");
144 SetDlgItemTextW(IDC_DOWNLOAD_SELECTED, temp.c_str());
145 temp = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_SEL_SAVE_AS");
146 SetDlgItemTextW(IDC_SELECTED_SAVE_AS, temp.c_str());
147 temp = theApp.m_str_table.LoadText(L"TXT_CLOSE");
148 SetDlgItemTextW(IDCANCEL, temp.c_str());
149
150 RepositionTextBasedControls({
151 { CtrlTextInfo::L1, IDC_TXT_LYRIC_DL_TITLE_STATIC },
152 { CtrlTextInfo::C0, IDC_TITLE_EDIT1 },
153 { CtrlTextInfo::R1, IDC_SEARCH_BUTTON2, CtrlTextInfo::W32 },
154 { CtrlTextInfo::L1, IDC_TXT_LYRIC_DL_ARTIST_STATIC },
155 { CtrlTextInfo::C0, IDC_ARTIST_EDIT1 }
156 }, CtrlTextInfo::W64);
157 RepositionTextBasedControls({
158 { CtrlTextInfo::R1, IDC_DOWNLOAD_SELECTED, CtrlTextInfo::W32 },
159 { CtrlTextInfo::R2, IDC_SELECTED_SAVE_AS, CtrlTextInfo::W32 },
160 { CtrlTextInfo::R3, IDCANCEL, CtrlTextInfo::W32 }
161 });
162 return true;
163 }
164
DoDataExchange(CDataExchange * pDX)165 void CLyricDownloadDlg::DoDataExchange(CDataExchange* pDX)
166 {
167 CBaseDialog::DoDataExchange(pDX);
168 DDX_Control(pDX, IDC_LYRIC_DOWN_LIST1, m_down_list_ctrl);
169 DDX_Control(pDX, IDC_DOWNLOAD_TRANSLATE_CHECK1, m_download_translate_chk);
170 DDX_Control(pDX, IDC_COMBO2, m_save_code_combo);
171 DDX_Control(pDX, IDC_UNASSOCIATE_LINK, m_unassciate_lnk);
172 }
173
174
BEGIN_MESSAGE_MAP(CLyricDownloadDlg,CBaseDialog)175 BEGIN_MESSAGE_MAP(CLyricDownloadDlg, CBaseDialog)
176 ON_BN_CLICKED(IDC_SEARCH_BUTTON2, &CLyricDownloadDlg::OnBnClickedSearchButton2)
177 ON_EN_CHANGE(IDC_TITLE_EDIT1, &CLyricDownloadDlg::OnEnChangeTitleEdit1)
178 ON_EN_CHANGE(IDC_ARTIST_EDIT1, &CLyricDownloadDlg::OnEnChangeArtistEdit1)
179 ON_NOTIFY(NM_CLICK, IDC_LYRIC_DOWN_LIST1, &CLyricDownloadDlg::OnNMClickLyricDownList1)
180 ON_NOTIFY(NM_RCLICK, IDC_LYRIC_DOWN_LIST1, &CLyricDownloadDlg::OnNMRClickLyricDownList1)
181 ON_BN_CLICKED(IDC_DOWNLOAD_SELECTED, &CLyricDownloadDlg::OnBnClickedDownloadSelected)
182 ON_BN_CLICKED(IDC_DOWNLOAD_TRANSLATE_CHECK1, &CLyricDownloadDlg::OnBnClickedDownloadTranslateCheck1)
183 ON_WM_DESTROY()
184 ON_MESSAGE(WM_SEARCH_COMPLATE, &CLyricDownloadDlg::OnSearchComplate)
185 ON_MESSAGE(WM_DOWNLOAD_COMPLATE, &CLyricDownloadDlg::OnDownloadComplate)
186 ON_BN_CLICKED(IDC_SAVE_TO_SONG_FOLDER1, &CLyricDownloadDlg::OnBnClickedSaveToSongFolder1)
187 ON_BN_CLICKED(IDC_SAVE_TO_LYRIC_FOLDER1, &CLyricDownloadDlg::OnBnClickedSaveToLyricFolder1)
188 ON_BN_CLICKED(IDC_SELECTED_SAVE_AS, &CLyricDownloadDlg::OnBnClickedSelectedSaveAs)
189 ON_CBN_SELCHANGE(IDC_COMBO2, &CLyricDownloadDlg::OnCbnSelchangeCombo2)
190 ON_COMMAND(ID_LD_LYRIC_DOWNLOAD, &CLyricDownloadDlg::OnLdLyricDownload)
191 ON_COMMAND(ID_LD_LYRIC_SAVEAS, &CLyricDownloadDlg::OnLdLyricSaveas)
192 ON_COMMAND(ID_LD_COPY_TITLE, &CLyricDownloadDlg::OnLdCopyTitle)
193 ON_COMMAND(ID_LD_COPY_ARTIST, &CLyricDownloadDlg::OnLdCopyArtist)
194 ON_COMMAND(ID_LD_COPY_ALBUM, &CLyricDownloadDlg::OnLdCopyAlbum)
195 ON_COMMAND(ID_LD_COPY_ID, &CLyricDownloadDlg::OnLdCopyId)
196 ON_COMMAND(ID_LD_VIEW_ONLINE, &CLyricDownloadDlg::OnLdViewOnline)
197 ON_NOTIFY(NM_DBLCLK, IDC_LYRIC_DOWN_LIST1, &CLyricDownloadDlg::OnNMDblclkLyricDownList1)
198 ON_NOTIFY(NM_CLICK, IDC_UNASSOCIATE_LINK, &CLyricDownloadDlg::OnNMClickUnassociateLink)
199 ON_COMMAND(ID_LD_PREVIEW, &CLyricDownloadDlg::OnLdPreview)
200 ON_COMMAND(ID_LD_RELATE, &CLyricDownloadDlg::OnLdRelate)
201 END_MESSAGE_MAP()
202
203
204 // CLyricDownloadDlg 消息处理程序
205
206
207 bool CLyricDownloadDlg::IsItemSelectedValid() const
208 {
209 return (m_item_selected >= 0 && m_item_selected < static_cast<int>(m_down_list.size()));
210 }
211
OnInitDialog()212 BOOL CLyricDownloadDlg::OnInitDialog()
213 {
214 CBaseDialog::OnInitDialog();
215
216 // TODO: 在此添加额外的初始化
217 LoadConfig();
218
219 SetIcon(IconMgr::IconType::IT_Download, FALSE);
220 SetButtonIcon(IDC_SEARCH_BUTTON2, IconMgr::IconType::IT_Find);
221 SetButtonIcon(IDC_DOWNLOAD_SELECTED, IconMgr::IconType::IT_Download);
222 SetButtonIcon(IDC_SELECTED_SAVE_AS, IconMgr::IconType::IT_Save_As);
223
224 m_song = CPlayer::GetInstance().GetCurrentSongInfo();
225
226 if (m_song.IsTitleEmpty()) //如果没有标题信息,就把文件名设为标题
227 {
228 m_song.title = m_song.GetFileName();
229 size_t index = m_song.title.rfind(L'.');
230 m_song.title = m_song.title.substr(0, index);
231 }
232 if (m_song.IsArtistEmpty()) //没有艺术家信息,清空艺术家的文本
233 {
234 m_song.artist.clear();
235 }
236 if (m_song.IsAlbumEmpty()) //没有唱片集信息,清空唱片集的文本
237 {
238 m_song.album.clear();
239 }
240
241 if (m_song.is_cue || CPlayer::GetInstance().IsOsuFile())
242 {
243 m_lyric_name = CSongInfoHelper::GetDisplayStr(m_song, DF_ARTIST_TITLE);
244 CCommon::FileNameNormalize(m_lyric_name);
245 }
246 else
247 {
248 m_lyric_name = m_song.GetFileName();
249 m_lyric_name = CFilePathHelper(m_lyric_name).ReplaceFileExtension(nullptr); //清除文件名的扩展名
250 }
251 //if (!song.is_cue)
252 //else
253 // m_lyric_name = song.artist + L" - " + song.title + L".lrc";
254 //m_file_path = CPlayer::GetInstance().GetCurrentDir() + m_lyric_name;
255 //if (!song.is_cue)
256 //{
257 //}
258
259 SetDlgItemText(IDC_TITLE_EDIT1, m_song.title.c_str());
260 SetDlgItemText(IDC_ARTIST_EDIT1, m_song.artist.c_str());
261
262 //设置列表控件主题颜色
263 //m_down_list_ctrl.SetColor(theApp.m_app_setting_data.theme_color);
264
265 //初始化搜索结果列表控件
266 CRect rect;
267 m_down_list_ctrl.GetWindowRect(rect);
268 int width0, width1, width2, width3, width4;
269 width0 = rect.Width() / 10;
270 width1 = rect.Width() * 3 / 10;
271 width2 = rect.Width() * 2 / 10;
272 width4 = rect.Width() / 10;
273 width3 = rect.Width() - theApp.DPI(20) - 1 - width0 - width1 - width2 - width4;
274
275 m_down_list_ctrl.SetExtendedStyle(m_down_list_ctrl.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_LABELTIP);
276 m_down_list_ctrl.InsertColumn(0, theApp.m_str_table.LoadText(L"TXT_SERIAL_NUMBER").c_str(), LVCFMT_LEFT, width0);
277 m_down_list_ctrl.InsertColumn(1, theApp.m_str_table.LoadText(L"TXT_TITLE").c_str(), LVCFMT_LEFT, width1);
278 m_down_list_ctrl.InsertColumn(2, theApp.m_str_table.LoadText(L"TXT_ARTIST").c_str(), LVCFMT_LEFT, width2);
279 m_down_list_ctrl.InsertColumn(3, theApp.m_str_table.LoadText(L"TXT_ALBUM").c_str(), LVCFMT_LEFT, width3);
280 m_down_list_ctrl.InsertColumn(4, theApp.m_str_table.LoadText(L"TXT_LENGTH").c_str(), LVCFMT_LEFT, width4);
281
282 //设置列表控件的提示总是置顶,用于解决如果弹出此窗口的父窗口具有置顶属性时,提示信息在窗口下面的问题
283 m_down_list_ctrl.GetToolTips()->SetWindowPos(&CWnd::wndTopMost, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
284
285 //m_tool_tip.Create(this, TTS_ALWAYSTIP);
286
287 //初始化下载选项中控件的状态
288 m_download_translate_chk.SetCheck(m_download_translate);
289 m_save_code_combo.AddString(_T("ANSI"));
290 m_save_code_combo.AddString(_T("UTF-8"));
291 m_save_code_combo.SetCurSel(static_cast<int>(m_save_code));
292 if (m_save_to_song_folder)
293 ((CButton*)GetDlgItem(IDC_SAVE_TO_SONG_FOLDER1))->SetCheck(TRUE);
294 else
295 ((CButton*)GetDlgItem(IDC_SAVE_TO_LYRIC_FOLDER1))->SetCheck(TRUE);
296
297 //判断歌词文件夹是否存在
298 bool lyric_path_exist = CCommon::FolderExist(theApp.m_lyric_setting_data.lyric_path);
299 if (!lyric_path_exist) //如果歌词文件不存在,则禁用“保存到歌词文件夹”单选按钮,并强制选中“保存到歌曲所在目录”
300 {
301 ((CButton*)GetDlgItem(IDC_SAVE_TO_LYRIC_FOLDER1))->EnableWindow(FALSE);
302 ((CButton*)GetDlgItem(IDC_SAVE_TO_LYRIC_FOLDER1))->SetCheck(FALSE);
303 ((CButton*)GetDlgItem(IDC_SAVE_TO_SONG_FOLDER1))->SetCheck(TRUE);
304 m_save_to_song_folder = true;
305 }
306
307 m_unassciate_lnk.ShowWindow(SW_HIDE);
308
309 return TRUE; // return TRUE unless you set the focus to a control
310 // 异常: OCX 属性页应返回 FALSE
311 }
312
313
OnBnClickedSearchButton2()314 void CLyricDownloadDlg::OnBnClickedSearchButton2()
315 {
316 // TODO: 在此添加控件通知处理程序代码
317 SetDlgItemText(IDC_STATIC_INFO, theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_INFO_SEARCHING").c_str());
318 GetDlgItem(IDC_SEARCH_BUTTON2)->EnableWindow(FALSE); //点击“搜索”后禁用该按钮
319 wstring keyword = CInternetCommon::URLEncode(m_song.artist + L' ' + m_song.title); //搜索关键字为“艺术家 标题”,并将其转换成URL编码
320 CString url;
321 url.Format(L"http://music.163.com/api/search/get/?s=%s&limit=%d&type=1&offset=0", keyword.c_str(), m_search_max_item);
322 //int rtn = CLyricDownloadCommon::HttpPost(buff, m_search_result); //向网易云音乐的歌曲搜索API发送http的POST请求
323 m_search_thread_info.url = url;
324 m_search_thread_info.hwnd = GetSafeHwnd();
325 theApp.m_lyric_download_dialog_exit = false;
326 m_pSearchThread = AfxBeginThread(LyricSearchThreadFunc, &m_search_thread_info);
327 }
328
329
OnEnChangeTitleEdit1()330 void CLyricDownloadDlg::OnEnChangeTitleEdit1()
331 {
332 // TODO: 如果该控件是 RICHEDIT 控件,它将不
333 // 发送此通知,除非重写 CBaseDialog::OnInitDialog()
334 // 函数并调用 CRichEditCtrl().SetEventMask(),
335 // 同时将 ENM_CHANGE 标志“或”运算到掩码中。
336
337 // TODO: 在此添加控件通知处理程序代码
338 CString tmp;
339 GetDlgItemText(IDC_TITLE_EDIT1, tmp);
340 m_song.title = tmp;
341 }
342
343
OnEnChangeArtistEdit1()344 void CLyricDownloadDlg::OnEnChangeArtistEdit1()
345 {
346 // TODO: 如果该控件是 RICHEDIT 控件,它将不
347 // 发送此通知,除非重写 CBaseDialog::OnInitDialog()
348 // 函数并调用 CRichEditCtrl().SetEventMask(),
349 // 同时将 ENM_CHANGE 标志“或”运算到掩码中。
350
351 // TODO: 在此添加控件通知处理程序代码
352 CString tmp;
353 GetDlgItemText(IDC_ARTIST_EDIT1, tmp);
354 m_song.artist = tmp;
355 }
356
357
OnNMClickLyricDownList1(NMHDR * pNMHDR,LRESULT * pResult)358 void CLyricDownloadDlg::OnNMClickLyricDownList1(NMHDR *pNMHDR, LRESULT *pResult)
359 {
360 LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
361 // TODO: 在此添加控件通知处理程序代码
362 m_item_selected = pNMItemActivate->iItem;
363 *pResult = 0;
364 }
365
366
OnNMRClickLyricDownList1(NMHDR * pNMHDR,LRESULT * pResult)367 void CLyricDownloadDlg::OnNMRClickLyricDownList1(NMHDR *pNMHDR, LRESULT *pResult)
368 {
369 LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
370 // TODO: 在此添加控件通知处理程序代码
371 m_item_selected = pNMItemActivate->iItem;
372
373 if (IsItemSelectedValid())
374 {
375 //弹出右键菜单
376 CMenu* pContextMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::LdListMenu);
377 m_down_list_ctrl.ShowPopupMenu(pContextMenu, pNMItemActivate->iItem, this);
378 }
379
380 *pResult = 0;
381 }
382
383
OnBnClickedDownloadSelected()384 void CLyricDownloadDlg::OnBnClickedDownloadSelected()
385 {
386 // TODO: 在此添加控件通知处理程序代码
387 if (!IsItemSelectedValid())
388 return;
389
390 GetDlgItem(IDC_DOWNLOAD_SELECTED)->EnableWindow(FALSE); //点击“下载选中项”后禁用该按钮
391 GetDlgItem(IDC_SELECTED_SAVE_AS)->EnableWindow(FALSE); //点击“下载选中项”后禁用该按钮
392 SetID(m_down_list[m_item_selected].id); // 将选中项目的歌曲ID关联到歌曲
393 m_download_thread_info.hwnd = GetSafeHwnd();
394 m_download_thread_info.download_translate = m_download_translate;
395 m_download_thread_info.save_as = false;
396 m_download_thread_info.song_id = m_down_list[m_item_selected].id;
397 m_pDownThread = AfxBeginThread(LyricDownloadThreadFunc, &m_download_thread_info);
398 }
399
400
OnBnClickedSelectedSaveAs()401 void CLyricDownloadDlg::OnBnClickedSelectedSaveAs()
402 {
403 // TODO: 在此添加控件通知处理程序代码
404 if (!IsItemSelectedValid())
405 return;
406
407 GetDlgItem(IDC_DOWNLOAD_SELECTED)->EnableWindow(FALSE); //点击“下载选中项”后禁用该按钮
408 GetDlgItem(IDC_SELECTED_SAVE_AS)->EnableWindow(FALSE); //点击“下载选中项”后禁用该按钮
409 m_download_thread_info.hwnd = GetSafeHwnd();
410 m_download_thread_info.download_translate = m_download_translate;
411 m_download_thread_info.save_as = true;
412 m_download_thread_info.song_id = m_down_list[m_item_selected].id;
413 m_pDownThread = AfxBeginThread(LyricDownloadThreadFunc, &m_download_thread_info);
414 }
415
416
OnBnClickedDownloadTranslateCheck1()417 void CLyricDownloadDlg::OnBnClickedDownloadTranslateCheck1()
418 {
419 // TODO: 在此添加控件通知处理程序代码
420 m_download_translate = (m_download_translate_chk.GetCheck() != 0);
421 }
422
423
OnDestroy()424 void CLyricDownloadDlg::OnDestroy()
425 {
426 CBaseDialog::OnDestroy();
427
428 // TODO: 在此处添加消息处理程序代码
429 SaveConfig();
430 }
431
LyricSearchThreadFunc(LPVOID lpParam)432 UINT CLyricDownloadDlg::LyricSearchThreadFunc(LPVOID lpParam)
433 {
434 CCommon::SetThreadLanguageList(theApp.m_str_table.GetLanguageTag());
435 SearchThreadInfo* pInfo = (SearchThreadInfo*)lpParam;
436 wstring url = pInfo->url;
437 wstring result;
438 bool rtn = CInternetCommon::HttpPost(url, result); //向网易云音乐的歌曲搜索API发送http的POST请求
439 if (theApp.m_lyric_download_dialog_exit) return 0;
440 // 此处(以及大部分网络相关)有线程安全问题,HttpPost可能卡30s网络超时,要解决此问题CInternetSession的封装应当提供退出flag参数
441 // 此时如果歌词下载窗口关闭则pInfo会是野指针(比如关闭再打开此对话框会使得上面的检查无效)
442 pInfo->rtn = rtn;
443 pInfo->result = result;
444 ::PostMessage(pInfo->hwnd, WM_SEARCH_COMPLATE, 0, 0); //搜索完成后发送一个搜索完成的消息
445
446 return 0;
447 }
448
LyricDownloadThreadFunc(LPVOID lpParam)449 UINT CLyricDownloadDlg::LyricDownloadThreadFunc(LPVOID lpParam)
450 {
451 CCommon::SetThreadLanguageList(theApp.m_str_table.GetLanguageTag());
452 DownloadThreadInfo* pInfo = (DownloadThreadInfo*)lpParam;
453 wstring song_id = pInfo->song_id;
454 bool download_translate = pInfo->download_translate;
455 wstring result;
456 bool rtn = CLyricDownloadCommon::DownloadLyric(song_id, result, download_translate); //下载歌词
457 if (theApp.m_lyric_download_dialog_exit) return 0;
458 pInfo->success = rtn;
459 pInfo->result = result;
460 ::PostMessage(pInfo->hwnd, WM_DOWNLOAD_COMPLATE, (WPARAM)pInfo->save_as, 0); //下载完成后发送一个下载完成消息(wParam用于传递是否弹出“另存为”对话框)
461 return 0;
462 }
463
464
OnSearchComplate(WPARAM wParam,LPARAM lParam)465 afx_msg LRESULT CLyricDownloadDlg::OnSearchComplate(WPARAM wParam, LPARAM lParam)
466 {
467 //响应WM_SEARCH_CONPLATE消息
468 GetDlgItem(IDC_SEARCH_BUTTON2)->EnableWindow(TRUE); //搜索完成之后启用该按钮
469 m_search_result = m_search_thread_info.result;
470 if(m_search_thread_info.rtn != CInternetCommon::SUCCESS)
471 SetDlgItemText(IDC_STATIC_INFO, theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_INFO").c_str());
472
473 switch (m_search_thread_info.rtn)
474 {
475 case CInternetCommon::FAILURE:
476 {
477 const wstring& info = theApp.m_str_table.LoadText(L"MSG_NETWORK_SEARCH_FAILED");
478 MessageBox(info.c_str(), NULL, MB_ICONWARNING);
479 return 0;
480 }
481 case CInternetCommon::OUTTIME:
482 {
483 const wstring& info = theApp.m_str_table.LoadText(L"MSG_NETWORK_SEARCH_TIME_OUT");
484 MessageBox(info.c_str(), NULL, MB_ICONWARNING);
485 return 0;
486 }
487 default: break;
488 }
489 //DEBUG模式下,将查找返回的结果保存到文件
490 #ifdef DEBUG
491 ofstream out_put{ L".\\down.log", std::ios::binary };
492 out_put << CCommon::UnicodeToStr(m_search_result, CodeType::UTF8);
493 #endif // DEBUG
494
495 CInternetCommon::DisposeSearchResult(m_down_list, m_search_result); //处理返回的结果
496 ShowDownloadList(); //将搜索的结果显示在列表控件中
497
498 //计算搜索结果中最佳匹配项目
499 int best_matched;
500 bool id_releated{ false };
501 CSongDataManager::GetInstance().GetSongID(m_song, m_song.song_id); // 从媒体库读取id
502 if (m_song.song_id != 0) //如果当前歌曲已经有关联的ID,则根据该ID在搜索结果列表中查找对应的项目
503 {
504 for (size_t i{}; i<m_down_list.size(); i++)
505 {
506 if (m_song.GetSongId() == m_down_list[i].id)
507 {
508 id_releated = true;
509 best_matched = i;
510 break;
511 }
512 }
513 }
514 if(!id_releated)
515 best_matched = CInternetCommon::SelectMatchedItem(m_down_list, m_song.title, m_song.artist, m_song.album, m_lyric_name, true);
516 wstring info;
517 m_unassciate_lnk.ShowWindow(SW_HIDE);
518 SongInfo song_info_ori{ CSongDataManager::GetInstance().GetSongInfo3(m_song) };
519 if (m_down_list.empty())
520 {
521 song_info_ori.SetNoOnlineLyric(true);
522 CSongDataManager::GetInstance().AddItem(song_info_ori);
523 info = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_INFO_SEARCH_NO_SONG");
524 }
525 else if (best_matched == -1)
526 {
527 song_info_ori.SetNoOnlineLyric(true);
528 CSongDataManager::GetInstance().AddItem(song_info_ori);
529 info = theApp.m_str_table.LoadText(L"TXT_LYRIC_DL_INFO_SEARCH_NO_MATCHED");
530 }
531 else if(id_releated)
532 {
533 info = theApp.m_str_table.LoadTextFormat(L"TXT_LYRIC_DL_INFO_SEARCH_RELATED", { best_matched + 1 });
534 m_unassciate_lnk.ShowWindow(SW_SHOW);
535 }
536 else
537 info = theApp.m_str_table.LoadTextFormat(L"TXT_LYRIC_DL_INFO_SEARCH_BEST_MATCHED", { best_matched + 1 });
538
539 SetDlgItemText(IDC_STATIC_INFO, info.c_str());
540 //自动选中列表中最佳匹配的项目
541 m_down_list_ctrl.SetFocus();
542 m_down_list_ctrl.SetItemState(best_matched, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); //选中行
543 m_down_list_ctrl.EnsureVisible(best_matched, FALSE); //使选中行保持可见
544 m_item_selected = best_matched;
545 return 0;
546 }
547
548
OnCancel()549 void CLyricDownloadDlg::OnCancel()
550 {
551 // TODO: 在此添加专用代码和/或调用基类
552 theApp.m_lyric_download_dialog_exit = true;
553 if (m_pSearchThread != nullptr)
554 WaitForSingleObject(m_pSearchThread->m_hThread, 1000); //等待线程退出
555 if (m_pDownThread != nullptr)
556 WaitForSingleObject(m_pDownThread->m_hThread, 1000); //等待线程退出
557 CBaseDialog::OnCancel();
558 }
559
560
OnOK()561 void CLyricDownloadDlg::OnOK()
562 {
563 // TODO: 在此添加专用代码和/或调用基类
564 theApp.m_lyric_download_dialog_exit = true;
565 if (m_pSearchThread != nullptr)
566 WaitForSingleObject(m_pSearchThread->m_hThread, 1000); //等待线程退出
567 if (m_pDownThread != nullptr)
568 WaitForSingleObject(m_pDownThread->m_hThread, 1000); //等待线程退出
569 CBaseDialog::OnOK();
570 }
571
572
OnDownloadComplate(WPARAM wParam,LPARAM lParam)573 afx_msg LRESULT CLyricDownloadDlg::OnDownloadComplate(WPARAM wParam, LPARAM lParam)
574 {
575 m_lyric_str = m_download_thread_info.result;
576 GetDlgItem(IDC_DOWNLOAD_SELECTED)->EnableWindow(TRUE); //下载完成后启用该按钮
577 GetDlgItem(IDC_SELECTED_SAVE_AS)->EnableWindow(TRUE); //下载完成后启用该按钮
578 if (!m_download_thread_info.success || m_lyric_str.empty())
579 {
580 const wstring& info = theApp.m_str_table.LoadText(L"MSG_NETWORK_LYRIC_DOWNLOAD_FAILED");
581 MessageBox(info.c_str(), NULL, MB_ICONWARNING);
582 return 0;
583 }
584 if (!CLyricDownloadCommon::DisposeLryic(m_lyric_str))
585 {
586 const wstring& info = theApp.m_str_table.LoadText(L"MSG_NETWORK_SONG_NO_LYRIC");
587 MessageBox(info.c_str(), NULL, MB_ICONWARNING);
588 return 0;
589 }
590
591 CLyricDownloadCommon::AddLyricTag(m_lyric_str, m_down_list[m_item_selected].id, m_down_list[m_item_selected].title, m_down_list[m_item_selected].artist, m_down_list[m_item_selected].album);
592
593 //保存歌词
594 if (wParam == 0) //wParam为0时不弹出“另存为对话框”
595 {
596 if (!m_save_to_song_folder && !CCommon::FolderExist(theApp.m_lyric_setting_data.lyric_path))
597 {
598 const wstring& info = theApp.m_str_table.LoadText(L"MSG_LYRIC_FOLDER_NOT_EXIST");
599 MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK);
600 return 0;
601 }
602 wstring saved_path = GetSavedPath();
603 if (CCommon::FileExist(saved_path))
604 {
605 const wstring& info = theApp.m_str_table.LoadText(L"MSG_LYRIC_OVERWRITE_INQUIRY");
606 if (MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OKCANCEL) == IDCANCEL)
607 return 0;
608 }
609 if (!SaveLyric(saved_path.c_str(), m_save_code)) //保存歌词
610 return 0;
611 if (m_download_translate)
612 {
613 CLyrics lyrics{ saved_path, CLyrics::LyricType::LY_LRC_NETEASE }; //打开保存过的歌词
614 lyrics.SaveLyric2(theApp.m_general_setting_data.download_lyric_text_and_translation_in_same_line);
615 }
616
617 if (m_song.IsSameSong(CPlayer::GetInstance().GetCurrentSongInfo())) //如果正在播放的歌曲还是当前下载歌词的歌曲,才更新歌词显示
618 CPlayer::GetInstance().IniLyrics(saved_path);
619 wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_LYRIC_DOWNLOAD_COMPLETE_SAVED", { saved_path });
620 MessageBox(info.c_str(), NULL, MB_ICONINFORMATION);
621 }
622 else
623 {
624 //设置过滤器
625 wstring filter = FilterHelper::GetLyricFileFilter();
626 //构造保存文件对话框
627 CFileDialog fileDlg(FALSE, _T("lrc"), GetSavedPath().c_str(), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, filter.c_str(), this);
628 //为“另存为”对话框添加一个组合选择框
629 fileDlg.AddComboBox(IDC_SAVE_COMBO_BOX);
630 //为组合选择框添加项目
631 fileDlg.AddControlItem(IDC_SAVE_COMBO_BOX, 0, theApp.m_str_table.LoadText(L"TXT_SAVE_AS_ANSI").c_str());
632 fileDlg.AddControlItem(IDC_SAVE_COMBO_BOX, 1, theApp.m_str_table.LoadText(L"TXT_SAVE_AS_UTF8").c_str());
633 //为组合选择框设置默认选中的项目
634 fileDlg.SetSelectedControlItem(IDC_SAVE_COMBO_BOX, static_cast<int>(m_save_code));
635
636 //显示保存文件对话框
637 if (IDOK == fileDlg.DoModal())
638 {
639 DWORD selected_item;
640 fileDlg.GetSelectedControlItem(IDC_SAVE_COMBO_BOX, selected_item); //获取“编码格式”中选中的项目
641 CodeType save_code{};
642 switch (selected_item)
643 {
644 case 0: save_code = CodeType::ANSI; break;
645 case 1: save_code = CodeType::UTF8; break;
646 default: break;
647 }
648 wstring saved_path{ fileDlg.GetPathName().GetString() };
649 if (!SaveLyric(saved_path.c_str(), save_code)) //保存歌词
650 return 0;
651
652 if (m_download_translate)
653 {
654 CLyrics lyrics{ saved_path, CLyrics::LyricType::LY_LRC_NETEASE }; //打开保存过的歌词
655 lyrics.SaveLyric2(theApp.m_general_setting_data.download_lyric_text_and_translation_in_same_line);
656 }
657
658 if (m_song.IsSameSong(CPlayer::GetInstance().GetCurrentSongInfo())) //如果正在播放的歌曲还是当前下载歌词的歌曲,才更新歌词显示
659 CPlayer::GetInstance().IniLyrics(saved_path);
660 }
661 }
662 return 0;
663 }
664
665
OnBnClickedSaveToSongFolder1()666 void CLyricDownloadDlg::OnBnClickedSaveToSongFolder1()
667 {
668 // TODO: 在此添加控件通知处理程序代码
669 m_save_to_song_folder = true;
670 }
671
672
OnBnClickedSaveToLyricFolder1()673 void CLyricDownloadDlg::OnBnClickedSaveToLyricFolder1()
674 {
675 // TODO: 在此添加控件通知处理程序代码
676 m_save_to_song_folder = false;
677 }
678
679
OnCbnSelchangeCombo2()680 void CLyricDownloadDlg::OnCbnSelchangeCombo2()
681 {
682 // TODO: 在此添加控件通知处理程序代码
683 //获取组合框中选中的编码格式
684 switch (m_save_code_combo.GetCurSel())
685 {
686 case 1: m_save_code = CodeType::UTF8; break;
687 default: m_save_code = CodeType::ANSI; break;
688 }
689 }
690
691
OnLdLyricDownload()692 void CLyricDownloadDlg::OnLdLyricDownload()
693 {
694 // TODO: 在此添加命令处理程序代码
695 OnBnClickedDownloadSelected();
696 }
697
698
OnLdLyricSaveas()699 void CLyricDownloadDlg::OnLdLyricSaveas()
700 {
701 // TODO: 在此添加命令处理程序代码
702 OnBnClickedSelectedSaveAs();
703 }
704
705
OnLdCopyTitle()706 void CLyricDownloadDlg::OnLdCopyTitle()
707 {
708 // TODO: 在此添加命令处理程序代码
709 if (IsItemSelectedValid())
710 {
711 if(!CCommon::CopyStringToClipboard(m_down_list[m_item_selected].title))
712 MessageBox(theApp.m_str_table.LoadText(L"MSG_COPY_CLIPBOARD_FAILED").c_str(), NULL, MB_ICONWARNING);
713 }
714 }
715
716
OnLdCopyArtist()717 void CLyricDownloadDlg::OnLdCopyArtist()
718 {
719 // TODO: 在此添加命令处理程序代码
720 if (IsItemSelectedValid())
721 {
722 if (!CCommon::CopyStringToClipboard(m_down_list[m_item_selected].artist))
723 MessageBox(theApp.m_str_table.LoadText(L"MSG_COPY_CLIPBOARD_FAILED").c_str(), NULL, MB_ICONWARNING);
724 }
725 }
726
727
OnLdCopyAlbum()728 void CLyricDownloadDlg::OnLdCopyAlbum()
729 {
730 // TODO: 在此添加命令处理程序代码
731 if (IsItemSelectedValid())
732 {
733 if (!CCommon::CopyStringToClipboard(m_down_list[m_item_selected].album))
734 MessageBox(theApp.m_str_table.LoadText(L"MSG_COPY_CLIPBOARD_FAILED").c_str(), NULL, MB_ICONWARNING);
735 }
736 }
737
738
OnLdCopyId()739 void CLyricDownloadDlg::OnLdCopyId()
740 {
741 // TODO: 在此添加命令处理程序代码
742 if (IsItemSelectedValid())
743 {
744 if (!CCommon::CopyStringToClipboard(m_down_list[m_item_selected].id))
745 MessageBox(theApp.m_str_table.LoadText(L"MSG_COPY_CLIPBOARD_FAILED").c_str(), NULL, MB_ICONWARNING);
746 }
747 }
748
749
OnLdViewOnline()750 void CLyricDownloadDlg::OnLdViewOnline()
751 {
752 // TODO: 在此添加命令处理程序代码
753 if (IsItemSelectedValid())
754 {
755 //获取网易云音乐中该歌曲的在线接听网址
756 wstring song_url{ L"http://music.163.com/#/song?id=" + m_down_list[m_item_selected].id };
757 //打开超链接
758 ShellExecute(NULL, _T("open"), song_url.c_str(), NULL, NULL, SW_SHOW);
759 }
760 }
761
762 //双击列表项目后下载选中项目
OnNMDblclkLyricDownList1(NMHDR * pNMHDR,LRESULT * pResult)763 void CLyricDownloadDlg::OnNMDblclkLyricDownList1(NMHDR *pNMHDR, LRESULT *pResult)
764 {
765 LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
766 // TODO: 在此添加控件通知处理程序代码
767 m_item_selected = pNMItemActivate->iItem;
768 if (IsItemSelectedValid())
769 {
770 OnBnClickedDownloadSelected();
771 }
772 *pResult = 0;
773 }
774
775
PreTranslateMessage(MSG * pMsg)776 BOOL CLyricDownloadDlg::PreTranslateMessage(MSG* pMsg)
777 {
778 // TODO: 在此添加专用代码和/或调用基类
779 //if (pMsg->message == WM_MOUSEMOVE)
780 // m_tool_tip.RelayEvent(pMsg);
781
782 return CBaseDialog::PreTranslateMessage(pMsg);
783 }
784
785
OnNMClickUnassociateLink(NMHDR * pNMHDR,LRESULT * pResult)786 void CLyricDownloadDlg::OnNMClickUnassociateLink(NMHDR *pNMHDR, LRESULT *pResult)
787 {
788 // TODO: 在此添加控件通知处理程序代码
789 SetID(wstring());
790 m_unassciate_lnk.ShowWindow(SW_HIDE);
791
792 *pResult = 0;
793 }
794
795
OnLdPreview()796 void CLyricDownloadDlg::OnLdPreview()
797 {
798 // TODO: 在此添加命令处理程序代码
799
800 //下载歌词
801 const CInternetCommon::ItemInfo& item{ m_down_list[m_item_selected] };
802 bool success{ false };
803 wstring result;
804 {
805 CWaitCursor wait_cursor;
806 success = CLyricDownloadCommon::DownloadLyric(item.id, result, m_download_translate); //下载歌词
807 }
808
809 //如果不成功弹出消息对话框
810 if (!success || result.empty())
811 {
812 const wstring& info = theApp.m_str_table.LoadText(L"MSG_NETWORK_LYRIC_DOWNLOAD_FAILED");
813 MessageBox(info.c_str(), NULL, MB_ICONWARNING);
814 return;
815 }
816 if (!CLyricDownloadCommon::DisposeLryic(result))
817 {
818 const wstring& info = theApp.m_str_table.LoadText(L"MSG_NETWORK_SONG_NO_LYRIC");
819 MessageBox(info.c_str(), NULL, MB_ICONWARNING);
820 return;
821 }
822
823 //添加歌词标签
824 CLyricDownloadCommon::AddLyricTag(result, item.id, item.title, item.artist, item.album);
825
826 CLyrics lyrics;
827 lyrics.LyricsFromRowString(result, CLyrics::LyricType::LY_LRC_NETEASE);
828 result = lyrics.GetLyricsString2(theApp.m_general_setting_data.download_lyric_text_and_translation_in_same_line);
829
830 // 显示预览窗口
831 CMessageDlg dlg(L"LrcPreviewDlg");
832 dlg.SetWindowTitle(theApp.m_str_table.LoadText(L"TITLE_LYRIC_PREVIEW"));
833 wstring info = item.artist + L" - " + item.title;
834 dlg.SetInfoText(info);
835 dlg.SetMessageText(result);
836 dlg.DoModal();
837 }
838
839
OnLdRelate()840 void CLyricDownloadDlg::OnLdRelate()
841 {
842 // TODO: 在此添加命令处理程序代码
843 if (m_item_selected >= 0 && m_item_selected < static_cast<int>(m_down_list.size()))
844 {
845 SetID(m_down_list[m_item_selected].id); // 将选中项目的歌曲ID关联到歌曲
846 }
847 }
848