xref: /MusicPlayer2/MusicPlayer2/MusicPlayerDlg.cpp (revision fc77c71b2623add2756a54b7bf5cd93b7619bbd0)
1 
2 // MusicPlayerDlg.cpp : 实现文件
3 //
4 
5 #include "stdafx.h"
6 #include "MusicPlayer2.h"
7 #include "MusicPlayerDlg.h"
8 #include "SupportedFormatDlg.h"
9 #include "AboutDlg.h"
10 #include "CTest.h"
11 #include "CListenTimeStatisticsDlg.h"
12 #include "CFloatPlaylistDlg.h"
13 #include "Playlist.h"
14 #include "InputDlg.h"
15 #include "FileRelateDlg.h"
16 #include "TestDlg.h"
17 #include "COSUPlayerHelper.h"
18 #include "MusicPlayerCmdHelper.h"
19 #include "AddToPlaylistDlg.h"
20 #include "LyricRelateDlg.h"
21 #include "SongDataManager.h"
22 #include "RenameDlg.h"
23 #include "PropertyDlgHelper.h"
24 #include "TagLibHelper.h"
25 #include "UserUi.h"
26 #include "FfmpegCore.h"
27 #include "SongInfoHelper.h"
28 #include "FilterHelper.h"
29 #include "CommonDialogMgr.h"
30 #include "WinVersionHelper.h"
31 #include "MoreRecentItemDlg.h"
32 #include "UiMediaLibItemMgr.h"
33 #include "CRecentList.h"
34 
35 #ifdef _DEBUG
36 #define new DEBUG_NEW
37 #endif
38 
39 
40 
41 // CMusicPlayerDlg 对话框
42 
43 const UINT WM_TASKBARCREATED{ ::RegisterWindowMessage(_T("TaskbarCreated")) };  //注册任务栏建立的消息
44 
CMusicPlayerDlg(wstring cmdLine,CWnd * pParent)45 CMusicPlayerDlg::CMusicPlayerDlg(wstring cmdLine, CWnd* pParent /*=NULL*/)
46     : m_cmdLine{ cmdLine }, CMainDialogBase(IDD_MUSICPLAYER2_DIALOG, pParent)
47     , m_current_cache(LT_CURRENT)
48     , m_recent_cache(LT_RECENT)
49 {
50     m_hIcon = theApp.m_icon_mgr.GetHICON(IconMgr::IconType::IT_App, IconMgr::IconStyle::IS_Color, IconMgr::IconSize::IS_ALL);
51     m_path_edit.SetTooltopText(theApp.m_str_table.LoadText(L"UI_TIP_BTN_RECENT_FOLDER_OR_PLAYLIST").c_str());
52 
53     //初始化UI
54     //加载内置界面
55     m_ui_list.push_back(std::make_shared<CUserUi>(&m_ui_static_ctrl, IDR_UI1));
56     m_ui_list.push_back(std::make_shared<CUserUi>(&m_ui_static_ctrl, IDR_UI2));
57 
58     //加载skins目录下的用户自定义界面
59     std::vector<std::shared_ptr<CUserUi>> user_ui_list_with_index;      //指定了序号的用户自定义界面
60     std::vector<std::shared_ptr<CUserUi>> user_ui_list;                 //未指定序号的用户自定义界面
61     std::vector<std::wstring> skin_files;
62     CCommon::GetFiles(theApp.m_local_dir + L"skins\\*.xml", skin_files);
63     for (const auto& file_name : skin_files)
64     {
65         std::wstring file_path = theApp.m_local_dir + L"skins\\" + file_name;
66         auto ui = std::make_shared<CUserUi>(&m_ui_static_ctrl, file_path);
67         if (ui->IsIndexValid())
68             user_ui_list_with_index.push_back(ui);
69         else
70             user_ui_list.push_back(ui);
71     }
72     CUserUi::UniqueUiIndex(user_ui_list_with_index);        //确保序号唯一
73     std::sort(user_ui_list_with_index.begin(), user_ui_list_with_index.end(), [](const std::shared_ptr<CUserUi>& ui1, const std::shared_ptr<CUserUi>& ui2)
__anon0dda294f0102(const std::shared_ptr<CUserUi>& ui1, const std::shared_ptr<CUserUi>& ui2) 74         {
75             return ui1->GetUiIndex() < ui2->GetUiIndex();
76         });
77     for (const auto& ui : user_ui_list_with_index)
78         m_ui_list.push_back(ui);
79     int index = m_ui_list.size() + 1;
80     if (!user_ui_list_with_index.empty())
81         index = user_ui_list_with_index.back()->GetUiIndex() + 1;
82     for (const auto& ui : user_ui_list)
83     {
84         m_ui_list.push_back(ui);
85         ui->SetIndex(index);
86         index++;
87     }
88 }
89 
~CMusicPlayerDlg()90 CMusicPlayerDlg::~CMusicPlayerDlg()
91 {
92     CCommon::DeleteModelessDialog(m_pLyricEdit);
93     CCommon::DeleteModelessDialog(m_pLyricBatchDownDlg);
94     CCommon::DeleteModelessDialog(m_pMediaLibDlg);
95     CCommon::DeleteModelessDialog(m_pSoundEffecDlg);
96     CCommon::DeleteModelessDialog(m_pFormatConvertDlg);
97     CCommon::DeleteModelessDialog(m_pFloatPlaylistDlg);
98 }
99 
GetInstance()100 CMusicPlayerDlg* CMusicPlayerDlg::GetInstance()
101 {
102     return dynamic_cast<CMusicPlayerDlg*>(theApp.m_pMainWnd);
103 }
104 
IsMiniMode() const105 bool CMusicPlayerDlg::IsMiniMode() const
106 {
107     return m_miniModeDlg.GetSafeHwnd() != NULL;
108 }
109 
GetMinimodeDlg()110 CMiniModeDlg* CMusicPlayerDlg::GetMinimodeDlg()
111 {
112     return &m_miniModeDlg;
113 }
114 
UiForceRefresh()115 void CMusicPlayerDlg::UiForceRefresh()
116 {
117     m_ui_thread_para.ui_force_refresh = true;
118 }
119 
DoDataExchange(CDataExchange * pDX)120 void CMusicPlayerDlg::DoDataExchange(CDataExchange* pDX)
121 {
122     CMainDialogBase::DoDataExchange(pDX);
123     //DDX_Control(pDX, IDC_TRACK_EDIT, m_track_edit);
124     DDX_Control(pDX, IDC_PLAYLIST_LIST, m_playlist_list);
125     DDX_Control(pDX, IDC_PATH_STATIC, m_path_static);
126     DDX_Control(pDX, IDC_PATH_EDIT, m_path_edit);
127     DDX_Control(pDX, ID_MEDIA_LIB, m_media_lib_button);
128     DDX_Control(pDX, IDC_SEARCH_EDIT, m_search_edit);
129     DDX_Control(pDX, IDC_PLAYLIST_TOOLBAR, m_playlist_toolbar);
130     DDX_Control(pDX, IDC_UI_STATIC, m_ui_static_ctrl);
131     DDX_Control(pDX, IDC_HSPLITER_STATIC, m_splitter_ctrl);
132 }
133 
BEGIN_MESSAGE_MAP(CMusicPlayerDlg,CMainDialogBase)134 BEGIN_MESSAGE_MAP(CMusicPlayerDlg, CMainDialogBase)
135     ON_WM_SYSCOMMAND()
136     ON_WM_PAINT()
137     ON_WM_QUERYDRAGICON()
138     ON_WM_SIZE()
139     ON_WM_TIMER()
140     ON_COMMAND(ID_PLAY_PAUSE, &CMusicPlayerDlg::OnPlayPause)
141     ON_COMMAND(ID_PLAY, &CMusicPlayerDlg::OnPlay)
142     ON_COMMAND(ID_PAUSE, &CMusicPlayerDlg::OnPause)
143     ON_COMMAND(ID_STOP, &CMusicPlayerDlg::OnStop)
144     ON_COMMAND(ID_PREVIOUS, &CMusicPlayerDlg::OnPrevious)
145     ON_COMMAND(ID_NEXT, &CMusicPlayerDlg::OnNext)
146     ON_COMMAND(ID_REW, &CMusicPlayerDlg::OnRew)
147     ON_COMMAND(ID_FF, &CMusicPlayerDlg::OnFF)
148     ON_COMMAND(ID_MEDIA_LIB, &CMusicPlayerDlg::OnMediaLib)
149     ON_COMMAND(ID_FIND, &CMusicPlayerDlg::OnFind)
150     ON_COMMAND(ID_EXPLORE_PATH, &CMusicPlayerDlg::OnExplorePath)
151     ON_WM_DESTROY()
152     ON_COMMAND(ID_APP_ABOUT, &CMusicPlayerDlg::OnAppAbout)
153     ON_COMMAND(ID_FILE_OPEN, &CMusicPlayerDlg::OnFileOpen)
154     ON_COMMAND(ID_FILE_OPEN_FOLDER, &CMusicPlayerDlg::OnFileOpenFolder)
155     ON_WM_DROPFILES()
156     ON_WM_INITMENU()
157     ON_COMMAND(ID_REPEAT_MODE, &CMusicPlayerDlg::OnRepeatMode)
158     ON_COMMAND(ID_PLAY_ORDER, &CMusicPlayerDlg::OnPlayOrder)
159     ON_COMMAND(ID_PLAY_SHUFFLE, &CMusicPlayerDlg::OnPlayShuffle)
160     ON_COMMAND(ID_LOOP_PLAYLIST, &CMusicPlayerDlg::OnLoopPlaylist)
161     ON_COMMAND(ID_LOOP_TRACK, &CMusicPlayerDlg::OnLoopTrack)
162     ON_WM_MOUSEWHEEL()
163     ON_WM_GETMINMAXINFO()
164     ON_NOTIFY(NM_DBLCLK, IDC_PLAYLIST_LIST, &CMusicPlayerDlg::OnNMDblclkPlaylistList)
165     ON_COMMAND(ID_OPTION_SETTINGS, &CMusicPlayerDlg::OnOptionSettings)
166     ON_COMMAND(ID_RELOAD_PLAYLIST, &CMusicPlayerDlg::OnReloadPlaylist)
167     ON_NOTIFY(NM_RCLICK, IDC_PLAYLIST_LIST, &CMusicPlayerDlg::OnNMRClickPlaylistList)
168     ON_COMMAND(ID_PLAY_ITEM, &CMusicPlayerDlg::OnPlayItem)
169     ON_COMMAND(ID_ITEM_PROPERTY, &CMusicPlayerDlg::OnItemProperty)
170     ON_COMMAND(ID_EXPLORE_TRACK, &CMusicPlayerDlg::OnExploreTrack)
171     ON_WM_HOTKEY()
172     ON_COMMAND(ID_RE_INI_BASS, &CMusicPlayerDlg::OnReIniBass)
173     ON_COMMAND(ID_SORT_BY_FILE, &CMusicPlayerDlg::OnSortByFile)
174     ON_COMMAND(ID_SORT_BY_PATH, &CMusicPlayerDlg::OnSortByPath)
175     ON_COMMAND(ID_SORT_BY_TITLE, &CMusicPlayerDlg::OnSortByTitle)
176     ON_COMMAND(ID_SORT_BY_ARTIST, &CMusicPlayerDlg::OnSortByArtist)
177     ON_COMMAND(ID_SORT_BY_ALBUM, &CMusicPlayerDlg::OnSortByAlbum)
178     ON_COMMAND(ID_SORT_BY_TRACK, &CMusicPlayerDlg::OnSortByTrack)
179     ON_COMMAND(ID_SORT_BY_LISTEN_TIME, &CMusicPlayerDlg::OnSortByListenTime)
180     ON_COMMAND(ID_SORT_BY_MODIFIED_TIME, &CMusicPlayerDlg::OnSortByModifiedTime)
181     ON_COMMAND(ID_DELETE_FROM_DISK, &CMusicPlayerDlg::OnDeleteFromDisk)
182     ON_REGISTERED_MESSAGE(WM_TASKBARCREATED, &CMusicPlayerDlg::OnTaskbarcreated)
183     ON_COMMAND(ID_DISP_FILE_NAME, &CMusicPlayerDlg::OnDispFileName)
184     ON_COMMAND(ID_DISP_TITLE, &CMusicPlayerDlg::OnDispTitle)
185     ON_COMMAND(ID_DISP_ARTIST_TITLE, &CMusicPlayerDlg::OnDispArtistTitle)
186     ON_COMMAND(ID_DISP_TITLE_ARTIST, &CMusicPlayerDlg::OnDispTitleArtist)
187     ON_COMMAND(ID_MINI_MODE, &CMusicPlayerDlg::OnMiniMode)
188     ON_COMMAND(ID_RELOAD_LYRIC, &CMusicPlayerDlg::OnReloadLyric)
189     ON_COMMAND(ID_SONG_INFO, &CMusicPlayerDlg::OnSongInfo)
190     ON_COMMAND(ID_COPY_CURRENT_LYRIC, &CMusicPlayerDlg::OnCopyCurrentLyric)
191     ON_COMMAND(ID_COPY_ALL_LYRIC, &CMusicPlayerDlg::OnCopyAllLyric)
192     ON_WM_LBUTTONDBLCLK()
193     ON_COMMAND(ID_LYRIC_FORWARD, &CMusicPlayerDlg::OnLyricForward)
194     ON_COMMAND(ID_LYRIC_DELAY, &CMusicPlayerDlg::OnLyricDelay)
195     ON_COMMAND(ID_SAVE_MODIFIED_LYRIC, &CMusicPlayerDlg::OnSaveModifiedLyric)
196     ON_COMMAND(ID_EDIT_LYRIC, &CMusicPlayerDlg::OnEditLyric)
197     ON_COMMAND(ID_DOWNLOAD_LYRIC, &CMusicPlayerDlg::OnDownloadLyric)
198     ON_COMMAND(ID_LYRIC_BATCH_DOWNLOAD, &CMusicPlayerDlg::OnLyricBatchDownload)
199     ON_COMMAND(ID_DELETE_LYRIC, &CMusicPlayerDlg::OnDeleteLyric)
200     ON_WM_RBUTTONUP()
201     ON_WM_MOUSEMOVE()
202     ON_WM_LBUTTONUP()
203     ON_WM_CTLCOLOR()
204     ON_MESSAGE(WM_PLAYLIST_INI_COMPLATE, &CMusicPlayerDlg::OnPlaylistIniComplate)
205     ON_MESSAGE(WM_AFTER_SET_TRACK, &CMusicPlayerDlg::OnAfterSetTrack)
206     ON_COMMAND(ID_EQUALIZER, &CMusicPlayerDlg::OnEqualizer)
207     ON_COMMAND(ID_EXPLORE_ONLINE, &CMusicPlayerDlg::OnExploreOnline)
208     ON_MESSAGE(WM_PLAYLIST_INI_START, &CMusicPlayerDlg::OnPlaylistIniStart)
209     ON_COMMAND(ID_BROWSE_LYRIC, &CMusicPlayerDlg::OnBrowseLyric)
210     ON_COMMAND(ID_TRANSLATE_TO_SIMPLIFIED_CHINESE, &CMusicPlayerDlg::OnTranslateToSimplifiedChinese)
211     ON_COMMAND(ID_TRANSLATE_TO_TRANDITIONAL_CHINESE, &CMusicPlayerDlg::OnTranslateToTranditionalChinese)
212     ON_COMMAND(ID_ALBUM_COVER_SAVE_AS, &CMusicPlayerDlg::OnAlbumCoverSaveAs)
213     // ON_MESSAGE(WM_PATH_SELECTED, &CMusicPlayerDlg::OnPathSelected)
214     ON_MESSAGE(WM_CONNOT_PLAY_WARNING, &CMusicPlayerDlg::OnConnotPlayWarning)
215     ON_EN_CHANGE(IDC_SEARCH_EDIT, &CMusicPlayerDlg::OnEnChangeSearchEdit)
216     ON_COMMAND(ID_DOWNLOAD_ALBUM_COVER, &CMusicPlayerDlg::OnDownloadAlbumCover)
217     ON_MESSAGE(WM_MUSIC_STREAM_OPENED, &CMusicPlayerDlg::OnMusicStreamOpened)
218     ON_COMMAND(ID_CURRENT_EXPLORE_ONLINE, &CMusicPlayerDlg::OnCurrentExploreOnline)
219     ON_COMMAND(ID_DELETE_ALBUM_COVER, &CMusicPlayerDlg::OnDeleteAlbumCover)
220     ON_COMMAND(ID_COPY_FILE_TO, &CMusicPlayerDlg::OnCopyFileTo)
221     ON_COMMAND(ID_MOVE_FILE_TO, &CMusicPlayerDlg::OnMoveFileTo)
222     //ON_MESSAGE(WM_OPEN_FILE_COMMAND_LINE, &CMusicPlayerDlg::OnOpenFileCommandLine)
223     ON_COMMAND(ID_FORMAT_CONVERT, &CMusicPlayerDlg::OnFormatConvert)
224     ON_COMMAND(ID_FORMAT_CONVERT1, &CMusicPlayerDlg::OnFormatConvert1)
225     ON_MESSAGE(WM_SETTINGS_APPLIED, &CMusicPlayerDlg::OnSettingsApplied)
226     ON_MESSAGE(WM_ALBUM_COVER_DOWNLOAD_COMPLETE, &CMusicPlayerDlg::OnAlbumCoverDownloadComplete)
227     ON_WM_DWMCOLORIZATIONCOLORCHANGED()
228     ON_COMMAND(ID_SUPPORTED_FORMAT, &CMusicPlayerDlg::OnSupportedFormat)
229     ON_COMMAND(ID_SWITCH_UI, &CMusicPlayerDlg::OnSwitchUi)
230     ON_COMMAND(ID_VOLUME_UP, &CMusicPlayerDlg::OnVolumeUp)
231     ON_COMMAND(ID_VOLUME_DOWN, &CMusicPlayerDlg::OnVolumeDown)
232     ON_MESSAGE(MY_WM_NOTIFYICON, &CMusicPlayerDlg::OnNotifyicon)
233     ON_WM_CLOSE()
234     ON_COMMAND(ID_MENU_EXIT, &CMusicPlayerDlg::OnMenuExit)
235     ON_COMMAND(ID_MINIMODE_RESTORE, &CMusicPlayerDlg::OnMinimodeRestore)
236     ON_WM_APPCOMMAND()
237     ON_WM_LBUTTONDOWN()
238     ON_COMMAND(ID_SHOW_PLAYLIST, &CMusicPlayerDlg::OnShowPlaylist)
239     ON_WM_SETCURSOR()
240     ON_WM_MOUSELEAVE()
241     ON_COMMAND(ID_SHOW_MENU_BAR, &CMusicPlayerDlg::OnShowMenuBar)
242     ON_COMMAND(ID_FULL_SCREEN, &CMusicPlayerDlg::OnFullScreen)
243     ON_COMMAND(ID_CREATE_PLAY_SHORTCUT, &CMusicPlayerDlg::OnCreatePlayShortcut)
244     ON_COMMAND(ID_LISTEN_STATISTICS, &CMusicPlayerDlg::OnListenStatistics)
245     ON_COMMAND(ID_DARK_MODE, &CMusicPlayerDlg::OnDarkMode)
246     ON_MESSAGE(WM_MAIN_MENU_POPEDUP, &CMusicPlayerDlg::OnMainMenuPopup)
247     ON_COMMAND(ID_ALWAYS_ON_TOP, &CMusicPlayerDlg::OnAlwaysOnTop)
248     ON_COMMAND(ID_FLOAT_PLAYLIST, &CMusicPlayerDlg::OnFloatPlaylist)
249     ON_COMMAND(ID_DOCKED_PLAYLIST, &CMusicPlayerDlg::OnDockedPlaylist)
250     ON_COMMAND(ID_FLOATED_PLAYLIST, &CMusicPlayerDlg::OnFloatedPlaylist)
251     ON_MESSAGE(WM_FLOAT_PLAYLIST_CLOSED, &CMusicPlayerDlg::OnFloatPlaylistClosed)
252     // ON_MESSAGE(WM_PLAYLIST_SELECTED, &CMusicPlayerDlg::OnPlaylistSelected)
253     ON_COMMAND(ID_PLAYLIST_ADD_FILE, &CMusicPlayerDlg::OnPlaylistAddFile)
254     ON_COMMAND(ID_REMOVE_FROM_PLAYLIST, &CMusicPlayerDlg::OnRemoveFromPlaylist)
255     ON_COMMAND(ID_EMPTY_PLAYLIST, &CMusicPlayerDlg::OnEmptyPlaylist)
256     ON_COMMAND(ID_MOVE_PLAYLIST_ITEM_UP, &CMusicPlayerDlg::OnMovePlaylistItemUp)
257     ON_COMMAND(ID_MOVE_PLAYLIST_ITEM_DOWN, &CMusicPlayerDlg::OnMovePlaylistItemDown)
258     ON_NOTIFY(NM_CLICK, IDC_PLAYLIST_LIST, &CMusicPlayerDlg::OnNMClickPlaylistList)
259     ON_COMMAND(ID_REMOVE_SAME_SONGS, &CMusicPlayerDlg::OnRemoveSameSongs)
260     ON_COMMAND(ID_ADD_TO_NEW_PLAYLIST, &CMusicPlayerDlg::OnAddToNewPlaylist)
261     ON_COMMAND(ID_TOOL_FILE_RELATE, &CMusicPlayerDlg::OnToolFileRelate)
262     ON_COMMAND(ID_PLAYLIST_ADD_FOLDER, &CMusicPlayerDlg::OnPlaylistAddFolder)
263     ON_COMMAND(ID_REMOVE_INVALID_ITEMS, &CMusicPlayerDlg::OnRemoveInvalidItems)
264     ON_MESSAGE(WM_LIST_ITEM_DRAGGED, &CMusicPlayerDlg::OnListItemDragged)
265     ON_COMMAND(ID_ADD_REMOVE_FROM_FAVOURITE, &CMusicPlayerDlg::OnAddRemoveFromFavourite)
266     ON_COMMAND(ID_FILE_OPEN_URL, &CMusicPlayerDlg::OnFileOpenUrl)
267     ON_COMMAND(ID_PLAYLIST_ADD_URL, &CMusicPlayerDlg::OnPlaylistAddUrl)
268     ON_MESSAGE(WM_SET_MENU_STATE, &CMusicPlayerDlg::OnSetMenuState)
269     ON_COMMAND(ID_LOCK_DESKTOP_LRYIC, &CMusicPlayerDlg::OnLockDesktopLryic)
270     ON_COMMAND(ID_CLOSE_DESKTOP_LYRIC, &CMusicPlayerDlg::OnCloseDesktopLyric)
271     ON_COMMAND(ID_LYRIC_DISPLAYED_DOUBLE_LINE, &CMusicPlayerDlg::OnLyricDisplayedDoubleLine)
272     ON_COMMAND(ID_LYRIC_BACKGROUND_PENETRATE, &CMusicPlayerDlg::OnLyricBackgroundPenetrate)
273     ON_COMMAND(ID_PLAYLIST_SELECT_CHANGE, &CMusicPlayerDlg::OnPlaylistSelectChange)
274     ON_COMMAND(ID_PLAYLIST_SELECT_ALL, &CMusicPlayerDlg::OnPlaylistSelectAll)
275     ON_COMMAND(ID_PLAYLIST_SELECT_NONE, &CMusicPlayerDlg::OnPlaylistSelectNone)
276     ON_COMMAND(ID_PLAYLIST_SELECT_REVERT, &CMusicPlayerDlg::OnPlaylistSelectRevert)
277     ON_MESSAGE(WM_CUR_PLAYLIST_RENAMED, &CMusicPlayerDlg::OnCurPlaylistRenamed)
278     ON_COMMAND(ID_ONLINE_HELP, &CMusicPlayerDlg::OnOnlineHelp)
279     ON_COMMAND(ID_SPEED_UP, &CMusicPlayerDlg::OnSpeedUp)
280     ON_COMMAND(ID_SLOW_DOWN, &CMusicPlayerDlg::OnSlowDown)
281     ON_COMMAND(ID_ORIGINAL_SPEED, &CMusicPlayerDlg::OnOriginalSpeed)
282     ON_COMMAND(ID_PITCH_UP, &CMusicPlayerDlg::OnPitchUp)
283     ON_COMMAND(ID_PITCH_DOWN, &CMusicPlayerDlg::OnPitchDown)
284     ON_COMMAND(ID_ORIGINAL_PITCH, &CMusicPlayerDlg::OnOriginalPitch)
285     ON_MESSAGE(WM_SEARCH_EDIT_BTN_CLICKED, &CMusicPlayerDlg::OnSearchEditBtnClicked)
286     ON_MESSAGE(WM_INIT_ADD_TO_MENU, &CMusicPlayerDlg::OnInitAddToMenu)
287     ON_MESSAGE(WM_OPTION_SETTINGS, &CMusicPlayerDlg::OnMsgOptionSettings)
288     ON_COMMAND(ID_ALWAYS_SHOW_STATUS_BAR, &CMusicPlayerDlg::OnAlwaysShowStatusBar)
289     ON_MESSAGE(WM_POST_MUSIC_STREAM_OPENED, &CMusicPlayerDlg::OnPostMusicStreamOpened)
290     ON_COMMAND(ID_SHOW_MAIN_WINDOW, &CMusicPlayerDlg::OnShowMainWindow)
291     ON_MESSAGE(WM_RECENT_PLAYED_LIST_CLEARED, &CMusicPlayerDlg::OnRecentPlayedListCleared)
292     ON_COMMAND(ID_AB_REPEAT, &CMusicPlayerDlg::OnAbRepeat)
293     ON_COMMAND(ID_SET_A_POINT, &CMusicPlayerDlg::OnSetAPoint)
294     ON_COMMAND(ID_SET_B_POINT, &CMusicPlayerDlg::OnSetBPoint)
295     ON_COMMAND(ID_RESET_AB_REPEAT, &CMusicPlayerDlg::OnResetAbRepeat)
296     ON_COMMAND(ID_NEXT_AB_REPEAT, &CMusicPlayerDlg::OnNextAbRepeat)
297     ON_COMMAND(ID_SAVE_CURRENT_PLAYLIST_AS, &CMusicPlayerDlg::OnSaveCurrentPlaylistAs)
298     ON_COMMAND(ID_FILE_OPEN_PLAYLIST, &CMusicPlayerDlg::OnFileOpenPlaylist)
299     ON_COMMAND(ID_SAVE_AS_NEW_PLAYLIST, &CMusicPlayerDlg::OnSaveAsNewPlaylist)
300     ON_COMMAND(ID_CREATE_DESKTOP_SHORTCUT, &CMusicPlayerDlg::OnCreateDesktopShortcut)
301     ON_COMMAND(ID_CREATE_MINI_MODE_SHORT_CUT, &CMusicPlayerDlg::OnCreateMiniModeShortCut)
302     ON_COMMAND(ID_REMOVE_CURRENT_FROM_PLAYLIST, &CMusicPlayerDlg::OnRemoveCurrentFromPlaylist)
303     ON_COMMAND(ID_DELETE_CURRENT_FROM_DISK, &CMusicPlayerDlg::OnDeleteCurrentFromDisk)
304     ON_WM_QUERYENDSESSION()
305     ON_COMMAND(ID_ALWAYS_USE_EXTERNAL_ALBUM_COVER, &CMusicPlayerDlg::OnAlwaysUseExternalAlbumCover)
306     ON_WM_COPYDATA()
307     ON_COMMAND(ID_RELATE_LOCAL_LYRIC, &CMusicPlayerDlg::OnRelateLocalLyric)
308     ON_COMMAND(ID_ALBUM_COVER_INFO, &CMusicPlayerDlg::OnAlbumCoverInfo)
309     ON_COMMAND(ID_UNLINK_LYRIC, &CMusicPlayerDlg::OnUnlinkLyric)
310     ON_COMMAND(ID_SHOW_DESKTOP_LYRIC, &CMusicPlayerDlg::OnShowDesktopLyric)
311     ON_MESSAGE(WM_MAIN_WINDOW_ACTIVATED, &CMusicPlayerDlg::OnMainWindowActivated)
312     ON_COMMAND(ID_CONTAIN_SUB_FOLDER, &CMusicPlayerDlg::OnContainSubFolder)
313     ON_MESSAGE(WM_GET_MUSIC_CURRENT_POSITION, &CMusicPlayerDlg::OnGetMusicCurrentPosition)
314     ON_COMMAND(ID_PLAY_RANDOM, &CMusicPlayerDlg::OnPlayRandom)
315     ON_MESSAGE(WM_CURRENT_FILE_ALBUM_COVER_CHANGED, &CMusicPlayerDlg::OnCurrentFileAlbumCoverChanged)
316     ON_COMMAND(ID_RENAME, &CMusicPlayerDlg::OnRename)
317     ON_COMMAND(ID_EMBED_LYRIC_TO_AUDIO_FILE, &CMusicPlayerDlg::OnEmbedLyricToAudioFile)
318     ON_COMMAND(ID_DELETE_LYRIC_FROM_AUDIO_FILE, &CMusicPlayerDlg::OnDeleteLyricFromAudioFile)
319     ON_MESSAGE(WM_AFTER_MUSIC_STREAM_CLOSED, &CMusicPlayerDlg::OnAfterMusicStreamClosed)
320     ON_COMMAND(ID_PLAY_TRACK, &CMusicPlayerDlg::OnPlayTrack)
321     ON_COMMAND(ID_SHOW_LYRIC_TRANSLATE, &CMusicPlayerDlg::OnShowLyricTranslate)
322     ON_COMMAND(ID_VIEW_ARTIST, &CMusicPlayerDlg::OnViewArtist)
323     ON_COMMAND(ID_VIEW_ALBUM, &CMusicPlayerDlg::OnViewAlbum)
324     ON_COMMAND(ID_LOCATE_TO_CURRENT, &CMusicPlayerDlg::OnLocateToCurrent)
325     ON_COMMAND(ID_USE_STANDARD_TITLE_BAR, &CMusicPlayerDlg::OnUseStandardTitleBar)
326     ON_MESSAGE(WM_RE_INIT_BASS_CONTINUE_PLAY, &CMusicPlayerDlg::OnReInitBassContinuePlay)
327     ON_MESSAGE(WM_DISPLAYCHANGE, &CMusicPlayerDlg::OnDisplaychange)
328     ON_WM_WINDOWPOSCHANGING()
329     ON_WM_WINDOWPOSCHANGED()
330     ON_COMMAND(ID_PLAYLIST_VIEW_ARTIST, &CMusicPlayerDlg::OnPlaylistViewArtist)
331     ON_COMMAND(ID_PLAYLIST_VIEW_ALBUM, &CMusicPlayerDlg::OnPlaylistViewAlbum)
332     ON_MESSAGE(WM_VOLUME_CHANGED, &CMusicPlayerDlg::OnVolumeChanged)
333     ON_COMMAND(ID_PLAYLIST_OPTIONS, &CMusicPlayerDlg::OnPlaylistOptions)
334     ON_WM_MOVE()
335     ON_MESSAGE(WM_RECENT_FOLDER_OR_PLAYLIST_CHANGED, &CMusicPlayerDlg::OnRecentFolderOrPlaylistChanged)
336     ON_COMMAND(ID_PLAY_AS_NEXT, &CMusicPlayerDlg::OnPlayAsNext)
337     ON_COMMAND(ID_PLAYLIST_FIX_PATH_ERROR, &CMusicPlayerDlg::OnPlaylistFixPathError)
338     ON_WM_POWERBROADCAST()
339     ON_MESSAGE(WM_SET_UI_FORCE_FRESH_FLAG, &CMusicPlayerDlg::OnSetUiForceFreshFlag)
340     ON_COMMAND(ID_MORE_RECENT_ITEMS, &CMusicPlayerDlg::OnMoreRecentItems)
341     ON_WM_NCCALCSIZE()
342     ON_MESSAGE(WM_CLEAR_UI_SERCH_BOX, &CMusicPlayerDlg::OnClearUiSerchBox)
343 END_MESSAGE_MAP()
344 
345 
346 // CMusicPlayerDlg 消息处理程序
347 
348 void CMusicPlayerDlg::SaveConfig()
349 {
350     CIniHelper ini(theApp.m_config_path);
351 
352     ini.WriteInt(L"config", L"window_width", m_window_width);
353     ini.WriteInt(L"config", L"window_hight", m_window_height);
354     ini.WriteInt(L"config", L"transparency", theApp.m_app_setting_data.window_transparency);
355     ini.WriteBool(L"config", L"narrow_mode", theApp.m_ui_data.narrow_mode);
356     ini.WriteBool(L"config", L"show_translate", theApp.m_lyric_setting_data.show_translate);
357     ini.WriteBool(L"config", L"show_playlist", theApp.m_ui_data.show_playlist);
358     ini.WriteBool(L"config", L"show_menu_bar", theApp.m_ui_data.show_menu_bar);
359     ini.WriteBool(L"config", L"show_window_frame", theApp.m_app_setting_data.show_window_frame);
360     ini.WriteBool(L"config", L"always_show_statusbar", theApp.m_app_setting_data.always_show_statusbar);
361     ini.WriteBool(L"config", L"float_playlist", theApp.m_nc_setting_data.float_playlist);
362     ini.WriteInt(L"config", L"float_playlist_width", theApp.m_nc_setting_data.playlist_size.cx);
363     ini.WriteInt(L"config", L"float_playlist_height", theApp.m_nc_setting_data.playlist_size.cy);
364 
365     ini.WriteInt(L"config", L"lyric_save_policy", static_cast<int>(theApp.m_lyric_setting_data.lyric_save_policy));
366     ini.WriteBool(L"config", L"use_inner_lyric_first", theApp.m_lyric_setting_data.use_inner_lyric_first);
367     ini.WriteBool(L"config", L"donot_show_blank_lines", theApp.m_lyric_setting_data.donot_show_blank_lines);
368     ini.WriteBool(L"config", L"show_song_info_if_lyric_not_exist", theApp.m_lyric_setting_data.show_song_info_if_lyric_not_exist);
369 
370     ini.WriteInt(L"config", L"theme_color", theApp.m_app_setting_data.theme_color.original_color);
371     ini.WriteBool(L"config", L"theme_color_follow_system", theApp.m_app_setting_data.theme_color_follow_system);
372     ini.WriteInt(L"config", L"playlist_display_format", static_cast<int>(theApp.m_media_lib_setting_data.display_format));
373     ini.WriteBool(L"config", L"show_lyric_in_cortana", theApp.m_lyric_setting_data.cortana_info_enable);
374     ini.WriteBool(L"config", L"cortana_show_lyric", theApp.m_lyric_setting_data.cortana_show_lyric);
375     // ini.WriteBool(L"config", L"save_lyric_in_offset", theApp.m_lyric_setting_data.save_lyric_in_offset);
376     ini.WriteString(L"config", L"font", theApp.m_lyric_setting_data.lyric_font.name);
377     ini.WriteInt(L"config", L"font_size", theApp.m_lyric_setting_data.lyric_font.size);
378     ini.WriteInt(L"config", L"font_style", theApp.m_lyric_setting_data.lyric_font.style.ToInt());
379     ini.WriteInt(L"config", L"lyric_line_space", theApp.m_lyric_setting_data.lyric_line_space);
380     ini.WriteInt(L"config", L"lyric_align", static_cast<int>(theApp.m_lyric_setting_data.lyric_align));
381     ini.WriteInt(L"config", L"spectrum_height", theApp.m_app_setting_data.sprctrum_height);
382     ini.WriteBool(L"config", L"cortana_lyric_double_line", theApp.m_lyric_setting_data.cortana_lyric_double_line);
383     ini.WriteBool(L"config", L"show_spectrum", theApp.m_app_setting_data.show_spectrum);
384     ini.WriteBool(L"config", L"spectrum_low_freq_in_center", theApp.m_app_setting_data.spectrum_low_freq_in_center);
385     ini.WriteBool(L"config", L"use_old_style_specturm", theApp.m_app_setting_data.use_old_style_specturm);
386     ini.WriteBool(L"config", L"show_album_cover", theApp.m_app_setting_data.show_album_cover);
387     ini.WriteInt(L"config", L"album_cover_fit", static_cast<int>(theApp.m_app_setting_data.album_cover_fit));
388     ini.WriteBool(L"config", L"enable_background", theApp.m_app_setting_data.enable_background);
389     ini.WriteBool(L"config", L"album_cover_as_background", theApp.m_app_setting_data.album_cover_as_background);
390     ini.WriteBool(L"config", L"cortana_show_album_cover", theApp.m_lyric_setting_data.cortana_show_album_cover);
391     ini.WriteBool(L"config", L"cortana_icon_beat", theApp.m_lyric_setting_data.cortana_icon_beat);
392     ini.WriteBool(L"config", L"cortana_lyric_compatible_mode", theApp.m_lyric_setting_data.cortana_lyric_compatible_mode);
393     ini.WriteString(L"config", L"cortana_font", theApp.m_lyric_setting_data.cortana_font.name);
394     ini.WriteInt(L"config", L"cortana_font_size", theApp.m_lyric_setting_data.cortana_font.size);
395     ini.WriteInt(L"config", L"cortana_font_style", theApp.m_lyric_setting_data.cortana_font.style.ToInt());
396     ini.WriteBool(L"config", L"cortana_lyric_keep_display", theApp.m_lyric_setting_data.cortana_lyric_keep_display);
397     ini.WriteBool(L"config", L"cortana_show_spectrum", theApp.m_lyric_setting_data.cortana_show_spectrum);
398     ini.WriteInt(L"config", L"cortana_lyric_align", static_cast<int>(theApp.m_lyric_setting_data.cortana_lyric_align));
399     ini.WriteBool(L"config", L"show_default_album_icon_in_search_box", theApp.m_lyric_setting_data.show_default_album_icon_in_search_box);
400 
401     ini.WriteBool(L"desktop_lyric", L"show_desktop_lyric", theApp.m_lyric_setting_data.show_desktop_lyric);
402     ini.WriteString(L"desktop_lyric", L"font_name", theApp.m_lyric_setting_data.desktop_lyric_data.lyric_font.name);
403     ini.WriteInt(L"desktop_lyric", L"font_size", theApp.m_lyric_setting_data.desktop_lyric_data.lyric_font.size);
404     ini.WriteInt(L"desktop_lyric", L"font_style", theApp.m_lyric_setting_data.desktop_lyric_data.lyric_font.style.ToInt());
405     ini.WriteInt(L"desktop_lyric", L"text_color1", theApp.m_lyric_setting_data.desktop_lyric_data.text_color1);
406     ini.WriteInt(L"desktop_lyric", L"text_color2", theApp.m_lyric_setting_data.desktop_lyric_data.text_color2);
407     ini.WriteInt(L"desktop_lyric", L"text_gradient", theApp.m_lyric_setting_data.desktop_lyric_data.text_gradient);
408     ini.WriteInt(L"desktop_lyric", L"highlight_color1", theApp.m_lyric_setting_data.desktop_lyric_data.highlight_color1);
409     ini.WriteInt(L"desktop_lyric", L"highlight_color2", theApp.m_lyric_setting_data.desktop_lyric_data.highlight_color2);
410     ini.WriteInt(L"desktop_lyric", L"highlight_gradient", theApp.m_lyric_setting_data.desktop_lyric_data.highlight_gradient);
411     ini.WriteBool(L"desktop_lyric", L"lock_desktop_lyric", theApp.m_lyric_setting_data.desktop_lyric_data.lock_desktop_lyric);
412     ini.WriteBool(L"desktop_lyric", L"lyric_double_line", theApp.m_lyric_setting_data.desktop_lyric_data.lyric_double_line);
413     ini.WriteBool(L"desktop_lyric", L"hide_lyric_window_without_lyric", theApp.m_lyric_setting_data.desktop_lyric_data.hide_lyric_window_without_lyric);
414     ini.WriteBool(L"desktop_lyric", L"hide_lyric_window_when_paused", theApp.m_lyric_setting_data.desktop_lyric_data.hide_lyric_window_when_paused);
415     ini.WriteBool(L"desktop_lyric", L"lyric_background_penetrate", theApp.m_lyric_setting_data.desktop_lyric_data.lyric_background_penetrate);
416     ini.WriteInt(L"desktop_lyric", L"opacity", theApp.m_lyric_setting_data.desktop_lyric_data.opacity);
417     ini.WriteBool(L"desktop_lyric", L"show_unlock_when_locked", theApp.m_lyric_setting_data.desktop_lyric_data.show_unlock_when_locked);
418     ini.WriteInt(L"desktop_lyric", L"lyric_align", static_cast<int>(theApp.m_lyric_setting_data.desktop_lyric_data.lyric_align));
419     ini.WriteInt(L"desktop_lyric", L"position_x", m_desktop_lyric_pos.x);
420     ini.WriteInt(L"desktop_lyric", L"position_y", m_desktop_lyric_pos.y);
421     ini.WriteInt(L"desktop_lyric", L"width", m_desktop_lyric_size.cx);
422     ini.WriteInt(L"desktop_lyric", L"height", m_desktop_lyric_size.cy);
423 
424     ini.WriteBool(L"config", L"background_gauss_blur", theApp.m_app_setting_data.background_gauss_blur);
425     ini.WriteInt(L"config", L"gauss_blur_radius", theApp.m_app_setting_data.gauss_blur_radius);
426     ini.WriteBool(L"config", L"lyric_background", theApp.m_app_setting_data.lyric_background);
427     ini.WriteBool(L"config", L"dark_mode", theApp.m_app_setting_data.dark_mode);
428     ini.WriteInt(L"config", L"background_transparency", theApp.m_app_setting_data.background_transparency);
429     ini.WriteBool(L"config", L"use_out_image", theApp.m_app_setting_data.use_out_image);
430     ini.WriteBool(L"config", L"use_inner_image_first", theApp.m_app_setting_data.use_inner_image_first);
431     ini.WriteBool(L"config", L"draw_album_high_quality", theApp.m_app_setting_data.draw_album_high_quality);
432     ini.WriteInt(L"config", L"ui_refresh_interval", theApp.m_app_setting_data.ui_refresh_interval);
433     ini.WriteInt(L"config", L"notify_icon_selected", theApp.m_app_setting_data.notify_icon_selected);
434     ini.WriteBool(L"config", L"notify_icon_auto_adapt", theApp.m_app_setting_data.notify_icon_auto_adapt);
435     ini.WriteBool(L"config", L"button_round_corners", theApp.m_app_setting_data.button_round_corners);
436     ini.WriteInt(L"config", L"playlist_width_percent", theApp.m_app_setting_data.playlist_width_percent);
437     ini.WriteString(L"config", L"default_background", theApp.m_app_setting_data.default_background);
438     ini.WriteBool(L"config", L"use_desktop_background", theApp.m_app_setting_data.use_desktop_background);
439 
440     ini.WriteBool(L"config", L"show_fps", theApp.m_app_setting_data.show_fps);
441     ini.WriteBool(L"config", L"show_next_track", theApp.m_app_setting_data.show_next_track);
442     ini.WriteBool(L"config", L"show_minimize_btn_in_titlebar", theApp.m_app_setting_data.show_minimize_btn_in_titlebar);
443     ini.WriteBool(L"config", L"show_maximize_btn_in_titlebar", theApp.m_app_setting_data.show_maximize_btn_in_titlebar);
444     ini.WriteBool(L"config", L"show_minimode_btn_in_titlebar", theApp.m_app_setting_data.show_minimode_btn_in_titlebar);
445     ini.WriteBool(L"config", L"show_fullscreen_btn_in_titlebar", theApp.m_app_setting_data.show_fullscreen_btn_in_titlebar);
446     ini.WriteBool(L"config", L"show_skin_btn_in_titlebar", theApp.m_app_setting_data.show_skin_btn_in_titlebar);
447     ini.WriteBool(L"config", L"show_settings_btn_in_titlebar", theApp.m_app_setting_data.show_settings_btn_in_titlebar);
448     ini.WriteBool(L"config", L"show_dark_light_btn_in_titlebar", theApp.m_app_setting_data.show_dark_light_btn_in_titlebar);
449 
450     ini.WriteBool(L"config", L"remove_titlebar_top_frame", theApp.m_app_setting_data.remove_titlebar_top_frame);
451 
452     ini.WriteInt(L"config", L"volum_step", theApp.m_nc_setting_data.volum_step);
453     ini.WriteInt(L"config", L"mouse_volum_step", theApp.m_nc_setting_data.mouse_volum_step);
454     ini.WriteInt(L"config", L"cortana_back_color", theApp.m_lyric_setting_data.cortana_color);
455     ini.WriteInt(L"config", L"volume_map", theApp.m_nc_setting_data.volume_map);
456     ini.WriteBool(L"config", L"show_cover_tip", theApp.m_nc_setting_data.show_cover_tip);
457     ini.WriteBool(L"config", L"always_on_top", theApp.m_nc_setting_data.always_on_top);
458     ini.WriteInt(L"config", L"max_album_cover_size", theApp.m_nc_setting_data.max_album_cover_size);
459 
460     ini.WriteBool(L"other", L"no_sf2_warning", theApp.m_nc_setting_data.no_sf2_warning);
461     ini.WriteBool(L"other", L"show_hide_menu_bar_tip", theApp.m_nc_setting_data.show_hide_menu_bar_tip);
462     ini.WriteBool(L"other", L"cortana_opaque", theApp.m_lyric_setting_data.cortana_opaque);
463     ini.WriteInt(L"other", L"cortana_transparent_color", theApp.m_lyric_setting_data.cortana_transparent_color);
464     ini.WriteString(L"other", L"default_osu_img", theApp.m_nc_setting_data.default_osu_img);
465     ini.WriteBool(L"other", L"show_debug_info", theApp.m_nc_setting_data.show_debug_info);
466     ini.WriteInt(L"other", L"light_mode_default_transparency", theApp.m_nc_setting_data.light_mode_default_transparency);
467     ini.WriteInt(L"other", L"dark_mode_default_transparency", theApp.m_nc_setting_data.dark_mode_default_transparency);
468     ini.WriteInt(L"other", L"debug_log", theApp.m_nc_setting_data.debug_log);
469 
470     ini.WriteStringList(L"config", L"default_file_type", theApp.m_nc_setting_data.default_file_type);
471     ini.WriteStringList(L"config", L"user_defined_type_ffmpeg", theApp.m_nc_setting_data.user_defined_type_ffmpeg);
472 
473     ini.WriteBool(L"general", L"id3v2_first", theApp.m_general_setting_data.id3v2_first);
474     ini.WriteBool(L"general", L"auto_download_lyric", theApp.m_general_setting_data.auto_download_lyric);
475     ini.WriteBool(L"general", L"auto_download_album_cover", theApp.m_general_setting_data.auto_download_album_cover);
476     ini.WriteBool(L"general", L"auto_download_only_tag_full", theApp.m_general_setting_data.auto_download_only_tag_full);
477     ini.WriteBool(L"general", L"save_lyric_to_song_folder", theApp.m_general_setting_data.save_lyric_to_song_folder);
478     ini.WriteBool(L"general", L"save_album_to_song_folder", theApp.m_general_setting_data.save_album_to_song_folder);
479     ini.WriteBool(L"general", L"download_lyric_text_and_translation_in_same_line", theApp.m_general_setting_data.download_lyric_text_and_translation_in_same_line);
480     ini.WriteString(L"general", L"sf2_path", theApp.m_play_setting_data.sf2_path);
481     ini.WriteBool(L"general", L"midi_use_inner_lyric", theApp.m_play_setting_data.midi_use_inner_lyric);
482     ini.WriteBool(L"general", L"minimize_to_notify_icon", theApp.m_general_setting_data.minimize_to_notify_icon);
483     ini.WriteBool(L"general", L"global_mouse_wheel_volume_adjustment", theApp.m_general_setting_data.global_mouse_wheel_volume_adjustment);
484     ini.WriteInt(L"general", L"update_source", theApp.m_general_setting_data.update_source);
485 
486     ini.WriteBool(L"config", L"stop_when_error", theApp.m_play_setting_data.stop_when_error);
487     ini.WriteBool(L"config", L"auto_play_when_start", theApp.m_play_setting_data.auto_play_when_start);
488     ini.WriteBool(L"config", L"continue_when_switch_playlist", theApp.m_play_setting_data.continue_when_switch_playlist);
489     ini.WriteBool(L"config", L"show_taskbar_progress", theApp.m_play_setting_data.show_taskbar_progress);
490     ini.WriteBool(L"config", L"show_playstate_icon", theApp.m_play_setting_data.show_playstate_icon);
491     ini.WriteBool(L"config", L"fade_effect", theApp.m_play_setting_data.fade_effect);
492     ini.WriteInt(L"config", L"fade_time", theApp.m_play_setting_data.fade_time);
493     ini.WriteBool(L"config", L"use_media_trans_control", theApp.m_play_setting_data.use_media_trans_control);
494     ini.WriteString(L"config", L"output_device", theApp.m_play_setting_data.output_device);
495     ini.WriteBool(L"config", L"use_mci", theApp.m_play_setting_data.use_mci);
496     ini.WriteBool(L"config", L"use_ffmpeg", theApp.m_play_setting_data.use_ffmpeg);
497     ini.WriteInt(L"config", L"ffmpeg_core_cache_length", theApp.m_play_setting_data.ffmpeg_core_cache_length);
498     ini.WriteInt(L"config", L"ffmpeg_core_max_retry_count", theApp.m_play_setting_data.ffmpeg_core_max_retry_count);
499     ini.WriteInt(L"config", L"ffmpeg_core_url_retry_interval", theApp.m_play_setting_data.ffmpeg_core_url_retry_interval);
500     ini.WriteBool(L"config", L"ffmpeg_core_enable_WASAPI", theApp.m_play_setting_data.ffmpeg_core_enable_WASAPI);
501     ini.WriteBool(L"config", L"ffmpeg_core_enable_WASAPI_exclusive_mode", theApp.m_play_setting_data.ffmpeg_core_enable_WASAPI_exclusive_mode);
502     ini.WriteInt(L"config", L"ffmpeg_core_max_wait_time", theApp.m_play_setting_data.ffmpeg_core_max_wait_time);
503     ini.WriteInt(L"config", L"UI_selected", GetUiSelected());
504 
505     //保存热键设置
506     ini.WriteBool(L"hot_key", L"hot_key_enable", theApp.m_hot_key_setting_data.hot_key_enable);
507     m_hot_key.SaveToTni(ini);
508 
509     ini.WriteInt(L"other", L"playlist_sort_mode", static_cast<int>(CRecentList::Instance().GetSortMode(LT_PLAYLIST)));
510     ini.WriteInt(L"other", L"folder_sort_mode", static_cast<int>(CRecentList::Instance().GetSortMode(LT_FOLDER)));
511 
512     //保存桌面歌词预设
513     m_desktop_lyric.SaveDefaultStyle(ini);
514 
515     //媒体库设置
516     ini.WriteStringList(L"media_lib", L"media_folders", theApp.m_media_lib_setting_data.media_folders);
517     ini.WriteStringList(L"media_lib", L"artist_split_ext", theApp.m_media_lib_setting_data.artist_split_ext);
518     ini.WriteBool(L"media_lib", L"hide_only_one_classification", theApp.m_media_lib_setting_data.hide_only_one_classification);
519     ini.WriteBool(L"media_lib", L"disable_delete_from_disk", theApp.m_media_lib_setting_data.disable_delete_from_disk);
520     ini.WriteBool(L"media_lib", L"show_tree_tool_tips", theApp.m_media_lib_setting_data.show_tree_tool_tips);
521     ini.WriteBool(L"media_lib", L"update_media_lib_when_start_up", theApp.m_media_lib_setting_data.update_media_lib_when_start_up);
522     ini.WriteBool(L"media_lib", L"ignore_too_short_when_update", theApp.m_media_lib_setting_data.ignore_too_short_when_update);
523     ini.WriteInt(L"media_lib", L"file_too_short_sec", theApp.m_media_lib_setting_data.file_too_short_sec);
524     ini.WriteBool(L"media_lib", L"remove_file_not_exist_when_update", theApp.m_media_lib_setting_data.remove_file_not_exist_when_update);
525     ini.WriteBool(L"media_lib", L"disable_drag_sort", theApp.m_media_lib_setting_data.disable_drag_sort);
526     // ini.WriteBool(L"media_lib", L"ignore_songs_already_in_playlist", theApp.m_media_lib_setting_data.ignore_songs_already_in_playlist);不再使用,默认行为为true
527     ini.WriteBool(L"media_lib", L"insert_begin_of_playlist", theApp.m_media_lib_setting_data.insert_begin_of_playlist);
528     ini.WriteBool(L"media_lib", L"show_playlist_tooltip", theApp.m_media_lib_setting_data.show_playlist_tooltip);
529     ini.WriteBool(L"media_lib", L"float_playlist_follow_main_wnd", theApp.m_media_lib_setting_data.float_playlist_follow_main_wnd);
530     ini.WriteBool(L"config", L"playlist_btn_for_float_playlist", theApp.m_media_lib_setting_data.playlist_btn_for_float_playlist);
531     ini.WriteInt(L"media_lib", L"playlist_item_height", theApp.m_media_lib_setting_data.playlist_item_height);
532     ini.WriteInt(L"media_lib", L"recent_played_range", static_cast<int>(theApp.m_media_lib_setting_data.recent_played_range));
533     ini.WriteInt(L"media_lib", L"display_item", theApp.m_media_lib_setting_data.display_item);
534     ini.WriteBool(L"media_lib", L"write_id3_v2_3", theApp.m_media_lib_setting_data.write_id3_v2_3);
535     ini.WriteBool(L"media_lib", L"enable_lastfm", theApp.m_media_lib_setting_data.enable_lastfm);
536     ini.WriteInt(L"media_lib", L"lastfm_least_perdur", theApp.m_media_lib_setting_data.lastfm_least_perdur);
537     ini.WriteInt(L"media_lib", L"lastfm_least_dur", theApp.m_media_lib_setting_data.lastfm_least_dur);
538     ini.WriteBool(L"media_lib", L"lastfm_auto_scrobble", theApp.m_media_lib_setting_data.lastfm_auto_scrobble);
539     ini.WriteInt(L"media_lib", L"lastfm_auto_scrobble_min", theApp.m_media_lib_setting_data.lastfm_auto_scrobble_min);
540     ini.WriteBool(L"media_lib", L"lastfm_enable_https", theApp.m_media_lib_setting_data.lastfm_enable_https);
541     ini.WriteBool(L"media_lib", L"lastfm_enable_nowplaying", theApp.m_media_lib_setting_data.lastfm_enable_nowplaying);
542 
543     ini.Save();
544 }
545 
LoadConfig()546 void CMusicPlayerDlg::LoadConfig()
547 {
548     CIniHelper ini(theApp.m_config_path);
549 
550     m_window_width = ini.GetInt(L"config", L"window_width", theApp.DPI(660));
551     m_window_height = ini.GetInt(L"config", L"window_hight", theApp.DPI(482));
552     theApp.m_app_setting_data.window_transparency = ini.GetInt(L"config", L"transparency", 100);
553     theApp.m_ui_data.narrow_mode = ini.GetBool(L"config", L"narrow_mode", false);
554     theApp.m_lyric_setting_data.show_translate = ini.GetBool(L"config", L"show_translate", true);
555     theApp.m_ui_data.show_playlist = ini.GetBool(L"config", L"show_playlist", false);
556     theApp.m_ui_data.show_menu_bar = ini.GetBool(L"config", L"show_menu_bar", false);
557     theApp.m_app_setting_data.show_window_frame = ini.GetBool(L"config", L"show_window_frame", CWinVersionHelper::IsWindows10OrLater());    //Win10以上系统默认使用系统标准标题栏
558     theApp.m_app_setting_data.always_show_statusbar = ini.GetBool(L"config", L"always_show_statusbar", false);
559     theApp.m_nc_setting_data.float_playlist = ini.GetBool(L"config", L"float_playlist", false);
560     theApp.m_nc_setting_data.playlist_size.cx = ini.GetInt(L"config", L"float_playlist_width", theApp.DPI(320));
561     theApp.m_nc_setting_data.playlist_size.cy = ini.GetInt(L"config", L"float_playlist_height", theApp.DPI(482));
562 
563     theApp.m_lyric_setting_data.lyric_save_policy = static_cast<LyricSettingData::LyricSavePolicy>(ini.GetInt(L"config", L"lyric_save_policy", 2));
564     theApp.m_lyric_setting_data.use_inner_lyric_first = ini.GetBool(L"config", L"use_inner_lyric_first", true);
565     theApp.m_lyric_setting_data.donot_show_blank_lines = ini.GetBool(L"config", L"donot_show_blank_lines", true);
566     theApp.m_lyric_setting_data.show_song_info_if_lyric_not_exist = ini.GetBool(L"config", L"show_song_info_if_lyric_not_exist", false);
567 
568     theApp.m_app_setting_data.theme_color.original_color = ini.GetInt(L"config", L"theme_color", 16760187);
569     theApp.m_app_setting_data.theme_color_follow_system = ini.GetBool(L"config", L"theme_color_follow_system", true);
570     theApp.m_media_lib_setting_data.display_format = static_cast<DisplayFormat>(ini.GetInt(L"config", L"playlist_display_format", 2));
571     theApp.m_lyric_setting_data.cortana_show_lyric = ini.GetBool(L"config", L"cortana_show_lyric", true);
572     //if (CWinVersionHelper::IsWindows11OrLater())        //Windows11没有搜索框,禁用搜索框显示播放信息
573     //    theApp.m_lyric_setting_data.cortana_info_enable = false;
574     //else
575     theApp.m_lyric_setting_data.cortana_info_enable = ini.GetBool(L"config", L"show_lyric_in_cortana", false);
576     // theApp.m_lyric_setting_data.save_lyric_in_offset = ini.GetBool(L"config", L"save_lyric_in_offset", false);
577     theApp.m_lyric_setting_data.lyric_font.name = ini.GetString(L"config", L"font", theApp.m_str_table.GetDefaultFontName().c_str());
578     theApp.m_lyric_setting_data.lyric_font.size = ini.GetInt(L"config", L"font_size", 11);
579     theApp.m_lyric_setting_data.lyric_font.style.FromInt(ini.GetInt(L"config", L"font_style", 0));
580     theApp.m_lyric_setting_data.lyric_line_space = ini.GetInt(L"config", L"lyric_line_space", 4);
581     theApp.m_lyric_setting_data.lyric_align = static_cast<Alignment>(ini.GetInt(L"config", L"lyric_align", static_cast<int>(Alignment::AUTO)));
582     theApp.m_app_setting_data.sprctrum_height = ini.GetInt(L"config", L"spectrum_height", 80);
583     theApp.m_lyric_setting_data.cortana_lyric_double_line = ini.GetBool(L"config", L"cortana_lyric_double_line", true);
584     theApp.m_app_setting_data.show_spectrum = ini.GetBool(L"config", L"show_spectrum", 1);
585     theApp.m_app_setting_data.spectrum_low_freq_in_center = ini.GetBool(L"config", L"spectrum_low_freq_in_center", false);
586     theApp.m_app_setting_data.use_old_style_specturm = ini.GetBool(L"config", L"use_old_style_specturm", false);
587     theApp.m_app_setting_data.show_album_cover = ini.GetBool(L"config", L"show_album_cover", 1);
588     theApp.m_app_setting_data.album_cover_fit = static_cast<CDrawCommon::StretchMode>(ini.GetInt(L"config", L"album_cover_fit", 1));
589     theApp.m_app_setting_data.enable_background = ini.GetBool(L"config", L"enable_background", true);
590     theApp.m_app_setting_data.album_cover_as_background = ini.GetBool(L"config", L"album_cover_as_background", true);
591     theApp.m_lyric_setting_data.cortana_show_album_cover = ini.GetBool(L"config", L"cortana_show_album_cover", 1);
592     theApp.m_lyric_setting_data.cortana_icon_beat = ini.GetBool(L"config", L"cortana_icon_beat", 0);
593     theApp.m_lyric_setting_data.cortana_lyric_compatible_mode = ini.GetBool(L"config", L"cortana_lyric_compatible_mode", false);
594     theApp.m_lyric_setting_data.cortana_font.name = ini.GetString(L"config", L"cortana_font", theApp.m_str_table.GetDefaultFontName().c_str());
595     theApp.m_lyric_setting_data.cortana_font.size = ini.GetInt(L"config", L"cortana_font_size", 11);
596     theApp.m_lyric_setting_data.cortana_font.style.FromInt(ini.GetInt(L"config", L"cortana_font_style", 0));
597     theApp.m_lyric_setting_data.cortana_lyric_keep_display = ini.GetBool(L"config", L"cortana_lyric_keep_display", false);
598     theApp.m_lyric_setting_data.cortana_show_spectrum = ini.GetBool(L"config", L"cortana_show_spectrum", false);
599     theApp.m_lyric_setting_data.cortana_lyric_align = static_cast<Alignment>(ini.GetInt(L"config", L"cortana_lyric_align", static_cast<int>(Alignment::AUTO)));
600     theApp.m_lyric_setting_data.show_default_album_icon_in_search_box = ini.GetBool(L"config", L"show_default_album_icon_in_search_box", false);
601 
602     theApp.m_lyric_setting_data.show_desktop_lyric = ini.GetBool(L"desktop_lyric", L"show_desktop_lyric", false);
603     theApp.m_lyric_setting_data.desktop_lyric_data.lyric_font.name = ini.GetString(L"desktop_lyric", L"font_name", theApp.m_str_table.GetDefaultFontName().c_str());
604     theApp.m_lyric_setting_data.desktop_lyric_data.lyric_font.size = ini.GetInt(L"desktop_lyric", L"font_size", 30);
605     theApp.m_lyric_setting_data.desktop_lyric_data.lyric_font.style.FromInt(ini.GetInt(L"desktop_lyric", L"font_style", 0));
606     theApp.m_lyric_setting_data.desktop_lyric_data.text_color1 = ini.GetInt(L"desktop_lyric", L"text_color1", RGB(37, 152, 10));
607     theApp.m_lyric_setting_data.desktop_lyric_data.text_color2 = ini.GetInt(L"desktop_lyric", L"text_color2", RGB(129, 249, 0));
608     theApp.m_lyric_setting_data.desktop_lyric_data.text_gradient = ini.GetInt(L"desktop_lyric", L"text_gradient", 1);
609     theApp.m_lyric_setting_data.desktop_lyric_data.highlight_color1 = ini.GetInt(L"desktop_lyric", L"highlight_color1", RGB(253, 232, 0));
610     theApp.m_lyric_setting_data.desktop_lyric_data.highlight_color2 = ini.GetInt(L"desktop_lyric", L"highlight_color2", RGB(255, 120, 0));
611     theApp.m_lyric_setting_data.desktop_lyric_data.highlight_gradient = ini.GetInt(L"desktop_lyric", L"highlight_gradient", 2);
612     theApp.m_lyric_setting_data.desktop_lyric_data.lock_desktop_lyric = ini.GetBool(L"desktop_lyric", L"lock_desktop_lyric", false);
613     theApp.m_lyric_setting_data.desktop_lyric_data.lyric_double_line = ini.GetBool(L"desktop_lyric", L"lyric_double_line", false);
614     theApp.m_lyric_setting_data.desktop_lyric_data.hide_lyric_window_without_lyric = ini.GetBool(L"desktop_lyric", L"hide_lyric_window_without_lyric", false);
615     theApp.m_lyric_setting_data.desktop_lyric_data.hide_lyric_window_when_paused = ini.GetBool(L"desktop_lyric", L"hide_lyric_window_when_paused", false);
616     theApp.m_lyric_setting_data.desktop_lyric_data.lyric_background_penetrate = ini.GetBool(L"desktop_lyric", L"lyric_background_penetrate", false);
617     theApp.m_lyric_setting_data.desktop_lyric_data.opacity = ini.GetInt(L"desktop_lyric", L"opacity", 100);
618     theApp.m_lyric_setting_data.desktop_lyric_data.show_unlock_when_locked = ini.GetBool(L"desktop_lyric", L"show_unlock_when_locked", true);
619     theApp.m_lyric_setting_data.desktop_lyric_data.lyric_align = static_cast<Alignment>(ini.GetInt(L"desktop_lyric", L"lyric_align", static_cast<int>(Alignment::AUTO)));
620     m_desktop_lyric_pos.x = ini.GetInt(L"desktop_lyric", L"position_x", -1);
621     m_desktop_lyric_pos.y = ini.GetInt(L"desktop_lyric", L"position_y", -1);
622     m_desktop_lyric_size.cx = ini.GetInt(L"desktop_lyric", L"width", 0);
623     m_desktop_lyric_size.cy = ini.GetInt(L"desktop_lyric", L"height", 0);
624 
625     theApp.m_app_setting_data.background_gauss_blur = ini.GetBool(L"config", L"background_gauss_blur", true);
626     theApp.m_app_setting_data.gauss_blur_radius = ini.GetInt(L"config", L"gauss_blur_radius", 150);
627     theApp.m_app_setting_data.lyric_background = ini.GetBool(L"config", L"lyric_background", false);
628     theApp.m_app_setting_data.dark_mode = ini.GetBool(L"config", L"dark_mode", true);
629     theApp.m_app_setting_data.background_transparency = ini.GetInt(L"config", L"background_transparency", 40);
630     theApp.m_app_setting_data.use_out_image = ini.GetBool(L"config", L"use_out_image", true);
631     theApp.m_app_setting_data.use_inner_image_first = ini.GetBool(L"config", L"use_inner_image_first", true);
632     theApp.m_app_setting_data.draw_album_high_quality = ini.GetBool(L"config", L"draw_album_high_quality", false);
633     theApp.m_app_setting_data.ui_refresh_interval = ini.GetInt(L"config", L"ui_refresh_interval", UI_INTERVAL_DEFAULT);
634     if (theApp.m_app_setting_data.ui_refresh_interval < MIN_UI_INTERVAL || theApp.m_app_setting_data.ui_refresh_interval > MAX_UI_INTERVAL)
635         theApp.m_app_setting_data.ui_refresh_interval = UI_INTERVAL_DEFAULT;
636     theApp.m_app_setting_data.notify_icon_selected = ini.GetInt(L"config", L"notify_icon_selected", 0);
637     theApp.m_app_setting_data.notify_icon_auto_adapt = ini.GetBool(L"config", L"notify_icon_auto_adapt", false);
638     theApp.m_app_setting_data.button_round_corners = ini.GetBool(L"config", L"button_round_corners", !CWinVersionHelper::IsWindows8Or8point1() && !CWinVersionHelper::IsWindows10());  //Win8/8.1/10默认使用直角风格,其他默认使用圆角风格
639     theApp.m_app_setting_data.playlist_width_percent = ini.GetInt(L"config", L"playlist_width_percent", 50);
640     theApp.m_app_setting_data.default_background = ini.GetString(L"config", L"default_background", DEFAULT_BACKGROUND_NAME);
641     theApp.m_app_setting_data.use_desktop_background = ini.GetBool(L"config", L"use_desktop_background", false);
642 
643     theApp.m_app_setting_data.show_fps = ini.GetBool(L"config", L"show_fps", true);
644     theApp.m_app_setting_data.show_next_track = ini.GetBool(L"config", L"show_next_track", true);
645     theApp.m_app_setting_data.show_minimize_btn_in_titlebar = ini.GetBool(L"config", L"show_minimize_btn_in_titlebar", true);
646     theApp.m_app_setting_data.show_maximize_btn_in_titlebar = ini.GetBool(L"config", L"show_maximize_btn_in_titlebar", true);
647     theApp.m_app_setting_data.show_minimode_btn_in_titlebar = ini.GetBool(L"config", L"show_minimode_btn_in_titlebar", true);
648     theApp.m_app_setting_data.show_fullscreen_btn_in_titlebar = ini.GetBool(L"config", L"show_fullscreen_btn_in_titlebar", true);
649     theApp.m_app_setting_data.show_skin_btn_in_titlebar = ini.GetBool(L"config", L"show_skin_btn_in_titlebar", false);
650     theApp.m_app_setting_data.show_settings_btn_in_titlebar = ini.GetBool(L"config", L"show_settings_btn_in_titlebar", false);
651     theApp.m_app_setting_data.show_dark_light_btn_in_titlebar = ini.GetBool(L"config", L"show_dark_light_btn_in_titlebar", false);
652 
653     theApp.m_app_setting_data.remove_titlebar_top_frame = ini.GetBool(L"config", L"remove_titlebar_top_frame", false);
654 
655     theApp.m_nc_setting_data.volum_step = ini.GetInt(L"config", L"volum_step", 3);
656     theApp.m_nc_setting_data.mouse_volum_step = ini.GetInt(L"config", L"mouse_volum_step", 2);
657     theApp.m_lyric_setting_data.cortana_color = ini.GetInt(L"config", L"cortana_back_color", 0);
658     theApp.m_nc_setting_data.volume_map = ini.GetInt(L"config", L"volume_map", 100);
659     theApp.m_nc_setting_data.show_cover_tip = ini.GetBool(L"config", L"show_cover_tip", false);
660     theApp.m_nc_setting_data.always_on_top = ini.GetBool(L"config", L"always_on_top", false);
661     theApp.m_nc_setting_data.max_album_cover_size = ini.GetInt(L"config", L"max_album_cover_size", 800);
662 
663     theApp.m_nc_setting_data.no_sf2_warning = ini.GetBool(L"other", L"no_sf2_warning", true);
664     theApp.m_nc_setting_data.show_hide_menu_bar_tip = ini.GetBool(L"other", L"show_hide_menu_bar_tip", true);
665     theApp.m_lyric_setting_data.cortana_opaque = ini.GetBool(L"other", L"cortana_opaque", false);
666     theApp.m_lyric_setting_data.cortana_transparent_color = ini.GetInt(L"other", L"cortana_transparent_color", SEARCH_BOX_DEFAULT_TRANSPARENT_COLOR);
667     theApp.m_nc_setting_data.default_osu_img = ini.GetString(L"other", L"default_osu_img", L"");
668     theApp.m_nc_setting_data.show_debug_info = ini.GetBool(L"other", L"show_debug_info", true);
669     theApp.m_nc_setting_data.light_mode_default_transparency = ini.GetInt(L"other", L"light_mode_default_transparency", 80);
670     theApp.m_nc_setting_data.dark_mode_default_transparency = ini.GetInt(L"other", L"dark_mode_default_transparency", 40);
671     theApp.m_nc_setting_data.debug_log = ini.GetInt(L"other", L"debug_log", NonCategorizedSettingData::LT_ERROR);
672 
673     ini.GetStringList(L"config", L"default_file_type", theApp.m_nc_setting_data.default_file_type, vector<wstring>{L"mp3", L"wma", L"wav", L"flac", L"ogg", L"oga", L"m4a", L"mp4", L"cue", L"mp2", L"mp1", L"aif", L"aiff", L"asf"});
674     ini.GetStringList(L"config", L"user_defined_type_ffmpeg", theApp.m_nc_setting_data.user_defined_type_ffmpeg, vector<wstring>{});
675 
676     theApp.m_general_setting_data.id3v2_first = ini.GetBool(L"general", L"id3v2_first", 1);
677     theApp.m_general_setting_data.auto_download_lyric = ini.GetBool(L"general", L"auto_download_lyric", 1);
678     theApp.m_general_setting_data.auto_download_album_cover = ini.GetBool(L"general", L"auto_download_album_cover", 1);
679     theApp.m_general_setting_data.auto_download_only_tag_full = ini.GetBool(L"general", L"auto_download_only_tag_full", 1);
680     theApp.m_general_setting_data.save_lyric_to_song_folder = ini.GetBool(L"general", L"save_lyric_to_song_folder", true);
681     theApp.m_general_setting_data.save_album_to_song_folder = ini.GetBool(L"general", L"save_album_to_song_folder", true);
682     theApp.m_general_setting_data.download_lyric_text_and_translation_in_same_line = ini.GetBool(L"general", L"download_lyric_text_and_translation_in_same_line", true);
683     theApp.m_play_setting_data.sf2_path = ini.GetString(L"general", L"sf2_path", L"");
684     theApp.m_play_setting_data.midi_use_inner_lyric = ini.GetBool(L"general", L"midi_use_inner_lyric", 0);
685     theApp.m_general_setting_data.minimize_to_notify_icon = ini.GetBool(L"general", L"minimize_to_notify_icon", false);
686     theApp.m_general_setting_data.global_mouse_wheel_volume_adjustment = ini.GetBool(L"general", L"global_mouse_wheel_volume_adjustment", true);
687 
688     bool is_zh_cn = theApp.m_str_table.IsSimplifiedChinese();       //当前语言是否为简体中文
689     theApp.m_general_setting_data.update_source = ini.GetInt(L"general", L"update_source", is_zh_cn ? 1 : 0);   //如果当前语言为简体,则默认更新源为Gitee,否则为GitHub
690 
691     theApp.m_play_setting_data.stop_when_error = ini.GetBool(L"config", L"stop_when_error", true);
692     theApp.m_play_setting_data.auto_play_when_start = ini.GetBool(L"config", L"auto_play_when_start", false);
693     theApp.m_play_setting_data.continue_when_switch_playlist = ini.GetBool(L"config", L"continue_when_switch_playlist", false);
694     theApp.m_play_setting_data.show_taskbar_progress = ini.GetBool(L"config", L"show_taskbar_progress", !CWinVersionHelper::IsWindows11OrLater());
695     theApp.m_play_setting_data.show_playstate_icon = ini.GetBool(L"config", L"show_playstate_icon", !CWinVersionHelper::IsWindows11OrLater());
696     theApp.m_play_setting_data.fade_effect = ini.GetBool(L"config", L"fade_effect", true);
697     theApp.m_play_setting_data.fade_time = ini.GetInt(L"config", L"fade_time", 500);
698     if (theApp.m_play_setting_data.fade_time < 0)
699         theApp.m_play_setting_data.fade_time = 0;
700     if (theApp.m_play_setting_data.fade_time > 2000)
701         theApp.m_play_setting_data.fade_time = 2000;
702     if (CWinVersionHelper::IsWindows81OrLater())
703         theApp.m_play_setting_data.use_media_trans_control = ini.GetBool(L"config", L"use_media_trans_control", true);
704     else
705         theApp.m_play_setting_data.use_media_trans_control = false;
706     theApp.m_play_setting_data.output_device = ini.GetString(L"config", L"output_device", L"");
707     theApp.m_play_setting_data.use_mci = ini.GetBool(L"config", L"use_mci", false);
708     theApp.m_play_setting_data.use_ffmpeg = ini.GetBool(L"config", L"use_ffmpeg", false);
709     theApp.m_play_setting_data.ffmpeg_core_cache_length = ini.GetInt(L"config", L"ffmpeg_core_cache_length", 15);
710     theApp.m_play_setting_data.ffmpeg_core_max_retry_count = ini.GetInt(L"config", L"ffmpeg_core_max_retry_count", 3);
711     theApp.m_play_setting_data.ffmpeg_core_url_retry_interval = ini.GetInt(L"config", L"ffmpeg_core_url_retry_interval", 5);
712     theApp.m_play_setting_data.ffmpeg_core_enable_WASAPI = ini.GetBool(L"config", L"ffmpeg_core_enable_WASAPI", false);
713     theApp.m_play_setting_data.ffmpeg_core_enable_WASAPI_exclusive_mode = ini.GetBool(L"config", L"ffmpeg_core_enable_WASAPI_exclusive_mode", false);
714     theApp.m_play_setting_data.ffmpeg_core_max_wait_time = ini.GetInt(L"config", L"ffmpeg_core_max_wait_time", 3000);
715 
716     int ui_selected = ini.GetInt(L"config", L"UI_selected", 1);
717     if (ui_selected < 0 || ui_selected >= static_cast<int>(m_ui_list.size()))
718     {
719         if (m_ui_list.size() >= 2)
720             ui_selected = 1;
721         else
722             ui_selected = 0;
723     }
724     SelectUi(ui_selected);
725 
726     CRecentList::listSortMode playlist_sort_mode = static_cast<CRecentList::listSortMode>(ini.GetInt(L"other", L"playlist_sort_mode", CRecentList::listSortMode::SM_RECENT_PLAYED));
727     CRecentList::Instance().SetSortMode(LT_PLAYLIST, playlist_sort_mode);
728     CRecentList::listSortMode folder_sort_mode = static_cast<CRecentList::listSortMode>(ini.GetInt(L"other", L"folder_sort_mode", static_cast<int>(CRecentList::listSortMode::SM_RECENT_PLAYED)));
729     CRecentList::Instance().SetSortMode(LT_FOLDER, folder_sort_mode);
730     // 暂时没有使用这个,但为其设置一个默认值
731     CRecentList::Instance().SetSortMode(LT_MEDIA_LIB, CRecentList::listSortMode::SM_RECENT_PLAYED);
732 
733     //载入热键设置
734     theApp.m_hot_key_setting_data.hot_key_enable = ini.GetBool(L"hot_key", L"hot_key_enable", true);
735     m_hot_key.LoadFromIni(ini);
736 
737     //载入桌面歌词预设方案
738     m_desktop_lyric.LoadDefaultStyle(ini);
739 
740     //载入媒体库设置
741     ini.GetStringList(L"media_lib", L"media_folders", theApp.m_media_lib_setting_data.media_folders, vector<wstring>{CCommon::GetSpecialDir(CSIDL_MYMUSIC)});
742     ini.GetStringList(L"media_lib", L"artist_split_ext", theApp.m_media_lib_setting_data.artist_split_ext, vector<wstring>{ L"AC/DC", L"+/-", L"22/7" });
743     theApp.m_media_lib_setting_data.hide_only_one_classification = ini.GetBool(L"media_lib", L"hide_only_one_classification", false);
744     theApp.m_media_lib_setting_data.disable_delete_from_disk = ini.GetBool(L"media_lib", L"disable_delete_from_disk", false);
745     theApp.m_media_lib_setting_data.show_tree_tool_tips = ini.GetBool(L"media_lib", L"show_tree_tool_tips", true);
746     theApp.m_media_lib_setting_data.update_media_lib_when_start_up = ini.GetBool(L"media_lib", L"update_media_lib_when_start_up", true);
747     theApp.m_media_lib_setting_data.ignore_too_short_when_update = ini.GetBool(L"media_lib", L"ignore_too_short_when_update", true);
748     theApp.m_media_lib_setting_data.file_too_short_sec = ini.GetInt(L"media_lib", L"file_too_short_sec", 30);
749     theApp.m_media_lib_setting_data.remove_file_not_exist_when_update = ini.GetBool(L"media_lib", L"remove_file_not_exist_when_update", true);
750     theApp.m_media_lib_setting_data.disable_drag_sort = ini.GetBool(L"media_lib", L"disable_drag_sort", false);
751     // theApp.m_media_lib_setting_data.ignore_songs_already_in_playlist = ini.GetBool(L"media_lib", L"ignore_songs_already_in_playlist", true);不再使用,默认行为为true
752     theApp.m_media_lib_setting_data.insert_begin_of_playlist = ini.GetBool(L"media_lib", L"insert_begin_of_playlist", false);
753     theApp.m_media_lib_setting_data.show_playlist_tooltip = ini.GetBool(L"media_lib", L"show_playlist_tooltip", true);
754     theApp.m_media_lib_setting_data.float_playlist_follow_main_wnd = ini.GetBool(L"media_lib", L"float_playlist_follow_main_wnd", true);
755     theApp.m_media_lib_setting_data.playlist_btn_for_float_playlist = ini.GetBool(L"config", L"playlist_btn_for_float_playlist", false);
756     theApp.m_media_lib_setting_data.playlist_item_height = ini.GetInt(L"media_lib", L"playlist_item_height", 24);
757     CCommon::SetNumRange(theApp.m_media_lib_setting_data.playlist_item_height, MIN_PLAYLIST_ITEM_HEIGHT, MAX_PLAYLIST_ITEM_HEIGHT);
758     theApp.m_media_lib_setting_data.recent_played_range = static_cast<RecentPlayedRange>(ini.GetInt(L"media_lib", L"recent_played_range", 0));
759     theApp.m_media_lib_setting_data.display_item = ini.GetInt(L"media_lib", L"display_item", (MLDI_ARTIST | MLDI_ALBUM | MLDI_YEAR | MLDI_GENRE | MLDI_ALL | MLDI_RECENT | MLDI_FOLDER_EXPLORE));
760     theApp.m_media_lib_setting_data.write_id3_v2_3 = ini.GetBool(L"media_lib", L"write_id3_v2_3", true);
761     theApp.m_media_lib_setting_data.enable_lastfm = ini.GetBool(L"media_lib", L"enable_lastfm", false);
762     theApp.m_media_lib_setting_data.lastfm_least_perdur = ini.GetInt(L"media_lib", L"lastfm_least_perdur", 50);
763     theApp.m_media_lib_setting_data.lastfm_least_perdur = min(90, max(10, theApp.m_media_lib_setting_data.lastfm_least_perdur));
764     theApp.m_media_lib_setting_data.lastfm_least_dur = ini.GetInt(L"media_lib", L"lastfm_least_dur", 60);
765     theApp.m_media_lib_setting_data.lastfm_least_dur = min(240, max(10, theApp.m_media_lib_setting_data.lastfm_least_dur));
766     theApp.m_media_lib_setting_data.lastfm_auto_scrobble = ini.GetBool(L"media_lib", L"lastfm_auto_scrobble", true);
767     theApp.m_media_lib_setting_data.lastfm_auto_scrobble_min = ini.GetInt(L"media_lib", L"lastfm_auto_scrobble_min", 1);
768     theApp.m_media_lib_setting_data.lastfm_auto_scrobble_min = min(50, max(1, theApp.m_media_lib_setting_data.lastfm_auto_scrobble_min));
769     theApp.m_media_lib_setting_data.lastfm_enable_https = ini.GetBool(L"media_lib", L"lastfm_enable_https", false);
770     theApp.m_media_lib_setting_data.lastfm_enable_nowplaying = ini.GetBool(L"media_lib", L"lastfm_enable_nowplaying", true);
771     CTagLibHelper::SetWriteId3V2_3(theApp.m_media_lib_setting_data.write_id3_v2_3);
772 }
773 
SetTransparency()774 void CMusicPlayerDlg::SetTransparency()
775 {
776     CCommon::SetWindowOpacity(m_hWnd, theApp.m_app_setting_data.window_transparency);
777 }
778 
SetDesptopLyricTransparency()779 void CMusicPlayerDlg::SetDesptopLyricTransparency()
780 {
781     m_desktop_lyric.SetLyricOpacity(theApp.m_lyric_setting_data.desktop_lyric_data.opacity);
782 }
783 
DrawInfo(bool reset)784 void CMusicPlayerDlg::DrawInfo(bool reset)
785 {
786     //主界面的绘图已经移动到线程函数UiThreadFunc中处理,这里不再执行绘图的代码
787 
788     //if (!IsIconic() && IsWindowVisible())     //窗口最小化或隐藏时不绘制,以降低CPU利用率
789     //    m_pUI->DrawInfo(reset);
790 
791     if (reset)      //如果reset为true,则通过m_draw_reset变量通知线程以重置绘图中的参数
792         m_ui_thread_para.draw_reset = true;
793 }
794 
SetPlaylistSize(int cx,int cy,int playlist_width)795 void CMusicPlayerDlg::SetPlaylistSize(int cx, int cy, int playlist_width)
796 {
797     CPlayerUIBase* pUiBase = dynamic_cast<CPlayerUIBase*>(m_pUI);
798 
799     CRect rect_base;
800     if (!theApp.m_ui_data.narrow_mode)
801         rect_base = { CPoint(cx - playlist_width + m_layout.margin, m_layout.margin),
802         CSize(playlist_width - 2 * m_layout.margin, cy - 2 * m_layout.margin) };
803     else
804         rect_base = { CPoint(m_layout.margin, pUiBase->DrawAreaHeight()/* + m_layout.margin*/),         // 不知道为什窄界面时上面不需要加边距
805         CSize(cx - 2 * m_layout.margin, cy - pUiBase->DrawAreaHeight() - /*2 * */m_layout.margin) };    // 同上
806 
807     // 设置IDC_PATH_STATIC/IDC_PATH_EDIT/ID_MEDIA_LIB的位置和大小
808     int edit_height = m_layout.path_edit_height;
809     CRect rect_static{ rect_base.left, rect_base.top, rect_base.left + m_part_static_width, rect_base.top + edit_height };
810     CRect rect_media_lib{ rect_base.right - m_medialib_btn_width, rect_base.top - 1, rect_base.right, rect_base.top + edit_height + 1 };
811     CRect rect_edit{ rect_static.right + m_layout.margin, rect_base.top, rect_media_lib.left - m_layout.margin, rect_base.top + edit_height };
812     m_path_static.MoveWindow(rect_static);
813     m_path_edit.MoveWindow(rect_edit);
814     m_media_lib_button.MoveWindow(rect_media_lib);
815 
816     rect_base.top += edit_height + m_layout.margin;
817     //设置歌曲搜索框的大小和位置
818     CRect rect_search;
819     m_search_edit.GetWindowRect(rect_search);
820     int search_height = rect_search.Height();
821     rect_search = { rect_base.left, rect_base.top, rect_base.right, rect_base.top + search_height };
822     m_search_edit.MoveWindow(rect_search);
823 
824     rect_base.top += search_height + m_layout.margin;
825     //设置播放列表工具栏的大小位置
826     int toolbar_height = m_layout.toolbar_height;
827     CRect rect_toolbar{ rect_base.left, rect_base.top, rect_base.right, rect_base.top + toolbar_height };
828     m_playlist_toolbar.MoveWindow(rect_toolbar);
829     m_playlist_toolbar.Invalidate();
830 
831     rect_base.top += toolbar_height + m_layout.margin;
832     // 设置播放列表控件大小和位置(即rect_base剩余空间)
833     m_playlist_list.MoveWindow(rect_base);
834     m_playlist_list.AdjustColumnWidth();
835 
836 
837     //设置分隔条的大小和位置
838     if (!theApp.m_ui_data.narrow_mode && theApp.m_ui_data.show_playlist)
839     {
840         m_splitter_ctrl.ShowWindow(SW_SHOW);
841         CRect rect_splitter{ cx - playlist_width - 1, 0, cx - playlist_width + m_layout.margin - 1, cy };
842         m_splitter_ctrl.MoveWindow(rect_splitter);
843     }
844     else
845     {
846         m_splitter_ctrl.ShowWindow(SW_HIDE);
847     }
848 }
849 
SetDrawAreaSize(int cx,int cy,int playlist_width)850 void CMusicPlayerDlg::SetDrawAreaSize(int cx, int cy, int playlist_width)
851 {
852     //调整绘图区域的大小
853     CRect draw_rect;
854     if (!theApp.m_ui_data.show_playlist)
855     {
856         draw_rect = CRect(0, 0, cx, cy);
857     }
858     else
859     {
860         if (!theApp.m_ui_data.narrow_mode)
861         {
862             draw_rect = CRect{ CPoint(), CPoint{ cx - playlist_width - 1, cy} };
863         }
864         else
865         {
866             CPlayerUIBase* pUiBase = dynamic_cast<CPlayerUIBase*>(m_pUI);
867             draw_rect = CRect{ CPoint(), CSize{ cx, pUiBase->DrawAreaHeight() - pUiBase->Margin() } };
868         }
869     }
870     m_ui_static_ctrl.MoveWindow(draw_rect);
871 }
872 
SetAlwaysOnTop()873 void CMusicPlayerDlg::SetAlwaysOnTop()
874 {
875     if (theApp.m_nc_setting_data.always_on_top)
876         SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);         //设置置顶
877     else
878         SetWindowPos(&wndNoTopMost, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);       //取消置顶
879 }
880 
IsMainWindowPopupMenu() const881 bool CMusicPlayerDlg::IsMainWindowPopupMenu() const
882 {
883     return (m_pCurMenu == theApp.m_menu_mgr.GetMenu(MenuMgr::MainAreaMenu)
884         || m_pCurMenu == theApp.m_menu_mgr.GetMenu(MenuMgr::AddToPlaylistMenu)
885         || m_pCurMenu == theApp.m_menu_mgr.GetMenu(MenuMgr::MiniAreaMenu));
886 }
887 
AdjustVolume(int step)888 void CMusicPlayerDlg::AdjustVolume(int step)
889 {
890     if (m_miniModeDlg.m_hWnd == NULL)
891     {
892         CPlayer::GetInstance().MusicControl(Command::VOLUME_ADJ, step);
893         CUserUi* cur_ui{ dynamic_cast<CUserUi*>(GetCurrentUi()) };
894         if (cur_ui != nullptr)
895             cur_ui->VolumeAdjusted();
896     }
897     else
898     {
899         m_miniModeDlg.SetVolume(step);
900     }
901 }
902 
CalculatePlaylistWidth(int client_width)903 int CMusicPlayerDlg::CalculatePlaylistWidth(int client_width)
904 {
905     int playlist_width = client_width * theApp.m_app_setting_data.playlist_width_percent / 100;
906     SLayoutData layout_data;
907     int min_width = layout_data.width_threshold / 2;
908     if (playlist_width < min_width)
909         playlist_width = min_width;
910     if (client_width - playlist_width < min_width)
911         playlist_width = client_width - min_width;
912     return playlist_width;
913 }
914 
ShowPlayList(bool highlight_visible)915 void CMusicPlayerDlg::ShowPlayList(bool highlight_visible)
916 {
917     m_current_cache.reload();
918 
919     m_playlist_list.ShowPlaylist(theApp.m_media_lib_setting_data.display_format);
920     m_playlist_list.SetCurSel(-1);
921     //设置播放列表中突出显示的项目
922     SetPlayListColor(highlight_visible);
923     //显示当前路径
924     const ListItem& cur_list = m_current_cache.at(0);
925     m_path_static.SetWindowText(cur_list.GetTypeDisplayName().c_str());
926     m_path_static.SetIcon(cur_list.GetTypeIcon());
927     m_path_edit.SetWindowTextW(cur_list.GetDisplayName().c_str());
928 
929     //播放列表模式下,播放列表工具栏第一个菜单为“添加”,文件夹模式下为“文件夹”
930     if (cur_list.type != LT_FOLDER)
931     {
932         const wstring& menu_str = theApp.m_str_table.LoadText(L"UI_TXT_PLAYLIST_TOOLBAR_ADD");
933         m_playlist_toolbar.ModifyToolButton(0, IconMgr::IconType::IT_Add, menu_str.c_str(), menu_str.c_str(), theApp.m_menu_mgr.GetMenu(MenuMgr::MainPlaylistAddMenu), true);
934     }
935     else
936     {
937         const wstring& menu_str = theApp.m_str_table.LoadText(L"UI_TXT_PLAYLIST_TOOLBAR_FOLDER");
938         m_playlist_toolbar.ModifyToolButton(0, IconMgr::IconType::IT_Folder, menu_str.c_str(), menu_str.c_str(), theApp.m_menu_mgr.GetMenu(MenuMgr::PlaylistToolBarFolderMenu), true);
939     }
940 
941     if (m_miniModeDlg.m_hWnd != NULL)
942     {
943         m_miniModeDlg.ShowPlaylist();
944     }
945 
946     if (IsFloatPlaylistExist())
947     {
948         m_pFloatPlaylistDlg->RefreshData();
949     }
950 }
951 
SetPlayListColor(bool highlight_visible)952 void CMusicPlayerDlg::SetPlayListColor(bool highlight_visible)
953 {
954     m_playlist_list.SetHightItem(CPlayer::GetInstance().GetIndex());
955     //m_playlist_list.SetColor(theApp.m_app_setting_data.theme_color);
956     m_playlist_list.Invalidate(FALSE);
957     if (highlight_visible)
958     {
959         m_playlist_list.EnsureVisible(CPlayer::GetInstance().GetIndex(), FALSE);
960         CUserUi* user_ui{ dynamic_cast<CUserUi*>(GetCurrentUi()) };
961         if (user_ui != nullptr)
962             user_ui->PlaylistLocateToCurrent();
963     }
964 
965     if (IsFloatPlaylistExist())
966     {
967         m_pFloatPlaylistDlg->RefreshState(highlight_visible);
968     }
969 }
970 
SwitchTrack()971 void CMusicPlayerDlg::SwitchTrack()
972 {
973     CPlayer::GetInstance().ResetABRepeat();
974     UpdateABRepeatToolTip();
975 
976     //当切换正在播放的歌曲时设置播放列表中突出显示的项目
977     SetPlayListColor();
978     if (m_miniModeDlg.m_hWnd != NULL)
979     {
980         m_miniModeDlg.SetPlayListColor();
981         //m_miniModeDlg.RePaint();
982         m_miniModeDlg.Invalidate(FALSE);
983     }
984     //由于播放列表使用了LVS_OWNERDATA样式,因此不能使用SetItemText函数为某一项单独设置文本
985     ////切换歌曲时如果当前歌曲的时间没有显示,则显示出来
986     //CString song_length_str;
987     //int index{ CPlayer::GetInstance().GetIndex() };
988     //song_length_str = m_playlist_list.GetItemText(index, 2);
989     //if (song_length_str == _T("-:--") && !CPlayer::GetInstance().GetAllSongLength(index).isZero())
990     //{
991     //    m_playlist_list.SetItemText(index, 2, CPlayer::GetInstance().GetAllSongLength(index).toString().c_str());
992     //}
993 
994     DrawInfo(true);
995 
996     UpdateSongInfoToolTip();
997 }
998 
UpdateSongInfoToolTip()999 void CMusicPlayerDlg::UpdateSongInfoToolTip()
1000 {
1001     for (auto& ui : m_ui_list)
1002     {
1003         ui->UpdateSongInfoToolTip();
1004     }
1005     if (IsMiniMode())
1006     {
1007         CPlayerUIBase* minimode_ui = m_miniModeDlg.GetCurUi();
1008         if (minimode_ui != nullptr)
1009             minimode_ui->UpdateSongInfoToolTip();
1010     }
1011 }
1012 
SetPlaylistVisible()1013 void CMusicPlayerDlg::SetPlaylistVisible()
1014 {
1015     int cmdShow = (theApp.m_ui_data.show_playlist ? SW_SHOW : SW_HIDE);
1016     m_playlist_list.ShowWindow(cmdShow);
1017     m_path_static.ShowWindow(cmdShow);
1018     m_path_edit.ShowWindow(cmdShow);
1019     m_search_edit.ShowWindow(cmdShow);
1020     //m_clear_search_button.ShowWindow(cmdShow);
1021     m_media_lib_button.ShowWindow(cmdShow);
1022     m_playlist_toolbar.ShowWindow(cmdShow);
1023     if (!theApp.m_ui_data.narrow_mode)
1024         m_splitter_ctrl.ShowWindow(cmdShow);
1025     else
1026         m_splitter_ctrl.ShowWindow(SW_HIDE);
1027 }
1028 
SetMenubarVisible()1029 void CMusicPlayerDlg::SetMenubarVisible()
1030 {
1031     if (theApp.m_ui_data.ShowWindowMenuBar() && theApp.m_app_setting_data.show_window_frame && !theApp.m_ui_data.full_screen)
1032     {
1033         SetMenu(theApp.m_menu_mgr.GetMenu(MenuMgr::MainMenu));
1034     }
1035     else
1036     {
1037         SetMenu(nullptr);
1038     }
1039 }
1040 
TaskBarInit()1041 void CMusicPlayerDlg::TaskBarInit()
1042 {
1043     if (theApp.IsTaskbarInteractionEnabled())
1044     {
1045         // 向任务栏添加按钮,已有按钮时不能重复调用(在UpdatePlayPauseButton之前)
1046         theApp.GetITaskbarList3()->ThumbBarAddButtons(m_hWnd, 3, m_thumbButton);    // 添加任务栏缩略图窗口按钮
1047         CRect thumbnail_rect = m_pUI->GetThumbnailClipArea();
1048         if (!thumbnail_rect.IsRectEmpty())
1049             theApp.GetITaskbarList3()->SetThumbnailClip(m_hWnd, thumbnail_rect);    // 设置任务栏缩略图的区域
1050 
1051     }
1052     UpdateTaskBarProgress(true);
1053     UpdatePlayPauseButton();
1054 }
1055 
UpdateTaskBarProgress(bool force) const1056 void CMusicPlayerDlg::UpdateTaskBarProgress(bool force) const
1057 {
1058     if (theApp.IsTaskbarInteractionEnabled())
1059     {
1060         // 降低更新频率,避免win11任务栏卡死(待测试)
1061         const int total = 100;              // 将进度分为100段,仅变化时更新
1062         static int last_progress{};
1063         static TBPFLAG last_status{ TBPF_NOPROGRESS };
1064         int progress{};
1065         TBPFLAG status{ TBPF_NOPROGRESS };
1066         //根据播放状态设置任务栏状态和进度
1067         if (theApp.m_play_setting_data.show_taskbar_progress)
1068         {
1069             int position = CPlayer::GetInstance().GetCurrentPosition();
1070             int length = CPlayer::GetInstance().GetSongLength();
1071             progress = max(position, 0) * total / max(length, 1);
1072             if (progress > total) progress = total;
1073             if (progress < 1) progress = 1;         // 为0时显示效果为TBPF_NOPROGRESS所以直接从1开始
1074             if (CPlayer::GetInstance().IsError())
1075                 status = TBPF_ERROR;
1076             else if (CPlayer::GetInstance().IsPlaying())
1077                 status = TBPF_INDETERMINATE;
1078             else
1079                 status = TBPF_PAUSED;
1080         }
1081         if (last_status != status || force)
1082         {
1083             theApp.GetITaskbarList3()->SetProgressState(this->GetSafeHwnd(), status);
1084             last_status = status;
1085         }
1086         if (last_progress != progress || force)
1087         {
1088             theApp.GetITaskbarList3()->SetProgressValue(this->GetSafeHwnd(), progress, total);
1089             last_progress = progress;
1090         }
1091     }
1092 }
1093 
UpdatePlayPauseButton()1094 void CMusicPlayerDlg::UpdatePlayPauseButton()
1095 {
1096     if (theApp.IsTaskbarInteractionEnabled())
1097     {
1098         HICON hIcon_play = theApp.m_icon_mgr.GetHICON(IconMgr::IconType::IT_Play, IconMgr::IconStyle::IS_Filled, IconMgr::IconSize::IS_DPI_16);
1099         HICON hIcon_pause = theApp.m_icon_mgr.GetHICON(IconMgr::IconType::IT_Pause, IconMgr::IconStyle::IS_Filled, IconMgr::IconSize::IS_DPI_16);
1100         if (CPlayer::GetInstance().IsPlaying() && !CPlayer::GetInstance().IsError())
1101         {
1102             //更新任务栏缩略图上“播放/暂停”的图标
1103             m_thumbButton[1].hIcon = hIcon_pause;
1104             wcscpy_s(m_thumbButton[1].szTip, theApp.m_str_table.LoadText(L"UI_TIP_BTN_PAUSE").c_str());
1105             //更新任务按钮上的播放状态图标
1106             if (theApp.m_play_setting_data.show_playstate_icon)
1107                 theApp.GetITaskbarList3()->SetOverlayIcon(m_hWnd, hIcon_play, L"");
1108             else
1109                 theApp.GetITaskbarList3()->SetOverlayIcon(m_hWnd, NULL, L"");
1110         }
1111         else
1112         {
1113             //更新任务栏缩略图上“播放/暂停”的图标
1114             m_thumbButton[1].hIcon = hIcon_play;
1115             wcscpy_s(m_thumbButton[1].szTip, theApp.m_str_table.LoadText(L"UI_TIP_BTN_PLAY").c_str());
1116             //更新任务按钮上的播放状态图标
1117             if (theApp.m_play_setting_data.show_playstate_icon && CPlayer::GetInstance().GetPlayingState2() == 1)
1118                 theApp.GetITaskbarList3()->SetOverlayIcon(m_hWnd, hIcon_pause, L"");
1119             else
1120                 theApp.GetITaskbarList3()->SetOverlayIcon(m_hWnd, NULL, L"");
1121         }
1122         theApp.GetITaskbarList3()->ThumbBarUpdateButtons(m_hWnd, 3, m_thumbButton);
1123     }
1124     if (m_miniModeDlg.m_hWnd != NULL)
1125         m_miniModeDlg.UpdatePlayPauseButton();
1126 
1127     m_pUI->UpdatePlayPauseButtonTip();
1128 }
1129 
TaskBarSetClipArea(CRect rect)1130 void CMusicPlayerDlg::TaskBarSetClipArea(CRect rect)
1131 {
1132     if (theApp.IsTaskbarInteractionEnabled())
1133     {
1134         if (!rect.IsRectEmpty())
1135         {
1136             theApp.GetITaskbarList3()->SetThumbnailClip(m_hWnd, rect);
1137         }
1138     }
1139 }
1140 
EnablePlaylist(bool enable)1141 void CMusicPlayerDlg::EnablePlaylist(bool enable)
1142 {
1143     m_playlist_list.EnableWindow(enable);
1144     m_search_edit.EnableWindow(enable);
1145     //m_clear_search_button.EnableWindow(enable);
1146     m_media_lib_button.EnableWindow(enable);
1147     m_playlist_toolbar.EnableWindow(enable);
1148     m_playlist_toolbar.Invalidate();
1149 
1150     if (m_pFloatPlaylistDlg->GetSafeHwnd() != NULL)
1151         m_pFloatPlaylistDlg->EnableControl(enable);
1152     if (m_miniModeDlg.GetSafeHwnd() != NULL)
1153         m_miniModeDlg.GetPlaylistCtrl().EnableWindow(enable);
1154 }
1155 
1156 
FirstRunCreateShortcut()1157 void CMusicPlayerDlg::FirstRunCreateShortcut()
1158 {
1159     //如果目录下没有recent_list(新)/recent_path(旧)和song_data文件,就判断为是第一次运行程序,提示用户是否创建桌面快捷方式
1160     if (!CCommon::FileExist(theApp.m_song_data_path) && !CCommon::FileExist(theApp.m_recent_list_dat_path) && !CCommon::FileExist(theApp.m_recent_path_dat_path))
1161     {
1162         const wstring& create_info = theApp.m_str_table.LoadText(L"MSG_SHORTCUT_INQUIRY_FIRST");
1163         if (MessageBox(create_info.c_str(), NULL, MB_ICONQUESTION | MB_YESNO) == IDYES)
1164         {
1165             if (CCommon::CreateFileShortcut(theApp.m_desktop_path.c_str(), NULL, _T("MusicPlayer2.lnk")))
1166             {
1167                 wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_SHORTCUT_CREATED", { theApp.m_desktop_path });
1168                 MessageBox(info.c_str(), NULL, MB_ICONINFORMATION);
1169             }
1170             else
1171             {
1172                 const wstring& info = theApp.m_str_table.LoadText(L"MSG_SHORTCUT_FAILED");
1173                 MessageBox(info.c_str(), NULL, MB_ICONWARNING);
1174             }
1175         }
1176     }
1177 }
1178 
ApplySettings(const COptionsDlg & optionDlg)1179 void CMusicPlayerDlg::ApplySettings(const COptionsDlg& optionDlg)
1180 {
1181     //获取选项设置对话框中的设置数据
1182 
1183     if (theApp.m_lyric_setting_data.cortana_info_enable == true && optionDlg.m_tab1_dlg.m_data.cortana_info_enable == false)    //如果在选项中关闭了“在Cortana搜索框中显示歌词”的选项,则重置Cortana搜索框的文本
1184         m_cortana_lyric.ResetCortanaText();
1185     m_cortana_lyric.SetEnable(optionDlg.m_tab1_dlg.m_data.cortana_info_enable);
1186 
1187     bool reload_sf2{ theApp.m_play_setting_data.sf2_path != optionDlg.m_tab4_dlg.m_data.sf2_path };
1188     bool gauss_blur_changed{ theApp.m_app_setting_data.background_gauss_blur != optionDlg.m_tab2_dlg.m_data.background_gauss_blur
1189                              || theApp.m_app_setting_data.gauss_blur_radius != optionDlg.m_tab2_dlg.m_data.gauss_blur_radius
1190                              || theApp.m_app_setting_data.album_cover_as_background != optionDlg.m_tab2_dlg.m_data.album_cover_as_background
1191                              || theApp.m_app_setting_data.enable_background != optionDlg.m_tab2_dlg.m_data.enable_background };
1192     bool output_device_changed{ theApp.m_play_setting_data.device_selected != optionDlg.m_tab4_dlg.m_data.device_selected };
1193     bool player_core_changed{ theApp.m_play_setting_data.use_mci != optionDlg.m_tab4_dlg.m_data.use_mci || theApp.m_play_setting_data.use_ffmpeg != optionDlg.m_tab4_dlg.m_data.use_ffmpeg };
1194     bool media_lib_folder_changed{ theApp.m_media_lib_setting_data.media_folders != optionDlg.m_media_lib_dlg.m_data.media_folders };
1195     bool media_lib_setting_changed{ theApp.m_media_lib_setting_data.hide_only_one_classification != optionDlg.m_media_lib_dlg.m_data.hide_only_one_classification
1196                                     || theApp.m_media_lib_setting_data.media_folders != optionDlg.m_media_lib_dlg.m_data.media_folders
1197                                     || theApp.m_media_lib_setting_data.recent_played_range != optionDlg.m_media_lib_dlg.m_data.recent_played_range
1198                                     || theApp.m_media_lib_setting_data.artist_split_ext != optionDlg.m_media_lib_dlg.m_data.artist_split_ext
1199     };
1200     bool use_inner_lyric_changed{ theApp.m_lyric_setting_data.use_inner_lyric_first != optionDlg.m_tab1_dlg.m_data.use_inner_lyric_first };
1201     //bool timer_interval_changed{ theApp.m_app_setting_data.ui_refresh_interval != optionDlg.m_tab2_dlg.m_data.ui_refresh_interval };
1202     bool notify_icon_changed{ theApp.m_app_setting_data.notify_icon_selected != optionDlg.m_tab2_dlg.m_data.notify_icon_selected };
1203     bool media_lib_display_item_changed{ theApp.m_media_lib_setting_data.display_item != optionDlg.m_media_lib_dlg.m_data.display_item };
1204     bool default_background_changed{ theApp.m_app_setting_data.default_background != optionDlg.m_tab2_dlg.m_data.default_background
1205                                      || theApp.m_app_setting_data.use_desktop_background != optionDlg.m_tab2_dlg.m_data.use_desktop_background };
1206     bool search_box_background_transparent_changed{ theApp.m_lyric_setting_data.cortana_transparent_color != optionDlg.m_tab1_dlg.m_data.cortana_transparent_color };
1207     bool float_playlist_follow_main_wnd_changed{ theApp.m_media_lib_setting_data.float_playlist_follow_main_wnd != optionDlg.m_media_lib_dlg.m_data.float_playlist_follow_main_wnd };
1208     bool show_window_frame_changed{ theApp.m_app_setting_data.show_window_frame != optionDlg.m_tab2_dlg.m_data.show_window_frame };
1209     bool playlist_item_height_changed{ theApp.m_media_lib_setting_data.playlist_item_height != optionDlg.m_media_lib_dlg.m_data.playlist_item_height };
1210     bool need_restart_player{ theApp.m_play_setting_data.ffmpeg_core_enable_WASAPI != optionDlg.m_tab4_dlg.m_data.ffmpeg_core_enable_WASAPI
1211     || (theApp.m_play_setting_data.ffmpeg_core_enable_WASAPI && (theApp.m_play_setting_data.ffmpeg_core_enable_WASAPI_exclusive_mode != optionDlg.m_tab4_dlg.m_data.ffmpeg_core_enable_WASAPI_exclusive_mode)) };
1212     bool SMTC_enable_changed{ theApp.m_play_setting_data.use_media_trans_control != optionDlg.m_tab4_dlg.m_data.use_media_trans_control };
1213     bool playlist_btn_changed{ theApp.m_media_lib_setting_data.playlist_btn_for_float_playlist != optionDlg.m_media_lib_dlg.m_data.playlist_btn_for_float_playlist };
1214 
1215     theApp.m_lyric_setting_data = optionDlg.m_tab1_dlg.m_data;
1216     theApp.m_app_setting_data = optionDlg.m_tab2_dlg.m_data;
1217     theApp.m_general_setting_data = optionDlg.m_tab3_dlg.m_data;
1218     theApp.m_play_setting_data = optionDlg.m_tab4_dlg.m_data;
1219     m_hot_key.FromHotkeyGroup(optionDlg.m_tab5_dlg.m_hotkey_group);
1220     theApp.m_hot_key_setting_data = optionDlg.m_tab5_dlg.m_data;
1221     theApp.m_media_lib_setting_data = optionDlg.m_media_lib_dlg.m_data;
1222 
1223     CTagLibHelper::SetWriteId3V2_3(theApp.m_media_lib_setting_data.write_id3_v2_3);
1224 
1225     if (reload_sf2 || output_device_changed || player_core_changed || need_restart_player)
1226     {
1227         CPlayer::GetInstance().ReIniPlayerCore(true);
1228         OnAfterSetTrack(0, 0);
1229     } else {
1230         if (CPlayer::GetInstance().IsFfmpegCore()) {
1231             CFfmpegCore* core = (CFfmpegCore*)CPlayer::GetInstance().GetPlayerCore();
1232             core->UpdateSettings();
1233         }
1234     }
1235     if (gauss_blur_changed)
1236         CPlayer::GetInstance().AlbumCoverGaussBlur();
1237 
1238     if (m_pMediaLibDlg != nullptr && IsWindow(m_pMediaLibDlg->m_hWnd))
1239     {
1240         if (media_lib_display_item_changed)     //如果媒体库显示项目发生发改变,则关闭媒体库对话框然后重新打开
1241         {
1242             CCommon::DeleteModelessDialog(m_pMediaLibDlg);
1243             int cur_tab{ CPlayer::GetInstance().IsFolderMode() ? 0 : 1 };
1244             m_pMediaLibDlg = new CMediaLibDlg(cur_tab);
1245             m_pMediaLibDlg->Create(IDD_MEDIA_LIB_DIALOG/*, GetDesktopWindow()*/);
1246             m_pMediaLibDlg->ShowWindow(SW_SHOW);
1247         }
1248         else if (media_lib_setting_changed)
1249         {
1250             CWaitCursor wait_cursor;
1251             m_pMediaLibDlg->m_artist_dlg->RefreshData();
1252             m_pMediaLibDlg->m_album_dlg->RefreshData();
1253             m_pMediaLibDlg->m_genre_dlg->RefreshData();
1254             m_pMediaLibDlg->m_folder_explore_dlg->RefreshData();
1255             m_pMediaLibDlg->m_recent_media_dlg->RefreshData();
1256         }
1257     }
1258 
1259     if (media_lib_folder_changed)
1260     {
1261         //更新UI中的文件夹浏览
1262         CUiFolderExploreMgr::Instance().UpdateFolders();
1263     }
1264 
1265     UpdatePlayPauseButton();
1266 
1267     ThemeColorChanged();
1268     ApplyThemeColor();
1269 
1270     if (optionDlg.m_tab1_dlg.FontChanged())
1271     {
1272         theApp.m_font_set.lyric.SetFont(theApp.m_lyric_setting_data.lyric_font);
1273         FontInfo translate_font = theApp.m_lyric_setting_data.lyric_font;
1274         translate_font.size--;
1275         theApp.m_font_set.lyric_translate.SetFont(translate_font);
1276     }
1277     if (optionDlg.m_tab1_dlg.SearchBoxFontChanged())
1278     {
1279         CCortanaLyric::InitFont();
1280     }
1281 
1282     m_desktop_lyric.ApplySettings(theApp.m_lyric_setting_data.desktop_lyric_data);
1283 
1284     SetPlaylistDragEnable();
1285     ShowPlayList();
1286 
1287     if (use_inner_lyric_changed)
1288     {
1289         OnReloadLyric();
1290     }
1291 
1292     if (SMTC_enable_changed)
1293     {
1294         CPlayer::GetInstance().m_controls.InitSMTC(theApp.m_play_setting_data.use_media_trans_control);
1295         if (theApp.m_play_setting_data.use_media_trans_control) // 如果设置从禁用更改为启用那么更新一次状态
1296         {
1297             PlaybackStatus status{};
1298             switch (CPlayer::GetInstance().GetPlayingState2())
1299             {
1300             case 0: status = PlaybackStatus::Stopped; break;
1301             case 1: status = PlaybackStatus::Paused; break;
1302             case 2: status = PlaybackStatus::Playing; break;
1303             }
1304             CPlayer::GetInstance().m_controls.UpdateControls(status);
1305             CPlayer::GetInstance().m_controls.UpdateControlsMetadata(CPlayer::GetInstance().GetCurrentSongInfo());
1306             CPlayer::GetInstance().m_controls.UpdatePosition(CPlayer::GetInstance().GetCurrentPosition(), true);
1307             CPlayer::GetInstance().m_controls.UpdateSpeed(CPlayer::GetInstance().GetSpeed());
1308             CPlayer::GetInstance().MediaTransControlsLoadThumbnail();
1309         }
1310     }
1311 
1312     if (notify_icon_changed)
1313     {
1314         if (theApp.m_app_setting_data.notify_icon_auto_adapt)
1315         {
1316             theApp.AutoSelectNotifyIcon();
1317         }
1318         if (theApp.m_app_setting_data.notify_icon_selected < 0 || theApp.m_app_setting_data.notify_icon_selected >= MAX_NOTIFY_ICON)
1319             theApp.m_app_setting_data.notify_icon_selected = 0;
1320         m_notify_icon.SetIcon(theApp.GetNotifyIncon(theApp.m_app_setting_data.notify_icon_selected));
1321         m_notify_icon.DeleteNotifyIcon();
1322         m_notify_icon.AddNotifyIcon();
1323     }
1324 
1325     if (default_background_changed)
1326         LoadDefaultBackground();
1327 
1328     if (search_box_background_transparent_changed)
1329         m_cortana_lyric.ApplySearchBoxTransparentChanged();
1330 
1331     if (optionDlg.m_tab3_dlg.IsAutoRunModified())
1332         theApp.SetAutoRun(optionDlg.m_tab3_dlg.m_auto_run);
1333 
1334     if (float_playlist_follow_main_wnd_changed && IsFloatPlaylistExist())
1335     {
1336         //if (theApp.m_media_lib_setting_data.float_playlist_follow_main_wnd)
1337         //{
1338         //    m_pFloatPlaylistDlg->ShowWindow(SW_RESTORE);
1339         //    MoveFloatPlaylistPos();
1340         //}
1341         //m_pFloatPlaylistDlg->UpdateStyles();
1342         HideFloatPlaylist();
1343         ShowFloatPlaylist();
1344     }
1345 
1346     if (show_window_frame_changed)
1347     {
1348         ApplyShowStandardTitlebar();
1349     }
1350 
1351     if (playlist_item_height_changed)
1352     {
1353         int row_height{ theApp.DPI(theApp.m_media_lib_setting_data.playlist_item_height) };
1354         m_playlist_list.SetRowHeight(row_height);
1355         if (IsFloatPlaylistExist())
1356             m_pFloatPlaylistDlg->GetListCtrl().SetRowHeight(row_height);
1357         if (m_miniModeDlg.GetSafeHwnd() != NULL)
1358             m_miniModeDlg.GetPlaylistCtrl().SetRowHeight(row_height);
1359     }
1360 
1361     //根据当前选择的深色/浅色模式,将当前“背景不透明度”设置更新到对应的深色/浅色“背景不透明度”设置中
1362     if (theApp.m_app_setting_data.dark_mode)
1363         theApp.m_nc_setting_data.dark_mode_default_transparency = theApp.m_app_setting_data.background_transparency;
1364     else
1365         theApp.m_nc_setting_data.light_mode_default_transparency = theApp.m_app_setting_data.background_transparency;
1366 
1367     SaveConfig();       //将设置写入到ini文件
1368     theApp.SaveConfig();
1369     CPlayer::GetInstance().SaveConfig();
1370     auto pCurUi = GetCurrentUi();
1371     if (pCurUi != nullptr)
1372         pCurUi->ClearBtnRect();
1373     DrawInfo(true);
1374     if (pCurUi != nullptr)
1375         pCurUi->UpdateToolTipPositionLater();
1376     if (pCurUi != nullptr && playlist_btn_changed)
1377         pCurUi->UpdatePlaylistBtnToolTip();
1378 }
1379 
ApplyThemeColor()1380 void CMusicPlayerDlg::ApplyThemeColor()
1381 {
1382     CColorConvert::ConvertColor(theApp.m_app_setting_data.theme_color);
1383     SetPlayListColor();
1384     m_cortana_lyric.SetUIColors();
1385     m_playlist_toolbar.Invalidate();
1386     DrawInfo();
1387     if (m_miniModeDlg.m_hWnd != NULL)
1388     {
1389         m_miniModeDlg.SetPlayListColor();
1390     }
1391 }
1392 
ThemeColorChanged()1393 void CMusicPlayerDlg::ThemeColorChanged()
1394 {
1395     if (!theApp.m_app_setting_data.theme_color_follow_system)
1396         return;
1397     COLORREF color{};
1398     color = CCommon::GetWindowsThemeColor();
1399     CColorConvert::ReduceLuminance(color);              //如果主题颜色过深,就将其降低一点亮度
1400     if (theApp.m_app_setting_data.theme_color.original_color != color && color != RGB(255, 255, 255))   //当前主题色变了的时候重新设置主题色,但是确保获取到的颜色不是纯白色
1401     {
1402         theApp.m_app_setting_data.theme_color.original_color = color;
1403         ApplyThemeColor();
1404         TRACE("Theme color changed: %x\n", color);
1405     }
1406     m_ui_thread_para.ui_force_refresh = true;
1407 }
1408 
SetMenuState(CMenu * pMenu)1409 void CMusicPlayerDlg::SetMenuState(CMenu* pMenu)
1410 {
1411     bool is_main_pop = IsMainWindowPopupMenu(); // 菜单是主窗口弹出的,视为选中当前播放,否则为播放列表弹出,选中项为播放列表选中状态
1412 
1413     //设置循环模式菜单的单选标记
1414     RepeatMode repeat_mode{ CPlayer::GetInstance().GetRepeatMode() };
1415     switch (repeat_mode)
1416     {
1417     case RM_PLAY_ORDER:
1418         pMenu->CheckMenuRadioItem(ID_PLAY_ORDER, ID_PLAY_TRACK, ID_PLAY_ORDER, MF_BYCOMMAND | MF_CHECKED);
1419         break;
1420     case RM_PLAY_SHUFFLE:
1421         pMenu->CheckMenuRadioItem(ID_PLAY_ORDER, ID_PLAY_TRACK, ID_PLAY_SHUFFLE, MF_BYCOMMAND | MF_CHECKED);
1422         break;
1423     case RM_PLAY_RANDOM:
1424         pMenu->CheckMenuRadioItem(ID_PLAY_ORDER, ID_PLAY_TRACK, ID_PLAY_RANDOM, MF_BYCOMMAND | MF_CHECKED);
1425         break;
1426     case RM_LOOP_PLAYLIST:
1427         pMenu->CheckMenuRadioItem(ID_PLAY_ORDER, ID_PLAY_TRACK, ID_LOOP_PLAYLIST, MF_BYCOMMAND | MF_CHECKED);
1428         break;
1429     case RM_LOOP_TRACK:
1430         pMenu->CheckMenuRadioItem(ID_PLAY_ORDER, ID_PLAY_TRACK, ID_LOOP_TRACK, MF_BYCOMMAND | MF_CHECKED);
1431         break;
1432     case RM_PLAY_TRACK:
1433         pMenu->CheckMenuRadioItem(ID_PLAY_ORDER, ID_PLAY_TRACK, ID_PLAY_TRACK, MF_BYCOMMAND | MF_CHECKED);
1434         break;
1435     default:
1436         break;
1437     }
1438 
1439     //弹出右键菜单时,如果没有选中播放列表中的项目,则禁用右键菜单中“播放”、“从列表中删除”、“属性”、“从磁盘删除”项目。
1440     bool selete_valid = m_item_selected >= 0 && m_item_selected < CPlayer::GetInstance().GetSongNum();
1441     bool playlist_mode{ CPlayer::GetInstance().IsPlaylistMode() };
1442     bool can_delete = false;     //选中的曲目是否全是cue音轨或osu音乐,如果是,则不允许“从磁盘删除”、“移动文件到”、“重命名”命令
1443     bool can_copy = false;       //选中的曲目是否全是cue音轨,如果是,则不允许“复制文件到”命令
1444     int rating{};
1445     //bool rating_enable = false;     //分级是否可用
1446     bool single_selected = selete_valid && m_items_selected.size() < 2;     //只选中了一个
1447     SongInfo rating_file_songinfo;
1448     if (is_main_pop)
1449     {
1450         rating_file_songinfo = CPlayer::GetInstance().GetCurrentSongInfo();
1451     }
1452     else if (selete_valid)
1453     {
1454         rating_file_songinfo = CPlayer::GetInstance().GetPlayList()[m_item_selected];
1455     }
1456     if (is_main_pop || single_selected)
1457     {
1458         SongInfo song_info{ CSongDataManager::GetInstance().GetSongInfo3(rating_file_songinfo) };
1459         // 对非cue且支持读取分级的本地音频获取分级
1460         if (!song_info.is_cue && COSUPlayerHelper::IsOsuFile(song_info.file_path) && song_info.rating > 5 && CAudioTag::IsFileRatingSupport(CFilePathHelper(song_info.file_path).GetFileExtension()))      //分级大于5,说明没有获取过分级,在这里重新获取
1461         {
1462             CAudioTag audio_tag(song_info);
1463             audio_tag.GetAudioRating();
1464             CSongDataManager::GetInstance().AddItem(song_info);
1465         }
1466         rating = song_info.rating;
1467 
1468         //rating_enable = CAudioTag::IsFileRatingSupport(CFilePathHelper(rating_file_path).GetFileExtension());
1469     }
1470     //else if (selete_valid)      //多选的情况下,分级命令始终可用
1471     //{
1472     //    rating_enable = true;
1473     //}
1474 
1475     for (auto index : m_items_selected)
1476     {
1477         SongInfo selected_song;
1478         if (index >= 0 && index < CPlayer::GetInstance().GetSongNum())
1479             selected_song = CPlayer::GetInstance().GetPlayList()[index];
1480         if (!selected_song.is_cue && !COSUPlayerHelper::IsOsuFile(selected_song.file_path))
1481             can_delete = true;
1482         if (!selected_song.is_cue)
1483             can_copy = true;
1484         if (can_copy && can_delete)
1485             break;
1486     }
1487     pMenu->EnableMenuItem(ID_PLAY_ITEM, MF_BYCOMMAND | (selete_valid ? MF_ENABLED : MF_GRAYED));
1488     pMenu->EnableMenuItem(ID_PLAY_AS_NEXT, MF_BYCOMMAND | (selete_valid ? MF_ENABLED : MF_GRAYED));
1489     pMenu->EnableMenuItem(ID_REMOVE_FROM_PLAYLIST, MF_BYCOMMAND | (selete_valid && playlist_mode ? MF_ENABLED : MF_GRAYED));
1490     pMenu->EnableMenuItem(ID_ITEM_PROPERTY, MF_BYCOMMAND | (selete_valid ? MF_ENABLED : MF_GRAYED));
1491     pMenu->EnableMenuItem(ID_RENAME, MF_BYCOMMAND | (can_delete ? MF_ENABLED : MF_GRAYED));
1492     pMenu->EnableMenuItem(ID_DELETE_FROM_DISK, MF_BYCOMMAND | (selete_valid && can_delete && !theApp.m_media_lib_setting_data.disable_delete_from_disk ? MF_ENABLED : MF_GRAYED));
1493     pMenu->EnableMenuItem(ID_EXPLORE_ONLINE, MF_BYCOMMAND | (selete_valid ? MF_ENABLED : MF_GRAYED));
1494     pMenu->EnableMenuItem(ID_COPY_FILE_TO, MF_BYCOMMAND | (selete_valid && can_copy ? MF_ENABLED : MF_GRAYED));
1495     pMenu->EnableMenuItem(ID_MOVE_FILE_TO, MF_BYCOMMAND | (selete_valid && can_delete && !theApp.m_media_lib_setting_data.disable_delete_from_disk ? MF_ENABLED : MF_GRAYED));
1496     pMenu->EnableMenuItem(ID_PLAYLIST_VIEW_ARTIST, MF_BYCOMMAND | (single_selected ? MF_ENABLED : MF_GRAYED));
1497     pMenu->EnableMenuItem(ID_PLAYLIST_VIEW_ALBUM, MF_BYCOMMAND | (single_selected ? MF_ENABLED : MF_GRAYED));
1498 
1499     pMenu->EnableMenuItem(ID_PLAYLIST_ADD_FILE, MF_BYCOMMAND | (playlist_mode ? MF_ENABLED : MF_GRAYED));
1500     pMenu->EnableMenuItem(ID_PLAYLIST_ADD_FOLDER, MF_BYCOMMAND | (playlist_mode ? MF_ENABLED : MF_GRAYED));
1501     pMenu->EnableMenuItem(ID_PLAYLIST_ADD_URL, MF_BYCOMMAND | (playlist_mode ? MF_ENABLED : MF_GRAYED));
1502     pMenu->EnableMenuItem(ID_EMPTY_PLAYLIST, MF_BYCOMMAND | (playlist_mode ? MF_ENABLED : MF_GRAYED));
1503     pMenu->EnableMenuItem(ID_REMOVE_SAME_SONGS, MF_BYCOMMAND | (playlist_mode ? MF_ENABLED : MF_GRAYED));
1504     pMenu->EnableMenuItem(ID_REMOVE_INVALID_ITEMS, MF_BYCOMMAND | (playlist_mode ? MF_ENABLED : MF_GRAYED));
1505     pMenu->EnableMenuItem(ID_PLAYLIST_FIX_PATH_ERROR, MF_BYCOMMAND | (playlist_mode ? MF_ENABLED : MF_GRAYED));
1506 
1507     pMenu->EnableMenuItem(ID_CONTAIN_SUB_FOLDER, MF_BYCOMMAND | (CPlayer::GetInstance().IsFolderMode() ? MF_ENABLED : MF_GRAYED));
1508 
1509     //设置分级菜单的选中
1510     if (rating >= 1 && rating <= 5)
1511         pMenu->CheckMenuRadioItem(ID_RATING_1, ID_RATING_NONE, ID_RATING_1 + rating - 1, MF_BYCOMMAND | MF_CHECKED);
1512     else
1513         pMenu->CheckMenuRadioItem(ID_RATING_1, ID_RATING_NONE, ID_RATING_NONE, MF_BYCOMMAND | MF_CHECKED);
1514 
1515     //设置分级菜单的启用/禁用状态
1516     bool rating_menu_emable{ is_main_pop || selete_valid };
1517     pMenu->EnableMenuItem(ID_RATING_1, MF_BYCOMMAND | (rating_menu_emable ? MF_ENABLED : MF_GRAYED));
1518     pMenu->EnableMenuItem(ID_RATING_2, MF_BYCOMMAND | (rating_menu_emable ? MF_ENABLED : MF_GRAYED));
1519     pMenu->EnableMenuItem(ID_RATING_3, MF_BYCOMMAND | (rating_menu_emable ? MF_ENABLED : MF_GRAYED));
1520     pMenu->EnableMenuItem(ID_RATING_4, MF_BYCOMMAND | (rating_menu_emable ? MF_ENABLED : MF_GRAYED));
1521     pMenu->EnableMenuItem(ID_RATING_5, MF_BYCOMMAND | (rating_menu_emable ? MF_ENABLED : MF_GRAYED));
1522     pMenu->EnableMenuItem(ID_RATING_NONE, MF_BYCOMMAND | (rating_menu_emable ? MF_ENABLED : MF_GRAYED));
1523 
1524     bool move_enable = playlist_mode && !m_searched && selete_valid;
1525     pMenu->EnableMenuItem(ID_MOVE_PLAYLIST_ITEM_UP, MF_BYCOMMAND | (move_enable ? MF_ENABLED : MF_GRAYED));
1526     pMenu->EnableMenuItem(ID_MOVE_PLAYLIST_ITEM_DOWN, MF_BYCOMMAND | (move_enable ? MF_ENABLED : MF_GRAYED));
1527 
1528     pMenu->CheckMenuItem(ID_CONTAIN_SUB_FOLDER, MF_BYCOMMAND | (CPlayer::GetInstance().IsContainSubFolder() ? MF_CHECKED : MF_UNCHECKED));
1529 
1530     //设置“添加到播放列表”子菜单项的可用状态
1531     bool add_to_valid{ is_main_pop ? true : selete_valid };
1532     bool playing_default_playlist = CRecentList::Instance().IsPlayingSpecPlaylist(CRecentList::PT_DEFAULT);
1533     pMenu->EnableMenuItem(ID_ADD_TO_DEFAULT_PLAYLIST, MF_BYCOMMAND | (!playing_default_playlist && add_to_valid ? MF_ENABLED : MF_GRAYED));
1534     bool playing_faourite_playlist = CRecentList::Instance().IsPlayingSpecPlaylist(CRecentList::PT_FAVOURITE);
1535     pMenu->EnableMenuItem(ID_ADD_TO_MY_FAVOURITE, MF_BYCOMMAND | (!playing_faourite_playlist && add_to_valid ? MF_ENABLED : MF_GRAYED));
1536     wstring current_playlist{ m_current_cache.at(0).GetDisplayName() };
1537     for (UINT id = ID_ADD_TO_MY_FAVOURITE + 1; id < ID_ADD_TO_MY_FAVOURITE + ADD_TO_PLAYLIST_MAX_SIZE + 1; id++)
1538     {
1539         CString menu_string;
1540         pMenu->GetMenuString(id, menu_string, 0);
1541         pMenu->EnableMenuItem(id, MF_BYCOMMAND | (add_to_valid && current_playlist != menu_string.GetString() ? MF_ENABLED : MF_GRAYED));
1542     }
1543     pMenu->EnableMenuItem(ID_ADD_TO_NEW_PLAYLIST, MF_BYCOMMAND | (add_to_valid ? MF_ENABLED : MF_GRAYED));
1544     pMenu->EnableMenuItem(ID_ADD_TO_OTHER_PLAYLIST, MF_BYCOMMAND | (add_to_valid ? MF_ENABLED : MF_GRAYED));
1545 
1546     //打开菜单时,如果播放列表中没有歌曲,则禁用主菜单和右键菜单中的“打开文件位置”项目
1547     if (CPlayer::GetInstance().GetSongNum() == 0)
1548     {
1549         pMenu->EnableMenuItem(ID_EXPLORE_PATH, MF_BYCOMMAND | MF_GRAYED);
1550         pMenu->EnableMenuItem(ID_EXPLORE_TRACK, MF_BYCOMMAND | MF_GRAYED);
1551         pMenu->EnableMenuItem(ID_EDIT_LYRIC, MF_BYCOMMAND | MF_GRAYED);
1552         pMenu->EnableMenuItem(ID_RELOAD_LYRIC, MF_BYCOMMAND | MF_GRAYED);
1553         pMenu->EnableMenuItem(ID_DOWNLOAD_LYRIC, MF_BYCOMMAND | MF_GRAYED);
1554         pMenu->EnableMenuItem(ID_LYRIC_BATCH_DOWNLOAD, MF_BYCOMMAND | MF_GRAYED);
1555     }
1556     else
1557     {
1558         pMenu->EnableMenuItem(ID_EXPLORE_PATH, MF_BYCOMMAND | MF_ENABLED);
1559         pMenu->EnableMenuItem(ID_EXPLORE_TRACK, MF_BYCOMMAND | MF_ENABLED);
1560         pMenu->EnableMenuItem(ID_EDIT_LYRIC, MF_BYCOMMAND | MF_ENABLED);
1561         pMenu->EnableMenuItem(ID_RELOAD_LYRIC, MF_BYCOMMAND | MF_ENABLED);
1562         pMenu->EnableMenuItem(ID_DOWNLOAD_LYRIC, MF_BYCOMMAND | MF_ENABLED);
1563         pMenu->EnableMenuItem(ID_LYRIC_BATCH_DOWNLOAD, MF_BYCOMMAND | MF_ENABLED);
1564     }
1565 
1566     //设置“视图”菜单下的复选标记
1567     pMenu->CheckMenuItem(ID_SHOW_PLAYLIST, MF_BYCOMMAND | (theApp.m_ui_data.show_playlist ? MF_CHECKED : MF_UNCHECKED));
1568     pMenu->CheckMenuItem(ID_USE_STANDARD_TITLE_BAR, MF_BYCOMMAND | (theApp.m_app_setting_data.show_window_frame ? MF_CHECKED : MF_UNCHECKED));
1569     pMenu->CheckMenuItem(ID_SHOW_MENU_BAR, MF_BYCOMMAND | (theApp.m_ui_data.show_menu_bar ? MF_CHECKED : MF_UNCHECKED));
1570     pMenu->CheckMenuItem(ID_FULL_SCREEN, MF_BYCOMMAND | (theApp.m_ui_data.full_screen ? MF_CHECKED : MF_UNCHECKED));
1571     pMenu->CheckMenuItem(ID_DARK_MODE, MF_BYCOMMAND | (theApp.m_app_setting_data.dark_mode ? MF_CHECKED : MF_UNCHECKED));
1572     pMenu->CheckMenuItem(ID_ALWAYS_ON_TOP, MF_BYCOMMAND | (theApp.m_nc_setting_data.always_on_top ? MF_CHECKED : MF_UNCHECKED));
1573     pMenu->CheckMenuItem(ID_ALWAYS_SHOW_STATUS_BAR, MF_BYCOMMAND | (theApp.m_app_setting_data.always_show_statusbar ? MF_CHECKED : MF_UNCHECKED));
1574 
1575     pMenu->EnableMenuItem(ID_SHOW_MENU_BAR, MF_BYCOMMAND | (theApp.m_ui_data.full_screen /*|| !theApp.m_app_setting_data.show_window_frame*/ ? MF_GRAYED : MF_ENABLED));        //全屏或不使用系统标准标题栏时禁止显示/关闭菜单栏
1576     pMenu->EnableMenuItem(ID_FULL_SCREEN, MF_BYCOMMAND | (m_miniModeDlg.m_hWnd != NULL ? MF_GRAYED : MF_ENABLED));          //迷你模式下禁用全屏模式
1577     //pMenu->EnableMenuItem(ID_MINI_MODE, MF_BYCOMMAND | (theApp.m_ui_data.full_screen ? MF_GRAYED : MF_ENABLED));            //全屏时禁止进入迷你模式
1578 
1579     pMenu->CheckMenuItem(ID_FLOAT_PLAYLIST, MF_BYCOMMAND | (theApp.m_nc_setting_data.float_playlist ? MF_CHECKED : MF_UNCHECKED));
1580 
1581     int ui_selected = GetUiSelected();
1582     pMenu->CheckMenuRadioItem(ID_SWITCH_UI + 1, ID_SWITCH_UI + m_ui_list.size(), ID_SWITCH_UI + 1 + ui_selected, MF_BYCOMMAND | MF_CHECKED);
1583 
1584     // 设置播放列表菜单中排序方式的图标
1585     const CBitmap* bitmap_sort_up = theApp.m_menu_mgr.GetMenuBitmap(IconMgr::IconType::IT_Triangle_Up);
1586     const CBitmap* bitmap_sort_down = theApp.m_menu_mgr.GetMenuBitmap(IconMgr::IconType::IT_Triangle_Down);
1587     std::array<const CBitmap*, 8> pSortBitmap{};
1588     switch (CPlayer::GetInstance().m_sort_mode)
1589     {
1590     case SM_U_FILE: pSortBitmap[0] = bitmap_sort_up; break;
1591     case SM_D_FILE: pSortBitmap[0] = bitmap_sort_down; break;
1592     case SM_U_PATH: pSortBitmap[1] = bitmap_sort_up; break;
1593     case SM_D_PATH: pSortBitmap[1] = bitmap_sort_down; break;
1594     case SM_U_TITLE: pSortBitmap[2] = bitmap_sort_up; break;
1595     case SM_D_TITLE: pSortBitmap[2] = bitmap_sort_down; break;
1596     case SM_U_ARTIST: pSortBitmap[3] = bitmap_sort_up; break;
1597     case SM_D_ARTIST: pSortBitmap[3] = bitmap_sort_down; break;
1598     case SM_U_ALBUM: pSortBitmap[4] = bitmap_sort_up; break;
1599     case SM_D_ALBUM: pSortBitmap[4] = bitmap_sort_down; break;
1600     case SM_U_TRACK: pSortBitmap[5] = bitmap_sort_up; break;
1601     case SM_D_TRACK: pSortBitmap[5] = bitmap_sort_down; break;
1602     case SM_U_LISTEN: pSortBitmap[6] = bitmap_sort_up; break;
1603     case SM_D_LISTEN: pSortBitmap[6] = bitmap_sort_down; break;
1604     case SM_U_TIME: pSortBitmap[7] = bitmap_sort_up; break;
1605     case SM_D_TIME: pSortBitmap[7] = bitmap_sort_down; break;
1606     default: break;
1607     }
1608     pMenu->SetMenuItemBitmaps(ID_SORT_BY_FILE, MF_BYCOMMAND, pSortBitmap[0], NULL);
1609     pMenu->SetMenuItemBitmaps(ID_SORT_BY_PATH, MF_BYCOMMAND, pSortBitmap[1], NULL);
1610     pMenu->SetMenuItemBitmaps(ID_SORT_BY_TITLE, MF_BYCOMMAND, pSortBitmap[2], NULL);
1611     pMenu->SetMenuItemBitmaps(ID_SORT_BY_ARTIST, MF_BYCOMMAND, pSortBitmap[3], NULL);
1612     pMenu->SetMenuItemBitmaps(ID_SORT_BY_ALBUM, MF_BYCOMMAND, pSortBitmap[4], NULL);
1613     pMenu->SetMenuItemBitmaps(ID_SORT_BY_TRACK, MF_BYCOMMAND, pSortBitmap[5], NULL);
1614     pMenu->SetMenuItemBitmaps(ID_SORT_BY_LISTEN_TIME, MF_BYCOMMAND, pSortBitmap[6], NULL);
1615     pMenu->SetMenuItemBitmaps(ID_SORT_BY_MODIFIED_TIME, MF_BYCOMMAND, pSortBitmap[7], NULL);
1616 
1617 
1618     //设置播放列表菜单中“播放列表显示样式”的单选标记
1619     switch (theApp.m_media_lib_setting_data.display_format)
1620     {
1621     case DF_FILE_NAME:
1622         pMenu->CheckMenuRadioItem(ID_DISP_FILE_NAME, ID_DISP_TITLE_ARTIST, ID_DISP_FILE_NAME, MF_BYCOMMAND | MF_CHECKED);
1623         break;
1624     case DF_TITLE:
1625         pMenu->CheckMenuRadioItem(ID_DISP_FILE_NAME, ID_DISP_TITLE_ARTIST, ID_DISP_TITLE, MF_BYCOMMAND | MF_CHECKED);
1626         break;
1627     case DF_ARTIST_TITLE:
1628         pMenu->CheckMenuRadioItem(ID_DISP_FILE_NAME, ID_DISP_TITLE_ARTIST, ID_DISP_ARTIST_TITLE, MF_BYCOMMAND | MF_CHECKED);
1629         break;
1630     case DF_TITLE_ARTIST:
1631         pMenu->CheckMenuRadioItem(ID_DISP_FILE_NAME, ID_DISP_TITLE_ARTIST, ID_DISP_TITLE_ARTIST, MF_BYCOMMAND | MF_CHECKED);
1632         break;
1633     }
1634 
1635     if (theApp.m_media_lib_setting_data.playlist_btn_for_float_playlist)
1636         pMenu->CheckMenuRadioItem(ID_DOCKED_PLAYLIST, ID_FLOATED_PLAYLIST, ID_FLOATED_PLAYLIST, MF_BYCOMMAND | MF_CHECKED);
1637     else
1638         pMenu->CheckMenuRadioItem(ID_DOCKED_PLAYLIST, ID_FLOATED_PLAYLIST, ID_DOCKED_PLAYLIST, MF_BYCOMMAND | MF_CHECKED);
1639 
1640     //根据歌词是否存在设置启用或禁用菜单项
1641     bool midi_lyric{ CPlayer::GetInstance().IsMidi() && theApp.m_play_setting_data.midi_use_inner_lyric && !CPlayer::GetInstance().MidiNoLyric() };
1642     bool lyric_disable{ midi_lyric || CPlayer::GetInstance().m_Lyrics.IsEmpty() };
1643     bool no_lyric{ CPlayer::GetInstance().m_Lyrics.IsEmpty() && CPlayer::GetInstance().MidiNoLyric() };
1644     //pMenu->EnableMenuItem(ID_RELOAD_LYRIC, MF_BYCOMMAND | (!CPlayer::GetInstance().m_Lyrics.IsEmpty() ? MF_ENABLED : MF_GRAYED));
1645     pMenu->EnableMenuItem(ID_COPY_CURRENT_LYRIC, MF_BYCOMMAND | (!no_lyric ? MF_ENABLED : MF_GRAYED));
1646     pMenu->EnableMenuItem(ID_COPY_ALL_LYRIC, MF_BYCOMMAND | (!lyric_disable ? MF_ENABLED : MF_GRAYED));
1647     //pMenu->EnableMenuItem(ID_EDIT_LYRIC, MF_BYCOMMAND | (!CPlayer::GetInstance().m_Lyrics.IsEmpty() ? MF_ENABLED : MF_GRAYED));
1648     pMenu->EnableMenuItem(ID_LYRIC_FORWARD, MF_BYCOMMAND | (!lyric_disable ? MF_ENABLED : MF_GRAYED));
1649     pMenu->EnableMenuItem(ID_LYRIC_DELAY, MF_BYCOMMAND | (!lyric_disable ? MF_ENABLED : MF_GRAYED));
1650     pMenu->EnableMenuItem(ID_SAVE_MODIFIED_LYRIC, MF_BYCOMMAND | ((!lyric_disable && CPlayer::GetInstance().m_Lyrics.IsModified()) ? MF_ENABLED : MF_GRAYED));
1651     if (midi_lyric)
1652         pMenu->EnableMenuItem(ID_DELETE_LYRIC, MF_BYCOMMAND | MF_GRAYED);
1653     else
1654         pMenu->EnableMenuItem(ID_DELETE_LYRIC, MF_BYCOMMAND | (CCommon::FileExist(CPlayer::GetInstance().m_Lyrics.GetPathName()) ? MF_ENABLED : MF_GRAYED));        //当歌词文件存在时启用“删除歌词”菜单项
1655     pMenu->EnableMenuItem(ID_BROWSE_LYRIC, MF_BYCOMMAND | (!lyric_disable && !CPlayer::GetInstance().IsInnerLyric() ? MF_ENABLED : MF_GRAYED));
1656     pMenu->EnableMenuItem(ID_TRANSLATE_TO_SIMPLIFIED_CHINESE, MF_BYCOMMAND | (!lyric_disable ? MF_ENABLED : MF_GRAYED));
1657     pMenu->EnableMenuItem(ID_TRANSLATE_TO_TRANDITIONAL_CHINESE, MF_BYCOMMAND | (!lyric_disable ? MF_ENABLED : MF_GRAYED));
1658     pMenu->EnableMenuItem(ID_RELOAD_LYRIC, MF_BYCOMMAND | (!midi_lyric ? MF_ENABLED : MF_GRAYED));
1659     pMenu->EnableMenuItem(ID_EDIT_LYRIC, MF_BYCOMMAND | (!midi_lyric ? MF_ENABLED : MF_GRAYED));
1660     pMenu->EnableMenuItem(ID_DOWNLOAD_LYRIC, MF_BYCOMMAND | (!midi_lyric && !CPlayer::GetInstance().IsInnerLyric() ? MF_ENABLED : MF_GRAYED));
1661     pMenu->EnableMenuItem(ID_UNLINK_LYRIC, MF_BYCOMMAND | (!lyric_disable && !CPlayer::GetInstance().IsInnerLyric() ? MF_ENABLED : MF_GRAYED));
1662 
1663     pMenu->CheckMenuItem(ID_SHOW_LYRIC_TRANSLATE, MF_BYCOMMAND | (theApp.m_lyric_setting_data.show_translate ? MF_CHECKED : MF_UNCHECKED));
1664     pMenu->EnableMenuItem(ID_SHOW_LYRIC_TRANSLATE, MF_BYCOMMAND | (!CPlayer::GetInstance().m_Lyrics.IsEmpty() ? MF_ENABLED : MF_GRAYED));
1665 
1666     //内嵌歌词
1667     SongInfo cur_song_ori{ CSongDataManager::GetInstance().GetSongInfo3(CPlayer::GetInstance().GetCurrentSongInfo()) };
1668     bool lyric_write_support = CAudioTag::IsFileTypeLyricWriteSupport(CFilePathHelper(cur_song_ori.file_path).GetFileExtension());
1669     lyric_write_support &= !cur_song_ori.is_cue && !COSUPlayerHelper::IsOsuFile(cur_song_ori.file_path);    // 对cue与osu文件禁止写入
1670     bool lyric_write_enable = (lyric_write_support && !CPlayer::GetInstance().m_Lyrics.IsEmpty() && !CPlayer::GetInstance().IsInnerLyric());
1671     bool lyric_delete_enable = (lyric_write_support && !CPlayer::GetInstance().m_Lyrics.IsEmpty());
1672     pMenu->EnableMenuItem(ID_EMBED_LYRIC_TO_AUDIO_FILE, MF_BYCOMMAND | (lyric_write_enable ? MF_ENABLED : MF_GRAYED));
1673     pMenu->EnableMenuItem(ID_DELETE_LYRIC_FROM_AUDIO_FILE, MF_BYCOMMAND | (lyric_delete_enable ? MF_ENABLED : MF_GRAYED));
1674 
1675     //专辑封面
1676     pMenu->EnableMenuItem(ID_ALBUM_COVER_SAVE_AS, MF_BYCOMMAND | (CPlayer::GetInstance().AlbumCoverExist() ? MF_ENABLED : MF_GRAYED));
1677     pMenu->EnableMenuItem(ID_DOWNLOAD_ALBUM_COVER, MF_BYCOMMAND | (!CPlayer::GetInstance().IsOsuFile() && !CPlayer::GetInstance().IsInnerCover() ? MF_ENABLED : MF_GRAYED));
1678     pMenu->EnableMenuItem(ID_DELETE_ALBUM_COVER, MF_BYCOMMAND | ((!CPlayer::GetInstance().IsOsuFile() /*&& !CPlayer::GetInstance().IsInnerCover()*/ && CPlayer::GetInstance().AlbumCoverExist()) ? MF_ENABLED : MF_GRAYED));
1679     pMenu->EnableMenuItem(ID_ALBUM_COVER_INFO, MF_BYCOMMAND | (CPlayer::GetInstance().AlbumCoverExist() ? MF_ENABLED : MF_GRAYED));
1680 
1681     //正在执行格式转换时禁用“格式转换”菜单项
1682     pMenu->EnableMenuItem(ID_FORMAT_CONVERT, MF_BYCOMMAND | (theApp.m_format_convert_dialog_exit ? MF_ENABLED : MF_GRAYED));
1683     pMenu->EnableMenuItem(ID_FORMAT_CONVERT1, MF_BYCOMMAND | (theApp.m_format_convert_dialog_exit ? MF_ENABLED : MF_GRAYED));
1684 
1685     //桌面歌词
1686     pMenu->CheckMenuItem(ID_LOCK_DESKTOP_LRYIC, MF_BYCOMMAND | (theApp.m_lyric_setting_data.desktop_lyric_data.lock_desktop_lyric ? MF_CHECKED : MF_UNCHECKED));
1687     pMenu->CheckMenuItem(ID_LYRIC_DISPLAYED_DOUBLE_LINE, MF_BYCOMMAND | (theApp.m_lyric_setting_data.desktop_lyric_data.lyric_double_line ? MF_CHECKED : MF_UNCHECKED));
1688     pMenu->CheckMenuItem(ID_LYRIC_BACKGROUND_PENETRATE, MF_BYCOMMAND | (theApp.m_lyric_setting_data.desktop_lyric_data.lyric_background_penetrate ? MF_CHECKED : MF_UNCHECKED));
1689     pMenu->CheckMenuItem(ID_SHOW_DESKTOP_LYRIC, MF_BYCOMMAND | (theApp.m_lyric_setting_data.show_desktop_lyric ? MF_CHECKED : MF_UNCHECKED));
1690     pMenu->EnableMenuItem(ID_LOCK_DESKTOP_LRYIC, MF_BYCOMMAND | (theApp.m_lyric_setting_data.show_desktop_lyric ? MF_ENABLED : MF_GRAYED));
1691 
1692     bool current_song_valid{ !CPlayer::GetInstance().IsError() && !CPlayer::GetInstance().IsPlaylistEmpty() };
1693 
1694     //播放控制
1695     pMenu->EnableMenuItem(ID_REW, MF_BYCOMMAND | (current_song_valid ? MF_ENABLED : MF_GRAYED));
1696     pMenu->EnableMenuItem(ID_FF, MF_BYCOMMAND | (current_song_valid ? MF_ENABLED : MF_GRAYED));
1697     pMenu->EnableMenuItem(ID_SPEED_UP, MF_BYCOMMAND | (current_song_valid ? MF_ENABLED : MF_GRAYED));
1698     pMenu->EnableMenuItem(ID_SLOW_DOWN, MF_BYCOMMAND | (current_song_valid ? MF_ENABLED : MF_GRAYED));
1699     pMenu->EnableMenuItem(ID_ORIGINAL_SPEED, MF_BYCOMMAND | (current_song_valid ? MF_ENABLED : MF_GRAYED));
1700     pMenu->EnableMenuItem(ID_PITCH_UP, MF_BYCOMMAND | (current_song_valid ? MF_ENABLED : MF_GRAYED));
1701     pMenu->EnableMenuItem(ID_PITCH_DOWN, MF_BYCOMMAND | (current_song_valid ? MF_ENABLED : MF_GRAYED));
1702     pMenu->EnableMenuItem(ID_ORIGINAL_PITCH, MF_BYCOMMAND | (current_song_valid ? MF_ENABLED : MF_GRAYED));
1703 
1704     //AB重复
1705     pMenu->EnableMenuItem(ID_NEXT_AB_REPEAT, MF_BYCOMMAND | (current_song_valid && CPlayer::GetInstance().GetABRepeatMode() == CPlayer::AM_AB_REPEAT ? MF_ENABLED : MF_GRAYED));
1706     pMenu->EnableMenuItem(ID_SET_B_POINT, MF_BYCOMMAND | (current_song_valid && CPlayer::GetInstance().GetABRepeatMode() != CPlayer::AM_NONE ? MF_ENABLED : MF_GRAYED));
1707     pMenu->EnableMenuItem(ID_AB_REPEAT, MF_BYCOMMAND | (current_song_valid ? MF_ENABLED : MF_GRAYED));
1708     pMenu->EnableMenuItem(ID_SET_A_POINT, MF_BYCOMMAND | (current_song_valid ? MF_ENABLED : MF_GRAYED));
1709     pMenu->EnableMenuItem(ID_RESET_AB_REPEAT, MF_BYCOMMAND | (current_song_valid ? MF_ENABLED : MF_GRAYED));
1710 
1711     // 工具->删除正在播放的曲目
1712     pMenu->EnableMenuItem(ID_REMOVE_CURRENT_FROM_PLAYLIST, MF_BYCOMMAND | (playlist_mode && !CPlayer::GetInstance().IsPlaylistEmpty() ? MF_ENABLED : MF_GRAYED));
1713     pMenu->EnableMenuItem(ID_DELETE_CURRENT_FROM_DISK, MF_BYCOMMAND | (!theApp.m_media_lib_setting_data.disable_delete_from_disk && !CPlayer::GetInstance().IsPlaylistEmpty() ? MF_ENABLED : MF_GRAYED));
1714 
1715     //专辑封面
1716     bool always_use_external_album_cover{ cur_song_ori.AlwaysUseExternalAlbumCover() };
1717     pMenu->CheckMenuItem(ID_ALWAYS_USE_EXTERNAL_ALBUM_COVER, (always_use_external_album_cover ? MF_CHECKED : MF_UNCHECKED));
1718 }
1719 
1720 
SetPlaylistSelected(const vector<int> & indexes)1721 void CMusicPlayerDlg::SetPlaylistSelected(const vector<int>& indexes)
1722 {
1723     if (!indexes.empty())
1724         m_item_selected = indexes.front();
1725     else
1726         m_item_selected = -1;
1727     m_items_selected = indexes;
1728     m_playlist_list.SetCurSel(indexes);
1729     if (m_pFloatPlaylistDlg->GetSafeHwnd() != NULL)
1730         m_pFloatPlaylistDlg->GetListCtrl().SetCurSel(indexes);
1731 }
1732 
SetUiPlaylistSelected(int index)1733 void CMusicPlayerDlg::SetUiPlaylistSelected(int index)
1734 {
1735     CUserUi* user_ui{ dynamic_cast<CUserUi*>(GetCurrentUi()) };
1736     if (user_ui != nullptr)
1737     {
1738         user_ui->IterateAllElements<UiElement::Playlist>([index](UiElement::Playlist* playlist_element) ->bool {
1739             playlist_element->SetItemSelected(index);
1740             return false;
1741         });
1742         m_ui_thread_para.ui_force_refresh = true;
1743     }
1744 }
1745 
ShowFloatPlaylist()1746 void CMusicPlayerDlg::ShowFloatPlaylist()
1747 {
1748     theApp.m_nc_setting_data.float_playlist = true;
1749     if (IsFloatPlaylistExist())
1750     {
1751         m_pFloatPlaylistDlg->ShowWindow(SW_RESTORE);
1752         return;
1753     }
1754 
1755     CCommon::DeleteModelessDialog(m_pFloatPlaylistDlg);
1756     m_pFloatPlaylistDlg = new CFloatPlaylistDlg(m_item_selected, m_items_selected);
1757     m_pFloatPlaylistDlg->SetInitPoint(m_float_playlist_pos);
1758     m_pFloatPlaylistDlg->Create(IDD_MUSICPLAYER2_DIALOG, theApp.m_media_lib_setting_data.float_playlist_follow_main_wnd ? this : GetDesktopWindow());
1759     m_pFloatPlaylistDlg->ShowWindow(SW_SHOW);
1760     if (!MoveFloatPlaylistPos())
1761     {
1762         if (!IsPointValid(m_float_playlist_pos))
1763             m_pFloatPlaylistDlg->CenterWindow();
1764     }
1765 
1766     theApp.m_ui_data.show_playlist = false;
1767     SetPlaylistVisible();
1768     CRect rect;
1769     GetClientRect(rect);
1770     SetDrawAreaSize(rect.Width(), rect.Height(), CalculatePlaylistWidth(rect.Width()));       //调整绘图区域的大小和位置
1771     DrawInfo(true);
1772 }
1773 
HideFloatPlaylist()1774 void CMusicPlayerDlg::HideFloatPlaylist()
1775 {
1776     OnFloatPlaylistClosed(0, 0);
1777     CCommon::DeleteModelessDialog(m_pFloatPlaylistDlg);
1778     theApp.m_nc_setting_data.float_playlist = false;
1779 }
1780 
ShowHidePlaylist()1781 void CMusicPlayerDlg::ShowHidePlaylist()
1782 {
1783     m_pUI->ClearInfo();
1784     theApp.m_ui_data.show_playlist = !theApp.m_ui_data.show_playlist;
1785 
1786     if (theApp.m_ui_data.show_playlist)
1787         HideFloatPlaylist();
1788 
1789     SetPlaylistVisible();
1790     CRect rect;
1791     GetClientRect(rect);
1792     int playlsit_size = CalculatePlaylistWidth(rect.Width());
1793     SetDrawAreaSize(rect.Width(), rect.Height(), playlsit_size);       //调整绘图区域的大小和位置
1794     SetPlaylistSize(rect.Width(), rect.Height(), playlsit_size);
1795 
1796     DrawInfo(true);
1797 }
1798 
ShowHideFloatPlaylist()1799 void CMusicPlayerDlg::ShowHideFloatPlaylist()
1800 {
1801     if (IsFloatPlaylistExist() && m_pFloatPlaylistDlg->IsIconic())
1802     {
1803         m_pFloatPlaylistDlg->ShowWindow(SW_RESTORE);
1804         return;
1805     }
1806     theApp.m_nc_setting_data.float_playlist = !theApp.m_nc_setting_data.float_playlist;
1807     if (theApp.m_nc_setting_data.float_playlist)
1808     {
1809         ShowFloatPlaylist();
1810     }
1811     else
1812     {
1813         HideFloatPlaylist();
1814     }
1815 }
1816 
GetPlaylistItemSelected(int cur_index)1817 void CMusicPlayerDlg::GetPlaylistItemSelected(int cur_index)
1818 {
1819     if (!m_searched)
1820     {
1821         m_item_selected = cur_index;  //获取鼠标选中的项目
1822         m_playlist_list.GetItemSelected(m_items_selected);      //获取多个选中的项目
1823     }
1824     else
1825     {
1826         CString str;
1827         str = m_playlist_list.GetItemText(cur_index, 0);
1828         m_item_selected = _ttoi(str) - 1;
1829         m_playlist_list.GetItemSelectedSearched(m_items_selected);
1830     }
1831 
1832 }
1833 
GetPlaylistItemSelected()1834 void CMusicPlayerDlg::GetPlaylistItemSelected()
1835 {
1836     GetPlaylistItemSelected(m_playlist_list.GetCurSel());
1837 }
1838 
IniPlaylistPopupMenu()1839 void CMusicPlayerDlg::IniPlaylistPopupMenu()
1840 {
1841     //向“添加到播放列表”菜单更新播放列表
1842     vector<MenuMgr::MenuItem> menu_list;
1843     CListCache playlist_cache(LT_PLAYLIST);
1844     playlist_cache.reload();
1845     for (size_t i{}; i < playlist_cache.size(); ++i)
1846     {
1847         if (CRecentList::IsSpecPlaylist(playlist_cache.at(i)))
1848             continue;
1849         UINT id = ID_ADD_TO_MY_FAVOURITE + 1 + menu_list.size();
1850         wstring name = CFilePathHelper(playlist_cache.at(i).path).GetFileNameWithoutExtension();
1851         menu_list.emplace_back(MenuMgr::MenuItem{ id, IconMgr::IconType::IT_NO_ICON, name });
1852         if (menu_list.size() >= ADD_TO_PLAYLIST_MAX_SIZE)
1853             break;
1854     }
1855     theApp.m_menu_mgr.UpdateMenu(MenuMgr::AddToPlaylistMenu, menu_list);
1856 }
1857 
InitUiMenu()1858 void CMusicPlayerDlg::InitUiMenu()
1859 {
1860     vector<MenuMgr::MenuItem> menu_list;
1861     for (size_t i{}; i < m_ui_list.size(); ++i)
1862     {
1863         if (menu_list.size() >= SELECT_UI_MAX_SIZE + 1)
1864             break;
1865         wstring str_name = m_ui_list[i]->GetUIName();       // 获取界面的名称
1866         if (str_name.empty())   // 如果名称为空(没有指定名称),则使用“界面 +数字”的默认名称
1867             str_name = theApp.m_str_table.LoadTextFormat(L"TXT_UI_NAME_DEFAULT", { m_ui_list[i]->GetUiIndex() });
1868         if (i < 9)              // 如果界面的序号在9以内,为其分配Ctrl+数字的快捷键
1869             str_name += L"\tCtrl+" + std::to_wstring(i + 1);
1870         if (i == 9)             // 第10个界面分配快捷键C+0
1871             str_name += L"\tCtrl+0";
1872         if (i == 2)
1873             menu_list.emplace_back(MenuMgr::MenuItem{});    // 在外部UI前插入一个分割条
1874         UINT id = ID_SWITCH_UI + i + 1;
1875         menu_list.emplace_back(MenuMgr::MenuItem{ id, IconMgr::IconType::IT_NO_ICON, str_name });
1876     }
1877     theApp.m_menu_mgr.UpdateMenu(MenuMgr::MainViewSwitchUiMenu, menu_list);
1878 }
1879 
SetPlaylistDragEnable()1880 void CMusicPlayerDlg::SetPlaylistDragEnable()
1881 {
1882     bool enable = CPlayer::GetInstance().IsPlaylistMode() && !theApp.m_media_lib_setting_data.disable_drag_sort && !m_searched;   //处于播放列表模式且不处理搜索状态时才允许拖动排序
1883     m_playlist_list.SetDragEnable(enable);
1884 
1885     if (m_pFloatPlaylistDlg->GetSafeHwnd() != NULL)
1886         m_pFloatPlaylistDlg->SetDragEnable();
1887     if (m_miniModeDlg.GetSafeHwnd() != NULL)
1888         m_miniModeDlg.SetDragEnable();
1889 }
1890 
_OnOptionSettings(CWnd * pParent)1891 void CMusicPlayerDlg::_OnOptionSettings(CWnd* pParent)
1892 {
1893     m_hot_key.UnRegisterAllHotKey();
1894     try
1895     {
1896         // 设置窗口类的内存申请从栈移动到堆以修正警告
1897         std::shared_ptr<COptionsDlg> pOptionDlg = std::make_shared<COptionsDlg>(pParent);
1898         //初始化对话框中变量的值
1899         pOptionDlg->m_tab_selected = m_tab_selected;
1900         pOptionDlg->m_tab1_dlg.m_data = theApp.m_lyric_setting_data;
1901         pOptionDlg->m_tab1_dlg.m_pDesktopLyric = &m_desktop_lyric;
1902         if (m_miniModeDlg.m_hWnd == NULL)
1903             pOptionDlg->m_tab2_dlg.m_hMainWnd = m_hWnd;
1904         else
1905             pOptionDlg->m_tab2_dlg.m_hMainWnd = m_miniModeDlg.m_hWnd;
1906         pOptionDlg->m_tab2_dlg.m_data = theApp.m_app_setting_data;
1907         pOptionDlg->m_tab3_dlg.m_data = theApp.m_general_setting_data;
1908         pOptionDlg->m_tab4_dlg.m_data = theApp.m_play_setting_data;
1909         pOptionDlg->m_tab5_dlg.m_hotkey_group = m_hot_key.GetHotKeyGroup();
1910         pOptionDlg->m_tab5_dlg.m_data = theApp.m_hot_key_setting_data;
1911         pOptionDlg->m_media_lib_dlg.m_data = theApp.m_media_lib_setting_data;
1912 
1913         int sprctrum_height = theApp.m_app_setting_data.sprctrum_height;        //保存theApp.m_app_setting_data.sprctrum_height的值,如果用户点击了选项对话框的取消,则需要把恢复为原来的
1914         int background_transparency = theApp.m_app_setting_data.background_transparency;        //同上
1915         int desktop_lyric_opacity = theApp.m_lyric_setting_data.desktop_lyric_data.opacity;
1916 
1917         if (pOptionDlg->DoModal() == IDOK)
1918         {
1919             ApplySettings(*pOptionDlg);
1920         }
1921         else
1922         {
1923             SetTransparency();      //如果点击了取消,则需要重新设置窗口透明度
1924             SetDesptopLyricTransparency();
1925 
1926             if (m_miniModeDlg.m_hWnd != NULL)
1927                 m_miniModeDlg.SetTransparency();
1928 
1929             theApp.m_app_setting_data.sprctrum_height = sprctrum_height;
1930             theApp.m_app_setting_data.background_transparency = background_transparency;
1931             theApp.m_lyric_setting_data.desktop_lyric_data.opacity = desktop_lyric_opacity;
1932         }
1933 
1934         m_tab_selected = pOptionDlg->m_tab_selected;
1935     }
1936     catch (std::bad_alloc)
1937     {
1938         // 这里暂时不处理了,只是保险起见
1939     }
1940     if (theApp.m_hot_key_setting_data.hot_key_enable)
1941         m_hot_key.RegisterAllHotKey();
1942 }
1943 
DoLyricsAutoSave(bool no_inquiry)1944 void CMusicPlayerDlg::DoLyricsAutoSave(bool no_inquiry)
1945 {
1946     bool midi_lyric{ CPlayerUIHelper::IsMidiLyric() };
1947     bool lyric_disable{ midi_lyric || CPlayer::GetInstance().m_Lyrics.IsEmpty() };
1948     if (!lyric_disable && CPlayer::GetInstance().m_Lyrics.IsModified())     //如果有歌词修改过
1949     {
1950         switch (theApp.m_lyric_setting_data.lyric_save_policy)
1951         {
1952         case LyricSettingData::LS_DO_NOT_SAVE:
1953             break;
1954         case LyricSettingData::LS_AUTO_SAVE:
1955             OnSaveModifiedLyric();
1956             break;
1957         case LyricSettingData::LS_INQUIRY:
1958         {
1959             const wstring& info = theApp.m_str_table.LoadText(L"MSG_LYRIC_SAVE_INRUARY");
1960             if (no_inquiry || MessageBoxW(info.c_str(), NULL, MB_YESNO | MB_ICONQUESTION) == IDYES)     // 仅当MessageBox按下是时保存
1961             {
1962                 OnSaveModifiedLyric();
1963             }
1964             break;
1965         }
1966         default:
1967             break;
1968         }
1969     }
1970 }
1971 
UpdateABRepeatToolTip()1972 void CMusicPlayerDlg::UpdateABRepeatToolTip()
1973 {
1974     wstring tip_str;
1975     if (CPlayer::GetInstance().GetABRepeatMode() == CPlayer::AM_A_SELECTED)
1976         tip_str = theApp.m_str_table.LoadTextFormat(L"UI_TXT_AB_REPEAT_A_SELECTED", { CPlayer::GetInstance().GetARepeatPosition().toString(false) });
1977     else if (CPlayer::GetInstance().GetABRepeatMode() == CPlayer::AM_AB_REPEAT)
1978         tip_str = theApp.m_str_table.LoadTextFormat(L"UI_TXT_AB_REPEAT_ON", { CPlayer::GetInstance().GetARepeatPosition().toString(false), CPlayer::GetInstance().GetBRepeatPosition().toString(false) });
1979     else
1980         tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_AB_REPEAT") + CPlayerUIBase::GetCmdShortcutKeyForTooltips(ID_AB_REPEAT).GetString();
1981     m_pUI->UpdateMouseToolTip(CPlayerUIBase::BTN_AB_REPEAT, tip_str.c_str());
1982 }
1983 
LoadDefaultBackground()1984 void CMusicPlayerDlg::LoadDefaultBackground()
1985 {
1986     CSingleLock sync(&theApp.m_ui_data.default_background_sync, TRUE);
1987     theApp.m_ui_data.default_background.Destroy();
1988     CString background_img;
1989     if (theApp.m_app_setting_data.use_desktop_background)
1990         background_img = CCommon::GetDesktopBackgroundPath();
1991     else
1992         background_img = theApp.m_app_setting_data.default_background.c_str();
1993     theApp.m_ui_data.default_background.Load(background_img);
1994     if (theApp.m_ui_data.default_background.IsNull())
1995         theApp.m_ui_data.default_background.Load((theApp.m_local_dir + DEFAULT_BACKGROUND_NAME).c_str());
1996     if (theApp.m_ui_data.default_background.IsNull())
1997         theApp.m_ui_data.default_background.LoadFromResource(AfxGetResourceHandle(), IDB_DEFAULT_COVER);
1998     }
1999 
SelectUi(int ui_selected)2000 void CMusicPlayerDlg::SelectUi(int ui_selected)
2001 {
2002     if (ui_selected < 0 || ui_selected >= static_cast<int>(m_ui_list.size()))
2003         ui_selected = 0;
2004     m_pUI = m_ui_list[ui_selected].get();
2005 
2006     CUserUi* user_ui{ dynamic_cast<CUserUi*>(m_pUI) };
2007     if (user_ui != nullptr)
2008         user_ui->ListLocateToCurrent();
2009 }
2010 
GetUiSelected() const2011 int CMusicPlayerDlg::GetUiSelected() const
2012 {
2013     for (int i{}; i < static_cast<int>(m_ui_list.size()); i++)
2014     {
2015         if (m_pUI == m_ui_list[i].get())
2016             return i;
2017     }
2018     return 0;
2019 }
2020 
GetCurrentUi()2021 CPlayerUIBase* CMusicPlayerDlg::GetCurrentUi()
2022 {
2023     if (m_miniModeDlg.m_hWnd != NULL)
2024         return m_miniModeDlg.GetCurUi();
2025     else
2026         return dynamic_cast<CPlayerUIBase*>(m_pUI);
2027 }
2028 
GetScreenInfo()2029 void CMusicPlayerDlg::GetScreenInfo()
2030 {
2031     theApp.m_screen_rects.clear();
2032     Monitors monitors;
2033     for (auto& a : monitors.monitorinfos)
2034     {
2035         theApp.m_screen_rects.push_back(a.rcWork); // 获取各显示器工作区
2036     }
2037 }
2038 
MoveDesktopLyricWindowPos()2039 void CMusicPlayerDlg::MoveDesktopLyricWindowPos()
2040 {
2041     CRect rcLyric;
2042     ::GetWindowRect(m_desktop_lyric.GetSafeHwnd(), rcLyric);
2043     rcLyric += CCommon::CalculateWindowMoveOffset(rcLyric, theApp.m_screen_rects);
2044     ::SetWindowPos(m_desktop_lyric.GetSafeHwnd(), nullptr, rcLyric.left, rcLyric.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
2045 }
2046 
IsFloatPlaylistExist()2047 bool CMusicPlayerDlg::IsFloatPlaylistExist()
2048 {
2049     return (m_pFloatPlaylistDlg != nullptr && IsWindow(m_pFloatPlaylistDlg->GetSafeHwnd()));
2050 }
2051 
OnInitDialog()2052 BOOL CMusicPlayerDlg::OnInitDialog()
2053 {
2054     //载入设置
2055     LoadConfig();
2056     LoadUiData();
2057 
2058     // 载入&初始化最近播放列表列表
2059     CRecentList::Instance().LoadData();
2060 
2061     CMainDialogBase::OnInitDialog();
2062 
2063     theApp.UpdateUiMeidaLibItems();
2064 
2065     // 载入图标资源
2066     theApp.LoadImgResource();
2067     // 载入字体资源
2068     theApp.m_font_set.Init(theApp.m_str_table.GetDefaultFontName().c_str());
2069 
2070     // 多语言主窗口资源移除后各窗口对象的->GetFont()不再自动跟随语言设置
2071     // 我没有找到能够修改其返回值的方法,暂时改为使用m_font_set中的字体
2072     // 设置窗口字体
2073     CCommon::SetDialogFont(this, &theApp.m_font_set.dlg.GetFont());
2074 
2075     // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动执行此操作
2076 
2077     SetIcon(m_hIcon, TRUE);         // 设置大图标
2078     SetIcon(m_hIcon, FALSE);        // 设置小图标
2079 
2080     // TODO: 在此添加额外的初始化代码
2081 
2082     // 获取窗口信息
2083     GetScreenInfo();
2084 
2085     //如果以迷你模式启动,则先隐藏主窗口
2086     if (theApp.m_cmd & ControlCmd::MINI_MODE)
2087     {
2088         CCommon::SetWindowOpacity(m_hWnd, 0);
2089     }
2090 
2091     m_hAccel = LoadAccelerators(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_ACCELERATOR1));
2092 
2093 
2094     m_miniModeDlg.Init();
2095 
2096     for (auto& ui : m_ui_list)
2097     {
2098         CUserUi* cur_ui{ dynamic_cast<CUserUi*>(ui.get()) };
2099         if (cur_ui != nullptr)
2100             cur_ui->InitSearchBox(this);
2101     }
2102 
2103     //只有Windows Vista以上的系统才能跟随系统主题色
2104 #ifdef COMPILE_IN_WIN_XP
2105     theApp.m_app_setting_data.theme_color_follow_system = false;
2106     //#else
2107     //  if (!CWinVersionHelper::IsWindows8OrLater())
2108     //      theApp.m_app_setting_data.theme_color_follow_system = false;
2109 #endif
2110 
2111     //只有Win10以上的系统才能在Cortana搜索框中显示歌词
2112     if (!CWinVersionHelper::IsWindows10OrLater())
2113         theApp.m_lyric_setting_data.cortana_info_enable = false;
2114     m_cortana_lyric.SetEnable(CWinVersionHelper::IsWindows10OrLater());
2115 
2116     //设置桌面歌词窗口不透明度
2117     SetDesptopLyricTransparency();
2118 
2119     //初始化窗口大小
2120     //rect.right = m_window_width;
2121     //rect.bottom = m_window_height;
2122     if (m_window_height != -1 && m_window_width != -1)
2123     {
2124         //MoveWindow(rect);
2125         SetWindowPos(nullptr, 0, 0, m_window_width, m_window_height, SWP_NOZORDER | SWP_NOMOVE);
2126     }
2127 
2128     ShowTitlebar(theApp.m_app_setting_data.show_window_frame);
2129 
2130     // 测量主窗口受翻译字符串影响的控件所需宽度,并应用翻译字符串到控件
2131     CString text;
2132     CRect text_size;
2133     CDC* pDC = GetDC();
2134     pDC->SelectObject(&theApp.m_font_set.dlg.GetFont());
2135     text = theApp.m_str_table.LoadText(L"TXT_FOLDER").c_str();
2136     m_path_static.SetWindowTextW(text);
2137     // 媒体库按钮宽度
2138     text = theApp.m_str_table.LoadText(L"UI_TXT_BTN_MEDIA_LIB").c_str();
2139     m_media_lib_button.SetWindowTextW(text);
2140     pDC->DrawTextW(text, &text_size, DT_CALCRECT);
2141     if (m_medialib_btn_width < text_size.Width() + theApp.DPI(40))
2142         m_medialib_btn_width = min(text_size.Width() + theApp.DPI(40), theApp.DPI(150));
2143     ReleaseDC(pDC);
2144 
2145     //初始化提示信息
2146     m_tool_tip.Create(this, TTS_ALWAYSTIP);
2147     m_tool_tip.SetMaxTipWidth(theApp.DPI(400));
2148     wstring tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_MEDIA_LIB") + CPlayerUIBase::GetCmdShortcutKeyForTooltips(ID_MEDIA_LIB).GetString();
2149     m_tool_tip.AddTool(GetDlgItem(ID_MEDIA_LIB), tip_str.c_str());
2150 
2151     SetMenubarVisible();
2152 
2153     m_media_lib_button.SetIcon(theApp.m_icon_mgr.GetHICON(IconMgr::IconType::IT_Media_Lib, IconMgr::IconStyle::IS_OutlinedDark, IconMgr::IconSize::IS_DPI_16));
2154 
2155     wstring prompt_str = theApp.m_str_table.LoadText(L"TXT_SEARCH_PROMPT") + L"(F)";
2156     m_search_edit.SetCueBanner(prompt_str.c_str(), TRUE);
2157 
2158     //CoInitialize(0);  //初始化COM组件,用于支持任务栏显示进度和缩略图按钮
2159 #ifndef COMPILE_IN_WIN_XP
2160     //if (CWinVersionHelper::IsWindows7OrLater())
2161     //  CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&m_pTaskbar)); //创建ITaskbarList3的实例
2162 
2163     //初始化任务栏缩略图中的按钮
2164     THUMBBUTTONMASK dwMask = THB_ICON | THB_TOOLTIP | THB_FLAGS;
2165     //上一曲按钮
2166     m_thumbButton[0].dwMask = dwMask;
2167     m_thumbButton[0].iId = IDT_PREVIOUS;
2168     m_thumbButton[0].hIcon = theApp.m_icon_mgr.GetHICON(IconMgr::IconType::IT_Previous, IconMgr::IconStyle::IS_Filled, IconMgr::IconSize::IS_DPI_16);
2169     wcscpy_s(m_thumbButton[0].szTip, theApp.m_str_table.LoadText(L"UI_TIP_BTN_PREVIOUS").c_str());
2170     m_thumbButton[0].dwFlags = THBF_ENABLED;
2171     //播放/暂停按钮
2172     m_thumbButton[1].dwMask = dwMask;
2173     m_thumbButton[1].iId = IDT_PLAY_PAUSE;
2174     m_thumbButton[1].hIcon = theApp.m_icon_mgr.GetHICON(IconMgr::IconType::IT_Play, IconMgr::IconStyle::IS_Filled, IconMgr::IconSize::IS_DPI_16);
2175     wcscpy_s(m_thumbButton[1].szTip, theApp.m_str_table.LoadText(L"UI_TIP_BTN_PLAY").c_str());
2176     m_thumbButton[1].dwFlags = THBF_ENABLED;
2177     //下一曲按钮
2178     m_thumbButton[2].dwMask = dwMask;
2179     m_thumbButton[2].iId = IDT_NEXT;
2180     m_thumbButton[2].hIcon = theApp.m_icon_mgr.GetHICON(IconMgr::IconType::IT_Next, IconMgr::IconStyle::IS_Filled, IconMgr::IconSize::IS_DPI_16);
2181     wcscpy_s(m_thumbButton[2].szTip, theApp.m_str_table.LoadText(L"UI_TIP_BTN_NEXT").c_str());
2182     m_thumbButton[2].dwFlags = THBF_ENABLED;
2183 #endif
2184 
2185     //注册接收音频设备变化通知回调的IMMNotificationClient接口
2186     devicesManager = new CDevicesManager;
2187     devicesManager->InitializeDeviceEnumerator();
2188 
2189     // 注册休眠/睡眠状态唤醒事件通知
2190     if (CWinVersionHelper::IsWindows8OrLater())
2191     {
2192         static _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS NotifyCallback = { DeviceNotifyCallbackRoutine, nullptr };
2193         DWORD rtn = PowerRegisterSuspendResumeNotification(DEVICE_NOTIFY_CALLBACK, &NotifyCallback, &RegistrationHandle);
2194         ASSERT(rtn == ERROR_SUCCESS);
2195     }
2196 
2197     //注册全局热键
2198     if (theApp.m_hot_key_setting_data.hot_key_enable)
2199         m_hot_key.RegisterAllHotKey();
2200 
2201     //设置界面的颜色
2202     CColorConvert::ConvertColor(theApp.m_app_setting_data.theme_color);
2203 
2204     //初始化查找对话框中的数据
2205     m_findDlg.LoadChildrenConfig();
2206 
2207     //获取Cortana歌词
2208     m_cortana_lyric.Init();
2209 
2210     //初始化桌面歌词
2211     m_desktop_lyric.Create();
2212     m_desktop_lyric.ApplySettings(theApp.m_lyric_setting_data.desktop_lyric_data);
2213     if (m_desktop_lyric_size.cx > 0 && m_desktop_lyric_size.cy > 0) // 尺寸大于0视为桌面歌词位置信息已存在,由于多显示器允许负坐标使 pos == -1 不再可靠
2214     {
2215         if (m_desktop_lyric_size.cx < theApp.DPI(400))              // 桌面歌词位置设置存在时进行最小尺寸检查
2216             m_desktop_lyric_size.cx = theApp.DPI(400);
2217         if (m_desktop_lyric_size.cy < theApp.DPI(100))
2218             m_desktop_lyric_size.cy = theApp.DPI(100);
2219         ::SetWindowPos(m_desktop_lyric.GetSafeHwnd(), nullptr, m_desktop_lyric_pos.x, m_desktop_lyric_pos.y, m_desktop_lyric_size.cx, m_desktop_lyric_size.cy, SWP_NOZORDER);
2220     }
2221     MoveDesktopLyricWindowPos();                                    // 移动桌面歌词窗口到可见位置
2222 
2223     //初始化绘图的类
2224     m_pUiDC = m_ui_static_ctrl.GetDC();
2225     //m_draw.Create(m_pDC, this);
2226     for (const auto& ui : m_ui_list)
2227     {
2228         ui->Init(m_pUiDC);
2229     }
2230 
2231     InitUiMenu();
2232 
2233     //初始化歌词字体
2234     theApp.m_font_set.lyric.SetFont(theApp.m_lyric_setting_data.lyric_font);
2235     FontInfo translate_font = theApp.m_lyric_setting_data.lyric_font;
2236     translate_font.size--;
2237     theApp.m_font_set.lyric_translate.SetFont(translate_font);
2238 
2239     //载入默认背景图片(用于没有专辑封面时显示)
2240     LoadDefaultBackground();
2241 
2242     if (theApp.m_app_setting_data.notify_icon_selected < 0 || theApp.m_app_setting_data.notify_icon_selected >= MAX_NOTIFY_ICON)
2243         theApp.m_app_setting_data.notify_icon_selected = 0;
2244     m_notify_icon.Init(theApp.GetNotifyIncon(theApp.m_app_setting_data.notify_icon_selected));
2245     m_notify_icon.AddNotifyIcon();
2246 
2247     //初始化播放列表工具栏
2248     wstring menu_str;
2249     m_playlist_toolbar.SetIconSize(theApp.DPI(20));
2250     menu_str = theApp.m_str_table.LoadText(L"UI_TXT_PLAYLIST_TOOLBAR_ADD");
2251     m_playlist_toolbar.AddToolButton(IconMgr::IconType::IT_Add, menu_str.c_str(), menu_str.c_str(), theApp.m_menu_mgr.GetMenu(MenuMgr::MainPlaylistAddMenu), true);
2252     menu_str = theApp.m_str_table.LoadText(L"UI_TXT_PLAYLIST_TOOLBAR_DELETE");
2253     m_playlist_toolbar.AddToolButton(IconMgr::IconType::IT_Cancel, menu_str.c_str(), menu_str.c_str(), theApp.m_menu_mgr.GetMenu(MenuMgr::MainPlaylistDelMenu), true);
2254     menu_str = theApp.m_str_table.LoadText(L"UI_TXT_PLAYLIST_TOOLBAR_SORT");
2255     m_playlist_toolbar.AddToolButton(IconMgr::IconType::IT_Sort_Mode, menu_str.c_str(), menu_str.c_str(), theApp.m_menu_mgr.GetMenu(MenuMgr::MainPlaylistSortMenu), true);
2256     menu_str = theApp.m_str_table.LoadText(L"UI_TXT_PLAYLIST_TOOLBAR_LIST");
2257     m_playlist_toolbar.AddToolButton(IconMgr::IconType::IT_Playlist, menu_str.c_str(), menu_str.c_str(), theApp.m_menu_mgr.GetMenu(MenuMgr::PlaylistToolBarListMenu), true);
2258     menu_str = theApp.m_str_table.LoadText(L"UI_TXT_PLAYLIST_TOOLBAR_EDIT");
2259     m_playlist_toolbar.AddToolButton(IconMgr::IconType::IT_Edit, menu_str.c_str(), menu_str.c_str(), theApp.m_menu_mgr.GetMenu(MenuMgr::PlaylistToolBarEditMenu), true);
2260     menu_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_LOCATE_TO_CURRENT") + CPlayerUIBase::GetCmdShortcutKeyForTooltips(ID_LOCATE_TO_CURRENT).GetString();
2261     m_playlist_toolbar.AddToolButton(IconMgr::IconType::IT_Locate, nullptr, menu_str.c_str(), ID_LOCATE_TO_CURRENT);
2262 
2263     //初始化分隔条
2264     m_splitter_ctrl.RegAdjustLayoutCallBack(CMusicPlayerDlg::OnSplitterChanged);
2265     SLayoutData layout_data;
2266     m_splitter_ctrl.SetMinWidth(layout_data.width_threshold / 2, layout_data.width_threshold / 2);
2267 
2268     //设置定时器
2269     //SetTimer(TIMER_ID, theApp.m_app_setting_data.ui_refresh_interval, NULL);
2270     SetTimer(TIMER_ID, TIMER_ELAPSE, NULL);
2271     SetTimer(TIMER_1_SEC, 1000, NULL);
2272 
2273     return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
2274 }
2275 
OnSysCommand(UINT nID,LPARAM lParam)2276 void CMusicPlayerDlg::OnSysCommand(UINT nID, LPARAM lParam)
2277 {
2278     DWORD cmd = nID & 0xFFF0;
2279     /*if (cmd == IDM_ABOUTBOX)
2280     {
2281         CAboutDlg dlgAbout;
2282         dlgAbout.DoModal();
2283     }
2284     else if (cmd == IDM_MINIMODE)
2285     {
2286         OnMiniMode();
2287     }
2288     else*/
2289     {
2290         CMainDialogBase::OnSysCommand(nID, lParam);
2291     }
2292 
2293     if (nID >= 0x8000)
2294     {
2295         SendMessage(WM_COMMAND, nID);
2296     }
2297 }
2298 
2299 // 如果向对话框添加最小化按钮,则需要下面的代码
2300 //  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
2301 //  这将由框架自动完成。
2302 
OnPaint()2303 void CMusicPlayerDlg::OnPaint()
2304 {
2305     if (IsIconic())
2306     {
2307         CPaintDC dc(this); // 用于绘制的设备上下文
2308 
2309         SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
2310 
2311         // 使图标在工作区矩形中居中
2312         int cxIcon = GetSystemMetrics(SM_CXICON);
2313         int cyIcon = GetSystemMetrics(SM_CYICON);
2314         CRect rect;
2315         GetClientRect(&rect);
2316         int x = (rect.Width() - cxIcon + 1) / 2;
2317         int y = (rect.Height() - cyIcon + 1) / 2;
2318 
2319         // 绘制图标
2320         dc.DrawIcon(x, y, m_hIcon);
2321     }
2322     else
2323     {
2324         CMainDialogBase::OnPaint();
2325     }
2326     //DrawInfo();
2327 }
2328 
2329 //当用户拖动最小化窗口时系统调用此函数取得光标
2330 //显示。
OnQueryDragIcon()2331 HCURSOR CMusicPlayerDlg::OnQueryDragIcon()
2332 {
2333     return static_cast<HCURSOR>(m_hIcon);
2334 }
2335 
2336 
OnSize(UINT nType,int cx,int cy)2337 void CMusicPlayerDlg::OnSize(UINT nType, int cx, int cy)
2338 {
2339     CMainDialogBase::OnSize(nType, cx, cy);
2340     if (nType != SIZE_MINIMIZED && m_pUI != nullptr)
2341     {
2342         //if (m_pUiDC != NULL)
2343         //{
2344         //    DrawInfo(true);
2345         //    if ((cx < m_ui.WidthThreshold()) != theApp.m_ui_data.narrow_mode) //如果在窄界面模式和普通模式之间进行了切换,则重绘客户区
2346         //    {
2347         //        Invalidate(FALSE);
2348         //        //m_time_static.Invalidate(FALSE);
2349         //    }
2350         //    //m_pUI->OnSizeRedraw(cx, cy);
2351         //}
2352         CPlayerUIBase* pUiBase = dynamic_cast<CPlayerUIBase*>(m_pUI);
2353         if (pUiBase->WidthThreshold() != 0)
2354         {
2355             theApp.m_ui_data.narrow_mode = (cx < pUiBase->WidthThreshold());
2356             //if (!theApp.m_ui_data.show_playlist)
2357             //  theApp.m_ui_data.narrow_mode = false;
2358         }
2359         if (m_playlist_list.m_hWnd)
2360         {
2361             SetPlaylistSize(cx, cy, CalculatePlaylistWidth(cx));
2362             m_splitter_ctrl.Invalidate();
2363         }
2364         SetDrawAreaSize(cx, cy, CalculatePlaylistWidth(cx));
2365 
2366         if (nType == SIZE_RESTORED)
2367         {
2368             if (IsFloatPlaylistExist())
2369             {
2370                 m_pFloatPlaylistDlg->ShowWindow(SW_SHOW);
2371             }
2372         }
2373 
2374         if (nType != SIZE_MAXIMIZED && !theApp.m_ui_data.full_screen)
2375         {
2376             CRect rect;
2377             GetWindowRect(&rect);
2378             m_window_width = rect.Width();
2379             m_window_height = rect.Height();
2380 
2381             MoveFloatPlaylistPos();
2382         }
2383 
2384         //窗口大小变化时更新界面鼠标提示的位置
2385         static UINT last_type;
2386         if (last_type != nType)
2387         {
2388             if (m_pUI != nullptr)
2389                 DrawInfo(true);
2390             if (pUiBase != nullptr)
2391                 pUiBase->UpdateTitlebarBtnToolTip();
2392         }
2393         last_type = nType;
2394     }
2395     if (nType == SIZE_MINIMIZED)
2396     {
2397         if (IsFloatPlaylistExist())
2398             m_pFloatPlaylistDlg->ShowWindow(SW_HIDE);
2399 
2400     }
2401 
2402 
2403     // TODO: 在此处添加消息处理程序代码
2404 }
2405 
2406 
OnTimer(UINT_PTR nIDEvent)2407 void CMusicPlayerDlg::OnTimer(UINT_PTR nIDEvent)
2408 {
2409     // TODO: 在此添加消息处理程序代码和/或调用默认值
2410 
2411     static std::atomic<bool> cmd_open_files_disable{ true };    // 用于阻止TIMER_CMD_OPEN_FILES_DELAY重入以及在避免在CPlayer::Create之前触发
2412     //响应主定时器
2413     if (nIDEvent == TIMER_ID)
2414     {
2415         if (m_first_start)
2416         {
2417             //此if语句只在定时器第1次触发时才执行
2418             m_first_start = false;
2419             CRect rect;
2420             GetClientRect(rect);
2421             //theApp.m_ui_data.client_width = rect.Width();
2422             //theApp.m_ui_data.client_height = rect.Height();
2423             SetPlaylistSize(rect.Width(), rect.Height(), CalculatePlaylistWidth(rect.Width()));       //调整播放列表的大小和位置
2424             m_path_static.Invalidate();
2425             SetPlaylistVisible();
2426 
2427             if (m_cmdLine.empty())      //没有有通过命令行打开文件
2428             {
2429                 CPlayer::GetInstance().Create();
2430             }
2431             else if (m_cmdLine.find(L"RestartByRestartManager") != wstring::npos)       //如果命令行参数中有RestartByRestartManager,则忽略命令行参数
2432             {
2433                 CPlayer::GetInstance().Create();
2434                 ////将命令行参数写入日志文件
2435                 //wchar_t buff[256];
2436                 //swprintf_s(buff, L"程序已被Windows的RestartManager重启,重启参数:%s", m_cmdLine.c_str());
2437                 //theApp.WriteLog(wstring{ buff });
2438             }
2439             else        //从命令行参数获取要打开的文件
2440             {
2441                 bool open_default_playlist{ true };
2442                 vector<wstring> files;
2443                 CCommon::DisposeCmdLineFiles(m_cmdLine, files);
2444                 if (!files.empty())
2445                 {
2446                     if (CPlaylistFile::IsPlaylistFile(files.front()))
2447                     {
2448                         CPlayer::GetInstance().CreateWithPlaylist(files.front());
2449                         files.erase(files.begin());
2450                         open_default_playlist = false;
2451                     }
2452                     else if (CCommon::IsFolder(files.front()))
2453                     {
2454                         CPlayer::GetInstance().CreateWithPath(files.front());
2455                         files.erase(files.begin());
2456                         open_default_playlist = false;
2457                     }
2458                 }
2459                 if (open_default_playlist)
2460                 {
2461                     CPlayer::GetInstance().CreateWithPlaylist(CRecentList::Instance().GetSpecPlaylist(CRecentList::PT_DEFAULT).path);
2462                 }
2463                 if (!files.empty())
2464                 {
2465                     std::unique_lock<std::mutex> lock(m_cmd_open_files_mutx);
2466                     // theApp.WriteLog(m_cmdLine + L"<from_first_timer>");
2467                     m_cmd_open_files.insert(m_cmd_open_files.begin(), files.begin(), files.end());  // 当前实例成功创建互斥量,故插入到开头
2468                     SetTimer(TIMER_CMD_OPEN_FILES_DELAY, 1000, nullptr);
2469                 }
2470             }
2471             cmd_open_files_disable = false;
2472             DrawInfo();
2473             m_uiThread = AfxBeginThread(UiThreadFunc, (LPVOID)&m_ui_thread_para);
2474 
2475             TaskBarInit();
2476 
2477             ThemeColorChanged();
2478 
2479             //设置窗口不透明度
2480             SetTransparency();
2481 
2482             if (theApp.m_nc_setting_data.float_playlist && theApp.m_media_lib_setting_data.playlist_btn_for_float_playlist)
2483                 ShowFloatPlaylist();
2484 
2485             IniPlaylistPopupMenu();
2486 
2487             //命令行有迷你模式参数,则启动时直接进入迷你模式
2488             if (theApp.m_cmd & ControlCmd::MINI_MODE)
2489             {
2490                 OnMiniMode();
2491             }
2492 
2493             //提示用户是否创建桌面快捷方式
2494             FirstRunCreateShortcut();
2495 
2496             SetAlwaysOnTop();
2497         }
2498 
2499         m_timer_count++;
2500 
2501         UpdateTaskBarProgress();
2502 
2503         // 判断主窗口是否具有焦点
2504         CWnd* pActiveWnd = GetActiveWindow();
2505         m_ui_thread_para.is_active_window = (pActiveWnd == this);
2506 
2507         // 判断主窗口是否被前端窗口完全覆盖
2508         bool is_covered{ false };
2509         CWnd* pForegroundWnd = GetForegroundWindow();
2510         if (pForegroundWnd != this && pForegroundWnd != nullptr)        // 如果主窗口为前端窗口或没有成功获取前端窗口
2511         {
2512             CRect rectWholeDlg, rectWholeForegroundDlg;
2513             GetWindowRect(&rectWholeDlg);                               // 得到当前窗体的总的相对于屏幕的坐标
2514             pForegroundWnd->GetWindowRect(&rectWholeForegroundDlg);     // 得到前端窗体的总的相对于屏幕的坐标
2515             if (rectWholeForegroundDlg.left <= rectWholeDlg.left
2516                 && rectWholeForegroundDlg.top <= rectWholeDlg.top
2517                 && rectWholeForegroundDlg.right >= rectWholeDlg.right
2518                 && rectWholeForegroundDlg.bottom >= rectWholeDlg.bottom
2519                 && pForegroundWnd->IsZoomed()
2520                 )                           // 判断前端窗口是否完全覆盖主窗口
2521             {
2522                 BYTE pbAlpha{};
2523                 DWORD pdwFlags{};
2524                 pForegroundWnd->GetLayeredWindowAttributes(NULL, &pbAlpha, &pdwFlags);
2525                 // 指定颜色进行透明的窗口视为透明,按Alpha进行透明的窗口当透明度不为255时视为透明,透明窗口不会覆盖主窗口
2526                 is_covered = !(pdwFlags == 1 || (pdwFlags == 2 && pbAlpha != 255));
2527             }
2528         }
2529         m_ui_thread_para.is_completely_covered = is_covered;
2530 
2531 
2532         //获取频谱分析数据
2533         CPlayer::GetInstance().CalculateSpectralData();
2534 
2535 
2536         // 这里在更改播放状态,需要先取得锁,没有成功取得锁的话下次再试
2537         if (CPlayer::GetInstance().GetPlayStatusMutex().try_lock())
2538         {
2539             //if (CPlayer::GetInstance().SongIsOver() && (!theApp.m_lyric_setting_data.stop_when_error || !CPlayer::GetInstance().IsError()))   //当前曲目播放完毕且没有出现错误时才播放下一曲
2540             if ((CPlayer::GetInstance().SongIsOver() || (!theApp.m_play_setting_data.stop_when_error && (CPlayer::GetInstance().IsError() || CPlayer::GetInstance().GetSongLength() <= 0)))
2541                 && m_play_error_cnt <= CPlayer::GetInstance().GetSongNum()
2542                 && CPlayer::GetInstance().IsFileOpened()) //当前曲目播放完毕且没有出现错误时才播放下一曲
2543             {
2544                 if (CPlayer::GetInstance().IsError() || CPlayer::GetInstance().GetSongLength() <= 0)
2545                     m_play_error_cnt++;
2546                 else
2547                     m_play_error_cnt = 0;
2548                 // 如果当前正在编辑歌词,播放完当前歌曲就停止播放,否则使用CPlayer::PlayTrack进行播放下一曲处理(播放完毕时PlayTrack会进行停止)
2549                 if (m_pLyricEdit != nullptr && m_pLyricEdit->m_dlg_exist)
2550                 {
2551                     CPlayer::GetInstance().MusicControl(Command::STOP);     //停止播放
2552                     if (theApp.m_lyric_setting_data.cortana_info_enable)
2553                         m_cortana_lyric.ResetCortanaText();
2554                     SwitchTrack();
2555                     UpdatePlayPauseButton();
2556                 }
2557                 else
2558                     CPlayer::GetInstance().PlayTrack(NEXT, true);
2559             }
2560             if (CPlayer::GetInstance().IsPlaying() && (theApp.m_play_setting_data.stop_when_error && CPlayer::GetInstance().IsError()))
2561             {
2562                 CPlayer::GetInstance().MusicControl(Command::PAUSE);
2563                 UpdatePlayPauseButton();
2564             }
2565 
2566             //处理AB重复
2567             if (CPlayer::GetInstance().GetABRepeatMode() == CPlayer::AM_AB_REPEAT)
2568             {
2569                 Time a_position = CPlayer::GetInstance().GetARepeatPosition();
2570                 Time b_position = CPlayer::GetInstance().GetBRepeatPosition();
2571                 if (a_position > CPlayer::GetInstance().GetSongLength() || b_position > CPlayer::GetInstance().GetSongLength())
2572                 {
2573                     CPlayer::GetInstance().ResetABRepeat();
2574                     UpdateABRepeatToolTip();
2575                 }
2576                 else
2577                 {
2578                     Time current_play_time{ CPlayer::GetInstance().GetCurrentPosition() };
2579                     if (current_play_time < CPlayer::GetInstance().GetARepeatPosition() || current_play_time > CPlayer::GetInstance().GetBRepeatPosition())
2580                     {
2581                         CPlayer::GetInstance().SeekTo(CPlayer::GetInstance().GetARepeatPosition().toInt());
2582                     }
2583                 }
2584             }
2585             CPlayer::GetInstance().GetPlayStatusMutex().unlock();
2586         }
2587 
2588         if (CWinVersionHelper::IsWindowsVista())
2589         {
2590             if (m_timer_count % 15 == 14)
2591                 ThemeColorChanged();
2592         }
2593 
2594         if (m_timer_count % 600 == 599)
2595         {
2596             //CPlayer::GetInstance().EmplaceCurrentPathToRecent();
2597             //CPlayer::GetInstance().SaveRecentPath();
2598             if (CSongDataManager::GetInstance().IsSongDataModified())               //在歌曲信息被修改过的情况下,每隔一定的时间保存一次
2599                 theApp.SaveSongData();
2600         }
2601     }
2602 
2603     //响应1秒定时器
2604     else if (nIDEvent == TIMER_1_SEC)
2605     {
2606         m_one_sec_timer_counter++;
2607         if (CPlayer::GetInstance().IsPlaying())
2608         {
2609             CPlayer::GetInstance().AddListenTime(1);
2610         }
2611 
2612         CWinVersionHelper::CheckWindows10LightTheme();
2613         m_cortana_lyric.SetDarkMode(!CWinVersionHelper::IsWindows10LightTheme());
2614 
2615         //根据当前Win10颜色模式自动切换通知区图标
2616         if (theApp.m_app_setting_data.notify_icon_auto_adapt)
2617         {
2618             int notify_icon_selected = theApp.m_app_setting_data.notify_icon_selected;
2619             theApp.AutoSelectNotifyIcon();
2620             if (notify_icon_selected != theApp.m_app_setting_data.notify_icon_selected)
2621             {
2622                 m_notify_icon.SetIcon(theApp.GetNotifyIncon(theApp.m_app_setting_data.notify_icon_selected));
2623                 m_notify_icon.DeleteNotifyIcon();
2624                 m_notify_icon.AddNotifyIcon();
2625             }
2626         }
2627 
2628         //响应主题颜色变化(两秒响应一次)
2629         if (m_one_sec_timer_counter % 2 == 1 && m_theme_color_changed)
2630         {
2631             //响应主题颜色改变消息
2632             ThemeColorChanged();
2633 
2634             //如果设置了使用桌面背景为背景,则重新载入背景图片
2635             if (theApp.m_app_setting_data.use_desktop_background)
2636                 LoadDefaultBackground();
2637 
2638             //响应完成后重置标志
2639             m_theme_color_changed = false;
2640         }
2641 
2642         //每隔一秒保存一次统计的帧率
2643         theApp.m_fps = m_fps_cnt;
2644         m_fps_cnt = 0;
2645     }
2646 
2647     else if (nIDEvent == CUserUi::SHOW_VOLUME_TIMER_ID)
2648     {
2649         CUserUi* cur_ui = dynamic_cast<CUserUi*>(GetCurrentUi());
2650         if (cur_ui != nullptr)
2651             cur_ui->ResetVolumeToPlayTime();
2652     }
2653 
2654     // 距最后一次设置此定时器1s,说明已经1s没有收到copy_data消息,将m_cmd_open_files内容设为当前播放
2655     else if (nIDEvent == TIMER_CMD_OPEN_FILES_DELAY && !cmd_open_files_disable)
2656     {
2657         cmd_open_files_disable = true;
2658         // 这里会在一次一次的回调中先逐个打开并移除m_cmd_open_files中的播放列表/文件夹条目
2659         // m_cmd_open_files中不含播放列表/文件夹后将剩余歌曲一次在默认播放列表打开并清空m_cmd_open_files
2660         // m_cmd_open_files为空后再KillTimer
2661         wstring path_playlist, path_folder, path_playlist_new;
2662         vector<wstring> path_songs;
2663         m_cmd_open_files_mutx.lock();
2664         auto iter_p = std::find_if(m_cmd_open_files.begin(), m_cmd_open_files.end(),
2665             [&](const wstring& path) { return CPlaylistFile::IsPlaylistFile(path); });
2666         if (iter_p != m_cmd_open_files.end())
2667             path_playlist = *iter_p;
2668         else
2669         {
2670             auto iter_f = std::find_if(m_cmd_open_files.begin(), m_cmd_open_files.end(),
2671                 [&](const wstring& path) { return CCommon::IsFolder(path); });
2672             if (iter_f != m_cmd_open_files.end())
2673                 path_folder = *iter_f;
2674             else
2675                 path_songs = m_cmd_open_files;
2676         }
2677         m_cmd_open_files_mutx.unlock();
2678         // CPlayer的初始化方法会向主线程发消息而主线程的copy_data有可能正在等待获取这个锁故需要先解锁,否则有可能死锁
2679         if (!path_playlist.empty())
2680         {
2681             path_playlist_new = path_playlist;
2682             if (CPlayer::GetInstance().OpenPlaylistFile(path_playlist_new))   // 注意OpenPlaylistFile会修改参数,需将修改结果反映到m_cmd_open_files,防止反复复制播放列表
2683                 path_playlist_new.clear();  // 下面的行为是path_playlist_new为空直接移除path_playlist,否则将m_cmd_open_files中的path_playlist替换为path_playlist_new
2684         }
2685         else if (!path_folder.empty())
2686         {
2687             if (!CPlayer::GetInstance().OpenFolder(path_folder))
2688                 path_folder.clear();
2689         }
2690         else
2691         {
2692             if (!CPlayer::GetInstance().OpenFilesInDefaultPlaylist(path_songs))
2693                 path_songs.clear();
2694         }
2695         m_cmd_open_files_mutx.lock();
2696         if (!path_playlist.empty())
2697         {
2698             auto iter = std::find(m_cmd_open_files.begin(), m_cmd_open_files.end(), path_playlist);
2699             if (iter != m_cmd_open_files.end())
2700             {
2701                 if (!path_playlist_new.empty())
2702                     *iter = path_playlist_new;
2703                 else
2704                     m_cmd_open_files.erase(iter);
2705             }
2706         }
2707         else if (!path_folder.empty())
2708         {
2709             auto iter = std::find(m_cmd_open_files.begin(), m_cmd_open_files.end(), path_folder);
2710             if (iter != m_cmd_open_files.end())
2711             {
2712                 m_cmd_open_files.erase(iter);
2713             }
2714         }
2715         else if (!path_songs.empty())
2716         {
2717             // 因为中间解锁过所以m_cmd_open_files和path_songs不一定相同,不能直接清空m_cmd_open_files
2718             auto new_end = std::remove_if(m_cmd_open_files.begin(), m_cmd_open_files.end(),
2719                 [&](const wstring& path) { return CCommon::IsItemInVector(path_songs, path); });
2720             m_cmd_open_files.erase(new_end, m_cmd_open_files.end());
2721         }
2722         // 如果m_cmd_open_files已全部处理完成则关闭定时器,否则下次时间到再尝试
2723         if (m_cmd_open_files.empty())
2724             KillTimer(TIMER_CMD_OPEN_FILES_DELAY);
2725         m_cmd_open_files_mutx.unlock();
2726         cmd_open_files_disable = false;
2727     }
2728 
2729     CMainDialogBase::OnTimer(nIDEvent);
2730 }
2731 
2732 
OnPlayPause()2733 void CMusicPlayerDlg::OnPlayPause()
2734 {
2735     // TODO: 在此添加命令处理程序代码
2736     if (CPlayer::GetInstance().m_loading) return;   // 这行大概率能够防止播放列表初始化线程工作时try_lock_for无意义等待
2737     if (!CPlayer::GetInstance().GetPlayStatusMutex().try_lock_for(std::chrono::milliseconds(1000))) return;
2738 
2739     CPlayer::GetInstance().MusicControl(Command::PLAY_PAUSE);
2740     if (!CPlayer::GetInstance().IsPlaying())
2741         DrawInfo();
2742     UpdatePlayPauseButton();
2743     m_ui_thread_para.search_box_force_refresh = true;
2744     m_ui_thread_para.ui_force_refresh = true;
2745 
2746     CPlayer::GetInstance().GetPlayStatusMutex().unlock();
2747 }
2748 
OnPlay()2749 void CMusicPlayerDlg::OnPlay()
2750 {
2751     // TODO: 在此添加命令处理程序代码
2752     if (CPlayer::GetInstance().m_loading) return;
2753     if (!CPlayer::GetInstance().GetPlayStatusMutex().try_lock_for(std::chrono::milliseconds(1000))) return;
2754 
2755     CPlayer::GetInstance().MusicControl(Command::PLAY);
2756     UpdatePlayPauseButton();
2757     m_ui_thread_para.search_box_force_refresh = true;
2758     m_ui_thread_para.ui_force_refresh = true;
2759 
2760     CPlayer::GetInstance().GetPlayStatusMutex().unlock();
2761 }
2762 
OnPause()2763 void CMusicPlayerDlg::OnPause()
2764 {
2765     // TODO: 在此添加命令处理程序代码
2766     if (CPlayer::GetInstance().m_loading) return;
2767     if (!CPlayer::GetInstance().GetPlayStatusMutex().try_lock_for(std::chrono::milliseconds(1000))) return;
2768 
2769     CPlayer::GetInstance().MusicControl(Command::PAUSE);
2770     UpdatePlayPauseButton();
2771     m_ui_thread_para.search_box_force_refresh = true;
2772     m_ui_thread_para.ui_force_refresh = true;
2773 
2774     CPlayer::GetInstance().GetPlayStatusMutex().unlock();
2775 }
2776 
2777 
OnStop()2778 void CMusicPlayerDlg::OnStop()
2779 {
2780     // TODO: 在此添加命令处理程序代码
2781     if (CPlayer::GetInstance().m_loading) return;
2782     if (!CPlayer::GetInstance().GetPlayStatusMutex().try_lock_for(std::chrono::milliseconds(1000))) return;
2783 
2784     CPlayer::GetInstance().MusicControl(Command::STOP);
2785     UpdatePlayPauseButton();
2786     //ShowTime();
2787     m_ui_thread_para.search_box_force_refresh = true;
2788     m_ui_thread_para.ui_force_refresh = true;
2789 
2790     CPlayer::GetInstance().GetPlayStatusMutex().unlock();
2791 }
2792 
2793 
OnPrevious()2794 void CMusicPlayerDlg::OnPrevious()
2795 {
2796     // TODO: 在此添加命令处理程序代码
2797     if (!CPlayer::GetInstance().PlayTrack(PREVIOUS))
2798     {
2799         const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY");
2800         MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK);
2801     }
2802 }
2803 
2804 
OnNext()2805 void CMusicPlayerDlg::OnNext()
2806 {
2807     // TODO: 在此添加命令处理程序代码
2808     if (!CPlayer::GetInstance().PlayTrack(NEXT))
2809     {
2810         const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY");
2811         MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK);
2812     }
2813 }
2814 
2815 
OnRew()2816 void CMusicPlayerDlg::OnRew()
2817 {
2818     // TODO: 在此添加命令处理程序代码
2819     if (CPlayer::GetInstance().m_loading) return;
2820     if (!CPlayer::GetInstance().GetPlayStatusMutex().try_lock_for(std::chrono::milliseconds(1000))) return;
2821 
2822     CPlayer::GetInstance().MusicControl(Command::REW);
2823     UpdateTaskBarProgress();
2824     //ShowTime();
2825 
2826     CPlayer::GetInstance().GetPlayStatusMutex().unlock();
2827 }
2828 
2829 
OnFF()2830 void CMusicPlayerDlg::OnFF()
2831 {
2832     // TODO: 在此添加命令处理程序代码
2833     if (CPlayer::GetInstance().m_loading) return;
2834     if (!CPlayer::GetInstance().GetPlayStatusMutex().try_lock_for(std::chrono::milliseconds(1000))) return;
2835 
2836     CPlayer::GetInstance().MusicControl(Command::FF);
2837     UpdateTaskBarProgress();
2838     //ShowTime();
2839 
2840     CPlayer::GetInstance().GetPlayStatusMutex().unlock();
2841 }
2842 
2843 
OnMediaLib()2844 void CMusicPlayerDlg::OnMediaLib()
2845 {
2846     CMusicPlayerCmdHelper helper;
2847     //设置打开媒体库对话框时显示的标签页
2848     int cur_tab{ -1 };
2849     if (CPlayer::GetInstance().IsFolderMode())
2850     {
2851         cur_tab = CMusicPlayerCmdHelper::ML_FOLDER;
2852     }
2853     else if (CPlayer::GetInstance().IsPlaylistMode())
2854     {
2855         cur_tab = CMusicPlayerCmdHelper::ML_PLAYLIST;
2856     }
2857     if (CPlayer::GetInstance().IsMediaLibMode())
2858     {
2859         switch (CPlayer::GetInstance().GetMediaLibPlaylistType())
2860         {
2861         case CMediaClassifier::CT_ARTIST: cur_tab = CMusicPlayerCmdHelper::ML_ARTIST; break;
2862         case CMediaClassifier::CT_ALBUM: cur_tab = CMusicPlayerCmdHelper::ML_ALBUM; break;
2863         case CMediaClassifier::CT_GENRE: cur_tab = CMusicPlayerCmdHelper::ML_GENRE; break;
2864         case CMediaClassifier::CT_YEAR: cur_tab = CMusicPlayerCmdHelper::ML_YEAR; break;
2865         case CMediaClassifier::CT_TYPE: cur_tab = CMusicPlayerCmdHelper::ML_FILE_TYPE; break;
2866         case CMediaClassifier::CT_BITRATE: cur_tab = CMusicPlayerCmdHelper::ML_BITRATE; break;
2867         case CMediaClassifier::CT_RATING: cur_tab = CMusicPlayerCmdHelper::ML_RATING; break;
2868         }
2869     }
2870 
2871     helper.ShowMediaLib(cur_tab);
2872 }
2873 
2874 
OnFind()2875 void CMusicPlayerDlg::OnFind()
2876 {
2877     // TODO: 在此添加命令处理程序代码
2878     m_findDlg.ShowModelessDialog(IDD_FIND_CONTAINER_DIALOG);
2879 }
2880 
OnExplorePath()2881 void CMusicPlayerDlg::OnExplorePath()
2882 {
2883     // TODO: 在此添加命令处理程序代码
2884     CPlayer::GetInstance().ExplorePath();
2885 }
2886 
2887 
PreTranslateMessage(MSG * pMsg)2888 BOOL CMusicPlayerDlg::PreTranslateMessage(MSG* pMsg)
2889 {
2890     // TODO: 在此添加专用代码和/或调用基类
2891     CWnd* search_box;
2892     if (IsFloatPlaylistExist())
2893         search_box = &m_pFloatPlaylistDlg->GetSearchBox();
2894     else
2895         search_box = &m_search_edit;
2896     if (pMsg->hwnd != search_box->GetSafeHwnd())  //如果焦点在搜索框上,则不响应快捷键
2897     {
2898         if (WM_KEYFIRST <= pMsg->message && pMsg->message <= WM_KEYLAST)
2899         {
2900             //响应Accelerator中设置的快捷键
2901             if (m_hAccel && ::TranslateAccelerator(m_hWnd, m_hAccel, pMsg))
2902                 return TRUE;
2903         }
2904 
2905         // 响应不在Accelerator中的快捷键
2906         if (pMsg->message == WM_KEYDOWN)
2907         {
2908             if (pMsg->wParam == 'F' && (theApp.m_ui_data.show_playlist || IsFloatPlaylistExist()))    //按F键快速查找
2909             {
2910                 search_box->SetFocus();
2911                 return TRUE;
2912             }
2913             if (pMsg->wParam == VK_ESCAPE)      // 按ESC键退出全屏模式
2914             {
2915                 if (theApp.m_ui_data.full_screen)
2916                 {
2917                     OnFullScreen();
2918                     return TRUE;
2919                 }
2920             }
2921 
2922             if (pMsg->wParam == VK_APPS)        // 按菜单键弹出主菜单
2923             {
2924                 CPoint poi(0, 0);
2925                 SendMessage(WM_MAIN_MENU_POPEDUP, (WPARAM)&poi);
2926                 return TRUE;
2927             }
2928         }
2929     }
2930 
2931     //如果焦点在搜索框内,按ESC键将焦点重新设置为主窗口
2932     if (pMsg->hwnd == search_box->GetSafeHwnd() && pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE)
2933     {
2934         SetFocus();
2935     }
2936 
2937     if (pMsg->message == WM_KEYDOWN && (pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE))        //屏蔽按回车键和ESC键退出
2938     {
2939         return TRUE;
2940     }
2941 
2942 
2943     if (pMsg->message == WM_MOUSEMOVE)
2944         m_tool_tip.RelayEvent(pMsg);
2945 
2946 
2947     return CMainDialogBase::PreTranslateMessage(pMsg);
2948 }
2949 
2950 
OnDestroy()2951 void CMusicPlayerDlg::OnDestroy()
2952 {
2953     CMainDialogBase::OnDestroy();
2954 
2955     // TODO: 在此处添加消息处理程序代码
2956 
2957     //退出程序时,如果开启了淡入淡出选项,则暂时播放,以实现在退出时音量的淡出效果
2958     if (theApp.m_play_setting_data.fade_effect && CPlayer::GetInstance().IsPlaying())
2959         CPlayer::GetInstance().GetPlayerCore()->Pause();
2960 
2961     //获取桌面歌词窗口的位置
2962     CRect rect;
2963     ::GetWindowRect(m_desktop_lyric.GetSafeHwnd(), rect);
2964     m_desktop_lyric_pos = rect.TopLeft();
2965     m_desktop_lyric_size = rect.Size();
2966 
2967     //保存修改过的歌词
2968     DoLyricsAutoSave();
2969 
2970     //退出时保存设置
2971     CPlayer::GetInstance().OnExit();
2972     SaveUiData();
2973     SaveConfig();
2974     m_findDlg.SaveChildrenConfig();
2975     theApp.SaveConfig();
2976     //解除全局热键
2977     m_hot_key.UnRegisterAllHotKey();
2978 
2979     //取消注册接收音频设备变化通知回调的IMMNotificationClient接口
2980     devicesManager->ReleaseDeviceEnumerator();
2981     delete devicesManager;
2982 
2983     // 取消注册电源状态切换通知
2984     if (CWinVersionHelper::IsWindows8OrLater())
2985     {
2986         PowerUnregisterSuspendResumeNotification(&RegistrationHandle);
2987     }
2988 
2989     //退出时恢复Cortana的默认文本
2990     m_cortana_lyric.ResetCortanaText();
2991     m_cortana_lyric.SetEnable(false);
2992 
2993     ////退出时删除专辑封面临时文件
2994     //DeleteFile(CPlayer::GetInstance().GetAlbumCoverPath().c_str());
2995 
2996     m_notify_icon.DeleteNotifyIcon();
2997 
2998     m_ui_thread_para.ui_thread_exit = true;
2999     DWORD rtn{};
3000     if (m_uiThread != nullptr)
3001         rtn = WaitForSingleObject(m_uiThread->m_hThread, 20000);   //等待线程退出
3002 
3003     m_ui_static_ctrl.ReleaseDC(m_pUiDC);
3004 
3005 }
3006 
3007 
OnAppAbout()3008 void CMusicPlayerDlg::OnAppAbout()
3009 {
3010     CAboutDlg dlgAbout;
3011     dlgAbout.DoModal();
3012 }
3013 
3014 
OnFileOpen()3015 void CMusicPlayerDlg::OnFileOpen()
3016 {
3017     // TODO: 在此添加命令处理程序代码
3018     vector<wstring> files;  //储存打开的多个文件路径
3019     //设置过滤器
3020     wstring filter = FilterHelper::GetAudioFileFilter();
3021     CCommon::DoOpenFileDlg(filter, files, this);
3022     if (!files.empty())
3023     {
3024         if (!CPlayer::GetInstance().OpenFilesInDefaultPlaylist(files))
3025         {
3026             const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY");
3027             MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK);
3028         }
3029     }
3030 }
3031 
3032 
OnFileOpenFolder()3033 void CMusicPlayerDlg::OnFileOpenFolder()
3034 {
3035     CMusicPlayerCmdHelper helper(this);
3036     helper.OnOpenFolder();
3037 }
3038 
3039 
OnDropFiles(HDROP hDropInfo)3040 void CMusicPlayerDlg::OnDropFiles(HDROP hDropInfo)
3041 {
3042     // TODO: 在此添加消息处理程序代码和/或调用默认值
3043     vector<wstring> files;  //储存拖放到窗口的多个文件路径
3044     TCHAR file_path[MAX_PATH];
3045     int drop_count = DragQueryFileW(hDropInfo, -1, NULL, 0);     //取得被拖动文件的数目
3046     //获取第1个文件
3047     DragQueryFile(hDropInfo, 0, file_path, MAX_PATH);
3048     wstring file_path_wcs{ file_path };
3049     //if (file_path_wcs.size() > 4 && file_path_wcs[file_path_wcs.size() - 4] != L'.' && file_path_wcs[file_path_wcs.size() - 5] != L'.')
3050     bool ok{};
3051     if (CCommon::IsFolder(file_path_wcs))
3052         ok = CPlayer::GetInstance().OpenFolder(file_path_wcs);
3053     else if (CPlaylistFile::IsPlaylistFile(file_path_wcs))
3054         ok = CPlayer::GetInstance().OpenPlaylistFile(file_path_wcs);
3055     else
3056     {
3057         for (int i{}; i < drop_count; i++)
3058         {
3059             DragQueryFile(hDropInfo, i, file_path, MAX_PATH);   //获取第i个文件
3060             if (CAudioCommon::FileIsAudio(wstring(file_path)))
3061                 files.push_back(file_path);
3062         }
3063         if (!files.empty())
3064         {
3065             if (CPlayer::GetInstance().IsPlaylistMode())
3066             {
3067                 int rtn = CPlayer::GetInstance().AddFilesToPlaylist(files);
3068                 ok = (rtn != -1);   // 返回值不是-1说明没有遇到取得锁失败的问题
3069                 if (rtn == 0)
3070                 {
3071                     const wstring& info = theApp.m_str_table.LoadText(L"MSG_FILE_EXIST_IN_PLAYLIST");
3072                     MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK);
3073                 }
3074             }
3075             else
3076                 ok = CPlayer::GetInstance().OpenFilesInDefaultPlaylist(files, false);
3077         }
3078     }
3079     if (!ok)
3080     {
3081         const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY");
3082         MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK);
3083     }
3084 
3085     CMainDialogBase::OnDropFiles(hDropInfo);
3086 }
3087 
3088 
OnInitMenu(CMenu * pMenu)3089 void CMusicPlayerDlg::OnInitMenu(CMenu* pMenu)
3090 {
3091     CMainDialogBase::OnInitMenu(pMenu);
3092 
3093     // TODO: 在此处添加消息处理程序代码
3094     m_pCurMenu = pMenu;
3095 
3096     SetMenuState(pMenu);
3097 
3098     CMenu* pSysMenu = GetSystemMenu(FALSE);
3099     SetMenuState(pSysMenu);
3100 }
3101 
OnRepeatMode()3102 void CMusicPlayerDlg::OnRepeatMode()
3103 {
3104     CPlayer::GetInstance().SetRepeatMode();
3105     CPlayerUIBase* pUI = GetCurrentUi();
3106     if (pUI != nullptr)
3107         pUI->UpdateRepeatModeToolTip();
3108 }
3109 
3110 
OnPlayOrder()3111 void CMusicPlayerDlg::OnPlayOrder()
3112 {
3113     // TODO: 在此添加命令处理程序代码
3114     CPlayer::GetInstance().SetRepeatMode(RM_PLAY_ORDER);        //设置顺序播放
3115     CPlayerUIBase* pUI = GetCurrentUi();
3116     if (pUI != nullptr)
3117         pUI->UpdateRepeatModeToolTip();
3118 }
3119 
3120 
OnPlayShuffle()3121 void CMusicPlayerDlg::OnPlayShuffle()
3122 {
3123     // TODO: 在此添加命令处理程序代码
3124     CPlayer::GetInstance().SetRepeatMode(RM_PLAY_SHUFFLE);      //设置无序播放
3125     CPlayerUIBase* pUI = GetCurrentUi();
3126     if (pUI != nullptr)
3127         pUI->UpdateRepeatModeToolTip();
3128 }
3129 
3130 
OnPlayRandom()3131 void CMusicPlayerDlg::OnPlayRandom()
3132 {
3133     // TODO: 在此添加命令处理程序代码
3134     CPlayer::GetInstance().SetRepeatMode(RM_PLAY_RANDOM);       //设置无序播放
3135     CPlayerUIBase* pUI = GetCurrentUi();
3136     if (pUI != nullptr)
3137         pUI->UpdateRepeatModeToolTip();
3138 }
3139 
3140 
OnPlayTrack()3141 void CMusicPlayerDlg::OnPlayTrack()
3142 {
3143     // TODO: 在此添加命令处理程序代码
3144     CPlayer::GetInstance().SetRepeatMode(RM_PLAY_TRACK);        //设置单曲播放
3145     CPlayerUIBase* pUI = GetCurrentUi();
3146     if (pUI != nullptr)
3147         pUI->UpdateRepeatModeToolTip();
3148 }
3149 
3150 
OnLoopPlaylist()3151 void CMusicPlayerDlg::OnLoopPlaylist()
3152 {
3153     // TODO: 在此添加命令处理程序代码
3154     CPlayer::GetInstance().SetRepeatMode(RM_LOOP_PLAYLIST);     //设置列表循环
3155     CPlayerUIBase* pUI = GetCurrentUi();
3156     if (pUI != nullptr)
3157         pUI->UpdateRepeatModeToolTip();
3158 }
3159 
3160 
OnLoopTrack()3161 void CMusicPlayerDlg::OnLoopTrack()
3162 {
3163     // TODO: 在此添加命令处理程序代码
3164     CPlayer::GetInstance().SetRepeatMode(RM_LOOP_TRACK);        //设置单曲循环
3165     CPlayerUIBase* pUI = GetCurrentUi();
3166     if (pUI != nullptr)
3167         pUI->UpdateRepeatModeToolTip();
3168 }
3169 
3170 
OnMouseWheel(UINT nFlags,short zDelta,CPoint pt)3171 BOOL CMusicPlayerDlg::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
3172 {
3173     // TODO: 在此添加消息处理程序代码和/或调用默认值
3174     CRect draw_rect{ 0,0,theApp.m_ui_data.draw_area_width, theApp.m_ui_data.draw_area_height };
3175     bool from_desktop_lyric{ pt.x == INT16_MAX && pt.y == INT16_MAX };  // 从桌面歌词/迷你模式窗口转发
3176     ScreenToClient(&pt);
3177 
3178     if (m_pUI->MouseWheel(zDelta, pt))
3179         return TRUE;
3180 
3181     //获取音量图标的矩形区域
3182     CRect volumn_rect;
3183     CPlayerUIBase* pUI = GetCurrentUi();
3184     if (pUI != nullptr)
3185         volumn_rect = pUI->GetVolumeRect();
3186 
3187     bool volumn_adj_enable{ (theApp.m_general_setting_data.global_mouse_wheel_volume_adjustment && draw_rect.PtInRect(pt))
3188         || (!theApp.m_general_setting_data.global_mouse_wheel_volume_adjustment && volumn_rect.PtInRect(pt)) };
3189 
3190     if (volumn_adj_enable || from_desktop_lyric)
3191     {
3192         static int nogori = 0;
3193         if (nogori * zDelta < 0)    // 换向时清零累计值使得滚轮总是能够及时响应
3194             nogori = 0;
3195         // 在触控板下有必要处理zDelta,触控板驱动会通过较小的zDelta连发模拟惯性
3196         // 每120的zDelta(即滚轮一格)音量调整百分之mouse_volum_step
3197         nogori += zDelta * theApp.m_nc_setting_data.mouse_volum_step;
3198         AdjustVolume(nogori / 120);
3199         nogori = nogori % 120;
3200     }
3201 
3202     return CMainDialogBase::OnMouseWheel(nFlags, zDelta, pt);
3203 }
3204 
3205 
OnGetMinMaxInfo(MINMAXINFO * lpMMI)3206 void CMusicPlayerDlg::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
3207 {
3208     // TODO: 在此添加消息处理程序代码和/或调用默认值
3209     //限制窗口最小大小
3210     lpMMI->ptMinTrackSize.x = theApp.DPI(340);      //设置最小宽度
3211     lpMMI->ptMinTrackSize.y = theApp.DPI(360);      //设置最小高度
3212 
3213     CMainDialogBase::OnGetMinMaxInfo(lpMMI);
3214 }
3215 
3216 
OnNMDblclkPlaylistList(NMHDR * pNMHDR,LRESULT * pResult)3217 void CMusicPlayerDlg::OnNMDblclkPlaylistList(NMHDR* pNMHDR, LRESULT* pResult)
3218 {
3219     LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
3220     SetUiPlaylistSelected(pNMItemActivate->iItem);
3221     int song_index{};
3222     if (!m_searched)    //如果播放列表不在搜索状态,则当前选中项的行号就是曲目的索引
3223     {
3224         song_index = pNMItemActivate->iItem;
3225     }
3226     else        //如果播放列表处理选中状态,则曲目的索引是选中行第一列的数字-1
3227     {
3228         CString str;
3229         str = m_playlist_list.GetItemText(pNMItemActivate->iItem, 0);
3230         song_index = _ttoi(str) - 1;
3231     }
3232 
3233     if (song_index < 0) return;
3234     if (!CPlayer::GetInstance().PlayTrack(song_index))
3235     {
3236         const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY");
3237         MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK);
3238     }
3239 
3240     *pResult = 0;
3241 }
3242 
3243 
3244 //void CMusicPlayerDlg::OnRefreshPlaylist()
3245 //{
3246 //  // TODO: 在此添加命令处理程序代码
3247 //  ShowPlayList();
3248 //}
3249 
3250 
OnOptionSettings()3251 void CMusicPlayerDlg::OnOptionSettings()
3252 {
3253     // TODO: 在此添加命令处理程序代码
3254     _OnOptionSettings(this);
3255 }
3256 
3257 
OnReloadPlaylist()3258 void CMusicPlayerDlg::OnReloadPlaylist()
3259 {
3260     // TODO: 在此添加命令处理程序代码
3261     if (!CPlayer::GetInstance().ReloadPlaylist(MR_FOECE_FULL))  // 强制重新获取全部音频元数据
3262     {
3263         const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY");
3264         MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK);
3265     }
3266 }
3267 
3268 
OnNMRClickPlaylistList(NMHDR * pNMHDR,LRESULT * pResult)3269 void CMusicPlayerDlg::OnNMRClickPlaylistList(NMHDR* pNMHDR, LRESULT* pResult)
3270 {
3271     LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
3272     SetUiPlaylistSelected(pNMItemActivate->iItem);
3273     if (!m_searched)
3274     {
3275         m_item_selected = pNMItemActivate->iItem;   //获取鼠标选中的项目
3276         m_playlist_list.GetItemSelected(m_items_selected);      //获取多个选中的项目
3277     }
3278     else
3279     {
3280         CString str;
3281         str = m_playlist_list.GetItemText(pNMItemActivate->iItem, 0);
3282         m_item_selected = _ttoi(str) - 1;
3283         m_playlist_list.GetItemSelectedSearched(m_items_selected);
3284     }
3285 
3286     CMenu* pContextMenu{};
3287     if (m_item_selected >= 0)
3288         pContextMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::PlaylistMenu);
3289     else
3290         pContextMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::PlaylistToolBarMenu);
3291     m_playlist_list.ShowPopupMenu(pContextMenu, pNMItemActivate->iItem, this);
3292 
3293     *pResult = 0;
3294 }
3295 
3296 
OnPlayItem()3297 void CMusicPlayerDlg::OnPlayItem()
3298 {
3299     // TODO: 在此添加命令处理程序代码
3300     CMusicPlayerCmdHelper helper(this);
3301     helper.OnPlayTrack(m_item_selected);
3302 }
3303 
3304 
OnItemProperty()3305 void CMusicPlayerDlg::OnItemProperty()
3306 {
3307     // TODO: 在此添加命令处理程序代码
3308     CPropertyDlg* pDlg;
3309     vector<SongInfo> items_selected;
3310     if (m_items_selected.size() > 1)        //批量编辑
3311     {
3312         for (int index : m_items_selected)
3313         {
3314             if (index >= 0 && index < CPlayer::GetInstance().GetSongNum())
3315                 items_selected.push_back(CPlayer::GetInstance().GetPlayList()[index]);
3316         }
3317         pDlg = new CPropertyDlg(items_selected);
3318     }
3319     else
3320     {
3321         pDlg = new CPropertyDlg(CPlayer::GetInstance().GetPlayList(), m_item_selected, false);
3322     }
3323     pDlg->DoModal();
3324 
3325     if (m_items_selected.size() > 1 && pDlg->GetModified())        //批量修改时更新已修改的曲目信息
3326     {
3327         for (int index : m_items_selected)
3328         {
3329             if (index >= 0 && index < CPlayer::GetInstance().GetSongNum())
3330             {
3331                 CSongDataManager::GetInstance().LoadSongInfo(CPlayer::GetInstance().GetPlayList()[index]);
3332             }
3333         }
3334     }
3335     if (pDlg->GetListRefresh())
3336         ShowPlayList();
3337     SAFE_DELETE(pDlg);
3338 }
3339 
3340 
3341 //void CMusicPlayerDlg::OnRemoveFromPlaylist()
3342 //{
3343 //  // TODO: 在此添加命令处理程序代码
3344 //  CPlayer::GetInstance().RemoveSong(m_item_selected);
3345 //  ShowPlayList();
3346 //  UpdatePlayPauseButton();
3347 //}
3348 
3349 
3350 //void CMusicPlayerDlg::OnClearPlaylist()
3351 //{
3352 //  // TODO: 在此添加命令处理程序代码
3353 //  CPlayer::GetInstance().ClearPlaylist();
3354 //  ShowPlayList();
3355 //  UpdatePlayPauseButton();
3356 //}
3357 
3358 
OnExploreTrack()3359 void CMusicPlayerDlg::OnExploreTrack()
3360 {
3361     // TODO: 在此添加命令处理程序代码
3362     CPlayer::GetInstance().ExplorePath(m_item_selected);
3363 }
3364 
3365 
OnCommand(WPARAM wParam,LPARAM lParam)3366 BOOL CMusicPlayerDlg::OnCommand(WPARAM wParam, LPARAM lParam)
3367 {
3368     // TODO: 在此添加专用代码和/或调用基类
3369     //响应任务栏缩略图按钮
3370     WORD command = LOWORD(wParam);
3371     switch (command)
3372     {
3373     case IDT_PLAY_PAUSE:
3374         OnPlayPause();
3375         break;
3376     case IDT_PREVIOUS:
3377         OnPrevious();
3378         break;
3379     case IDT_NEXT:
3380         OnNext();
3381         break;
3382     case ID_TEST:
3383         CTest::Test();
3384         //CPlayer::GetInstance().DoABRepeat();
3385         break;
3386     case ID_TEST_DIALOG:
3387     {
3388         CTestDlg dlg;
3389         dlg.DoModal();
3390     }
3391     break;
3392     }
3393 
3394     //响应切换界面命令
3395     if (command > ID_SWITCH_UI && command <= ID_SWITCH_UI + SELECT_UI_MAX_SIZE)
3396     {
3397         int ui_index = command - ID_SWITCH_UI - 1;
3398         if (ui_index >= 0 && ui_index < static_cast<int>(m_ui_list.size()))
3399         {
3400             SelectUi(ui_index);
3401             m_ui_list[ui_index]->ClearBtnRect();
3402             DrawInfo(true);
3403             m_ui_list[ui_index]->UpdateRepeatModeToolTip();
3404             m_ui_list[ui_index]->UpdateVolumeToolTip();
3405         }
3406     }
3407 
3408     //响应文件夹/播放列表快捷菜单中的项目
3409     if (command >= ID_RECENT_FOLDER_PLAYLIST_MENU_START && command <= ID_RECENT_FOLDER_PLAYLIST_MENU_END)
3410     {
3411         int index = command - ID_RECENT_FOLDER_PLAYLIST_MENU_START;
3412         CMusicPlayerCmdHelper helper;
3413         if (index >= 0 && index < static_cast<int>(m_recent_cache.size()))
3414             helper.OnListItemSelected(m_recent_cache.at(index));
3415     }
3416 
3417     // 这里应当先判断ID再调用IsMainWindowPopupMenu,避免程序初始化时的无关命令导致菜单全量创建
3418     // 将菜单初始化延迟到用户使用菜单有助于提高启动速度
3419 
3420     //响应播放列表右键菜单中的“添加到播放列表”
3421     if ((command >= ID_ADD_TO_DEFAULT_PLAYLIST && command <= ID_ADD_TO_MY_FAVOURITE + ADD_TO_PLAYLIST_MAX_SIZE) || command == ID_ADD_TO_OTHER_PLAYLIST)
3422     {
3423         auto getSelectedItems = [&](std::vector<SongInfo>& item_list)
3424             {
3425                 item_list.clear();
3426                 if (IsMainWindowPopupMenu())      //如果当前命令是从主界面右键菜单中弹出来的,则是添加正在播放的曲目到播放列表
3427                 {
3428                     item_list.push_back(CPlayer::GetInstance().GetCurrentSongInfo());
3429                 }
3430                 else        //否则是添加选中的曲目到播放列表
3431                 {
3432                     for (auto i : m_items_selected)
3433                     {
3434                         if (i >= 0 && i < CPlayer::GetInstance().GetSongNum())
3435                         {
3436                             item_list.push_back(CPlayer::GetInstance().GetPlayList()[i]);
3437                         }
3438                     }
3439                 }
3440             };
3441         CMusicPlayerCmdHelper cmd_helper;
3442         if (cmd_helper.OnAddToPlaylistCommand(getSelectedItems, command))
3443             m_pCurMenu = nullptr;
3444     }
3445     //响应主窗口右键菜单中的分级
3446     if ((command >= ID_RATING_1 && command <= ID_RATING_5) || command == ID_RATING_NONE)    //如果命令是歌曲分级(应确保分级命令的ID是连续的)
3447     {
3448         bool rating_failed{ false };
3449         CMusicPlayerCmdHelper cmd_helper;
3450         if (IsMainWindowPopupMenu())
3451         {
3452             if (!cmd_helper.OnRating(CPlayer::GetInstance().GetCurrentSongInfo(), command))
3453                 rating_failed = true;
3454         }
3455         //响应播放列表右键菜单中的分级
3456         else
3457         {
3458             for (int i : m_items_selected)
3459             {
3460                 if (i >= 0 && i < CPlayer::GetInstance().GetSongNum())
3461                 {
3462                     SongInfo& select_file = CPlayer::GetInstance().GetPlayList()[i];
3463                     if (!cmd_helper.OnRating(select_file, command))
3464                         rating_failed = true;
3465                 }
3466             }
3467         }
3468         if (rating_failed)
3469         {
3470             const wstring& info = theApp.m_str_table.LoadText(L"MSG_FILE_WRITE_FAILED");
3471             MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK);
3472         }
3473     }
3474 
3475     return CMainDialogBase::OnCommand(wParam, lParam);
3476 }
3477 
3478 
OnHotKey(UINT nHotKeyId,UINT nKey1,UINT nKey2)3479 void CMusicPlayerDlg::OnHotKey(UINT nHotKeyId, UINT nKey1, UINT nKey2)
3480 {
3481     // TODO: 在此添加消息处理程序代码和/或调用默认值
3482     //响应全局快捷键
3483     switch (nHotKeyId)
3484     {
3485     case HK_PLAY_PAUSE:
3486         OnPlayPause();
3487         break;
3488     case HK_PREVIOUS:
3489         OnPrevious();
3490         break;
3491     case HK_NEXT:
3492         OnNext();
3493         break;
3494     case HK_VOLUME_UP:
3495         OnVolumeUp();
3496         break;
3497     case HK_VOLUME_DOWN:
3498         OnVolumeDown();
3499         break;
3500     default:
3501         break;
3502     case HK_STOP:
3503         OnStop();
3504         break;
3505     case HK_FF:
3506         OnFF();
3507         break;
3508     case HK_REW:
3509         OnRew();
3510         break;
3511     case HK_EXIT:
3512         OnMenuExit();
3513         break;
3514     case HK_SHOW_HIDE_PLAYER:
3515     {
3516         if (m_miniModeDlg.m_hWnd != NULL)             // 如果是mini模式则返回标准窗口
3517         {
3518             ::SendMessageW(m_miniModeDlg.m_hWnd, WM_COMMAND, IDOK, 0);
3519         }
3520         else if (GetActiveWindow() == this)           // 如果窗口拥有焦点则隐藏
3521         {
3522             ShowWindow(SW_HIDE);
3523             if (IsFloatPlaylistExist())
3524             {
3525                 m_pFloatPlaylistDlg->ShowWindow(SW_HIDE);
3526             }
3527         }
3528         else                                          // 进行窗口恢复并取得焦点
3529         {
3530             if (IsIconic())                           // 如果是最小化的窗口那么还原
3531                 ShowWindow(SW_RESTORE);
3532             else                                      // 如果是HIDE的窗口那么显示
3533             {
3534                 ShowWindow(SW_SHOW);
3535                 if (IsFloatPlaylistExist())
3536                 {
3537                     m_pFloatPlaylistDlg->ShowWindow(SW_SHOW);
3538                 }
3539                 TaskBarInit();
3540             }
3541             SetForegroundWindow();
3542         }
3543     }
3544     break;
3545     case HK_SHOW_HIDE_DESKTOP_LYRIC:
3546         OnShowDesktopLyric();
3547         break;
3548     case HK_ADD_TO_MY_FAVOURITE:
3549     {
3550         CMusicPlayerCmdHelper helper(this);
3551         helper.OnAddToFavourite();
3552     }
3553         break;
3554     }
3555 
3556     CMainDialogBase::OnHotKey(nHotKeyId, nKey1, nKey2);
3557 }
3558 
3559 
OnReIniBass()3560 void CMusicPlayerDlg::OnReIniBass()
3561 {
3562     // TODO: 在此添加命令处理程序代码
3563     CPlayer::GetInstance().ReIniPlayerCore();
3564     UpdatePlayPauseButton();
3565 }
3566 
3567 
OnSortByFile()3568 void CMusicPlayerDlg::OnSortByFile()
3569 {
3570     // TODO: 在此添加命令处理程序代码
3571     auto& sort_mode = CPlayer::GetInstance().m_sort_mode;
3572     sort_mode = (sort_mode != SM_U_FILE) ? SM_U_FILE : SM_D_FILE;
3573     CPlayer::GetInstance().SortPlaylist();
3574     ShowPlayList();
3575 }
3576 
3577 
OnSortByPath()3578 void CMusicPlayerDlg::OnSortByPath()
3579 {
3580     // TODO: 在此添加命令处理程序代码
3581     auto& sort_mode = CPlayer::GetInstance().m_sort_mode;
3582     sort_mode = (sort_mode != SM_U_PATH) ? SM_U_PATH : SM_D_PATH;
3583     CPlayer::GetInstance().SortPlaylist();
3584     ShowPlayList();
3585 }
3586 
3587 
OnSortByTitle()3588 void CMusicPlayerDlg::OnSortByTitle()
3589 {
3590     // TODO: 在此添加命令处理程序代码
3591     auto& sort_mode = CPlayer::GetInstance().m_sort_mode;
3592     sort_mode = (sort_mode != SM_U_TITLE) ? SM_U_TITLE : SM_D_TITLE;
3593     CPlayer::GetInstance().SortPlaylist();
3594     ShowPlayList();
3595 }
3596 
3597 
OnSortByArtist()3598 void CMusicPlayerDlg::OnSortByArtist()
3599 {
3600     // TODO: 在此添加命令处理程序代码
3601     auto& sort_mode = CPlayer::GetInstance().m_sort_mode;
3602     sort_mode = (sort_mode != SM_U_ARTIST) ? SM_U_ARTIST : SM_D_ARTIST;
3603     CPlayer::GetInstance().SortPlaylist();
3604     ShowPlayList();
3605 }
3606 
3607 
OnSortByAlbum()3608 void CMusicPlayerDlg::OnSortByAlbum()
3609 {
3610     // TODO: 在此添加命令处理程序代码
3611     auto& sort_mode = CPlayer::GetInstance().m_sort_mode;
3612     sort_mode = (sort_mode != SM_U_ALBUM) ? SM_U_ALBUM : SM_D_ALBUM;
3613     CPlayer::GetInstance().SortPlaylist();
3614     ShowPlayList();
3615 }
3616 
3617 
OnSortByTrack()3618 void CMusicPlayerDlg::OnSortByTrack()
3619 {
3620     // TODO: 在此添加命令处理程序代码
3621     auto& sort_mode = CPlayer::GetInstance().m_sort_mode;
3622     sort_mode = (sort_mode != SM_U_TRACK) ? SM_U_TRACK : SM_D_TRACK;
3623     CPlayer::GetInstance().SortPlaylist();
3624     ShowPlayList();
3625 }
3626 
3627 
OnSortByListenTime()3628 void CMusicPlayerDlg::OnSortByListenTime()
3629 {
3630     // TODO: 在此添加命令处理程序代码
3631     auto& sort_mode = CPlayer::GetInstance().m_sort_mode;
3632     sort_mode = (sort_mode != SM_D_LISTEN) ? SM_D_LISTEN : SM_U_LISTEN; // 这个特殊,第一次点击默认为降序
3633     CPlayer::GetInstance().SortPlaylist();
3634     ShowPlayList();
3635 }
3636 
3637 
OnSortByModifiedTime()3638 void CMusicPlayerDlg::OnSortByModifiedTime()
3639 {
3640     // TODO: 在此添加命令处理程序代码
3641     auto& sort_mode = CPlayer::GetInstance().m_sort_mode;
3642     sort_mode = (sort_mode != SM_U_TIME) ? SM_U_TIME : SM_D_TIME;
3643     CPlayer::GetInstance().SortPlaylist();
3644     ShowPlayList();
3645 }
3646 
3647 
OnDeleteFromDisk()3648 void CMusicPlayerDlg::OnDeleteFromDisk()
3649 {
3650     // TODO: 在此添加命令处理程序代码
3651     if (theApp.m_media_lib_setting_data.disable_delete_from_disk)
3652         return;
3653 
3654     if (m_item_selected < 0 || m_item_selected >= CPlayer::GetInstance().GetSongNum())
3655         return;
3656 
3657     wstring info;
3658     if (m_items_selected.size() == 1)
3659     {
3660         const auto& song = CPlayer::GetInstance().GetPlayList()[m_items_selected.front()];
3661         info = theApp.m_str_table.LoadTextFormat(L"MSG_DELETE_SINGLE_FILE_INQUIRY", { song.file_path });
3662     }
3663     else
3664     {
3665         info = theApp.m_str_table.LoadTextFormat(L"MSG_DELETE_SEL_AUDIO_FILE_INQUIRY", { m_items_selected.size() });
3666     }
3667     if (MessageBoxW(info.c_str(), NULL, MB_ICONWARNING | MB_OKCANCEL) != IDOK) return;
3668     // 以下操作可能涉及MusicControl,先取得锁
3669     if (!CPlayer::GetInstance().GetPlayStatusMutex().try_lock_for(std::chrono::milliseconds(1000))) return;
3670     int rtn;
3671     wstring delected_file;
3672     vector<wstring> delected_files;
3673     if (m_items_selected.size() > 1)
3674     {
3675         if (CCommon::IsItemInVector(m_items_selected, CPlayer::GetInstance().GetIndex()))   //如果选中的文件中有正在播放的文件,则删除前必须先关闭文件
3676             CPlayer::GetInstance().MusicControl(Command::CLOSE);
3677         for (const auto& index : m_items_selected)
3678         {
3679             const auto& song = CPlayer::GetInstance().GetPlayList()[index];
3680             if (!song.is_cue && !COSUPlayerHelper::IsOsuFile(song.file_path))
3681                 delected_files.push_back(song.file_path);
3682         }
3683         if (delected_files.empty())
3684             return;
3685         rtn = CommonDialogMgr::DeleteFiles(m_hWnd, delected_files);
3686     }
3687     else
3688     {
3689         if (m_item_selected == CPlayer::GetInstance().GetIndex())   //如果删除的文件是正在播放的文件,则删除前必须先关闭文件
3690             CPlayer::GetInstance().MusicControl(Command::CLOSE);
3691         const auto& song = CPlayer::GetInstance().GetPlayList()[m_item_selected];
3692         if (song.is_cue || COSUPlayerHelper::IsOsuFile(song.file_path))
3693             return;
3694         delected_file = song.file_path;
3695 
3696         rtn = CommonDialogMgr::DeleteAFile(m_hWnd, delected_file);
3697     }
3698     if (rtn == ERROR_SUCCESS)
3699     {
3700         //如果文件删除成功,同时从播放列表中移除
3701         if (m_items_selected.size() > 1)
3702             CPlayer::GetInstance().RemoveSongs(m_items_selected, true);
3703         else
3704             CPlayer::GetInstance().RemoveSong(m_item_selected, true);
3705         CPlayer::GetInstance().GetPlayStatusMutex().unlock();
3706         ShowPlayList(false);
3707         UpdatePlayPauseButton();
3708         DrawInfo(true);
3709         //文件删除后同时删除和文件同名的图片文件和歌词文件
3710         if (m_items_selected.size() > 1)
3711         {
3712             for (auto& file : delected_files)
3713             {
3714                 CFilePathHelper file_path(file);
3715                 file = file_path.ReplaceFileExtension(L"jpg").c_str();
3716             }
3717             CommonDialogMgr::DeleteFiles(m_hWnd, delected_files);
3718             for (const wstring& ext : CLyrics::m_surpported_lyric)      // 删除所有后缀的歌词
3719             {
3720                 for (auto& file : delected_files)
3721                 {
3722                     CFilePathHelper file_path(file);
3723                     file = file_path.ReplaceFileExtension(ext.c_str()).c_str();
3724                 }
3725                 CommonDialogMgr::DeleteFiles(m_hWnd, delected_files);
3726             }
3727         }
3728         else
3729         {
3730             CFilePathHelper file_path(delected_file);
3731             CommonDialogMgr::DeleteAFile(m_hWnd, file_path.ReplaceFileExtension(L"jpg").c_str());
3732             for (const wstring& ext : CLyrics::m_surpported_lyric)      // 删除所有后缀的歌词
3733             {
3734                 CommonDialogMgr::DeleteAFile(m_hWnd, file_path.ReplaceFileExtension(ext.c_str()).c_str());
3735             }
3736         }
3737     }
3738     else if (rtn == ERROR_CANCELLED)   //如果在弹出的对话框中点击“取消”则返回值为1223
3739     {
3740         if (m_item_selected == CPlayer::GetInstance().GetIndex())       //如果删除的文件是正在播放的文件,又点击了“取消”,则重新打开当前文件
3741         {
3742             CPlayer::GetInstance().MusicControl(Command::OPEN);
3743             CPlayer::GetInstance().MusicControl(Command::SEEK);
3744             //CPlayer::GetInstance().Refresh();
3745             UpdatePlayPauseButton();
3746             DrawInfo(true);
3747         }
3748         CPlayer::GetInstance().GetPlayStatusMutex().unlock();
3749     }
3750     else
3751     {
3752         CPlayer::GetInstance().GetPlayStatusMutex().unlock();   // 在进入模态对话框MessageBox前及时解锁
3753         MessageBox(theApp.m_str_table.LoadText(L"MSG_DELETE_FILE_FAILED").c_str(), NULL, MB_ICONWARNING);
3754     }
3755 }
3756 
3757 
OnTaskbarcreated(WPARAM wParam,LPARAM lParam)3758 afx_msg LRESULT CMusicPlayerDlg::OnTaskbarcreated(WPARAM wParam, LPARAM lParam)
3759 {
3760     TaskBarInit();
3761 
3762     //资源管理器重启后Cortana的句柄会发生改变,此时要重新获取Cortana的句柄
3763     m_cortana_lyric.Init();
3764 
3765     m_notify_icon.AddNotifyIcon();      //重新添加通知区图标
3766 
3767     return 0;
3768 }
3769 
3770 
OnDispFileName()3771 void CMusicPlayerDlg::OnDispFileName()
3772 {
3773     // TODO: 在此添加命令处理程序代码
3774     theApp.m_media_lib_setting_data.display_format = DF_FILE_NAME;
3775     ShowPlayList();
3776 }
3777 
3778 
OnDispTitle()3779 void CMusicPlayerDlg::OnDispTitle()
3780 {
3781     // TODO: 在此添加命令处理程序代码
3782     theApp.m_media_lib_setting_data.display_format = DF_TITLE;
3783     ShowPlayList();
3784 }
3785 
3786 
OnDispArtistTitle()3787 void CMusicPlayerDlg::OnDispArtistTitle()
3788 {
3789     // TODO: 在此添加命令处理程序代码
3790     theApp.m_media_lib_setting_data.display_format = DF_ARTIST_TITLE;
3791     ShowPlayList();
3792 }
3793 
3794 
OnDispTitleArtist()3795 void CMusicPlayerDlg::OnDispTitleArtist()
3796 {
3797     // TODO: 在此添加命令处理程序代码
3798     theApp.m_media_lib_setting_data.display_format = DF_TITLE_ARTIST;
3799     ShowPlayList();
3800 }
3801 
3802 
OnMiniMode()3803 void CMusicPlayerDlg::OnMiniMode()
3804 {
3805     // TODO: 在此添加命令处理程序代码
3806     if (m_miniModeDlg.m_hWnd != NULL)
3807         return;
3808 
3809     //if (theApp.m_ui_data.full_screen)   //全屏模式下禁用响应迷你模式
3810     //    return;
3811 
3812     //m_miniModeDlg.SetDefaultBackGround(&theApp.m_ui_data.default_background);
3813     //m_miniModeDlg.SetDisplayFormat(&theApp.m_media_lib_setting_data.display_format);
3814 
3815     //Show(false);
3816     ShowWindow(SW_HIDE);
3817     bool float_playlist_exist{ IsFloatPlaylistExist() };
3818     if (theApp.m_media_lib_setting_data.float_playlist_follow_main_wnd)
3819         HideFloatPlaylist();
3820 
3821     if (m_miniModeDlg.DoModal() == IDCANCEL)
3822     {
3823         //SendMessage(WM_COMMAND, ID_APP_EXIT);
3824         OnMenuExit();
3825     }
3826     else
3827     {
3828         //Show(true);
3829         ShowWindow(SW_SHOW);
3830         if (float_playlist_exist)
3831             ShowFloatPlaylist();
3832 
3833         SetForegroundWindow();
3834         SwitchTrack();
3835         SetTransparency();
3836         SetAlwaysOnTop();
3837 
3838         TaskBarInit();
3839     }
3840 }
3841 
SaveUiData()3842 void CMusicPlayerDlg::SaveUiData()
3843 {
3844     CFile file;
3845     BOOL bRet = file.Open(theApp.m_ui_data_path.c_str(), CFile::modeCreate | CFile::modeWrite);
3846     if (!bRet) {
3847         return;
3848     }
3849     CArchive ar(&file, CArchive::store);
3850     /// 版本号
3851     ar << (uint16_t)1;
3852     for (const auto& ui : m_ui_list)
3853     {
3854         CUserUi* user_ui{ dynamic_cast<CUserUi*>(ui.get()) };
3855         if (user_ui != nullptr)
3856         {
3857             user_ui->SaveStatackElementIndex(ar);
3858         }
3859     }
3860     ar.Close();
3861     file.Close();
3862 }
3863 
LoadUiData()3864 void CMusicPlayerDlg::LoadUiData()
3865 {
3866     CFile file;
3867     BOOL bRet = file.Open(theApp.m_ui_data_path.c_str(), CFile::modeRead);
3868     if (!bRet) {
3869         return;
3870     }
3871     CArchive ar(&file, CArchive::load);
3872     try {
3873         uint16_t version;
3874         ar >> version;
3875         for (const auto& ui : m_ui_list)
3876         {
3877             CUserUi* user_ui{ dynamic_cast<CUserUi*>(ui.get()) };
3878             if (user_ui != nullptr)
3879             {
3880                 user_ui->LoadStatackElementIndex(ar);
3881             }
3882         }
3883     }
3884     catch (CArchiveException* exception) {
3885         wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_SERIALIZE_ERROR", { theApp.m_ui_data_path, exception->m_cause });
3886         theApp.WriteLog(info);
3887     }
3888     ar.Close();
3889     file.Close();
3890 }
3891 
3892 
OnSplitterChanged(CRect splitter_rect)3893 void CMusicPlayerDlg::OnSplitterChanged(CRect splitter_rect)
3894 {
3895     CMusicPlayerDlg* pThis{ dynamic_cast<CMusicPlayerDlg*>(AfxGetMainWnd()) };
3896     if (pThis != nullptr)
3897     {
3898         //调整两侧界面的宽度
3899         CRect rect;
3900         pThis->GetClientRect(rect);
3901         int playlist_width = rect.Width() - splitter_rect.left;
3902         pThis->SetPlaylistSize(rect.Width(), rect.Height(), playlist_width);
3903         pThis->SetDrawAreaSize(rect.Width(), rect.Height(), playlist_width);
3904         pThis->m_path_static.Invalidate();
3905         pThis->m_playlist_list.Invalidate();
3906         //将两侧宽度的比例保存
3907         theApp.m_app_setting_data.playlist_width_percent = playlist_width * 100 / rect.Width();
3908     }
3909 }
3910 
3911 
OnReloadLyric()3912 void CMusicPlayerDlg::OnReloadLyric()
3913 {
3914     // TODO: 在此添加命令处理程序代码
3915     CWaitCursor wait_cursor;
3916     CPlayer::GetInstance().SearchLyrics(true);
3917     CPlayer::GetInstance().IniLyrics();
3918 }
3919 
3920 
OnSongInfo()3921 void CMusicPlayerDlg::OnSongInfo()
3922 {
3923     // TODO: 在此添加命令处理程序代码
3924     CPropertyDlg propertyDlg(CPlayer::GetInstance().GetPlayList(), CPlayer::GetInstance().GetIndex(), false);
3925     propertyDlg.DoModal();
3926     if (propertyDlg.GetListRefresh())
3927         ShowPlayList();
3928 }
3929 
3930 
OnCopyCurrentLyric()3931 void CMusicPlayerDlg::OnCopyCurrentLyric()
3932 {
3933     // TODO: 在此添加命令处理程序代码
3934     bool midi_lyric{ CPlayer::GetInstance().IsMidi() && theApp.m_play_setting_data.midi_use_inner_lyric && !CPlayer::GetInstance().MidiNoLyric() };
3935     wstring lyric_str;
3936     if (midi_lyric)
3937     {
3938         lyric_str = CPlayer::GetInstance().GetMidiLyric();
3939     }
3940     else
3941     {
3942         const CLyrics::Lyric& lyric{ CPlayer::GetInstance().m_Lyrics.GetLyric(Time(CPlayer::GetInstance().GetCurrentPosition()), false, theApp.m_lyric_setting_data.donot_show_blank_lines, false) };
3943         lyric_str = lyric.text;
3944         if (theApp.m_lyric_setting_data.show_translate && !lyric.translate.empty())
3945         {
3946             lyric_str += L"\r\n";
3947             lyric_str += lyric.translate;
3948         }
3949     }
3950     if (!CCommon::CopyStringToClipboard(lyric_str))
3951         //  MessageBox(_T("当前歌词已成功复制到剪贴板。"), NULL, MB_ICONINFORMATION);
3952         //else
3953         MessageBox(theApp.m_str_table.LoadText(L"MSG_COPY_CLIPBOARD_FAILED").c_str(), NULL, MB_ICONWARNING);
3954 }
3955 
3956 
OnCopyAllLyric()3957 void CMusicPlayerDlg::OnCopyAllLyric()
3958 {
3959     // TODO: 在此添加命令处理程序代码
3960     if (CCommon::CopyStringToClipboard(CPlayer::GetInstance().m_Lyrics.GetAllLyricText(theApp.m_lyric_setting_data.show_translate)))
3961         MessageBox(theApp.m_str_table.LoadText(L"MSG_COPY_CLIPBOARD_ALL_LYRIC").c_str(), NULL, MB_ICONINFORMATION);
3962     else
3963         MessageBox(theApp.m_str_table.LoadText(L"MSG_COPY_CLIPBOARD_FAILED").c_str(), NULL, MB_ICONWARNING);
3964 }
3965 
3966 
OnLButtonDblClk(UINT nFlags,CPoint point)3967 void CMusicPlayerDlg::OnLButtonDblClk(UINT nFlags, CPoint point)
3968 {
3969     // TODO: 在此添加消息处理程序代码和/或调用默认值
3970 
3971     ////双击鼠标左键进入迷你模式
3972     //if (!theApp.m_ui_data.repetemode_rect.PtInRect(point) && !theApp.m_ui_data.volume_btn.rect.PtInRect(point)
3973     //  && !theApp.m_ui_data.volume_up_rect.PtInRect(point) && !theApp.m_ui_data.volume_down_rect.PtInRect(point)
3974     //  && !theApp.m_ui_data.translate_btn.rect.PtInRect(point))
3975     //  OnMiniMode();
3976     CMainDialogBase::OnLButtonDblClk(nFlags, point);
3977 }
3978 
3979 
OnLyricForward()3980 void CMusicPlayerDlg::OnLyricForward()
3981 {
3982     // TODO: 在此添加命令处理程序代码
3983     //歌词提前0.5秒
3984     CPlayer::GetInstance().m_Lyrics.AdjustLyric(-500);
3985 
3986 }
3987 
3988 
OnLyricDelay()3989 void CMusicPlayerDlg::OnLyricDelay()
3990 {
3991     // TODO: 在此添加命令处理程序代码
3992     //歌词延后0.5秒
3993     CPlayer::GetInstance().m_Lyrics.AdjustLyric(500);
3994 }
3995 
3996 
OnSaveModifiedLyric()3997 void CMusicPlayerDlg::OnSaveModifiedLyric()
3998 {
3999     // TODO: 在此添加命令处理程序代码
4000     if (!CPlayer::GetInstance().m_Lyrics.IsEmpty() && CPlayer::GetInstance().m_Lyrics.IsModified())
4001     {
4002         if (CPlayer::GetInstance().IsInnerLyric())      //保存内嵌歌词
4003         {
4004             wstring lyric_contents = CPlayer::GetInstance().m_Lyrics.GetLyricsString2();
4005             if (!lyric_contents.empty())
4006             {
4007                 CAudioTag audio_tag(CPlayer::GetInstance().GetCurrentSongInfo2());
4008                 audio_tag.WriteAudioLyric(lyric_contents);
4009                 CPlayer::GetInstance().m_Lyrics.SetModified(false);
4010             }
4011         }
4012         else
4013         {
4014             CPlayer::GetInstance().m_Lyrics.SaveLyric2();
4015         }
4016     }
4017 }
4018 
4019 
OnEditLyric()4020 void CMusicPlayerDlg::OnEditLyric()
4021 {
4022     // TODO: 在此添加命令处理程序代码
4023     //ShellExecute(NULL, _T("open"), CPlayer::GetInstance().m_Lyrics.GetPathName().c_str(), NULL, NULL, SW_SHOWNORMAL);
4024     CCommon::DeleteModelessDialog(m_pLyricEdit);
4025     if (!theApp.IsScintillaLoaded())
4026     {
4027         const wstring& info = theApp.m_str_table.LoadText(L"MSG_SCI_NOT_LOADED_ERROR");
4028         MessageBox(info.c_str(), NULL, MB_ICONERROR | MB_OK);
4029         return;
4030     }
4031     m_pLyricEdit = new CLyricEditDlg;
4032     m_pLyricEdit->Create(IDD_LYRIC_EDIT_DIALOG);
4033     m_pLyricEdit->ShowWindow(SW_SHOW);
4034 }
4035 
4036 
OnDownloadLyric()4037 void CMusicPlayerDlg::OnDownloadLyric()
4038 {
4039     // TODO: 在此添加命令处理程序代码
4040     CLyricDownloadDlg aDlg;
4041     aDlg.DoModal();
4042 }
4043 
4044 
OnLyricBatchDownload()4045 void CMusicPlayerDlg::OnLyricBatchDownload()
4046 {
4047     // TODO: 在此添加命令处理程序代码
4048     //CLyricBatchDownloadDlg aDlg;
4049     //aDlg.DoModal();
4050     CCommon::DeleteModelessDialog(m_pLyricBatchDownDlg);
4051     m_pLyricBatchDownDlg = new CLyricBatchDownloadDlg;
4052     m_pLyricBatchDownDlg->Create(IDD_LYRIC_BATCH_DOWN_DIALOG);
4053     m_pLyricBatchDownDlg->ShowWindow(SW_SHOW);
4054 
4055 }
4056 
4057 
OnDeleteLyric()4058 void CMusicPlayerDlg::OnDeleteLyric()
4059 {
4060     // TODO: 在此添加命令处理程序代码
4061     if (CCommon::FileExist(CPlayer::GetInstance().m_Lyrics.GetPathName()))
4062     {
4063         int rtn = CommonDialogMgr::DeleteAFile(m_hWnd, CPlayer::GetInstance().m_Lyrics.GetPathName());      //删除歌词文件
4064         CPlayer::GetInstance().ClearLyric();        //清除歌词关联
4065     }
4066 
4067     SongInfo song_info{ CSongDataManager::GetInstance().GetSongInfo3(CPlayer::GetInstance().GetCurrentSongInfo()) };
4068     song_info.SetNoOnlineLyric(true);
4069     CSongDataManager::GetInstance().AddItem(song_info);
4070 }
4071 
4072 
OnRButtonUp(UINT nFlags,CPoint point)4073 void CMusicPlayerDlg::OnRButtonUp(UINT nFlags, CPoint point)
4074 {
4075     // TODO: 在此添加消息处理程序代码和/或调用默认值
4076 
4077     CMainDialogBase::OnRButtonUp(nFlags, point);
4078 }
4079 
4080 
OnMouseMove(UINT nFlags,CPoint point)4081 void CMusicPlayerDlg::OnMouseMove(UINT nFlags, CPoint point)
4082 {
4083     // TODO: 在此添加消息处理程序代码和/或调用默认值
4084 
4085     CMainDialogBase::OnMouseMove(nFlags, point);
4086 }
4087 
4088 
OnLButtonUp(UINT nFlags,CPoint point)4089 void CMusicPlayerDlg::OnLButtonUp(UINT nFlags, CPoint point)
4090 {
4091     // TODO: 在此添加消息处理程序代码和/或调用默认值
4092 
4093     CMainDialogBase::OnLButtonUp(nFlags, point);
4094 }
4095 
4096 
OnLButtonDown(UINT nFlags,CPoint point)4097 void CMusicPlayerDlg::OnLButtonDown(UINT nFlags, CPoint point)
4098 {
4099     // TODO: 在此添加消息处理程序代码和/或调用默认值
4100 
4101     CMainDialogBase::OnLButtonDown(nFlags, point);
4102 }
4103 
4104 
OnCtlColor(CDC * pDC,CWnd * pWnd,UINT nCtlColor)4105 HBRUSH CMusicPlayerDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
4106 {
4107     HBRUSH hbr = CMainDialogBase::OnCtlColor(pDC, pWnd, nCtlColor);
4108 
4109     // TODO:  在此更改 DC 的任何特性
4110 
4111     // TODO:  如果默认的不是所需画笔,则返回另一个画笔
4112     if (pWnd == this || pWnd == &m_ui_static_ctrl /*|| pWnd == &m_path_static*/)
4113     {
4114         static HBRUSH hBackBrush{};
4115         if (hBackBrush == NULL)
4116             hBackBrush = CreateSolidBrush(CONSTVAL::BACKGROUND_COLOR);
4117         return hBackBrush;
4118     }
4119 
4120     return hbr;
4121 }
4122 
4123 
OnPlaylistIniComplate(WPARAM wParam,LPARAM lParam)4124 afx_msg LRESULT CMusicPlayerDlg::OnPlaylistIniComplate(WPARAM wParam, LPARAM lParam)
4125 {
4126     DoLyricsAutoSave();
4127     CPlayer::GetInstance().IniPlaylistComplate();
4128     theApp.DoWaitCursor(0);
4129     ShowPlayList();
4130     m_playlist_list.SelectNone();
4131     //ShowTime();
4132     DrawInfo(true);
4133     //SetPorgressBarSize();
4134     UpdatePlayPauseButton();
4135     //ShowTime();
4136 
4137     UpdateSongInfoToolTip();
4138 
4139     EnablePlaylist(true);
4140     theApp.DoWaitCursor(-1);
4141 
4142     SetPlaylistDragEnable();
4143 
4144     //static int last_play_mode = -1;
4145     //int play_mode = CPlayer::GetInstance().IsPlaylistMode();
4146     //if (last_play_mode != play_mode)
4147     //{
4148     //    //在文件夹模式和播放列表模式间切换时
4149     //    m_findDlg.ClearFindResult();
4150     //    last_play_mode = play_mode;
4151     //}
4152 
4153     //启动时第一次初始化完播放列表后更新媒体库
4154     if (theApp.m_media_lib_setting_data.update_media_lib_when_start_up)
4155     {
4156         static bool first_init{ true };
4157         if (first_init)
4158         {
4159             theApp.StartUpdateMediaLib(false);   // 获取不存在的项目以及更新修改时间变化的项目
4160             first_init = false;
4161         }
4162     }
4163 
4164     m_part_static_width = UpdatePlaylistCtrlPosition(this, &m_path_static, &m_path_edit);
4165     if (IsFloatPlaylistExist())
4166         UpdatePlaylistCtrlPosition(m_pFloatPlaylistDlg, &m_pFloatPlaylistDlg->GetPathStatic(), &m_pFloatPlaylistDlg->GetPathEdit());
4167 
4168 
4169     if (CPlayer::GetInstance().IsMediaLibMode())
4170     {
4171         CUiMediaLibItemMgr::Instance().SetCurrentName(CPlayer::GetInstance().GetMediaLibPlaylistType(), CPlayer::GetInstance().GetMedialibItemName());
4172     }
4173 
4174     return 0;
4175 }
4176 
4177 
OnAfterSetTrack(WPARAM wParam,LPARAM lParam)4178 afx_msg LRESULT CMusicPlayerDlg::OnAfterSetTrack(WPARAM wParam, LPARAM lParam)
4179 {
4180     wstring title = CSongInfoHelper::GetDisplayStr(CPlayer::GetInstance().GetCurrentSongInfo(), theApp.m_media_lib_setting_data.display_format);
4181     wstring title_suffix;
4182     if (!title.empty())
4183         title_suffix += L" - ";
4184     title_suffix += APP_NAME;
4185 
4186     if (CPlayer::GetInstance().IsMciCore())
4187         title_suffix += L" (MCI)";
4188     else if (CPlayer::GetInstance().IsFfmpegCore()) {
4189         title_suffix += L" (FFMPEG";
4190         auto core = (CFfmpegCore*)CPlayer::GetInstance().GetPlayerCore();
4191         if (core->IsWASAPISupported() && theApp.m_play_setting_data.ffmpeg_core_enable_WASAPI) {
4192             title_suffix += L", WASAPI";
4193             if (theApp.m_play_setting_data.ffmpeg_core_enable_WASAPI_exclusive_mode) {
4194                 title_suffix += L'(' + theApp.m_str_table.LoadText(L"UI_TITLE_EXCLUSIVE_MODE") + L')';
4195             }
4196         }
4197         title_suffix += L')';
4198     }
4199 
4200 #ifdef _DEBUG
4201     title_suffix += L' ';
4202     title_suffix += L'(' + theApp.m_str_table.LoadText(L"UI_TITLE_DEBUG_MODE") + L')';
4203 #endif
4204 
4205     theApp.m_window_title = title + title_suffix;
4206     SetWindowText(theApp.m_window_title.c_str());        //用当前正在播放的歌曲名作为窗口标题
4207 
4208     if (title_suffix.size() <= 127)
4209     {
4210         size_t title_length = 127 - title_suffix.size();
4211         if (title.size() > title_length)
4212             title = title.substr(0, title_length) + title_suffix;
4213         else
4214             title += title_suffix;
4215     }
4216     else
4217         title = title_suffix.substr(0, 127);
4218     m_notify_icon.SetIconToolTip(title.c_str());
4219 
4220     SwitchTrack();
4221     UpdatePlayPauseButton();
4222     CUiAllTracksMgr::Instance().SetCurrentSong(CPlayer::GetInstance().GetCurrentSongInfo());
4223 
4224     return 0;
4225 }
4226 
4227 
OnEqualizer()4228 void CMusicPlayerDlg::OnEqualizer()
4229 {
4230     // TODO: 在此添加命令处理程序代码
4231     if (CPlayer::GetInstance().IsMciCore())
4232     {
4233         const wstring& info = theApp.m_str_table.LoadText(L"MSG_MCI_NO_THIS_FUNCTION_WARNING");
4234         MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK);
4235         return;
4236     }
4237 
4238     CCommon::DeleteModelessDialog(m_pSoundEffecDlg);
4239     m_pSoundEffecDlg = new CSoundEffectDlg;
4240     m_pSoundEffecDlg->Create(IDD_SOUND_EFFECT_DIALOG);
4241     m_pSoundEffecDlg->ShowWindow(SW_SHOW);
4242 }
4243 
4244 
OnExploreOnline()4245 void CMusicPlayerDlg::OnExploreOnline()
4246 {
4247     // TODO: 在此添加命令处理程序代码
4248     m_pThread = AfxBeginThread(ViewOnlineThreadFunc, (void*)m_item_selected);
4249 }
4250 
ViewOnlineThreadFunc(LPVOID lpParam)4251 UINT CMusicPlayerDlg::ViewOnlineThreadFunc(LPVOID lpParam)
4252 {
4253     CCommon::SetThreadLanguageList(theApp.m_str_table.GetLanguageTag());
4254     //此命令用于跳转到歌曲对应的网易云音乐的在线页面
4255     int item_selected = (int)lpParam;
4256     if (item_selected >= 0 && item_selected < CPlayer::GetInstance().GetSongNum())
4257     {
4258         SongInfo& song{ CPlayer::GetInstance().GetPlayList()[item_selected] };
4259         CMusicPlayerCmdHelper helper;
4260         helper.VeiwOnline(song);
4261     }
4262     return 0;
4263 }
4264 
DownloadLyricAndCoverThreadFunc(LPVOID lpParam)4265 UINT CMusicPlayerDlg::DownloadLyricAndCoverThreadFunc(LPVOID lpParam)
4266 {
4267     CCommon::SetThreadLanguageList(theApp.m_str_table.GetLanguageTag());
4268     //CMusicPlayerDlg* pThis = (CMusicPlayerDlg*)lpParam;
4269 
4270     bool is_osu{ CPlayer::GetInstance().IsOsuFile() };
4271     // 获取媒体库项目后所有操作基于song_info_ori进行
4272     SongInfo song_info_ori{ CSongDataManager::GetInstance().GetSongInfo3(CPlayer::GetInstance().GetCurrentSongInfo()) };
4273     CFilePathHelper song_info_ori_path{ song_info_ori.file_path };
4274     if (theApp.m_general_setting_data.auto_download_only_tag_full)      //设置了“仅当歌曲信息完整进才自动下载”时,如果歌曲标题和艺术家有一个为空,则不自动下载
4275     {
4276         if (song_info_ori.IsTitleEmpty() || song_info_ori.IsArtistEmpty())
4277             return 0;
4278     }
4279 
4280     bool download_cover{ theApp.m_general_setting_data.auto_download_album_cover && !CPlayer::GetInstance().AlbumCoverExist() && !song_info_ori.is_cue && !song_info_ori.NoOnlineAlbumCover() };
4281     bool midi_lyric{ CPlayer::GetInstance().IsMidi() && theApp.m_play_setting_data.midi_use_inner_lyric };
4282     bool download_lyric{ theApp.m_general_setting_data.auto_download_lyric && CPlayer::GetInstance().m_Lyrics.IsEmpty() && !midi_lyric && !song_info_ori.NoOnlineLyric() };
4283     CInternetCommon::ItemInfo match_item;
4284     if (download_cover || download_lyric)
4285     {
4286         DownloadResult result{};
4287         if (song_info_ori.song_id == 0)      //如果没有获取过ID,则获取一次ID
4288         {
4289             //搜索歌曲并获取最佳匹配的项目
4290             match_item = CInternetCommon::SearchSongAndGetMatched(song_info_ori.title, song_info_ori.artist, song_info_ori.album, song_info_ori.GetFileName(), false, &result);
4291             song_info_ori.SetSongId(match_item.id);
4292             CSongDataManager::GetInstance().SetSongID(song_info_ori, song_info_ori.song_id);  // 与媒体库同步
4293         }
4294         if (song_info_ori.song_id == 0)
4295         {
4296             if (result == DR_DOWNLOAD_ERROR)     //如果搜索歌曲失败,则标记为没有在线歌词和专辑封面
4297             {
4298                 song_info_ori.SetNoOnlineAlbumCover(true);
4299                 song_info_ori.SetNoOnlineLyric(true);
4300                 CSongDataManager::GetInstance().AddItem(song_info_ori);
4301             }
4302             return 0;
4303         }
4304     }
4305     //自动下载专辑封面
4306     if (download_cover && !is_osu)  // osu文件不进行自动下载专辑封面
4307     {
4308         wstring cover_url = CCoverDownloadCommon::GetAlbumCoverURL(song_info_ori.GetSongId());
4309         if (cover_url.empty())
4310         {
4311             song_info_ori.SetNoOnlineAlbumCover(true);
4312             CSongDataManager::GetInstance().AddItem(song_info_ori);
4313             return 0;
4314         }
4315 
4316         //获取要保存的专辑封面的文件名
4317         wstring album_name;
4318         if (match_item.album == song_info_ori.album && !song_info_ori.album.empty())      //如果在线搜索结果的唱片集名称和歌曲的相同,则以“唱片集”为文件名保存
4319         {
4320             album_name = match_item.album;
4321             CCommon::FileNameNormalize(album_name);
4322         }
4323         else                //否则以歌曲文件名为文件名保存
4324         {
4325             album_name = song_info_ori.GetFileName();
4326         }
4327         // 判断是否保存到封面文件夹
4328         bool saved_to_album_cover_folder{ !theApp.m_general_setting_data.save_album_to_song_folder && CCommon::FolderExist(theApp.m_app_setting_data.album_cover_path) };
4329 
4330         CFilePathHelper cover_file_path;
4331         if (saved_to_album_cover_folder)
4332             cover_file_path.SetFilePath(theApp.m_app_setting_data.album_cover_path + album_name);
4333         else
4334             cover_file_path.SetFilePath(song_info_ori_path.GetDir() + album_name);
4335 
4336         CFilePathHelper url_path(cover_url);
4337         cover_file_path.ReplaceFileExtension(url_path.GetFileExtension().c_str());
4338 
4339         //下面专辑封面
4340         URLDownloadToFile(0, cover_url.c_str(), cover_file_path.GetFilePath().c_str(), 0, NULL);
4341 
4342         //将下载的专辑封面改为隐藏属性
4343         if (!saved_to_album_cover_folder)
4344             SetFileAttributes(cover_file_path.GetFilePath().c_str(), FILE_ATTRIBUTE_HIDDEN);
4345 
4346         //重新从本地获取专辑封面
4347         CPlayer::GetInstance().SearchOutAlbumCover();
4348         ::PostMessage(theApp.m_pMainWnd->GetSafeHwnd(), WM_ALBUM_COVER_DOWNLOAD_COMPLETE, 0, 0);
4349     }
4350     //自动下载歌词
4351     if (download_lyric)
4352     {
4353         //下载歌词
4354         wstring lyric_str;
4355         if (!CLyricDownloadCommon::DownloadLyric(song_info_ori.GetSongId(), lyric_str, true))
4356         {
4357             song_info_ori.SetNoOnlineLyric(true);
4358             CSongDataManager::GetInstance().AddItem(song_info_ori);
4359             return 0;
4360         }
4361         if (!CLyricDownloadCommon::DisposeLryic(lyric_str))
4362         {
4363             song_info_ori.SetNoOnlineLyric(true);
4364             CSongDataManager::GetInstance().AddItem(song_info_ori);
4365             return 0;
4366         }
4367         CLyricDownloadCommon::AddLyricTag(lyric_str, match_item.id, match_item.title, match_item.artist, match_item.album);
4368         //保存歌词
4369         CFilePathHelper lyric_path;
4370         wstring file_name;
4371         if (!song_info_ori.is_cue && !is_osu)   // osu文件使用与cue同样的“艺术家 - 标题”保存自动下载歌词
4372             file_name = song_info_ori.GetFileName();
4373         else
4374         {
4375             file_name = song_info_ori.artist + L" - " + song_info_ori.title + L".lrc";
4376             CCommon::FileNameNormalize(file_name);
4377         }
4378         if (!theApp.m_general_setting_data.save_lyric_to_song_folder && CCommon::FolderExist(theApp.m_lyric_setting_data.lyric_path))
4379         {
4380             lyric_path.SetFilePath(theApp.m_lyric_setting_data.lyric_path + file_name);
4381         }
4382         else
4383         {
4384             lyric_path.SetFilePath(song_info_ori_path.GetDir() + file_name);
4385         }
4386         lyric_path.ReplaceFileExtension(L"lrc");
4387         string _lyric_str = CCommon::UnicodeToStr(lyric_str, CodeType::UTF8);
4388         ofstream out_put{ lyric_path.GetFilePath(), std::ios::binary };
4389         out_put << _lyric_str;
4390         out_put.close();
4391         //处理歌词翻译
4392         CLyrics lyrics{ lyric_path.GetFilePath(), CLyrics::LyricType::LY_LRC_NETEASE };     // 打开网易云半json的原始歌词
4393         lyrics.SaveLyric2(theApp.m_general_setting_data.download_lyric_text_and_translation_in_same_line);                                                                // 保存为lrc格式
4394 
4395         CPlayer::GetInstance().IniLyrics(lyric_path.GetFilePath());
4396     }
4397     return 0;
4398 }
4399 
UiThreadFunc(LPVOID lpParam)4400 UINT CMusicPlayerDlg::UiThreadFunc(LPVOID lpParam)
4401 {
4402     CCommon::SetThreadLanguageList(theApp.m_str_table.GetLanguageTag());
4403     UIThreadPara* pPara = (UIThreadPara*)lpParam;
4404     CMusicPlayerDlg* pThis = dynamic_cast<CMusicPlayerDlg*>(theApp.m_pMainWnd);
4405     int fresh_cnt{ };
4406     while (true)
4407     {
4408         if (pPara->ui_thread_exit)
4409             break;
4410 
4411         //获取频谱顶端的数据
4412         CPlayer::GetInstance().CalculateSpectralDataPeak();
4413 
4414         //获取当前播放进度
4415         //这里将获取当前播放进度的处理放到UI线程中,和UI同步,使得当界面刷新时间间隔设置得比较小时歌词和进度条看起来更加流畅
4416         if (CPlayer::GetInstance().IsPlaying() && CPlayer::GetInstance().GetPlayStatusMutex().try_lock_for(std::chrono::milliseconds(10)))
4417         {
4418             if (CPlayer::GetInstance().IsMciCore())
4419                 pThis->SendMessage(WM_GET_MUSIC_CURRENT_POSITION);     //由于MCI无法跨线程操作,因此在这里向主线程发送消息,在主线程中处理
4420             else
4421                 CPlayer::GetInstance().GetPlayerCoreCurrentPosition();
4422             CPlayer::GetInstance().GetPlayStatusMutex().unlock();
4423         }
4424 
4425         //绘制主界面
4426         if (pThis->IsWindowVisible() && !pThis->IsIconic()
4427             && (CPlayer::GetInstance().IsPlaying() || pPara->is_active_window || pPara->draw_reset || pPara->ui_force_refresh || CPlayer::GetInstance().m_loading || theApp.IsMeidaLibUpdating())
4428             && (!pPara->is_completely_covered || theApp.m_nc_setting_data.always_on_top)
4429             )
4430             //窗口最小化、隐藏,以及窗口未激活并且未播放时不刷新界面,以降低CPU利用率
4431         {
4432             fresh_cnt = 2;
4433         }
4434         if (fresh_cnt)
4435         {
4436             fresh_cnt--;
4437             pThis->m_pUI->DrawInfo(pPara->draw_reset);
4438             pPara->draw_reset = false;
4439             pPara->ui_force_refresh = false;
4440         }
4441 
4442         //绘制迷你模式界面
4443         if (IsWindow(pThis->m_miniModeDlg.GetSafeHwnd()))
4444             pThis->m_miniModeDlg.DrawInfo();
4445 
4446         //在Cortana搜索框里显示歌词
4447         if (theApp.m_lyric_setting_data.cortana_info_enable)
4448         {
4449             if (theApp.m_lyric_setting_data.cortana_lyric_keep_display || CPlayer::GetInstance().IsPlaying() || pPara->search_box_force_refresh)
4450             {
4451                 pThis->m_cortana_lyric.DrawInfo();
4452                 pPara->search_box_force_refresh = false;
4453             }
4454         }
4455 
4456         //显示桌面歌词
4457         bool desktop_lyric_visible = theApp.m_lyric_setting_data.show_desktop_lyric;
4458         if (CPlayer::GetInstance().m_Lyrics.IsEmpty() && theApp.m_lyric_setting_data.desktop_lyric_data.hide_lyric_window_without_lyric)
4459             desktop_lyric_visible = false;
4460         if (!CPlayer::GetInstance().IsPlaying() && theApp.m_lyric_setting_data.desktop_lyric_data.hide_lyric_window_when_paused)
4461             desktop_lyric_visible = false;
4462         pThis->m_desktop_lyric.SetLyricWindowVisible(desktop_lyric_visible);
4463         if (desktop_lyric_visible)
4464         {
4465             pThis->m_desktop_lyric.ShowLyric();
4466         }
4467 
4468         CPlayer::GetInstance().m_controls.UpdatePosition(CPlayer::GetInstance().GetCurrentPosition());
4469         pThis->m_fps_cnt++;
4470         Sleep(theApp.m_app_setting_data.ui_refresh_interval);
4471     }
4472     return 0;
4473 }
4474 
4475 
4476 
OnPlaylistIniStart(WPARAM wParam,LPARAM lParam)4477 afx_msg LRESULT CMusicPlayerDlg::OnPlaylistIniStart(WPARAM wParam, LPARAM lParam)
4478 {
4479     EnablePlaylist(false);
4480     theApp.DoWaitCursor(1);
4481     m_play_error_cnt = 0;
4482     UpdatePlayPauseButton();
4483     DrawInfo(true);
4484 
4485     // 移除wParam指示的列表项目
4486     ListItem* pListItem = reinterpret_cast<ListItem*>(wParam);
4487     if (pListItem && CRecentList::Instance().RemoveItem(*pListItem) && pListItem->type == LT_PLAYLIST)
4488         CommonDialogMgr::DeleteAFile(this->GetSafeHwnd(), pListItem->path);
4489     return 0;
4490 }
4491 
4492 
OnBrowseLyric()4493 void CMusicPlayerDlg::OnBrowseLyric()
4494 {
4495     // TODO: 在此添加命令处理程序代码
4496     CPlayer::GetInstance().ExploreLyric();
4497 }
4498 
4499 
OnTranslateToSimplifiedChinese()4500 void CMusicPlayerDlg::OnTranslateToSimplifiedChinese()
4501 {
4502     // TODO: 在此添加命令处理程序代码
4503     CWaitCursor wait_cursor;
4504     CPlayer::GetInstance().m_Lyrics.ChineseConvertion(true);
4505 }
4506 
4507 
OnTranslateToTranditionalChinese()4508 void CMusicPlayerDlg::OnTranslateToTranditionalChinese()
4509 {
4510     // TODO: 在此添加命令处理程序代码
4511     CWaitCursor wait_cursor;
4512     CPlayer::GetInstance().m_Lyrics.ChineseConvertion(false);
4513 }
4514 
4515 
OnAlbumCoverSaveAs()4516 void CMusicPlayerDlg::OnAlbumCoverSaveAs()
4517 {
4518     // TODO: 在此添加命令处理程序代码
4519     //设置过滤器
4520     wstring szFilter = theApp.m_str_table.LoadText(L"TXT_FILTER_ALL_FILES") + L"(*.*)|*.*||";
4521     //设置另存为时的默认文件名
4522     CString file_name;
4523     wstring extension;
4524     if (CPlayer::GetInstance().IsInnerCover())
4525     {
4526         extension = CPlayer::GetInstance().GetAlbumCoverType();
4527     }
4528     else
4529     {
4530         CFilePathHelper cover_path(CPlayer::GetInstance().GetAlbumCoverPath());
4531         extension = cover_path.GetFileExtension();
4532     }
4533     file_name.Format(_T("AlbumCover - %s - %s.%s"), CPlayer::GetInstance().GetCurrentSongInfo().artist.c_str(), CPlayer::GetInstance().GetCurrentSongInfo().album.c_str(), extension.c_str());
4534     wstring file_name_wcs{ file_name };
4535     CCommon::FileNameNormalize(file_name_wcs);      //替换掉文件名中的无效字符
4536     //构造保存文件对话框
4537     CFileDialog fileDlg(FALSE, _T("txt"), file_name_wcs.c_str(), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter.c_str(), this);
4538     //显示保存文件对话框
4539     if (IDOK == fileDlg.DoModal())
4540     {
4541         CString dest_file = fileDlg.GetPathName();
4542         ::CopyFile(CPlayer::GetInstance().GetAlbumCoverPath().c_str(), dest_file, FALSE);
4543         SetFileAttributes(dest_file, FILE_ATTRIBUTE_NORMAL);        //取消文件的隐藏属性
4544     }
4545 }
4546 
4547 
OnConnotPlayWarning(WPARAM wParam,LPARAM lParam)4548 afx_msg LRESULT CMusicPlayerDlg::OnConnotPlayWarning(WPARAM wParam, LPARAM lParam)
4549 {
4550     if (theApp.m_nc_setting_data.no_sf2_warning)
4551     {
4552         const wstring& info = theApp.m_str_table.LoadText(L"MSG_NO_MIDI_SF2_WARNING");
4553         if (MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OKCANCEL) == IDCANCEL)
4554             theApp.m_nc_setting_data.no_sf2_warning = false;
4555     }
4556     return 0;
4557 }
4558 
4559 
OnEnChangeSearchEdit()4560 void CMusicPlayerDlg::OnEnChangeSearchEdit()
4561 {
4562     // TODO:  如果该控件是 RICHEDIT 控件,它将不
4563     // 发送此通知,除非重写 CMainDialogBase::OnInitDialog()
4564     // 函数并调用 CRichEditCtrl().SetEventMask(),
4565     // 同时将 ENM_CHANGE 标志“或”运算到掩码中。
4566 
4567     // TODO:  在此添加控件通知处理程序代码
4568     CString key_word;
4569     m_search_edit.GetWindowText(key_word);
4570     m_searched = (key_word.GetLength() != 0);
4571     SetPlaylistDragEnable();
4572     m_playlist_list.QuickSearch(wstring(key_word));
4573     m_playlist_list.ShowPlaylist(theApp.m_media_lib_setting_data.display_format, m_searched);
4574 }
4575 
4576 
4577 //void CMusicPlayerDlg::OnBnClickedClearSearchButton()
4578 //{
4579 //    // TODO: 在此添加控件通知处理程序代码
4580 //    if (m_searched)
4581 //    {
4582 //        //清除搜索结果
4583 //        m_searched = false;
4584 //        m_search_edit.SetWindowText(_T(""));
4585 //        m_playlist_list.ShowPlaylist(theApp.m_media_lib_setting_data.display_format, m_searched);
4586 //        m_playlist_list.EnsureVisible(CPlayer::GetInstance().GetIndex(), FALSE);      //清除搜索结果后确保正在播放曲目可见
4587 //    }
4588 //}
4589 
4590 
OnDownloadAlbumCover()4591 void CMusicPlayerDlg::OnDownloadAlbumCover()
4592 {
4593     // TODO: 在此添加命令处理程序代码
4594     //_OnDownloadAlbumCover(true);
4595     CCoverDownloadDlg dlg;
4596     dlg.DoModal();
4597 }
4598 
4599 
OnPostMusicStreamOpened(WPARAM wParam,LPARAM lParam)4600 afx_msg LRESULT CMusicPlayerDlg::OnPostMusicStreamOpened(WPARAM wParam, LPARAM lParam)
4601 {
4602     CPlayer::GetInstance().ResetABRepeat();
4603     UpdateABRepeatToolTip();
4604 
4605     return 0;
4606 }
4607 
4608 
OnMusicStreamOpened(WPARAM wParam,LPARAM lParam)4609 afx_msg LRESULT CMusicPlayerDlg::OnMusicStreamOpened(WPARAM wParam, LPARAM lParam)
4610 {
4611     //专辑封面高斯模糊处理(放到这里是为了避免此函数在工作线程中被调用,在工作线程中,拉伸图片的处理CDrawCommon::BitmapStretch有一定的概率出错,原因未知)
4612     CPlayer::GetInstance().AlbumCoverGaussBlur();
4613     //自动下载专辑封面
4614     m_pDownloadThread = AfxBeginThread(DownloadLyricAndCoverThreadFunc, this);
4615 
4616     m_desktop_lyric.ClearLyric();
4617 
4618     //保存播放时间
4619     SYSTEMTIME sys_time;
4620     GetLocalTime(&sys_time);
4621     CTime cur_time(sys_time);
4622     auto cur_time_int = cur_time.GetTime();
4623     SongInfo song_info{ CSongDataManager::GetInstance().GetSongInfo3(CPlayer::GetInstance().GetCurrentSongInfo()) };
4624     song_info.last_played_time = cur_time_int;
4625     CSongDataManager::GetInstance().AddItem(song_info);
4626 
4627     return 0;
4628 }
4629 
4630 
OnCurrentExploreOnline()4631 void CMusicPlayerDlg::OnCurrentExploreOnline()
4632 {
4633     // TODO: 在此添加命令处理程序代码
4634     m_pThread = AfxBeginThread(ViewOnlineThreadFunc, (void*)CPlayer::GetInstance().GetIndex());
4635 }
4636 
4637 
OnDeleteAlbumCover()4638 void CMusicPlayerDlg::OnDeleteAlbumCover()
4639 {
4640     // TODO: 在此添加命令处理程序代码
4641     wstring delete_info;
4642     bool is_inner_cover{ CPlayer::GetInstance().IsInnerCover() };
4643     if (is_inner_cover)
4644         delete_info = theApp.m_str_table.LoadText(L"MSG_DELETE_INNER_COVER_INQUERY");
4645     else
4646         delete_info = theApp.m_str_table.LoadTextFormat(L"MSG_DELETE_SINGLE_FILE_INQUIRY", { CPlayer::GetInstance().GetAlbumCoverPath() });
4647     if (MessageBox(delete_info.c_str(), NULL, MB_ICONQUESTION | MB_OKCANCEL) == IDOK)
4648     {
4649         bool result{ false };
4650         //内嵌专辑封面,从音频文件中删除
4651         if (is_inner_cover)
4652         {
4653             CPlayer::ReOpen reopen(true);
4654             if (reopen.IsLockSuccess())
4655             {
4656                 CAudioTag audio_tag(CPlayer::GetInstance().GetCurrentSongInfo2());
4657                 result = audio_tag.WriteAlbumCover(wstring());
4658             }
4659             else
4660             {
4661                 const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY");
4662                 MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK);
4663             }
4664         }
4665         //外部专辑封面,删除专辑封面文件
4666         else
4667         {
4668             result = (CommonDialogMgr::DeleteAFile(theApp.m_pMainWnd->GetSafeHwnd(), CPlayer::GetInstance().GetAlbumCoverPath().c_str()) == ERROR_SUCCESS);
4669             CPlayer::GetInstance().SearchAlbumCover();      // 重新获取专辑封面(代替原来的m_album_cover.Destroy();)
4670             CPlayer::GetInstance().AlbumCoverGaussBlur();
4671         }
4672 
4673         if (result)
4674         {
4675             SongInfo song_info{ CSongDataManager::GetInstance().GetSongInfo3(CPlayer::GetInstance().GetCurrentSongInfo()) };
4676             song_info.SetNoOnlineAlbumCover(true);  // 此歌曲封面经过手动操作,设置标志位不进行自动下载封面
4677             CSongDataManager::GetInstance().AddItem(song_info);
4678         }
4679         else
4680         {
4681             MessageBox(theApp.m_str_table.LoadText(L"MSG_DELETE_FILE_FAILED").c_str(), NULL, MB_ICONWARNING);
4682         }
4683     }
4684 }
4685 
4686 
OnCopyFileTo()4687 void CMusicPlayerDlg::OnCopyFileTo()
4688 {
4689     // TODO: 在此添加命令处理程序代码
4690     const wstring& title = theApp.m_str_table.LoadText(L"TITLE_FOLDER_BROWSER_COPY_TARGET");
4691 #ifdef COMPILE_IN_WIN_XP
4692     CFolderBrowserDlg folderPickerDlg(this->GetSafeHwnd());
4693     folderPickerDlg.SetInfo(title.c_str());
4694 #else
4695     CFilePathHelper current_path(CPlayer::GetInstance().GetCurrentDir());
4696     CFolderPickerDialog folderPickerDlg(current_path.GetParentDir().c_str());
4697     folderPickerDlg.m_ofn.lpstrTitle = title.c_str();
4698 #endif
4699     if (folderPickerDlg.DoModal() == IDOK)
4700     {
4701         if (m_item_selected < 0 || m_item_selected >= CPlayer::GetInstance().GetSongNum())
4702             return;
4703         if (m_items_selected.size() > 1)
4704         {
4705             vector<wstring> source_files;
4706             for (const auto& index : m_items_selected)
4707             {
4708                 const auto& song = CPlayer::GetInstance().GetPlayList()[index];
4709                 if (!song.is_cue)
4710                     source_files.push_back(song.file_path);
4711             }
4712             if (source_files.empty())
4713                 return;
4714             CommonDialogMgr::CopyFiles(this->GetSafeHwnd(), source_files, wstring(folderPickerDlg.GetPathName()));
4715         }
4716         else
4717         {
4718             const auto& song = CPlayer::GetInstance().GetPlayList()[m_item_selected];
4719             if (song.is_cue)
4720                 return;
4721             CommonDialogMgr::CopyAFile(this->GetSafeHwnd(), song.file_path, wstring(folderPickerDlg.GetPathName()));
4722         }
4723     }
4724 }
4725 
4726 
OnMoveFileTo()4727 void CMusicPlayerDlg::OnMoveFileTo()
4728 {
4729     // TODO: 在此添加命令处理程序代码
4730     if (theApp.m_media_lib_setting_data.disable_delete_from_disk)
4731         return;
4732 
4733     const wstring& title = theApp.m_str_table.LoadText(L"TITLE_FOLDER_BROWSER_MOVE_TARGET");
4734 #ifdef COMPILE_IN_WIN_XP
4735     CFolderBrowserDlg folderPickerDlg(this->GetSafeHwnd());
4736     folderPickerDlg.SetInfo(title.c_str());
4737 #else
4738     CFilePathHelper current_path(CPlayer::GetInstance().GetCurrentDir());
4739     CFolderPickerDialog folderPickerDlg(current_path.GetParentDir().c_str());
4740     folderPickerDlg.m_ofn.lpstrTitle = title.c_str();
4741 #endif
4742     if (folderPickerDlg.DoModal() == IDOK)
4743     {
4744         if (m_item_selected < 0 || m_item_selected >= CPlayer::GetInstance().GetSongNum())
4745             return;
4746         if (CPlayer::GetInstance().m_loading) return;
4747         if (!CPlayer::GetInstance().GetPlayStatusMutex().try_lock_for(std::chrono::milliseconds(1000))) return;
4748         wstring source_file;
4749         vector<wstring> source_files;
4750         int rtn;
4751         if (m_items_selected.size() > 1)
4752         {
4753             if (CCommon::IsItemInVector(m_items_selected, CPlayer::GetInstance().GetIndex()))   //如果选中的文件中有正在播放的文件,则移动前必须先关闭文件
4754                 CPlayer::GetInstance().MusicControl(Command::CLOSE);
4755             for (const auto& index : m_items_selected)
4756             {
4757                 const auto& song = CPlayer::GetInstance().GetPlayList()[index];
4758                 if (!song.is_cue && !COSUPlayerHelper::IsOsuFile(song.file_path))
4759                     source_files.push_back(song.file_path);
4760             }
4761             if (source_files.empty())
4762                 return;
4763             rtn = CommonDialogMgr::MoveFiles(m_hWnd, source_files, wstring(folderPickerDlg.GetPathName()));
4764         }
4765         else
4766         {
4767             if (m_item_selected == CPlayer::GetInstance().GetIndex())   //如果移动的文件是正在播放的文件,则移动前必须先关闭文件
4768                 CPlayer::GetInstance().MusicControl(Command::CLOSE);
4769             const auto& song = CPlayer::GetInstance().GetPlayList()[m_item_selected];
4770             if (song.is_cue || COSUPlayerHelper::IsOsuFile(song.file_path))
4771                 return;
4772             source_file = song.file_path;
4773             rtn = CommonDialogMgr::MoveAFile(m_hWnd, source_file, wstring(folderPickerDlg.GetPathName()));
4774         }
4775         if (rtn == ERROR_SUCCESS)
4776         {
4777             //如果文件移动成功,同时从播放列表中移除
4778             if (m_items_selected.size() > 1)
4779                 CPlayer::GetInstance().RemoveSongs(m_items_selected, true);
4780             else
4781                 CPlayer::GetInstance().RemoveSong(m_item_selected, true);
4782             ShowPlayList();
4783             UpdatePlayPauseButton();
4784             DrawInfo(true);
4785         }
4786         CPlayer::GetInstance().GetPlayStatusMutex().unlock();
4787     }
4788 }
4789 
4790 
OnFormatConvert()4791 void CMusicPlayerDlg::OnFormatConvert()
4792 {
4793     // TODO: 在此添加命令处理程序代码
4794     std::vector<SongInfo> songs;
4795     for (int index : m_items_selected)
4796     {
4797         if (index >= 0 && index < CPlayer::GetInstance().GetSongNum())
4798             songs.push_back(CPlayer::GetInstance().GetPlayList()[index]);
4799     }
4800     CMusicPlayerCmdHelper cmd_helper(this);
4801     cmd_helper.FormatConvert(songs);
4802 }
4803 
4804 
OnFormatConvert1()4805 void CMusicPlayerDlg::OnFormatConvert1()
4806 {
4807     // TODO: 在此添加命令处理程序代码
4808     std::vector<SongInfo> songs;
4809     songs.push_back(CPlayer::GetInstance().GetCurrentSongInfo());
4810     CMusicPlayerCmdHelper cmd_helper(this);
4811     cmd_helper.FormatConvert(songs);
4812 }
4813 
4814 
OnSettingsApplied(WPARAM wParam,LPARAM lParam)4815 afx_msg LRESULT CMusicPlayerDlg::OnSettingsApplied(WPARAM wParam, LPARAM lParam)
4816 {
4817     COptionsDlg* pOptionsDlg = (COptionsDlg*)wParam;
4818     if (pOptionsDlg == nullptr)
4819         return 0;
4820     ApplySettings(*pOptionsDlg);
4821     return 0;
4822 }
4823 
4824 
OnAlbumCoverDownloadComplete(WPARAM wParam,LPARAM lParam)4825 afx_msg LRESULT CMusicPlayerDlg::OnAlbumCoverDownloadComplete(WPARAM wParam, LPARAM lParam)
4826 {
4827     //由于此函数放到线程中处理时,拉伸图片的处理CDrawCommon::BitmapStretch有一定的概率出错,原因未知
4828     //导致专辑封面背景是黑色的,因此通过发送消息放到主线程中处理
4829     CPlayer::GetInstance().AlbumCoverGaussBlur();
4830 
4831     if (theApp.m_nc_setting_data.show_cover_tip)
4832     {
4833         UpdateSongInfoToolTip();
4834     }
4835 
4836     return 0;
4837 }
4838 
4839 
OnColorizationColorChanged(DWORD dwColorizationColor,BOOL bOpacity)4840 void CMusicPlayerDlg::OnColorizationColorChanged(DWORD dwColorizationColor, BOOL bOpacity)
4841 {
4842     // 此功能要求 Windows Vista 或更高版本。
4843     // _WIN32_WINNT 符号必须 >= 0x0600。
4844     // TODO: 在此添加消息处理程序代码和/或调用默认值
4845     static DWORD last_color;
4846     if (last_color != dwColorizationColor)
4847     {
4848         last_color = dwColorizationColor;
4849         m_theme_color_changed = true;
4850     }
4851 
4852     CMainDialogBase::OnColorizationColorChanged(dwColorizationColor, bOpacity);
4853 }
4854 
4855 
OnSupportedFormat()4856 void CMusicPlayerDlg::OnSupportedFormat()
4857 {
4858     // TODO: 在此添加命令处理程序代码
4859     CSupportedFormatDlg dlg;
4860     dlg.DoModal();
4861 }
4862 
4863 
OnSwitchUi()4864 void CMusicPlayerDlg::OnSwitchUi()
4865 {
4866     // TODO: 在此添加命令处理程序代码
4867 
4868     //if (m_pUI == &m_ui)
4869     //{
4870     //    m_pUI = &m_ui2;
4871     //    m_ui.ClearBtnRect();
4872     //    //m_ui.UpdateToolTipPosition();
4873     //}
4874     //else
4875     //{
4876     //    m_pUI = &m_ui;
4877     //    m_ui2.ClearBtnRect();
4878     //    //m_ui2.UpdateToolTipPosition();
4879     //}
4880 
4881     int ui_selected = GetUiSelected();
4882     ui_selected++;
4883     if (ui_selected >= static_cast<int>(m_ui_list.size()))
4884         ui_selected = 0;
4885     SelectUi(ui_selected);
4886     auto pCurUi = GetCurrentUi();
4887     if (pCurUi != nullptr)
4888         pCurUi->ClearBtnRect();
4889 
4890     DrawInfo(true);
4891     if (pCurUi != nullptr)
4892     {
4893         pCurUi->UpdateRepeatModeToolTip();
4894         pCurUi->UpdateVolumeToolTip();
4895     }
4896 }
4897 
OnVolumeUp()4898 void CMusicPlayerDlg::OnVolumeUp()
4899 {
4900     AdjustVolume(theApp.m_nc_setting_data.volum_step);
4901 }
4902 
OnVolumeDown()4903 void CMusicPlayerDlg::OnVolumeDown()
4904 {
4905     AdjustVolume(-theApp.m_nc_setting_data.volum_step);
4906 }
4907 
4908 
OnNotifyicon(WPARAM wParam,LPARAM lParam)4909 afx_msg LRESULT CMusicPlayerDlg::OnNotifyicon(WPARAM wParam, LPARAM lParam)
4910 {
4911     if (lParam == WM_LBUTTONUP)
4912     {
4913         if (IsFloatPlaylistExist() && m_miniModeDlg.m_hWnd == NULL)
4914             m_pFloatPlaylistDlg->ShowWindow(SW_SHOW);
4915     }
4916 
4917     m_notify_icon.OnNotifyIcon(lParam, m_miniModeDlg.m_hWnd);
4918 
4919     if (lParam == WM_LBUTTONUP && m_miniModeDlg.m_hWnd == NULL)
4920     {
4921         TaskBarInit();
4922     }
4923 
4924     return 0;
4925 }
4926 
4927 
OnClose()4928 void CMusicPlayerDlg::OnClose()
4929 {
4930     // TODO: 在此添加消息处理程序代码和/或调用默认值
4931 
4932     CMainDialogBase::OnClose();
4933 }
4934 
4935 
OnCancel()4936 void CMusicPlayerDlg::OnCancel()
4937 {
4938     // TODO: 在此添加专用代码和/或调用基类
4939     if (theApp.m_general_setting_data.minimize_to_notify_icon)
4940     {
4941         ShowWindow(SW_HIDE);
4942         if (IsFloatPlaylistExist())
4943         {
4944             m_pFloatPlaylistDlg->ShowWindow(SW_HIDE);
4945         }
4946     }
4947     else
4948     {
4949         CMainDialogBase::OnCancel();
4950         CBaseDialog::CloseAllWindow();
4951     }
4952 }
4953 
4954 
OnMenuExit()4955 void CMusicPlayerDlg::OnMenuExit()
4956 {
4957     // TODO: 在此添加命令处理程序代码
4958     if (m_miniModeDlg.m_hWnd == NULL)
4959     {
4960         CMainDialogBase::OnCancel();
4961     }
4962     else
4963     {
4964         ::SendMessage(m_miniModeDlg.m_hWnd, WM_COMMAND, ID_MINI_MODE_EXIT, NULL);
4965     }
4966     CBaseDialog::CloseAllWindow();
4967 }
4968 
4969 
OnMinimodeRestore()4970 void CMusicPlayerDlg::OnMinimodeRestore()
4971 {
4972     // TODO: 在此添加命令处理程序代码
4973     if (m_miniModeDlg.m_hWnd == NULL)
4974     {
4975         OnMiniMode();
4976     }
4977     else
4978     {
4979         ::SendMessage(m_miniModeDlg.m_hWnd, WM_COMMAND, IDOK, NULL);
4980     }
4981 }
4982 
4983 
OnAppCommand(CWnd * pWnd,UINT nCmd,UINT nDevice,UINT nKey)4984 void CMusicPlayerDlg::OnAppCommand(CWnd* pWnd, UINT nCmd, UINT nDevice, UINT nKey)
4985 {
4986     // 该功能要求使用 Windows 2000 或更高版本。
4987     // 符号 _WIN32_WINNT 和 WINVER 必须 >= 0x0500。
4988 
4989     ////响应多媒体键
4990     //if (!theApp.IsGlobalMultimediaKeyEnabled() && !CPlayer::GetInstance().m_controls.IsActive()) //如果没有设置响应全局的多媒体按键消息,则在当前窗口内响应多媒体按键消息
4991     //{
4992     //    switch (nCmd)
4993     //    {
4994     //    case APPCOMMAND_MEDIA_PLAY_PAUSE:
4995     //        OnPlayPause();
4996     //        break;
4997     //    case APPCOMMAND_MEDIA_PREVIOUSTRACK:
4998     //        OnPrevious();
4999     //        break;
5000     //    case APPCOMMAND_MEDIA_NEXTTRACK:
5001     //        OnNext();
5002     //        break;
5003     //    case APPCOMMAND_MEDIA_STOP:
5004     //        OnStop();
5005     //        break;
5006     //    default:
5007     //        break;
5008     //    }
5009     //}
5010 
5011     CMainDialogBase::OnAppCommand(pWnd, nCmd, nDevice, nKey);
5012 }
5013 
5014 
5015 
OnShowPlaylist()5016 void CMusicPlayerDlg::OnShowPlaylist()
5017 {
5018     // TODO: 在此添加命令处理程序代码
5019     //if (theApp.m_media_lib_setting_data.playlist_btn_for_float_playlist)
5020     //    ShowHideFloatPlaylist();
5021     //else
5022     //    ShowHidePlaylist();
5023     ShowHidePlaylist();
5024 }
5025 
5026 
OnSetCursor(CWnd * pWnd,UINT nHitTest,UINT message)5027 BOOL CMusicPlayerDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
5028 {
5029     // TODO: 在此添加消息处理程序代码和/或调用默认值
5030     if (m_pUI->SetCursor())
5031         return TRUE;
5032     else
5033         return CMainDialogBase::OnSetCursor(pWnd, nHitTest, message);
5034 }
5035 
5036 
OnMouseLeave()5037 void CMusicPlayerDlg::OnMouseLeave()
5038 {
5039     // TODO: 在此添加消息处理程序代码和/或调用默认值
5040 
5041     CMainDialogBase::OnMouseLeave();
5042 }
5043 
5044 
OnShowMenuBar()5045 void CMusicPlayerDlg::OnShowMenuBar()
5046 {
5047     // TODO: 在此添加命令处理程序代码
5048     theApp.m_ui_data.show_menu_bar = !theApp.m_ui_data.show_menu_bar;
5049     if (theApp.m_app_setting_data.show_window_frame)
5050     {
5051         SetMenubarVisible();
5052     }
5053     auto pCurUi = GetCurrentUi();
5054     if (pCurUi != nullptr)
5055         pCurUi->ClearBtnRect();
5056 
5057     DrawInfo(true);
5058 
5059     if (pCurUi != nullptr)
5060         pCurUi->UpdateToolTipPositionLater();
5061 
5062     //隐藏菜单栏后弹出提示,告诉用户如何再次显示菜单栏
5063     if (!theApp.m_ui_data.show_menu_bar)
5064     {
5065         if (theApp.m_nc_setting_data.show_hide_menu_bar_tip)
5066         {
5067             const wstring& info = theApp.m_str_table.LoadText(L"MSG_HIDE_MENU_BAR_INFO");
5068             if (MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OKCANCEL) == IDCANCEL)
5069                 theApp.m_nc_setting_data.show_hide_menu_bar_tip = false;
5070         }
5071     }
5072 }
5073 
5074 
OnFullScreen()5075 void CMusicPlayerDlg::OnFullScreen()
5076 {
5077     // TODO: 在此添加命令处理程序代码
5078 
5079     if (m_miniModeDlg.m_hWnd != NULL)   //迷你模式下不允许响应全屏显示
5080         return;
5081 
5082     // 记录进入全屏时是否最大化,若是否显示大小边框成为全局变量可改用其他实现方式
5083     static bool is_zoomed{};
5084     if (!theApp.m_ui_data.full_screen)
5085         is_zoomed = IsZoomed();
5086 
5087     theApp.m_ui_data.full_screen = !theApp.m_ui_data.full_screen;
5088 
5089     // 全屏时不显示标题栏、菜单栏与大小边框
5090     ShowTitlebar(!theApp.m_ui_data.full_screen && theApp.m_app_setting_data.show_window_frame);
5091     SetMenubarVisible();
5092     if (!is_zoomed)          // 最大化时进入全屏以及之后的退出全屏不改动大小边框的状态
5093         ShowSizebox(!theApp.m_ui_data.full_screen);
5094 
5095     SetFullScreen(theApp.m_ui_data.full_screen);
5096 
5097     // 清空按钮区域,防止全屏时自绘标题栏按钮区域仍能响应
5098     auto pCurUi = GetCurrentUi();
5099     if (pCurUi != nullptr)
5100         pCurUi->ClearBtnRect();
5101 
5102     DrawInfo(true);
5103     m_pUI->UpdateFullScreenTip();
5104 }
5105 
5106 
OnCreatePlayShortcut()5107 void CMusicPlayerDlg::OnCreatePlayShortcut()
5108 {
5109     // TODO: 在此添加命令处理程序代码
5110 
5111     const wstring& create_info = theApp.m_str_table.LoadText(L"MSG_SHORTCUT_INQUIRY_PLAY_CONTROL");
5112     if (MessageBox(create_info.c_str(), NULL, MB_ICONQUESTION | MB_OKCANCEL) == IDOK)
5113     {
5114         bool success = true;
5115         wstring lnk_name;
5116         //创建播放/暂停快捷方式
5117         lnk_name = theApp.m_str_table.LoadText(L"UI_TIP_BTN_PLAY_PAUSE") + L".lnk";
5118         CCommon::FileNameNormalize(lnk_name);
5119         success &= CCommon::CreateFileShortcut(theApp.m_module_dir.c_str(), NULL, lnk_name.c_str(), NULL, 0, 0, 1, L"-play_pause", 2);
5120 
5121         //创建上一曲快捷方式
5122         lnk_name = theApp.m_str_table.LoadText(L"UI_TIP_BTN_PREVIOUS") + L".lnk";
5123         CCommon::FileNameNormalize(lnk_name);
5124         success &= CCommon::CreateFileShortcut(theApp.m_module_dir.c_str(), NULL, lnk_name.c_str(), NULL, 0, 0, 1, L"-previous", 1);
5125 
5126         //创建下一曲快捷方式
5127         lnk_name = theApp.m_str_table.LoadText(L"UI_TIP_BTN_NEXT") + L".lnk";
5128         CCommon::FileNameNormalize(lnk_name);
5129         success &= CCommon::CreateFileShortcut(theApp.m_module_dir.c_str(), NULL, lnk_name.c_str(), NULL, 0, 0, 1, L"-next", 3);
5130 
5131         //创建停止快捷方式
5132         lnk_name = theApp.m_str_table.LoadText(L"UI_TIP_BTN_STOP") + L".lnk";
5133         CCommon::FileNameNormalize(lnk_name);
5134         success &= CCommon::CreateFileShortcut(theApp.m_module_dir.c_str(), NULL, lnk_name.c_str(), NULL, 0, 0, 1, L"-stop", 6);
5135 
5136         if (success)
5137         {
5138             wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_SHORTCUT_CREATED", { theApp.m_module_dir });
5139             MessageBox(info.c_str(), NULL, MB_ICONINFORMATION);
5140         }
5141         else
5142         {
5143             const wstring& info = theApp.m_str_table.LoadText(L"MSG_SHORTCUT_FAILED");
5144             MessageBox(info.c_str(), NULL, MB_ICONWARNING);
5145         }
5146     }
5147 }
5148 
5149 
OnListenStatistics()5150 void CMusicPlayerDlg::OnListenStatistics()
5151 {
5152     // TODO: 在此添加命令处理程序代码
5153     CListenTimeStatisticsDlg dlg;
5154     dlg.DoModal();
5155 }
5156 
5157 
OnDarkMode()5158 void CMusicPlayerDlg::OnDarkMode()
5159 {
5160     // TODO: 在此添加命令处理程序代码
5161     theApp.m_app_setting_data.dark_mode = !theApp.m_app_setting_data.dark_mode;
5162     if (theApp.m_app_setting_data.dark_mode)
5163         theApp.m_app_setting_data.background_transparency = theApp.m_nc_setting_data.dark_mode_default_transparency;
5164     else
5165         theApp.m_app_setting_data.background_transparency = theApp.m_nc_setting_data.light_mode_default_transparency;
5166     SaveConfig();
5167     auto ui{ GetCurrentUi() };
5168     if (ui != nullptr)
5169         ui->UpdateDarkLightModeBtnToolTip();
5170 }
5171 
5172 
OnMainMenuPopup(WPARAM wParam,LPARAM lParam)5173 afx_msg LRESULT CMusicPlayerDlg::OnMainMenuPopup(WPARAM wParam, LPARAM lParam)
5174 {
5175     CPoint point = *((CPoint*)wParam);
5176     ClientToScreen(&point);
5177     theApp.m_menu_mgr.GetMenu(MenuMgr::MainPopupMenu)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this);
5178 
5179     return 0;
5180 }
5181 
5182 
5183 
OnAlwaysOnTop()5184 void CMusicPlayerDlg::OnAlwaysOnTop()
5185 {
5186     // TODO: 在此添加命令处理程序代码
5187     theApp.m_nc_setting_data.always_on_top = !theApp.m_nc_setting_data.always_on_top;
5188     SetAlwaysOnTop();
5189 }
5190 
5191 
OnFloatPlaylist()5192 void CMusicPlayerDlg::OnFloatPlaylist()
5193 {
5194     // TODO: 在此添加命令处理程序代码
5195     //theApp.m_media_lib_setting_data.playlist_btn_for_float_playlist = !theApp.m_media_lib_setting_data.playlist_btn_for_float_playlist;
5196     //if (theApp.m_media_lib_setting_data.playlist_btn_for_float_playlist)
5197     //{
5198     //    //改为浮动播放列表时,如果显示了停靠的播放列表,则显示浮动播放列表,隐藏停靠播放列表
5199     //    if (theApp.m_ui_data.show_playlist)
5200     //    {
5201     //        ShowFloatPlaylist();
5202     //    }
5203     //}
5204     //else
5205     //{
5206     //    //改为停靠的播放列表时,如果显示了浮动的播放列表,则显示停靠的播放列表
5207     //    if (theApp.m_nc_setting_data.float_playlist)
5208     //    {
5209     //        ShowHidePlaylist();
5210     //    }
5211     //}
5212     ShowHideFloatPlaylist();
5213 }
5214 
5215 
OnDockedPlaylist()5216 void CMusicPlayerDlg::OnDockedPlaylist()
5217 {
5218     // TODO: 在此添加命令处理程序代码
5219     theApp.m_media_lib_setting_data.playlist_btn_for_float_playlist = false;
5220     auto ui{ GetCurrentUi() };
5221     if (ui != nullptr)
5222         ui->UpdatePlaylistBtnToolTip();
5223 }
5224 
5225 
OnFloatedPlaylist()5226 void CMusicPlayerDlg::OnFloatedPlaylist()
5227 {
5228     // TODO: 在此添加命令处理程序代码
5229     theApp.m_media_lib_setting_data.playlist_btn_for_float_playlist = true;
5230     auto ui{ GetCurrentUi() };
5231     if (ui != nullptr)
5232         ui->UpdatePlaylistBtnToolTip();
5233 }
5234 
OnFloatPlaylistClosed(WPARAM wParam,LPARAM lParam)5235 LRESULT CMusicPlayerDlg::OnFloatPlaylistClosed(WPARAM wParam, LPARAM lParam)
5236 {
5237     CRect rect;
5238     if (IsFloatPlaylistExist())
5239     {
5240         ::GetWindowRect(m_pFloatPlaylistDlg->GetSafeHwnd(), rect);
5241         if (!m_pFloatPlaylistDlg->IsIconic() && !m_pFloatPlaylistDlg->IsZoomed())
5242             m_float_playlist_pos = rect.TopLeft();
5243     }
5244 
5245     return 0;
5246 }
5247 
5248 
OnPlaylistAddFile()5249 void CMusicPlayerDlg::OnPlaylistAddFile()
5250 {
5251     // TODO: 在此添加命令处理程序代码
5252 
5253     if (!CPlayer::GetInstance().IsPlaylistMode())
5254         return;
5255 
5256     vector<wstring> files;
5257     wstring filter = FilterHelper::GetAudioFileFilter();
5258     CCommon::DoOpenFileDlg(filter, files, this);
5259     if (!files.empty())
5260     {
5261         int rtn = CPlayer::GetInstance().AddFilesToPlaylist(files);
5262         if (rtn == 0)
5263         {
5264             const wstring& info = theApp.m_str_table.LoadText(L"MSG_FILE_EXIST_IN_PLAYLIST");
5265             MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK);
5266         }
5267         else if (rtn == -1)
5268         {
5269             const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY");
5270             MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK);
5271         }
5272     }
5273 }
5274 
5275 
OnRemoveFromPlaylist()5276 void CMusicPlayerDlg::OnRemoveFromPlaylist()
5277 {
5278     // TODO: 在此添加命令处理程序代码
5279     CMusicPlayerCmdHelper helper(this);
5280     if (helper.OnRemoveFromCurrentPlaylist(m_items_selected))
5281         ShowPlayList(false);
5282 }
5283 
5284 
OnEmptyPlaylist()5285 void CMusicPlayerDlg::OnEmptyPlaylist()
5286 {
5287     // TODO: 在此添加命令处理程序代码
5288     const wstring& info = theApp.m_str_table.LoadText(L"MSG_PLAYLIST_CLEAR_WARNING");
5289     if (MessageBox(info.c_str(), NULL, MB_ICONQUESTION | MB_OKCANCEL) == IDOK)
5290     {
5291         CPlayer::GetInstance().ClearPlaylist();
5292         ShowPlayList();
5293     }
5294 }
5295 
5296 
OnMovePlaylistItemUp()5297 void CMusicPlayerDlg::OnMovePlaylistItemUp()
5298 {
5299     // TODO: 在此添加命令处理程序代码
5300     if (m_items_selected.empty())
5301         return;
5302 
5303     bool move_enable = CPlayer::GetInstance().IsPlaylistMode() && !m_searched;
5304     if (!move_enable)
5305         return;
5306 
5307     int first = m_items_selected.front();
5308     int last = m_items_selected.back();
5309     if (CPlayer::GetInstance().MoveUp(first, last))
5310     {
5311         ShowPlayList(false);
5312         if (m_pFloatPlaylistDlg->GetSafeHwnd() == NULL)
5313         {
5314             m_playlist_list.SetCurSel(first - 1, last - 1);
5315             GetPlaylistItemSelected();
5316         }
5317         else
5318         {
5319             m_pFloatPlaylistDlg->GetListCtrl().SetCurSel(first - 1, last - 1);
5320             m_pFloatPlaylistDlg->GetPlaylistItemSelected();
5321         }
5322         SetUiPlaylistSelected(first - 1);
5323     }
5324 }
5325 
5326 
OnMovePlaylistItemDown()5327 void CMusicPlayerDlg::OnMovePlaylistItemDown()
5328 {
5329     // TODO: 在此添加命令处理程序代码
5330     if (m_items_selected.empty())
5331         return;
5332 
5333     bool move_enable = CPlayer::GetInstance().IsPlaylistMode() && !m_searched;
5334     if (!move_enable)
5335         return;
5336 
5337     int first = m_items_selected.front();
5338     int last = m_items_selected.back();
5339     if (CPlayer::GetInstance().MoveDown(first, last))
5340     {
5341         ShowPlayList(false);
5342         if (m_pFloatPlaylistDlg->GetSafeHwnd() == NULL)
5343         {
5344             m_playlist_list.SetCurSel(first + 1, last + 1);
5345             GetPlaylistItemSelected();
5346         }
5347         else
5348         {
5349             m_pFloatPlaylistDlg->GetListCtrl().SetCurSel(first + 1, last + 1);
5350             m_pFloatPlaylistDlg->GetPlaylistItemSelected();
5351         }
5352         SetUiPlaylistSelected(first + 1);
5353     }
5354 }
5355 
5356 
OnNMClickPlaylistList(NMHDR * pNMHDR,LRESULT * pResult)5357 void CMusicPlayerDlg::OnNMClickPlaylistList(NMHDR* pNMHDR, LRESULT* pResult)
5358 {
5359     LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
5360     SetUiPlaylistSelected(pNMItemActivate->iItem);
5361     GetPlaylistItemSelected(pNMItemActivate->iItem);
5362     *pResult = 0;
5363 }
5364 
5365 
OnRemoveSameSongs()5366 void CMusicPlayerDlg::OnRemoveSameSongs()
5367 {
5368     // TODO: 在此添加命令处理程序代码
5369     int removed = CPlayer::GetInstance().RemoveSameSongs();
5370     if (removed > 0)
5371     {
5372         ShowPlayList();
5373     }
5374     wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_PLAYLIST_REMOVE_SONGS", { removed });
5375     MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK);
5376 }
5377 
5378 
OnAddToNewPlaylist()5379 void CMusicPlayerDlg::OnAddToNewPlaylist()
5380 {
5381     // TODO: 在此添加命令处理程序代码
5382     auto getSongList = [&](std::vector<SongInfo>& song_list)
5383         {
5384             if (IsMainWindowPopupMenu())      //如果当前命令是从主界面右键菜单中弹出来的,则是添加正在播放的曲目到播放列表
5385             {
5386                 song_list.push_back(CPlayer::GetInstance().GetCurrentSongInfo());
5387             }
5388             else        //否则是添加选中的曲目到播放列表
5389             {
5390                 for (auto i : m_items_selected)
5391                 {
5392                     if (i >= 0 && i < CPlayer::GetInstance().GetSongNum())
5393                     {
5394                         song_list.push_back(CPlayer::GetInstance().GetPlayList()[i]);
5395                     }
5396                 }
5397             }
5398         };
5399     CMusicPlayerCmdHelper cmd_helper(this);
5400     std::wstring playlist_path;
5401     if (cmd_helper.OnAddToNewPlaylist(getSongList, playlist_path))
5402         m_pCurMenu = nullptr;
5403 }
5404 
5405 
OnToolFileRelate()5406 void CMusicPlayerDlg::OnToolFileRelate()
5407 {
5408     // TODO: 在此添加命令处理程序代码
5409     CFileRelateDlg dlg;
5410     dlg.DoModal();
5411 }
5412 
5413 
OnPlaylistAddFolder()5414 void CMusicPlayerDlg::OnPlaylistAddFolder()
5415 {
5416     // TODO: 在此添加命令处理程序代码
5417 
5418     if (!CPlayer::GetInstance().IsPlaylistMode())
5419         return;
5420 
5421     static bool include_sub_dir{ false };
5422     static CString include_sub_dir_str{ theApp.m_str_table.LoadText(L"TXT_FOLDER_BROWSER_INCLUDE_SUB_DIR").c_str() };
5423     const wstring& title = theApp.m_str_table.LoadText(L"TITLE_FOLDER_BROWSER_SONG_SOURCE");
5424 #ifdef COMPILE_IN_WIN_XP
5425     CFolderBrowserDlg folderPickerDlg(this->GetSafeHwnd());
5426     folderPickerDlg.SetInfo(title.c_str());
5427 #else
5428     CFilePathHelper current_path(CPlayer::GetInstance().GetCurrentDir());
5429     CFolderPickerDialog folderPickerDlg(current_path.GetParentDir().c_str());
5430     folderPickerDlg.m_ofn.lpstrTitle = title.c_str();
5431     folderPickerDlg.AddCheckButton(IDC_OPEN_CHECKBOX, include_sub_dir_str, include_sub_dir);     //在打开对话框中添加一个复选框
5432 #endif
5433     if (folderPickerDlg.DoModal() == IDOK)
5434     {
5435 #ifndef COMPILE_IN_WIN_XP
5436         BOOL checked;
5437         folderPickerDlg.GetCheckButtonState(IDC_OPEN_CHECKBOX, checked);
5438         include_sub_dir = (checked != FALSE);
5439 #endif
5440         std::vector<wstring> file_list;
5441         CAudioCommon::GetAudioFiles(wstring(folderPickerDlg.GetPathName()), file_list, MAX_SONG_NUM, include_sub_dir);
5442         int rtn = CPlayer::GetInstance().AddFilesToPlaylist(file_list);
5443         if (rtn == 0)
5444         {
5445             const wstring& info = theApp.m_str_table.LoadText(L"MSG_FILE_EXIST_IN_PLAYLIST");
5446             MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK);
5447         }
5448         else if (rtn == -1)
5449         {
5450             const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY");
5451             MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK);
5452         }
5453 
5454     }
5455 }
5456 
5457 
OnRemoveInvalidItems()5458 void CMusicPlayerDlg::OnRemoveInvalidItems()
5459 {
5460     // TODO: 在此添加命令处理程序代码
5461     int removed = CPlayer::GetInstance().RemoveInvalidSongs();
5462     if (removed > 0)
5463     {
5464         ShowPlayList();
5465     }
5466     wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_PLAYLIST_REMOVE_SONGS", { removed });
5467     MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK);
5468 }
5469 
5470 
OnListItemDragged(WPARAM wParam,LPARAM lParam)5471 afx_msg LRESULT CMusicPlayerDlg::OnListItemDragged(WPARAM wParam, LPARAM lParam)
5472 {
5473     if (!CPlayer::GetInstance().IsPlaylistMode())
5474         return 0;
5475 
5476     CWaitCursor wait_cursor;
5477     int drop_index = static_cast<int>(wParam);
5478     std::vector<int> drag_items;
5479     if (m_pFloatPlaylistDlg->GetSafeHwnd() == NULL)
5480         m_playlist_list.GetItemSelected(drag_items);
5481     else
5482         m_pFloatPlaylistDlg->GetListCtrl().GetItemSelected(drag_items);
5483 
5484     if (m_miniModeDlg.GetSafeHwnd() != NULL)
5485         m_miniModeDlg.GetPlaylistCtrl().GetItemSelected(drag_items);
5486 
5487     int index = CPlayer::GetInstance().MoveItems(drag_items, drop_index);
5488     ShowPlayList(false);
5489 
5490     //移动后设置当前选中行
5491     if (m_pFloatPlaylistDlg->GetSafeHwnd() == NULL)
5492     {
5493         m_playlist_list.SetCurSel(index, index + drag_items.size() - 1);
5494         GetPlaylistItemSelected();
5495     }
5496     else
5497     {
5498         m_pFloatPlaylistDlg->GetListCtrl().SetCurSel(index, index + drag_items.size() - 1);
5499         m_pFloatPlaylistDlg->GetPlaylistItemSelected();
5500     }
5501 
5502     if (m_miniModeDlg.GetSafeHwnd() != NULL)
5503         m_miniModeDlg.GetPlaylistCtrl().SetCurSel(index, index + drag_items.size() - 1);
5504 
5505     return 0;
5506 }
5507 
5508 
OnAddRemoveFromFavourite()5509 void CMusicPlayerDlg::OnAddRemoveFromFavourite()
5510 {
5511     // TODO: 在此添加命令处理程序代码
5512     CMusicPlayerCmdHelper helper(this);
5513     helper.OnAddRemoveFromFavourite(CPlayer::GetInstance().GetIndex());
5514 }
5515 
5516 
OnFileOpenUrl()5517 void CMusicPlayerDlg::OnFileOpenUrl()
5518 {
5519     // TODO: 在此添加命令处理程序代码
5520     CInputDlg input_dlg;
5521     input_dlg.SetTitle(theApp.m_str_table.LoadText(L"TITLE_INPUT_URL_OPEN_URL").c_str());
5522     input_dlg.SetInfoText(theApp.m_str_table.LoadText(L"TXT_INPUT_URL_INPUT_URL").c_str());
5523     if (input_dlg.DoModal() == IDOK)
5524     {
5525         wstring strUrl = input_dlg.GetEditText().GetString();
5526         //如果输入的是文件夹,则在文件夹模式中打开
5527         if (CCommon::FolderExist(strUrl))
5528         {
5529             if (!CPlayer::GetInstance().OpenFolder(strUrl))
5530             {
5531                 const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY");
5532                 MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK);
5533             }
5534             return;
5535         }
5536         else if (!CCommon::FileExist(strUrl) && !CCommon::IsURL(strUrl))
5537         {
5538             const wstring& info = theApp.m_str_table.LoadText(L"MSG_INPUT_URL_INVALID_WARNING");
5539             MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK);
5540             return;
5541         }
5542         //本地文件或URL将被添加到默认的播放列表播放
5543         vector<wstring> vecUrl;
5544         vecUrl.push_back(strUrl);
5545         if (!CPlayer::GetInstance().OpenFilesInDefaultPlaylist(vecUrl))
5546         {
5547             const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY");
5548             MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK);
5549         }
5550     }
5551 }
5552 
5553 
OnPlaylistAddUrl()5554 void CMusicPlayerDlg::OnPlaylistAddUrl()
5555 {
5556     // TODO: 在此添加命令处理程序代码
5557     if (!CPlayer::GetInstance().IsPlaylistMode())
5558         return;
5559 
5560     CInputDlg input_dlg;
5561     input_dlg.SetTitle(theApp.m_str_table.LoadText(L"TITLE_INPUT_URL_ADD_URL").c_str());
5562     input_dlg.SetInfoText(theApp.m_str_table.LoadText(L"TXT_INPUT_URL_INPUT_URL").c_str());
5563     if (input_dlg.DoModal() == IDOK)
5564     {
5565         wstring strUrl = input_dlg.GetEditText().GetString();
5566         vector<wstring> vecUrl;
5567         //如果输入的是文件夹路径,则将文件夹内的音频文件添加到播放列表
5568         if (CCommon::FolderExist(strUrl))
5569         {
5570             CAudioCommon::GetAudioFiles(strUrl, vecUrl);
5571         }
5572         else
5573         {
5574             if (!CCommon::FileExist(strUrl) && !CCommon::IsURL(strUrl))
5575             {
5576                 const wstring& info = theApp.m_str_table.LoadText(L"MSG_INPUT_URL_INVALID_WARNING");
5577                 MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK);
5578                 return;
5579             }
5580             vecUrl.push_back(strUrl);
5581         }
5582         int rtn = CPlayer::GetInstance().AddFilesToPlaylist(vecUrl);
5583         if (rtn == 0)
5584         {
5585             const wstring& info = theApp.m_str_table.LoadText(L"MSG_FILE_EXIST_IN_PLAYLIST");
5586             MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK);
5587         }
5588         else if (rtn == -1)
5589         {
5590             const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY");
5591             MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK);
5592         }
5593     }
5594 }
5595 
5596 
OnSetMenuState(WPARAM wParam,LPARAM lParam)5597 afx_msg LRESULT CMusicPlayerDlg::OnSetMenuState(WPARAM wParam, LPARAM lParam)
5598 {
5599     CMenu* pMenu = (CMenu*)wParam;
5600     if (pMenu != nullptr)
5601         SetMenuState(pMenu);
5602     return 0;
5603 }
5604 
5605 
OnLockDesktopLryic()5606 void CMusicPlayerDlg::OnLockDesktopLryic()
5607 {
5608     // TODO: 在此添加命令处理程序代码
5609     theApp.m_lyric_setting_data.desktop_lyric_data.lock_desktop_lyric = !theApp.m_lyric_setting_data.desktop_lyric_data.lock_desktop_lyric;
5610     m_desktop_lyric.SetLyricWindowLock(theApp.m_lyric_setting_data.desktop_lyric_data.lock_desktop_lyric);
5611     wstring tip_str;
5612     if (theApp.m_lyric_setting_data.desktop_lyric_data.lock_desktop_lyric)
5613         tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_DESKTOP_LYRIC_UNLOCK");
5614     else
5615         tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_DESKTOP_LYRIC_LOCK");
5616     m_desktop_lyric.UpdateMouseToolTip(CDesktopLyric::BTN_LOCK, tip_str.c_str());
5617 }
5618 
5619 
OnCloseDesktopLyric()5620 void CMusicPlayerDlg::OnCloseDesktopLyric()
5621 {
5622     // TODO: 在此添加命令处理程序代码
5623     theApp.m_lyric_setting_data.show_desktop_lyric = false;
5624 }
5625 
5626 
OnLyricDisplayedDoubleLine()5627 void CMusicPlayerDlg::OnLyricDisplayedDoubleLine()
5628 {
5629     // TODO: 在此添加命令处理程序代码
5630     theApp.m_lyric_setting_data.desktop_lyric_data.lyric_double_line = !theApp.m_lyric_setting_data.desktop_lyric_data.lyric_double_line;
5631 }
5632 
5633 
OnLyricBackgroundPenetrate()5634 void CMusicPlayerDlg::OnLyricBackgroundPenetrate()
5635 {
5636     // TODO: 在此添加命令处理程序代码
5637     theApp.m_lyric_setting_data.desktop_lyric_data.lyric_background_penetrate = !theApp.m_lyric_setting_data.desktop_lyric_data.lyric_background_penetrate;
5638     m_desktop_lyric.SetLyricBackgroundPenetrate(theApp.m_lyric_setting_data.desktop_lyric_data.lyric_background_penetrate);
5639 }
5640 
5641 
OnPlaylistSelectChange()5642 void CMusicPlayerDlg::OnPlaylistSelectChange()
5643 {
5644     // TODO: 在此添加命令处理程序代码
5645     GetPlaylistItemSelected();
5646 }
5647 
5648 
OnPlaylistSelectAll()5649 void CMusicPlayerDlg::OnPlaylistSelectAll()
5650 {
5651     // TODO: 在此添加命令处理程序代码
5652     m_playlist_list.SelectAll();
5653     GetPlaylistItemSelected();
5654 
5655     CUserUi* user_ui{ dynamic_cast<CUserUi*>(GetCurrentUi()) };
5656     if (user_ui != nullptr)
5657     {
5658         user_ui->IterateAllElements<UiElement::ListElement>([](UiElement::ListElement* list_element) ->bool {
5659             list_element->SelectAll();
5660             return false;
5661         }, true);
5662     }
5663 }
5664 
5665 
OnPlaylistSelectNone()5666 void CMusicPlayerDlg::OnPlaylistSelectNone()
5667 {
5668     // TODO: 在此添加命令处理程序代码
5669     m_playlist_list.SelectNone();
5670     GetPlaylistItemSelected();
5671 
5672     CUserUi* user_ui{ dynamic_cast<CUserUi*>(GetCurrentUi()) };
5673     if (user_ui != nullptr)
5674     {
5675         user_ui->IterateAllElements<UiElement::ListElement>([](UiElement::ListElement* list_element) ->bool {
5676             list_element->SelectNone();
5677             return false;
5678         }, true);
5679     }
5680 }
5681 
5682 
OnPlaylistSelectRevert()5683 void CMusicPlayerDlg::OnPlaylistSelectRevert()
5684 {
5685     // TODO: 在此添加命令处理程序代码
5686     m_playlist_list.SelectReverse();
5687     GetPlaylistItemSelected();
5688 
5689     CUserUi* user_ui{ dynamic_cast<CUserUi*>(GetCurrentUi()) };
5690     if (user_ui != nullptr)
5691     {
5692         user_ui->IterateAllElements<UiElement::ListElement>([](UiElement::ListElement* list_element) ->bool {
5693             list_element->SelectReversed();
5694             return false;
5695         }, true);
5696     }
5697 }
5698 
5699 
OnCurPlaylistRenamed(WPARAM wParam,LPARAM lParam)5700 afx_msg LRESULT CMusicPlayerDlg::OnCurPlaylistRenamed(WPARAM wParam, LPARAM lParam)
5701 {
5702     m_current_cache.reload();
5703     m_path_edit.SetWindowTextW(m_current_cache.at(0).GetDisplayName().c_str());
5704     // 这里忘了浮动播放列表
5705     return 0;
5706 }
5707 
5708 
OnOnlineHelp()5709 void CMusicPlayerDlg::OnOnlineHelp()
5710 {
5711     // TODO: 在此添加命令处理程序代码
5712     ShellExecute(NULL, _T("open"), _T("https://github.com/zhongyang219/MusicPlayer2/wiki"), NULL, NULL, SW_SHOW);   //打开超链接
5713 }
5714 
5715 
OnSpeedUp()5716 void CMusicPlayerDlg::OnSpeedUp()
5717 {
5718     // TODO: 在此添加命令处理程序代码
5719     if (!CPlayer::GetInstance().IsError() && !CPlayer::GetInstance().IsPlaylistEmpty())
5720         CPlayer::GetInstance().SpeedUp();
5721 }
5722 
5723 
OnSlowDown()5724 void CMusicPlayerDlg::OnSlowDown()
5725 {
5726     // TODO: 在此添加命令处理程序代码
5727     if (!CPlayer::GetInstance().IsError() && !CPlayer::GetInstance().IsPlaylistEmpty())
5728         CPlayer::GetInstance().SlowDown();
5729 }
5730 
5731 
OnOriginalSpeed()5732 void CMusicPlayerDlg::OnOriginalSpeed()
5733 {
5734     // TODO: 在此添加命令处理程序代码
5735     if (!CPlayer::GetInstance().IsError() && !CPlayer::GetInstance().IsPlaylistEmpty())
5736         CPlayer::GetInstance().SetOrignalSpeed();
5737 }
5738 
OnPitchUp()5739 void CMusicPlayerDlg::OnPitchUp()
5740 {
5741     if (!CPlayer::GetInstance().IsError() && !CPlayer::GetInstance().IsPlaylistEmpty())
5742         CPlayer::GetInstance().PitchUp();
5743 }
5744 
5745 
OnPitchDown()5746 void CMusicPlayerDlg::OnPitchDown()
5747 {
5748     if (!CPlayer::GetInstance().IsError() && !CPlayer::GetInstance().IsPlaylistEmpty())
5749         CPlayer::GetInstance().PitchDown();
5750 }
5751 
5752 
OnOriginalPitch()5753 void CMusicPlayerDlg::OnOriginalPitch()
5754 {
5755     if (!CPlayer::GetInstance().IsError() && !CPlayer::GetInstance().IsPlaylistEmpty())
5756         CPlayer::GetInstance().SetOrignalPitch();
5757 }
5758 
5759 
OnSearchEditBtnClicked(WPARAM wParam,LPARAM lParam)5760 afx_msg LRESULT CMusicPlayerDlg::OnSearchEditBtnClicked(WPARAM wParam, LPARAM lParam)
5761 {
5762     if (m_searched)
5763     {
5764         //清除搜索结果
5765         m_searched = false;
5766         m_search_edit.SetWindowText(_T(""));
5767         m_playlist_list.ShowPlaylist(theApp.m_media_lib_setting_data.display_format, m_searched);
5768         m_playlist_list.EnsureVisible(CPlayer::GetInstance().GetIndex(), FALSE);        //清除搜索结果后确保正在播放曲目可见
5769     }
5770     return 0;
5771 }
5772 
5773 
OnInitAddToMenu(WPARAM wParam,LPARAM lParam)5774 afx_msg LRESULT CMusicPlayerDlg::OnInitAddToMenu(WPARAM wParam, LPARAM lParam)
5775 {
5776     IniPlaylistPopupMenu();
5777     return 0;
5778 }
5779 
5780 
OnMsgOptionSettings(WPARAM wParam,LPARAM lParam)5781 afx_msg LRESULT CMusicPlayerDlg::OnMsgOptionSettings(WPARAM wParam, LPARAM lParam)
5782 {
5783     m_tab_selected = wParam;
5784     _OnOptionSettings((CWnd*)lParam);
5785     return 0;
5786 }
5787 
5788 
OnAlwaysShowStatusBar()5789 void CMusicPlayerDlg::OnAlwaysShowStatusBar()
5790 {
5791     // TODO: 在此添加命令处理程序代码
5792     theApp.m_app_setting_data.always_show_statusbar = !theApp.m_app_setting_data.always_show_statusbar;
5793     DrawInfo(true);
5794 }
5795 
5796 
OnShowMainWindow()5797 void CMusicPlayerDlg::OnShowMainWindow()
5798 {
5799     // TODO: 在此添加命令处理程序代码
5800     if (m_miniModeDlg.m_hWnd != NULL)       //如果是迷你模式,则退出迷你模式
5801         ::SendMessage(m_miniModeDlg.m_hWnd, WM_COMMAND, IDOK, NULL);
5802 
5803     ShowWindow(SW_SHOWNORMAL);  //激活并显示窗口
5804     SetForegroundWindow();      //将窗口设置为焦点
5805 
5806 }
5807 
5808 
OnRecentPlayedListCleared(WPARAM wParam,LPARAM lParam)5809 afx_msg LRESULT CMusicPlayerDlg::OnRecentPlayedListCleared(WPARAM wParam, LPARAM lParam)
5810 {
5811     if (m_pMediaLibDlg != nullptr && IsWindow(m_pMediaLibDlg->m_hWnd))
5812     {
5813         CWaitCursor wait_cursor;
5814         m_pMediaLibDlg->m_recent_media_dlg->RefreshData();
5815     }
5816 
5817     return 0;
5818 }
5819 
5820 
OnAbRepeat()5821 void CMusicPlayerDlg::OnAbRepeat()
5822 {
5823     // TODO: 在此添加命令处理程序代码
5824     if (!CPlayer::GetInstance().IsError() && !CPlayer::GetInstance().IsPlaylistEmpty())
5825     {
5826         CPlayer::GetInstance().DoABRepeat();
5827         UpdateABRepeatToolTip();
5828     }
5829 }
5830 
5831 
OnSetAPoint()5832 void CMusicPlayerDlg::OnSetAPoint()
5833 {
5834     // TODO: 在此添加命令处理程序代码
5835     if (!CPlayer::GetInstance().IsError() && !CPlayer::GetInstance().IsPlaylistEmpty())
5836     {
5837         CPlayer::GetInstance().SetARepeatPoint();
5838         UpdateABRepeatToolTip();
5839     }
5840 }
5841 
5842 
OnSetBPoint()5843 void CMusicPlayerDlg::OnSetBPoint()
5844 {
5845     // TODO: 在此添加命令处理程序代码
5846     if (!CPlayer::GetInstance().IsError() && !CPlayer::GetInstance().IsPlaylistEmpty())
5847     {
5848         CPlayer::GetInstance().SetBRepeatPoint();
5849         UpdateABRepeatToolTip();
5850     }
5851 }
5852 
5853 
OnResetAbRepeat()5854 void CMusicPlayerDlg::OnResetAbRepeat()
5855 {
5856     // TODO: 在此添加命令处理程序代码
5857     if (!CPlayer::GetInstance().IsError() && !CPlayer::GetInstance().IsPlaylistEmpty())
5858     {
5859         CPlayer::GetInstance().ResetABRepeat();
5860         UpdateABRepeatToolTip();
5861     }
5862 }
5863 
5864 
OnNextAbRepeat()5865 void CMusicPlayerDlg::OnNextAbRepeat()
5866 {
5867     // TODO: 在此添加命令处理程序代码
5868     if (!CPlayer::GetInstance().IsError() && !CPlayer::GetInstance().IsPlaylistEmpty())
5869     {
5870         CPlayer::GetInstance().ContinueABRepeat();
5871         UpdateABRepeatToolTip();
5872     }
5873 }
5874 
5875 
OnSaveCurrentPlaylistAs()5876 void CMusicPlayerDlg::OnSaveCurrentPlaylistAs()
5877 {
5878     // TODO: 在此添加命令处理程序代码
5879     wstring playlist_name = m_current_cache.at(0).GetDisplayName();
5880     if (m_current_cache.at(0).type == LT_FOLDER)
5881     {
5882         playlist_name = CFilePathHelper(playlist_name).GetFolderName();
5883     }
5884     wstring filter = FilterHelper::GetPlaylistSaveAsFilter();
5885     CFileDialog fileDlg(FALSE, _T("m3u"), playlist_name.c_str(), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, filter.c_str(), this);
5886     if (IDOK == fileDlg.DoModal())
5887     {
5888         //将当前播放列表保存到文件
5889         wstring file_path{ fileDlg.GetPathName() };
5890         wstring file_extension{ fileDlg.GetFileExt() };
5891         file_extension = L'.' + file_extension;
5892         CPlaylistFile::Type file_type{};
5893         if (file_extension == PLAYLIST_EXTENSION)
5894             file_type = CPlaylistFile::PL_PLAYLIST;
5895         else if (file_extension == L".m3u")
5896             file_type = CPlaylistFile::PL_M3U;
5897         else if (file_extension == L".m3u8")
5898             file_type = CPlaylistFile::PL_M3U8;
5899         CPlaylistFile::SavePlaylistToFile(CPlayer::GetInstance().GetPlayList(), file_path, file_type);
5900     }
5901 
5902 }
5903 
5904 
OnFileOpenPlaylist()5905 void CMusicPlayerDlg::OnFileOpenPlaylist()
5906 {
5907     // TODO: 在此添加命令处理程序代码
5908     //设置过滤器
5909     wstring filter = FilterHelper::GetPlaylistSelectFilter();
5910     //构造打开文件对话框
5911     CFileDialog fileDlg(TRUE, NULL, NULL, 0, filter.c_str(), this);
5912     //显示打开文件对话框
5913     if (IDOK == fileDlg.DoModal())
5914     {
5915         wstring file_path{ fileDlg.GetPathName() };
5916         if (!CPlayer::GetInstance().OpenPlaylistFile(file_path))
5917         {
5918             const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY");
5919             MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK);
5920         }
5921     }
5922 
5923 }
5924 
5925 
OnSaveAsNewPlaylist()5926 void CMusicPlayerDlg::OnSaveAsNewPlaylist()
5927 {
5928     // TODO: 在此添加命令处理程序代码
5929     auto getSongList = [&](std::vector<SongInfo>& song_list)
5930         {
5931             for (const auto& item : CPlayer::GetInstance().GetPlayList())
5932                 song_list.push_back(item);
5933         };
5934     wstring playlist_path;
5935     CMusicPlayerCmdHelper cmd_helper(this);
5936     cmd_helper.OnAddToNewPlaylist(getSongList, playlist_path);
5937 }
5938 
5939 
OnCreateDesktopShortcut()5940 void CMusicPlayerDlg::OnCreateDesktopShortcut()
5941 {
5942     const wstring& create_info = theApp.m_str_table.LoadText(L"MSG_SHORTCUT_INQUIRY_DESKTOP");
5943     if (MessageBox(create_info.c_str(), NULL, MB_ICONQUESTION | MB_YESNO) == IDYES)
5944     {
5945         if (CCommon::CreateFileShortcut(theApp.m_desktop_path.c_str(), NULL, _T("MusicPlayer2.lnk")))
5946         {
5947             wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_SHORTCUT_CREATED", { theApp.m_desktop_path });
5948             MessageBox(info.c_str(), NULL, MB_ICONINFORMATION);
5949         }
5950         else
5951         {
5952             const wstring& info = theApp.m_str_table.LoadText(L"MSG_SHORTCUT_FAILED");
5953             MessageBox(info.c_str(), NULL, MB_ICONWARNING);
5954         }
5955     }
5956 }
5957 
5958 
OnCreateMiniModeShortCut()5959 void CMusicPlayerDlg::OnCreateMiniModeShortCut()
5960 {
5961     const wstring& create_info = theApp.m_str_table.LoadText(L"MSG_SHORTCUT_INQUIRY_MINIMODE");
5962     if (MessageBox(create_info.c_str(), NULL, MB_ICONQUESTION | MB_YESNO) == IDYES)
5963     {
5964         wstring file_name = theApp.m_str_table.LoadText(L"UI_TIP_BTN_MINIMODE") + L".lnk";
5965         CCommon::FileNameNormalize(file_name);
5966         if (CCommon::CreateFileShortcut(theApp.m_module_dir.c_str(), NULL, file_name.c_str(), NULL, 0, 0, 1, L"-mini"))
5967         {
5968             wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_SHORTCUT_CREATED", { theApp.m_module_dir });
5969             MessageBox(info.c_str(), NULL, MB_ICONINFORMATION);
5970         }
5971         else
5972         {
5973             const wstring& info = theApp.m_str_table.LoadText(L"MSG_SHORTCUT_FAILED");
5974             MessageBox(info.c_str(), NULL, MB_ICONWARNING);
5975         }
5976     }
5977 }
5978 
5979 
OnRemoveCurrentFromPlaylist()5980 void CMusicPlayerDlg::OnRemoveCurrentFromPlaylist()
5981 {
5982     // TODO: 在此添加命令处理程序代码
5983     if (CPlayer::GetInstance().IsPlaylistMode())
5984     {
5985         const SongInfo& song = CPlayer::GetInstance().GetCurrentSongInfo();
5986         std::wstring song_display_name = CSongInfoHelper::GetDisplayStr(song, theApp.m_media_lib_setting_data.display_format);
5987         std::wstring playlist_name = m_current_cache.at(0).GetDisplayName();
5988         std::wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_REMOVE_SINGLE_ITEM_FROM_PLAYLIST_INQUIRY", { playlist_name, song_display_name });
5989         if (MessageBox(info.c_str(), NULL, MB_ICONQUESTION | MB_YESNO) == IDYES)
5990         {
5991             CPlayer::GetInstance().RemoveSong(CPlayer::GetInstance().GetIndex());
5992             ShowPlayList(false);
5993         }
5994     }
5995 }
5996 
5997 
OnDeleteCurrentFromDisk()5998 void CMusicPlayerDlg::OnDeleteCurrentFromDisk()
5999 {
6000     // TODO: 在此添加命令处理程序代码
6001     if (theApp.m_media_lib_setting_data.disable_delete_from_disk) return;
6002 
6003     SongInfo song = CPlayer::GetInstance().GetCurrentSongInfo();
6004     wstring file_path = song.file_path;
6005     if (file_path.empty() || song.is_cue || COSUPlayerHelper::IsOsuFile(file_path))
6006         return;
6007     wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_DELETE_SINGLE_FILE_INQUIRY", { file_path });
6008     if (MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OKCANCEL) != IDOK)
6009         return;
6010     if (!CPlayer::GetInstance().GetPlayStatusMutex().try_lock_for(std::chrono::milliseconds(1000))) return;
6011     bool file_exist = CCommon::FileExist(file_path);
6012     int rtn{};
6013     if (file_exist)
6014     {
6015         CPlayer::GetInstance().MusicControl(Command::CLOSE);
6016         rtn = CommonDialogMgr::DeleteAFile(m_hWnd, file_path);
6017     }
6018     if (rtn == ERROR_SUCCESS || !file_exist)
6019     {
6020         //如果文件删除成功,同时从播放列表中移除
6021         CPlayer::GetInstance().RemoveSong(CPlayer::GetInstance().GetIndex(), true);
6022         CPlayer::GetInstance().GetPlayStatusMutex().unlock();
6023         ShowPlayList(false);
6024         UpdatePlayPauseButton();
6025         DrawInfo(true);
6026         //文件删除后同时删除和文件同名的图片文件和歌词文件
6027         CFilePathHelper file_path(file_path);
6028         CommonDialogMgr::DeleteAFile(m_hWnd, file_path.ReplaceFileExtension(L"jpg").c_str());
6029         CommonDialogMgr::DeleteAFile(m_hWnd, file_path.ReplaceFileExtension(L"lrc").c_str());
6030     }
6031     else if (rtn == ERROR_CANCELLED)   //如果在弹出的对话框中点击“取消”则返回值为1223
6032     {
6033         //如果点击了“取消”,则重新打开当前文件
6034         CPlayer::GetInstance().MusicControl(Command::OPEN);
6035         CPlayer::GetInstance().MusicControl(Command::SEEK);
6036         CPlayer::GetInstance().GetPlayStatusMutex().unlock();
6037         //CPlayer::GetInstance().Refresh();
6038         UpdatePlayPauseButton();
6039         DrawInfo(true);
6040     }
6041     else
6042     {
6043         CPlayer::GetInstance().GetPlayStatusMutex().unlock();
6044         MessageBox(theApp.m_str_table.LoadText(L"MSG_DELETE_FILE_FAILED").c_str(), NULL, MB_ICONWARNING);
6045     }
6046 }
6047 
6048 
OnQueryEndSession()6049 BOOL CMusicPlayerDlg::OnQueryEndSession()
6050 {
6051     if (!CMainDialogBase::OnQueryEndSession())
6052         return FALSE;
6053 
6054     // TODO:  在此添加专用的查询结束会话代码
6055 
6056     //获取桌面歌词窗口的位置
6057     CRect rect;
6058     ::GetWindowRect(m_desktop_lyric.GetSafeHwnd(), rect);
6059     m_desktop_lyric_pos = rect.TopLeft();
6060     m_desktop_lyric_size = rect.Size();
6061 
6062     //保存修改过的歌词
6063     DoLyricsAutoSave(true);
6064 
6065     //退出时保存设置
6066     CPlayer::GetInstance().OnExit();
6067     SaveConfig();
6068     m_findDlg.SaveChildrenConfig();
6069     theApp.SaveConfig();
6070 
6071     return TRUE;
6072 }
6073 
6074 
OnAlwaysUseExternalAlbumCover()6075 void CMusicPlayerDlg::OnAlwaysUseExternalAlbumCover()
6076 {
6077     // TODO: 在此添加命令处理程序代码
6078     SongInfo song_info{ CSongDataManager::GetInstance().GetSongInfo3(CPlayer::GetInstance().GetCurrentSongInfo()) };
6079     bool always_use_external_album_cover{ song_info.AlwaysUseExternalAlbumCover() };
6080     always_use_external_album_cover = !always_use_external_album_cover;
6081     song_info.SetAlwaysUseExternalAlbumCover(always_use_external_album_cover);
6082     CSongDataManager::GetInstance().AddItem(song_info);
6083     CPlayer::GetInstance().SearchAlbumCover();      //重新获取专辑封面
6084     CPlayer::GetInstance().AlbumCoverGaussBlur();
6085     if (always_use_external_album_cover && !CPlayer::GetInstance().AlbumCoverExist())
6086     {
6087         //如果专辑封面不存在,则重新下载专辑封面
6088         m_pDownloadThread = AfxBeginThread(DownloadLyricAndCoverThreadFunc, this);
6089     }
6090 
6091 }
6092 
6093 
OnCopyData(CWnd * pWnd,COPYDATASTRUCT * pCopyDataStruct)6094 BOOL CMusicPlayerDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
6095 {
6096     // TODO: 在此添加消息处理程序代码和/或调用默认值
6097     if (pCopyDataStruct != nullptr)
6098     {
6099         if (pCopyDataStruct->dwData == COPY_DATA_OPEN_FILE || pCopyDataStruct->dwData == COPY_DATA_ADD_FILE)
6100         {
6101             wstring cmd_line((const wchar_t*)pCopyDataStruct->lpData, pCopyDataStruct->cbData / sizeof(wchar_t));
6102             //MessageBox(cmd_line.c_str());
6103             if (cmd_line.empty())
6104                 return 0;
6105             vector<wstring> files;
6106             CCommon::DisposeCmdLineFiles(cmd_line, files);
6107             // 这里不再区分COPY_DATA_OPEN_FILE和COPY_DATA_ADD_FILE,统一处理
6108             std::unique_lock<std::mutex> lock(m_cmd_open_files_mutx);
6109             // theApp.WriteLog(cmd_line + L"<from_copy_data>");
6110             m_cmd_open_files.insert(m_cmd_open_files.end(), files.begin(), files.end());     // 将来自其他实例的cmd追加到末尾
6111             SetTimer(TIMER_CMD_OPEN_FILES_DELAY, 1000, nullptr);
6112         }
6113     }
6114 
6115     return CMainDialogBase::OnCopyData(pWnd, pCopyDataStruct);
6116 }
6117 
6118 
OnRelateLocalLyric()6119 void CMusicPlayerDlg::OnRelateLocalLyric()
6120 {
6121     // TODO: 在此添加命令处理程序代码
6122     CLyricRelateDlg dlg;
6123     dlg.DoModal();
6124 }
6125 
6126 
OnAlbumCoverInfo()6127 void CMusicPlayerDlg::OnAlbumCoverInfo()
6128 {
6129     // TODO: 在此添加命令处理程序代码
6130     //CAlbumCoverInfoDlg dlg;
6131     //dlg.DoModal();
6132     CPropertyDlg propertyDlg(CPlayer::GetInstance().GetPlayList(), CPlayer::GetInstance().GetIndex(), false, 1, !CPlayer::GetInstance().IsInnerCover());
6133     propertyDlg.DoModal();
6134     if (propertyDlg.GetListRefresh())
6135         ShowPlayList();
6136 }
6137 
6138 
OnUnlinkLyric()6139 void CMusicPlayerDlg::OnUnlinkLyric()
6140 {
6141     // TODO: 在此添加命令处理程序代码
6142     CPlayer::GetInstance().ClearLyric();        //清除歌词
6143     SongInfo song_info{ CSongDataManager::GetInstance().GetSongInfo3(CPlayer::GetInstance().GetCurrentSongInfo()) };
6144     song_info.lyric_file = NO_LYRIC_STR;       //将该歌曲设置为不关联歌词
6145     song_info.SetNoOnlineLyric(true);
6146     CSongDataManager::GetInstance().AddItem(song_info);
6147 }
6148 
6149 
OnShowDesktopLyric()6150 void CMusicPlayerDlg::OnShowDesktopLyric()
6151 {
6152     // TODO: 在此添加命令处理程序代码
6153     theApp.m_lyric_setting_data.show_desktop_lyric = !theApp.m_lyric_setting_data.show_desktop_lyric;
6154 }
6155 
6156 
OnMainWindowActivated(WPARAM wParam,LPARAM lParam)6157 afx_msg LRESULT CMusicPlayerDlg::OnMainWindowActivated(WPARAM wParam, LPARAM lParam)
6158 {
6159     TaskBarInit();
6160     return 0;
6161 }
6162 
6163 
OnContainSubFolder()6164 void CMusicPlayerDlg::OnContainSubFolder()
6165 {
6166     // TODO: 在此添加命令处理程序代码
6167     if (!CPlayer::GetInstance().SetContainSubFolder())
6168     {
6169         const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY");
6170         MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK);
6171     }
6172 }
6173 
6174 
OnGetMusicCurrentPosition(WPARAM wParam,LPARAM lParam)6175 afx_msg LRESULT CMusicPlayerDlg::OnGetMusicCurrentPosition(WPARAM wParam, LPARAM lParam)
6176 {
6177     CPlayer::GetInstance().GetPlayerCoreCurrentPosition();
6178     return 0;
6179 }
6180 
6181 
OnCurrentFileAlbumCoverChanged(WPARAM wParam,LPARAM lParam)6182 afx_msg LRESULT CMusicPlayerDlg::OnCurrentFileAlbumCoverChanged(WPARAM wParam, LPARAM lParam)
6183 {
6184 
6185     return 0;
6186 }
6187 
6188 
OnRename()6189 void CMusicPlayerDlg::OnRename()
6190 {
6191     // TODO: 在此添加命令处理程序代码
6192     int count{}, fail_count{};
6193     CRenameDlg dlg(m_items_selected.size());
6194     auto& cur_playlist = CPlayer::GetInstance().GetPlayList();
6195     // 单选曲目重命名时建议当前名称
6196     if (m_items_selected.size() <= 1 && m_item_selected >= 0 && m_item_selected < static_cast<int>(cur_playlist.size()))
6197         dlg.SetInitInsertFormular(CFilePathHelper(cur_playlist[m_item_selected].file_path).GetFileNameWithoutExtension());
6198     if (dlg.DoModal() != IDOK)
6199         return;
6200     wstring formular = dlg.GetFormularSelected();
6201     for (int index : m_items_selected)
6202     {
6203         if (index < 0 || index >= static_cast<int>(cur_playlist.size()))
6204             continue;
6205         SongInfo& song = cur_playlist[index];
6206         if (song.is_cue || COSUPlayerHelper::IsOsuFile(song.file_path))
6207             continue;
6208         CPlayer::ReOpen reopen(song.IsSameSong(CPlayer::GetInstance().GetCurrentSongInfo()));
6209         if (!reopen.IsLockSuccess())
6210             continue;
6211         wstring new_name = CRenameDlg::FileNameFromTag(formular, song);
6212         wstring new_file_path = CCommon::FileRename(song.file_path, new_name);
6213         if (!new_file_path.empty())
6214         {
6215             CSongDataManager::GetInstance().ChangeFilePath(song.file_path, new_file_path);
6216             song.file_path = new_file_path;
6217             ++count;
6218         }
6219         else
6220             ++fail_count;
6221     }
6222     if (count > 0)  //重命名成功,刷新播放列表
6223     {
6224         ShowPlayList(false);
6225         CPlayer::GetInstance().SaveCurrentPlaylist();
6226     }
6227     wstring info = theApp.m_str_table.LoadTextFormat(L"MSG_RENAME_SONG_COMPLETED_INFO",
6228         { m_items_selected.size(), count, static_cast<int>(m_items_selected.size()) - count - fail_count, fail_count });
6229     MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK);
6230 }
6231 
6232 
OnEmbedLyricToAudioFile()6233 void CMusicPlayerDlg::OnEmbedLyricToAudioFile()
6234 {
6235     // TODO: 在此添加命令处理程序代码
6236     SongInfo& cur_song{ CPlayer::GetInstance().GetCurrentSongInfo2() };
6237     if (cur_song.is_cue || COSUPlayerHelper::IsOsuFile(cur_song.file_path)) return;
6238     bool lyric_write_support = CAudioTag::IsFileTypeLyricWriteSupport(CFilePathHelper(cur_song.file_path).GetFileExtension());
6239     bool lyric_write_enable = (lyric_write_support && !CPlayer::GetInstance().m_Lyrics.IsEmpty() && !CPlayer::GetInstance().IsInnerLyric());
6240     if (lyric_write_enable)
6241     {
6242         wstring lyric_contents = CPlayer::GetInstance().m_Lyrics.GetLyricsString2();
6243         bool failed{ false };
6244         if (!lyric_contents.empty())
6245         {
6246             CPlayer::ReOpen reopen(true);
6247             if (reopen.IsLockSuccess())
6248             {
6249                 CAudioTag audio_tag(cur_song);
6250                 failed = !audio_tag.WriteAudioLyric(lyric_contents);
6251             }
6252             else
6253             {
6254                 const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY");
6255                 MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK);
6256             }
6257         }
6258         if (failed)
6259         {
6260             const wstring& info = theApp.m_str_table.LoadText(L"MSG_FILE_WRITE_FAILED");
6261             MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK);
6262         }
6263     }
6264 }
6265 
6266 
OnDeleteLyricFromAudioFile()6267 void CMusicPlayerDlg::OnDeleteLyricFromAudioFile()
6268 {
6269     // TODO: 在此添加命令处理程序代码
6270     SongInfo& cur_song{ CPlayer::GetInstance().GetCurrentSongInfo2() };
6271     if (cur_song.is_cue || COSUPlayerHelper::IsOsuFile(cur_song.file_path)) return;
6272     bool lyric_write_support = CAudioTag::IsFileTypeLyricWriteSupport(CFilePathHelper(cur_song.file_path).GetFileExtension());
6273     bool lyric_delete_enable = (lyric_write_support && !CPlayer::GetInstance().m_Lyrics.IsEmpty());
6274     bool failed{ false };
6275     if (lyric_delete_enable)
6276     {
6277         CPlayer::ReOpen reopen(true);
6278         if (reopen.IsLockSuccess())
6279         {
6280             CAudioTag audio_tag(cur_song);
6281             failed = !audio_tag.WriteAudioLyric(wstring());
6282         }
6283         else
6284         {
6285             const wstring& info = theApp.m_str_table.LoadText(L"MSG_WAIT_AND_RETRY");
6286             MessageBox(info.c_str(), NULL, MB_ICONINFORMATION | MB_OK);
6287         }
6288     }
6289     if (failed)
6290     {
6291         const wstring& info = theApp.m_str_table.LoadText(L"MSG_FILE_WRITE_FAILED");
6292         MessageBox(info.c_str(), NULL, MB_ICONWARNING | MB_OK);
6293     }
6294 }
6295 
6296 
OnAfterMusicStreamClosed(WPARAM wParam,LPARAM lParam)6297 afx_msg LRESULT CMusicPlayerDlg::OnAfterMusicStreamClosed(WPARAM wParam, LPARAM lParam)
6298 {
6299     //保存修改过的歌词
6300     DoLyricsAutoSave();
6301     return 0;
6302 }
6303 
6304 
OnShowLyricTranslate()6305 void CMusicPlayerDlg::OnShowLyricTranslate()
6306 {
6307     // TODO: 在此添加命令处理程序代码
6308     theApp.m_lyric_setting_data.show_translate = !theApp.m_lyric_setting_data.show_translate;
6309 }
6310 
6311 
OnViewArtist()6312 void CMusicPlayerDlg::OnViewArtist()
6313 {
6314     // TODO: 在此添加命令处理程序代码
6315     CMusicPlayerCmdHelper helper;
6316     helper.OnViewArtist(CPlayer::GetInstance().GetCurrentSongInfo());
6317 }
6318 
6319 
OnViewAlbum()6320 void CMusicPlayerDlg::OnViewAlbum()
6321 {
6322     // TODO: 在此添加命令处理程序代码
6323     CMusicPlayerCmdHelper helper;
6324     helper.OnViewAlbum(CPlayer::GetInstance().GetCurrentSongInfo());
6325 }
6326 
6327 
OnLocateToCurrent()6328 void CMusicPlayerDlg::OnLocateToCurrent()
6329 {
6330     // TODO: 在此添加命令处理程序代码
6331     m_playlist_list.EnsureVisible(CPlayer::GetInstance().GetIndex(), FALSE);
6332     if (IsFloatPlaylistExist())
6333         m_pFloatPlaylistDlg->GetListCtrl().EnsureVisible(CPlayer::GetInstance().GetIndex(), FALSE);
6334     CUserUi* user_ui{ dynamic_cast<CUserUi*>(GetCurrentUi()) };
6335     if (user_ui != nullptr)
6336         user_ui->ListLocateToCurrent();
6337 }
6338 
6339 
OnUseStandardTitleBar()6340 void CMusicPlayerDlg::OnUseStandardTitleBar()
6341 {
6342     // TODO: 在此添加命令处理程序代码
6343     if (m_miniModeDlg.m_hWnd != NULL)   // 迷你模式下不允许响应
6344         return;
6345 
6346     theApp.m_app_setting_data.show_window_frame = !theApp.m_app_setting_data.show_window_frame;
6347     ApplyShowStandardTitlebar();
6348 }
6349 
ApplyShowStandardTitlebar()6350 void CMusicPlayerDlg::ApplyShowStandardTitlebar()
6351 {
6352     // 有可能同时处于最大化与全屏状态,更改标题栏状态前逐个退出
6353     if (theApp.m_ui_data.full_screen)   // 如果全屏则退出全屏
6354     {
6355         OnFullScreen();
6356     }
6357     if (IsZoomed())                     // 如果是窗口处于最大化下则还原窗口
6358     {
6359         SendMessage(WM_SYSCOMMAND, SC_RESTORE);
6360     }
6361     ShowTitlebar(theApp.m_app_setting_data.show_window_frame);
6362     SetMenubarVisible();
6363     auto pCurUi = GetCurrentUi();
6364     if (pCurUi != nullptr)
6365         pCurUi->ClearBtnRect();
6366 }
6367 
6368 
OnReInitBassContinuePlay(WPARAM wParam,LPARAM lParam)6369 afx_msg LRESULT CMusicPlayerDlg::OnReInitBassContinuePlay(WPARAM wParam, LPARAM lParam)
6370 {
6371     if (CPlayer::GetInstance().GetPlayerCore() != nullptr && CPlayer::GetInstance().GetPlayerCore()->GetCoreType() == PlayerCoreType::PT_BASS)
6372     {
6373         CPlayer::GetInstance().ReIniPlayerCore(true);       // 重新初始化播放内核
6374     }
6375     return 0;
6376 }
6377 
6378 
OnDisplaychange(WPARAM wParam,LPARAM lParam)6379 afx_msg LRESULT CMusicPlayerDlg::OnDisplaychange(WPARAM wParam, LPARAM lParam)
6380 {
6381     // 由主窗口更新显示器信息,子窗口OnDisplaychange时的位置调整应在全部此进行
6382     // 子窗口自身的OnDisplaychange先于主窗口无法使用更新后的m_screen_rects
6383     GetScreenInfo();
6384     // 移动桌面歌词窗口位置
6385     MoveDesktopLyricWindowPos();
6386     // 若此时为mini模式则移动mini窗口位置
6387     if (m_miniModeDlg.m_hWnd != NULL)
6388     {
6389         m_miniModeDlg.MoveWindowPos();
6390     }
6391 
6392     // 显示器状态改变时退出全屏,防止窗口被移动后以旧尺寸全屏显示在主显示器上
6393     if (theApp.m_ui_data.full_screen)
6394     {
6395         OnFullScreen();
6396     }
6397     return 0;
6398 }
6399 
6400 
OnWindowPosChanging(WINDOWPOS * lpwndpos)6401 void CMusicPlayerDlg::OnWindowPosChanging(WINDOWPOS* lpwndpos)
6402 {
6403     // 最大化时更改为rcWork,全屏时更改为rcMonitor
6404     if (IsZoomed() || theApp.m_ui_data.full_screen)
6405     {
6406         // 获取主窗口所在监视器句柄,如果窗口不在任何监视器则返回主监视器句柄
6407         HMONITOR hMonitor = MonitorFromWindow(theApp.m_pMainWnd->GetSafeHwnd(), MONITOR_DEFAULTTOPRIMARY);
6408         // 获取监视器信息
6409         MONITORINFO lpmi;
6410         lpmi.cbSize = sizeof(lpmi);
6411         GetMonitorInfo(hMonitor, &lpmi);
6412         if (theApp.m_ui_data.full_screen)
6413         {
6414             lpwndpos->x = lpmi.rcMonitor.left;
6415             lpwndpos->y = lpmi.rcMonitor.top;
6416             lpwndpos->cx = lpmi.rcMonitor.right - lpmi.rcMonitor.left;
6417             lpwndpos->cy = lpmi.rcMonitor.bottom - lpmi.rcMonitor.top;
6418         }
6419         else
6420         {
6421             lpwndpos->x = lpmi.rcWork.left;
6422             lpwndpos->y = lpmi.rcWork.top;
6423             lpwndpos->cx = lpmi.rcWork.right - lpmi.rcWork.left;
6424             lpwndpos->cy = lpmi.rcWork.bottom - lpmi.rcWork.top;
6425         }
6426     }
6427     CMainDialogBase::OnWindowPosChanging(lpwndpos);
6428 
6429     // TODO: 在此处添加消息处理程序代码
6430 }
6431 
6432 
OnWindowPosChanged(WINDOWPOS * lpwndpos)6433 void CMusicPlayerDlg::OnWindowPosChanged(WINDOWPOS* lpwndpos)
6434 {
6435     CMainDialogBase::OnWindowPosChanged(lpwndpos);
6436 
6437     // TODO: 在此处添加消息处理程序代码
6438 
6439     // 需要去掉大小边框的情况
6440     if ((IsZoomed() && !theApp.m_app_setting_data.show_window_frame) || theApp.m_ui_data.full_screen)
6441     {
6442         ShowSizebox(false);
6443     }
6444     else
6445     {
6446         ShowSizebox(true);
6447     }
6448 }
6449 
6450 
OnPlaylistViewArtist()6451 void CMusicPlayerDlg::OnPlaylistViewArtist()
6452 {
6453     // TODO: 在此添加命令处理程序代码
6454     if (m_item_selected >= 0 && m_item_selected < CPlayer::GetInstance().GetSongNum())
6455     {
6456         CMusicPlayerCmdHelper helper;
6457         helper.OnViewArtist(CPlayer::GetInstance().GetPlayList()[m_item_selected]);
6458     }
6459 }
6460 
6461 
OnPlaylistViewAlbum()6462 void CMusicPlayerDlg::OnPlaylistViewAlbum()
6463 {
6464     // TODO: 在此添加命令处理程序代码
6465     if (m_item_selected >= 0 && m_item_selected < CPlayer::GetInstance().GetSongNum())
6466     {
6467         CMusicPlayerCmdHelper helper;
6468         helper.OnViewAlbum(CPlayer::GetInstance().GetPlayList()[m_item_selected]);
6469     }
6470 }
6471 
OnVolumeChanged(WPARAM wParam,LPARAM lParam)6472 LRESULT CMusicPlayerDlg::OnVolumeChanged(WPARAM wParam, LPARAM lParam)
6473 {
6474     auto* cur_ui = GetCurrentUi();
6475     if (cur_ui != nullptr)
6476     {
6477         cur_ui->UpdateVolumeToolTip();
6478     }
6479     return 0;
6480 }
6481 
6482 
OnPlaylistOptions()6483 void CMusicPlayerDlg::OnPlaylistOptions()
6484 {
6485     // TODO: 在此添加命令处理程序代码
6486     m_tab_selected = 4;
6487     _OnOptionSettings(this);
6488 }
6489 
6490 
OnMove(int x,int y)6491 void CMusicPlayerDlg::OnMove(int x, int y)
6492 {
6493     CMainDialogBase::OnMove(x, y);
6494 
6495     //移动主窗口时同步移动浮动播放列表的位置
6496     MoveFloatPlaylistPos();
6497 }
6498 
6499 
MoveFloatPlaylistPos()6500 bool CMusicPlayerDlg::MoveFloatPlaylistPos()
6501 {
6502     if (theApp.m_media_lib_setting_data.float_playlist_follow_main_wnd && !theApp.m_ui_data.full_screen && !IsZoomed() && !IsIconic())
6503     {
6504         CRect rect;
6505         GetWindowRect(rect);
6506         if (rect.IsRectEmpty() || (rect.right < 0 && rect.top < 0))
6507             return false;
6508         m_float_playlist_pos.x = rect.right;
6509         m_float_playlist_pos.y = rect.top;
6510         if (m_float_playlist_pos.x != 0 && m_float_playlist_pos.y != 0)
6511         {
6512             if (IsFloatPlaylistExist() && !m_pFloatPlaylistDlg->IsZoomed())
6513             {
6514                 CRect float_playlist_rect;
6515                 m_pFloatPlaylistDlg->GetWindowRect(float_playlist_rect);
6516                 m_pFloatPlaylistDlg->SetWindowPos(nullptr, m_float_playlist_pos.x, m_float_playlist_pos.y, float_playlist_rect.Width(), rect.Height(), SWP_NOACTIVATE | SWP_NOZORDER);
6517                 return true;
6518             }
6519         }
6520     }
6521     return false;
6522 }
6523 
IsPointValid(CPoint point)6524 bool CMusicPlayerDlg::IsPointValid(CPoint point)
6525 {
6526     return (point.x != INT_MAX && point.y != INT_MAX && point.x != INT_MIN && point.y != INT_MAX);
6527 }
6528 
UpdatePlaylistCtrlPosition(CWnd * pParent,CWnd * pStatic,CWnd * pEdit)6529 int CMusicPlayerDlg::UpdatePlaylistCtrlPosition(CWnd* pParent, CWnd* pStatic, CWnd* pEdit)
6530 {
6531     if (!IsWindow(pParent->GetSafeHwnd()) || !IsWindow(pStatic->GetSafeHwnd()) || !IsWindow(pEdit->GetSafeHwnd()))
6532         return 0;
6533 
6534     //计算CStatic控件的宽度
6535     int static_width = theApp.DPI(20);
6536     wstring static_text = m_current_cache.at(0).GetTypeDisplayName();
6537     CDC* pDC = pParent->GetDC();
6538     pDC->SelectObject(&theApp.m_font_set.dlg.GetFont());
6539     static_width += pDC->GetTextExtent(static_text.c_str()).cx;
6540     pParent->ReleaseDC(pDC);
6541 
6542     if (!static_text.empty())
6543         static_width += theApp.DPI(4);
6544 
6545     if (static_width > theApp.DPI(150))
6546         static_width = theApp.DPI(150);
6547 
6548     //获取两个控件原来的位置
6549     CRect static_rect;
6550     CRect edit_rect;
6551     pStatic->GetWindowRect(static_rect);
6552     pEdit->GetWindowRect(edit_rect);
6553     pParent->ScreenToClient(&static_rect);
6554     pParent->ScreenToClient(&edit_rect);
6555     //计算static控件原来的宽度和要设置的宽度的差
6556     int width_diff = static_rect.Width() - static_width;
6557     pStatic->SetWindowPos(nullptr, 0, 0, static_width, static_rect.Height(), SWP_NOMOVE | SWP_NOZORDER);
6558     pEdit->SetWindowPos(nullptr, edit_rect.left - width_diff, edit_rect.top, edit_rect.Width() + width_diff, edit_rect.Height(), SWP_NOZORDER);
6559     return static_width;
6560 }
6561 
OnRecentFolderOrPlaylistChanged(WPARAM wParam,LPARAM lParam)6562 afx_msg LRESULT CMusicPlayerDlg::OnRecentFolderOrPlaylistChanged(WPARAM wParam, LPARAM lParam)
6563 {
6564     //初始化点击文件夹/播放列表右侧按钮弹出的菜单
6565     m_recent_cache.reload();    // 仅在更新菜单时reload,此对象总是与此菜单同步
6566     vector<MenuMgr::MenuItem> menu_list;
6567     for (size_t i{}; i < m_recent_cache.size(); ++i)
6568     {
6569         UINT id = ID_RECENT_FOLDER_PLAYLIST_MENU_START + menu_list.size();
6570         menu_list.emplace_back(MenuMgr::MenuItem{ id, m_recent_cache.at(i).GetTypeIcon(), m_recent_cache.at(i).GetDisplayName() });
6571         if (menu_list.size() >= RECENT_FOLDER_PLAYLIST_MAX_SIZE)
6572             break;
6573     }
6574     theApp.m_menu_mgr.UpdateMenu(MenuMgr::RecentFolderPlaylistMenu, menu_list);
6575 
6576     return 0;
6577 }
6578 
6579 
OnPlayAsNext()6580 void CMusicPlayerDlg::OnPlayAsNext() {
6581     CPlayer::GetInstance().PlayAfterCurrentTrack(m_items_selected);
6582     m_ui_thread_para.ui_force_refresh = true;   // 虽然现在这行的效果被“主窗口拥有焦点”盖过了,不过保留这行
6583 }
6584 
6585 
OnPlaylistFixPathError()6586 void CMusicPlayerDlg::OnPlaylistFixPathError()
6587 {
6588     const wstring& inquiry_info = theApp.m_str_table.LoadText(L"MSG_PLAYLIST_FIX_ERROR_PATH_INQUIRY");
6589     if (MessageBox(inquiry_info.c_str(), NULL, MB_ICONQUESTION | MB_YESNO) == IDYES)
6590     {
6591         CMusicPlayerCmdHelper helper(this);
6592         int fixed_count = helper.FixPlaylistPathError(CPlayer::GetInstance().GetPlaylistPath());
6593         wstring complete_info = theApp.m_str_table.LoadTextFormat(L"MSG_PLAYLIST_FIX_ERROR_PATH_COMPLETE", { fixed_count });
6594         MessageBox(complete_info.c_str(), NULL, MB_ICONINFORMATION | MB_OK);
6595     }
6596 }
6597 
6598 
OnPowerBroadcast(UINT nPowerEvent,LPARAM nEventData)6599 UINT CMusicPlayerDlg::OnPowerBroadcast(UINT nPowerEvent, LPARAM nEventData)
6600 {
6601     // theApp.WriteLog(L"OnPowerBroadcast " + std::to_wstring(nPowerEvent));
6602     // 按文档描述应该是这里收到4,18,7才对,实际上这里好像只能收到10(交流适配器插入拔出)
6603     // 自win8之后加入的powrprof.h含有新的PowerRegisterSuspendResumeNotification可能代替了这里的功能
6604     if (nPowerEvent == PBT_APMRESUMESUSPEND)  // 系统正在从“睡眠S3”“休眠S4”唤醒(由用户触发)
6605         ::PostMessage(theApp.m_pMainWnd->GetSafeHwnd(), WM_RE_INIT_BASS_CONTINUE_PLAY, 0, 0);
6606     return CMainDialogBase::OnPowerBroadcast(nPowerEvent, nEventData);
6607 }
6608 
DeviceNotifyCallbackRoutine(PVOID Context,ULONG Type,PVOID Setting)6609 ULONG CMusicPlayerDlg::DeviceNotifyCallbackRoutine(PVOID Context, ULONG Type, PVOID Setting)
6610 {
6611     // theApp.WriteLog(L"DeviceNotifyCallbackRoutine " + std::to_wstring(Type));
6612     // 睡眠唤醒流程依次收到4,18,7
6613     if (Type == PBT_APMRESUMESUSPEND)   // 系统正在从“睡眠S3”“休眠S4”唤醒(由用户触发)
6614         ::PostMessage(theApp.m_pMainWnd->GetSafeHwnd(), WM_RE_INIT_BASS_CONTINUE_PLAY, 0, 0);
6615     return 0;
6616 }
6617 
6618 
OnSetUiForceFreshFlag(WPARAM wParam,LPARAM lParam)6619 afx_msg LRESULT CMusicPlayerDlg::OnSetUiForceFreshFlag(WPARAM wParam, LPARAM lParam)
6620 {
6621     m_ui_thread_para.ui_force_refresh = true;
6622     return 0;
6623 }
6624 
OnMoreRecentItems()6625 void CMusicPlayerDlg::OnMoreRecentItems()
6626 {
6627     CMoreRecentItemDlg dlg;
6628     if (dlg.DoModal() == IDOK)
6629     {
6630         ListItem list_item = dlg.GetSelectedItem();
6631         CMusicPlayerCmdHelper helper;
6632         helper.OnListItemSelected(list_item);
6633     }
6634 }
6635 
6636 
OnNcCalcSize(BOOL bCalcValidRects,NCCALCSIZE_PARAMS * lpncsp)6637 void CMusicPlayerDlg::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp)
6638 {
6639     if (theApp.m_app_setting_data.remove_titlebar_top_frame && CWinVersionHelper::IsWindows10OrLater() && !theApp.m_app_setting_data.show_window_frame && !IsZoomed() && !theApp.m_ui_data.full_screen)
6640     {
6641         if (bCalcValidRects)
6642         {
6643             //这里去掉使用了自绘标题栏时顶部的白边
6644             lpncsp->rgrc[0].top -= theApp.DPI(6);
6645         }
6646     }
6647     CMainDialogBase::OnNcCalcSize(bCalcValidRects, lpncsp);
6648 }
6649 
6650 
OnClearUiSerchBox(WPARAM wParam,LPARAM lParam)6651 afx_msg LRESULT CMusicPlayerDlg::OnClearUiSerchBox(WPARAM wParam, LPARAM lParam)
6652 {
6653     for (auto& ui : m_ui_list)
6654     {
6655         CUserUi* cur_ui{ dynamic_cast<CUserUi*>(ui.get()) };
6656         if (cur_ui != nullptr)
6657         {
6658             switch (wParam)
6659             {
6660             case UI_LIST_TYPE_RECENT_PLAYED:
6661                 cur_ui->ClearSearchResult<UiElement::RecentPlayedList>();
6662                 break;
6663             case UI_LIST_TYPE_FOLDER:
6664                 cur_ui->ClearSearchResult<UiElement::MediaLibFolder>();
6665                 break;
6666             case UI_LIST_TYPE_PLAYLIST:
6667                 cur_ui->ClearSearchResult<UiElement::MediaLibPlaylist>();
6668                 break;
6669             }
6670         }
6671     }
6672 
6673     return 0;
6674 }
6675