为什么我的滚动条并不总是正确绘制?

时间:2014-10-07 21:24:08

标签: delphi scrollbar components delphi-2009

我有一个图形TCustomControl后代组件,上面有系统滚动条。问题是,当我将窗口移动到屏幕外半部分然后将其向后拖动时,滚动条会消失(它没有绘制)。我怎样才能解决这个问题 ?我在思考,也许我应该在组件Paint中调用滚动条Paint方法,但我不知道如何。

这是代码。无需安装组件或在主窗体上放置内容,只需复制代码并指定TForm1.FormCreate事件:

Unit1.pas

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, SuperList;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  end;

var
  Form1: TForm1;
  List: TSuperList;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
 List:=TSuperList.Create(self);
 List.AlignWithMargins:=true;
 List.Align:=alClient;
 List.Visible:=true;
 List.Parent:=Form1;
end;

end.

SuperList.pas

unit SuperList;

interface

uses Windows, Controls, Graphics, Classes, Messages, SysUtils, StdCtrls, Forms;

type

  TSuperList = class(TCustomControl)
  public
    DX,DY: integer;
    procedure   Paint; override;
    constructor Create(AOwner: TComponent); override;
    procedure   WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
    procedure   CreateParams(var Params: TCreateParams); override;
  published
    property    TabStop default true;
    property    Align;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Marus', [TSuperList]);
end;

procedure TSuperList.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.Style := Params.Style or WS_VSCROLL;
end;

procedure TSuperList.WMLButtonDown(var Message: TWMLButtonDown);
begin
 DX:=Message.XPos;
 DY:=Message.YPos;
 Invalidate;
 inherited;
end;

constructor TSuperList.Create(AOwner: TComponent);
begin
 inherited;
 DoubleBuffered:=true;
 TabStop:=true;
 Color:=clBtnFace;
 BevelKind:=bkFlat;
 Width:=200; Height:=100;
 DX:=50; DY:=50;
end;

procedure TSuperList.Paint;
begin
 Canvas.Brush.Color:=clWindow;
 Canvas.FillRect(Canvas.ClipRect);
 Canvas.TextOut(10,10,'Press left mouse button !');
 Canvas.Brush.Color:=clRed;
 Canvas.Pen.Color:=clBlue;
 Canvas.Rectangle(DX,DY,DX+30,DY+20);
end;

end.

1 个答案:

答案 0 :(得分:3)

问题在于设置BevelKind:=bkFlat;

在绘制控件的非客户区域时调用TWinControl.WMNCPaint时,这将覆盖滚动条。

作为一种快速解决方法,您可以将WMNCPaint添加到您的控件并将Region更改为1. Delphi将重新绘制整个非客户区域,然后更好一些。

procedure WMNCPaint(var Message: TWMNCPaint); message WM_NCPAINT;

procedure TSuperList.WMNCPaint(var Message: TWMNCPaint);
var
  TmpRgn: HRGN;
begin
  TmpRgn := Message.RGN;
  try
    Message.RGN := 1;
    inherited;
  finally
    Message.RGN := TmpRgn;
  end;
  // if you want to add some custom NC painting, you could do it here...
end;

更清洁的解决方案是自己实施斜角绘画。这将减少闪烁。