TListbox : horizontaler Scrollbalken

Für Fragen von Einsteigern und Programmieranfängern...
malabarista
Beiträge: 321
Registriert: Sa 11. Jun 2016, 12:16
OS, Lazarus, FPC: Linux Mint 18.1 L1.6.2-1 FPC 3.0.0
CPU-Target: 64Bit
Wohnort: Konstanz

Re: TListbox : horizontaler Scrollbalken

Beitrag von malabarista »

Dieses Problem mit der (automatisch geänderten) Scrollwidth tritt sowohl unter Linux wie unter Windows auf.
Unter Linux hat es keine weiteren Auswirkungen, d.h. es wird kein horizontaler Scrollbalken angezeigt.

Unter Windows 7 allerdings wird dann deshalb immer ein horizontaler Scrollbalken angezeigt: und das sieht bei kleinen Listboxen schlecht aus.

wp_xyz
Beiträge: 3746
Registriert: Fr 8. Apr 2011, 09:01

Re: TListbox : horizontaler Scrollbalken

Beitrag von wp_xyz »

Ok, dann also doch so wie im 1. Post beschrieben. Dann kann ich dir leider nicht helfen, denn ich kann das Verhalten auch unter Win7 mit Laz trunk und 1.6 nicht bestätigen (wobei das Win 7 in meiner VM aber nur 32-Bit hat) (die bisherigen Tests waren auf Win 10, 64-bit).

moasda
Beiträge: 3
Registriert: Sa 29. Mai 2021, 16:35

Re: TListbox : horizontaler Scrollbalken

Beitrag von moasda »

Dieser Thread ist zwar schon etwas älter, aber ich habe auch das oben beschriebene Problem, dass der Wert ListBox.ScrollWidth automatisch verändert wird, sobald ich ein entsprechendes Formular in Lazarus öffne.

OS: Ubuntu 21.04
Lazarus: 2.0.12

Beim Debuggen im Lazarus-Code habe ich festgestellt, dass der zuvor in der Eigenschaft ScrollWidth eingestellte Wert gar nicht verwendet, sondern stets von GTK2 abgefragt wird, wie an nachfolgenden Codeausschnitten zu sehen ist.

Beim Abfragen der Eigenschaft ScrollWidth wird GetScrollWidth() aufgerufen (Datei customlistbox.inc):

Code: Alles auswählen

function TCustomListBox.GetScrollWidth: Integer;
begin
  if HandleAllocated then
    Result := TWSCustomListBoxClass(WidgetSetClass).GetScrollWidth(Self)
  else
    Result := FScrollWidth;
end;
Da HandleAllocated immer True ist, wird der Aufruf bei mir an TGtk2WSCustomListBox weitergereicht (Datei Gtk2WSStdCtrls.pp):

Code: Alles auswählen

class function TGtk2WSCustomListBox.GetScrollWidth(const ACustomListBox: TCustomListBox): Integer;
var
  Adjustment: PGtkAdjustment;
begin
  Adjustment := gtk_scrolled_window_get_hadjustment({%H-}PGtkScrolledWindow(ACustomListBox.Handle));
  Result := Trunc(Adjustment^.upper);
end;
Die Funktion gtk_scrolled_window_get_hadjustment() der GTK2-Bibliothek gibt schließlich den Wert zurück, den man dann im Objektinstpektor bei ScrollWidth sieht. Der Wert wird also zur Laufzeit (im Lazarus-Editor und auch später bei der Programmausführung) ermittelt, daher sucht man ihn vergeblich in den eigenen Projektdateien.

Ein möglicher Lösungsansatz besteht in folgendem Lazarus-Ticket, das die Einführung einer Eigenschaft TListBox.AutoScrollWidth vorschlägt. Dann könnte man steuern, ob der Wert für ScrollWidth dynamisch ermittelt oder der eingestellte Wert verwendet werden soll:
https://bugs.freepascal.org/view.php?id=19079

Michl
Beiträge: 2424
Registriert: Di 19. Jun 2012, 12:54

Re: TListbox : horizontaler Scrollbalken

Beitrag von Michl »

Hab den Thread hier nur überflogen. Soweit ich sehen konnte, konnte wp es nicht nachstellen. Von daher, kannst du ein entsprechendes Minimalprojekt anfügen?

Neue Properties einzufügen, nur um ein ungewolltes Verhalten zu überdecken, finde ich nicht so gut.

Der Patch im Bugreport enthält auch nicht dieses Property.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

moasda
Beiträge: 3
Registriert: Sa 29. Mai 2021, 16:35

Re: TListbox : horizontaler Scrollbalken

Beitrag von moasda »

malabarista hat bereits weiter oben ein Minimalprojekt angehängt, mit dem ich das Problem auch bei mir reproduzieren kann.

Das Minimalprojekt kann aber auch selbst schnell zusammengeklickt werden: Einfach ein neues Lazarus-Projekt anlegen und in das Hauptformular (Form1) eine TListBox setzen. Fertig. Diese ListBox hat bei mir von Anfang an für ScrollWidth einen Wert > 0 (genau genommen Width - 2). Wenn ich die Breite der ListBox ändere (egal ob mit der Maus oder über die Eigenschaft Width), ändert sich auch der Wert von ScrollWidth synchron mit (immer Width - 2).

