前两贴地址:
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 再次出现……

解决方案 »

  1.   

    unit SkinScrollBox;interfaceuses
      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;implementationprocedure 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.
      

  2.   


    unit SkinScrollBox;interfaceuses
      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;implementationprocedure 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.
      

  3.   

    几点想法:
    出现楼主的情况是因为滚动条滚动之后没有重绘客户区所导致,
    一可能是楼主从没编写过控件,
    还有一个可能是楼主没有看过TScrollBox及其父类TScrollingWinControl的代码,懒所导致,
    楼主的控件在三种情况下需要重绘,一个拖动过大小,还有就是垂直和水平滚动条滚动之后,
    需要在三个消息的事件处理中进行手动重绘,WM_SIZE,WM_HSCROLL,WM_WSCROLL这三个消息我贴的最后一份是加入了双缓冲的,提高绘制效率的
      

  4.   

    谢谢楼上高人,的确是刚用Delphi写东西,呵呵我只重写了WM_Paint现不是说本身的事件,而是其被动的接收WM_Paint消息,重绘自身的时候因为原来的还在上面,但WM_Paint会全部重新,导至部分效果不对……就是怎么样擦除原来绘制的效果,恢复原来的样子了,呵呵
      

  5.   

    上面的贴图很明了,对比一下左边的是正常绘制的右边的,下半部分正常,因为下半部分,被滚到不可见的地方后,再滚动出来,这样,整个控件会重绘,下半部是无效域,重绘后正常!但上半部分,实际上被绘制了两次,造成效果异常!所以,问题在于,在重绘时(WM_Paint消息处理中),怎么样强制清除原来的效果……再次感谢……
      

  6.   

    网上找了好多资料,难道要 自己处理 WM_ERASEBKGND 消息?????
    关键怎么处理呢……