开发圆角Panel的问题,老闪!

yinxd6112 2006-01-11 10:28:49
我写了个圆角的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;
...全文
307 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
yinxd6112 2006-01-17
  • 打赏
  • 举报
回复
有没意义,纯属个人见解,本人已做好,谢谢各位,给分
xzhifei 2006-01-16
  • 打赏
  • 举报
回复
这东西做成控件没有多大的意义,还不如像 ahjoe(强哥) 所说的那样做
postfxj 2006-01-16
  • 打赏
  • 举报
回复
不錯。學習。
baiduan 2006-01-16
  • 打赏
  • 举报
回复
学习
ahjoe 2006-01-16
  • 打赏
  • 举报
回复
应该在Panel的OnResize事件中SetWindowRgn
Frank.WU 2006-01-12
  • 打赏
  • 举报
回复
我的意思也是做成控件啊,不过过程简单一点而已,将我上面的那代码写入一个子过程,让用户控制圆角和颜色好了。
lvjun 2006-01-11
  • 打赏
  • 举报
回复
你不应该在重绘的时候设置不规则窗体,应该在大小改变时(或者时位置变化时)设置
alexanda2000 2006-01-11
  • 打赏
  • 举报
回复
你的Paint方法调用了RoundClientArea;
而RoundClientArea调用了setWindowRgn(self.Handle,rgn,true);
而setWindowRgn的第三个参数为True,所以它立刻重绘,于是Paint方法又被调用.....

这样就处于不停的重绘状态了
yinxd6112 2006-01-11
  • 打赏
  • 举报
回复
我也是想这么做,可老板让作成控件,我晕,所以一大堆问题就出来了,烦!
Frank.WU 2006-01-11
  • 打赏
  • 举报
回复
这样开发出来的也不是圆角 Panel 啊,其实只要用
var
HT: THandle;

HT := CreateRoundRectRgn(0, 0, Width, Height, RX, RY);//RX,RY就是圆角控制,integer;

SetWindowRgn(Handle, HT, True);

然后用 Pen 的大小来描一下边框就很好了。不用那么复杂;

以上纯属个人之见!!
yinxd6112 2006-01-11
  • 打赏
  • 举报
回复
setWindowRgn(self.Handle,rgn,true)这句话的第3个参数即使改为false也不行,同样的问题。
我把源代码贴出来大家共同探讨一下。其实我觉得写过控件的应该觉得很简单。

unit RoundPanel;

interface

uses
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;

implementation

procedure 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.


希望高手们给出具体点的建议来!
jinjazz 2006-01-11
  • 打赏
  • 举报
回复
{曲线化控件}

procedure MakeRound(mControl: TWinControl; Width, height: integer; style: byte);
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;
coffee36 2006-01-11
  • 打赏
  • 举报
回复
学习

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