Ein manuelles Setzen von ScrollWidth hilft nicht dauerhaft: Wenn ich ScrollWidth im Objektinspektor auf z.B. 1 setze, das Projekt speichere und wieder öffne, ist der Wert wieder wie oben an die ListBox-Breite angepasst. Dasselbe passiert zur Laufzeit des Programms: ScrollWidth in FormCreate auf 1 setzen, dann hat es anfangs auch den Wert 1. Sobald man aber die Breite der ListBox verändert (z.B. ListBox.Align=alTop und dann die Fensterbreite per Maus ändern), passt sich ScrollWidth wieder an die ListBox-Breite an.
Michl hat geschrieben:
Sa 29. Mai 2021, 20:13
Neue Properties einzufügen, nur um ein ungewolltes Verhalten zu überdecken, finde ich nicht so gut.

Der Patch im Bugreport enthält auch nicht dieses Property.
Stimmt, das war nur das einzige gefundene Ticket, das halbwegs zum Thema passt.

Benutzeravatar
Winni
Beiträge: 796
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.0.12, fpc 3.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: TListbox : horizontaler Scrollbalken

Beitrag von Winni »

Hi!

Workaround bis der Bug behoben ist:. In OnResize einhängen:

Code: Alles auswählen

procedure TForm1.ListBox1Resize(Sender: TObject);
begin
ListBox1.ScrollWidth:= ListBox1.width +3;
end;
Winni

Michl
Beiträge: 2424
Registriert: Di 19. Jun 2012, 12:54

Re: TListbox : horizontaler Scrollbalken

Beitrag von Michl »

Ok, das Problem ist, daß du eine horizontale Scrollbar sehen willst, obwohl keine da bzw. notwendig ist??

Unter Windows ist default ScrollWidth 0, da die API das so zurück gibt. Linux Mint mit GTK2 verhält sich hier so, wie von dir beschrieben.

Kannst du folgenden Code ersetzen und die IDE neu bauen und sagen, ob das dann gut für dich ist?!:

Code: Alles auswählen

function TCustomListBox.GetScrollWidth: Integer;
begin
  Result := FScrollWidth;
  if (Result > 0) or (csDesigning in ComponentState) then Exit;
  if HandleAllocated then
    Result := TWSCustomListBoxClass(WidgetSetClass).GetScrollWidth(Self);
end; 

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

wp_xyz
Beiträge: 3746
Registriert: Fr 8. Apr 2011, 09:01

Re: TListbox : horizontaler Scrollbalken

Beitrag von wp_xyz »

Ich glaube, das Problem ist, dass Linux (genauer: gtk2) den Wert 0 nicht akzeptiert und immer im wesentlichen die aktuelle Listboxbreite als ScrollWidth einträgt. Wenn das Programm nun unter Windows übersetzt wird, steht dieser Nicht-0-Wert in der lfm-Datei und es wird evtl ein Scrollbalken angezeigt, insbesondere dann, wenn z.B. durch Anchoring etc. die Listbox schmäler wird.

Das beigefügte Programm wurde unter Linux Mint LMDE 4 erzeugt. Dort wird ScrollWidth <> 0 eingetragen, und bei Größenveränderung der Listbox immer so angepasst, dass nie ein horizontaler Scrollbar zu sehen ist. Unter Windows dagegen sehe ich (zumindest bei den aktuellen Größen) einen Scrollbalken, weil eben dieser Nicht-Null-Wert in der LFD-Datei steht (oder man kann den Scrollbalken mit einer geringen Breitenveränderung anzeigen).

Das Ganze ist übrigens eine Eigenheit von gtk2. Unter qt5 und gtk3 kann man sehr wohl eine Null bei ScrollWidth eintragen - allerdings wird hier ein Wert <> 0 zur Laufzeit wieder auf Null zurückgesetzt... Unter Linux wird es nie langweilig...
Dateianhänge
listbox_scrollwidth_gtk2.zip
(1.91 KiB) 5-mal heruntergeladen

moasda
Beiträge: 3
Registriert: Sa 29. Mai 2021, 16:35

Re: TListbox : horizontaler Scrollbalken

Beitrag von moasda »

Michl hat geschrieben:
So 30. Mai 2021, 16:56
Kannst du folgenden Code ersetzen und die IDE neu bauen und sagen, ob das dann gut für dich ist?!:

Code: Alles auswählen

function TCustomListBox.GetScrollWidth: Integer;
begin
  Result := FScrollWidth;
  if (Result > 0) or (csDesigning in ComponentState) then Exit;
  if HandleAllocated then
    Result := TWSCustomListBoxClass(WidgetSetClass).GetScrollWidth(Self);
end; 
Danke, Michl, hab's ausprobiert und funktioniert prima! Den Code lasse ich gleich bei mir drin. :D
wp_xyz hat geschrieben:
So 30. Mai 2021, 17:49
Unter qt5 und gtk3 kann man sehr wohl eine Null bei ScrollWidth eintragen - allerdings wird hier ein Wert <> 0 zur Laufzeit wieder auf Null zurückgesetzt.
Bei GTK3 liegt es allerdings daran, dass GetScrollWidth noch nicht wirklich implementiert ist:

Code: Alles auswählen

class function TGtk3WSCustomListBox.GetScrollWidth(const ACustomListBox: TCustomListBox): Integer;
begin
  Result := 0;
end;

Antworten