xref: /MusicPlayer2/MusicPlayer2/LyricsWindow.cpp (revision e496400b88f7fbf29a2315234990ff687f065638)
1 // LyricsWindow.cpp : 实现文件
2 //
3 
4 #include "stdafx.h"
5 #include "LyricsWindow.h"
6 
7 // CLyricsWindow
8 
9 const Gdiplus::REAL TRANSLATE_FONT_SIZE_FACTOR = 0.88f;		//歌词翻译文本大小占歌词文本大小的比例
10 
11 IMPLEMENT_DYNAMIC(CLyricsWindow, CWnd)
12 
13 CLyricsWindow::CLyricsWindow()
14 {
15 	HDC hDC=::GetDC(NULL);
16 	m_hCacheDC=::CreateCompatibleDC(hDC);
17 	::ReleaseDC(NULL,hDC);
18 	//---------------------------------
19 	m_nHighlight=NULL ; //高亮歌词的百分比 0--100
20 	m_TextGradientMode=LyricsGradientMode_Two ; //普通歌词渐变模式
21 	m_pTextPen=NULL ; //普通歌词边框画笔
22 	m_HighlightGradientMode=LyricsGradientMode_Two ; //高亮歌词渐变模式
23 	m_pHighlightPen=NULL ; //高亮歌词边框画笔
24 	m_pShadowBrush=NULL ; //阴影画刷,GDIPlus画刷
25 	m_nShadowOffset=1 ; //阴影偏移
26 	m_pFont=NULL ; //GDIPlus字体
27 	m_FontStyle=NULL ;
28 	m_FontSize=NULL ;
29 	m_pTextFormat=NULL;
30 	//---------------------------------
31 	m_pFontFamily=new Gdiplus::FontFamily();
32 	m_pTextFormat=new Gdiplus::StringFormat();
33 	m_pTextFormat->SetFormatFlags(Gdiplus::StringFormatFlagsNoWrap);//不换行
34 	m_pTextFormat->SetAlignment(Gdiplus::StringAlignmentCenter); //置水平对齐方式
35 	m_pTextFormat->SetLineAlignment(Gdiplus::StringAlignmentNear); //置垂直对齐方式
36 	//---------------------------------
37 	//SetLyricsFont(L"微软雅黑", 40, Gdiplus::FontStyle::FontStyleRegular);
38 	//SetLyricsColor(Gdiplus::Color::Red,Gdiplus::Color(255,172,0),LyricsGradientMode_Three);
39 	//SetLyricsBorder(Gdiplus::Color::Black,1);
40 	SetLyricsShadow(Gdiplus::Color(150,0,0,0),1);
41 	//SetHighlightColor(Gdiplus::Color(255,100,26),Gdiplus::Color(255,255,0),LyricsGradientMode_Three);
42 	//SetHighlightBorder(Gdiplus::Color::Black,1);
43 
44 }
45 
46 CLyricsWindow::~CLyricsWindow()
47 {
48 	if(m_pTextPen){
49 		delete m_pTextPen;
50 		m_pTextPen=NULL;
51 	}
52 	if(m_pHighlightPen){
53 		delete m_pHighlightPen;
54 		m_pHighlightPen=NULL;
55 	}
56 	if(m_pShadowBrush){
57 		delete m_pShadowBrush;
58 		m_pShadowBrush=NULL;
59 	}
60 	if(m_pFontFamily){
61 		delete m_pFontFamily;
62 		m_pFontFamily=NULL;
63 	}
64 	if(m_pTextFormat){
65 		delete m_pTextFormat;
66 		m_pTextFormat=NULL;
67 	}
68 	if(m_pFont){
69 		delete m_pFont;
70 		m_pFont=NULL;
71 	}
72 }
73 
74 
75 BEGIN_MESSAGE_MAP(CLyricsWindow, CWnd)
76 	ON_WM_LBUTTONDOWN()
77 END_MESSAGE_MAP()
78 
79 
80 
81 BOOL CLyricsWindow::Create(int nHeight)
82 {
83 	return CLyricsWindow::Create(_T("CometLyricsWindow"), -1, nHeight);
84 }
85 BOOL CLyricsWindow::Create(LPCTSTR lpszClassName)
86 {
87 	return CLyricsWindow::Create(lpszClassName,-1,-1);
88 }
89 BOOL CLyricsWindow::Create(LPCTSTR lpszClassName,int nWidth,int nHeight)
90 {
91 	if(!RegisterWndClass(lpszClassName))
92 	{
93 		TRACE("Class Registration Failedn");
94 	}
95 
96 	//--------------------------------------------
97 	//取出桌面工作区域
98 	RECT rcWork;
99 	SystemParametersInfo (SPI_GETWORKAREA,NULL,&rcWork,NULL);
100 	int nWorkWidth=rcWork.right-rcWork.left;
101 	int nWorkHeight=rcWork.bottom-rcWork.top;
102 	//未传递宽度、高度参数时设置个默认值
103 	if(nWidth<0)nWidth=nWorkWidth*2/3;      //默认宽度为桌面宽度的2/3
104 	if(nHeight<0)nHeight=150;
105 	//设置左边、顶边位置,让窗口在屏幕下方
106 	int x=rcWork.left+( (nWorkWidth-nWidth)/2 );
107 	int y=rcWork.bottom-nHeight;
108 	//--------------------------------------------
109 	DWORD dwStyle=WS_POPUP|WS_VISIBLE|WS_THICKFRAME;
110 	DWORD dwExStyle=WS_EX_TOOLWINDOW|WS_EX_TOPMOST|WS_EX_LAYERED;
111     BOOL rtn = CWnd::CreateEx(dwExStyle, lpszClassName, NULL, dwStyle, x, y, nWidth, nHeight, NULL, NULL);
112 
113     return rtn;
114 }
115 BOOL CLyricsWindow::RegisterWndClass(LPCTSTR lpszClassName)
116 {
117 	HINSTANCE hInstance=AfxGetInstanceHandle();
118 	WNDCLASSEX wndcls;
119 	memset(&wndcls,0,sizeof(WNDCLASSEX));
120 	wndcls.cbSize=sizeof(WNDCLASSEX);
121 	if(GetClassInfoEx(hInstance,lpszClassName,&wndcls))
122 	{
123 		return TRUE;
124 	}
125 	if(GetClassInfoEx(NULL,lpszClassName,&wndcls))
126 	{
127 		return TRUE;
128 	}
129 
130 	wndcls.style=CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW;
131 	wndcls.lpfnWndProc=::DefWindowProc;
132 	wndcls.hInstance=hInstance;
133 	wndcls.hIcon=NULL;
134 	wndcls.hCursor=::LoadCursor(NULL,IDC_ARROW);
135 	wndcls.hbrBackground=(HBRUSH)(COLOR_BTNFACE+1);
136 	wndcls.lpszMenuName=NULL;
137 	wndcls.lpszClassName=lpszClassName;
138 	if(!RegisterClassEx(&wndcls))
139 	{
140 		return FALSE;
141 	}
142 	return TRUE;
143 }
144 
145 
146 //更新歌词(进度符号,歌词文本,高亮进度百分比,是否为进度符号高亮)
147 void CLyricsWindow::UpdateLyrics(LPCTSTR lpszBeforeLyrics, LPCTSTR lpszLyrics, int nHighlight, bool bBeforeLyrics)
148 {
149     m_lpszBeforeLyrics = lpszBeforeLyrics;
150     m_bBeforeLyrics = bBeforeLyrics;
151     m_lpszLyrics = lpszLyrics;
152     UpdateLyrics(nHighlight);
153 }
154 //更新歌词(歌词文本,高亮进度百分比)
155 void CLyricsWindow::UpdateLyrics(LPCTSTR lpszLyrics,int nHighlight)
156 {
157     m_lpszBeforeLyrics.Empty();
158     m_bBeforeLyrics = false;
159     m_lpszLyrics = lpszLyrics;
160     UpdateLyrics(nHighlight);
161 }
162 //更新高亮进度(高亮进度百分比)
163 void CLyricsWindow::UpdateLyrics(int nHighlight)
164 {
165 	m_nHighlight=nHighlight;
166 	if(m_nHighlight<0)
167 		m_nHighlight=0;
168 	if(m_nHighlight>1000)
169 		m_nHighlight=1000;
170 	Draw();
171 }
172 
173 void CLyricsWindow::UpdateLyricTranslate(LPCTSTR lpszLyricTranslate)
174 {
175 	m_strTranslate = lpszLyricTranslate;
176 }
177 
178 //重画歌词窗口
179 void CLyricsWindow::Draw()
180 {
181 	//CRect rcWindow;
182 	GetWindowRect(m_rcWindow);
183 	m_nWidth= m_rcWindow.Width();
184 	m_nHeight= m_rcWindow.Height();
185     CRect rcClient;
186     GetClientRect(rcClient);
187     m_frameSize.cx = (m_rcWindow.Width() - rcClient.Width()) / 2;
188     m_frameSize.cy = (m_rcWindow.Height() - rcClient.Height()) / 2;
189 
190 	//----------------------------------
191 	BITMAPINFO bitmapinfo;
192 	bitmapinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
193 	bitmapinfo.bmiHeader.biBitCount = 32;
194 	bitmapinfo.bmiHeader.biHeight = m_nHeight;
195 	bitmapinfo.bmiHeader.biWidth = m_nWidth;
196 	bitmapinfo.bmiHeader.biPlanes = 1;
197 	bitmapinfo.bmiHeader.biCompression=BI_RGB;
198 	bitmapinfo.bmiHeader.biXPelsPerMeter=0;
199 	bitmapinfo.bmiHeader.biYPelsPerMeter=0;
200 	bitmapinfo.bmiHeader.biClrUsed=0;
201 	bitmapinfo.bmiHeader.biClrImportant=0;
202 	bitmapinfo.bmiHeader.biSizeImage = bitmapinfo.bmiHeader.biWidth * bitmapinfo.bmiHeader.biHeight * bitmapinfo.bmiHeader.biBitCount / 8;
203 	HBITMAP hBitmap=CreateDIBSection (m_hCacheDC,&bitmapinfo, 0,NULL, 0, 0);
204 	HBITMAP hOldBitmap = (HBITMAP)SelectObject (m_hCacheDC,hBitmap);
205 	//----------------------------------
206 	Gdiplus::Graphics* pGraphics=new Gdiplus::Graphics(m_hCacheDC);
207 	pGraphics->SetSmoothingMode (Gdiplus::SmoothingModeAntiAlias);
208 	pGraphics->SetTextRenderingHint (Gdiplus::TextRenderingHintAntiAlias);
209 
210     PreDrawLyric(pGraphics);
211     bool bDrawTranslate = m_bShowTranslate && !m_strTranslate.IsEmpty();
212     if (m_bDoubleLine && !m_strNextLyric.IsEmpty() && !bDrawTranslate)
213         DrawLyricsDoubleLine(pGraphics);
214     else
215         DrawLyrics(pGraphics);
216     AfterDrawLyric(pGraphics);
217 
218 	delete pGraphics;
219 	//----------------------------------
220 	//设置透明窗口
221 	CPoint DestPt(0,0);
222 	CSize psize(m_nWidth,m_nHeight);
223 	BLENDFUNCTION blendFunc32bpp;
224 	blendFunc32bpp.AlphaFormat = AC_SRC_ALPHA;
225 	blendFunc32bpp.BlendFlags = 0;
226 	blendFunc32bpp.BlendOp = AC_SRC_OVER;
227 	blendFunc32bpp.SourceConstantAlpha = m_alpha;
228 	HDC hDC=::GetDC(m_hWnd);
229 	::UpdateLayeredWindow(m_hWnd,hDC,NULL,&psize,m_hCacheDC,&DestPt,0,&blendFunc32bpp,ULW_ALPHA);
230 	//----------------------------------
231 	//释放资源
232 	::SelectObject (m_hCacheDC,hOldBitmap);
233 	::DeleteObject(hBitmap);
234 	::ReleaseDC(m_hWnd,hDC);
235 }
236 
237 void CLyricsWindow::DrawLyricText(Gdiplus::Graphics* pGraphics, LPCTSTR strText, Gdiplus::RectF rect, bool bDrawHighlight, bool bDrawTranslate)
238 {
239 	Gdiplus::REAL fontSize = bDrawTranslate ? m_FontSize * TRANSLATE_FONT_SIZE_FACTOR : m_FontSize;
240 	if (fontSize < 1)
241 		fontSize = m_FontSize;
242 
243     Gdiplus::REAL textWidth = rect.Width;
244     Gdiplus::REAL highlighWidth = rect.Width * m_nHighlight / 1000;
245 
246     if (!bDrawHighlight && !bDrawTranslate)
247     {
248         if (rect.X < 0)
249             rect.X = 0;
250     }
251     else
252     {
253         //如果文本宽度大于控件宽度,就要根据分割的位置滚动文本
254         if (textWidth > m_nWidth)
255         {
256             //如果分割的位置(歌词进度)剩下的宽度已经小于控件宽度的一半,此时使文本右侧和控件右侧对齐
257             if (textWidth - highlighWidth < m_nWidth / 2)
258             {
259                 rect.X = m_nWidth - textWidth;
260             }
261             //分割位置剩下的宽度还没有到小于控件宽度的一半,但是分割位置的宽度已经大于控件宽度的一半时,需要移动文本使分割位置正好在控件的中间
262             else if (highlighWidth > m_nWidth / 2)
263             {
264                 rect.X = m_nWidth / 2 - highlighWidth;
265             }
266             //分割位置还不到控件宽度的一半时,使文本左侧和控件左侧对齐
267             else
268             {
269                 rect.X = 0;
270             }
271         }
272     }
273 
274 	//-----------------------------------------------------------
275 	//画出阴影
276 	if (m_pShadowBrush) {
277 		Gdiplus::RectF layoutRect(0, 0, 0, 0);
278 		layoutRect = rect;
279 		layoutRect.X = layoutRect.X + m_nShadowOffset;
280 		layoutRect.Y = layoutRect.Y + m_nShadowOffset;
281 		Gdiplus::GraphicsPath* pShadowPath = new Gdiplus::GraphicsPath(Gdiplus::FillModeAlternate);//创建路径
282 		pShadowPath->AddString(strText, -1, m_pFontFamily, m_FontStyle, fontSize, layoutRect, m_pTextFormat); //把文字加入路径
283 		pGraphics->FillPath(m_pShadowBrush, pShadowPath);//填充路径
284 		delete pShadowPath; //销毁路径
285 	}
286 
287 	//-----------------------------------------------------------
288 	//画出歌词
289 	Gdiplus::GraphicsPath* pStringPath = new Gdiplus::GraphicsPath(Gdiplus::FillModeAlternate);//创建路径
290 	pStringPath->AddString(strText, -1, m_pFontFamily, m_FontStyle, fontSize, rect, m_pTextFormat); //把文字加入路径
291 	if (m_pTextPen) {
292 		pGraphics->DrawPath(m_pTextPen, pStringPath);//画路径,文字边框
293 	}
294 	Gdiplus::Brush* pBrush = CreateGradientBrush(m_TextGradientMode, m_TextColor1, m_TextColor2, rect);
295 	pGraphics->FillPath(pBrush, pStringPath);//填充路径
296 	delete pBrush;//销毁画刷
297 	if(bDrawHighlight)
298 		DrawHighlightLyrics(pGraphics, pStringPath, rect);
299 	delete pStringPath; //销毁路径
300 }
301 
302 //绘制歌词
303 void CLyricsWindow::DrawLyrics(Gdiplus::Graphics* pGraphics)
304 {
305     int lyricHeight = m_nHeight - m_toobar_height;
306 	//先取出文字宽度和高度
307 	Gdiplus::RectF layoutRect(0,0,0,0);
308 	Gdiplus::RectF boundingBox;
309     if (!m_lpszBeforeLyrics.IsEmpty())
310     {
311         pGraphics->MeasureString(m_lpszBeforeLyrics, -1, m_pFont, layoutRect, m_pTextFormat, &boundingBox, 0, 0);
312         auto bef_width{ boundingBox.Width };
313         pGraphics->MeasureString(L" ", -1, m_pFont, layoutRect, m_pTextFormat, &boundingBox, 0, 0);
314         auto sp_width{ boundingBox.Width };
315         m_lpszLyrics = m_lpszBeforeLyrics + L" " + m_lpszLyrics;
316         pGraphics->MeasureString(m_lpszLyrics, -1, m_pFont, layoutRect, m_pTextFormat, &boundingBox, 0, 0);
317         if(m_bBeforeLyrics)
318             m_nHighlight = m_nHighlight * bef_width / boundingBox.Width;
319         else
320             m_nHighlight = ((bef_width + sp_width) * 1000 + m_nHighlight * (boundingBox.Width - bef_width - sp_width)) / boundingBox.Width;
321     }
322 	else
323 	{
324 		pGraphics->MeasureString (m_lpszLyrics, -1, m_pFont,layoutRect, m_pTextFormat,&boundingBox, 0, 0);
325 	}
326     boundingBox.Width += 1;     //测量到的文本宽度加1,以防止出现使用某些字体时,最后一个字符无法显示的问题
327 	//计算歌词画出的位置
328 	Gdiplus::RectF dstRect;		//文字的矩形
329 	Gdiplus::RectF transRect;	//翻译文本的矩形
330     bool bDrawTranslate = m_bShowTranslate && !m_strTranslate.IsEmpty();
331 	if(!bDrawTranslate)
332 	{
333         switch (m_alignment)
334         {
335         case Alignment::LEFT:
336             dstRect = Gdiplus::RectF(0, m_toobar_height + (lyricHeight - boundingBox.Height) / 2, boundingBox.Width, boundingBox.Height);
337             break;
338         case Alignment::RIGHT:
339             dstRect = Gdiplus::RectF(m_nWidth - boundingBox.Width, m_toobar_height + (lyricHeight - boundingBox.Height) / 2, boundingBox.Width, boundingBox.Height);
340             break;
341         //居中
342         default:
343             dstRect = Gdiplus::RectF((m_nWidth - boundingBox.Width) / 2, m_toobar_height + (lyricHeight - boundingBox.Height) / 2, boundingBox.Width, boundingBox.Height);
344         }
345     }
346 	else
347 	{
348 		Gdiplus::RectF transBoundingBox;
349 		pGraphics->MeasureString(m_strTranslate, -1, m_pFont, layoutRect, m_pTextFormat, &transBoundingBox, 0, 0);
350         transBoundingBox.Width += 1;     //测量到的文本宽度加1,以防止出现使用某些字体时,最后一个字符无法显示的问题
351         Gdiplus::REAL translateHeight = transBoundingBox.Height * TRANSLATE_FONT_SIZE_FACTOR;
352 		Gdiplus::REAL translateWidth = transBoundingBox.Width * TRANSLATE_FONT_SIZE_FACTOR;
353 		Gdiplus::REAL gapHeight = boundingBox.Height * 0.2f;	//歌词和翻译之间的间隙
354 		Gdiplus::REAL height = boundingBox.Height + gapHeight + translateHeight;
355         switch (m_alignment)
356         {
357         case Alignment::LEFT:
358             dstRect = Gdiplus::RectF(0, m_toobar_height + (lyricHeight - height) / 2, boundingBox.Width, boundingBox.Height);
359             transRect = Gdiplus::RectF(0, dstRect.GetBottom() + gapHeight, translateWidth, translateHeight);
360             break;
361         case Alignment::RIGHT:
362             dstRect = Gdiplus::RectF((m_nWidth - boundingBox.Width), m_toobar_height + (lyricHeight - height) / 2, boundingBox.Width, boundingBox.Height);
363             transRect = Gdiplus::RectF((m_nWidth - translateWidth), dstRect.GetBottom() + gapHeight, translateWidth, translateHeight);
364             break;
365         default:
366 		    dstRect = Gdiplus::RectF((m_nWidth - boundingBox.Width) / 2, m_toobar_height + (lyricHeight - height) / 2, boundingBox.Width, boundingBox.Height);
367 		    transRect = Gdiplus::RectF((m_nWidth - translateWidth) / 2, dstRect.GetBottom() + gapHeight, translateWidth, translateHeight);
368             break;
369         }
370 	}
371 
372 	DrawLyricText(pGraphics, m_lpszLyrics, dstRect, m_lyric_karaoke_disp);
373 	if (bDrawTranslate)
374 		DrawLyricText(pGraphics, m_strTranslate, transRect, false, true);
375 }
376 
377 void CLyricsWindow::DrawLyricsDoubleLine(Gdiplus::Graphics* pGraphics)
378 {
379     int lyricHeight = m_nHeight - m_toobar_height;
380     static bool bSwap = false;
381     if (m_lyricChangeFlag)      //如果歌词发生了改变,则交换当前歌词和下一句歌词的位置
382         bSwap = !bSwap;
383     //先取出文字宽度和高度
384     Gdiplus::RectF layoutRect(0, 0, 0, 0);
385     Gdiplus::RectF boundingBox;
386     if (!m_lpszBeforeLyrics.IsEmpty())
387     {
388         pGraphics->MeasureString(m_lpszBeforeLyrics, -1, m_pFont, layoutRect, m_pTextFormat, &boundingBox, 0, 0);
389         auto bef_width{ boundingBox.Width };
390         pGraphics->MeasureString(L" ", -1, m_pFont, layoutRect, m_pTextFormat, &boundingBox, 0, 0);
391         auto sp_width{ boundingBox.Width };
392         m_lpszLyrics = m_lpszBeforeLyrics + L" " + m_lpszLyrics;
393         pGraphics->MeasureString(m_lpszLyrics, -1, m_pFont, layoutRect, m_pTextFormat, &boundingBox, 0, 0);
394         if (m_bBeforeLyrics)
395             m_nHighlight = m_nHighlight * bef_width / boundingBox.Width;
396         else
397             m_nHighlight = ((bef_width + sp_width) * 1000 + m_nHighlight * (boundingBox.Width - bef_width - sp_width)) / boundingBox.Width;
398     }
399     else
400     {
401         pGraphics->MeasureString(m_lpszLyrics, -1, m_pFont, layoutRect, m_pTextFormat, &boundingBox, 0, 0);
402     }
403     boundingBox.Width += 1;     //测量到的文本宽度加1,以防止出现使用某些字体时,最后一个字符无法显示的问题
404     Gdiplus::RectF nextBoundingBox;
405     pGraphics->MeasureString(m_strNextLyric, -1, m_pFont, layoutRect, m_pTextFormat, &nextBoundingBox, 0, 0);
406     nextBoundingBox.Width += 1; //测量到的文本宽度加1,以防止出现使用某些字体时,最后一个字符无法显示的问题
407     //计算歌词画出的位置
408     Gdiplus::RectF dstRect;		//文字的矩形
409     Gdiplus::RectF nextRect;	//下一句文本的矩形
410 
411     dstRect = Gdiplus::RectF(0, m_toobar_height + (lyricHeight / 2 - boundingBox.Height) / 2, boundingBox.Width, boundingBox.Height);
412     nextRect = Gdiplus::RectF(m_nWidth - nextBoundingBox.Width, dstRect.Y + lyricHeight / 2, nextBoundingBox.Width, nextBoundingBox.Height);
413 
414     if (bSwap)
415     {
416         std::swap(dstRect.Y, nextRect.Y);
417         nextRect.X = 0;
418         dstRect.X = m_nWidth - dstRect.Width;
419     }
420 
421     DrawLyricText(pGraphics, m_lpszLyrics, dstRect, true);
422     DrawLyricText(pGraphics, m_strNextLyric, nextRect, false);
423 }
424 
425 //绘制高亮歌词
426 void CLyricsWindow::DrawHighlightLyrics(Gdiplus::Graphics* pGraphics,Gdiplus::GraphicsPath* pPath, Gdiplus::RectF& dstRect)
427 {
428 	if(m_nHighlight<=0)return;
429 	Gdiplus::Region* pRegion=NULL;
430 	if(m_nHighlight<1000 && m_lyric_karaoke_disp){
431 		Gdiplus::RectF CliptRect(dstRect);
432 		CliptRect.Width=CliptRect.Width * m_nHighlight / 1000;
433 		pRegion=new Gdiplus::Region(CliptRect);
434 		pGraphics->SetClip(pRegion, Gdiplus::CombineModeReplace);
435 	}
436 	//--------------------------------------------
437 	if(m_pHighlightPen){
438 		pGraphics->DrawPath (m_pHighlightPen,pPath);//画路径,文字边框
439 	}
440 	Gdiplus::Brush* pBrush = CreateGradientBrush(m_HighlightGradientMode, m_HighlightColor1,m_HighlightColor2,dstRect);
441 	pGraphics->FillPath (pBrush,pPath);//填充路径
442 	delete pBrush;//销毁画刷
443 	//--------------------------------------------
444 	if(pRegion){
445 		pGraphics->ResetClip();
446 		delete pRegion;
447 	}
448 }
449 
450 //创建渐变画刷
451 Gdiplus::Brush* CLyricsWindow::CreateGradientBrush(LyricsGradientMode TextGradientMode,Gdiplus::Color& Color1,Gdiplus::Color& Color2, Gdiplus::RectF& dstRect)
452 {
453 	Gdiplus::PointF pt1;
454 	Gdiplus::PointF pt2;
455 	Gdiplus::Brush* pBrush=NULL;
456 	switch (TextGradientMode)
457 	{
458 	case LyricsGradientMode_Two://两色渐变
459 		{
460 			Gdiplus::PointF point1(dstRect.X,dstRect.Y);
461 			Gdiplus::PointF point2(dstRect.X,dstRect.Y+dstRect.Height);
462 			pBrush=new Gdiplus::LinearGradientBrush(point1,point2,Color1,Color2);
463 			((Gdiplus::LinearGradientBrush*)pBrush)->SetWrapMode(Gdiplus::WrapModeTileFlipXY);
464 			break;
465 		}
466 
467 	case LyricsGradientMode_Three://三色渐变
468 		{
469 			Gdiplus::PointF point1(dstRect.X,dstRect.Y);
470 			Gdiplus::PointF point2(dstRect.X,dstRect.Y+dstRect.Height/2);
471 			pBrush=new Gdiplus::LinearGradientBrush(point1,point2,Color1,Color2);
472 			((Gdiplus::LinearGradientBrush*)pBrush)->SetWrapMode(Gdiplus::WrapModeTileFlipXY);
473 			break;
474 		}
475 
476 	default://无渐变
477 		{
478 			pBrush=new Gdiplus::SolidBrush(Color1);
479 			break;
480 		}
481 	}
482 	return pBrush;
483 }
484 
485 //设置歌词颜色
486 void CLyricsWindow::SetLyricsColor(Gdiplus::Color TextColor1)
487 {
488 	CLyricsWindow::SetLyricsColor(TextColor1,Gdiplus::Color::Black,LyricsGradientMode_None);
489 }
490 void CLyricsWindow::SetLyricsColor(Gdiplus::Color TextColor1,Gdiplus::Color TextColor2,LyricsGradientMode TextGradientMode)
491 {
492 	m_TextColor1=TextColor1;
493 	m_TextColor2=TextColor2;
494 	m_TextGradientMode=TextGradientMode;
495 
496 }
497 //设置歌词边框
498 void CLyricsWindow::SetLyricsBorder(Gdiplus::Color BorderColor, Gdiplus::REAL BorderWidth)
499 {
500 	if(m_pTextPen){
501 		delete m_pTextPen;
502 		m_pTextPen=NULL;
503 	}
504 	if(BorderColor.GetA()>0 && BorderWidth>0)
505 		m_pTextPen=new Gdiplus::Pen(BorderColor,BorderWidth);
506 }
507 //设置高亮歌词颜色
508 void CLyricsWindow::SetHighlightColor(Gdiplus::Color TextColor1)
509 {
510 	CLyricsWindow::SetHighlightColor(TextColor1,Gdiplus::Color::Black,LyricsGradientMode_None);
511 }
512 void CLyricsWindow::SetHighlightColor(Gdiplus::Color TextColor1,Gdiplus::Color TextColor2,LyricsGradientMode TextGradientMode)
513 {
514 	m_HighlightColor1=TextColor1;
515 	m_HighlightColor2=TextColor2;
516 	m_HighlightGradientMode=TextGradientMode;
517 
518 }
519 //设置高亮歌词边框
520 void CLyricsWindow::SetHighlightBorder(Gdiplus::Color BorderColor, Gdiplus::REAL BorderWidth)
521 {
522 	if(m_pHighlightPen){
523 		delete m_pHighlightPen;
524 		m_pHighlightPen=NULL;
525 	}
526 	if(BorderColor.GetA()>0 && BorderWidth>0)
527 		m_pHighlightPen=new Gdiplus::Pen(BorderColor,BorderWidth);
528 }
529 //设置歌词阴影
530 void CLyricsWindow::SetLyricsShadow(Gdiplus::Color ShadowColor,int nShadowOffset)
531 {
532 	if(m_pShadowBrush){
533 		delete m_pShadowBrush;
534 		m_pShadowBrush=NULL;
535 	}
536 	if(ShadowColor.GetA()>0 && nShadowOffset>0){
537 		m_nShadowOffset=nShadowOffset;
538 		m_pShadowBrush=new Gdiplus::SolidBrush(ShadowColor);
539 	}else{
540 		m_nShadowOffset=0;
541 	}
542 }
543 //设置歌词字体
544 void CLyricsWindow::SetLyricsFont(const WCHAR * familyName, Gdiplus::REAL emSize,INT style, Gdiplus::Unit unit)
545 {
546 	if(m_pFont){
547 		delete m_pFont;
548 		m_pFont=NULL;
549 	}
550 	Gdiplus::FontFamily family(familyName,NULL);
551 	Gdiplus::Status lastResult = family.GetLastStatus();
552 	if (lastResult != Gdiplus::Ok)
553 	{
554 		HFONT hFont=(HFONT)GetStockObject(DEFAULT_GUI_FONT);
555 		LOGFONTW lf;
556 		ZeroMemory(&lf,sizeof(LOGFONTW));
557 		GetObjectW(hFont,sizeof(LOGFONTW),&lf);
558 		Gdiplus::FontFamily family2(lf.lfFaceName,NULL);
559 		m_pFont=new Gdiplus::Font(&family2,emSize,style,unit);
560 	}else{
561 		m_pFont=new Gdiplus::Font(&family,emSize,style,unit);
562 	}
563 	 //----------------
564 	//保存一些字体属性,加入路径时要用到
565 	m_pFont->GetFamily (m_pFontFamily);
566 	m_FontSize=m_pFont->GetSize ();
567 	m_FontStyle=m_pFont->GetStyle ();
568 
569 
570 
571 }
572 
573 void CLyricsWindow::SetLyricDoubleLine(bool doubleLine)
574 {
575 	m_bDoubleLine = doubleLine;
576 }
577 
578 void CLyricsWindow::SetNextLyric(LPCTSTR lpszNextLyric)
579 {
580 	m_strNextLyric = lpszNextLyric;
581 }
582 
583 void CLyricsWindow::SetShowTranslate(bool showTranslate)
584 {
585     m_bShowTranslate = showTranslate;
586 }
587 
588 void CLyricsWindow::SetAlpha(int alpha)
589 {
590     m_alpha = alpha;
591 }
592 
593 const CString& CLyricsWindow::GetLyricStr() const
594 {
595     return m_lpszLyrics;
596 }
597 
598 void CLyricsWindow::SetLyricChangeFlag(bool bFlag)
599 {
600     m_lyricChangeFlag = bFlag;
601 }
602 
603 void CLyricsWindow::SetAlignment(Alignment alignment)
604 {
605 	m_alignment = alignment;
606 }
607 
608 void CLyricsWindow::SetLyricKaraokeDisplay(bool karaoke_disp)
609 {
610     m_lyric_karaoke_disp = karaoke_disp;
611 }
612 
613 void CLyricsWindow::OnLButtonDown(UINT nFlags, CPoint point)
614 {
615 
616 	CWnd::OnLButtonDown(nFlags, point);
617 	//ReleaseCapture();
618 	//SendMessage(WM_NCLBUTTONDOWN,HTCAPTION,NULL);
619 }
620