«« Site Rescued »»

While the site is still going to move from its current host, a new site will now take its place. More Info.

The new site may have less content, but the core will now remain. And it will now play nicely with phones! Keep an eye on the DelphiDabbler Blog for news.

» Help

How to create a TScrollBox with its own background

   
unit NScroll;

interface

uses
  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics,
  Controls, Forms;

type
  TMyScrollBox = Class(TScrollBox)
  private
    FNHBitmap: TBitmap;
    FNHCanvas: TCanvas;
    procedure WMPaint(var Msg: TWMPaint); message WM_PAINT;
    procedure SetBitmap(Value: TBitmap);
  protected
    procedure Painting;
    procedure PaintWindow(DC: HDC); override;
  published
    property BackBitmap: TBitmap read FNHBitmap write SetBitmap;
  public
    constructor Create(Owner: TComponent); override;
    destructor Destroy; override;
end;

procedure Register;

implementation

constructor TMyScrollBox.Create(Owner: TComponent);
begin
  inherited Create(Owner);
  FNHBitmap := TBitmap.Create;
  FNHCanvas := TControlCanvas.Create;
  TControlCanvas(FNHCanvas).Control := Self;
end;

destructor TMyScrollBox.Destroy;
begin
  FNHBitmap.Destroy;
  FNHCanvas.Destroy;
  inherited Destroy;
end;

procedure TMyScrollBox.SetBitmap(Value: TBitmap);
begin
  FNHBitmap.Assign(Value);
  invalidate;
end;

procedure TMyScrollBox.WMPaint(var Msg: TWMPaint);
begin
  PaintHandler(Msg);
end;

procedure TMyScrollBox.PaintWindow(DC: HDC);
begin
  FNHCanvas.Handle := DC;
  try
    Painting;
  finally
    FNHCanvas.Handle := 0;
  end;
end;

procedure TMyScrollBox.Painting;
var
  FDrawHeight, FDrawWidth: Integer;
  Row, Column, xl, xt, xw, xh: Integer;
  xdl, xdt: Integer;
  xRect: TRect;
  i: integer;
  xhdl: Word;
begin
  if (FNHBitmap.width <> 0) and (FNHBitmap.Height <> 0) then
  begin
    xRect := ClientRect;
    FDrawHeight := xRect.Bottom - xRect.Top;
    FDrawWidth := xRect.Right - xRect.Left;
    xdl := (HorzScrollBar.Position mod FNHBitmap.Width);
    xdt := (VertScrollBar.Position mod FNHBitmap.Height);
    for Row := 0 to (FDrawHeight div FNHBitmap.Height) + 1 do
    begin
      for Column := 0 to (FDrawWidth div FNHBitmap.Width) + 1 do
      begin
        xl := Column * FNHBitmap.Width + xRect.Left - xdl;
        xt := Row * FNHBitmap.Height + xRect.Top - xdt;
        xw := FNHBitmap.Width;
        if (FDrawWidth - xl + xRect.Left) < xw then
          xw := (FDrawWidth - xl + xRect.Top);
        xh := FNHBitmap.Height;
        if (FDrawHeight - xt + xRect.Top) < xh then
          xh := (FDrawHeight - xt + xRect.Top);
        FNHCanvas.CopyRect(
          Rect(xl, xt, xl + xw, xt + xh),
          FNHBitmap.Canvas,
          Rect(0, 0, xw, xh)
        );
      end;
    end;
  end;
end;

procedure Register;
begin
  RegisterComponents('Samples', [TMyScrollBox]);
end;

end.
Original resource: The Delphi Pool
Author: Unknown
Added: 2009-10-28
Last updated: 2009-10-28

« Return to contents »