Delphi以GDI+制作桌面歌词效果

Posted sjwics

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Delphi以GDI+制作桌面歌词效果相关的知识,希望对你有一定的参考价值。

在Windows XP下效果图:

技术图片

在Windows 7下有焦点时效果图:

技术图片

在Windows 7下无焦点时效果图:
技术图片

在Windows 7下右键菜单效果图:

技术图片

      很多音频播放软件都带有桌面歌词效果,在桌面上显示歌词字幕,可以设置是否置顶桌面,是否背景穿透等等。要实现这样的效果方法有很多种,利用GDI+的特性来实现桌面歌词效果,可以达到歌词字幕的平滑柔和。在参考了CodeProject的一篇文章,文章标题《To Create A COOL Desktop Lyrics Demo 》链接地址:http://www.codeproject.com/KB/GDI-plus/DesktopLyrics.aspx。这是使用C++和GDI+来实现的,在这里我另外使用Delphi和GDI+来再次实现下,前提需要Delphi配置GDI+环境,若是Delphi 7的话可参考文章《Delphi 7下IGDIPlus库的使用》,链接地址:http://blog.csdn.net/akof1314/archive/2011/02/24/6205578.aspx

       新建一个应用程序,在窗体上放置一个TTimer和一个TPopupMenu,TTimer的Interval属性为1500,TPopupMenu建立三个子菜单项,分别为“总在最前”、“背景穿透”和“退出”。再准备一张背景图片。工程源代码如下:

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
  {*******************************************************} 
{                                                       } 
{       环境:Delphi 7 + IGDIPlus                       } 
{                                                       } 
{       作者:无幻 http://blog.csdn.net/akof1314        } 
{                                                       } 
{*******************************************************} 
unit Unit1; 
 
interface 
 
uses 
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs, IGDIPlus, ExtCtrls, Menus; 
 
type 
  TForm1 = class(TForm) 
    tmr1: TTimer; 
    pm1: TPopupMenu; 
    mni_topMost: TMenuItem; 
    mni_transparent: TMenuItem; 
    mni_exit: TMenuItem; 
    procedure FormCreate(Sender: TObject); 
    procedure FormMouseDown(Sender: TObject; Button: TMouseButton; 
      Shift: TShiftState; X, Y: Integer); 
    procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, 
      Y: Integer); 
    procedure tmr1Timer(Sender: TObject); 
    procedure mni_topMostClick(Sender: TObject); 
    procedure MouseLeave(var Msg: TMessage);message WM_MOUSELEAVE; 
    procedure mni_transparentClick(Sender: TObject); 
    procedure mni_exitClick(Sender: TObject); 
  private 
    m_Kind: Integer;        //当前第几行字符串 
    m_bBack: Boolean;       //是否显示背景 
    m_pszbuf: array[0..5] of WideString;   //要绘制的字符串数组 
    function UpdateDisplay(pszbuf: WideString;bBack: Boolean = False; 
        Transparent: Integer = 100):Boolean; 
  public 
    { Public declarations } 
  end
 
var 
  Form1: TForm1; 
 
implementation 
 
{$R *.dfm} 
{------------------------------------------------------------------------------- 
  过程名:    TForm1.UpdateDisplay 
  功能:      绘制桌面歌词 
  参数:      pszbuf: WideString;     绘制的字符串 
             bBack: Boolean;         是否绘制背景 
             Transparent: Integer    透明程度 
  返回值:    Boolean 
-------------------------------------------------------------------------------} 
function TForm1.UpdateDisplay(pszbuf: WideString;bBack: Boolean;Transparent: Integer):Boolean; 
var 
  hdcTemp,hdcScreen,m_hdcMemory: HDC; 
  hBitMap: Windows.HBITMAP; 
  blend: BLENDFUNCTION;      //这种结构的混合控制通过指定源和目标位图的混合功能 
  rct: TRect; 
  ptWinPos,ptSrc: TPoint; 
  graphics: IGPGraphics;     //封装一个 GDI+ 绘图图面 
  fontFamily: IGPFontFamily; //定义有着相似的基本设计但在形式上有某些差异的一组字样 
  path: IGPGraphicsPath;     //表示一系列相互连接的直线和曲线 
  strFormat: IGPStringFormat;//封装文本布局信息,显示操作 
  pen,pen1,pen2: IGPPen;     //定义用于绘制直线和曲线的对象 
  linGrBrush,linGrBrushW: IGPLinearGradientBrush;  //使用线性渐变封装 Brush 
  brush: IGPSolidBrush;      //定义单色画笔,画笔用于填充图形形状 
  image: TGPImage;           //使用这个类来创建和操作GDI+图像 
  i: Integer; 
  sizeWindow: SIZE; 
