Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 如何制作背景透明的滚动框?_Delphi_User Interface_Delphi 2006 - Fatal编程技术网

Delphi 如何制作背景透明的滚动框?

Delphi 如何制作背景透明的滚动框?,delphi,user-interface,delphi-2006,Delphi,User Interface,Delphi 2006,我有一个t帧,背景是t图像 这个框架作为我放在主TForm有限空间中的其他框架的祖先。 因此,它只是其他帧的用户界面基础 我需要在这些框架中放置许多控件,因为它们将处理大型数据库表单 由于主窗体的空间有限,我需要在所有t框架空间中放置一个TScrollBox,标题栏除外。但这涵盖了背景图像 如何使此滚动条成为背景透明? 还是制作具有该功能的新组件更好,以及如何制作? 我在其他网站上看到了一些示例,但它们在运行时有问题 谢谢大家! Edit2: 我从LMD Inovative的ElPack中找到了

我有一个
t帧
,背景是
t图像

这个框架作为我放在主
TForm
有限空间中的其他框架的祖先。 因此,它只是其他帧的用户界面基础

我需要在这些框架中放置许多控件,因为它们将处理大型数据库表单

由于主窗体的空间有限,我需要在所有
t框架
空间中放置一个
TScrollBox
,标题栏除外。但这涵盖了背景图像

如何使此滚动条成为背景透明?

还是制作具有该功能的新组件更好,以及如何制作?

我在其他网站上看到了一些示例,但它们在运行时有问题

谢谢大家!

Edit2:

我从LMD Inovative的ElPack中找到了
TElScrollBox
。 这是背景透明的,允许我们将图像作为背景。 但同样的问题也出现了:当我们在运行时滚动它时,它会在其影响区域移动祖先的背景

Edit1:

我试图创建一个子体,但滚动条只在我们将鼠标悬停在它应该在的位置时显示,当我们滚动它时,窗体的背景在滚动框内移动。 而且,它里面的控件也有一些绘制错误

interface

uses
  Windows, SysUtils, Messages, Classes, Graphics, Controls, Forms,
  Dialogs, Menus, StdCtrls, ExtCtrls;

type
  TTransScrollBox = class(TScrollBox)
  private
    { Private declarations }
  protected
    procedure CreateParams(var params: TCreateParams); override;
    procedure WMEraseBkGnd(var msg: TWMEraseBkGnd); message WM_ERASEBKGND;
  public
    { Public declarations }
  published
    { Published declarations }
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Eduardo', [TTransScrollBox]);
end;

procedure TTransScrollBox.CreateParams(var params: TCreateParams);
begin
  inherited CreateParams(params);
  params.ExStyle := params.ExStyle or WS_EX_TRANSPARENT;
end;

procedure TTransScrollBox.WMEraseBkGnd(var Msg: TWMEraseBkGnd); 
begin
  SetBkMode (Msg.DC, TRANSPARENT);
  Msg.Result := 1;
end;

颠倒基架上的顺序:)

打开ScrollBox,然后将图像放在ScrollBox(align Client)上并使其透明。然后将控件放在它上面,它允许滚动


我相信你已经尝试过了,那么是什么给了你一个问题…

如果你不想滚动图像,你就必须滚动你自己的滚动条,这并不太难(英国这里还在下雨,所以我很无聊!)

要进行测试,请创建一个框架,将图像放在其上并对齐到客户端。 将滚动条设置为垂直并向右对齐。 在设计时放大框架。 将控件放在任意位置,然后收缩控件,使某些控件不可见(底部下方)。 在form show(用于测试)中的主窗体上,或在创建新帧时调用frame.BeforeShow进行设置

[稍后]编辑下雨了&还是很无聊,所以我帮你做完了

unit ScrollingBaseFrameU;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs, jpeg, ExtCtrls, StdCtrls, contnrs, Generics.Collections, Grids,
  DBGrids;

const
  MaxLargeSteps = 5; // maximum large scroll clicks to scroll to max
  IgnoreTag = 99;   // Controls with this tag value are igored for scrolling
  TitleHeight = 23; // Height of title bar as we are dealing with the image mouse co-ordinates
  RightMargin = 25; // space after right-most control
  BottomMargin = 25; // space after bottom-most control
  StrControl = 'ControlName';  // prefix for controls with no name

