再开新贴讨论,mdejtod 或其他熟悉Gdi+的进,解决后一起结贴给分!

孤独的行者牛 2011-12-10 09:09:51
前两贴地址:
http://topic.csdn.net/u/20111118/07/da4a9390-82df-4c23-88fc-90193b9e330b.html
(已结)
http://topic.csdn.net/u/20111129/21/2f3a8d3c-def9-4427-a505-7ccd6fbde2de.html
(未结)

一段时间没搞它了
再翻出来,我找到问题了,再次求教!

当按件被其他窗体或滚动到不可见区域,再次出现时,Windows自动发出WM_Paint消息!
这时候就有问题了!
若仅是有部分被挡住,重绘的时候,未被挡住的部分,也会再绘制一次,这样就造成同一个控件两部分不一样
(因为和透明渐变,所以效果不一样了!)
求教:
怎么样让它在重绘之前,清除其内容呢?或者说恢复控件未被重绘时的状态呢?

期待 mdejtod 再次出现……
...全文
92 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
孤独的行者牛 2011-12-11
  • 打赏
  • 举报
回复
网上找了好多资料,难道要 自己处理 WM_ERASEBKGND 消息?????
关键怎么处理呢……
孤独的行者牛 2011-12-11
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 delphiteacher 的回复:]

几点想法:
出现楼主的情况是因为滚动条滚动之后没有重绘客户区所导致,
……
[/Quote]

问题就在这里,现在是肯定重绘了,但是连有效区域也重绘了,相当于有效区域绘制了两次,不知道朋友还能不能理解我出的问题噢 …………

PS:若只重绘部分的话,因为实际绘制的比上面的效果图复杂,而且是一个渐变,所以若去度算重区域,是比较麻烦
孤独的行者牛 2011-12-11
  • 打赏
  • 举报
回复
上面的贴图很明了,对比一下

左边的是正常绘制的

右边的,下半部分正常,因为下半部分,被滚到不可见的地方后,再滚动出来,这样,整个控件会重绘,下半部是无效域,重绘后正常!但上半部分,实际上被绘制了两次,造成效果异常!

所以,问题在于,在重绘时(WM_Paint消息处理中),怎么样强制清除原来的效果……

再次感谢……
DelphiTeacher 2011-12-10
  • 打赏
  • 举报
回复
几点想法:
出现楼主的情况是因为滚动条滚动之后没有重绘客户区所导致,
一可能是楼主从没编写过控件,
还有一个可能是楼主没有看过TScrollBox及其父类TScrollingWinControl的代码,懒所导致,
楼主的控件在三种情况下需要重绘,一个拖动过大小,还有就是垂直和水平滚动条滚动之后,
需要在三个消息的事件处理中进行手动重绘,WM_SIZE,WM_HSCROLL,WM_WSCROLL这三个消息

我贴的最后一份是加入了双缓冲的,提高绘制效率的
DelphiTeacher 2011-12-10
  • 打赏
  • 举报
回复

unit SkinScrollBox;

interface

uses
Windows,SysUtils,Classes,Controls,Forms,GdiPlus,Messages,Graphics,Types;


