我的问题是, 窗体的 TransparentColor 属性会在很大程度上影响到窗体的绘制效率, 有办法改善吗?有过经验的朋友应该知道, 如果想要做异形窗体(简单的比如四周圆角)就要用到窗体的 TransparentColor 属性.大家可以做一个实验, 就建一个空白 Form, 并把它的 TransparentColor 属性设置为 True. 同时与 TransparentColor 为 False 的空白窗体做比较, 在窗体最大化或拖动改变大小时, 绘制的效率相差很大. TransparentColor 为 True 的窗体的绘制效率低, 闪烁比较严重. 这还只是实验用的空白窗体, 如果再多放些控件的话, 效果就更不用说了.所以问题就是, 当设置了窗体的 TransparentColor 属性为 True 时, 有什么办法能改善这个窗体的绘制效率吗?请大家帮帮忙, 谢谢!
这样的效率肯定就会低了
你解释得没错, 但只是重述了我的问题现象, 而我要的是解决方案.@mjp1234airen4385
DoubleBuffered 属性并不能解决问题, 如果你先自试过就不会这样回答了.
"另外,使用GDI+处理。", 能详细说说应该怎么处理吗?
另外, 再补充一个实验参数, 要设置一下 TransparentColorValue, 不要用默认值, 可以设置成常用做透明色的紫色(clFuchsia)或绿色(clLime). 不然实验效果不明显. 可能 TForm 对默认值做了特别处理.
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
procedure CreateParams(var Params: TCreateParams); override;
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
Params.Style := (Params.Style or WS_POPUP) xor (ws_dlgframe)
xor WS_THICKFRAME;
end;procedure TForm1.FormCreate(Sender: TObject);
var
hr :thandle;
begin
hr:=createroundrectrgn(0,0,width,height,60,60);
setwindowrgn(handle,hr,true);
end;end.
单是"四周圆角"并不能满足我的要求, 不过 SetWindowRgn 却是个很好的入口, 之前我也尝试过, 裁剪窗体区域要比 Delphi 的计算背景绘图方式的所表现出来的效率好很多. 谢谢.根据这个思路, 那现在要解决的问题就是, 根据图像中指定的"透明色"来计算出非透明部分 Rgn 区域, 有谁做过这个的吗? 给个现成的算法好省我些时间, 我就再次谢谢了.
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));//????
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
Setwindowpos(Form1.Handle,HWND_TOPMOST,Form1.Left,form1.Top,Form1.Width,Form1.Height,0);
Rgn:=CreatepolygonRgn(Rgnpoints,High(RgnPoints),ALTERNATE);
SetWindowRgn(Handle,rgn,True);
Form1.color:=clgreen;
end;这是曾经有人csdn贴的代码实现一个五角星的窗口不知对你有没有用
我觉得画不规则窗体,用SetWindowRgn和设置透明色是两个思路
计算出显示部分 Rgn 区域是不是可以用其他办法,而不需要用颜色来区别
另外下面是TCustomForm中实现窗体透明或半透明的部分,看不出对默认色进行了处理
procedure TCustomForm.SetLayeredAttribs;
const
cUseAlpha: array [Boolean] of Integer = (0, LWA_ALPHA);
cUseColorKey: array [Boolean] of Integer = (0, LWA_COLORKEY);
var
AStyle: Integer;
begin
if not (csDesigning in ComponentState) and
(Assigned(SetLayeredWindowAttributes)) and HandleAllocated then
begin
AStyle := GetWindowLong(Handle, GWL_EXSTYLE);
if FAlphaBlend or FTransparentColor then
begin
if (AStyle and WS_EX_LAYERED) = 0 then
SetWindowLong(Handle, GWL_EXSTYLE, AStyle or WS_EX_LAYERED);
SetLayeredWindowAttributes(Handle, FTransparentColorValue, FAlphaBlendValue,
cUseAlpha[FAlphaBlend] or cUseColorKey[FTransparentColor]);
end
else
begin
SetWindowLong(Handle, GWL_EXSTYLE, AStyle and not WS_EX_LAYERED);
RedrawWindow(Handle, nil, 0, RDW_ERASE or RDW_INVALIDATE or RDW_FRAME or RDW_ALLCHILDREN);
end;
end;
end;
const
cUseAlpha: array [Boolean] of Integer = (0, LWA_ALPHA);
cUseColorKey: array [Boolean] of Integer = (0, LWA_COLORKEY);
var
AStyle: Integer;
begin
if not (csDesigning in ComponentState) and
(Assigned(SetLayeredWindowAttributes)) and HandleAllocated then
begin
AStyle := GetWindowLong(Handle, GWL_EXSTYLE);
if FAlphaBlend or FTransparentColor then
begin
if (AStyle and WS_EX_LAYERED) = 0 then
SetWindowLong(Handle, GWL_EXSTYLE, AStyle or WS_EX_LAYERED);
SetLayeredWindowAttributes(Handle, FTransparentColorValue, FAlphaBlendValue,
cUseAlpha[FAlphaBlend] or cUseColorKey[FTransparentColor]);
end
else
begin
SetWindowLong(Handle, GWL_EXSTYLE, AStyle and not WS_EX_LAYERED);
RedrawWindow(Handle, nil, 0, RDW_ERASE or RDW_INVALIDATE or RDW_FRAME or RDW_ALLCHILDREN);
end;
end;
end;这段代码不全,能发个全的吗?
[Error] Unit1.pas(32): Undeclared identifier: 'ComponentState'
有很多这样的报错?