将Canvas添加到TScrollBox

时间:2013-08-15 00:27:11

标签: delphi

我想做一件简单的事情:在TScrollBox后代上添加一个Canvas属性。我看过this article

但我的ScrollBox后代根本不在画布上绘制。可能有人告诉我,出了什么问题?

  TfrmScrollContainer = class (TScrollBox)
  private
    FCanvas: TCanvas; 
    FControlState:TControlState;
    procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
  protected
    procedure Paint;
    procedure PaintWindow(DC: HDC); override;
    property Canvas: TCanvas read FCanvas;
  public
    constructor Create(AOwner: TComponent);  override;
    destructor Destroy; override;
  end;

...这是精确的副本,TWincontrol如何转向TCustomControl(但它在某处失败)

constructor TfrmScrollContainer.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FCanvas := TControlCanvas.Create;
  TControlCanvas(FCanvas).Control := Self;
end;

destructor TfrmScrollContainer.Destroy;
begin
  FCanvas.Free;
  inherited Destroy;
end;

procedure TfrmScrollContainer.WMPaint(var Message: TWMPaint);
begin
  Include(FControlState, csCustomPaint);
  inherited;
  Exclude(FControlState, csCustomPaint);
end;

procedure TfrmScrollContainer.PaintWindow(DC: HDC);
begin
  FCanvas.Lock;
  try
    FCanvas.Handle := DC;
    try
      TControlCanvas(FCanvas).UpdateTextFlags;
      Paint;
    finally
      FCanvas.Handle := 0;
    end;
  finally
    FCanvas.Unlock;
  end;
end;

procedure TfrmScrollContainer.Paint;    // this is not executed (I do not see any ellipse)
begin
  Canvas.Brush.Color:=clRed;
  Canvas.Ellipse(ClientRect);
end;

感谢名单

1 个答案:

答案 0 :(得分:6)

您未将csCustomPaint包括在ControlState中,而是将其包含在您声明的类似名称字段中。您的字段未被检查,上升控件对此一无所知。要解决,请更换

procedure TfrmScrollContainer.WMPaint(var Message: TWMPaint);
begin
  Include(FControlState, csCustomPaint);
  inherited;
  Exclude(FControlState, csCustomPaint);
end;

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


或者,您的滚动框可以为您的自定义绘画提供任何控件。继承的WM_PAINT处理程序检查控件计数,如果它不是0则调用paint处理程序而不是将消息传递给默认处理程序。