在许多流行的MP3播放器中,桌面歌词功能是一个非常酷且受欢迎的特性。非常喜欢这个功能,因此决定尝试实现它。然而,发现这并不容易。在这里,首先要感谢所有CodeProject的贡献者,因为从GDI+部分学到了很多。在对GDI+函数进行了复习之后,编写了这段代码。希望它对有所帮助。这是送给CodeProject成员的礼物。新年快乐!现在就下载演示程序,享受乐趣吧!
让来看一下代码。这个演示是如何创建的。这个演示是基于对话框而不是类。但是,不会多谈生成对话框的基本步骤。假设已经知道MFC的用法。想要了解更多,请阅读其他文章或MSDN在线。
使用GDI+函数,所以第一件事是包含头文件和库文件。
#define UNICODE
#ifndef ULONG_PTR
#define ULONG_PTR unsigned long*
#endif
#include "gdiplus.h" // 修改为路径
using namespace Gdiplus;
#pragma comment(lib, "gdiplus.lib") // 修改为库路径
将这些代码片段添加到对话框的头文件中。当然,也可以修改自己计算机的路径。确保路径正确,否则VC找不到它。
使用类向导添加了几个消息处理函数。
WM_CREATE WM_TIMER WM_CONTENTMENU WM_DESTROY WM_LBUTTONDOWN
// ...更多,请下载资源。
将使用GDI+,所以必须在调用其函数之前调用
GdiplusStartup()
。在应用程序退出之前,需要调用另一个函数
GdiplusShutdown()
// 将以下代码放入构造方法
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
// 调用函数以清除
void CGDIAPPDlg::OnDestroy()
{
CDialog::OnDestroy();
GdiplusShutdown(gdiplusToken);
// TODO: 在这里添加消息处理代码
}
好的!已经完成了第一项工作。
对话框的初始化。想要调用
UpdateLayeredWindow()
在
"user32.dll"
中,所以需要获取该函数的地址。
int CGDIAPPDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDialog::OnCreate(lpCreateStruct) == -1)
return -1;
hFuncInst = LoadLibrary("User32.DLL");
BOOL bRet=FALSE;
if (hFuncInst)
UpdateLayeredWindow=(MYFUNC)GetProcAddress(hFuncInst, "UpdateLayeredWindow");
else
{
AfxMessageBox("User32.dll ERROR!");
exit(0);
}
// 初始化GDI+。
m_Blend.BlendOp=0;
m_Blend.BlendFlags=0;
m_Blend.AlphaFormat=1;
m_Blend.SourceConstantAlpha=255;
return 0;
}
好的!现在开始思考如何在桌面上绘制。方法是:
编写了一个方法来完成所有工作,就像其他人(其他人的代码片段)所做的那样。以下是代码。让来看一下细节:
BOOL CGDIAPPDlg::UpdateDisplay(int Transparent)
{
HDC hdcTemp=GetDC()->m_hDC;
m_hdcMemory=CreateCompatibleDC(hdcTemp);
//Create the compatibleDC
HBITMAP hBitMap=CreateCompatibleBitmap(hdcTemp, 755, 350);
//Create the compatible bitmap
SelectObject(m_hdcMemory,hBitMap);
//Select bitmap into device content
if (Transparent < 0 || Transparent > 100) Transparent=100;
m_Blend.SourceConstantAlpha=int(Transparent*2.55);
//1~255
HDC hdcScreen=::GetDC (m_hWnd);
RECT rct;
GetWindowRect(&rct);
POINT ptWinPos={rct.left,rct.top};
Graphics graph(m_hdcMemory);
Graphics graphics(m_hdcMemory);
graphics.SetSmoothingMode(SmoothingModeAntiAlias);
graphics.SetInterpolationMode(InterpolationModeHighQualityBicubic);
FontFamily fontFamily(L"Arial Black");
StringFormat strformat;
//Here is the text we want to show on the desktop, we can read it from a file.
//I'll modify it later.
wchar_t pszbuf[][80]={L"Hello everyone!", L"Happy New Year!", L"I wish you will lead a happy life!", L"Love you!", L"Thanks all the people on CP!"};
//The following code is used to draw the text on dc
GraphicsPath path;
path.AddString(pszbuf[m_kind], wcslen(pszbuf[m_kind]), &fontFamily, FontStyleRegular, 38, Point(10, 10), &strformat);
Pen pen(Color(155, 215, 215, 215), 3);
graphics.DrawPath(&pen, &path);
LinearGradientBrush linGrBrush(Point(0, 0), Point(0, 90), Color(255, 255, 255, 255), Color(255, 30, 120, 195));
LinearGradientBrush linGrBrushW(Point(0, 10), Point(0, 60), Color(255, 255, 255, 255), Color(15, 1, 1, 1));
/*
Draw shade ,I study from others.
*/
for (int i=1; i<9; i+=1)
{
Pen pen(Color(62, 0, 2, 2), i);
pen.SetLineJoin(LineJoinRound);
graphics.DrawPath(&pen, &path);
}
SolidBrush brush(Color(25, 228, 228, 228));
Pen pen1(Color(155, 223, 223, 223));
Pen pen2(Color(55, 223, 223, 223));
Image image(L"ly.png");
if (m_bBack)
{
graphics.FillRectangle(&brush, 3, 5, 750, 90);
graphics.DrawRectangle(&pen1, 2, 6, 751, 91);
graphics.DrawRectangle(&pen2, 1, 5, 753, 93);
graphics.DrawImage(ℑ, 600, 5);
}
graphics.FillPath(&linGrBrush, &path);
graphics.FillPath(&linGrBrushW, &path);
SIZE sizeWindow={755, 350};
POINT ptSrc={0, 0};
DWORD dwExStyle=GetWindowLong(m_hWnd, GWL_EXSTYLE);
//Don't forget to set the dialog's extent style.
if ((dwExStyle&0x80000)!=0x80000)
SetWindowLong(m_hWnd, GWL_EXSTYLE, dwExStyle^0x80000);
BOOL bRet=FALSE;
bRet= UpdateLayeredWindow( m_hWnd, hdcScreen, &ptWinPos, &sizeWindow, m_hdcMemory, &ptSrc, 0, &m_Blend, 2);
graph.ReleaseHDC(m_hdcMemory);
::ReleaseDC(m_hWnd, hdcScreen);
hdcScreen=NULL;
::ReleaseDC(m_hWnd, hdcTemp);
hdcTemp=NULL;
DeleteObject(hBitMap);
DeleteDC(m_hdcMemory);
m_hdcMemory=NULL;
return bRet;
}