Gtk3: Fixed sizing of group box and relatives checkgroup and radiogroup, fixed radiobutton gtk asserts because of HiddenRadioButton

This commit is contained in:
zeljan1 2025-01-20 19:23:41 +01:00
parent 0d73603378
commit fd3a20f5c9
6 changed files with 405 additions and 24 deletions

View File

@ -22,6 +22,8 @@ const
{$endif}
type
Pcairo_bool_t = ^TCairo_bool_t;
TCairo_bool_t = LongInt;
Tcairo_status_t = (
Tcairo_status_tMinValue = -$7FFFFFFF,
CAIRO_STATUS_SUCCESS = 0,
@ -605,8 +607,8 @@ procedure cairo_show_page(cr: Pcairo_t); cdecl; external LIB_CAIRO;
(* Insideness testing *)
//function cairo_in_stroke(cr: Pcairo_t; x, y: Double): Tcairo_bool_t; cdecl; external LIB_CAIRO;
//function cairo_in_fill(cr: Pcairo_t; x, y: Double): Tcairo_bool_t; cdecl; external LIB_CAIRO;
function cairo_in_stroke(cr: Pcairo_t; x, y: Double): Tcairo_bool_t; cdecl; external LIB_CAIRO;
function cairo_in_fill(cr: Pcairo_t; x, y: Double): Tcairo_bool_t; cdecl; external LIB_CAIRO;
(* Rectangular extents *)

View File

@ -0,0 +1,160 @@
{%MainUnit gtk3widgets.pas}
const
GTK_FRAME_CLASS_SIZE = SizeOf(TGtkFrameClass);
GTK_FRAME_INSTANCE_SIZE = SizeOf(TGtkFrame);
procedure LCLGtkFrameGetPreferredWidth(widget: PGtkWidget; min_width, nat_width: Pgint); cdecl;
var
AControl: TGtk3Widget;
ParentClass: PGtkWidgetClass;
begin
if not Assigned(min_width) or not Assigned(nat_width) then
begin
DebugLn('Error: LCLGtkFrameGetPreferredWidth invalid params.');
Exit;
end;
if not Gtk3IsWidget(widget) then
begin
DebugLn('Error: LCLGtkFrameGetPreferredWidth widget param is not PGtkWidget.');
Exit;
end;
ParentClass := PGtkWidgetClass(g_type_class_peek_parent(widget^.g_type_instance.g_class));
if not Assigned(ParentClass) then
begin
DebugLn('Error: LCLGtkFrameGetPreferredWidth cannot get ParentClass !');
Exit;
end;
// Call parent class implementation
ParentClass^.get_preferred_width(widget, min_width, nat_width);
// writeln('LCLFrame preferred min_width=',min_width^,' natural w=',nat_width^);
AControl := TGtk3Widget(HwndFromGtkWidget(widget));
if not Assigned(AControl) then
begin
DebugLn('Error: LCLGtkFrameGetPreferredWidth cannot get TGtk3Widget for widget parameter.');
Exit;
end;
// LCL does not like when ws calculates autosize dimensions
// writeln('====> FGPW(',dbgsName(AControl.LCLObject),'): AutoSize=', AControl.LCLObject.AutoSize,' minW=',min_width^,' natW=',nat_width^,' LCLWidth=',AControl.LCLWidth,' LCLHeight=',AControl.LCLHeight);
if AControl.LCLObject.AutoSize then
begin
//if AControl.LCLWidth > min_width^ then
// nat_width^ := AControl.LCLWidth;
//min_width^ := Max(min_width^, AControl.LCLObject.Width);
//if AControl.LCLWidth > 0 then
// nat_width^ := Max(min_width^, AControl.LCLWidth);
// exit;
end;
if AControl.LCLWidth = 0 then
begin
min_width^ := Max(min_width^ div 2, AControl.LCLObject.Width);
nat_width^ := Max(min_width^ div 2, AControl.LCLObject.Width);
end else
begin
min_width^ := Max(min_width^ div 2, AControl.LCLWidth);
nat_width^ := Max(min_width^ div 2, AControl.LCLWidth);
end;
end;
procedure LCLGtkFrameGetPreferredHeight(widget: PGtkWidget; min_height, nat_height: Pgint); cdecl;
var
AControl: TGtk3Widget;
ParentClass: PGtkWidgetClass;
begin
if not Assigned(min_height) or not Assigned(nat_height) then
begin
DebugLn('Error: LCLGtkFrameGetPreferredHeight invalid params.');
Exit;
end;
if not Gtk3IsWidget(widget) then
begin
DebugLn('Error: LCLGtkFrameGetPreferredHeight widget param is not PGtkWidget.');
Exit;
end;
ParentClass := PGtkWidgetClass(g_type_class_peek_parent(widget^.g_type_instance.g_class));
if not Assigned(ParentClass) then
begin
DebugLn('Error: LCLGtkFrameGetPreferredHeight cannot get ParentClass !');
Exit;
end;
// Call parent class implementation
ParentClass^.get_preferred_height(widget, min_height, nat_height);
AControl := TGtk3Widget(HwndFromGtkWidget(widget));
if not Assigned(AControl) then
begin
DebugLn('Error: LCLGtkFrameGetPreferredHeight cannot get TGtk3Widget for widget parameter.');
Exit;
end;
// fixme. min_height and nat_height reports complete box size, but lcl sets client size ?
// LCL does not like when ws calculates autosize dimensions.
// writeln('====> FGPH(',dbgsName(AControl.LCLObject),'): AutoSize=', AControl.LCLObject.AutoSize,' minH=',min_height^,' natH=',nat_height^,' LCLWidth=',AControl.LCLWidth,' Height=',AControl.LCLHeight);
if AControl.LCLObject.AutoSize then
begin
// if AControl.LCLHeight > nat_height^ then
// nat_height^ := AControl.LCLHeight;
// exit;
end;
if AControl.LCLHeight = 0 then
begin
min_height^ := Max(min_height^ div 2, AControl.LCLObject.Height);
nat_height^ := Max(min_height^ div 2, AControl.LCLObject.Height);
end else
begin
min_height^ := Max(min_height^ div 2, AControl.LCLHeight);
nat_height^ := Max(min_height^ div 2, AControl.LCLHeight);
end;
end;
procedure LCLGtkFrameClassInit(klass: PGTypeClass; {%H-}data: Pointer); cdecl;
var
AWidgetClass: PGtkWidgetClass;
begin
AWidgetClass := PGtkWidgetClass(klass);
AWidgetClass^.get_preferred_width := @LCLGtkFrameGetPreferredWidth;
AWidgetClass^.get_preferred_height := @LCLGtkFrameGetPreferredHeight;
end;
procedure LCLGtkFrameInstanceInit(instance: PGTypeInstance; {%H-}klass: PGTypeClass); cdecl;
begin
//
end;
var
LCLGtkFrameType: TGType = 0;
function LCLGtkFrameGetType: TGType; cdecl;
const
lcl_frame_type_info: TGTypeInfo = (
class_size: GTK_FRAME_CLASS_SIZE;
base_init: nil;
base_finalize: nil;
class_init: @LCLGtkFrameClassInit;
class_finalize: nil;
class_data: nil;
instance_size: GTK_FRAME_INSTANCE_SIZE;
n_preallocs: 0;
instance_init: @LCLGtkFrameInstanceInit;
value_table: nil;
);
begin
if LCLGtkFrameType = 0 then
LCLGtkFrameType := g_type_register_static(gtk_frame_get_type, 'LCLGtkFrame', @lcl_frame_type_info, G_TYPE_FLAG_NONE);
Result := LCLGtkFrameType;
end;
function LCLGtkFrameNew: PGtkFrame;
begin
{in gtk3 this is default shadow}
Result := PGtkFrame(g_object_new(LCLGtkFrameGetType(),'shadow-type',[GTK_SHADOW_ETCHED_IN, nil]));
end;

View File

@ -58,6 +58,8 @@ type
wtWindow, wtDialog, wtHintWindow, wtGLArea);
TGtk3WidgetTypes = set of TGtk3WidgetType;
TGtk3GroupBoxType = (gbtGroupBox, gbtCheckGroup, gbtRadioGroup);
{ TGtk3Widget }
TGtk3Widget = class(TGtk3Object, IUnknown)
@ -674,11 +676,20 @@ type
{ TGtk3GroupBox }
TGtk3GroupBox = class(TGtk3Bin)
strict private
class procedure GroupBoxSizeAllocate(AWidget: PGtkWidget; AGdkRect: PGdkRectangle; Data: gpointer); cdecl; static;
private
FGroupBoxType:TGtk3GroupBoxType;
function GetInnerClientRect(Frame:PGtkWidget):TRect;
protected
procedure ConnectSizeAllocateSignal(ToWidget: PGtkWidget); override;
function CreateWidget(const {%H-}Params: TCreateParams):PGtkWidget; override;
function getText: String; override;
procedure setText(const AValue: String); override;
public
procedure SetBounds(ALeft,ATop,AWidth,AHeight:integer); override;
function getClientRect:TRect; override;
property GroupBoxType: TGtk3GroupBoxType read FGroupBoxType write FGroupBoxType;
end;
{ TGtk3ComboBox }
@ -762,16 +773,17 @@ type
protected
function CreateWidget(const {%H-}Params: TCreateParams):PGtkWidget; override;
public
procedure SetBounds(ALeft,ATop,AWidth,AHeight:integer); override;
property State: TCheckBoxState read GetState write SetState;
end;
{ TGtk3RadioButton }
TGtk3RadioButton = class(TGtk3CheckBox)
private
protected
function CreateWidget(const {%H-}Params: TCreateParams):PGtkWidget; override;
public
function getClientRect:TRect; override;
procedure InitializeWidget; override;
end;
@ -1049,6 +1061,7 @@ end;
{$i gtk3lclentry.inc}
{$i gtk3lclbutton.inc}
{$i gtk3lclspinbutton.inc}
{$i gtk3lclframe.inc}
class function TGtk3Widget.WidgetEvent(widget: PGtkWidget; event: PGdkEvent; data: GPointer): gboolean; cdecl;
begin
@ -3005,7 +3018,6 @@ function TGtk3Widget.getClientRect: TRect;
var
AAlloc: TGtkAllocation;
begin
//writeln('GetClientRect ',LCLObject.Name,':',LCLObject.Name);
Result := LCLObject.BoundsRect;
if not IsWidgetOK then
exit;
@ -3019,7 +3031,7 @@ begin
FWidget^.get_allocation(@AAlloc);
Result := Rect(AAlloc.x, AAlloc.y, AAlloc.width + AAlloc.x,AAlloc.height + AAlloc.y);
end;
OffsetRect(Result, -Result.Left, -Result.Top);
Types.OffsetRect(Result, -Result.Left, -Result.Top);
end;
function TGtk3Widget.getClientBounds: TRect;
@ -3485,14 +3497,13 @@ end;
function TGtk3GroupBox.CreateWidget(const Params: TCreateParams): PGtkWidget;
begin
FHasPaint := True;
//dont use layout for now
FGroupBoxType := gbtGroupBox;
FWidgetType := [wtWidget, wtContainer, wtGroupBox];
Result := TGtkFrame.new(PChar(Self.LCLObject.Caption));
//FCentralWidget := TGtkLayout.new(nil,nil);
Result := LCLGtkFrameNew;
FCentralWidget := TGtkFixed.new;
PGtkBin(Result)^.add(FCentralWidget);
FCentralWidget^.set_has_window(True);
PgtkFrame(result)^.set_label_align(0.1,0.5);
PGtkFrame(result)^.set_label_align(0.1,0.5);
end;
function TGtk3GroupBox.getText: String;
@ -3502,7 +3513,7 @@ begin
begin
if PGtkFrame(Widget)^.get_label_widget = nil then
exit;
Result := ReplaceUnderscoresWithAmpersands(PGtkFrame(Widget)^.get_label);
Result := {%H-}ReplaceUnderscoresWithAmpersands(PGtkFrame(Widget)^.get_label);
end;
end;
@ -3512,16 +3523,178 @@ begin
begin
if AValue = '' then
PGtkFrame(Widget)^.set_label_widget(nil)
// maybe DoAdjustClientRect here
else
begin
if PGtkFrame(Widget)^.get_label_widget = nil then
PGtkFrame(Widget)^.set_label_widget(TGtkLabel.new(''));
PGtkFrame(Widget)^.set_label(PgChar(ReplaceAmpersandsWithUnderscores(AValue)));
{%H-}PGtkFrame(Widget)^.set_label(PgChar({%H-}ReplaceAmpersandsWithUnderscores(AValue)));
end;
end;
end;
procedure TGtk3GroupBox.SetBounds(ALeft,ATop,AWidth,AHeight:integer);
var
Alloc:TGtkAllocation;
begin
{$IF DEFINED(GTK3DEBUGSIZE) OR DEFINED(GTK3DEBUGGROUPBOX)}
writeln(Format('TGtk3GroupBox.setBounds l %d t %d w %d h %d',[ALeft, ATop, AWidth, AHeight]));
{$ENDIF}
LCLWidth := AWidth;
LCLHeight := AHeight;
Alloc.x := ALeft;
Alloc.y := ATop;
Alloc.width := AWidth;
Alloc.Height := AHeight;
Widget^.set_allocation(@Alloc);
Move(ALeft, ATop);
end;
{$IF DEFINED(GTK3DEBUGSIZE) OR DEFINED(GTK3DEBUGGROUPBOX)}
procedure ContainerChildrenCallback(widget: PGtkWidget; data: gpointer); cdecl;
begin
// This callback is called for each child of the GtkFixed container
WriteLn('TGtk3GroupBox Child widget pointer: ', PtrUInt(widget),' ACtl=',dbgsName(TGtk3WIdget(data)));
// Example: Print the widget type name
WriteLn('TGtk3GroupBox Widget type: ', gtk_widget_get_name(widget));
end;
{$ENDIF}
class procedure TGtk3GroupBox.GroupBoxSizeAllocate(AWidget:PGtkWidget;AGdkRect:
PGdkRectangle;Data:gpointer);cdecl;
var
Msg: TLMSize;
NewSize: TSize;
ACtl: TGtk3GroupBox;
AState: TGdkWindowState;
Alloc: TGtkAllocation;
AList:PGList;
AFixed: PGtkFixed;
i:Integer;
begin
if AWidget=nil then ;
ACtl := TGtk3GroupBox(Data);
{$IF DEFINED(GTK3DEBUGSIZE) OR DEFINED(GTK3DEBUGGROUPBOX)}
with AGdkRect^ do
DebugLn('**** GroupBoxSizeAllocate **** ....',dbgsName(ACtl.LCLObject),
' ',Format('GTK x %d y %d w %d h %d',[x, y, width, height]),
Format(' LCL W=%d H=%d LLW %d LLH %d upd=%s',[ACtl.LCLObject.Width, ACtl.LCLObject.Height, ACtl.LCLWidth, ACtl.LCLHeight, BoolToStr(ACtl.InUpdate, True)]));
{$ENDIF}
with Alloc do
begin
x := AGdkRect^.x;
y := AGdkRect^.y;
Width := AGdkRect^.width;
Height := AGdkRect^.height;
end;
gtk_widget_set_clip(AWidget, @Alloc);
if not Assigned(ACtl.LCLObject) then exit;
// return size w/o frame
NewSize.cx := AGdkRect^.width;
NewSize.cy := AGdkRect^.height;
if not (csDesigning in ACtl.LCLObject.ComponentState) then
begin
if ACtl.InUpdate then
exit;
end;
{$IF DEFINED(GTK3DEBUGSIZE) OR DEFINED(GTK3DEBUGGROUPBOX)}
if not ACtl.LCLObject.AutoSize and (ACtl.LCLWidth > 0) and (ACtl.LCLHeight > 0) and
ACtl.LCLObject.ClientRectNeedsInterfaceUpdate then
begin
if (AGdkRect^.Width = ACtl.LCLWidth) and (AGdkRect^.Height = ACtl.LCLHeight) then
begin
//ACtl.LCLObject.DoAdjustClientRectChange;
AFixed := PGtkFixed(ACtl.getContainerWidget);
if AFixed^.compute_expand(GTK_ORIENTATION_VERTICAL) then
AFixed^.resize_children;
// PGtkLayout(AFixed)^.set_size(AFixed^.get_allocated_width, AFixed^.get_allocated_height);
gtk_container_foreach(AFixed, @ContainerChildrenCallback, ACtl);
exit;
end;
end;
{$ENDIF}
FillChar(Msg{%H-}, SizeOf(Msg), #0);
Msg.Msg := LM_SIZE;
Msg.SizeType := SIZE_RESTORED;
Msg.SizeType := Msg.SizeType or Size_SourceIsInterface;
Msg.Width := Word(NewSize.cx);
Msg.Height := Word(NewSize.cy);
ACtl.DeliverMessage(Msg);
end;
{This routine is used as long as gtk3 is beta and getClientRect needs debugging}
function TGtk3GroupBox.GetInnerClientRect(Frame: PGtkWidget): TRect;
var
Allocation: TGdkRectangle;
AStyleContext: PGtkStyleContext;
Padding, Border: TGtkBorder;
LabelWidget: PGtkWidget;
FinalRect: TGdkRectangle;
minH:gint;
natH:gint;
begin
Result := Rect(0, 0, 0, 0);
gtk_widget_get_allocation(Frame, @Allocation);
LabelWidget := gtk_frame_get_label_widget(PGtkFrame(Frame));
AStyleContext := gtk_widget_get_style_context(Frame);
gtk_style_context_get_padding(AStyleContext, GTK_STATE_FLAG_NORMAL, @Padding);
gtk_style_context_get_border(AStyleContext, GTK_STATE_FLAG_NORMAL, @Border);
FinalRect.X := Allocation.X + Border.Left + Padding.Left;
FinalRect.Y := Allocation.Y + Border.Top + Padding.Top;
FinalRect.Width := Allocation.Width - Border.Left - Border.Right - Padding.Left - Padding.Right;
FinalRect.Height := Allocation.Height - Border.Top - Border.Bottom - Padding.Top - Padding.Bottom;
if PGtkFrame(Frame)^.get_shadow_type > GTK_SHADOW_NONE then
begin
// this looks like a bug in gtk3, that's why I separated this part of code. Zeljan.
if (Border.left = 0) and (Border.Right = 0) then
dec(FinalRect.Width, 2);
if (Border.Top = 0) and (Border.Bottom = 0) then
dec(FinalRect.Height, 2);
end;
if Assigned(LabelWidget) then
begin
PGtkLabel(LabelWidget)^.get_preferred_height(@minH, @natH);
FinalRect.Y := FinalRect.Y + natH;
FinalRect.Height := FinalRect.Height - natH;
{$IF DEFINED(GTK3DEBUGSIZE) OR DEFINED(GTK3DEBUGGROUPBOX)}
writeln('LabelAllocation LCLObject.Caption=',LCLObject.Caption,' LabelText=',PGtkLabel(LabelWidget)^.get_text,' MinH=',MinH,' NatH=',NatH);
{$ENDIF}
end;
Result := RectFromGdkRect(FinalRect);
end;
procedure TGtk3GroupBox.ConnectSizeAllocateSignal(ToWidget:PGtkWidget);
begin
g_signal_connect_data(ToWidget,'size-allocate',TGCallback(@GroupBoxSizeAllocate), Self, nil, G_CONNECT_DEFAULT);
end;
function TGtk3GroupBox.getClientRect:TRect;
var
Alloc:TGtkAllocation;
R: TRect;
begin
Result := GetInnerClientRect(Widget);
Types.OffsetRect(Result, -Result.Left, -Result.Top);
end;
{ TGtk3Editable }
@ -5668,7 +5841,6 @@ begin
VOffset := Bar^.get_allocated_width
else
VOffset := 0;
AViewPort^.get_view_window^.get_geometry(@x, @y, @w, @h);
Result := Bounds(x, y, w - VOffset, h - HOffset);
end else
@ -7816,6 +7988,24 @@ begin
check^.set_use_underline(True);
end;
procedure TGtk3CheckBox.SetBounds(ALeft,ATop,AWidth,AHeight:integer);
var
Alloc:TGtkAllocation;
begin
if LCLObject.Name = 'HiddenRadioButton' then
exit;
LCLWidth := AWidth;
LCLHeight := AHeight;
// not needed
// Widget^.set_size_request(AWidth, AHeight);
Alloc.x := ALeft;
Alloc.y := ATop;
Alloc.width := AWidth;
Alloc.height := AHeight;
Widget^.set_allocation(@Alloc);
Move(ALeft, ATop);
end;
{ TGtk3RadioButton }
function TGtk3RadioButton.CreateWidget(const Params: TCreateParams): PGtkWidget;
@ -7879,6 +8069,21 @@ begin
inherited InitializeWidget;
end;
function TGtk3RadioButton.getClientRect:TRect;
var
Alloc:TGtkAllocation;
R: TRect;
begin
Result := Rect(0, 0, 0, 0);
//Famous "HiddenRadioButton"
if (Widget = nil) then
exit;
Widget^.get_allocation(@Alloc);
Result := Bounds(Alloc.x, Alloc.y, Alloc.Width, Alloc.Height);
Types.OffsetRect(Result, -Result.Left, -Result.Top);
end;
{ TGtk3CustomControl }
function TGtk3CustomControl.CreateWidget(const Params: TCreateParams): PGtkWidget;

View File

@ -89,6 +89,7 @@ type
TGtk3WSCustomRadioGroup = class(TWSCustomRadioGroup)
published
class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLHandle; override;
end;
{ TGtk3WSRadioGroup }
@ -101,6 +102,7 @@ type
TGtk3WSCustomCheckGroup = class(TWSCustomCheckGroup)
published
class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLHandle; override;
end;
{ TGtk3WSCheckGroup }
@ -148,7 +150,7 @@ type
implementation
uses
gtk3widgets;
gtk3widgets, Gtk3WSStdCtrls;
{ TGtk3WSCustomSplitter }
@ -161,6 +163,20 @@ begin
Result := TLCLHandle(ASplitter);
end;
class function TGtk3WSCustomRadioGroup.CreateHandle(const AWinControl:TWinControl;
const AParams:TCreateParams):TLCLHandle;
begin
Result := TGtk3WSCustomGroupBox.CreateHandle(AWinControl,AParams);
TGtk3GroupBox(Result).GroupBoxType := gbtRadioGroup;
end;
class function TGtk3WSCustomCheckGroup.CreateHandle(const AWinControl:TWinControl;
const AParams:TCreateParams):TLCLHandle;
begin
Result:= TGtk3WSCustomGroupBox.CreateHandle(AWinControl,AParams);
TGtk3GroupBox(Result).GroupBoxType := gbtCheckGroup;
end;
{ TGtk3WSCustomPanel }
class function TGtk3WSCustomPanel.CreateHandle(const AWinControl: TWinControl;

View File

@ -437,16 +437,14 @@ end;
function RegisterCustomRadioGroup: Boolean; alias : 'WSRegisterCustomRadioGroup';
begin
// RegisterWSComponent(TCustomRadioGroup, TGtk2WSCustomRadioGroup);
// RegisterWSComponent(TRadioGroup, TGtk2WSRadioGroup);
Result := False;
RegisterWSComponent(TCustomRadioGroup, TGtk3WSCustomRadioGroup);
Result := True;
end;
function RegisterCustomCheckGroup: Boolean; alias : 'WSRegisterCustomCheckGroup';
begin
// RegisterWSComponent(TCustomCheckGroup, TGtk2WSCustomCheckGroup);
// RegisterWSComponent(TCheckGroup, TGtk2WSCheckGroup);
Result := False;
RegisterWSComponent(TCustomCheckGroup, TGtk3WSCustomCheckGroup);
Result := True;
end;
function RegisterCustomLabeledEdit: Boolean; alias : 'WSRegisterCustomLabeledEdit';

View File

@ -309,11 +309,10 @@ uses
class function TGtk3WSCustomGroupBox.CreateHandle(
const AWinControl: TWinControl; const AParams: TCreateParams): TLCLHandle;
var
AGroupBox: TGtk3GroupBox;
begin
AGroupBox := TGtk3GroupBox.Create(AWinControl, AParams);
Result := TLCLHandle(AGroupBox);
Result := TLCLHandle(TGtk3GroupBox.Create(AWinControl, AParams));
//Gtk3Frame needs label before first call of GetClientRect
TGtk3GroupBox(Result).Text := AWinControl.Caption;
end;
class procedure TGtk3WSCustomGroupBox.GetPreferredSize(
@ -383,6 +382,7 @@ class procedure TGtk3WSScrollBar.SetKind(const AScrollBar: TCustomScrollBar;
begin
if not WSCheckHandleAllocated(AScrollBar, 'SetKind') then
Exit;
//TODO: try with PGtkOrientable(Widget)^.set_orientation instead of RecreateWnd.
RecreateWnd(AScrollBar);
end;