关于透明控件,不规则按纽与窗体(200分)

  • 主题发起人 主题发起人 hgm99
  • 开始时间 开始时间
H

hgm99

Unregistered / Unconfirmed
GUEST, unregistred user!
1 透明控件基于 WINDOWS 的什么原理?哪些 API 函数?
2 透明控件、窗体有什么作用?产生什么样的效果?
3 透明控件、透明窗体的实现机制和具体方法?
4 常在浏览网页时看到许多很酷的按纽,比如说椭圆形的,类似手机上的按纽,DELPHI中
怎样实现?
5 许多软件比如 UNINSTALL,SYSTEM MECHANISM 等的界面都设计得很有特色,还有许多
网页设计成一个MP3播放机的样子,怎样使我 DELPHI 程序界面也象这样漂亮,比如象
一辆跑车或象一个手机?
 
不规则窗口:
unit StarRgnU;

interface

uses
Windows, Forms, Controls,
StdCtrls, Classes, Messages;


type
TForm1 = class(TForm)
CloseBtn: TButton;
Label1: TLabel;
procedure FormCreate(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure CloseBtnClick(Sender: TObject);
private
{ Private declarations }
procedure WmNCHitTest(var Msg :
TWMNCHitTest); message WM_NCHITTEST;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}
const
{ An array of points for the star region. }
RgnPoints : array[1..10] of TPoint =
((X:203;Y:22), (X:157;Y:168), (X:3;Y:168),
(X:128;Y:257), (X:81;Y:402), (X:203;Y:334),
(X:325;Y:422), (X:278;Y:257), (X:402;Y:168),
(X:249;Y:168));

{ An array of points used to draw a line }
{ around the region in the OnPaint handler. }
LinePoints : array[1..11] of TPoint =
((X:199;Y:0), (X:154;Y:146), (X:2;Y:146),
(X:127;Y:235), (X:79;Y:377), (X:198;Y:308),
(X:320;Y:396), (X:272;Y:234),(X:396;Y:146),
(X:244;Y:146), (X:199;Y:0));

procedure TForm1.FormCreate(Sender: TObject);
var
Rgn : HRGN;
begin
{ Create a polygon region from our points. }
Rgn := CreatePolygonRgn(
RgnPoints, High(RgnPoints), ALTERNATE);

{ Set the window region. }
SetWindowRgn(Handle, Rgn, True);
end;

procedure TForm1.FormPaint(Sender: TObject);
begin
{ Draw a line around the star. }
Canvas.Pen.Width := 3;
Canvas.Polyline(LinePoints);
end;

procedure TForm1.CloseBtnClick(Sender: TObject);
begin
Close();
end;

{ Catch the WM_NCHITTEST message so the user }
{ can drag the window around the screen. }
procedure TForm1.
WmNCHitTest(var Msg: TWMNCHitTest);
begin
DefaultHandler(Msg);
if Msg.Result = HTCLIENT then
Msg.Result := HTCAPTION;
end;

end.
 
CreateRectRgn,CreateRectRgnIndirect, CreateRoundRectRgn,
DeleteObject, SelectObject,SetRectRgn等API函数
想要详细信息和代码的话请与我联系
skyline@2bzd.com
 
1 透明控件和窗口的原理都是通过把控件或窗口的背景提取出来,成为一幅图,然后把
该图显示在控件或窗口上就达到了透明的效果。用到的 API 函数有:getwindowrect、
getdc、getdesktopwindow等。不过在win2000下可用SetWindowsAttribute(不知是否写错)
函数来设置窗口的透明度。

2 透明控件、窗体的主要作用是产生不同的视觉效果,并且有时需要看请窗口的背景。
3 你看了下面的文章后,你就能大概了解透明控件、透明窗体的实现机制和具体方法了。
如何制作半透明窗口
松本电工实业有限公司
舒嵩嵩
---- 用过金山词霸的朋友,一定会为其半透明的翻译提示窗口而称奇。究竟这种窗口是如何做出来的呢?下面我们将来探讨这种半透明的窗口的制作方法。

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

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

---- (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.
---- 程序的运行效果如图(一)所示。

三、 结束语
---- 需要说明的是:由于受到以上滤镜算法的速度影响,所以窗口显示时有所延迟,在窗口频繁显示和关闭时不是很流畅。但不知读者朋友们有没有发现,金山词霸的半透明窗口效果只能在带MMX指令集的处理器中才起作用,所以笔者大胆推测,金山词霸的半透明窗口是经过MMX的多媒体指令集进行优化的,这样它才可以达到理想的效果。有兴趣的朋友可以试一下,说不定您做得比金山词霸还好呢。 ---- 以上程序在中文Windows 98、Delphi 4 C/S环境下编译通过。

4 这个通常都是用图片来实现这样的效果。
5 其实要做出这样的效果的最大难点是你要设计出漂亮的图片来,图片做出来了,就容易了,
因为现在有很多控件帮我们,自己做的话,我估计程序的运行效率不高。
 
多人接受答案了。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
553
import
I
后退
顶部