type
TSkinScrollBox=class(TScrollBox)
private
FBufferBitmap:TBitmap;
protected
procedure WMEraseBkGnd(var Message:TWMEraseBkGnd);message WM_ERASEBKGND;
procedure WMHScroll(var Message: TWMHScroll); message WM_HSCROLL;
procedure WMVScroll(var Message: TWMVScroll); message WM_VSCROLL;
procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
procedure PaintWindow(DC: HDC); override;
procedure WMSize(var Message: TWMSize); message WM_SIZE;
public
constructor Create(AOwner:TComponent);override;
destructor Destroy;override;
published
property Align;
property Anchors;
property AutoScroll;
property AutoSize;
property BevelEdges;
property BevelInner;
property BevelOuter;
property BevelKind;
property BevelWidth;
property BiDiMode;
property BorderStyle;
property Constraints;
property DockSite;
property DoubleBuffered;
property DragCursor;
property DragKind;
property DragMode;
property Enabled;
property Color;
property Ctl3D;
property Font;
property Padding;
property ParentBiDiMode;
property ParentBackground default False;
property ParentColor;
property ParentCtl3D;
property ParentDoubleBuffered;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ShowHint;
property TabOrder;
property TabStop;
property Touch;
property Visible;
property OnCanResize;
property OnClick;
property OnConstrainedResize;
property OnContextPopup;
property OnDblClick;
property OnDockDrop;
property OnDockOver;
property OnDragDrop;
property OnDragOver;
property OnEndDock;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnGesture;
property OnGetSiteInfo;
property OnMouseActivate;
property OnMouseDown;
property OnMouseEnter;
property OnMouseLeave;
property OnMouseMove;
property OnMouseUp;
property OnMouseWheel;
property OnMouseWheelDown;
property OnMouseWheelUp;
property OnResize;
property OnStartDock;
property OnStartDrag;
property OnUnDock;
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('SkinEngine',[TSkinScrollBox]);
end;

{ TSkinScrollBox }

constructor TSkinScrollBox.Create(AOwner: TComponent);
begin
inherited;
FBufferBitmap:=TBitmap.Create;
end;

destructor TSkinScrollBox.Destroy;
begin
FBufferBitmap.Free;
inherited;
end;

procedure TSkinScrollBox.PaintWindow(DC: HDC);
var
Brush:IGpLinearGradientBrush;
Graphics:IGPGraphics;
ClientWidth,ClientHeight:Integer;
GPRect:TGPRect;
begin
if (Height=0) or (Width=0) then Exit;
ClientWidth:=RectWidth(ClientRect);
ClientHeight:=RectHeight(ClientRect);
if (ClientHeight<>Self.FBufferBitmap.Height)
or (ClientWidth<>Self.FBufferBitmap.Width) then
begin
Self.FBufferBitmap.SetSize(ClientWidth,ClientHeight);
Graphics:=TGPGraphics.Create(Self.FBufferBitmap.Canvas.Handle);
GPRect:=TGPRect.Create(ClientRect);
Brush:=TGpLinearGradientBrush.Create(GPRect,
TGPColor.Blue,
TGPColor.Gray,
TGPLinearGradientMode.LinearGradientModeVertical);
Graphics.FillRectangle(Brush,GPRect);
end;
BitBlt(DC,0,0,ClientWidth,ClientHeight,
Self.FBufferBitmap.Canvas.Handle,0,0,SRCCOPY);
end;

procedure TSkinScrollBox.WMEraseBkGnd(var Message: TWMEraseBkGnd);
begin
Message.Result:=1;
end;

procedure TSkinScrollBox.WMHScroll(var Message: TWMHScroll);
begin
Inherited;
Invalidate;
end;

procedure TSkinScrollBox.WMPaint(var Message: TWMPaint);
begin
ControlState:=ControlState+[csCustomPaint];
inherited;
ControlState:=ControlState-[csCustomPaint];
end;

procedure TSkinScrollBox.WMSize(var Message: TWMSize);
begin
inherited;
Invalidate;
end;

procedure TSkinScrollBox.WMVScroll(var Message: TWMVScroll);
begin
Inherited;
Invalidate;
end;

end.


DelphiTeacher 2011-12-10
  • 打赏
  • 举报
回复
unit SkinScrollBox;

interface

uses
Windows,SysUtils,Classes,Controls,Forms,GdiPlus,Messages;


