xref: /MusicPlayer2/MusicPlayer2/LyricDownloadDlg.cpp (revision 9c4ef8a8f2876557772f84b85d0eb04ab8fa8c61)
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