begin 
  //---------------------开始:初始化操作-------------------------------------- 
  hdcTemp := GetDC(Self.Handle); 
  m_hdcMemory := CreateCompatibleDC(hdcTemp); 
  hBitMap := CreateCompatibleBitmap(hdcTemp,755,350); 
  SelectObject(m_hdcMemory,hBitMap); 
  if (Transparent < 0or (Transparent > 100then 
    Transparent := 100
  with blend do 
  begin 
    BlendOp := AC_SRC_OVER;     //把源图片覆盖到目标之上 
    BlendFlags := 0
    AlphaFormat := AC_SRC_ALPHA;//每个像素有各自的alpha通道 
    SourceConstantAlpha :=Trunc(Transparent * 2.55);  //源图片的透明度 
  end
  hdcScreen := GetDC(Self.Handle); 
  GetWindowRect(Self.Handle,rct); 
  ptWinPos := Point(rct.Left,rct.Top); 
  graphics := TGPGraphics.Create(m_hdcMemory); 
  graphics.SetSmoothingMode(SmoothingModeAntiAlias); //指定平滑(抗锯齿) 
  graphics.SetInterpolationMode(InterpolationModeHighQualityBicubic);//指定的高品质,双三次插值 
  fontFamily := TGPFontFamily.Create(‘微软雅黑‘); //△字体,效果图为‘微软雅黑‘字体 
  strFormat := TGPStringFormat.Create(); 
  path := TGPGraphicsPath.Create(); 
  //---------------------结束:初始化操作-------------------------------------- 
  path.AddString(pszbuf,          //要添加的 String 
                fontFamily,       //表示绘制文本所用字体的名称 
                0,                //指定应用到文本的字形信息,这里为普通文本 
                38,               //限定字符的 Em(字体大小)方框的高度 
                MakePoint(10,10), //一个 Point,它表示文本从其起始的点 
                strFormat);       //指定文本格式设置信息 
  pen := TGPPen.Create(MakeColor(155,215,215,215),3);  //颜色、宽度 
  graphics.DrawPath(pen,path);    //初步绘制GraphicsPath 
  linGrBrush := TGPLinearGradientBrush.Create(MakePoint(0,0),    //线性渐变起始点 
                                                MakePoint(0,90), //线性渐变终结点 
                                                MakeColor(255,255,255,255), //线性渐变起始色 
                                                MakeColor(255,30,120,195)); //线性渐变结束色 
  linGrBrushW := TGPLinearGradientBrush.Create(MakePoint(0,10), 
                                                MakePoint(0,60), 
                                                MakeColor(255,255,255,255), 
                                                MakeColor(15,1,1,1)); 
  //---------------------开始:画字符串阴影-------------------------------------- 
  for i := 1 to 8 do 
  begin 
    pen.SetWidth(i); 
    pen.SetColor(MakeColor(62022)); 
    pen.SetLineJoin(LineJoinRound); //指定圆形联接。这将在两条线之间产生平滑的圆弧。 
    graphics.DrawPath(pen,path); 
  end
  //---------------------开始:画背景框和背景图---------------------------------- 
  if bBack then 
  begin 
    brush := TGPSolidBrush.Create(MakeColor(25,228,228,228)); 
    pen1 := TGPPen.Create(MakeColor(155,223,223,223)); 
    pen2 := TGPPen.Create(MakeColor(55,223,223,223)); 
    image := TGPImage.Create(‘back.png‘);             //背景图片 
    graphics.FillRectangle(brush,3,5,750,90);         //填充背景框色 
    graphics.DrawRectangle(pen1,2,6,751,91);          //内层背景框 
    graphics.DrawRectangle(pen2,1,5,753,93);          //外层背景框 
    graphics.DrawImage(image,600,25); 
  end
  //---------------------开始:以渐变色笔刷填充GraphicsPath内部----------------- 
  graphics.FillPath(linGrBrush,path); 
  graphics.FillPath(linGrBrushW,path); 
  sizeWindow.cx := 755
  sizeWindow.cy := 350
  ptSrc := Point(0,0); 
  //---------------------开始:更新一个分层的窗口的位置,大小,形状,内容和半透明度--- 
  Result := UpdateLayeredWindow(Self.Handle,   //分层窗口的句柄 
                                hdcScreen,     //屏幕的DC句柄 
                                @ptWinPos,     //分层窗口新的屏幕坐标 
                                @sizeWindow,   //分层窗口新的大小 
                                m_hdcMemory,   //用来定义分层窗口的表面DC句柄 
                                @ptSrc,        //分层窗口在设备上下文的位置 
                                0,             //合成分层窗口时使用指定颜色键值 
                                @blend,        //在分层窗口进行组合时的透明度值 
                                ULW_ALPHA);    //使用pblend为混合功能 
  //---------------------开始:释放和删除-------------------------------------- 
  ReleaseDC(Self.Handle,hdcScreen); 
  ReleaseDC(Self.Handle,hdcTemp); 
  DeleteObject(hBitMap); 
  DeleteDC(m_hdcMemory); 
end
{------------------------------------------------------------------------------- 
  功能:      窗体创建初始化 
-------------------------------------------------------------------------------} 
procedure TForm1.FormCreate(Sender: TObject); 
begin 
  //设置窗体属性 
  SetWindowLong(Application.Handle, 
                GWL_EXSTYLE, 
                GetWindowLong(Application.Handle,GWL_EXSTYLE) 
                or WS_EX_TOOLWINDOW);   //不在任务栏出现 
  SetWindowLong(Self.Handle, 
                GWL_EXSTYLE, 
                GetWindowLong(Self.Handle,GWL_EXSTYLE) 
                or WS_EX_LAYERED       //层次窗口 
                or WS_EX_TOOLWINDOW);  //不在alt+tab中出现 
  //初始化变量等等 
  m_kind := 0
  m_bBack := False; 
  PopupMenu := pm1; 
  Self.Cursor := crHandPoint; 
  mni_topMost.Checked := True; 
  mni_topMostClick(mni_topMost); 
 
  m_pszbuf[0] := ‘你好 Everyone!‘
  m_pszbuf[1] := ‘这是GDI+绘制的桌面歌词!‘
  m_pszbuf[2] := ‘欢迎光临无幻博客!‘
  m_pszbuf[3] := ‘http://blog.csdn.net/akof1314!‘
  m_pszbuf[4] := ‘源码根据需要进行修改!‘
  UpdateDisplay(m_pszbuf[m_kind],m_bBack); 
end
{------------------------------------------------------------------------------- 
  功能:      鼠标按下移动窗体 
-------------------------------------------------------------------------------} 
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; 
  Shift: TShiftState; X, Y: Integer); 
begin 
  ReleaseCapture; 
  SendMessage(Self.Handle,WM_SYSCOMMAND,SC_MOVE or HTCAPTION,0); 
end
{------------------------------------------------------------------------------- 
  功能:      鼠标移过窗体 
-------------------------------------------------------------------------------} 
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, 
  Y: Integer); 
