我写了个圆角的panel组件,重绘的时候会一直闪烁,设计期和运行期都是如此,请大家看看!
这是Paint事件
procedure TRoundPanel.Paint;
var
rect:TRect;
i:integer;
tmpPS:PAINTSTRUCT;
myHDC:HDC;
begin
if FRoundPanel then
begin
rect:=self.ClientRect;
myHDC:=BeginPaint(Handle,tmpPS);
for i:=5 downto 1 do
begin
canvas.Pen.Color:= BaseColor+FStepColor;
canvas.RoundRect(rect.Left+i,rect.Top+i,rect.Right-i,rect.Bottom-i,FRoundWidth,FRoundHeight);
end;
RoundClientArea;
EndPaint(Handle,tmpPS);
end;
inherited Paint;
end;
//是下面这个事件导致闪烁
procedure TRoundPanel.RoundClientArea;
var
rect:Trect;
rgn:Hrgn;
begin
rect:=self.ClientRect;
Rgn:=CreateRoundRectRgn(rect.Left,rect.Top,rect.Right,rect.Bottom,FRoundWidth,FRoundHeight);
setWindowRgn(self.Handle,rgn,true);(是这个语句导致的)
end;
这是Paint事件
procedure TRoundPanel.Paint;
var
rect:TRect;
i:integer;
tmpPS:PAINTSTRUCT;
myHDC:HDC;
begin
if FRoundPanel then
begin
rect:=self.ClientRect;
myHDC:=BeginPaint(Handle,tmpPS);
for i:=5 downto 1 do
begin
canvas.Pen.Color:= BaseColor+FStepColor;
canvas.RoundRect(rect.Left+i,rect.Top+i,rect.Right-i,rect.Bottom-i,FRoundWidth,FRoundHeight);
end;
RoundClientArea;
EndPaint(Handle,tmpPS);
end;
inherited Paint;
end;
//是下面这个事件导致闪烁
procedure TRoundPanel.RoundClientArea;
var
rect:Trect;
rgn:Hrgn;
begin
rect:=self.ClientRect;
Rgn:=CreateRoundRectRgn(rect.Left,rect.Top,rect.Right,rect.Bottom,FRoundWidth,FRoundHeight);
setWindowRgn(self.Handle,rgn,true);(是这个语句导致的)
end;
解决方案 »
- 我想你了
- l如何对包括自动加1字段的数据表添加新记录
- delphi打印的实现
- 設置RichEdit只能輸入一行資料,怎么做?
- delphi中怎么获得系统时间的小时,分钟
- tserversocket/tclientsocket写的程序,碰到几个问题解决不了了,
- 关于ModelMaker中的接口和自动生成代码的问题?
- DBGRIDEH多行选中的问题?
- 毕业设计
- 怎样在Delphi中实现类似Foxpro中 var1=&var2 (var2="aa"),即实现 var1=aa
- 那位好心人能给个delphi7 的update下载?
- 怎么发布用Delphi + Sql Server 2000 写的数据库应用程序——————在线等待!!!!!!
而RoundClientArea调用了setWindowRgn(self.Handle,rgn,true);
而setWindowRgn的第三个参数为True,所以它立刻重绘,于是Paint方法又被调用.....这样就处于不停的重绘状态了
var
Rgn: HRGN;
left, top, right, bottom: integer;
begin
top := -height;
left := -width;
right := mControl.BoundsRect.Right + width;
bottom := mControl.BoundsRect.bottom + height;
if (style and 1) > 0 then
begin
top := top + height;
left := left + width;
end;
if (style and 2) > 0 then
begin
if (style and 1) = 0 then
left := left + width;
bottom := bottom - height;
end;
if (style and 4) > 0 then
begin
if (style and 2) = 0 then
bottom := bottom - height;
right := right - width;
end;
if (style and 8) > 0 then
begin
if (style and 4) = 0 then
right := right - width;
if (style and 1) = 0 then
top := top + height;
end;
Rgn := CreateRoundRectRgn(left, top, right, bottom, Width, height);
SetWindowRgn(mControl.Handle, rgn, true);
end;
我把源代码贴出来大家共同探讨一下。其实我觉得写过控件的应该觉得很简单。unit RoundPanel;interfaceuses
SysUtils, Classes, Controls, ExtCtrls,graphics,windows,messages,Themes;type
TRoundPanel = class(TPanel)
private
FStepColor:int64;
FBaseColor:TColor;
FRoundPanel:boolean;
FRoundWidth:integer;
FRoundHeight:integer;
procedure SetStepColor(StepColor:int64);
procedure SetBaseColor(BaseColor:TColor);
procedure SetRoundPanel(RoundPanel:boolean);
procedure SetRoundWidth(RoundWidth:integer);
procedure SetRoundHeight(RoundHeight:integer);
procedure RoundClientArea;
protected
procedure WMEraseBkgnd(var Message: TWMEraseBkgnd);
message WM_ERASEBKGND;
procedure Paint;override;
public
procedure PaintRound;
constructor Create(AOwner: TComponent);override;
published
property StepColor:int64 read FStepColor Write SetStepColor default 1000000;
property BaseColor:TColor read FBaseColor write SetBaseColor default clBtnFace;
property RoundPanel:boolean read FRoundPanel Write SetRoundPanel default false;
property RoundWidth:integer read FRoundWidth write SetRoundWidth default 0;
property RoundHeight:integer read FRoundHeight write SetRoundHeight default 0;
end;procedure Register;implementationprocedure Register;
begin
RegisterComponents('Samples', [TRoundPanel]);
end;constructor TRoundPanel.Create(AOwner: TComponent);
begin
inherited Create(AOwner);end;procedure TRoundPanel.Paint;
var
rect:TRect;
i:integer;
tmpPS:PAINTSTRUCT;
myHDC:HDC;
begin
inherited Paint;
if FRoundPanel then
begin
rect:=self.ClientRect;
myHDC:=BeginPaint(Handle,tmpPS);
for i:=5 downto 1 do
begin
canvas.Pen.Color:= BaseColor+FStepColor;
canvas.RoundRect(rect.Left+i,rect.Top+i,rect.Right-i,rect.Bottom-i,FRoundWidth,FRoundHeight);
end;
//RoundClientArea;
EndPaint(Handle,tmpPS);
end;end;procedure TRoundPanel.SetStepColor(StepColor:int64);
begin
FStepColor:=StepColor;
end;procedure TRoundPanel.SetBaseColor(BaseColor:TColor);
begin
FBaseColor:=BaseColor;
end;procedure TRoundPanel.SetRoundPanel(RoundPanel:boolean);
begin
FRoundPanel:=RoundPanel;
end;procedure TRoundPanel.SetRoundWidth(RoundWidth:integer);
begin
FRoundWidth:=RoundWidth;
end;procedure TRoundPanel.SetRoundHeight(RoundHeight:integer);
begin
FRoundHeight:=RoundHeight;
end;procedure TRoundPanel.WMEraseBkgnd(var Message: TWMEraseBkgnd);
begin
Message.Result := 0;
end;procedure TRoundPanel.RoundClientArea;
var
rect:Trect;
rgn:Hrgn;
begin
rect:=self.ClientRect;
Rgn:=CreateRoundRectRgnrect.Left,rect.Top,rect.Right,rect.Bottom,FRoundWidth,FRoundHeight);
setWindowRgn(self.Handle,rgn,false);
end;procedure TRoundPanel.PaintRound;
begin
RoundClientArea;
paint;
end;end.
希望高手们给出具体点的建议来!
var
HT: THandle;HT := CreateRoundRectRgn(0, 0, Width, Height, RX, RY);//RX,RY就是圆角控制,integer;SetWindowRgn(Handle, HT, True);然后用 Pen 的大小来描一下边框就很好了。不用那么复杂;以上纯属个人之见!!