我是利用Mask文件做的,你看看吧!
现实制作Mask文件:
procedure TForm1.SaveMask(Image:TImage;TransColor:TColor;FileName:String);
var
x,y:integer;
RgnSize:integer;
Rgndata:pRGNDATA;
OutFile:TFileStream;
hRgn1,hRgn2:hrgn;
StartPos,EndPos:integer;
begin
hRgn1:=0;
hRgn2:=0;
ProgressBar1.Min:=0;
ProgressBar1.Max:=Image.Height;
ProgressBar1.Step:=1;
ProgressBar1.Position:=0;
for y:=0 to Image.Height-1 do
begin
x:=0;
EndPos:=x;
repeat
StartPos:=x;
inc(x);
while(Image.Canvas.Pixels[x,y]<>TransColor)
AND (x<=Image.Width) do
begin
//Image.Canvas.Pixels[x,y]:=clBlue;
Inc(x);
end;
EndPos:=x;
if StartPos<>Image.Width then
begin
if EndPos=Image.Width then Dec(EndPos);
if hRgn1=0 then
begin
hRgn1:=CreateRectRgn(StartPos+1,y,EndPos,y+1);
end
else
begin
hRgn2:=CreateRectRgn(StartPos+1,y,EndPos,y+1);
if hRgn2<>0 then CombineRgn(hRgn1,hRgn1,hRgn2,RGN_OR);
DeleteObject(hRgn2);
end;
end;
until x>=Image.Width-1;
ProgressBar1.StepIt;
end;
if hRgn1<>0 then
begin
OutFile:=TFileStream.Create(FileName,fmCreate);
RgnSize:=GetRegionData(hRgn1,0,nil);
OutFile.Write(RgnSize,sizeof(RgnSize)); GetMem(RgnData,RgnSize);
GetRegionData(hRgn1,RgnSize,RgnData);
if OutFile.Write(RgnData^,RgnSize)=0 then
ShowMEssage('bai');
FreeMem(RgnData,RgnSize);
OutFile.Free;
end;
ShowMessage('完成!');
end;
再来就是利用Mask文件生成窗口:
procedure TForm1.CreateMyForm();
var
InFile:TFileStream;
hRgn:Thandle;
Rgndata:pRGNData;
RgnSize:Integer;
begin
InFile:=TFileStream.Create(Edit1.Text,fmOpenRead);
InFile.Read(RgnSize,sizeof(RgnSize)); GetMem(RgnData,RgnSize);
InFile.Read(RgnData^,RgnSize); with RgnData^.rdh.rcBound do
begin
Form1.Width:=Right-Left;
Form1.Height:=Bottom-Top;
end; hRgn:=ExtCreateRegion(nil,RgnSize,RgnData^); FreeMem(RgnData,RgnSize);
InFile.Free; Form1.BorderStyle:=bsNone;
Label1.Visible:=false;
Edit1.Visible:=false;
SpeedButton1.Visible:=false;
SpeedButton2.Visible:=false;
SetWindowRgn(Form1.Handle,hRgn,True);
end;
现实制作Mask文件:
procedure TForm1.SaveMask(Image:TImage;TransColor:TColor;FileName:String);
var
x,y:integer;
RgnSize:integer;
Rgndata:pRGNDATA;
OutFile:TFileStream;
hRgn1,hRgn2:hrgn;
StartPos,EndPos:integer;
begin
hRgn1:=0;
hRgn2:=0;
ProgressBar1.Min:=0;
ProgressBar1.Max:=Image.Height;
ProgressBar1.Step:=1;
ProgressBar1.Position:=0;
for y:=0 to Image.Height-1 do
begin
x:=0;
EndPos:=x;
repeat
StartPos:=x;
inc(x);
while(Image.Canvas.Pixels[x,y]<>TransColor)
AND (x<=Image.Width) do
begin
//Image.Canvas.Pixels[x,y]:=clBlue;
Inc(x);
end;
EndPos:=x;
if StartPos<>Image.Width then
begin
if EndPos=Image.Width then Dec(EndPos);
if hRgn1=0 then
begin
hRgn1:=CreateRectRgn(StartPos+1,y,EndPos,y+1);
end
else
begin
hRgn2:=CreateRectRgn(StartPos+1,y,EndPos,y+1);
if hRgn2<>0 then CombineRgn(hRgn1,hRgn1,hRgn2,RGN_OR);
DeleteObject(hRgn2);
end;
end;
until x>=Image.Width-1;
ProgressBar1.StepIt;
end;
if hRgn1<>0 then
begin
OutFile:=TFileStream.Create(FileName,fmCreate);
RgnSize:=GetRegionData(hRgn1,0,nil);
OutFile.Write(RgnSize,sizeof(RgnSize)); GetMem(RgnData,RgnSize);
GetRegionData(hRgn1,RgnSize,RgnData);
if OutFile.Write(RgnData^,RgnSize)=0 then
ShowMEssage('bai');
FreeMem(RgnData,RgnSize);
OutFile.Free;
end;
ShowMessage('完成!');
end;
再来就是利用Mask文件生成窗口:
procedure TForm1.CreateMyForm();
var
InFile:TFileStream;
hRgn:Thandle;
Rgndata:pRGNData;
RgnSize:Integer;
begin
InFile:=TFileStream.Create(Edit1.Text,fmOpenRead);
InFile.Read(RgnSize,sizeof(RgnSize)); GetMem(RgnData,RgnSize);
InFile.Read(RgnData^,RgnSize); with RgnData^.rdh.rcBound do
begin
Form1.Width:=Right-Left;
Form1.Height:=Bottom-Top;
end; hRgn:=ExtCreateRegion(nil,RgnSize,RgnData^); FreeMem(RgnData,RgnSize);
InFile.Free; Form1.BorderStyle:=bsNone;
Label1.Visible:=false;
Edit1.Visible:=false;
SpeedButton1.Visible:=false;
SpeedButton2.Visible:=false;
SetWindowRgn(Form1.Handle,hRgn,True);
end;
你可以做成彩色的,创建Form后,再将这幅图贴到背景上去,就好看了!
在窗体上放一个图象空间使之充满整个窗体区域.
在图象空间上放一张背景透明的bmp,设置图象控件的透明属性为真.
让窗体透明(brush.style:=bsclear),属性为无边框(bsnone)
编译执行.此时窗体的样子就和bmp的非透明部分一样啦...
(brush.style:=bsclear)怎么做??
email:[email protected]
多谢你能给我一个控件
Email:[email protected]
我觉得使画刷窗体属性为clear,然后设置image的透明属性为真,那么其实也就实现了mask的功能.
首先,窗体是透明的,不会影响外观.
其次,其次,bmp图象透明的部分(就是mask的值,好象是值与[0,0]相同的吧?)不会显示出来,也不会影响外观.这样的话,你的bmp图象是什么样子,你的窗体也就是什么样子啦.例如小猫小狗或者轻舞飞扬什么的:)Talent(塔伦特) :
你的bmp是什么样子,窗体就是什么样子.可以随意的啊~~
不过我觉得还是他们说的CreateRect比较正规一些...
而且我所做的这个,需要在窗体的透明方面下工夫...
HRGN rgn参数是关键
var Rgn : DWORD;//VC也可以这样定义的。——————————————————————————————————————————
要做到一个不规则的窗口,你可以在Form 的Create事件中加入以下程序:
(这个程序的意思是在窗体上开一个椭圆的洞)procedure TForm1.FormCreate(Sender: TObject);
var Rgn1,Rgn2 : DWORD;
re : TRect;
begin Rgn2:=CreateEllipticRgn(100,100,450,300);//定义一个椭圆的区域
re:=GetClientRect();//把窗体的短形数据放入TRect变量中
Rgn1:=CreateRectRgn(re.left,re.top,re.right+10,re.bottom+100);
//创建一个和窗体一样大小的区域 CombineRgn(Rgn1,Rgn1,Rgn2,RGN_XOR);
//用异或的方式把两个区域合并,并把合并后听区域放入Rgn1变量中
SetWindowRgn(Form1.handle,Rgn1,TRUE);
//设置窗体显示的区域。
end;
——————————————————————————————————————————
以下是有关区域的Windows API函数,用它们可以创建各种不规则的区域,
详情请参看MSDN和Delphi的Win32帮助。
CombineRgn
CreateEllipticRgn
CreateEllipticRgnIndirect
CreatePolygonRgn
CreatePolyPolygonRgn
CreateRectRgn
CreateRectRgnIndirect
CreateRoundRectRgn
EqualRgn
ExtCreateRegion
FillRgn
FrameRgn
GetPolyFillMode
GetRegionData
GetRgnBox
InvertRgn
OffsetRgn
PaintRgn
PtInRegion
RectInRegion
SetPolyFillMode
——————————————————————————————————————————
以下是有关Path的Windows API函数,用它们可以创建更加不规则的窗口,
如:一个楷体字的形状的窗口。
详情请参看MSDN和Delphi的Win32帮助。AbortPath
BeginPath
CloseFigure
EndPath
FillPath
FlattenPath
GetMiterLimit
GetPath
PathToRegion
SetMiterLimit
StrokeAndFillPath
StrokePath
WidenPath
——————————————————————————————————————
BTW:例程我就不发了,有什么问题可以再请教我。