你可以这样做:
而不是 ScrollBox 在您的表单上放置一个 ScrollBar。将其对齐设置为底部(如果您希望拥有更多列,或者您可以将每一列放在自己的面板中,则可以手动设置其大小和位置)。然后设置备忘录的大小并将标签放置在表单的中心。设置备忘录的大小后(可能通过代码动态)放置以下代码:
ScrollBar1.Min:=0-Memo1.Left;
ScrollBar1.Max:=Memo1.Width-Form1.ClientWidth+Memo1.Left;
最后一件事是设置 ScrollBar OnChange 事件:
procedure TForm1.ScrollBar1Change(Sender: TObject);
begin
Memo1.Left:=0-ScrollBar1.Position;
Memo2.Left:=0-ScrollBar1.Position;
...
MemoXY.Left:=0-ScrollBar1.Position;
end;
您的表单应如下所示:
完毕!你有一个稳定的居中标签和平滑滚动的备忘录。
编辑:
这是一个版本,在他自己的面板中各有 3 列,并且还带有垂直滚动条:
以及整个源代码:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Panel1: TPanel;
Panel2: TPanel;
Panel3: TPanel;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
Memo1: TMemo;
Memo2: TMemo;
Memo3: TMemo;
Memo4: TMemo;
Memo5: TMemo;
Memo6: TMemo;
ScrollBar1: TScrollBar;
ScrollBar2: TScrollBar;
ScrollBar3: TScrollBar;
ScrollBar4: TScrollBar;
ScrollBar5: TScrollBar;
ScrollBar6: TScrollBar;
procedure FormCreate(Sender: TObject);
procedure ScrollBarHChange(Sender: TObject);
procedure ScrollBarVChange(Sender: TObject);
procedure FormResize(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var cycle: Integer;
begin
//GENERATE YOUR COMPONENTS HERE
//sets every components tag to its default top position
//(you can do this in any other way for example using array)
for cycle:=0 to Form1.ComponentCount-1 do
begin
if(Form1.Components[cycle] is TControl)then
Form1.Components[cycle].Tag:=(Form1.Components[cycle] as TControl).Top
end;
end;
procedure TForm1.FormResize(Sender: TObject);
begin
//changes the panels sizes and positions
Panel1.Width:=Form1.ClientWidth div 3;
Panel2.Width:=Form1.ClientWidth div 3;
Panel3.Width:=Form1.ClientWidth div 3;
Panel2.Left:=Panel1.Width+1;
Panel3.Left:=Panel1.Width+Panel2.Width+1;
//if you dont want all scrollbars to reset on window resize, you need to handle the positioning of elements when window (and panels) size is changing
ScrollBar1.Position:=ScrollBar1.Min;
ScrollBar2.Position:=ScrollBar2.Min;
ScrollBar3.Position:=ScrollBar3.Min;
ScrollBar4.Position:=ScrollBar4.Min;
ScrollBar5.Position:=ScrollBar5.Min;
ScrollBar6.Position:=ScrollBar6.Min;
//make these tests on the widest element of each panel (8 is just a margin so the memo has some space on the right)
if((Memo1.Left+Memo1.Width)>(Panel1.ClientWidth-ScrollBar4.Width-8))then
begin
ScrollBar1.Enabled:=true;
ScrollBar1.Max:=Memo1.Width-Panel1.ClientWidth+Memo1.Left+ScrollBar4.Width+8;
end
else
ScrollBar1.Enabled:=false;
if((Memo3.Left+Memo3.Width)>(Panel2.ClientWidth-ScrollBar5.Width-8))then
begin
ScrollBar2.Enabled:=true;
ScrollBar2.Max:=Memo3.Width-Panel1.ClientWidth+Memo3.Left+ScrollBar5.Width+8;
end
else
begin
ScrollBar2.Position:=ScrollBar2.Min;
ScrollBar2.Enabled:=false;
end;
if((Memo5.Left+Memo5.Width)>(Panel3.ClientWidth-ScrollBar6.Width-8))then
begin
ScrollBar3.Enabled:=true;
ScrollBar3.Max:=Memo5.Width-Panel1.ClientWidth+Memo5.Left+ScrollBar6.Width+8;
end
else
ScrollBar3.Enabled:=false;
//make these tests on the bottom element of each panel (16 is just a margin so the memo has some space on the bottom)
if((Memo2.Top+Memo2.Height)>(Panel1.ClientHeight-ScrollBar1.Height-16))then
begin
ScrollBar4.Enabled:=true;
ScrollBar4.Max:=Memo2.Top+Memo2.Height-Panel1.ClientHeight+ScrollBar1.Height+16;
end
else
ScrollBar4.Enabled:=false;
if((Memo4.Top+Memo4.Height)>(Panel2.ClientHeight-ScrollBar2.Height-16))then
begin
ScrollBar5.Enabled:=true;
ScrollBar5.Max:=Memo4.Top+Memo4.Height-Panel2.ClientHeight+ScrollBar2.Height+16;
end
else
ScrollBar5.Enabled:=false;
if((Memo6.Top+Memo6.Height)>(Panel3.ClientHeight-ScrollBar3.Height-16))then
begin
ScrollBar6.Enabled:=true;
ScrollBar6.Max:=Memo6.Top+Memo6.Height-Panel3.ClientHeight+ScrollBar3.Height+16;
end
else
ScrollBar6.Enabled:=false;
end;
procedure TForm1.ScrollBarHChange(Sender: TObject);
var cycle: Integer;
begin
for cycle:=0 to ((Sender as TScrollBar).Parent as TPanel).ControlCount-1 do
begin
if(((Sender as TScrollBar).Parent as TPanel).Controls[cycle] is TMemo)then
(((Sender as TScrollBar).Parent as TPanel).Controls[cycle] as TMemo).Left:=0-(Sender as TScrollBar).Position+8;
end;
end;
procedure TForm1.ScrollBarVChange(Sender: TObject);
var cycle: Integer;
begin
for cycle:=0 to ((Sender as TScrollBar).Parent as TPanel).ControlCount-1 do
begin
if(not (((Sender as TScrollBar).Parent as TPanel).Controls[cycle] is TScrollBar))then
(((Sender as TScrollBar).Parent as TPanel).Controls[cycle] as TControl).Top:=(((Sender as TScrollBar).Parent as TPanel).Controls[cycle] as TControl).Tag-(Sender as TScrollBar).Position;
end;
end;
end.
和.dfm:
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 473
ClientWidth = 769
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
OnResize = FormResize
DesignSize = (
769
473)
PixelsPerInch = 96
TextHeight = 13
object Panel1: TPanel
Left = 0
Top = 0
Width = 257
Height = 473
Anchors = [akLeft, akTop, akBottom]
BevelOuter = bvNone
BorderStyle = bsSingle
TabOrder = 0
object Label1: TLabel
Left = 104
Top = 16
Width = 31
Height = 13
Caption = 'Label1'
end
object Label2: TLabel
Left = 104
Top = 152
Width = 31
Height = 13
Caption = 'Label2'
end
object Memo1: TMemo
Left = 8
Top = 32
Width = 497
Height = 89
Lines.Strings = (
'Memo1')
TabOrder = 0
end
object Memo2: TMemo
Left = 8
Top = 168
Width = 497
Height = 89
Lines.Strings = (
'Memo2')
TabOrder = 1
end
object ScrollBar1: TScrollBar
AlignWithMargins = True
Left = 0
Top = 452
Width = 236
Height = 17
Margins.Left = 0
Margins.Top = 0
Margins.Right = 17
Margins.Bottom = 0
Align = alBottom
PageSize = 0
TabOrder = 2
OnChange = ScrollBarHChange
ExplicitWidth = 253
end
object ScrollBar4: TScrollBar
Left = 236
Top = 0
Width = 17
Height = 452
Align = alRight
Enabled = False
Kind = sbVertical
PageSize = 0
TabOrder = 3
OnChange = ScrollBarVChange
ExplicitTop = 248
ExplicitHeight = 121
end
end
object Panel2: TPanel
Left = 256
Top = 0
Width = 257
Height = 473
Anchors = [akLeft, akTop, akBottom]
BevelOuter = bvNone
BorderStyle = bsSingle
TabOrder = 1
object Label3: TLabel
Left = 104
Top = 16
Width = 31
Height = 13
Caption = 'Label3'
end
object Label4: TLabel
Left = 104
Top = 152
Width = 31
Height = 13
Caption = 'Label4'
end
object Memo3: TMemo
Left = 8
Top = 32
Width = 497
Height = 89
Lines.Strings = (
'Memo3')
TabOrder = 0
end
object Memo4: TMemo
Left = 8
Top = 168
Width = 497
Height = 89
Lines.Strings = (
'Memo4')
TabOrder = 1
end
object ScrollBar2: TScrollBar
AlignWithMargins = True
Left = 0
Top = 452
Width = 236
Height = 17
Margins.Left = 0
Margins.Top = 0
Margins.Right = 17
Margins.Bottom = 0
Align = alBottom
PageSize = 0
TabOrder = 2
OnChange = ScrollBarHChange
ExplicitWidth = 253
end
object ScrollBar5: TScrollBar
Left = 236
Top = 0
Width = 17
Height = 452
Align = alRight
Enabled = False
Kind = sbVertical
PageSize = 0
TabOrder = 3
OnChange = ScrollBarVChange
ExplicitTop = 248
ExplicitHeight = 121
end
end
object Panel3: TPanel
Left = 512
Top = 0
Width = 257
Height = 473
Anchors = [akLeft, akTop, akBottom]
BevelOuter = bvNone
BorderStyle = bsSingle
TabOrder = 2
object Label5: TLabel
Left = 104
Top = 16
Width = 31
Height = 13
Caption = 'Label5'
end
object Label6: TLabel
Left = 104
Top = 152
Width = 31
Height = 13
Caption = 'Label6'
end
object Memo5: TMemo
Left = 8
Top = 32
Width = 497
Height = 89
Lines.Strings = (
'Memo5')
TabOrder = 0
end
object Memo6: TMemo
Left = 8
Top = 168
Width = 497
Height = 89
Lines.Strings = (
'Memo6')
TabOrder = 1
end
object ScrollBar3: TScrollBar
AlignWithMargins = True
Left = 0
Top = 452
Width = 236
Height = 17
Margins.Left = 0
Margins.Top = 0
Margins.Right = 17
Margins.Bottom = 0
Align = alBottom
PageSize = 0
TabOrder = 2
OnChange = ScrollBarHChange
ExplicitWidth = 253
end
object ScrollBar6: TScrollBar
Left = 236
Top = 0
Width = 17
Height = 452
Align = alRight
Enabled = False
Kind = sbVertical
PageSize = 0
TabOrder = 3
OnChange = ScrollBarVChange
ExplicitTop = 248
ExplicitHeight = 121
end
end
end