1877f5f92SZhongYang // LyricsWindow.cpp : 实现文件 2b1f2b024SZhong Yang // 3b1f2b024SZhong Yang 4b1f2b024SZhong Yang #include "stdafx.h" 5b1f2b024SZhong Yang #include "LyricsWindow.h" 6b1f2b024SZhong Yang 7b1f2b024SZhong Yang // CLyricsWindow 8b1f2b024SZhong Yang 9877f5f92SZhongYang const Gdiplus::REAL TRANSLATE_FONT_SIZE_FACTOR = 0.88f; //歌词翻译文本大小占歌词文本大小的比例 102256f4d4SZhong Yang 11b1f2b024SZhong Yang IMPLEMENT_DYNAMIC(CLyricsWindow, CWnd) 12b1f2b024SZhong Yang 13b1f2b024SZhong Yang CLyricsWindow::CLyricsWindow() 14b1f2b024SZhong Yang { 15b1f2b024SZhong Yang HDC hDC=::GetDC(NULL); 16b1f2b024SZhong Yang m_hCacheDC=::CreateCompatibleDC(hDC); 17b1f2b024SZhong Yang ::ReleaseDC(NULL,hDC); 18b1f2b024SZhong Yang //--------------------------------- 19877f5f92SZhongYang m_nHighlight=NULL ; //高亮歌词的百分比 0--100 20877f5f92SZhongYang m_TextGradientMode=LyricsGradientMode_Two ; //普通歌词渐变模式 21877f5f92SZhongYang m_pTextPen=NULL ; //普通歌词边框画笔 22877f5f92SZhongYang m_HighlightGradientMode=LyricsGradientMode_Two ; //高亮歌词渐变模式 23877f5f92SZhongYang m_pHighlightPen=NULL ; //高亮歌词边框画笔 24877f5f92SZhongYang m_pShadowBrush=NULL ; //阴影画刷,GDIPlus画刷 25877f5f92SZhongYang m_nShadowOffset=1 ; //阴影偏移 26877f5f92SZhongYang m_pFont=NULL ; //GDIPlus字体 27b1f2b024SZhong Yang m_FontStyle=NULL ; 28b1f2b024SZhong Yang m_FontSize=NULL ; 29b1f2b024SZhong Yang m_pTextFormat=NULL; 30b1f2b024SZhong Yang //--------------------------------- 31b1f2b024SZhong Yang m_pFontFamily=new Gdiplus::FontFamily(); 32b1f2b024SZhong Yang m_pTextFormat=new Gdiplus::StringFormat(); 33877f5f92SZhongYang m_pTextFormat->SetFormatFlags(Gdiplus::StringFormatFlagsNoWrap);//不换行 34877f5f92SZhongYang m_pTextFormat->SetAlignment(Gdiplus::StringAlignmentCenter); //置水平对齐方式 35877f5f92SZhongYang m_pTextFormat->SetLineAlignment(Gdiplus::StringAlignmentNear); //置垂直对齐方式 36b1f2b024SZhong Yang //--------------------------------- 37877f5f92SZhongYang //SetLyricsFont(L"微软雅黑", 40, Gdiplus::FontStyle::FontStyleRegular); 3854359200SZhong Yang //SetLyricsColor(Gdiplus::Color::Red,Gdiplus::Color(255,172,0),LyricsGradientMode_Three); 39b1f2b024SZhong Yang //SetLyricsBorder(Gdiplus::Color::Black,1); 4054359200SZhong Yang SetLyricsShadow(Gdiplus::Color(150,0,0,0),1); 4154359200SZhong Yang //SetHighlightColor(Gdiplus::Color(255,100,26),Gdiplus::Color(255,255,0),LyricsGradientMode_Three); 42b1f2b024SZhong Yang //SetHighlightBorder(Gdiplus::Color::Black,1); 43b1f2b024SZhong Yang 44b1f2b024SZhong Yang } 45b1f2b024SZhong Yang 46b1f2b024SZhong Yang CLyricsWindow::~CLyricsWindow() 47b1f2b024SZhong Yang { 48b1f2b024SZhong Yang if(m_pTextPen){ 49b1f2b024SZhong Yang delete m_pTextPen; 50b1f2b024SZhong Yang m_pTextPen=NULL; 51b1f2b024SZhong Yang } 52b1f2b024SZhong Yang if(m_pHighlightPen){ 53b1f2b024SZhong Yang delete m_pHighlightPen; 54b1f2b024SZhong Yang m_pHighlightPen=NULL; 55b1f2b024SZhong Yang } 56b1f2b024SZhong Yang if(m_pShadowBrush){ 57b1f2b024SZhong Yang delete m_pShadowBrush; 58b1f2b024SZhong Yang m_pShadowBrush=NULL; 59b1f2b024SZhong Yang } 60b1f2b024SZhong Yang if(m_pFontFamily){ 61b1f2b024SZhong Yang delete m_pFontFamily; 62b1f2b024SZhong Yang m_pFontFamily=NULL; 63b1f2b024SZhong Yang } 64b1f2b024SZhong Yang if(m_pTextFormat){ 65b1f2b024SZhong Yang delete m_pTextFormat; 66b1f2b024SZhong Yang m_pTextFormat=NULL; 67b1f2b024SZhong Yang } 68b1f2b024SZhong Yang if(m_pFont){ 69b1f2b024SZhong Yang delete m_pFont; 70b1f2b024SZhong Yang m_pFont=NULL; 71b1f2b024SZhong Yang } 72b1f2b024SZhong Yang } 73b1f2b024SZhong Yang 74b1f2b024SZhong Yang 75b1f2b024SZhong Yang BEGIN_MESSAGE_MAP(CLyricsWindow, CWnd) 76b1f2b024SZhong Yang ON_WM_LBUTTONDOWN() 77b1f2b024SZhong Yang END_MESSAGE_MAP() 78b1f2b024SZhong Yang 79b1f2b024SZhong Yang 80b1f2b024SZhong Yang 812256f4d4SZhong Yang BOOL CLyricsWindow::Create(int nHeight) 82b1f2b024SZhong Yang { 832256f4d4SZhong Yang return CLyricsWindow::Create(_T("CometLyricsWindow"), -1, nHeight); 84b1f2b024SZhong Yang } 85b1f2b024SZhong Yang BOOL CLyricsWindow::Create(LPCTSTR lpszClassName) 86b1f2b024SZhong Yang { 87b1f2b024SZhong Yang return CLyricsWindow::Create(lpszClassName,-1,-1); 88b1f2b024SZhong Yang } 89b1f2b024SZhong Yang BOOL CLyricsWindow::Create(LPCTSTR lpszClassName,int nWidth,int nHeight) 90b1f2b024SZhong Yang { 91b1f2b024SZhong Yang if(!RegisterWndClass(lpszClassName)) 92b1f2b024SZhong Yang { 93877f5f92SZhongYang TRACE("Class Registration Failedn"); 94b1f2b024SZhong Yang } 95c45e940bSzhongyang 96b1f2b024SZhong Yang //-------------------------------------------- 97877f5f92SZhongYang //取出桌面工作区域 98b1f2b024SZhong Yang RECT rcWork; 99b1f2b024SZhong Yang SystemParametersInfo (SPI_GETWORKAREA,NULL,&rcWork,NULL); 100b1f2b024SZhong Yang int nWorkWidth=rcWork.right-rcWork.left; 101b1f2b024SZhong Yang int nWorkHeight=rcWork.bottom-rcWork.top; 102877f5f92SZhongYang //未传递宽度、高度参数时设置个默认值 103877f5f92SZhongYang if(nWidth<0)nWidth=nWorkWidth*2/3; //默认宽度为桌面宽度的2/3 104b1f2b024SZhong Yang if(nHeight<0)nHeight=150; 105877f5f92SZhongYang //设置左边、顶边位置,让窗口在屏幕下方 106b1f2b024SZhong Yang int x=rcWork.left+( (nWorkWidth-nWidth)/2 ); 107b1f2b024SZhong Yang int y=rcWork.bottom-nHeight; 108b1f2b024SZhong Yang //-------------------------------------------- 109c7bf0801Szhongyang DWORD dwStyle=WS_POPUP|WS_VISIBLE|WS_THICKFRAME; 110b1f2b024SZhong Yang DWORD dwExStyle=WS_EX_TOOLWINDOW|WS_EX_TOPMOST|WS_EX_LAYERED; 1118735f040SZhong Yang BOOL rtn = CWnd::CreateEx(dwExStyle, lpszClassName, NULL, dwStyle, x, y, nWidth, nHeight, NULL, NULL); 112a8b024cfSZhong Yang 1138735f040SZhong Yang return rtn; 114b1f2b024SZhong Yang } 115b1f2b024SZhong Yang BOOL CLyricsWindow::RegisterWndClass(LPCTSTR lpszClassName) 116b1f2b024SZhong Yang { 117b1f2b024SZhong Yang HINSTANCE hInstance=AfxGetInstanceHandle(); 118b1f2b024SZhong Yang WNDCLASSEX wndcls; 119b1f2b024SZhong Yang memset(&wndcls,0,sizeof(WNDCLASSEX)); 120b1f2b024SZhong Yang wndcls.cbSize=sizeof(WNDCLASSEX); 121b1f2b024SZhong Yang if(GetClassInfoEx(hInstance,lpszClassName,&wndcls)) 122b1f2b024SZhong Yang { 123b1f2b024SZhong Yang return TRUE; 124b1f2b024SZhong Yang } 125b1f2b024SZhong Yang if(GetClassInfoEx(NULL,lpszClassName,&wndcls)) 126b1f2b024SZhong Yang { 127b1f2b024SZhong Yang return TRUE; 128b1f2b024SZhong Yang } 129b1f2b024SZhong Yang 130b1f2b024SZhong Yang wndcls.style=CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW; 131b1f2b024SZhong Yang wndcls.lpfnWndProc=::DefWindowProc; 132b1f2b024SZhong Yang wndcls.hInstance=hInstance; 133b1f2b024SZhong Yang wndcls.hIcon=NULL; 134b1f2b024SZhong Yang wndcls.hCursor=::LoadCursor(NULL,IDC_ARROW); 135b1f2b024SZhong Yang wndcls.hbrBackground=(HBRUSH)(COLOR_BTNFACE+1); 136b1f2b024SZhong Yang wndcls.lpszMenuName=NULL; 137b1f2b024SZhong Yang wndcls.lpszClassName=lpszClassName; 138b1f2b024SZhong Yang if(!RegisterClassEx(&wndcls)) 139b1f2b024SZhong Yang { 140b1f2b024SZhong Yang return FALSE; 141b1f2b024SZhong Yang } 142b1f2b024SZhong Yang return TRUE; 143b1f2b024SZhong Yang } 144b1f2b024SZhong Yang 145b1f2b024SZhong Yang 1465c2d48a1Slrisora //更新歌词(进度符号,歌词文本,高亮进度百分比,是否为进度符号高亮) 1475c2d48a1Slrisora void CLyricsWindow::UpdateLyrics(LPCTSTR lpszBeforeLyrics, LPCTSTR lpszLyrics, int nHighlight, bool bBeforeLyrics) 1485c2d48a1Slrisora { 1495c2d48a1Slrisora m_lpszBeforeLyrics = lpszBeforeLyrics; 1505c2d48a1Slrisora m_bBeforeLyrics = bBeforeLyrics; 1515c2d48a1Slrisora m_lpszLyrics = lpszLyrics; 1525c2d48a1Slrisora UpdateLyrics(nHighlight); 1535c2d48a1Slrisora } 154877f5f92SZhongYang //更新歌词(歌词文本,高亮进度百分比) 155be1c6be2Szhongyang void CLyricsWindow::UpdateLyrics(LPCTSTR lpszLyrics,int nHighlight) 156b1f2b024SZhong Yang { 1575c2d48a1Slrisora m_lpszBeforeLyrics.Empty(); 1585c2d48a1Slrisora m_bBeforeLyrics = false; 159be1c6be2Szhongyang m_lpszLyrics = lpszLyrics; 160b1f2b024SZhong Yang UpdateLyrics(nHighlight); 161b1f2b024SZhong Yang } 162877f5f92SZhongYang //更新高亮进度(高亮进度百分比) 163b1f2b024SZhong Yang void CLyricsWindow::UpdateLyrics(int nHighlight) 164b1f2b024SZhong Yang { 165b1f2b024SZhong Yang m_nHighlight=nHighlight; 166b1f2b024SZhong Yang if(m_nHighlight<0) 167b1f2b024SZhong Yang m_nHighlight=0; 168b1f2b024SZhong Yang if(m_nHighlight>1000) 169b1f2b024SZhong Yang m_nHighlight=1000; 170b1f2b024SZhong Yang Draw(); 171b1f2b024SZhong Yang } 1722256f4d4SZhong Yang 1732256f4d4SZhong Yang void CLyricsWindow::UpdateLyricTranslate(LPCTSTR lpszLyricTranslate) 1742256f4d4SZhong Yang { 1752256f4d4SZhong Yang m_strTranslate = lpszLyricTranslate; 1762256f4d4SZhong Yang } 1772256f4d4SZhong Yang 178877f5f92SZhongYang //重画歌词窗口 179b1f2b024SZhong Yang void CLyricsWindow::Draw() 180b1f2b024SZhong Yang { 1818735f040SZhong Yang //CRect rcWindow; 1828735f040SZhong Yang GetWindowRect(m_rcWindow); 1838735f040SZhong Yang m_nWidth= m_rcWindow.Width(); 1848735f040SZhong Yang m_nHeight= m_rcWindow.Height(); 185b1f2b024SZhong Yang CRect rcClient; 186a8b024cfSZhong Yang GetClientRect(rcClient); 1878735f040SZhong Yang m_frameSize.cx = (m_rcWindow.Width() - rcClient.Width()) / 2; 1888735f040SZhong Yang m_frameSize.cy = (m_rcWindow.Height() - rcClient.Height()) / 2; 189a8b024cfSZhong Yang 190b1f2b024SZhong Yang //---------------------------------- 191b1f2b024SZhong Yang BITMAPINFO bitmapinfo; 192b1f2b024SZhong Yang bitmapinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 193b1f2b024SZhong Yang bitmapinfo.bmiHeader.biBitCount = 32; 194b1f2b024SZhong Yang bitmapinfo.bmiHeader.biHeight = m_nHeight; 195b1f2b024SZhong Yang bitmapinfo.bmiHeader.biWidth = m_nWidth; 196b1f2b024SZhong Yang bitmapinfo.bmiHeader.biPlanes = 1; 197b1f2b024SZhong Yang bitmapinfo.bmiHeader.biCompression=BI_RGB; 198b1f2b024SZhong Yang bitmapinfo.bmiHeader.biXPelsPerMeter=0; 199b1f2b024SZhong Yang bitmapinfo.bmiHeader.biYPelsPerMeter=0; 200b1f2b024SZhong Yang bitmapinfo.bmiHeader.biClrUsed=0; 201b1f2b024SZhong Yang bitmapinfo.bmiHeader.biClrImportant=0; 202b1f2b024SZhong Yang bitmapinfo.bmiHeader.biSizeImage = bitmapinfo.bmiHeader.biWidth * bitmapinfo.bmiHeader.biHeight * bitmapinfo.bmiHeader.biBitCount / 8; 203b1f2b024SZhong Yang HBITMAP hBitmap=CreateDIBSection (m_hCacheDC,&bitmapinfo, 0,NULL, 0, 0); 204b1f2b024SZhong Yang HBITMAP hOldBitmap = (HBITMAP)SelectObject (m_hCacheDC,hBitmap); 205b1f2b024SZhong Yang //---------------------------------- 206b1f2b024SZhong Yang Gdiplus::Graphics* pGraphics=new Gdiplus::Graphics(m_hCacheDC); 207b1f2b024SZhong Yang pGraphics->SetSmoothingMode (Gdiplus::SmoothingModeAntiAlias); 208b1f2b024SZhong Yang pGraphics->SetTextRenderingHint (Gdiplus::TextRenderingHintAntiAlias); 20932f06d7fSZhong Yang 210873885c9Szhongyang PreDrawLyric(pGraphics); 21183f8cda3SZhong Yang bool bDrawTranslate = m_bShowTranslate && !m_strTranslate.IsEmpty(); 21283f8cda3SZhong Yang if (m_bDoubleLine && !m_strNextLyric.IsEmpty() && !bDrawTranslate) 213b6d5f9dcSzhongyang DrawLyricsDoubleLine(pGraphics); 214b6d5f9dcSzhongyang else 215b1f2b024SZhong Yang DrawLyrics(pGraphics); 216873885c9Szhongyang AfterDrawLyric(pGraphics); 217b7f299bfSzhongyang 218b1f2b024SZhong Yang delete pGraphics; 219b1f2b024SZhong Yang //---------------------------------- 220877f5f92SZhongYang //设置透明窗口 221b1f2b024SZhong Yang CPoint DestPt(0,0); 222b1f2b024SZhong Yang CSize psize(m_nWidth,m_nHeight); 223b1f2b024SZhong Yang BLENDFUNCTION blendFunc32bpp; 224b1f2b024SZhong Yang blendFunc32bpp.AlphaFormat = AC_SRC_ALPHA; 225b1f2b024SZhong Yang blendFunc32bpp.BlendFlags = 0; 226b1f2b024SZhong Yang blendFunc32bpp.BlendOp = AC_SRC_OVER; 227be1c6be2Szhongyang blendFunc32bpp.SourceConstantAlpha = m_alpha; 228b1f2b024SZhong Yang HDC hDC=::GetDC(m_hWnd); 229b1f2b024SZhong Yang ::UpdateLayeredWindow(m_hWnd,hDC,NULL,&psize,m_hCacheDC,&DestPt,0,&blendFunc32bpp,ULW_ALPHA); 230b1f2b024SZhong Yang //---------------------------------- 231877f5f92SZhongYang //释放资源 232b1f2b024SZhong Yang ::SelectObject (m_hCacheDC,hOldBitmap); 233b1f2b024SZhong Yang ::DeleteObject(hBitmap); 234b1f2b024SZhong Yang ::ReleaseDC(m_hWnd,hDC); 235b1f2b024SZhong Yang } 2362256f4d4SZhong Yang 237b6d5f9dcSzhongyang void CLyricsWindow::DrawLyricText(Gdiplus::Graphics* pGraphics, LPCTSTR strText, Gdiplus::RectF rect, bool bDrawHighlight, bool bDrawTranslate) 2382256f4d4SZhong Yang { 2392256f4d4SZhong Yang Gdiplus::REAL fontSize = bDrawTranslate ? m_FontSize * TRANSLATE_FONT_SIZE_FACTOR : m_FontSize; 2402256f4d4SZhong Yang if (fontSize < 1) 2412256f4d4SZhong Yang fontSize = m_FontSize; 2422256f4d4SZhong Yang 243e3d88825Szhongyang Gdiplus::REAL textWidth = rect.Width; 244e3d88825Szhongyang Gdiplus::REAL highlighWidth = rect.Width * m_nHighlight / 1000; 245b6d5f9dcSzhongyang 246b6d5f9dcSzhongyang if (!bDrawHighlight && !bDrawTranslate) 247b6d5f9dcSzhongyang { 248b6d5f9dcSzhongyang if (rect.X < 0) 249b6d5f9dcSzhongyang rect.X = 0; 250b6d5f9dcSzhongyang } 251b6d5f9dcSzhongyang else 252b6d5f9dcSzhongyang { 253877f5f92SZhongYang //如果文本宽度大于控件宽度,就要根据分割的位置滚动文本 254e3d88825Szhongyang if (textWidth > m_nWidth) 255e3d88825Szhongyang { 256877f5f92SZhongYang //如果分割的位置(歌词进度)剩下的宽度已经小于控件宽度的一半,此时使文本右侧和控件右侧对齐 257e3d88825Szhongyang if (textWidth - highlighWidth < m_nWidth / 2) 258e3d88825Szhongyang { 259e3d88825Szhongyang rect.X = m_nWidth - textWidth; 260e3d88825Szhongyang } 261877f5f92SZhongYang //分割位置剩下的宽度还没有到小于控件宽度的一半,但是分割位置的宽度已经大于控件宽度的一半时,需要移动文本使分割位置正好在控件的中间 262e3d88825Szhongyang else if (highlighWidth > m_nWidth / 2) 263e3d88825Szhongyang { 264e3d88825Szhongyang rect.X = m_nWidth / 2 - highlighWidth; 265e3d88825Szhongyang } 266877f5f92SZhongYang //分割位置还不到控件宽度的一半时,使文本左侧和控件左侧对齐 267e3d88825Szhongyang else 268e3d88825Szhongyang { 269e3d88825Szhongyang rect.X = 0; 270e3d88825Szhongyang } 271e3d88825Szhongyang } 272b6d5f9dcSzhongyang } 273e3d88825Szhongyang 2742256f4d4SZhong Yang //----------------------------------------------------------- 275877f5f92SZhongYang //画出阴影 2762256f4d4SZhong Yang if (m_pShadowBrush) { 2772256f4d4SZhong Yang Gdiplus::RectF layoutRect(0, 0, 0, 0); 2782256f4d4SZhong Yang layoutRect = rect; 2792256f4d4SZhong Yang layoutRect.X = layoutRect.X + m_nShadowOffset; 2802256f4d4SZhong Yang layoutRect.Y = layoutRect.Y + m_nShadowOffset; 281877f5f92SZhongYang Gdiplus::GraphicsPath* pShadowPath = new Gdiplus::GraphicsPath(Gdiplus::FillModeAlternate);//创建路径 282877f5f92SZhongYang pShadowPath->AddString(strText, -1, m_pFontFamily, m_FontStyle, fontSize, layoutRect, m_pTextFormat); //把文字加入路径 283877f5f92SZhongYang pGraphics->FillPath(m_pShadowBrush, pShadowPath);//填充路径 284877f5f92SZhongYang delete pShadowPath; //销毁路径 2852256f4d4SZhong Yang } 2862256f4d4SZhong Yang 2872256f4d4SZhong Yang //----------------------------------------------------------- 288877f5f92SZhongYang //画出歌词 289877f5f92SZhongYang Gdiplus::GraphicsPath* pStringPath = new Gdiplus::GraphicsPath(Gdiplus::FillModeAlternate);//创建路径 290877f5f92SZhongYang pStringPath->AddString(strText, -1, m_pFontFamily, m_FontStyle, fontSize, rect, m_pTextFormat); //把文字加入路径 2912256f4d4SZhong Yang if (m_pTextPen) { 292877f5f92SZhongYang pGraphics->DrawPath(m_pTextPen, pStringPath);//画路径,文字边框 2932256f4d4SZhong Yang } 2942256f4d4SZhong Yang Gdiplus::Brush* pBrush = CreateGradientBrush(m_TextGradientMode, m_TextColor1, m_TextColor2, rect); 295877f5f92SZhongYang pGraphics->FillPath(pBrush, pStringPath);//填充路径 296877f5f92SZhongYang delete pBrush;//销毁画刷 297b6d5f9dcSzhongyang if(bDrawHighlight) 2982256f4d4SZhong Yang DrawHighlightLyrics(pGraphics, pStringPath, rect); 299877f5f92SZhongYang delete pStringPath; //销毁路径 3002256f4d4SZhong Yang } 3012256f4d4SZhong Yang 302877f5f92SZhongYang //绘制歌词 303b1f2b024SZhong Yang void CLyricsWindow::DrawLyrics(Gdiplus::Graphics* pGraphics) 304b1f2b024SZhong Yang { 30517b049b7Szhongyang int lyricHeight = m_nHeight - m_toobar_height; 306877f5f92SZhongYang //先取出文字宽度和高度 307b1f2b024SZhong Yang Gdiplus::RectF layoutRect(0,0,0,0); 308b1f2b024SZhong Yang Gdiplus::RectF boundingBox; 3095c2d48a1Slrisora if (!m_lpszBeforeLyrics.IsEmpty()) 3105c2d48a1Slrisora { 3115c2d48a1Slrisora pGraphics->MeasureString(m_lpszBeforeLyrics, -1, m_pFont, layoutRect, m_pTextFormat, &boundingBox, 0, 0); 3125c2d48a1Slrisora auto bef_width{ boundingBox.Width }; 3135c2d48a1Slrisora pGraphics->MeasureString(L" ", -1, m_pFont, layoutRect, m_pTextFormat, &boundingBox, 0, 0); 3145c2d48a1Slrisora auto sp_width{ boundingBox.Width }; 3155c2d48a1Slrisora m_lpszLyrics = m_lpszBeforeLyrics + L" " + m_lpszLyrics; 316b1f2b024SZhong Yang pGraphics->MeasureString(m_lpszLyrics, -1, m_pFont, layoutRect, m_pTextFormat, &boundingBox, 0, 0); 3175c2d48a1Slrisora if(m_bBeforeLyrics) 3185c2d48a1Slrisora m_nHighlight = m_nHighlight * bef_width / boundingBox.Width; 3195c2d48a1Slrisora else 3205c2d48a1Slrisora m_nHighlight = ((bef_width + sp_width) * 1000 + m_nHighlight * (boundingBox.Width - bef_width - sp_width)) / boundingBox.Width; 3215c2d48a1Slrisora } 3225c2d48a1Slrisora else 3235c2d48a1Slrisora { 3245c2d48a1Slrisora pGraphics->MeasureString (m_lpszLyrics, -1, m_pFont,layoutRect, m_pTextFormat,&boundingBox, 0, 0); 3255c2d48a1Slrisora } 3268e43b3d5Szhongyang219 boundingBox.Width += 1; //测量到的文本宽度加1,以防止出现使用某些字体时,最后一个字符无法显示的问题 327877f5f92SZhongYang //计算歌词画出的位置 328877f5f92SZhongYang Gdiplus::RectF dstRect; //文字的矩形 329877f5f92SZhongYang Gdiplus::RectF transRect; //翻译文本的矩形 330b6d5f9dcSzhongyang bool bDrawTranslate = m_bShowTranslate && !m_strTranslate.IsEmpty(); 331b6d5f9dcSzhongyang if(!bDrawTranslate) 332f5ba4de7SZhong Yang { 3333ae54aeaSzhongyang219 switch (m_alignment) 3343ae54aeaSzhongyang219 { 3353ae54aeaSzhongyang219 case Alignment::LEFT: 3363ae54aeaSzhongyang219 dstRect = Gdiplus::RectF(0, m_toobar_height + (lyricHeight - boundingBox.Height) / 2, boundingBox.Width, boundingBox.Height); 3373ae54aeaSzhongyang219 break; 3383ae54aeaSzhongyang219 case Alignment::RIGHT: 3393ae54aeaSzhongyang219 dstRect = Gdiplus::RectF(m_nWidth - boundingBox.Width, m_toobar_height + (lyricHeight - boundingBox.Height) / 2, boundingBox.Width, boundingBox.Height); 3403ae54aeaSzhongyang219 break; 3413ae54aeaSzhongyang219 //居中 3423ae54aeaSzhongyang219 default: 34317b049b7Szhongyang dstRect = Gdiplus::RectF((m_nWidth - boundingBox.Width) / 2, m_toobar_height + (lyricHeight - boundingBox.Height) / 2, boundingBox.Width, boundingBox.Height); 344f5ba4de7SZhong Yang } 3453ae54aeaSzhongyang219 } 346f5ba4de7SZhong Yang else 3472256f4d4SZhong Yang { 3482256f4d4SZhong Yang Gdiplus::RectF transBoundingBox; 3492256f4d4SZhong Yang pGraphics->MeasureString(m_strTranslate, -1, m_pFont, layoutRect, m_pTextFormat, &transBoundingBox, 0, 0); 3508e43b3d5Szhongyang219 transBoundingBox.Width += 1; //测量到的文本宽度加1,以防止出现使用某些字体时,最后一个字符无法显示的问题 351a517e787Szhongyang Gdiplus::REAL translateHeight = transBoundingBox.Height * TRANSLATE_FONT_SIZE_FACTOR; 352a517e787Szhongyang Gdiplus::REAL translateWidth = transBoundingBox.Width * TRANSLATE_FONT_SIZE_FACTOR; 353877f5f92SZhongYang Gdiplus::REAL gapHeight = boundingBox.Height * 0.2f; //歌词和翻译之间的间隙 3542256f4d4SZhong Yang Gdiplus::REAL height = boundingBox.Height + gapHeight + translateHeight; 3553ae54aeaSzhongyang219 switch (m_alignment) 3563ae54aeaSzhongyang219 { 3573ae54aeaSzhongyang219 case Alignment::LEFT: 3583ae54aeaSzhongyang219 dstRect = Gdiplus::RectF(0, m_toobar_height + (lyricHeight - height) / 2, boundingBox.Width, boundingBox.Height); 3593ae54aeaSzhongyang219 transRect = Gdiplus::RectF(0, dstRect.GetBottom() + gapHeight, translateWidth, translateHeight); 3603ae54aeaSzhongyang219 break; 3613ae54aeaSzhongyang219 case Alignment::RIGHT: 3623ae54aeaSzhongyang219 dstRect = Gdiplus::RectF((m_nWidth - boundingBox.Width), m_toobar_height + (lyricHeight - height) / 2, boundingBox.Width, boundingBox.Height); 3633ae54aeaSzhongyang219 transRect = Gdiplus::RectF((m_nWidth - translateWidth), dstRect.GetBottom() + gapHeight, translateWidth, translateHeight); 3643ae54aeaSzhongyang219 break; 3653ae54aeaSzhongyang219 default: 366a517e787Szhongyang dstRect = Gdiplus::RectF((m_nWidth - boundingBox.Width) / 2, m_toobar_height + (lyricHeight - height) / 2, boundingBox.Width, boundingBox.Height); 367a517e787Szhongyang transRect = Gdiplus::RectF((m_nWidth - translateWidth) / 2, dstRect.GetBottom() + gapHeight, translateWidth, translateHeight); 3683ae54aeaSzhongyang219 break; 3693ae54aeaSzhongyang219 } 3702256f4d4SZhong Yang } 371b1f2b024SZhong Yang 372e9075d48Szhongyang219 DrawLyricText(pGraphics, m_lpszLyrics, dstRect, m_lyric_karaoke_disp); 373b6d5f9dcSzhongyang if (bDrawTranslate) 374b6d5f9dcSzhongyang DrawLyricText(pGraphics, m_strTranslate, transRect, false, true); 375b1f2b024SZhong Yang } 376b6d5f9dcSzhongyang 377b6d5f9dcSzhongyang void CLyricsWindow::DrawLyricsDoubleLine(Gdiplus::Graphics* pGraphics) 378b6d5f9dcSzhongyang { 37917b049b7Szhongyang int lyricHeight = m_nHeight - m_toobar_height; 380b6d5f9dcSzhongyang static bool bSwap = false; 381877f5f92SZhongYang if (m_lyricChangeFlag) //如果歌词发生了改变,则交换当前歌词和下一句歌词的位置 382b6d5f9dcSzhongyang bSwap = !bSwap; 383877f5f92SZhongYang //先取出文字宽度和高度 384b6d5f9dcSzhongyang Gdiplus::RectF layoutRect(0, 0, 0, 0); 385b6d5f9dcSzhongyang Gdiplus::RectF boundingBox; 3865c2d48a1Slrisora if (!m_lpszBeforeLyrics.IsEmpty()) 3875c2d48a1Slrisora { 3885c2d48a1Slrisora pGraphics->MeasureString(m_lpszBeforeLyrics, -1, m_pFont, layoutRect, m_pTextFormat, &boundingBox, 0, 0); 3895c2d48a1Slrisora auto bef_width{ boundingBox.Width }; 3905c2d48a1Slrisora pGraphics->MeasureString(L" ", -1, m_pFont, layoutRect, m_pTextFormat, &boundingBox, 0, 0); 3915c2d48a1Slrisora auto sp_width{ boundingBox.Width }; 3925c2d48a1Slrisora m_lpszLyrics = m_lpszBeforeLyrics + L" " + m_lpszLyrics; 393b6d5f9dcSzhongyang pGraphics->MeasureString(m_lpszLyrics, -1, m_pFont, layoutRect, m_pTextFormat, &boundingBox, 0, 0); 3945c2d48a1Slrisora if (m_bBeforeLyrics) 3955c2d48a1Slrisora m_nHighlight = m_nHighlight * bef_width / boundingBox.Width; 3965c2d48a1Slrisora else 3975c2d48a1Slrisora m_nHighlight = ((bef_width + sp_width) * 1000 + m_nHighlight * (boundingBox.Width - bef_width - sp_width)) / boundingBox.Width; 3985c2d48a1Slrisora } 3995c2d48a1Slrisora else 4005c2d48a1Slrisora { 4015c2d48a1Slrisora pGraphics->MeasureString(m_lpszLyrics, -1, m_pFont, layoutRect, m_pTextFormat, &boundingBox, 0, 0); 4025c2d48a1Slrisora } 40334066710Slrisora boundingBox.Width += 1; //测量到的文本宽度加1,以防止出现使用某些字体时,最后一个字符无法显示的问题 404b6d5f9dcSzhongyang Gdiplus::RectF nextBoundingBox; 405b6d5f9dcSzhongyang pGraphics->MeasureString(m_strNextLyric, -1, m_pFont, layoutRect, m_pTextFormat, &nextBoundingBox, 0, 0); 40634066710Slrisora nextBoundingBox.Width += 1; //测量到的文本宽度加1,以防止出现使用某些字体时,最后一个字符无法显示的问题 407877f5f92SZhongYang //计算歌词画出的位置 408877f5f92SZhongYang Gdiplus::RectF dstRect; //文字的矩形 409877f5f92SZhongYang Gdiplus::RectF nextRect; //下一句文本的矩形 410b6d5f9dcSzhongyang 41117b049b7Szhongyang dstRect = Gdiplus::RectF(0, m_toobar_height + (lyricHeight / 2 - boundingBox.Height) / 2, boundingBox.Width, boundingBox.Height); 412a8b024cfSZhong Yang nextRect = Gdiplus::RectF(m_nWidth - nextBoundingBox.Width, dstRect.Y + lyricHeight / 2, nextBoundingBox.Width, nextBoundingBox.Height); 413b6d5f9dcSzhongyang 414b6d5f9dcSzhongyang if (bSwap) 415b6d5f9dcSzhongyang { 416b6d5f9dcSzhongyang std::swap(dstRect.Y, nextRect.Y); 417b6d5f9dcSzhongyang nextRect.X = 0; 418b6d5f9dcSzhongyang dstRect.X = m_nWidth - dstRect.Width; 419b6d5f9dcSzhongyang } 420b6d5f9dcSzhongyang 421b6d5f9dcSzhongyang DrawLyricText(pGraphics, m_lpszLyrics, dstRect, true); 422b6d5f9dcSzhongyang DrawLyricText(pGraphics, m_strNextLyric, nextRect, false); 423b6d5f9dcSzhongyang } 424b6d5f9dcSzhongyang 425877f5f92SZhongYang //绘制高亮歌词 426b1f2b024SZhong Yang void CLyricsWindow::DrawHighlightLyrics(Gdiplus::Graphics* pGraphics,Gdiplus::GraphicsPath* pPath, Gdiplus::RectF& dstRect) 427b1f2b024SZhong Yang { 428b1f2b024SZhong Yang if(m_nHighlight<=0)return; 429b1f2b024SZhong Yang Gdiplus::Region* pRegion=NULL; 430*7a97dbb6Szhongyang219 if(m_nHighlight<1000 && m_lyric_karaoke_disp){ 431b1f2b024SZhong Yang Gdiplus::RectF CliptRect(dstRect); 432b1f2b024SZhong Yang CliptRect.Width=CliptRect.Width * m_nHighlight / 1000; 433b1f2b024SZhong Yang pRegion=new Gdiplus::Region(CliptRect); 434b1f2b024SZhong Yang pGraphics->SetClip(pRegion, Gdiplus::CombineModeReplace); 435b1f2b024SZhong Yang } 436b1f2b024SZhong Yang //-------------------------------------------- 437b1f2b024SZhong Yang if(m_pHighlightPen){ 438877f5f92SZhongYang pGraphics->DrawPath (m_pHighlightPen,pPath);//画路径,文字边框 439b1f2b024SZhong Yang } 440b1f2b024SZhong Yang Gdiplus::Brush* pBrush = CreateGradientBrush(m_HighlightGradientMode, m_HighlightColor1,m_HighlightColor2,dstRect); 441877f5f92SZhongYang pGraphics->FillPath (pBrush,pPath);//填充路径 442877f5f92SZhongYang delete pBrush;//销毁画刷 443b1f2b024SZhong Yang //-------------------------------------------- 444b1f2b024SZhong Yang if(pRegion){ 445b1f2b024SZhong Yang pGraphics->ResetClip(); 446b1f2b024SZhong Yang delete pRegion; 447b1f2b024SZhong Yang } 448b1f2b024SZhong Yang } 449b7f299bfSzhongyang 450877f5f92SZhongYang //创建渐变画刷 451b1f2b024SZhong Yang Gdiplus::Brush* CLyricsWindow::CreateGradientBrush(LyricsGradientMode TextGradientMode,Gdiplus::Color& Color1,Gdiplus::Color& Color2, Gdiplus::RectF& dstRect) 452b1f2b024SZhong Yang { 453b1f2b024SZhong Yang Gdiplus::PointF pt1; 454b1f2b024SZhong Yang Gdiplus::PointF pt2; 455b1f2b024SZhong Yang Gdiplus::Brush* pBrush=NULL; 456b1f2b024SZhong Yang switch (TextGradientMode) 457b1f2b024SZhong Yang { 458877f5f92SZhongYang case LyricsGradientMode_Two://两色渐变 459b1f2b024SZhong Yang { 460b1f2b024SZhong Yang Gdiplus::PointF point1(dstRect.X,dstRect.Y); 461b1f2b024SZhong Yang Gdiplus::PointF point2(dstRect.X,dstRect.Y+dstRect.Height); 462b1f2b024SZhong Yang pBrush=new Gdiplus::LinearGradientBrush(point1,point2,Color1,Color2); 463b1f2b024SZhong Yang ((Gdiplus::LinearGradientBrush*)pBrush)->SetWrapMode(Gdiplus::WrapModeTileFlipXY); 464b1f2b024SZhong Yang break; 465b1f2b024SZhong Yang } 466b1f2b024SZhong Yang 467877f5f92SZhongYang case LyricsGradientMode_Three://三色渐变 468b1f2b024SZhong Yang { 469b1f2b024SZhong Yang Gdiplus::PointF point1(dstRect.X,dstRect.Y); 470b1f2b024SZhong Yang Gdiplus::PointF point2(dstRect.X,dstRect.Y+dstRect.Height/2); 471b1f2b024SZhong Yang pBrush=new Gdiplus::LinearGradientBrush(point1,point2,Color1,Color2); 472b1f2b024SZhong Yang ((Gdiplus::LinearGradientBrush*)pBrush)->SetWrapMode(Gdiplus::WrapModeTileFlipXY); 473b1f2b024SZhong Yang break; 474b1f2b024SZhong Yang } 475b1f2b024SZhong Yang 476877f5f92SZhongYang default://无渐变 477b1f2b024SZhong Yang { 478b1f2b024SZhong Yang pBrush=new Gdiplus::SolidBrush(Color1); 479b1f2b024SZhong Yang break; 480b1f2b024SZhong Yang } 481b1f2b024SZhong Yang } 482b1f2b024SZhong Yang return pBrush; 483b1f2b024SZhong Yang } 484b1f2b024SZhong Yang 485877f5f92SZhongYang //设置歌词颜色 486b1f2b024SZhong Yang void CLyricsWindow::SetLyricsColor(Gdiplus::Color TextColor1) 487b1f2b024SZhong Yang { 488b1f2b024SZhong Yang CLyricsWindow::SetLyricsColor(TextColor1,Gdiplus::Color::Black,LyricsGradientMode_None); 489b1f2b024SZhong Yang } 490b1f2b024SZhong Yang void CLyricsWindow::SetLyricsColor(Gdiplus::Color TextColor1,Gdiplus::Color TextColor2,LyricsGradientMode TextGradientMode) 491b1f2b024SZhong Yang { 492b1f2b024SZhong Yang m_TextColor1=TextColor1; 493b1f2b024SZhong Yang m_TextColor2=TextColor2; 494b1f2b024SZhong Yang m_TextGradientMode=TextGradientMode; 495b1f2b024SZhong Yang 496b1f2b024SZhong Yang } 497877f5f92SZhongYang //设置歌词边框 498b1f2b024SZhong Yang void CLyricsWindow::SetLyricsBorder(Gdiplus::Color BorderColor, Gdiplus::REAL BorderWidth) 499b1f2b024SZhong Yang { 500b1f2b024SZhong Yang if(m_pTextPen){ 501b1f2b024SZhong Yang delete m_pTextPen; 502b1f2b024SZhong Yang m_pTextPen=NULL; 503b1f2b024SZhong Yang } 504b1f2b024SZhong Yang if(BorderColor.GetA()>0 && BorderWidth>0) 505b1f2b024SZhong Yang m_pTextPen=new Gdiplus::Pen(BorderColor,BorderWidth); 506b1f2b024SZhong Yang } 507877f5f92SZhongYang //设置高亮歌词颜色 508b1f2b024SZhong Yang void CLyricsWindow::SetHighlightColor(Gdiplus::Color TextColor1) 509b1f2b024SZhong Yang { 510b1f2b024SZhong Yang CLyricsWindow::SetHighlightColor(TextColor1,Gdiplus::Color::Black,LyricsGradientMode_None); 511b1f2b024SZhong Yang } 512b1f2b024SZhong Yang void CLyricsWindow::SetHighlightColor(Gdiplus::Color TextColor1,Gdiplus::Color TextColor2,LyricsGradientMode TextGradientMode) 513b1f2b024SZhong Yang { 514b1f2b024SZhong Yang m_HighlightColor1=TextColor1; 515b1f2b024SZhong Yang m_HighlightColor2=TextColor2; 516b1f2b024SZhong Yang m_HighlightGradientMode=TextGradientMode; 517b1f2b024SZhong Yang 518b1f2b024SZhong Yang } 519877f5f92SZhongYang //设置高亮歌词边框 520b1f2b024SZhong Yang void CLyricsWindow::SetHighlightBorder(Gdiplus::Color BorderColor, Gdiplus::REAL BorderWidth) 521b1f2b024SZhong Yang { 522b1f2b024SZhong Yang if(m_pHighlightPen){ 523b1f2b024SZhong Yang delete m_pHighlightPen; 524b1f2b024SZhong Yang m_pHighlightPen=NULL; 525b1f2b024SZhong Yang } 526b1f2b024SZhong Yang if(BorderColor.GetA()>0 && BorderWidth>0) 527b1f2b024SZhong Yang m_pHighlightPen=new Gdiplus::Pen(BorderColor,BorderWidth); 528b1f2b024SZhong Yang } 529877f5f92SZhongYang //设置歌词阴影 530b1f2b024SZhong Yang void CLyricsWindow::SetLyricsShadow(Gdiplus::Color ShadowColor,int nShadowOffset) 531b1f2b024SZhong Yang { 532b1f2b024SZhong Yang if(m_pShadowBrush){ 533b1f2b024SZhong Yang delete m_pShadowBrush; 534b1f2b024SZhong Yang m_pShadowBrush=NULL; 535b1f2b024SZhong Yang } 536b1f2b024SZhong Yang if(ShadowColor.GetA()>0 && nShadowOffset>0){ 537b1f2b024SZhong Yang m_nShadowOffset=nShadowOffset; 538b1f2b024SZhong Yang m_pShadowBrush=new Gdiplus::SolidBrush(ShadowColor); 539b1f2b024SZhong Yang }else{ 540b1f2b024SZhong Yang m_nShadowOffset=0; 541b1f2b024SZhong Yang } 542b1f2b024SZhong Yang } 543877f5f92SZhongYang //设置歌词字体 544b1f2b024SZhong Yang void CLyricsWindow::SetLyricsFont(const WCHAR * familyName, Gdiplus::REAL emSize,INT style, Gdiplus::Unit unit) 545b1f2b024SZhong Yang { 546b1f2b024SZhong Yang if(m_pFont){ 547b1f2b024SZhong Yang delete m_pFont; 548b1f2b024SZhong Yang m_pFont=NULL; 549b1f2b024SZhong Yang } 550b1f2b024SZhong Yang Gdiplus::FontFamily family(familyName,NULL); 551b1f2b024SZhong Yang Gdiplus::Status lastResult = family.GetLastStatus(); 552b1f2b024SZhong Yang if (lastResult != Gdiplus::Ok) 553b1f2b024SZhong Yang { 554b1f2b024SZhong Yang HFONT hFont=(HFONT)GetStockObject(DEFAULT_GUI_FONT); 555b1f2b024SZhong Yang LOGFONTW lf; 556b1f2b024SZhong Yang ZeroMemory(&lf,sizeof(LOGFONTW)); 557b1f2b024SZhong Yang GetObjectW(hFont,sizeof(LOGFONTW),&lf); 558b1f2b024SZhong Yang Gdiplus::FontFamily family2(lf.lfFaceName,NULL); 559b1f2b024SZhong Yang m_pFont=new Gdiplus::Font(&family2,emSize,style,unit); 560b1f2b024SZhong Yang }else{ 561b1f2b024SZhong Yang m_pFont=new Gdiplus::Font(&family,emSize,style,unit); 562b1f2b024SZhong Yang } 563b1f2b024SZhong Yang //---------------- 564877f5f92SZhongYang //保存一些字体属性,加入路径时要用到 565b1f2b024SZhong Yang m_pFont->GetFamily (m_pFontFamily); 566b1f2b024SZhong Yang m_FontSize=m_pFont->GetSize (); 567b1f2b024SZhong Yang m_FontStyle=m_pFont->GetStyle (); 568b1f2b024SZhong Yang 569b1f2b024SZhong Yang 570b1f2b024SZhong Yang 571b1f2b024SZhong Yang } 572b1f2b024SZhong Yang 5732256f4d4SZhong Yang void CLyricsWindow::SetLyricDoubleLine(bool doubleLine) 5742256f4d4SZhong Yang { 5752256f4d4SZhong Yang m_bDoubleLine = doubleLine; 5762256f4d4SZhong Yang } 5772256f4d4SZhong Yang 5782256f4d4SZhong Yang void CLyricsWindow::SetNextLyric(LPCTSTR lpszNextLyric) 5792256f4d4SZhong Yang { 5802256f4d4SZhong Yang m_strNextLyric = lpszNextLyric; 5812256f4d4SZhong Yang } 5822256f4d4SZhong Yang 583b6d5f9dcSzhongyang void CLyricsWindow::SetShowTranslate(bool showTranslate) 584b6d5f9dcSzhongyang { 585b6d5f9dcSzhongyang m_bShowTranslate = showTranslate; 586b6d5f9dcSzhongyang } 587b6d5f9dcSzhongyang 588be1c6be2Szhongyang void CLyricsWindow::SetAlpha(int alpha) 589be1c6be2Szhongyang { 590be1c6be2Szhongyang m_alpha = alpha; 591be1c6be2Szhongyang } 592be1c6be2Szhongyang 593e32f802dSZhong Yang const CString& CLyricsWindow::GetLyricStr() const 594e32f802dSZhong Yang { 595e32f802dSZhong Yang return m_lpszLyrics; 596e32f802dSZhong Yang } 597e32f802dSZhong Yang 598b6d5f9dcSzhongyang void CLyricsWindow::SetLyricChangeFlag(bool bFlag) 599b6d5f9dcSzhongyang { 600b6d5f9dcSzhongyang m_lyricChangeFlag = bFlag; 601b6d5f9dcSzhongyang } 602b6d5f9dcSzhongyang 6033ae54aeaSzhongyang219 void CLyricsWindow::SetAlignment(Alignment alignment) 6043ae54aeaSzhongyang219 { 6053ae54aeaSzhongyang219 m_alignment = alignment; 6063ae54aeaSzhongyang219 } 6073ae54aeaSzhongyang219 608e9075d48Szhongyang219 void CLyricsWindow::SetLyricKaraokeDisplay(bool karaoke_disp) 609e9075d48Szhongyang219 { 610e9075d48Szhongyang219 m_lyric_karaoke_disp = karaoke_disp; 611e9075d48Szhongyang219 } 612e9075d48Szhongyang219 613b1f2b024SZhong Yang void CLyricsWindow::OnLButtonDown(UINT nFlags, CPoint point) 614b1f2b024SZhong Yang { 615b7f299bfSzhongyang 616b1f2b024SZhong Yang CWnd::OnLButtonDown(nFlags, point); 617a8b024cfSZhong Yang //ReleaseCapture(); 618a8b024cfSZhong Yang //SendMessage(WM_NCLBUTTONDOWN,HTCAPTION,NULL); 619b1f2b024SZhong Yang } 620