如何制作半透明窗口

字体大小: 中小 标准 ->行高大小: 标准
如何制作半透明窗口

---- 用过金山词霸的朋友,一定会为其半透明的翻译提示窗口而称奇。究竟这种窗口是如何做出来的呢?下面我们将来探讨这种半透明的窗口的制作方法。

一、 原理

---- 首先,我们先从透明窗口说起,其实透明窗口就是可以透过窗口看到它背景。所以,我们可以将窗口后面的背景图象,显示在窗口前面,就可实现透明窗口的效果了。至于半透明的效果,是在透明的基础上,加上一层滤镜,使看到的背景模糊一点而已。所以,在拿到背景图象后,先在该图象加上一层滤镜(把图象弄模糊),然后再显示在窗口上,就能达到半透明的效果。

---- 我们可归纳出实现半透明窗口的步骤:在窗口显示前其获取背景图 → 对背景图象进行滤镜效果处理 → 将处理过的背景图象显示在窗口前面。

---- (1) 获取背景图象

---- 要获取背景图,先用GetDC(0)函数获取整个屏幕设备场景(DC),再用CopyRect函数拷贝窗口的背景到指定的Tbitmap,该Tbitmap就是我们所要的图象了。其中函数GetDC(0)取得的DC可用TCanvas.Handle保存;而CopyRect是TCancas类的成员函数,作用是从一Canvas中拷贝一指定区域(Rect)到另一Canvas的指定区域。

---- (2)对背景图进行滤镜效果处理

---- 用循环的方法遍历图象的每一点,将各点的某些频段的光波滤除。其实,滤镜种类繁多,所以的算法亦很多,读者们可参考相关资料,选择您满意的方法。本文的滤镜是灰色的,实现方法见TranslucentBmp(Bmp:TBitmap;AColor:TColor;ATransparent:Longint)。其中,参数Bmp是要处理的图象,AColor是滤镜的颜色,ATransparent是透明度。

二、 写程序

----

将以上原理用Delphi编写成程序,在Delphi中新建一Project,Form1的Height和Width分别设成150和300(不要做的太大,不然显示速度很慢),再设置BorderStyle的值为bsNone;在Form1中添加一Timage控件Image1,将其Align属性设成alClient。再添加一标签Label1和按钮TSpeedButton,在Label1的Caption属性中输入"这是一半透明窗口!",按钮的Caption属性设成"x",在其onClick事件中输入一行"Close;"。并将它们Bring to Front。另外,可添加四个TShape,贴在Image1的四边上,以构造Form1的3D效果,如图(一)。各控件的属性如下表:

组件名称 属性 设置值

Form1 BorderStyle BsNone

Height 150

Width 300

TFont 宋体9号

Image1 Align AlClient

Label1 Caption 这是一半透明窗口!

TFont 宋体9号,黄色

SpeedButton1 Caption X

Left 279

Top -1

Height 14

Width 13

Transparent True

 

 

图(一)

---- 完整的源代码如下:

unit Unit1;

interface

uses

Windows, Messages, SysUtils, Classes,

Graphics, Controls, Forms, Dialogs,

StdCtrls, ExtCtrls, Buttons;

type

TForm1 = class(TForm)

Label1: TLabel;

Shape1: TShape;

Shape2: TShape;

Shape3: TShape;

Shape4: TShape;

Image1: TImage;

SpeedButton1: TSpeedButton;

procedure FormCreate(Sender: TObject);

procedure SpeedButton1Click(Sender: TObject);

private

{ Private declarations }

//截获背景图象

function GetBackgroundBmp:TBitmap;

//对背景图象进行滤镜处理

procedure TranslucentBmp(Bmp:TBitmap;

AColor:TColor;ATransparent:Longint);

public

{ Public declarations }

end;

var

Form1: TForm1;

implementation

{$R *.DFM}

//以下截获背景图象

function TForm1.GetBackgroundBmp:TBitmap;

var Scn:TCanvas;

h,w:Integer;

begin

Scn:=TCanvas.Create; //建立整个屏幕的画布

h:=ClientHeight;//窗口的高

w:=ClientWidth; //窗口的宽

Result.Height:=h; //设返回位图的高就是窗口的高

Result.Width:=w;//设返回位图的宽就是窗口的宽

try

Scn.Handle:=GetDC(0);//取得整个屏幕的DC

//以下一行将窗口的背景部分复制到指定的画布中,

也就是本函数的返回值

Result.Canvas.CopyRect(Rect(0,0,w,h),Scn,

Rect(Left,Top,Left+w,Top+h));

ReleaseDC(0, Scn.handle);

finally

Scn.Free;

end;

end;

//以下函数对背景图象进行滤镜处理,

Bmp是要处理的位图;ATransparent是透明度

procedure TForm1.TranslucentBmp(Bmp:

TBitmap;AColor:TColor;ATransparent:Longint);

var BkColor:COLORREF;

ForeColor:Longint;

R,G,B:Int64;

i,j:Integer;

begin

ForeColor:=ColorToRGB(AColor);

with Bmp.Canvas do

for i:=ClientHeight-1 downto 0 do

for j:=ClientWidth-1 downto 0 do

begin

BkColor:=GetPixel(Handle,j,i); //取得每一象素

R:=Byte(ForeColor)+

(Byte(BkColor)-Byte(ForeColor))*ATransparent;

G:=Byte(ForeColor shr 8)+

(Byte(BkColor shr 8)-Byte(ForeColor

shr 8))*ATransparent;

B:=Byte(ForeColor shr 16)+

(Byte(BkColor shr 16)-Byte(ForeColor

shr 16))*ATransparent;

SetPixelV(Handle,j,i,RGB(R,G,B));//合成象素

end;

end;

procedure TForm1.FormCreate(Sender: TObject);

var BackgroundBmp:TBitmap;

begin

try

BackgroundBmp:=Tbitmap.Create;

//建立窗口背景图

BackgroundBmp.PixelFormat:=pf24bit;

//指定该图是24位真彩色

BackgroundBmp:=GetBackgroundBmp;

//取得窗口背景图

TranslucentBmp(BackgroundBmp,clBlack,50);

//对该图象进行滤镜处理

Image1.Picture.Bitmap:=BackgroundBmp;

//将处理过的图象显示出来

finally

BackgroundBmp.Free;

end;

end;

procedure TForm1.SpeedButton1Click

(Sender: TObject);

begin

Close;

end;

end.

 

三、 结束语

---- 需要说明的是:由于受到以上滤镜算法的速度影响,所以窗口显示时有所延迟,在窗口频繁显示和关闭时不是很流畅

此文章由 http://www.ositren.com 收集整理 ,地址为: http://www.ositren.com/htmls/68373.html