1 // FormatConvertDlg.cpp: 实现文件
2 //
3
4 #include "stdafx.h"
5 #include "MusicPlayer2.h"
6 #include "Player.h"
7 #include "FormatConvertDlg.h"
8 #include "BassCore.h"
9 #include "MusicPlayerCmdHelper.h"
10 #include "SongDataManager.h"
11 #include "FileNameFormDlg.h"
12 #include "MP3EncodeCfgDlg.h"
13 #include "WmaEncodeCfgDlg.h"
14 #include "OggEncodeCfgDlg.h"
15 #include "FlacEncodeCfgDlg.h"
16 #include "FilterHelper.h"
17 #include "IniHelper.h"
18 #include "TagEditDlg.h"
19
20 #define MAX_ALBUM_COVER_SIZE (128 * 1024) //编码器支持的最大专辑封面大小
21 #define CONVERT_TEMP_ALBUM_COVER_NAME L"cover_R1hdyFy6CoEK7Gu8" //临时的专辑封面文件名
22 #define COMPRESSED_ALBUM_COVER_PIXEL 512 //要将专辑封面图片压缩的尺寸
23
24
GetCueDisplayFileName(const wstring & title,const wstring & artist)25 static wstring GetCueDisplayFileName(const wstring& title, const wstring& artist)
26 {
27 wstring str;
28 if (!artist.empty() && !title.empty())
29 str = artist + L" - " + title;
30 else
31 str = artist + title;
32 return str;
33 }
34
35 //////////////////////////////////////////////////////////////////////////
36
37 // CFormatConvertDlg 对话框
38
IMPLEMENT_DYNAMIC(CFormatConvertDlg,CBaseDialog)39 IMPLEMENT_DYNAMIC(CFormatConvertDlg, CBaseDialog)
40
41 CFormatConvertDlg::CFormatConvertDlg(CWnd* pParent /*=nullptr*/)
42 : CBaseDialog(IDD_FORMAT_CONVERT_DIALOG, pParent)
43 {
44 }
45
CFormatConvertDlg(const vector<SongInfo> & items,CWnd * pParent)46 CFormatConvertDlg::CFormatConvertDlg(const vector<SongInfo>& items, CWnd* pParent /*=nullptr*/)
47 : CBaseDialog(IDD_FORMAT_CONVERT_DIALOG, pParent)
48 {
49 //获取文件列表
50 for (SongInfo item : items)
51 {
52 item.Normalize();
53 m_file_list.push_back(std::move(item));
54 }
55 // 确保音频文件信息更新到媒体库,并解析cue,(对于大量不存在于媒体库的新文件此方法很慢)
56 int cnt{}, percent{};
57 bool exit_flag{ false };
58 CAudioCommon::GetAudioInfo(m_file_list, cnt, exit_flag, percent, MR_MIN_REQUIRED, false);
59 // 去重
60 std::unordered_set<SongKey> song_key;
61 song_key.reserve(m_file_list.size());
62 auto new_end = std::remove_if(m_file_list.begin(), m_file_list.end(),
63 [&](const SongInfo& song) { return !song_key.emplace(song).second; }); // emplace失败说明此项目已存在,返回true移除当前项目
64 m_file_list.erase(new_end, m_file_list.end());
65 // 加载歌曲信息(与播放列表一致)
66 CSongDataManager::GetInstance().LoadSongsInfo(m_file_list);
67
68 //如果文件是 MIDI 音乐,则把SF2音色库信息添加到注释信息
69 wstring midi_comment = L"Converted from MIDI by MusicPlayer2. SF2: " + CPlayer::GetInstance().GetSoundFontName();
70 for (auto& song : m_file_list)
71 {
72 if (CAudioCommon::GetAudioTypeByFileName(song.file_path) == AU_MIDI)
73 song.comment = midi_comment;
74 }
75
76 m_freq_map.emplace_back(L"8 kHz", 8000);
77 m_freq_map.emplace_back(L"16 kHz", 16000);
78 m_freq_map.emplace_back(L"22 kHz", 22050);
79 m_freq_map.emplace_back(L"24 kHz", 24000);
80 m_freq_map.emplace_back(L"32 kHz", 32000);
81 m_freq_map.emplace_back(L"44.1 kHz", 44100);
82 m_freq_map.emplace_back(L"48 kHz", 48000);
83 }
84
~CFormatConvertDlg()85 CFormatConvertDlg::~CFormatConvertDlg()
86 {
87 CPlayer::GetInstance().GetPlayerCore()->UnInitEncoder();
88 }
89
GetDialogName() const90 CString CFormatConvertDlg::GetDialogName() const
91 {
92 return _T("FormatConvertDlg");
93
94 }
95
InitializeControls()96 bool CFormatConvertDlg::InitializeControls()
97 {
98 wstring temp;
99 temp = theApp.m_str_table.LoadText(L"TITLE_FORMAT_CONVERT");
100 SetWindowTextW(temp.c_str());
101 temp = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_OUT_FORMAT_SEL");
102 SetDlgItemTextW(IDC_TXT_FORMAT_CONVERT_OUT_FORMAT_SEL_STATIC, temp.c_str());
103 // IDC_OUT_FORMAT_COMBO
104 temp = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_SETTING");
105 SetDlgItemTextW(IDC_ENCODER_CONFIG_BUTTON, temp.c_str());
106 temp = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_FILE_LIST");
107 SetDlgItemTextW(IDC_TXT_FORMAT_CONVERT_FILE_LIST_STATIC, temp.c_str());
108 // IDC_SONG_LIST1
109 temp = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_OPT");
110 SetDlgItemTextW(IDC_TXT_FORMAT_CONVERT_OPT_STATIC, temp.c_str());
111 temp = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_CHANGE_FREQ");
112 SetDlgItemTextW(IDC_CHANGE_FREQ_CHECK, temp.c_str());
113 // IDC_FREQ_COMBO
114 temp = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_COPY_TAG");
115 SetDlgItemTextW(IDC_COPY_TAG_CHECK, temp.c_str());
116 temp = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_COPY_COVER");
117 SetDlgItemTextW(IDC_COPY_ALBUM_COVER_CHECK, temp.c_str());
118 temp = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_OUT_FILE_NAME");
119 SetDlgItemTextW(IDC_TXT_FORMAT_CONVERT_OUT_FILE_NAME_STATIC, temp.c_str());
120 // IDC_OUT_NAME_EDIT
121 temp = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_ADD_SERIAL_NUMBER");
122 SetDlgItemTextW(IDC_ADD_NUMBER_CHECK, temp.c_str());
123 temp = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_FILE_EXIST_SEL");
124 SetDlgItemTextW(IDC_TXT_FORMAT_CONVERT_FILE_EXIST_SEL_STATIC, temp.c_str());
125 // IDC_TARGET_FILE_EXIST_COMBO
126 temp = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_OUT_DIR");
127 SetDlgItemTextW(IDC_TXT_FORMAT_CONVERT_OUT_DIR_STATIC, temp.c_str());
128 // IDC_OUT_DIR_EDIT
129 temp = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_OUT_DIR_OPEN_WHEN_COMPLETE");
130 SetDlgItemTextW(IDC_OPEN_TARGET_DIR_CHECK, temp.c_str());
131 temp = L"";
132 SetDlgItemTextW(IDC_PROGRESS_BAR, temp.c_str()); // 此控件持有的文本会影响接下来的重排,需要先清空
133 SetDlgItemTextW(IDC_PROGRESS_TEXT, temp.c_str());
134 temp = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_START_CONVERT");
135 SetDlgItemTextW(IDC_START_CONVERT_BUTTON, temp.c_str());
136 // IDCANCEL
137
138 RepositionTextBasedControls({
139 { CtrlTextInfo::L1, IDC_TXT_FORMAT_CONVERT_OUT_FORMAT_SEL_STATIC },
140 { CtrlTextInfo::C0, IDC_OUT_FORMAT_COMBO },
141 { CtrlTextInfo::R1, IDC_ENCODER_CONFIG_BUTTON, CtrlTextInfo::W32 }
142 }, CtrlTextInfo::W128);
143 RepositionTextBasedControls({
144 { CtrlTextInfo::L2, IDC_CHANGE_FREQ_CHECK, CtrlTextInfo::W32 },
145 { CtrlTextInfo::L1, IDC_FREQ_COMBO }
146 });
147 RepositionTextBasedControls({
148 { CtrlTextInfo::L1, IDC_TXT_FORMAT_CONVERT_OUT_FILE_NAME_STATIC },
149 { CtrlTextInfo::C0, IDC_OUT_NAME_EDIT },
150 { CtrlTextInfo::L1, IDC_TXT_FORMAT_CONVERT_OUT_DIR_STATIC },
151 { CtrlTextInfo::C0, IDC_OUT_DIR_EDIT }
152 }, CtrlTextInfo::W128);
153 RepositionTextBasedControls({
154 { CtrlTextInfo::L1, IDC_PROGRESS_BAR },
155 { CtrlTextInfo::C0, IDC_PROGRESS_TEXT },
156 { CtrlTextInfo::R1, IDC_START_CONVERT_BUTTON, CtrlTextInfo::W32 },
157 { CtrlTextInfo::R2, IDCANCEL, CtrlTextInfo::W32 }
158 }, CtrlTextInfo::W128);
159 return true;
160 }
161
DoDataExchange(CDataExchange * pDX)162 void CFormatConvertDlg::DoDataExchange(CDataExchange* pDX)
163 {
164 CBaseDialog::DoDataExchange(pDX);
165 DDX_Control(pDX, IDC_SONG_LIST1, m_file_list_ctrl);
166 DDX_Control(pDX, IDC_OUT_FORMAT_COMBO, m_encode_format_combo);
167 DDX_Control(pDX, IDC_PROGRESS_BAR, m_progress_bar);
168 DDX_Control(pDX, IDC_FREQ_COMBO, m_freq_comb);
169 DDX_Control(pDX, IDC_OUT_DIR_EDIT, m_out_dir_edit);
170 DDX_Control(pDX, IDC_OUT_NAME_EDIT, m_out_name_edit);
171 }
172
LoadConfig()173 void CFormatConvertDlg::LoadConfig()
174 {
175 CIniHelper ini(theApp.m_config_path);
176 m_encode_format = static_cast<EncodeFormat>(ini.GetInt(L"format_convert", L"encode_format", 1));
177 m_write_tag = ini.GetBool(L"format_convert", L"write_tag", true);
178 m_write_album_cover = ini.GetBool(L"format_convert", L"write_album_cover", true);
179 m_file_exist_action = ini.GetInt(L"format_convert", L"file_exist_action", 0);
180 m_add_file_serial_num = ini.GetBool(L"format_convert", L"add_file_serial_num", false);
181 m_out_dir = ini.GetString(L"format_convert", L"out_dir", L"");
182 if (!CCommon::FolderExist(m_out_dir)) //如果读取到的目录不存在,则设置为“我的文档”目录
183 {
184 m_out_dir = CCommon::GetSpecialDir(CSIDL_MYDOCUMENTS);
185 }
186 m_out_name = ini.GetString(L"format_convert", L"out_name_formular", CFileNameFormDlg::FORMULAR_ORIGINAL.c_str());
187 m_convert_freq = ini.GetBool(L"format_convert", L"convert_freq", false);
188 m_freq_sel = ini.GetString(L"format_convert", L"freq_sel", L"");
189 m_open_output_dir = ini.GetBool(L"format_convert", L"open_output_dir", false);
190 }
191
SaveConfig() const192 void CFormatConvertDlg::SaveConfig() const
193 {
194 CIniHelper ini(theApp.m_config_path);
195 ini.WriteInt(L"format_convert", L"encode_format", static_cast<int>(m_encode_format));
196 ini.WriteBool(L"format_convert", L"write_tag", m_write_tag);
197 ini.WriteBool(L"format_convert", L"write_album_cover", m_write_album_cover);
198 ini.WriteInt(L"format_convert", L"file_exist_action", m_file_exist_action);
199 ini.WriteBool(L"format_convert", L"add_file_serial_num", m_add_file_serial_num);
200 ini.WriteString(L"format_convert", L"out_dir", m_out_dir);
201 ini.WriteString(L"format_convert", L"out_name_formular", m_out_name);
202 ini.WriteBool(L"format_convert", L"convert_freq", m_convert_freq);
203 ini.WriteString(L"format_convert", L"freq_sel", m_freq_sel);
204 ini.WriteBool(L"format_convert", L"open_output_dir", m_open_output_dir);
205 ini.Save();
206 }
207
LoadEncoderConfig()208 void CFormatConvertDlg::LoadEncoderConfig()
209 {
210 CIniHelper ini(theApp.m_config_dir + L"Encoder\\encoder.ini");
211
212 m_mp3_encode_para.encode_type = ini.GetInt(L"mp3_encoder", L"encode_type", 0);
213 m_mp3_encode_para.cbr_bitrate = ini.GetInt(L"mp3_encoder", L"cbr_bitrate", 128);
214 m_mp3_encode_para.abr_bitrate = ini.GetInt(L"mp3_encoder", L"abr_bitrate", 128);
215 m_mp3_encode_para.vbr_quality = ini.GetInt(L"mp3_encoder", L"vbr_quality", 4);
216 m_mp3_encode_para.cmd_para = ini.GetString(L"mp3_encoder", L"cmd_para", L"");
217 m_mp3_encode_para.joint_stereo = ini.GetBool(L"mp3_encoder", L"joint_stereo", true);
218 if (m_mp3_encode_para.encode_type == 3) // 旧版兼容
219 {
220 m_mp3_encode_para.encode_type = 0;
221 m_mp3_encode_para.cmd_para.clear();
222 }
223 if (!m_mp3_encode_para.cmd_para.empty())
224 {
225 m_mp3_encode_para.user_define_para = true;
226 }
227 CMP3EncodeCfgDlg::EncodeParaToCmdline(m_mp3_encode_para);
228
229 m_wma_encode_para.cbr = ini.GetBool(L"wma_encoder", L"cbr", true);
230 m_wma_encode_para.cbr_bitrate = ini.GetInt(L"wma_encoder", L"cbr_bitrate", 64);
231 m_wma_encode_para.vbr_quality = ini.GetInt(L"wma_encoder", L"vbr_quality", 75);
232
233 m_ogg_encode_para.encode_quality = ini.GetInt(L"ogg_encoder", L"quality", 4);
234
235 m_flac_encode_para.compression_level = ini.GetInt(L"flac_encoder", L"compression_level", 8);
236 m_flac_encode_para.user_define_para = ini.GetBool(L"flac_encoder", L"user_define_para", false);
237 m_flac_encode_para.cmd_para = ini.GetString(L"flac_encoder", L"cmd_para", L"");
238 }
239
SaveEncoderConfig() const240 void CFormatConvertDlg::SaveEncoderConfig() const
241 {
242 std::wstring encoder_dir = theApp.m_config_dir + L"Encoder\\";
243 CCommon::CreateDir(encoder_dir);
244 CIniHelper ini(encoder_dir + L"encoder.ini");
245
246 ini.WriteInt(L"mp3_encoder", L"encode_type", m_mp3_encode_para.encode_type);
247 ini.WriteInt(L"mp3_encoder", L"cbr_bitrate", m_mp3_encode_para.cbr_bitrate);
248 ini.WriteInt(L"mp3_encoder", L"abr_bitrate", m_mp3_encode_para.abr_bitrate);
249 ini.WriteInt(L"mp3_encoder", L"vbr_quality", m_mp3_encode_para.vbr_quality);
250 ini.WriteString(L"mp3_encoder", L"cmd_para", m_mp3_encode_para.user_define_para ? m_mp3_encode_para.cmd_para : L"");
251 ini.WriteBool(L"mp3_encoder", L"joint_stereo", m_mp3_encode_para.joint_stereo);
252
253 ini.WriteBool(L"wma_encoder", L"cbr", m_wma_encode_para.cbr);
254 ini.WriteInt(L"wma_encoder", L"cbr_bitrate", m_wma_encode_para.cbr_bitrate);
255 ini.WriteInt(L"wma_encoder", L"vbr_quality", m_wma_encode_para.vbr_quality);
256
257 ini.WriteInt(L"ogg_encoder", L"quality", m_ogg_encode_para.encode_quality);
258
259 ini.WriteInt(L"flac_encoder", L"compression_level", m_flac_encode_para.compression_level);
260 ini.WriteBool(L"flac_encoder", L"user_define_para", m_flac_encode_para.user_define_para);
261 ini.WriteString(L"flac_encoder", L"cmd_para", m_flac_encode_para.cmd_para);
262
263 ini.Save();
264 }
265
266
BEGIN_MESSAGE_MAP(CFormatConvertDlg,CBaseDialog)267 BEGIN_MESSAGE_MAP(CFormatConvertDlg, CBaseDialog)
268 ON_CBN_SELCHANGE(IDC_OUT_FORMAT_COMBO, &CFormatConvertDlg::OnCbnSelchangeOutFormatCombo)
269 ON_BN_CLICKED(IDC_START_CONVERT_BUTTON, &CFormatConvertDlg::OnBnClickedStartConvertButton)
270 //ON_BN_CLICKED(IDC_BROWSE_BUTTON, &CFormatConvertDlg::OnBnClickedBrowseButton)
271 ON_MESSAGE(WM_CONVERT_PROGRESS, &CFormatConvertDlg::OnConvertProgress)
272 ON_MESSAGE(WM_CONVERT_COMPLETE, &CFormatConvertDlg::OnConvertComplete)
273 ON_WM_CLOSE()
274 ON_BN_CLICKED(IDC_ENCODER_CONFIG_BUTTON, &CFormatConvertDlg::OnBnClickedEncoderConfigButton)
275 ON_WM_GETMINMAXINFO()
276 ON_BN_CLICKED(IDC_COPY_TAG_CHECK, &CFormatConvertDlg::OnBnClickedCopyTagCheck)
277 ON_BN_CLICKED(IDC_COPY_ALBUM_COVER_CHECK, &CFormatConvertDlg::OnBnClickedCopyAlbumCoverCheck)
278 ON_CBN_SELCHANGE(IDC_TARGET_FILE_EXIST_COMBO, &CFormatConvertDlg::OnCbnSelchangeTargetFileExistCombo)
279 ON_BN_CLICKED(IDC_ADD_NUMBER_CHECK, &CFormatConvertDlg::OnBnClickedAddNumberCheck)
280 ON_NOTIFY(NM_RCLICK, IDC_SONG_LIST1, &CFormatConvertDlg::OnNMRClickSongList1)
281 ON_COMMAND(ID_ADD_FILE, &CFormatConvertDlg::OnAddFile)
282 ON_COMMAND(ID_DELETE_SELECT, &CFormatConvertDlg::OnDeleteSelect)
283 ON_COMMAND(ID_CLEAR_LIST, &CFormatConvertDlg::OnClearList)
284 ON_COMMAND(ID_MOVE_UP, &CFormatConvertDlg::OnMoveUp)
285 ON_COMMAND(ID_MOVE_DOWN, &CFormatConvertDlg::OnMoveDown)
286 ON_COMMAND(ID_EDIT_TAG_INFO, &CFormatConvertDlg::OnEditTagInfo)
287 ON_WM_INITMENU()
288 ON_NOTIFY(NM_DBLCLK, IDC_SONG_LIST1, &CFormatConvertDlg::OnNMDblclkSongList1)
289 ON_BN_CLICKED(IDC_CHANGE_FREQ_CHECK, &CFormatConvertDlg::OnBnClickedChangeFreqCheck)
290 ON_CBN_SELCHANGE(IDC_FREQ_COMBO, &CFormatConvertDlg::OnCbnSelchangeFreqCombo)
291 ON_MESSAGE(WM_EDIT_BROWSE_CHANGED, &CFormatConvertDlg::OnEditBrowseChanged)
292 ON_BN_CLICKED(IDC_OPEN_TARGET_DIR_CHECK, &CFormatConvertDlg::OnBnClickedOpenTargetDirCheck)
293 END_MESSAGE_MAP()
294
295
296 // CFormatConvertDlg 消息处理程序
297
298
299 BOOL CFormatConvertDlg::OnInitDialog()
300 {
301 CBaseDialog::OnInitDialog();
302
303 // TODO: 在此添加额外的初始化
304 CenterWindow();
305
306 SetIcon(IconMgr::IconType::IT_Convert, FALSE);
307 SetIcon(IconMgr::IconType::IT_Convert, TRUE);
308 SetButtonIcon(IDC_ENCODER_CONFIG_BUTTON, IconMgr::IconType::IT_Setting);
309 SetButtonIcon(IDC_START_CONVERT_BUTTON, IconMgr::IconType::IT_Convert);
310
311 LoadConfig();
312 LoadEncoderConfig();
313
314 m_encoder_succeed = InitEncoder();
315 if (!CPlayer::GetInstance().GetPlayerCore()->IsFreqConvertAvailable())
316 m_convert_freq = false;
317
318 //初始化文件列表
319 CRect rect;
320 m_file_list_ctrl.GetWindowRect(rect);
321 int width0{ theApp.DPI(40) }, width1, width2{ theApp.DPI(65) };
322 width1 = rect.Width() - width0 - width2 - theApp.DPI(20) - 1;
323 //插入列
324 m_file_list_ctrl.SetExtendedStyle(m_file_list_ctrl.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_LABELTIP);
325 m_file_list_ctrl.InsertColumn(0, theApp.m_str_table.LoadText(L"TXT_SERIAL_NUMBER").c_str(), LVCFMT_LEFT, width0);
326 m_file_list_ctrl.InsertColumn(1, theApp.m_str_table.LoadText(L"TXT_FILE_NAME").c_str(), LVCFMT_LEFT, width1);
327 m_file_list_ctrl.InsertColumn(2, theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_STAUS").c_str(), LVCFMT_LEFT, width2);
328 //插入项目
329 ShowFileList();
330 //设置主题颜色
331 //m_file_list_ctrl.SetColor(theApp.m_app_setting_data.theme_color);
332
333 //初始化转换格式的下拉列表
334 m_encode_format_combo.AddString(_T("WAV"));
335 m_encode_format_combo.AddString(theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_ENCODER_NAME_MP3_LAME").c_str());
336 m_encode_format_combo.AddString(_T("WMA"));
337 m_encode_format_combo.AddString(_T("OGG"));
338 m_encode_format_combo.AddString(_T("FLAC"));
339 m_encode_format_combo.SetCurSel(static_cast<int>(m_encode_format));
340
341 //初始化选项控件的状态
342 ((CButton*)GetDlgItem(IDC_COPY_TAG_CHECK))->SetCheck(m_write_tag);
343 ((CButton*)GetDlgItem(IDC_COPY_ALBUM_COVER_CHECK))->SetCheck(m_write_album_cover);
344 ((CButton*)GetDlgItem(IDC_ADD_NUMBER_CHECK))->SetCheck(m_add_file_serial_num);
345 CComboBox* file_exist_combo = (CComboBox*)GetDlgItem(IDC_TARGET_FILE_EXIST_COMBO);
346 file_exist_combo->AddString(theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_FILE_EXIST_AUTO_RENAME").c_str());
347 file_exist_combo->AddString(theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_FILE_EXIST_IGNORE").c_str());
348 file_exist_combo->AddString(theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_FILE_EXIST_OVERWRITE").c_str());
349 file_exist_combo->SetCurSel(m_file_exist_action);
350 ((CButton*)GetDlgItem(IDC_OPEN_TARGET_DIR_CHECK))->SetCheck(m_open_output_dir);
351
352 int freq_comb_sel{ -1 };
353 for (size_t i{}; i < m_freq_map.size(); ++i)
354 {
355 m_freq_comb.AddString(m_freq_map[i].first.c_str());
356 if (m_freq_map[i].first == m_freq_sel)
357 freq_comb_sel = i;
358 if (m_freq_map[i].second == 44100) // 默认值
359 m_freq_comb.SetCurSel(i);
360 }
361 if (freq_comb_sel != -1)
362 m_freq_comb.SetCurSel(freq_comb_sel);
363 m_freq_comb.EnableWindow(m_convert_freq);
364 ((CButton*)GetDlgItem(IDC_CHANGE_FREQ_CHECK))->SetCheck(m_convert_freq);
365
366 m_out_name_edit.SetWindowText(m_out_name.c_str());
367 m_out_name_edit.SetEditBrowseMode(CBrowseEdit::EditBrowseMode::RENAME);
368
369 if (!m_out_dir.empty() && m_out_dir.back() != L'\\')
370 m_out_dir.push_back(L'\\');
371 m_out_dir_edit.SetWindowText(m_out_dir.c_str());
372 m_out_dir_edit.EnableFolderBrowseButton(theApp.m_str_table.LoadText(L"TITLE_FOLDER_BROWSER_OUTPUT_FOLDER").c_str());
373 m_progress_bar.SetBackgroundColor(GetSysColor(COLOR_BTNFACE));
374 m_progress_bar.ShowWindow(SW_HIDE);
375
376 SetEncodeConfigBtnState();
377
378 //#ifndef COMPILE_IN_WIN_XP
379 // if (CWinVersionHelper::IsWindows7OrLater())
380 // CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&m_pTaskbar)); //创建ITaskbarList3的实例
381 //#endif
382
383 return TRUE; // return TRUE unless you set the focus to a control
384 // 异常: OCX 属性页应返回 FALSE
385 }
386
387
EnableControls(bool enable)388 void CFormatConvertDlg::EnableControls(bool enable)
389 {
390 GetDlgItem(IDC_OUT_FORMAT_COMBO)->EnableWindow(enable);
391 GetDlgItem(IDC_START_CONVERT_BUTTON)->EnableWindow(enable);
392 GetDlgItem(IDC_ENCODER_CONFIG_BUTTON)->EnableWindow(enable);
393 GetDlgItem(IDC_COPY_TAG_CHECK)->EnableWindow(enable);
394 GetDlgItem(IDC_TARGET_FILE_EXIST_COMBO)->EnableWindow(enable);
395 GetDlgItem(IDC_COPY_ALBUM_COVER_CHECK)->EnableWindow(enable);
396 GetDlgItem(IDC_ADD_NUMBER_CHECK)->EnableWindow(enable);
397 GetDlgItem(IDC_CHANGE_FREQ_CHECK)->EnableWindow(enable);
398 m_freq_comb.EnableWindow(enable && m_convert_freq);
399 GetDlgItem(IDC_OUT_DIR_EDIT)->EnableWindow(enable);
400 GetDlgItem(IDC_OUT_NAME_EDIT)->EnableWindow(enable);
401 }
402
SetEncodeConfigBtnState()403 void CFormatConvertDlg::SetEncodeConfigBtnState()
404 {
405 GetDlgItem(IDC_ENCODER_CONFIG_BUTTON)->EnableWindow(m_encode_format != EncodeFormat::WAV);
406 }
407
ShowFileList()408 void CFormatConvertDlg::ShowFileList()
409 {
410 m_file_list_ctrl.DeleteAllItems();
411 for (size_t i{}; i < m_file_list.size(); i++)
412 {
413 CString tmp;
414 tmp.Format(_T("%d"), i + 1);
415 m_file_list_ctrl.InsertItem(i, tmp);
416 if (!m_file_list[i].is_cue)
417 {
418 CFilePathHelper file_path(m_file_list[i].file_path);
419 m_file_list_ctrl.SetItemText(i, 1, file_path.GetFileName().c_str());
420 }
421 else
422 {
423 m_file_list_ctrl.SetItemText(i, 1, GetCueDisplayFileName(m_file_list[i].title, m_file_list[i].artist).c_str());
424 }
425 }
426 }
427
InitEncoder()428 bool CFormatConvertDlg::InitEncoder()
429 {
430 return CPlayer::GetInstance().GetPlayerCore()->InitEncoder();
431 }
432
EncodeSingleFile(CFormatConvertDlg * pthis,int file_index)433 bool CFormatConvertDlg::EncodeSingleFile(CFormatConvertDlg* pthis, int file_index)
434 {
435 //设置输出文件路径
436 SongInfo& song_info{ pthis->m_file_list[file_index] };
437
438 // 输出文件路径
439 wstring out_file_path{ pthis->m_out_dir };
440
441 // 为目标文件添加序号
442 if (pthis->m_add_file_serial_num)
443 {
444 CString index_str;
445 if (pthis->m_file_list.size() < 10)
446 index_str.Format(_T("%d."), file_index + 1);
447 else if (pthis->m_file_list.size() < 100)
448 index_str.Format(_T("%02d."), file_index + 1);
449 else
450 index_str.Format(_T("%03d."), file_index + 1);
451 out_file_path += index_str;
452 }
453
454 // 按照格式字符串生成输出文件名(这里缺少长度检查)
455 out_file_path += CFileNameFormDlg::FileNameFromTag(pthis->m_out_name, song_info);
456
457 // 按照输出格式添加后缀
458 switch (pthis->m_encode_format)
459 {
460 case EncodeFormat::WAV:
461 out_file_path += L".wav";
462 break;
463 case EncodeFormat::MP3:
464 out_file_path += L".mp3";
465 break;
466 case EncodeFormat::WMA:
467 out_file_path += L".wma";
468 break;
469 case EncodeFormat::OGG:
470 out_file_path += L".ogg";
471 break;
472 case EncodeFormat::FLAC:
473 out_file_path += L".flac";
474 break;
475 }
476
477 //判断目标文件是否存在
478 if (pthis->m_file_exist_action == 0) //如果设置了“目标文件存在时自动重命名”,自动在文件名后面添加形如“ (数字)”的编号
479 {
480 CCommon::FileAutoRename(out_file_path);
481 }
482 else if (pthis->m_file_exist_action == 1) //如果设置了“目标文件存在时忽略”
483 {
484 if (CCommon::FileExist(out_file_path))
485 {
486 ::PostMessage(pthis->GetSafeHwnd(), WM_CONVERT_PROGRESS, file_index, 102);
487 return false;
488 }
489 }
490
491 void* para{};
492 switch (pthis->m_encode_format)
493 {
494 case EncodeFormat::MP3:
495 para = &pthis->m_mp3_encode_para;
496 break;
497 case EncodeFormat::WMA:
498 para = &pthis->m_wma_encode_para;
499 break;
500 case EncodeFormat::OGG:
501 para = &pthis->m_ogg_encode_para;
502 break;
503 case EncodeFormat::FLAC:
504 para = &pthis->m_flac_encode_para;
505 default:
506 break;
507
508 }
509
510 int freq{};
511 if (CPlayer::GetInstance().GetPlayerCore()->IsFreqConvertAvailable() && pthis->m_convert_freq)
512 freq = pthis->GetFreq();
513
514 static int _file_index{};
515 _file_index = file_index;
516 static CFormatConvertDlg* _pthis{};
517 _pthis = pthis;
518 //执行转换格式
519 if (!CPlayer::GetInstance().GetPlayerCore()->EncodeAudio(song_info, out_file_path, pthis->m_encode_format, para, freq, [](int progress)
520 {
521 ::PostMessage(_pthis->GetSafeHwnd(), WM_CONVERT_PROGRESS, _file_index, progress);
522 }))
523 return false;
524
525 //转换完成后向目标文件写入标签信息和专辑封面
526 SongInfo song_info_out{ song_info };
527 song_info_out.file_path = out_file_path;
528 song_info_out.is_cue = false;
529 //写入标签信息
530 if (pthis->m_write_tag)
531 {
532 CAudioTag audio_tag_out(song_info_out);
533 audio_tag_out.WriteAudioTag();
534 }
535 //写入专辑封面
536 if (pthis->m_write_album_cover)
537 {
538 //获取原始文件的专辑封面
539 SongInfo song_info_tmp;
540 song_info_tmp.file_path = song_info.file_path;
541 CAudioTag audio_tag(song_info_tmp);
542 int cover_type;
543 wstring album_cover_path = audio_tag.GetAlbumCover(cover_type, ALBUM_COVER_NAME_ENCODE);
544 CImage image;
545 image.Load(album_cover_path.c_str());
546 if (image.IsNull()) //如果没有内嵌的专辑封面,则获取外部封面
547 {
548 CMusicPlayerCmdHelper helper;
549 album_cover_path = helper.SearchAlbumCover(song_info);
550 }
551 else
552 image.Destroy();
553 //将专辑封面写入目标文件
554 if (!album_cover_path.empty())
555 {
556 CAudioTag audio_tag_out(song_info_out);
557 audio_tag_out.WriteAlbumCover(album_cover_path);
558 }
559 }
560
561 return true;
562 }
563
564
SetProgressInfo(int progress)565 void CFormatConvertDlg::SetProgressInfo(int progress)
566 {
567 wstring info;
568 if (progress >= 100)
569 info = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_PROGRESS_INFO_COMPLETE");
570 else
571 info = theApp.m_str_table.LoadTextFormat(L"TXT_FORMAT_CONVERT_PROGRESS_INFO", { progress });
572 SetDlgItemText(IDC_PROGRESS_TEXT, info.c_str());
573 }
574
GetFreq()575 int CFormatConvertDlg::GetFreq()
576 {
577 int sel_index = m_freq_comb.GetCurSel();
578 return m_freq_map[sel_index].second;
579 }
580
ThreadFunc(LPVOID lpParam)581 UINT CFormatConvertDlg::ThreadFunc(LPVOID lpParam)
582 {
583 CCommon::SetThreadLanguageList(theApp.m_str_table.GetLanguageTag());
584 CFormatConvertDlg* pThis{ (CFormatConvertDlg*)lpParam };
585 for (size_t i{}; i < pThis->m_file_list.size(); i++)
586 {
587 if (theApp.m_format_convert_dialog_exit)
588 return 0;
589 //编码文件
590 if (EncodeSingleFile(pThis, i))
591 ::PostMessage(pThis->GetSafeHwnd(), WM_CONVERT_PROGRESS, i, 101);
592 }
593 ::PostMessage(pThis->GetSafeHwnd(), WM_CONVERT_COMPLETE, 0, 0);
594 return 0;
595 }
596
597
OnCbnSelchangeOutFormatCombo()598 void CFormatConvertDlg::OnCbnSelchangeOutFormatCombo()
599 {
600 // TODO: 在此添加控件通知处理程序代码
601 m_encode_format = static_cast<EncodeFormat>(m_encode_format_combo.GetCurSel());
602 SetEncodeConfigBtnState();
603 }
604
605
OnBnClickedStartConvertButton()606 void CFormatConvertDlg::OnBnClickedStartConvertButton()
607 {
608 // TODO: 在此添加控件通知处理程序代码
609 m_progress_bar.ShowWindow(SW_SHOW);
610 m_progress_bar.SetProgress(0);
611 SetProgressInfo(0);
612 if (!m_encoder_succeed)
613 {
614 CBassCore* bass_core = dynamic_cast<CBassCore*>(CPlayer::GetInstance().GetPlayerCore());
615 wstring info;
616 if (bass_core != nullptr)
617 info = theApp.m_str_table.LoadTextFormat(L"MSG_FORMAT_CONVERT_BASS_LOAD_ERROR", { bass_core->GetEncoderDir() + L"bassenc.dll" });
618 else
619 info = theApp.m_str_table.LoadText(L"MSG_FORMAT_CONVERT_INIT_ERROR");
620 MessageBox(info.c_str(), NULL, MB_ICONERROR | MB_OK);
621 return;
622 }
623
624 if (m_out_dir.empty())
625 {
626 const wstring& info = theApp.m_str_table.LoadText(L"MSG_FORMAT_CONVERT_SET_OUTPUT_DIR");
627 MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK);
628 return;
629 }
630 else if (!CCommon::FolderExist(m_out_dir))
631 {
632 wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_FORMAT_CONVERT_OUTPUT_DIR_NOT_EXIST", { m_out_dir });
633 MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK);
634 }
635
636 //先清除“状态”一列的内容
637 for (size_t i{}; i < m_file_list.size(); i++)
638 {
639 m_file_list_ctrl.SetItemText(i, 2, _T(""));
640 }
641
642 EnableControls(false);
643 theApp.m_format_convert_dialog_exit = false;
644 //创建格式转换的工作线程
645 m_pThread = AfxBeginThread(ThreadFunc, this);
646 m_thread_runing = true;
647 if (theApp.IsTaskbarInteractionEnabled())
648 theApp.GetITaskbarList3()->SetProgressState(this->GetSafeHwnd(), TBPF_INDETERMINATE);
649 }
650
651
OnConvertProgress(WPARAM wParam,LPARAM lParam)652 afx_msg LRESULT CFormatConvertDlg::OnConvertProgress(WPARAM wParam, LPARAM lParam)
653 {
654 wstring status_str;
655 int percent = (int)lParam;
656 if (percent == 0)
657 m_file_list_ctrl.EnsureVisible(wParam, FALSE); //转换开始时,确保当前列表项可见
658 if (percent < 0)
659 {
660 //显示错误信息
661 if (percent == CONVERT_ERROR_FILE_CANNOT_OPEN)
662 status_str = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_STAUS_ERROR_FILE_CANNOT_OPEN");
663 else if (percent == CONVERT_ERROR_ENCODE_CHANNEL_FAILED)
664 status_str = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_STAUS_ERROR_ENCODE_CHANNEL_FAILED");
665 else if (percent == CONVERT_ERROR_ENCODE_PARA_ERROR)
666 status_str = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_STAUS_ERROR_ENCODE_PARA_ERROR");
667 else if (percent == CONVERT_ERROR_MIDI_NO_SF2)
668 status_str = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_STAUS_ERROR_MIDI_NO_SF2");
669 else if (percent == CONVERT_ERROR_WMA_NO_WMP9_OR_LATER)
670 status_str = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_STAUS_ERROR_NO_WMP9_OR_LATER");
671 else if (percent == CONVERT_ERROR_WMA_NO_SUPPORTED_ENCODER)
672 status_str = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_STAUS_ERROR_NO_SUPPORTED_ENCODER");
673 else
674 status_str = theApp.m_str_table.LoadTextFormat(L"TXT_FORMAT_CONVERT_STAUS_ERROR_OTHER", { percent });
675 }
676 else if (percent == 101)
677 {
678 status_str = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_STAUS_COMPLETE");
679 }
680 else if (percent == 102)
681 {
682 status_str = theApp.m_str_table.LoadText(L"TXT_FORMAT_CONVERT_STAUS_SKIPPED");
683 }
684 else
685 {
686 status_str = std::to_wstring(static_cast<int>(lParam)) + L'%';
687 }
688 m_file_list_ctrl.SetItemText(wParam, 2, status_str.c_str());
689
690 //总体的进度
691 int position, length;
692 length = m_file_list.size() * 100;
693 position = wParam * 100 + percent;
694 if (theApp.IsTaskbarInteractionEnabled())
695 theApp.GetITaskbarList3()->SetProgressValue(this->GetSafeHwnd(), position, length);
696 int total_percent = position * 100 / length;
697 static int last_percent = -1;
698 if (last_percent != total_percent)
699 {
700 m_progress_bar.SetProgress(total_percent);
701 SetProgressInfo(total_percent);
702 last_percent = total_percent;
703 }
704
705 return 0;
706 }
707
708
OnConvertComplete(WPARAM wParam,LPARAM lParam)709 afx_msg LRESULT CFormatConvertDlg::OnConvertComplete(WPARAM wParam, LPARAM lParam)
710 {
711 EnableControls(true);
712 m_thread_runing = false;
713 m_progress_bar.SetProgress(100);
714 SetProgressInfo(100);
715
716 if (m_open_output_dir)
717 {
718 ShellExecute(NULL, _T("open"), _T("explorer"), m_out_dir.c_str(), NULL, SW_SHOWNORMAL);
719 }
720
721 return 0;
722 }
723
724
OnCancel()725 void CFormatConvertDlg::OnCancel()
726 {
727 // TODO: 在此添加专用代码和/或调用基类
728 theApp.m_format_convert_dialog_exit = true;
729 if (m_pThread != nullptr)
730 WaitForSingleObject(m_pThread->m_hThread, 2000); //等待线程退出
731
732 SaveConfig();
733 SaveEncoderConfig();
734
735 DestroyWindow();
736
737 //CBaseDialog::OnCancel();
738 }
739
740
OnOK()741 void CFormatConvertDlg::OnOK()
742 {
743 // TODO: 在此添加专用代码和/或调用基类
744 //theApp.m_format_convert_dialog_exit = true;
745 //if (m_pThread != nullptr)
746 // WaitForSingleObject(m_pThread->m_hThread, 2000); //等待线程退出
747
748 CBaseDialog::OnOK();
749 }
750
751
OnClose()752 void CFormatConvertDlg::OnClose()
753 {
754 // TODO: 在此添加消息处理程序代码和/或调用默认值
755
756 CBaseDialog::OnClose();
757 }
758
759
OnBnClickedEncoderConfigButton()760 void CFormatConvertDlg::OnBnClickedEncoderConfigButton()
761 {
762 // TODO: 在此添加控件通知处理程序代码
763 switch (m_encode_format)
764 {
765 case EncodeFormat::WAV:
766 break;
767 case EncodeFormat::MP3:
768 {
769 CMP3EncodeCfgDlg dlg;
770 dlg.m_encode_para = m_mp3_encode_para;
771 if (dlg.DoModal() == IDOK)
772 m_mp3_encode_para = dlg.m_encode_para;
773 }
774 break;
775 case EncodeFormat::WMA:
776 {
777 CWmaEncodeCfgDlg dlg;
778 dlg.m_encode_para = m_wma_encode_para;
779 if (dlg.DoModal() == IDOK)
780 m_wma_encode_para = dlg.m_encode_para;
781 }
782 break;
783 case EncodeFormat::OGG:
784 {
785 COggEncodeCfgDlg dlg;
786 dlg.m_encode_para = m_ogg_encode_para;
787 if (dlg.DoModal() == IDOK)
788 m_ogg_encode_para = dlg.m_encode_para;
789 }
790 break;
791 case EncodeFormat::FLAC:
792 {
793 CFlacEncodeCfgDlg dlg;
794 dlg.m_encode_para = m_flac_encode_para;
795 if (dlg.DoModal() == IDOK)
796 m_flac_encode_para = dlg.m_encode_para;
797 }
798 break;
799 default:
800 break;
801 }
802 }
803
804
OnBnClickedCopyTagCheck()805 void CFormatConvertDlg::OnBnClickedCopyTagCheck()
806 {
807 // TODO: 在此添加控件通知处理程序代码
808 m_write_tag = (((CButton*)GetDlgItem(IDC_COPY_TAG_CHECK))->GetCheck() != 0);
809 }
810
811
OnBnClickedCopyAlbumCoverCheck()812 void CFormatConvertDlg::OnBnClickedCopyAlbumCoverCheck()
813 {
814 // TODO: 在此添加控件通知处理程序代码
815 m_write_album_cover = (((CButton*)GetDlgItem(IDC_COPY_ALBUM_COVER_CHECK))->GetCheck() != 0);
816 }
817
818
OnCbnSelchangeTargetFileExistCombo()819 void CFormatConvertDlg::OnCbnSelchangeTargetFileExistCombo()
820 {
821 // TODO: 在此添加控件通知处理程序代码
822 m_file_exist_action = ((CComboBox*)GetDlgItem(IDC_TARGET_FILE_EXIST_COMBO))->GetCurSel();
823 }
824
825
OnBnClickedAddNumberCheck()826 void CFormatConvertDlg::OnBnClickedAddNumberCheck()
827 {
828 // TODO: 在此添加控件通知处理程序代码
829 m_add_file_serial_num = (((CButton*)GetDlgItem(IDC_ADD_NUMBER_CHECK))->GetCheck() != 0);
830 }
831
832
OnNMRClickSongList1(NMHDR * pNMHDR,LRESULT * pResult)833 void CFormatConvertDlg::OnNMRClickSongList1(NMHDR* pNMHDR, LRESULT* pResult)
834 {
835 LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
836 // TODO: 在此添加控件通知处理程序代码
837 m_item_selected = pNMItemActivate->iItem; //获取鼠标选中的项目
838 CMenu* pContextMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::FcListMenu);
839 m_file_list_ctrl.ShowPopupMenu(pContextMenu, pNMItemActivate->iItem, this);
840
841 *pResult = 0;
842 }
843
844
OnAddFile()845 void CFormatConvertDlg::OnAddFile()
846 {
847 // TODO: 在此添加命令处理程序代码
848 if (m_thread_runing)
849 return;
850 //设置过滤器
851 wstring filter = FilterHelper::GetAudioFileFilter();
852 //构造打开文件对话框
853 CFileDialog fileDlg(TRUE, NULL, NULL, OFN_ALLOWMULTISELECT, filter.c_str(), this);
854 //设置保存文件名的字符缓冲的大小为128kB(如果以平均一个文件名长度为32字节计算,最多可以打开大约4096个文件)
855 fileDlg.m_ofn.nMaxFile = 128 * 1024;
856 std::vector<wchar_t> buffer(fileDlg.m_ofn.nMaxFile);
857 fileDlg.m_ofn.lpstrFile = buffer.data();
858 //显示打开文件对话框
859 if (IDOK == fileDlg.DoModal())
860 {
861 POSITION posFile = fileDlg.GetStartPosition();
862 while (posFile != NULL)
863 {
864 CString file_path = fileDlg.GetNextPathName(posFile);
865 m_file_list.push_back(SongInfo(file_path.GetString()));
866 }
867 // 音频文件信息更新到媒体库,并解析cue,(对于大量不存在于媒体库的新文件此方法很慢)
868 int cnt{}, percent{};
869 bool exit_flag{ false };
870 CAudioCommon::GetAudioInfo(m_file_list, cnt, exit_flag, percent, MR_MIN_REQUIRED, false);
871 // 去重
872 std::unordered_set<SongKey> song_key;
873 song_key.reserve(m_file_list.size());
874 auto new_end = std::remove_if(m_file_list.begin(), m_file_list.end(),
875 [&](const SongInfo& song) { return !song_key.emplace(song).second; }); // emplace失败说明此项目已存在,返回true移除当前项目
876 m_file_list.erase(new_end, m_file_list.end());
877 // 加载歌曲信息(与播放列表一致)
878 CSongDataManager::GetInstance().LoadSongsInfo(m_file_list);
879 //如果文件是 MIDI 音乐,则把SF2音色库信息添加到注释信息
880 wstring midi_comment = L"Converted from MIDI by MusicPlayer2. SF2: " + CPlayer::GetInstance().GetSoundFontName();
881 for (auto& song : m_file_list)
882 {
883 if (CAudioCommon::GetAudioTypeByFileName(song.file_path) == AU_MIDI)
884 song.comment = midi_comment;
885 }
886 // 刷新显示
887 ShowFileList();
888 }
889 }
890
891
OnDeleteSelect()892 void CFormatConvertDlg::OnDeleteSelect()
893 {
894 // TODO: 在此添加命令处理程序代码
895 if (m_thread_runing)
896 return;
897 int select;
898 select = m_file_list_ctrl.GetCurSel(); //获取当前选中项序号
899 if (select >= 0 && select < static_cast<int>(m_file_list.size()))
900 {
901 m_file_list.erase(m_file_list.begin() + select); //删除选中项
902 ShowFileList();
903 }
904 }
905
906
OnClearList()907 void CFormatConvertDlg::OnClearList()
908 {
909 // TODO: 在此添加命令处理程序代码
910 if (m_thread_runing)
911 return;
912 m_file_list.clear();
913 m_file_list_ctrl.DeleteAllItems();
914 }
915
916
OnMoveUp()917 void CFormatConvertDlg::OnMoveUp()
918 {
919 // TODO: 在此添加命令处理程序代码
920 if (m_thread_runing)
921 return;
922 int select;
923 select = m_file_list_ctrl.GetCurSel(); //获取当前选中项序号
924 if (select < 0 || select >= static_cast<int>(m_file_list.size())) //当前选中项在索引以外
925 {
926 return;
927 }
928 else if (select > 0)
929 {
930 //交换文件列表中的选中项和前一项
931 auto temp = m_file_list[select];
932 m_file_list[select] = m_file_list[select - 1];
933 m_file_list[select - 1] = temp;
934 ShowFileList(); //上移操作完毕重新显示列表
935 m_file_list_ctrl.SetCurSel(select - 1); //设置选中项为前一项
936 }
937 }
938
939
OnMoveDown()940 void CFormatConvertDlg::OnMoveDown()
941 {
942 // TODO: 在此添加命令处理程序代码
943 if (m_thread_runing)
944 return;
945 int select;
946 select = m_file_list_ctrl.GetCurSel(); //获取当前选中项序号
947 if (select < 0 || select >= static_cast<int>(m_file_list.size())) //当前选中项在索引以外
948 {
949 return;
950 }
951 else if (select < static_cast<int>(m_file_list.size()) - 1)
952 {
953 //交换文件列表中的选中项和后一项
954 auto temp = m_file_list[select];
955 m_file_list[select] = m_file_list[select + 1];
956 m_file_list[select + 1] = temp;
957 ShowFileList(); //下移操作完毕重新显示列表
958 m_file_list_ctrl.SetCurSel(select + 1); //设置选中项为前一项
959 }
960 }
961
962
PreTranslateMessage(MSG * pMsg)963 BOOL CFormatConvertDlg::PreTranslateMessage(MSG* pMsg)
964 {
965 // TODO: 在此添加专用代码和/或调用基类
966 if (pMsg->message == WM_KEYDOWN)
967 {
968 //按下Ctrl键时
969 if (GetKeyState(VK_CONTROL) & 0x80)
970 {
971 if (pMsg->wParam == VK_UP) //按Ctr+↑上移
972 {
973 OnMoveUp();
974 return TRUE;
975 }
976 if (pMsg->wParam == VK_DOWN) //按Ctr+↓下移
977 {
978 OnMoveDown();
979 return TRUE;
980 }
981 }
982 }
983 return CBaseDialog::PreTranslateMessage(pMsg);
984 }
985
986
OnEditTagInfo()987 void CFormatConvertDlg::OnEditTagInfo()
988 {
989 // TODO: 在此添加命令处理程序代码
990 if (m_thread_runing)
991 return;
992
993 CTagEditDlg dlg(m_file_list, m_item_selected);
994 dlg.DoModal();
995 }
996
997
OnInitMenu(CMenu * pMenu)998 void CFormatConvertDlg::OnInitMenu(CMenu* pMenu)
999 {
1000 CBaseDialog::OnInitMenu(pMenu);
1001
1002 // TODO: 在此处添加消息处理程序代码
1003 bool item_selected_valid{ m_item_selected >= 0 && m_item_selected < static_cast<int>(m_file_list.size()) };
1004 pMenu->EnableMenuItem(ID_ADD_FILE, MF_BYCOMMAND | (!m_thread_runing ? MF_ENABLED : MF_GRAYED));
1005 pMenu->EnableMenuItem(ID_CLEAR_LIST, MF_BYCOMMAND | (!m_thread_runing ? MF_ENABLED : MF_GRAYED));
1006 pMenu->EnableMenuItem(ID_EDIT_TAG_INFO, MF_BYCOMMAND | ((!m_thread_runing && item_selected_valid) ? MF_ENABLED : MF_GRAYED));
1007 pMenu->EnableMenuItem(ID_DELETE_SELECT, MF_BYCOMMAND | ((!m_thread_runing && item_selected_valid) ? MF_ENABLED : MF_GRAYED));
1008 pMenu->EnableMenuItem(ID_MOVE_UP, MF_BYCOMMAND | ((!m_thread_runing && item_selected_valid) ? MF_ENABLED : MF_GRAYED));
1009 pMenu->EnableMenuItem(ID_MOVE_DOWN, MF_BYCOMMAND | ((!m_thread_runing && item_selected_valid) ? MF_ENABLED : MF_GRAYED));
1010
1011 pMenu->SetDefaultItem(ID_EDIT_TAG_INFO);
1012 }
1013
1014
OnNMDblclkSongList1(NMHDR * pNMHDR,LRESULT * pResult)1015 void CFormatConvertDlg::OnNMDblclkSongList1(NMHDR* pNMHDR, LRESULT* pResult)
1016 {
1017 LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
1018 // TODO: 在此添加控件通知处理程序代码
1019 m_item_selected = pNMItemActivate->iItem; //获取鼠标选中的项目
1020 if (m_item_selected >= 0 && m_item_selected < static_cast<int>(m_file_list.size()))
1021 OnEditTagInfo(); //双击打开“编辑标签信息”
1022
1023 *pResult = 0;
1024 }
1025
1026
OnBnClickedChangeFreqCheck()1027 void CFormatConvertDlg::OnBnClickedChangeFreqCheck()
1028 {
1029 // TODO: 在此添加控件通知处理程序代码
1030 CButton* pBtn = (CButton*)GetDlgItem(IDC_CHANGE_FREQ_CHECK);
1031 m_convert_freq = pBtn->GetCheck() != 0;
1032 if (m_convert_freq && !CPlayer::GetInstance().GetPlayerCore()->IsFreqConvertAvailable())
1033 {
1034 m_convert_freq = false;
1035 CBassCore* bass_core = dynamic_cast<CBassCore*>(CPlayer::GetInstance().GetPlayerCore());
1036 if (bass_core != nullptr)
1037 {
1038 wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_FORMAT_CONVERT_BASS_MIX_LOAD_ERROR", { bass_core->GetEncoderDir() + L"bassmix.dll" });
1039 MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK);
1040 }
1041 pBtn->SetCheck(FALSE);
1042 }
1043
1044 m_freq_comb.EnableWindow(m_convert_freq);
1045 }
1046
1047
OnCbnSelchangeFreqCombo()1048 void CFormatConvertDlg::OnCbnSelchangeFreqCombo()
1049 {
1050 // TODO: 在此添加控件通知处理程序代码
1051 CString str;
1052 m_freq_comb.GetWindowText(str);
1053 m_freq_sel = str.GetString();
1054 }
1055
1056
OnEditBrowseChanged(WPARAM wParam,LPARAM lParam)1057 afx_msg LRESULT CFormatConvertDlg::OnEditBrowseChanged(WPARAM wParam, LPARAM lParam)
1058 {
1059 CBrowseEdit* pEdit = (CBrowseEdit*)lParam;
1060 CString str;
1061 if (pEdit == &m_out_dir_edit)
1062 {
1063 GetDlgItemText(IDC_OUT_DIR_EDIT, str);
1064 m_out_dir = str.GetString();
1065 }
1066 if (pEdit == &m_out_name_edit)
1067 {
1068 GetDlgItemText(IDC_OUT_NAME_EDIT, str);
1069 m_out_name = str.GetString();
1070 }
1071 return 0;
1072 }
1073
1074
OnBnClickedOpenTargetDirCheck()1075 void CFormatConvertDlg::OnBnClickedOpenTargetDirCheck()
1076 {
1077 // TODO: 在此添加控件通知处理程序代码
1078 m_open_output_dir = (((CButton*)GetDlgItem(IDC_OPEN_TARGET_DIR_CHECK))->GetCheck() != 0);
1079 }
1080