1 #include "stdafx.h"
2 #include "DesktopLyric.h"
3 #include "MusicPlayer2.h"
4 #include "SongInfoHelper.h"
5 #include "GdiPlusTool.h"
6 #include "CPlayerUIHelper.h"
7 #include "MusicPlayerDlg.h"
8
CDesktopLyric()9 CDesktopLyric::CDesktopLyric()
10 {
11 m_toobar_height = theApp.DPI(24);
12 }
13
14
~CDesktopLyric()15 CDesktopLyric::~CDesktopLyric()
16 {
17 }
18
BEGIN_MESSAGE_MAP(CDesktopLyric,CLyricsWindow)19 BEGIN_MESSAGE_MAP(CDesktopLyric, CLyricsWindow)
20 ON_WM_LBUTTONDOWN()
21 ON_WM_LBUTTONUP()
22 ON_WM_MOUSEMOVE()
23 ON_WM_MOUSEHOVER()
24 ON_WM_MOUSELEAVE()
25 ON_WM_SIZING()
26 ON_WM_RBUTTONUP()
27 ON_WM_GETMINMAXINFO()
28 ON_WM_TIMER()
29
30 ON_COMMAND(ID_LYRIC_DEFAULT_STYLE1, &CDesktopLyric::OnLyricDefaultStyle1)
31 ON_COMMAND(ID_LYRIC_DEFAULT_STYLE2, &CDesktopLyric::OnLyricDefaultStyle2)
32 ON_COMMAND(ID_LYRIC_DEFAULT_STYLE3, &CDesktopLyric::OnLyricDefaultStyle3)
33 ON_WM_LBUTTONDBLCLK()
34 ON_WM_INITMENU()
35 END_MESSAGE_MAP()
36
37 void CDesktopLyric::Create()
38 {
39 CLyricsWindow::Create(theApp.DPI(150));
40
41 //初始化提示信息
42 m_tool_tip.Create(this, TTS_ALWAYSTIP);
43 m_tool_tip.SetMaxTipWidth(theApp.DPI(400));
44
45 //初始化定时器
46 SetTimer(TIMER_DESKTOP_LYRIC, 200, NULL);
47
48 }
49
ShowLyric()50 void CDesktopLyric::ShowLyric()
51 {
52 if (!IsWindowVisible())
53 return;
54
55 SetLyricDoubleLine(theApp.m_lyric_setting_data.desktop_lyric_data.lyric_double_line);
56 SetShowTranslate(theApp.m_lyric_setting_data.show_translate);
57 SetAlignment(theApp.m_lyric_setting_data.desktop_lyric_data.lyric_align);
58 SetLyricKaraokeDisplay(theApp.m_lyric_setting_data.lyric_karaoke_disp);
59
60 Draw();
61 }
62
63
64
UpdateLyric(Gdiplus::Graphics * pGraphics,Gdiplus::Font * pFont)65 void CDesktopLyric::UpdateLyric(Gdiplus::Graphics* pGraphics, Gdiplus::Font* pFont)
66 {
67 if (CPlayerUIHelper::IsMidiLyric())
68 {
69 wstring current_lyric{ CPlayer::GetInstance().GetMidiLyric() };
70 if (current_lyric != GetLyricStr().GetString())
71 {
72 UpdateLyrics(current_lyric.c_str(), 0);
73 }
74 UpdateLyricTranslate(_T(""));
75 SetNextLyric(_T(""));
76 }
77 else if (!CPlayer::GetInstance().m_Lyrics.IsEmpty())
78 {
79 const bool karaoke{ theApp.m_lyric_setting_data.lyric_karaoke_disp };
80 const bool ignore_blank{ theApp.m_lyric_setting_data.donot_show_blank_lines };
81
82 auto& now_lyrics{ CPlayer::GetInstance().m_Lyrics };
83 Time time{ CPlayer::GetInstance().GetCurrentPosition() };
84 CLyrics::Lyric lyric{ now_lyrics.GetLyric(time, false, ignore_blank, karaoke) };
85 bool is_lyric_empty{ lyric.text.empty() };
86 int progress{ now_lyrics.GetLyricProgress(time, ignore_blank, karaoke,
87 [&](const wstring& str)
88 {
89 Gdiplus::RectF boundingBox;
90 pGraphics->MeasureString(str.c_str(), -1, pFont, Gdiplus::RectF{}, Gdiplus::StringFormat::GenericTypographic(), &boundingBox, 0, 0);
91 return static_cast<int>(boundingBox.Width);
92 }
93 ) };
94 // TRACE("progress %d\n", progress);
95 static const wstring& empty_lyric = theApp.m_str_table.LoadText(L"UI_LYRIC_EMPTY_LINE_2");
96 if (is_lyric_empty)
97 lyric.text = empty_lyric;
98
99 if (theApp.m_lyric_setting_data.desktop_lyric_data.lyric_double_line)
100 {
101 CLyrics::Lyric next_lyric{ now_lyrics.GetLyric(time, true, ignore_blank, karaoke) };
102 if (next_lyric.text.empty())
103 next_lyric.text = empty_lyric;
104 SetNextLyric(next_lyric.text.c_str());
105 }
106
107 static int last_progress{ -1 };
108 SetLyricChangeFlag(last_progress > progress);
109 last_progress = progress;
110
111 UpdateLyrics(lyric.text.c_str(), progress);
112 UpdateLyricTranslate(lyric.translate.c_str());
113 }
114 else
115 {
116 const SongInfo& cur_song_info = CPlayer::GetInstance().GetCurrentSongInfo();
117 std::wstring display_text = CSongInfoHelper::GetDisplayStr(cur_song_info, DF_ARTIST_TITLE);
118 if (display_text != GetLyricStr().GetString())
119 {
120 UpdateLyrics(display_text.c_str(), 0);
121 }
122 UpdateLyricTranslate(_T(""));
123 SetNextLyric(_T(""));
124 }
125 }
126
ClearLyric()127 void CDesktopLyric::ClearLyric()
128 {
129 UpdateLyricTranslate(_T(""));
130 UpdateLyrics(_T(""), 0);
131 SetNextLyric(_T(""));
132 }
133
ApplySettings(const DesktopLyricSettingData & data)134 void CDesktopLyric::ApplySettings(const DesktopLyricSettingData& data)
135 {
136 SetLyricsFont(data.lyric_font.name.c_str(), static_cast<Gdiplus::REAL>(theApp.DPI(data.lyric_font.size)), CGdiPlusTool::ToGDIPluseFontStyle(data.lyric_font.style));
137 SetLyricsColor(CGdiPlusTool::COLORREFToGdiplusColor(data.text_color1), CGdiPlusTool::COLORREFToGdiplusColor(data.text_color2), static_cast<LyricsGradientMode>(data.text_gradient));
138 SetHighlightColor(CGdiPlusTool::COLORREFToGdiplusColor(data.highlight_color1), CGdiPlusTool::COLORREFToGdiplusColor(data.highlight_color2), static_cast<LyricsGradientMode>(data.highlight_gradient));
139 //SetLyricWindowLock(data.lock_desktop_lyric);
140 //SetLyricBackgroundPenetrate(data.lyric_background_penetrate);
141 m_bLocked = data.lock_desktop_lyric;
142 m_lyricBackgroundPenetrate = data.lyric_background_penetrate;
143 SetTimer(TIMER_DESKTOP_LYRIC_2, 200, NULL); //延迟200毫秒设置锁定歌词窗口和背景穿透
144 }
145
SetLyricWindowVisible(bool visible)146 void CDesktopLyric::SetLyricWindowVisible(bool visible)
147 {
148 ShowWindow(visible);
149 }
150
SetLyricWindowLock(bool locked)151 void CDesktopLyric::SetLyricWindowLock(bool locked)
152 {
153 m_bLocked = locked;
154 SetWindowStyle();
155 }
156
SetLyricOpacity(int opacity)157 void CDesktopLyric::SetLyricOpacity(int opacity)
158 {
159 SetAlpha(opacity * 255 / 100);
160 }
161
SetLyricBackgroundPenetrate(bool penetrate)162 void CDesktopLyric::SetLyricBackgroundPenetrate(bool penetrate)
163 {
164 m_lyricBackgroundPenetrate = penetrate;
165 SetWindowStyle();
166 }
167
GetDefaultStyle(int index) const168 LyricStyleDefaultData CDesktopLyric::GetDefaultStyle(int index) const
169 {
170 if (index < 0 || index >= LYRIC_DEFAULT_STYLE_NUM)
171 index = 0;
172 return m_default_style[index];
173 }
174
SetDefaultStyle(const LyricStyleDefaultData & style_data,int index)175 void CDesktopLyric::SetDefaultStyle(const LyricStyleDefaultData& style_data, int index)
176 {
177 if (index >= 0 && index < LYRIC_DEFAULT_STYLE_NUM)
178 {
179 m_default_style[index] = style_data;
180 }
181 }
182
RestoreDefaultStyle()183 void CDesktopLyric::RestoreDefaultStyle()
184 {
185 m_default_style[0].normal_style.color1 = RGB(37, 152, 10);
186 m_default_style[0].normal_style.color2 = RGB(129, 249, 0);
187 m_default_style[0].normal_style.gradient_mode = 1;
188 m_default_style[0].highlight_style.color1 = RGB(253, 232, 0);
189 m_default_style[0].highlight_style.color2 = RGB(255, 120, 0);
190 m_default_style[0].highlight_style.gradient_mode = 2;
191
192 m_default_style[1].normal_style.color1 = RGB(252, 82, 66);
193 m_default_style[1].normal_style.color2 = RGB(255, 128, 0);
194 m_default_style[1].normal_style.gradient_mode = 1;
195 m_default_style[1].highlight_style.color1 = RGB(255, 255, 0);
196 m_default_style[1].highlight_style.color2 = RGB(255, 192, 0);
197 m_default_style[1].highlight_style.gradient_mode = 2;
198
199 m_default_style[2].normal_style.color1 = RGB(210, 137, 255);
200 m_default_style[2].normal_style.color2 = RGB(200, 227, 255);
201 m_default_style[2].normal_style.gradient_mode = 1;
202 m_default_style[2].highlight_style.color1 = RGB(98, 237, 245);
203 m_default_style[2].highlight_style.color2 = RGB(74, 145, 253);
204 m_default_style[2].highlight_style.gradient_mode = 2;
205 }
206
LyricStyleDefaultDataToLyricSettingData(const LyricStyleDefaultData & style_data,DesktopLyricSettingData & setting_data)207 void CDesktopLyric::LyricStyleDefaultDataToLyricSettingData(const LyricStyleDefaultData& style_data, DesktopLyricSettingData& setting_data)
208 {
209 setting_data.text_color1 = style_data.normal_style.color1;
210 setting_data.text_color2 = style_data.normal_style.color2;
211 setting_data.text_gradient = style_data.normal_style.gradient_mode;
212 setting_data.highlight_color1 = style_data.highlight_style.color1;
213 setting_data.highlight_color2 = style_data.highlight_style.color2;
214 setting_data.highlight_gradient = style_data.highlight_style.gradient_mode;
215 }
216
LyricSettingDatatOLyricStyleDefaultData(const DesktopLyricSettingData & setting_data,LyricStyleDefaultData & style_data)217 void CDesktopLyric::LyricSettingDatatOLyricStyleDefaultData(const DesktopLyricSettingData& setting_data, LyricStyleDefaultData& style_data)
218 {
219 style_data.normal_style.color1 = setting_data.text_color1;
220 style_data.normal_style.color2 = setting_data.text_color2;
221 style_data.normal_style.gradient_mode = setting_data.text_gradient;
222 style_data.highlight_style.color1 = setting_data.highlight_color1;
223 style_data.highlight_style.color2 = setting_data.highlight_color2;
224 style_data.highlight_style.gradient_mode = setting_data.highlight_gradient;
225
226 }
227
LoadDefaultStyle(CIniHelper & ini)228 void CDesktopLyric::LoadDefaultStyle(CIniHelper& ini)
229 {
230 m_default_style[0].normal_style.color1 = ini.GetInt(L"desktop_lyric_default_style", L"default1_text_color1", RGB(37, 152, 10));
231 m_default_style[0].normal_style.color2 = ini.GetInt(L"desktop_lyric_default_style", L"default1_text_color2", RGB(129, 249, 0));
232 m_default_style[0].normal_style.gradient_mode = ini.GetInt(L"desktop_lyric_default_style", L"default1_text_gradient_mode", 1);
233 m_default_style[0].highlight_style.color1 = ini.GetInt(L"desktop_lyric_default_style", L"default1_highlight_color1", RGB(253, 232, 0));
234 m_default_style[0].highlight_style.color2 = ini.GetInt(L"desktop_lyric_default_style", L"default1_highlight_color2", RGB(255, 120, 0));
235 m_default_style[0].highlight_style.gradient_mode = ini.GetInt(L"desktop_lyric_default_style", L"default1_highlight_gradient_mode", 2);
236
237 m_default_style[1].normal_style.color1 = ini.GetInt(L"desktop_lyric_default_style", L"default2_text_color1", RGB(252, 82, 66));
238 m_default_style[1].normal_style.color2 = ini.GetInt(L"desktop_lyric_default_style", L"default2_text_color2", RGB(255, 128, 0));
239 m_default_style[1].normal_style.gradient_mode = ini.GetInt(L"desktop_lyric_default_style", L"default2_text_gradient_mode", 1);
240 m_default_style[1].highlight_style.color1 = ini.GetInt(L"desktop_lyric_default_style", L"default2_highlight_color1", RGB(255, 255, 0));
241 m_default_style[1].highlight_style.color2 = ini.GetInt(L"desktop_lyric_default_style", L"default2_highlight_color2", RGB(255, 192, 0));
242 m_default_style[1].highlight_style.gradient_mode = ini.GetInt(L"desktop_lyric_default_style", L"default2_highlight_gradient_mode", 2);
243
244 m_default_style[2].normal_style.color1 = ini.GetInt(L"desktop_lyric_default_style", L"default3_text_color1", RGB(210, 137, 255));
245 m_default_style[2].normal_style.color2 = ini.GetInt(L"desktop_lyric_default_style", L"default3_text_color2", RGB(200, 227, 255));
246 m_default_style[2].normal_style.gradient_mode = ini.GetInt(L"desktop_lyric_default_style", L"default3_text_gradient_mode", 1);
247 m_default_style[2].highlight_style.color1 = ini.GetInt(L"desktop_lyric_default_style", L"default3_highlight_color1", RGB(98, 237, 245));
248 m_default_style[2].highlight_style.color2 = ini.GetInt(L"desktop_lyric_default_style", L"default3_highlight_color2", RGB(74, 145, 253));
249 m_default_style[2].highlight_style.gradient_mode = ini.GetInt(L"desktop_lyric_default_style", L"default3_highlight_gradient_mode", 2);
250 }
251
SaveDefaultStyle(CIniHelper & ini) const252 void CDesktopLyric::SaveDefaultStyle(CIniHelper& ini) const
253 {
254 ini.WriteInt(L"desktop_lyric_default_style", L"default1_text_color1", m_default_style[0].normal_style.color1);
255 ini.WriteInt(L"desktop_lyric_default_style", L"default1_text_color2", m_default_style[0].normal_style.color2);
256 ini.WriteInt(L"desktop_lyric_default_style", L"default1_text_gradient_mode", m_default_style[0].normal_style.gradient_mode);
257 ini.WriteInt(L"desktop_lyric_default_style", L"default1_highlight_color1", m_default_style[0].highlight_style.color1);
258 ini.WriteInt(L"desktop_lyric_default_style", L"default1_highlight_color2", m_default_style[0].highlight_style.color2);
259 ini.WriteInt(L"desktop_lyric_default_style", L"default1_highlight_gradient_mode", m_default_style[0].highlight_style.gradient_mode);
260
261 ini.WriteInt(L"desktop_lyric_default_style", L"default2_text_color1", m_default_style[1].normal_style.color1);
262 ini.WriteInt(L"desktop_lyric_default_style", L"default2_text_color2", m_default_style[1].normal_style.color2);
263 ini.WriteInt(L"desktop_lyric_default_style", L"default2_text_gradient_mode", m_default_style[1].normal_style.gradient_mode);
264 ini.WriteInt(L"desktop_lyric_default_style", L"default2_highlight_color1", m_default_style[1].highlight_style.color1);
265 ini.WriteInt(L"desktop_lyric_default_style", L"default2_highlight_color2", m_default_style[1].highlight_style.color2);
266 ini.WriteInt(L"desktop_lyric_default_style", L"default2_highlight_gradient_mode", m_default_style[1].highlight_style.gradient_mode);
267
268 ini.WriteInt(L"desktop_lyric_default_style", L"default3_text_color1", m_default_style[2].normal_style.color1);
269 ini.WriteInt(L"desktop_lyric_default_style", L"default3_text_color2", m_default_style[2].normal_style.color2);
270 ini.WriteInt(L"desktop_lyric_default_style", L"default3_text_gradient_mode", m_default_style[2].normal_style.gradient_mode);
271 ini.WriteInt(L"desktop_lyric_default_style", L"default3_highlight_color1", m_default_style[2].highlight_style.color1);
272 ini.WriteInt(L"desktop_lyric_default_style", L"default3_highlight_color2", m_default_style[2].highlight_style.color2);
273 ini.WriteInt(L"desktop_lyric_default_style", L"default3_highlight_gradient_mode", m_default_style[2].highlight_style.gradient_mode);
274 }
275
DrawToolbar(Gdiplus::Graphics * pGraphics)276 void CDesktopLyric::DrawToolbar(Gdiplus::Graphics* pGraphics)
277 {
278 bool bLocked = theApp.m_lyric_setting_data.desktop_lyric_data.lock_desktop_lyric;
279 const int toolbar_num = bLocked ? 1 : BtnKey::MAX;
280 const int btn_size = m_toobar_height;
281 int toolbar_width = toolbar_num * btn_size;
282 Gdiplus::Rect toolbar_rect;
283 toolbar_rect.Y = 0;
284 toolbar_rect.X = (m_rcWindow.Width() - toolbar_width) / 2;
285 toolbar_rect.Width = toolbar_width;
286 toolbar_rect.Height = btn_size;
287
288 //绘制背景
289 if (!bLocked || theApp.m_lyric_setting_data.desktop_lyric_data.show_unlock_when_locked)
290 {
291 Gdiplus::Color back_color = CGdiPlusTool::COLORREFToGdiplusColor(theApp.m_app_setting_data.theme_color.light2, 180);
292 if (!theApp.m_app_setting_data.button_round_corners)
293 {
294 Gdiplus::Brush* pBrush = new Gdiplus::SolidBrush(back_color);
295 pGraphics->FillRectangle(pBrush, toolbar_rect);
296 delete pBrush;
297 }
298 else
299 {
300 CDrawCommon drawer;
301 drawer.Create(nullptr, pGraphics);
302 drawer.DrawRoundRect(toolbar_rect, back_color, theApp.DPI(4));
303 }
304 }
305
306 CRect rcIcon = CRect(toolbar_rect.X, toolbar_rect.Y, toolbar_rect.GetRight(), toolbar_rect.GetBottom());
307 rcIcon.right = rcIcon.left + btn_size;
308
309 if (!bLocked)
310 {
311 DrawToolIcon(pGraphics, IconMgr::IconType::IT_App, rcIcon, BTN_APP);
312 rcIcon.MoveToX(rcIcon.right);
313 DrawToolIcon(pGraphics, IconMgr::IconType::IT_Stop, rcIcon, BTN_STOP);
314 rcIcon.MoveToX(rcIcon.right);
315 DrawToolIcon(pGraphics, IconMgr::IconType::IT_Previous, rcIcon, BTN_PREVIOUS);
316 rcIcon.MoveToX(rcIcon.right);
317 DrawToolIcon(pGraphics, CPlayer::GetInstance().IsPlaying() ? IconMgr::IconType::IT_Pause : IconMgr::IconType::IT_Play, rcIcon, BTN_PLAY_PAUSE);
318 rcIcon.MoveToX(rcIcon.right);
319 DrawToolIcon(pGraphics, IconMgr::IconType::IT_Next, rcIcon, BTN_NEXT);
320 rcIcon.MoveToX(rcIcon.right);
321 DrawToolIcon(pGraphics, IconMgr::IconType::IT_Setting, rcIcon, BTN_SETTING);
322 rcIcon.MoveToX(rcIcon.right);
323 DrawToolIcon(pGraphics, IconMgr::IconType::IT_Media_Lib, rcIcon, BTN_DEFAULT_STYLE);
324 rcIcon.MoveToX(rcIcon.right);
325 DrawToolIcon(pGraphics, IconMgr::IconType::IT_Triangle_Left, rcIcon, BTN_LYRIC_DELAY);
326 rcIcon.MoveToX(rcIcon.right);
327 DrawToolIcon(pGraphics, IconMgr::IconType::IT_Triangle_Right, rcIcon, BTN_LYRIC_FORWARD);
328 rcIcon.MoveToX(rcIcon.right);
329 DrawToolIcon(pGraphics, IconMgr::IconType::IT_Double_Line, rcIcon, BTN_DOUBLE_LINE, theApp.m_lyric_setting_data.desktop_lyric_data.lyric_double_line);
330 rcIcon.MoveToX(rcIcon.right);
331 DrawToolIcon(pGraphics, IconMgr::IconType::IT_Background, rcIcon, BTN_BACKGROUND_PENETRATE, theApp.m_lyric_setting_data.desktop_lyric_data.lyric_background_penetrate);
332 rcIcon.MoveToX(rcIcon.right);
333 DrawToolIcon(pGraphics, IconMgr::IconType::IT_Lock, rcIcon, BTN_LOCK);
334 rcIcon.MoveToX(rcIcon.right);
335 DrawToolIcon(pGraphics, IconMgr::IconType::IT_Cancel, rcIcon, BTN_CLOSE);
336
337 bool lyric_disable{ CPlayer::GetInstance().m_Lyrics.IsEmpty() || CPlayerUIHelper::IsMidiLyric() };
338 m_buttons[BTN_LYRIC_FORWARD].enable = !lyric_disable;
339 m_buttons[BTN_LYRIC_DELAY].enable = !lyric_disable;
340
341 }
342 else if (theApp.m_lyric_setting_data.desktop_lyric_data.show_unlock_when_locked) //如果处于锁定状态,只绘制一个解锁图标
343 {
344 for (auto& btn : m_buttons)
345 {
346 if (btn.first == BTN_LOCK)
347 DrawToolIcon(pGraphics, IconMgr::IconType::IT_Lock, rcIcon, BTN_LOCK);
348 else
349 btn.second = UIButton();
350 }
351 }
352 static bool last_locked = !bLocked;
353 if (last_locked != bLocked)
354 {
355 UpdateToolTipPosition();
356 last_locked = bLocked;
357 }
358 }
359
DrawToolIcon(Gdiplus::Graphics * pGraphics,IconMgr::IconType icon_type,CRect rect,BtnKey btn_key,bool checked)360 void CDesktopLyric::DrawToolIcon(Gdiplus::Graphics* pGraphics, IconMgr::IconType icon_type, CRect rect, BtnKey btn_key, bool checked)
361 {
362 rect.DeflateRect(theApp.DPI(2), theApp.DPI(2));
363 auto& btn = m_buttons[btn_key];
364 btn.rect = rect;
365
366 if (btn.pressed && btn.enable)
367 rect.MoveToXY(rect.left + theApp.DPI(1), rect.top + theApp.DPI(1));
368
369 Gdiplus::Color back_color;
370 bool draw_background = false;
371 if (btn.pressed && btn.hover)
372 {
373 back_color = CGdiPlusTool::COLORREFToGdiplusColor(theApp.m_app_setting_data.theme_color.dark1, 180);
374 draw_background = true;
375 }
376 else if (btn.hover)
377 {
378 back_color = CGdiPlusTool::COLORREFToGdiplusColor(theApp.m_app_setting_data.theme_color.light1, 180);
379 draw_background = true;
380 }
381 else if (checked)
382 {
383 back_color = CGdiPlusTool::COLORREFToGdiplusColor(theApp.m_app_setting_data.theme_color.light1, 110);
384 draw_background = true;
385 }
386 if (draw_background)
387 {
388 if (!theApp.m_app_setting_data.button_round_corners)
389 {
390 Gdiplus::SolidBrush brush(back_color);
391 pGraphics->FillRectangle(&brush, rect.left, rect.top, rect.Width(), rect.Height());
392 }
393 else
394 {
395 CDrawCommon drawer;
396 drawer.Create(nullptr, pGraphics);
397 drawer.DrawRoundRect(CGdiPlusTool::CRectToGdiplusRect(rect), back_color, theApp.DPI(4));
398 }
399 }
400
401 HICON hIcon = theApp.m_icon_mgr.GetHICON(icon_type, IconMgr::IconStyle::IS_Filled, IconMgr::IconSize::IS_DPI_16);
402 CSize icon_size = IconMgr::GetIconSize(IconMgr::IconSize::IS_DPI_16);
403
404 CRect rc_tmp = rect;
405 //使图标在矩形中居中
406 rc_tmp.left = rect.left + (rect.Width() - icon_size.cx) / 2;
407 rc_tmp.top = rect.top + (rect.Height() - icon_size.cy) / 2;
408 rc_tmp.right = rc_tmp.left + icon_size.cx;
409 rc_tmp.bottom = rc_tmp.top + icon_size.cy;
410
411 HDC hDC = pGraphics->GetHDC();
412 CDrawCommon drawer;
413 drawer.Create(CDC::FromHandle(hDC));
414 drawer.DrawIcon(hIcon, rc_tmp.TopLeft(), rc_tmp.Size());
415 pGraphics->ReleaseHDC(hDC);
416 }
417
AddToolTips()418 void CDesktopLyric::AddToolTips()
419 {
420 wstring tip_str;
421 AddMouseToolTip(BTN_APP, theApp.m_str_table.LoadText(L"UI_TIP_BTN_MAIN_MENU").c_str());
422 AddMouseToolTip(BTN_STOP, theApp.m_str_table.LoadText(L"UI_TIP_BTN_STOP").c_str());
423 AddMouseToolTip(BTN_PREVIOUS, theApp.m_str_table.LoadText(L"UI_TIP_BTN_PREVIOUS").c_str());
424 AddMouseToolTip(BTN_PLAY_PAUSE, theApp.m_str_table.LoadText(L"UI_TIP_BTN_PLAY_PAUSE").c_str());
425 AddMouseToolTip(BTN_NEXT, theApp.m_str_table.LoadText(L"UI_TIP_BTN_NEXT").c_str());
426 AddMouseToolTip(BTN_SETTING, theApp.m_str_table.LoadText(L"UI_TIP_BTN_OPTION_SETTING").c_str());
427 tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_DESKTOP_LYRIC_FORWARD");
428 AddMouseToolTip(BTN_LYRIC_FORWARD, tip_str.c_str());
429 tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_DESKTOP_LYRIC_DELAY");
430 AddMouseToolTip(BTN_LYRIC_DELAY, tip_str.c_str());
431 tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_DESKTOP_LYRIC_DEFAULT_STYLE");
432 AddMouseToolTip(BTN_DEFAULT_STYLE, tip_str.c_str());
433 tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_DESKTOP_LYRIC_DOUBLE_LINE");
434 AddMouseToolTip(BTN_DOUBLE_LINE, tip_str.c_str());
435 tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_DESKTOP_LYRIC_BACKGROUND_PENETRATE");
436 AddMouseToolTip(BTN_BACKGROUND_PENETRATE, tip_str.c_str());
437 if (theApp.m_lyric_setting_data.desktop_lyric_data.lock_desktop_lyric)
438 tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_DESKTOP_LYRIC_UNLOCK");
439 else
440 tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_DESKTOP_LYRIC_LOCK");
441 AddMouseToolTip(BTN_LOCK, tip_str.c_str());
442 tip_str = theApp.m_str_table.LoadText(L"UI_TIP_BTN_DESKTOP_LYRIC_CLOSE");
443 AddMouseToolTip(BTN_CLOSE, tip_str.c_str());
444
445 m_tool_tip.SetWindowPos(&CWnd::wndTopMost, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
446 }
447
AddMouseToolTip(BtnKey btn,LPCTSTR str)448 void CDesktopLyric::AddMouseToolTip(BtnKey btn, LPCTSTR str)
449 {
450 CRect rcBtn = m_buttons[btn].rect;
451 rcBtn.MoveToX(rcBtn.left - m_frameSize.cx);
452 rcBtn.MoveToY(rcBtn.top - m_frameSize.cy);
453 m_tool_tip.AddTool(this, str, rcBtn, btn + 1000);
454
455 }
456
UpdateMouseToolTip(BtnKey btn,LPCTSTR str)457 void CDesktopLyric::UpdateMouseToolTip(BtnKey btn, LPCTSTR str)
458 {
459 m_tool_tip.UpdateTipText(str, this, btn + 1000);
460 }
461
UpdateToolTipPosition()462 void CDesktopLyric::UpdateToolTipPosition()
463 {
464 for (const auto& btn : m_buttons)
465 {
466 CRect rcBtn = btn.second.rect;
467 rcBtn.MoveToX(rcBtn.left - m_frameSize.cx);
468 rcBtn.MoveToY(rcBtn.top - m_frameSize.cy);
469 m_tool_tip.SetToolRect(this, btn.first + 1000, rcBtn);
470 }
471 }
472
473
PreDrawLyric(Gdiplus::Graphics * pGraphics,Gdiplus::Font * pFont)474 void CDesktopLyric::PreDrawLyric(Gdiplus::Graphics* pGraphics, Gdiplus::Font* pFont)
475 {
476 // 获取歌词信息
477 UpdateLyric(pGraphics, pFont);
478
479 //绘制半透明背景
480 if (!m_bLocked && !m_lyricBackgroundPenetrate)
481 {
482 BYTE alpha = (m_bHover) ? 80 : 1;
483 Gdiplus::Brush* pBrush = new Gdiplus::SolidBrush(Gdiplus::Color(alpha, 255, 255, 255));
484 pGraphics->FillRectangle(pBrush, 0, 0, m_rcWindow.Width(), m_rcWindow.Height());
485 delete pBrush;
486 }
487 }
488
AfterDrawLyric(Gdiplus::Graphics * pGraphics)489 void CDesktopLyric::AfterDrawLyric(Gdiplus::Graphics* pGraphics)
490 {
491 //绘制工具条
492 bool bLocked = theApp.m_lyric_setting_data.desktop_lyric_data.lock_desktop_lyric;
493 if (m_lyricBackgroundPenetrate || m_bLocked ? m_bMouseInWindowRect : m_bHover)
494 {
495 DrawToolbar(pGraphics);
496
497 if (m_first_draw)
498 {
499 AddToolTips();
500 m_first_draw = false;
501 }
502 }
503 }
504
SetWindowStyle()505 void CDesktopLyric::SetWindowStyle()
506 {
507 if (m_bLocked)
508 ModifyStyleEx(NULL, WS_EX_TRANSPARENT);
509 else
510 ModifyStyleEx(WS_EX_TRANSPARENT, NULL);
511
512 if (m_bLocked || m_lyricBackgroundPenetrate)
513 ModifyStyle(WS_THICKFRAME, NULL);
514 else
515 ModifyStyle(NULL, WS_THICKFRAME);
516 }
517
OnLButtonDown(UINT nFlags,CPoint point)518 void CDesktopLyric::OnLButtonDown(UINT nFlags, CPoint point)
519 {
520 CPoint point1 = point;
521 point1.x += m_frameSize.cx;
522 point1.y += m_frameSize.cy;
523
524 bool point_in_btns = false;
525 for (auto& btn : m_buttons)
526 {
527 if (btn.second.enable && btn.second.rect.PtInRect(point1) != FALSE)
528 {
529 btn.second.pressed = true;
530 point_in_btns = true;
531 }
532 }
533 if (!point_in_btns)
534 PostMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point1.x, point1.y));
535
536 CLyricsWindow::OnLButtonDown(nFlags, point);
537 }
538
OnLButtonUp(UINT nFlags,CPoint point)539 void CDesktopLyric::OnLButtonUp(UINT nFlags, CPoint point)
540 {
541 // TODO: 在此添加消息处理程序代码和/或调用默认值
542 CPoint point1 = point;
543 point1.x += m_frameSize.cx;
544 point1.y += m_frameSize.cy;
545
546 for (auto& btn : m_buttons)
547 {
548 btn.second.pressed = false;
549
550 if (btn.second.rect.PtInRect(point1) && btn.second.enable)
551 {
552 switch (btn.first)
553 {
554 case BTN_APP:
555 {
556 CPoint cur_point;
557 GetCursorPos(&cur_point);
558 m_bMenuPopedUp = true;
559 theApp.m_menu_mgr.GetMenu(MenuMgr::MainPopupMenu)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, cur_point.x, cur_point.y, this);
560 m_bMenuPopedUp = false;
561 }
562 return;
563
564 case BTN_STOP:
565 theApp.m_pMainWnd->SendMessage(WM_COMMAND, ID_STOP);
566 return;
567
568 case BTN_PREVIOUS:
569 theApp.m_pMainWnd->SendMessage(WM_COMMAND, ID_PREVIOUS);
570 return;
571 case BTN_PLAY_PAUSE:
572 theApp.m_pMainWnd->SendMessage(WM_COMMAND, ID_PLAY_PAUSE);
573 return;
574
575 case BTN_NEXT:
576 theApp.m_pMainWnd->SendMessage(WM_COMMAND, ID_NEXT);
577 return;
578
579 case BTN_SETTING:
580 theApp.m_pMainWnd->SendMessage(WM_OPTION_SETTINGS, 0, 0);
581 return;
582
583 case BTN_LYRIC_FORWARD:
584 theApp.m_pMainWnd->SendMessage(WM_COMMAND, ID_LYRIC_FORWARD, 0);
585 return;
586
587 case BTN_LYRIC_DELAY:
588 theApp.m_pMainWnd->SendMessage(WM_COMMAND, ID_LYRIC_DELAY, 0);
589 return;
590
591 case BTN_DEFAULT_STYLE:
592 {
593 CPoint cur_point;
594 cur_point.x = m_buttons[BTN_DEFAULT_STYLE].rect.left - m_frameSize.cx;
595 cur_point.y = m_buttons[BTN_DEFAULT_STYLE].rect.bottom - m_frameSize.cy;
596 ClientToScreen(&cur_point);
597 m_bMenuPopedUp = true;
598 CMenu* pMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::DlrcDefMenu);
599 if (pMenu != nullptr)
600 pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, cur_point.x, cur_point.y, this);
601 m_bMenuPopedUp = false;
602 }
603 return;
604
605 case BTN_DOUBLE_LINE:
606 theApp.m_pMainWnd->SendMessage(WM_COMMAND, ID_LYRIC_DISPLAYED_DOUBLE_LINE);
607 return;
608
609 case BTN_BACKGROUND_PENETRATE:
610 theApp.m_pMainWnd->SendMessage(WM_COMMAND, ID_LYRIC_BACKGROUND_PENETRATE);
611 return;
612
613 case BTN_LOCK:
614 theApp.m_pMainWnd->SendMessage(WM_COMMAND, ID_LOCK_DESKTOP_LRYIC);
615 btn.second.hover = false;
616 return;
617
618 case BTN_CLOSE:
619 theApp.m_pMainWnd->SendMessage(WM_COMMAND, ID_CLOSE_DESKTOP_LYRIC);
620 return;
621
622 default:
623 break;
624 }
625 }
626 }
627
628 CLyricsWindow::OnLButtonUp(nFlags, point);
629 }
630
631
OnMouseMove(UINT nFlags,CPoint point)632 void CDesktopLyric::OnMouseMove(UINT nFlags, CPoint point)
633 {
634 // TODO: 在此添加消息处理程序代码和/或调用默认值
635 CPoint point1 = point;
636 point1.x += m_frameSize.cx;
637 point1.y += m_frameSize.cy;
638 for (auto& btn : m_buttons)
639 {
640 if (btn.second.enable)
641 btn.second.hover = (btn.second.rect.PtInRect(point1) != FALSE);
642 }
643
644 TRACKMOUSEEVENT tme;
645 tme.cbSize = sizeof(tme);
646 tme.hwndTrack = m_hWnd;
647 tme.dwFlags = TME_LEAVE | TME_HOVER;
648 tme.dwHoverTime = 1;
649 _TrackMouseEvent(&tme);
650
651 CLyricsWindow::OnMouseMove(nFlags, point);
652 }
653
654
OnMouseHover(UINT nFlags,CPoint point)655 void CDesktopLyric::OnMouseHover(UINT nFlags, CPoint point)
656 {
657 // TODO: 在此添加消息处理程序代码和/或调用默认值
658 if (!m_bHover)
659 {
660 m_bHover = true;
661 //Invalidate();
662 }
663 else
664 {
665 CLyricsWindow::OnMouseHover(nFlags, point);
666 }
667 }
668
669
OnMouseLeave()670 void CDesktopLyric::OnMouseLeave()
671 {
672 // TODO: 在此添加消息处理程序代码和/或调用默认值
673 if (!m_bMenuPopedUp)
674 {
675 m_bHover = false;
676 //Invalidate();
677 for (auto& btn : m_buttons)
678 {
679 btn.second.pressed = false;
680 btn.second.hover = false;
681 }
682 }
683
684 CLyricsWindow::OnMouseLeave();
685 }
686
687
OnSizing(UINT fwSide,LPRECT pRect)688 void CDesktopLyric::OnSizing(UINT fwSide, LPRECT pRect)
689 {
690 CLyricsWindow::OnSizing(fwSide, pRect);
691
692 // TODO: 在此处添加消息处理程序代码
693 m_bHover = true;
694 UpdateToolTipPosition();
695 }
696
697
OnRButtonUp(UINT nFlags,CPoint point)698 void CDesktopLyric::OnRButtonUp(UINT nFlags, CPoint point)
699 {
700 // TODO: 在此添加消息处理程序代码和/或调用默认值
701 m_bMenuPopedUp = true;
702 CPoint point1; //定义一个用于确定光标位置的位置
703 GetCursorPos(&point1); //获取当前光标的位置,以便使得菜单可以跟随光标,该位置以屏幕左上角点为原点,point则以客户区左上角为原点
704 CMenu* pMenu = theApp.m_menu_mgr.GetMenu(MenuMgr::DlrcMenu);
705 if (pMenu != NULL)
706 pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point1.x, point1.y, this);
707 m_bMenuPopedUp = false;
708 //CLyricsWindow::OnRButtonUp(nFlags, point);
709 }
710
711
OnCommand(WPARAM wParam,LPARAM lParam)712 BOOL CDesktopLyric::OnCommand(WPARAM wParam, LPARAM lParam)
713 {
714 // TODO: 在此添加专用代码和/或调用基类
715 WORD command = LOWORD(wParam);
716 if (CCommon::IsMenuItemInMenu(theApp.m_menu_mgr.GetMenu(MenuMgr::DlrcMenu), command)
717 || CCommon::IsMenuItemInMenu(theApp.m_menu_mgr.GetMenu(MenuMgr::MainPopupMenu), command))
718 AfxGetMainWnd()->SendMessage(WM_COMMAND, wParam, lParam); //将未处理的菜单命令转发到主窗口
719
720 return CLyricsWindow::OnCommand(wParam, lParam);
721 }
722
723
OnGetMinMaxInfo(MINMAXINFO * lpMMI)724 void CDesktopLyric::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
725 {
726 // TODO: 在此添加消息处理程序代码和/或调用默认值
727 lpMMI->ptMinTrackSize.x = theApp.DPI(400);
728 lpMMI->ptMinTrackSize.y = theApp.DPI(100);
729
730 CLyricsWindow::OnGetMinMaxInfo(lpMMI);
731 }
732
733
PreTranslateMessage(MSG * pMsg)734 BOOL CDesktopLyric::PreTranslateMessage(MSG* pMsg)
735 {
736 // TODO: 在此添加专用代码和/或调用基类
737 if (pMsg->message == WM_MOUSEMOVE)
738 m_tool_tip.RelayEvent(pMsg);
739
740 if (pMsg->message == WM_MOUSEWHEEL) // 将滚轮消息转发给主窗口处理音量调整
741 {
742 CWnd* pMainWnd = AfxGetMainWnd();
743 if (pMainWnd)
744 {
745 POINT pt = { INT16_MAX, INT16_MAX }; // 修改pt参数为一个特殊值
746 LPARAM lParam = MAKELPARAM(pt.x, pt.y);
747 pMainWnd->SendMessage(WM_MOUSEWHEEL, pMsg->wParam, lParam);
748 return TRUE;
749 }
750 }
751
752 return CLyricsWindow::PreTranslateMessage(pMsg);
753 }
754
755
OnTimer(UINT_PTR nIDEvent)756 void CDesktopLyric::OnTimer(UINT_PTR nIDEvent)
757 {
758 // TODO: 在此添加消息处理程序代码和/或调用默认值
759 if (nIDEvent == TIMER_DESKTOP_LYRIC)
760 {
761 CPoint point;
762 GetCursorPos(&point);
763 m_bMouseInWindowRect = m_rcWindow.PtInRect(point);
764
765 bool bLocked = theApp.m_lyric_setting_data.desktop_lyric_data.lock_desktop_lyric;
766 if (bLocked && theApp.m_lyric_setting_data.desktop_lyric_data.show_unlock_when_locked) //处于锁定状态时,如果指针处于“锁定”按钮区域内,则取消鼠标穿透状态,以使得“锁定”按钮可以点击
767 {
768 CRect rcLockBtn = m_buttons[BTN_LOCK].rect;
769 rcLockBtn.MoveToX(rcLockBtn.left + m_rcWindow.left);
770 rcLockBtn.MoveToY(rcLockBtn.top + m_rcWindow.top);
771 if (rcLockBtn.PtInRect(point))
772 {
773 SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE, GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE) & (~WS_EX_TRANSPARENT)); //取消鼠标穿透
774 m_buttons[BTN_LOCK].hover = true;
775 }
776 else
777 {
778 SetWindowLong(GetSafeHwnd(), GWL_EXSTYLE, GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE) | WS_EX_TRANSPARENT); //设置鼠标穿透
779 m_buttons[BTN_LOCK].hover = false;
780 }
781 }
782 }
783 else if (nIDEvent == TIMER_DESKTOP_LYRIC_2)
784 {
785 KillTimer(TIMER_DESKTOP_LYRIC_2);
786 SetWindowStyle();
787 }
788
789 CLyricsWindow::OnTimer(nIDEvent);
790 }
791
792
OnLyricDefaultStyle1()793 void CDesktopLyric::OnLyricDefaultStyle1()
794 {
795 // TODO: 在此添加命令处理程序代码
796 auto style = GetDefaultStyle(0);
797 LyricStyleDefaultDataToLyricSettingData(style, theApp.m_lyric_setting_data.desktop_lyric_data);
798 ApplySettings(theApp.m_lyric_setting_data.desktop_lyric_data);
799 }
800
801
OnLyricDefaultStyle2()802 void CDesktopLyric::OnLyricDefaultStyle2()
803 {
804 // TODO: 在此添加命令处理程序代码
805 auto style = GetDefaultStyle(1);
806 LyricStyleDefaultDataToLyricSettingData(style, theApp.m_lyric_setting_data.desktop_lyric_data);
807 ApplySettings(theApp.m_lyric_setting_data.desktop_lyric_data);
808 }
809
810
OnLyricDefaultStyle3()811 void CDesktopLyric::OnLyricDefaultStyle3()
812 {
813 // TODO: 在此添加命令处理程序代码
814 auto style = GetDefaultStyle(2);
815 LyricStyleDefaultDataToLyricSettingData(style, theApp.m_lyric_setting_data.desktop_lyric_data);
816 ApplySettings(theApp.m_lyric_setting_data.desktop_lyric_data);
817 }
818
819
OnLButtonDblClk(UINT nFlags,CPoint point)820 void CDesktopLyric::OnLButtonDblClk(UINT nFlags, CPoint point)
821 {
822 // TODO: 在此添加消息处理程序代码和/或调用默认值
823 AfxGetMainWnd()->SendMessage(WM_COMMAND, ID_SHOW_MAIN_WINDOW);
824
825 CLyricsWindow::OnLButtonDblClk(nFlags, point);
826 }
827
828
OnInitMenu(CMenu * pMenu)829 void CDesktopLyric::OnInitMenu(CMenu* pMenu)
830 {
831 CLyricsWindow::OnInitMenu(pMenu);
832
833 // TODO: 在此处添加消息处理程序代码
834 CMusicPlayerDlg* pPlayerDlg = dynamic_cast<CMusicPlayerDlg*>(AfxGetMainWnd());
835 if (pPlayerDlg != nullptr)
836 pPlayerDlg->SetMenuState(pMenu);
837 pMenu->SetDefaultItem(ID_SHOW_MAIN_WINDOW);
838 }
839