type
TSkinScrollBox=class(TScrollBox)
protected
procedure WMEraseBkGnd(var Message:TWMEraseBkGnd);message WM_ERASEBKGND;
procedure WMHScroll(var Message: TWMHScroll); message WM_HSCROLL;
procedure WMVScroll(var Message: TWMVScroll); message WM_VSCROLL;
procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
procedure PaintWindow(DC: HDC); override;
procedure WMSize(var Message: TWMSize); message WM_SIZE;
public
constructor Create(AOwner:TComponent);override;
destructor Destroy;override;
published
property Align;
property Anchors;
property AutoScroll;
property AutoSize;
property BevelEdges;
property BevelInner;
property BevelOuter;
property BevelKind;
property BevelWidth;
property BiDiMode;
property BorderStyle;
property Constraints;
property DockSite;
property DoubleBuffered;
property DragCursor;
property DragKind;
property DragMode;
property Enabled;
property Color;
property Ctl3D;
property Font;
property Padding;
property ParentBiDiMode;
property ParentBackground default False;
property ParentColor;
property ParentCtl3D;
property ParentDoubleBuffered;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ShowHint;
property TabOrder;
property TabStop;
property Touch;
property Visible;
property OnCanResize;
property OnClick;
property OnConstrainedResize;
property OnContextPopup;
property OnDblClick;
property OnDockDrop;
property OnDockOver;
property OnDragDrop;
property OnDragOver;
property OnEndDock;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnGesture;
property OnGetSiteInfo;
property OnMouseActivate;
property OnMouseDown;
property OnMouseEnter;
property OnMouseLeave;
property OnMouseMove;
property OnMouseUp;
property OnMouseWheel;
property OnMouseWheelDown;
property OnMouseWheelUp;
property OnResize;
property OnStartDock;
property OnStartDrag;
property OnUnDock;
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('SkinEngine',[TSkinScrollBox]);
end;

{ TSkinScrollBox }

constructor TSkinScrollBox.Create(AOwner: TComponent);
begin
inherited;

end;

destructor TSkinScrollBox.Destroy;
begin

inherited;
end;

procedure TSkinScrollBox.PaintWindow(DC: HDC);
var
Brush:IGpLinearGradientBrush;
Graphics:IGPGraphics;
begin
Graphics:=TGPGraphics.Create(DC);
Brush:=TGpLinearGradientBrush.Create(TGPRect.Create(ClientRect),
TGPColor.Blue,
TGPColor.Gray,
TGPLinearGradientMode.LinearGradientModeVertical);
Graphics.FillRectangle(Brush,TGPRect.Create(ClientRect));
end;

procedure TSkinScrollBox.WMEraseBkGnd(var Message: TWMEraseBkGnd);
begin
Message.Result:=1;
end;

procedure TSkinScrollBox.WMHScroll(var Message: TWMHScroll);
begin
Inherited;
Invalidate;
end;

procedure TSkinScrollBox.WMPaint(var Message: TWMPaint);
begin
ControlState:=ControlState+[csCustomPaint];
inherited;
ControlState:=ControlState-[csCustomPaint];
end;

procedure TSkinScrollBox.WMSize(var Message: TWMSize);
begin
inherited;
Invalidate;
end;

procedure TSkinScrollBox.WMVScroll(var Message: TWMVScroll);
begin
Inherited;
Invalidate;
end;

end.
DelphiTeacher 2011-12-10
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 delphiteacher 的回复:]
是你贴的这种现象么?
[/Quote]
我贴的代码只是解决了这个问题,
但你上面写的我理解不了是怎么一个情况,你还是再上个图吧。
DelphiTeacher 2011-12-10
  • 打赏
  • 举报
回复

是你贴的这种现象么?
孤独的行者牛 2011-12-10
  • 打赏
  • 举报
回复
谢谢楼上高人,的确是刚用Delphi写东西,呵呵

我只重写了WM_Paint

现不是说本身的事件,而是其被动的接收WM_Paint消息,重绘自身的时候

因为原来的还在上面,但WM_Paint会全部重新,导至部分效果不对……

就是怎么样擦除原来绘制的效果,恢复原来的样子了,呵呵

5,388

社区成员

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

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