TL;DR If I put a control inside a TScrollBox at negative offset, is there a way to force scrollbars to appear?
TL;DR If I put a control inside a TScrollBox at negative offset, is there a way to force scrollbars to appear?
So I have this scrollbox (TScrollBox, VCL) ... If I put inside one TPanel so that it lies outside the scrollbox on the right/bottom edge, scrollbox will display scrollbars. All good and well.
If I, however, place that TPanel so that it lies outside the scrollbox on the left/top side, there are no scrollbars.
object ScrollBox: TScrollBox
Left = 40
Top = 24
Width = 225
Height = 160
TabOrder = 0
object Panel1: TPanel
Left = 88
Top = 72
Width = 217
Height = 137
Caption = 'Panel1'
TabOrder = 0
end
end
object ScrollBox1: TScrollBox
Left = 368
Top = 24
Width = 225
Height = 160
TabOrder = 1
object Panel2: TPanel
Left = -99
Top = -56
Width = 217
Height = 137
Caption = 'Panel1'
TabOrder = 0
end
end
If I understand the code correctly, this is "by design" as TControlScrollBar always sets scrollinfo.nMin to 0 and only modifies the nMax.
ScrollInfo.nMin := 0;
if FCalcRange > 0 then
ScrollInfo.nMax := Range else
ScrollInfo.nMax := 0;
Did anybody run into that and successfully solved this problem? I don't mind calling some code to update scrollbars as I'm already calling Realing to update them ...
/sub
ReplyDelete/sub
ReplyDeleteSo the case where you have the panel with negative Left and Top effectively means that the HScroll pos, VScroll pos should be at 99, 56, respectively, IF you could scroll using the scroll bar. Correct? I suppose you want to keep AutoScroll to True and have the scrollbar show if you place items at negative positions (and not set the scroll bars' range yourself). Interesting requirement, but I wonder what is the scenario, before I can try to help.
ReplyDeleteAttila Kovacs I'm not sure I understood you. What container? I want panel to "stick out" on the left.
ReplyDeleteIn reality this panel is a custom MDI window which user just moved with mouse to the left and (s)he is expecting scrollbars to appear.
Actually I don't use mdiform and mdichilds but normal forms with some (quite a lot) custom handling.
ReplyDeleteI'm guessing - one way is to do what happens with MDI Forms/children for controlling scrollbar visibility/range in VCL.Forms and the TFormStyleHook class?
ReplyDeleteBased on Attila Kovacs's suggestion, this seems to be working fine:
ReplyDeleteprocedure TScrollBox.FixScrollBoxScrollbarPositions;
var
control: TControl;
minx : integer;
miny : integer;
newx : integer;
newy : integer;
begin
if ControlCount = 0 then
Exit;
minx := 0;
miny := 0;
for control in EnumControls do
if control.Visible then begin
minx := Min(minx, control.Left);
miny := Min(miny, control.Top);
end;
minx := minx + HorzScrollBar.Position;
miny := miny + VertScrollBar.Position;
DisableAutoRange;
for control in EnumControls do begin
newx := control.Left - minx;
newy := control.Top - miny;
control.Left := newx;
control.Top := newy;
end;
LockWindowUpdate(Handle);
EnableAutoRange;
HorzScrollBar.Position := HorzScrollBar.Position - minx;
VertScrollBar.Position := VertScrollBar.Position - miny;
LockWindowUpdate(0);
end;
Primož Gabrijelčič thanks for posting the solution.
ReplyDeleteIt is working, but not good enough :( There are some edge cases where this "fix" fails to deliver. I'm still trying to find a better approach.
ReplyDeletePlease post the fix: if you will find one😊
ReplyDeleteFabio VITALE ATM it looks like I'll be 're-implementing' TScrollBox functionality using TPanel and two TScrollBars (and even TScrollBar will require some workaround as the implementation is just plain stupid in some parts).
ReplyDelete