var 
  xh: TTrackMouseEvent; 
begin 
  m_bBack := True; 
  UpdateDisplay(m_pszbuf[m_kind],m_bBack); 
  with xh do 
  begin 
    cbSize := SizeOf(xh); 
    dwFlags := TME_LEAVE; 
    hwndTrack := Self.Handle; 
    dwHoverTime := 0
  end
  TrackMouseEvent(xh); 
end
{------------------------------------------------------------------------------- 
  功能:      鼠标移出窗体时,去掉背景 
-------------------------------------------------------------------------------} 
procedure TForm1.MouseLeave(var Msg: TMessage); 
begin 
  m_bBack := False; 
  UpdateDisplay(m_pszbuf[m_kind],m_bBack); 
  Msg.Result := 0
end
{------------------------------------------------------------------------------- 
  功能:      定时器切换字符串 
-------------------------------------------------------------------------------} 
procedure TForm1.tmr1Timer(Sender: TObject); 
begin 
  Inc(m_Kind); 
  if m_kind > 4 then 
    m_kind := 0
  UpdateDisplay(m_pszbuf[m_kind],m_bBack); 
end
{------------------------------------------------------------------------------- 
  功能:      窗体置顶 
-------------------------------------------------------------------------------} 
procedure TForm1.mni_topMostClick(Sender: TObject); 
begin 
  if mni_topMost.Checked then 
  SetWindowPos(Self.Handle, 
               HWND_TOPMOST, 
               0,0,0,0
               SWP_NOSIZE or SWP_NOMOVE)    //窗口置顶 
  else 
  SetWindowPos(Self.Handle, 
               HWND_NOTOPMOST, 
               0,0,0,0
               SWP_NOSIZE or SWP_NOMOVE);    //窗口置顶 
end
{------------------------------------------------------------------------------- 
  功能:      背景穿透 (相当于锁定桌面) 
-------------------------------------------------------------------------------} 
procedure TForm1.mni_transparentClick(Sender: TObject); 
begin 
  SetWindowLong(Self.Handle, 
                GWL_EXSTYLE, 
                GetWindowLong(Self.Handle,GWL_EXSTYLE) or WS_EX_TRANSPARENT); 
  Application.MessageBox(‘你已关闭不了程序了,请从任务管理器里关闭‘
                        ‘提示‘,MB_OK or MB_ICONINFORMATION); 
end
{------------------------------------------------------------------------------- 
  功能:      退出 
-------------------------------------------------------------------------------} 
procedure TForm1.mni_exitClick(Sender: TObject); 
begin 
  Self.Close; 
end
 
end

工程源码下载:http://download.csdn.net/source/3291760

 

 

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net

以上是关于Delphi以GDI+制作桌面歌词效果的主要内容,如果未能解决你的问题,请参考以下文章

请问怎样用VB6.0做出文字在屏幕上流动的效果啊?像千千静听的歌词秀那样谢谢!

如何在 WINAPI GDI 中制作淡入淡出效果?

Delphi: 圆形进度(环形进度)

如何让图片以半透明的效果显示在所有程序或窗口的最上层?

如何使用奥特歌词制作双语LRC字幕

ios16桌面图标转盘效果