xref: /MusicPlayer2/MusicPlayer2/DesktopLyric.cpp (revision b6e722e330e53ac296201165ee987d41e56fd133)
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