显示歌词的控件 歌词文件是.lrc格式的 请下载我在CSDN里上传的酷狗音乐源码帮你更好理解
一。条用时请先在主程序里初始化GDI+:
1.在stdafx.h里添加
//----------------------------------------------------
#include "gdiplus.h" ////请修改为你的头文件路径 using namespace Gdiplus; #pragma comment(lib, "gdiplus.lib") ////请修改为你的.lib文件路径 //----------------------------------------------------------- 2.在××App里的初始化函数:InitInstance()里添加
初始化时
//---------------------------------------
GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); //-------------------------------------- 关闭时
//---------------------------------------
GdiplusShutdown(gdiplusToken); //------------------------------------- 二。初始化控件
geciwenj=new CGecikongjian;
geciwenj->Create(NULL, _T("歌词控件"), WS_CHILD, CRect(0,0,700,730), GetDesktopWindow(), 124); geciwenj->ShowWindow(SW_SHOW); geciwenj->OpenGeCiFile(存在在程序里的歌词文件名/在别处的带路径的歌词文件名);//打开歌词文件
三。歌词控件代码
/*******************************************************************************
文件名称 : Gecikongjian.h 头文件 作 者 : 杨治忠 创建时间 : 2010-12-20 15:45:17 文件描述 : 显示歌词控件 版权声明 : Copyright (C) 2010-2012 扬名科技 修改历史 : 杨治忠 2010-12-20 1.00 初始版本 *******************************************************************************/ #pragma once class CGecikongjian : public CWnd { DECLARE_DYNAMIC(CGecikongjian) public: void OpenGeCiFile(CString filename);//打开歌词文件 protected: typedef BOOL (WINAPI* lpfnUpdateLayeredWindow)(HWND hwnd,HDC hdcDst,POINT *pptDst,SIZE *psize,HDC hdcSrc,POINT *pptSrc,COLORREF crKey,BLENDFUNCTION *pblend,DWORD dwFlags); lpfnUpdateLayeredWindow UpdateLayeredWindow;//指针函数类型声明 void DrawGeCi(void);//显示歌词 CString texout;//歌词类容 double q;//一行歌词走动占整行的比例1 double m;//----------------2 int l;//-------------------3 CStdioFile file;//文件类对象 CString a[100];//存储打开歌词文件后的每行文字 int sum;//歌词文件的行数 void GetTimeAndGeci();//获取每个时间段和时间段对应的歌词 CString c[100];//每行歌词 int b[100];//每行时间 void TimeAndGeciPaiXu();//时间歌词排序 int sum1;//时间的段数 void YouHaGeCi();//把歌词里没用的符号去掉 DWORD readlen; BLENDFUNCTION m_Blend;//G++ public: CGecikongjian(); virtual ~CGecikongjian(); protected: DECLARE_MESSAGE_MAP() public: afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); public: afx_msg void OnTimer(UINT_PTR nIDEvent); public: };
/*******************************************************************************
文件名称 : Gecikongjian.cpp 实现文件 作 者 : 杨治忠 创建时间 : 2010-12-20 16:29:56 文件描述 : QQ号:940446982 VC技术QQ群:92790715欢迎加入 版权声明 : Copyright (C) 2010-2012 感谢技术支持 YZM 修改历史 : 杨治忠 2010-12-20 1.00 初始版本 *******************************************************************************/ #include "stdafx.h" #include "MyMp3Play.h" #include "Gecikongjian.h" extern int MusicTime;
IMPLEMENT_DYNAMIC(CGecikongjian, CWnd) CGecikongjian::CGecikongjian()
{ q = 0.0; m = 0.0; l = 0; texout = ""; } CGecikongjian::~CGecikongjian()
{ } BEGIN_MESSAGE_MAP(CGecikongjian, CWnd) ON_WM_CREATE() ON_WM_TIMER() END_MESSAGE_MAP() int CGecikongjian::OnCreate(LPCREATESTRUCT lpCreateStruct)
{ if (CWnd::OnCreate(lpCreateStruct) == -1) return -1; // TODO: 在此添加您专用的创建代码
/***************************************************
/********导出透明函数 *************************** /**************************************************/ HMODULE hMoudle=::GetModuleHandle(_T("user32.dll"));
if(hMoudle) { #ifndef WS_EX_LAYERED #define WS_EX_LAYERED 0x00080000 #endif SetWindowLong(GetSafeHwnd(),GWL_EXSTYLE,GetWindowLong(m_hWnd,GWL_EXSTYLE)|WS_EX_LAYERED); UpdateLayeredWindow=(lpfnUpdateLayeredWindow)GetProcAddress(hMoudle,_T("UpdateLayeredWindow")); } //GDI+ //--------------------------------------------------- m_Blend.BlendOp=0; //theonlyBlendOpdefinedinWindows2000 m_Blend.BlendFlags=0; //nothingelseisspecial... m_Blend.AlphaFormat=1; //... m_Blend.SourceConstantAlpha=255;//AC_SRC_ALPHA //---------------------------------------------- SetTimer(0,1000,NULL);//设置定时器 return 0; } /******************************************************************** 函数名称 ::DrawGeCi(void) 函数描述 :显示歌词 输入参数 : void 输出参数 : void 备注 : QQ号:940446982 VC技术QQ群:92790715欢迎加入 *********************************************************************/ void CGecikongjian::DrawGeCi(void) { RECT rct; GetWindowRect(&rct); HDC hdcTemp=GetDC()->m_hDC; HDC m_hdcMemory=CreateCompatibleDC(hdcTemp); HBITMAP hBitMap=CreateCompatibleBitmap(hdcTemp,rct.right - rct.left, rct.bottom - rct.top ); SelectObject(m_hdcMemory,hBitMap); m_Blend.SourceConstantAlpha=60; Graphics graphics(m_hdcMemory);
FontFamily fontFamily(L"宋体"); Font font(&fontFamily, 45, FontStyleBold, UnitPixel); SolidBrush solidBrush(Color(255, 0, 0, 255)); graphics.SetTextRenderingHint(TextRenderingHintSingleBitPerPixel); graphics.DrawString( texout.AllocSysString(), (INT)wcslen(texout.AllocSysString()), &font, PointF(10, 10), &solidBrush); int b; b=(INT)wcslen(texout.AllocSysString())*q; SolidBrush solidBrush1(Color(255, 255, 0,0)); graphics.SetTextRenderingHint(TextRenderingHintSingleBitPerPixel); graphics.DrawString( texout.AllocSysString(),b , &font, PointF(10, 10), &solidBrush1); HDC hdcScreen=::GetDC (m_hWnd); POINT ptWinPos={rct.left,rct.top}; POINT ptSrc={0,0};
SIZE sizeWindow={rct.right - rct.left, rct.bottom - rct.top}; BOOL bRet=FALSE; bRet= UpdateLayeredWindow( m_hWnd,hdcScreen,&ptWinPos, &sizeWindow,m_hdcMemory,&ptSrc,0,&m_Blend,2); graphics.ReleaseHDC(m_hdcMemory);
::ReleaseDC(m_hWnd,hdcScreen); hdcScreen=NULL; ::ReleaseDC(m_hWnd,hdcTemp); hdcTemp=NULL; DeleteObject(hBitMap); DeleteDC(m_hdcMemory); m_hdcMemory=NULL; } /******************************************************************** 函数名称 : OpenGeCiFile(CString filename) 函数描述 :打开歌词文件 备注 : QQ号:940446982 VC技术QQ群:92790715欢迎加入 *********************************************************************/ void CGecikongjian::OpenGeCiFile(CString filename) { try
{ file.Open(filename,CFile::modeRead); }catch(CFileException* e) { TCHAR szBuf[256]; e->GetErrorMessage(szBuf,256,NULL); MessageBox(szBuf,_T("错误")); e->Delete(); } CString readstring; if(file) { if (readlen==file.GetLength()) return; int i = 0; while(file.ReadString(readstring))
{ a[i]=readstring;
i++; }
file.Close(); sum=i; } GetTimeAndGeci(); TimeAndGeciPaiXu(); YouHaGeCi(); } /******************************************************************** 函数名称 : GetTimeAndGeci() 函数描述 : 获取时间和时间对应的歌词 备注 : QQ号:940446982 VC技术QQ群:92790715欢迎加入 *********************************************************************/ void CGecikongjian::GetTimeAndGeci() { int k=0; for(int j=0;j<sum;j++) { CString strGet; int nMinute; int nSecond; TCHAR szMinute[10]; TCHAR szSecond[10]; lstrcpy(szMinute,""); lstrcpy(szSecond,""); int point=0;
point= a[j].Find(":",0); if(point==-1) { b[k]=0; c[k]=a[j]; k++; } else { //分 strGet=a[j].Left(point); strGet=strGet.Right(2); lstrcpy(szMinute,strGet); nMinute=atoi(szMinute); //秒 strGet=a[j].Right(a[j].GetLength()-point-1); if(strGet.GetLength()==1) strGet=strGet.Left(1); else if(strGet.GetLength()>=2) strGet=strGet.Left(2); lstrcpy(szSecond,strGet); nSecond=atoi(szSecond); b[k]=nMinute*60+nSecond; c[k]=a[j]; k++; point= a[j].Find(":",10); if (point!=-1) { strGet=a[j].Left(point); strGet=strGet.Right(2); lstrcpy(szMinute,strGet); nMinute=atoi(szMinute); //秒 strGet=a[j].Right(a[j].GetLength()-point-1); if(strGet.GetLength()==1) strGet=strGet.Left(1); else if(strGet.GetLength()>=2) strGet=strGet.Left(2); lstrcpy(szSecond,strGet); nSecond=atoi(szSecond); b[k]=nMinute*60+nSecond; c[k]=a[j]; k++; } } } sum1=k; }
/******************************************************************** 函数名称 : TimeAndGeciPaiXu() 函数描述 : 对时间和时间对应的歌词排序 备注 : QQ号:940446982 VC技术QQ群:92790715欢迎加入 *********************************************************************/ void CGecikongjian::TimeAndGeciPaiXu() { for (int j=0;j<sum1;j++) for(int i=0;i<sum1-j;i++) if (b[i]>b[i+1]) { int t; CString s; t=b[i]; s=c[i]; b[i]=b[i+1]; c[i]=c[i+1]; b[i+1]=t; c[i+1]=s; } }
/******************************************************************** 函数名称 : YouHaGeCi() 函数描述 : 把歌词里没用的符号去掉 备注 : QQ号:940446982 VC技术QQ群:92790715欢迎加入 *********************************************************************/ void CGecikongjian::YouHaGeCi() { for (int i=0;i<100;i++) { if (b[i]!=0) { DWORD o=0; DWORD j=0; DWORD h=0; j=c[i].GetLength();//获取该行长度
o=c[i].Find("]",0);//找到"]"的位置 h=j-o-1; c[i]=c[i].Right(h);//去掉"]"前的类容 //重复一遍,因为有的行有两个时间 j=c[i].GetLength();//获取该行长度 o=c[i].Find("]",0);//找到"]"的位置 h=j-o-1; c[i]=c[i].Right(h);//去掉"]"前的类容 }
} } void CGecikongjian::OnTimer(UINT_PTR nIDEvent) { // TODO: 在此添加消息处理程序代码和/或调用默认值 if (MusicTime<1)
{ texout=c[0]+c[1]; } for (int i=0;i<100;i++)
{ if(b[i]==(MusicTime+1))
{ texout=c[i]; l=b[i+1]-b[i]; if (l<0) { l=b[i]-b[i-1]; } m=1.0/l; q=0.0; }
} q+=m; if (q>1) { q=m; } DrawGeCi(); Invalidate(); CWnd::OnTimer(nIDEvent); } |
|