type
  TControlPos = class(Tobject) // Little object to save initial control positions
  public
    Name: string;
    X,
    Y: Integer;
  end;

  TScrollingBaseFrame = class(TFrame)
    BackGroundImage: TImage;
    HorzScrollBar: TScrollBar;
    VertScrollBar: TScrollBar;
    pnlTitle: TPanel;
    procedure VertScrollBarChange(Sender: TObject);
    procedure BackGroundImageMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure FrameResize(Sender: TObject);
    procedure HorzScrollBarChange(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    ShowHScroller,
    ShowVScroller : Boolean;       // scroller needed at all?
    PosList: TList<TControlPos>;   // list of initial positions
    procedure BeforeShow; virtual; // override in descendants for specific behaviour
    procedure BeforeClose; virtual; // override in descendants for specific behaviour
    function IndexOfPos(AName:string): Integer;
  end;

implementation

{$R *.dfm}

procedure TScrollingBaseFrame.BeforeClose;
// Clean up
var
  p: TControlPos;
begin
  for p in PosList do
    p.free;
  PosList.Free;
end;

procedure TScrollingBaseFrame.BeforeShow;
//Setup scroller and save initial control positions
var
  i,XMax,YMax,Idx: Integer;
  AControl: TControl;
begin
  pnlTitle.Height := TitleHeight;
  PosList := TList<TControlpos>.Create;
  XMax := 0;
  YMax := 0;
  for i := 0 to ComponentCount - 1 do
  begin
    if Components[i] is TControl then
    begin
      AControl := TControl(Components[i]);
      if Acontrol.Tag <> IgnoreTag then
      begin
        Idx := PosList.Add(TcontrolPos.Create);
        if AControl.Name = '' then  // deal with empty names
          AControl.Name :=  StrControl + IntToStr(i);
        PosList[Idx].Name := AControl.Name;
        PosList[Idx].X := AControl.Left;
        PosList[Idx].Y := AControl.Top;
        if YMax < AControl.Top + AControl.Height then
         YMax := AControl.Top + AControl.Height;
        if XMax < AControl.Left + AControl.Width then
         XMax := AControl.Left + AControl.Width;
      end; // Ignored
    end; // is control
  end; // count
   VertScrollBar.Max := (YMax + BottomMargin) - Height; // bit of a bottom margin :)
   VertScrollBar.LargeChange := VertScrollBar.Max div MaxLargeSteps;
   ShowVScroller := VertScrollBar.Max > BottomMargin;
   VertScrollBar.Visible := ShowVScroller;
   HorzScrollBar.Max := (XMax + RightMargin) - Width; // bit of a Right margin :)
   HorzScrollBar.LargeChange := HorzScrollBar.Max div MaxLargeSteps;
   ShowHScroller := HorzScrollBar.Max > RightMargin;
   HorzScrollBar.Visible := ShowHScroller;
end;

procedure TScrollingBaseFrame.FrameResize(Sender: TObject);
begin
  BackGroundImage.Width := Width;
  BackGroundImage.Height := Height;
end;

procedure TScrollingBaseFrame.HorzScrollBarChange(Sender: TObject);
// Move the controls left and right relative to thier initail positions
var
  i,j: Integer;
  AControl: TControl;
begin
  for i := 0 to ComponentCount - 1 do
   begin
     if Components[i] is TControl then
     begin
       AControl :=  TControl(Components[i]);
       j := IndexOfPos(AControl.Name);
       if j >= 0 then  // could be ignored or the background image
         Acontrol.Left := PosList[j].X  - HorzScrollBar.Position;
     end;
   end;
end;

procedure TScrollingBaseFrame.BackGroundImageMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
// Show/Hide the scrollbars using mouse position
var
  ScrollBarWidth: Integer;
begin
  ScrollBarWidth := GetSystemmetrics(SM_CXVSCROLL);  // assume the same for horizontal
  VertScrollBar.Visible := (X > Width - ScrollBarWidth) and ShowVScroller;
  HorzScrollBar.Visible := (Y > (Height - TitleHeight) - ScrollBarWidth) and ShowHScroller;
end;

function TScrollingBaseFrame.IndexOfPos(AName:string): Integer;
// Find a control position in the list by name
var
  Idx: Integer;
begin
  Result := -1;
  Idx := 0;
  while (Result < 0) and (Idx < PosList.Count) do
  begin
    if PosList[idx].Name = AName then
      Result := idx;
    inc(idx);
  end;
end;

procedure TScrollingBaseFrame.VertScrollBarChange(Sender: TObject);
// Move the controls Up and down relative to thier initail positions
var
  i,j: Integer;
  AControl: TControl;
begin
  for i := 0 to ComponentCount - 1 do
   begin
     if Components[i] is TControl then
     begin
       AControl :=  TControl(Components[i]);
       j := IndexOfPos(AControl.Name);
       if j >= 0 then  // could be ignored
         Acontrol.Top := PosList[j].Y  - VertScrollBar.Position;
     end;
   end;
end;

end.
[2ND EDIT]好吧,我不想浪费我的业余时间,下面的内容应该适用于Delphi 6以后的版本

unit ScrollingBaseFrameU;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs, jpeg, ExtCtrls, StdCtrls, contnrs, Grids,
  DBGrids;

const
  MaxLargeSteps = 5; // maximum large scroll clicks to scroll to max
  IgnoreTag = 99;   // Controls with this tag value are igored for scrolling
  TitleHeight = 23; // Height of title bar as we are dealing with the image mouse co-ordinates
  RightMargin = 25; // space after right-most control
  BottomMargin = 25; // space after bottom-most control
  StrControl = 'ControlName';  // prefix for controls with no name

type
  TControlPos = class(Tobject) // Little object to save initial control positions
  public
    Name: string;
    X,
    Y: Integer;
  end;

  TControlPosList = class(TObject)
  private
    function GetCount: Integer;
    function GetItems(Index: Integer): TControlPos;
    procedure SetItems(Index: Integer; const Value: TControlPos);
  public
   TheList: TObjectList;
   Constructor Create; virtual;
   Destructor Destroy; override;
   function Add(APos: TControlPos): Integer;
   function IndexOfPos(AName: string): Integer;
   property Count: Integer read GetCount;
   property Items[Index: Integer]: TControlPos read GetItems write SetItems; default;
  end;

  TScrollingBaseFrame = class(TFrame)
    BackGroundImage: TImage;
    HorzScrollBar: TScrollBar;
    VertScrollBar: TScrollBar;
    pnlTitle: TPanel;
    procedure VertScrollBarChange(Sender: TObject);
    procedure BackGroundImageMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure FrameResize(Sender: TObject);
    procedure HorzScrollBarChange(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    ShowHScroller,
    ShowVScroller : Boolean;       // scroller needed at all?
    PosList: TControlPosList;   // list of initial positions
    procedure BeforeShow; virtual; // override in descendants for specific behaviour
    procedure BeforeClose; virtual; // override in descendants for specific behaviour
  end;

implementation

{$R *.dfm}

procedure TScrollingBaseFrame.BeforeClose;
// Clean up
begin
  PosList.Free;
end;

procedure TScrollingBaseFrame.BeforeShow;
//Setup scroller and save initial control positions
var
  i,XMax,YMax,Idx: Integer;
  AControl: TControl;
begin
  pnlTitle.Height := TitleHeight;
  PosList := TControlPosList.Create;
  XMax := 0;
  YMax := 0;
  for i := 0 to ComponentCount - 1 do
  begin
    if Components[i] is TControl then
    begin
      AControl := TControl(Components[i]);
      if Acontrol.Tag <> IgnoreTag then
      begin
        Idx := PosList.Add(TcontrolPos.Create);
        if AControl.Name = '' then  // deal with empty names
          AControl.Name :=  StrControl + IntToStr(i);
        PosList[Idx].Name := AControl.Name;
        PosList[Idx].X := AControl.Left;
        PosList[Idx].Y := AControl.Top;
        if YMax < AControl.Top + AControl.Height then
         YMax := AControl.Top + AControl.Height;
        if XMax < AControl.Left + AControl.Width then
         XMax := AControl.Left + AControl.Width;
      end; // Ignored
    end; // is control
  end; // count
   VertScrollBar.Max := (YMax + BottomMargin) - Height; // bit of a bottom margin :)
   VertScrollBar.LargeChange := VertScrollBar.Max div MaxLargeSteps;
   ShowVScroller := VertScrollBar.Max > BottomMargin;
   VertScrollBar.Visible := ShowVScroller;
   HorzScrollBar.Max := (XMax + RightMargin) - Width; // bit of a Right margin :)
   HorzScrollBar.LargeChange := HorzScrollBar.Max div MaxLargeSteps;
   ShowHScroller := HorzScrollBar.Max > RightMargin;
   HorzScrollBar.Visible := ShowHScroller;
end;

procedure TScrollingBaseFrame.FrameResize(Sender: TObject);
begin
  BackGroundImage.Width := Width;
  BackGroundImage.Height := Height;
end;

procedure TScrollingBaseFrame.HorzScrollBarChange(Sender: TObject);
// Move the controls left and right relative to thier initail positions
var
  i,j: Integer;
  AControl: TControl;
begin
  for i := 0 to ComponentCount - 1 do
   begin
     if Components[i] is TControl then
     begin
       AControl :=  TControl(Components[i]);
       j := PosList.IndexOfPos(AControl.Name);
       if j >= 0 then  // could be ignored
         Acontrol.Left := PosList[j].X  - HorzScrollBar.Position;
     end;
   end;
end;

procedure TScrollingBaseFrame.BackGroundImageMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
// Show/Hide the scrollbars using mouse position
var
  ScrollBarWidth: Integer;
begin
  ScrollBarWidth := GetSystemmetrics(SM_CXVSCROLL);  // assume the same for horizontal
  VertScrollBar.Visible := (X > Width - ScrollBarWidth) and ShowVScroller;
  HorzScrollBar.Visible := (Y > (Height - TitleHeight) - ScrollBarWidth) and ShowHScroller;
end;


procedure TScrollingBaseFrame.VertScrollBarChange(Sender: TObject);
// Move the controls Up and down relative to thier initail positions
var
  i,j: Integer;
  AControl: TControl;
begin
  for i := 0 to ComponentCount - 1 do
   begin
     if Components[i] is TControl then
     begin
       AControl :=  TControl(Components[i]);
       j := PosList.IndexOfPos(AControl.Name);
       if j >= 0 then  // could be ignored
         Acontrol.Top := PosList[j].Y  - VertScrollBar.Position;
     end;
   end;
end;

{ TcontrolPosList }

function TControlPosList.Add(APos: TControlPos): Integer;
begin
  Result := TheList.Add(APos);
end;

constructor TControlPosList.Create;
begin
  TheList := TObjectList.Create;
  TheList.OwnsObjects := True;
end;

destructor TControlPosList.Destroy;
begin
  TheList.Free;
  inherited;
end;

function TControlPosList.GetCount: Integer;
begin
  Result := TheList.Count;
end;

function TControlPosList.GetItems(Index: Integer): TControlPos;
begin
  Result := TControlPos(TheList[Index]);
end;

function TControlPosList.IndexOfPos(AName: string): Integer;
// Find a control position in the list by name
var
  Idx: Integer;
begin
  Result := -1;
  Idx := 0;
  while (Result < 0) and (Idx < TheList.Count) do
  begin
    if Items[idx].Name = AName then
      Result := idx;
    inc(idx);
  end;
end;

procedure TControlPosList.SetItems(Index: Integer; const Value: TControlPos);
begin
  TheList[Index] := Value;
end;

end.
单元滚动baseframeu;
接口
使用
窗口、消息、系统工具、变体、类、图形、控件、窗体、,
对话框、jpeg、ExtCtrls、StdCtrls、contnrs、网格、,
DBGrids;
常数
最大最大步数=5;//最大大滚动点击次数可滚动至最大
IgnoreTag=99;//带有此标记值的控件将被选中以进行滚动
TitleLight=23;//标题栏的高度,因为我们正在处理的图像鼠标坐标
RightMargin=25;//最右边控件后的空格
底部边距=25;//最底部控件后的空间
StrControl='ControlName';//没有名称的控件的前缀
类型
TControlPos=class(Tobject)//保存初始控制位置的小对象
公众的
名称:字符串;
X,,
Y:整数;
结束;
TControlPosList=类(ToObject)
私有的
函数GetCount:Integer;
函数GetItems(索引:整数):TControlPos;
过程集合项(索引:整数;常量值:TControlPos);
公众的
列表:对象列表;
构造函数创建;事实上的
毁灭者毁灭;推翻
函数Add(APos:TControlPos):整数;
函数IndexOfPos(AName:string):整数;
属性计数:整数读取GetCount;
属性项[索引:整数]:TControlPos读取GetItems写入SetItems;违约
结束;
TScrollingBaseFrame=类(TFrame)
背景图片:TImage;
HorzScrollBar:TScrollBar;
垂直滚动条:TScrollBar;
pnltite:TPanel;
程序变更(发送方:TObject);
过程背景ImageMouseMove(发送方:ToObject;Shift:TShiftState;X,
Y:整数);
程序FrameResize(发送方:TObject);
程序HorzScrollBarChange(发送方:TObject);
私有的
{私有声明}
公众的
{公开声明}
肖斯克罗勒,
ShowVScroller:Boolean;//需要滚动条吗?
PosList:t控制PosList;//初始职位列表
展览前的程序;虚拟的;//在子体中重写特定行为
关闭前的程序;虚拟的;//在子体中重写特定行为
结束;
实施
{$R*.dfm}
程序TSCROLINGBASEFRAME.BEFORECOSE;
//清理
开始
PosList.Free;
结束;
程序TSCROLINGBASEFRAME.BeforeShow;
//设置滚动条并保存初始控制位置
变量
i、 XMax,YMax,Idx:整数;
a控制:t控制;
开始
Pntlite.高度:=十分光;
PosList:=TControlPosList.Create;
XMax:=0;
YMax:=0;
对于i:=0到ComponentCount-1 do
开始
如果组件[i]为t控制,则
开始
a控制:=t控制(组件[i]);
如果a控件标记IgnoreTag,则
开始
Idx:=PosList.Add(TcontrolPos.Create);
如果AControl.Name='',则//处理空名称
a控制名称:=StrControl+IntToStr(i);
PosList[Idx]。名称:=AControl.Name;
PosList[Idx].X:=AControl.Left;
PosList[Idx].Y:=AControl.Top;
如果YMaxBottomMargin;
VertScrollBar.Visible:=ShowVScroller;
HorzScrollBar.Max:=(XMax+RightMargin)-宽度;//有点右边距:)
unit ScrollingBaseFrameU;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs, jpeg, ExtCtrls, StdCtrls, contnrs, Grids,
  DBGrids;

const
  MaxLargeSteps = 5; // maximum large scroll clicks to scroll to max
  IgnoreTag = 99;   // Controls with this tag value are igored for scrolling
  TitleHeight = 23; // Height of title bar as we are dealing with the image mouse co-ordinates
  RightMargin = 25; // space after right-most control
  BottomMargin = 25; // space after bottom-most control
  StrControl = 'ControlName';  // prefix for controls with no name

type
  TControlPos = class(Tobject) // Little object to save initial control positions
  public
    Name: string;
    X,
    Y: Integer;
  end;

  TControlPosList = class(TObject)
  private
    function GetCount: Integer;
    function GetItems(Index: Integer): TControlPos;
    procedure SetItems(Index: Integer; const Value: TControlPos);
  public
   TheList: TObjectList;
   Constructor Create; virtual;
   Destructor Destroy; override;
   function Add(APos: TControlPos): Integer;
   function IndexOfPos(AName: string): Integer;
   property Count: Integer read GetCount;
   property Items[Index: Integer]: TControlPos read GetItems write SetItems; default;
  end;

  TScrollingBaseFrame = class(TFrame)
    BackGroundImage: TImage;
    HorzScrollBar: TScrollBar;
    VertScrollBar: TScrollBar;
    pnlTitle: TPanel;
    procedure VertScrollBarChange(Sender: TObject);
    procedure BackGroundImageMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure FrameResize(Sender: TObject);
    procedure HorzScrollBarChange(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    ShowHScroller,
    ShowVScroller : Boolean;       // scroller needed at all?
    PosList: TControlPosList;   // list of initial positions
    procedure BeforeShow; virtual; // override in descendants for specific behaviour
    procedure BeforeClose; virtual; // override in descendants for specific behaviour
  end;

implementation

{$R *.dfm}

procedure TScrollingBaseFrame.BeforeClose;
// Clean up
begin
  PosList.Free;
end;

procedure TScrollingBaseFrame.BeforeShow;
//Setup scroller and save initial control positions
var
  i,XMax,YMax,Idx: Integer;
  AControl: TControl;
begin
  pnlTitle.Height := TitleHeight;
  PosList := TControlPosList.Create;
  XMax := 0;
  YMax := 0;
  for i := 0 to ComponentCount - 1 do
  begin
    if Components[i] is TControl then
    begin
      AControl := TControl(Components[i]);
      if Acontrol.Tag <> IgnoreTag then
      begin
        Idx := PosList.Add(TcontrolPos.Create);
        if AControl.Name = '' then  // deal with empty names
          AControl.Name :=  StrControl + IntToStr(i);
        PosList[Idx].Name := AControl.Name;
        PosList[Idx].X := AControl.Left;
        PosList[Idx].Y := AControl.Top;
        if YMax < AControl.Top + AControl.Height then
         YMax := AControl.Top + AControl.Height;
        if XMax < AControl.Left + AControl.Width then
         XMax := AControl.Left + AControl.Width;
      end; // Ignored
    end; // is control
  end; // count
   VertScrollBar.Max := (YMax + BottomMargin) - Height; // bit of a bottom margin :)
   VertScrollBar.LargeChange := VertScrollBar.Max div MaxLargeSteps;
   ShowVScroller := VertScrollBar.Max > BottomMargin;
   VertScrollBar.Visible := ShowVScroller;
   HorzScrollBar.Max := (XMax + RightMargin) - Width; // bit of a Right margin :)
   HorzScrollBar.LargeChange := HorzScrollBar.Max div MaxLargeSteps;
   ShowHScroller := HorzScrollBar.Max > RightMargin;
   HorzScrollBar.Visible := ShowHScroller;
end;

procedure TScrollingBaseFrame.FrameResize(Sender: TObject);
begin
  BackGroundImage.Width := Width;
  BackGroundImage.Height := Height;
end;

procedure TScrollingBaseFrame.HorzScrollBarChange(Sender: TObject);
// Move the controls left and right relative to thier initail positions
var
  i,j: Integer;
  AControl: TControl;
begin
  for i := 0 to ComponentCount - 1 do
   begin
     if Components[i] is TControl then
     begin
       AControl :=  TControl(Components[i]);
       j := PosList.IndexOfPos(AControl.Name);
       if j >= 0 then  // could be ignored
         Acontrol.Left := PosList[j].X  - HorzScrollBar.Position;
     end;
   end;
end;

procedure TScrollingBaseFrame.BackGroundImageMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
// Show/Hide the scrollbars using mouse position
var
  ScrollBarWidth: Integer;
begin
  ScrollBarWidth := GetSystemmetrics(SM_CXVSCROLL);  // assume the same for horizontal
  VertScrollBar.Visible := (X > Width - ScrollBarWidth) and ShowVScroller;
  HorzScrollBar.Visible := (Y > (Height - TitleHeight) - ScrollBarWidth) and ShowHScroller;
end;


procedure TScrollingBaseFrame.VertScrollBarChange(Sender: TObject);
// Move the controls Up and down relative to thier initail positions
var
  i,j: Integer;
  AControl: TControl;
begin
  for i := 0 to ComponentCount - 1 do
   begin
     if Components[i] is TControl then
     begin
       AControl :=  TControl(Components[i]);
       j := PosList.IndexOfPos(AControl.Name);
       if j >= 0 then  // could be ignored
         Acontrol.Top := PosList[j].Y  - VertScrollBar.Position;
     end;
   end;
end;

{ TcontrolPosList }

function TControlPosList.Add(APos: TControlPos): Integer;
begin
  Result := TheList.Add(APos);
end;

constructor TControlPosList.Create;
begin
  TheList := TObjectList.Create;
  TheList.OwnsObjects := True;
end;

destructor TControlPosList.Destroy;
begin
  TheList.Free;
  inherited;
end;

function TControlPosList.GetCount: Integer;
begin
  Result := TheList.Count;
end;

function TControlPosList.GetItems(Index: Integer): TControlPos;
begin
  Result := TControlPos(TheList[Index]);
end;

function TControlPosList.IndexOfPos(AName: string): Integer;
// Find a control position in the list by name
var
  Idx: Integer;
begin
  Result := -1;
  Idx := 0;
  while (Result < 0) and (Idx < TheList.Count) do
  begin
    if Items[idx].Name = AName then
      Result := idx;
    inc(idx);
  end;
end;

procedure TControlPosList.SetItems(Index: Integer; const Value: TControlPos);
begin
  TheList[Index] := Value;
end;

end.