Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Mit Mausrad in TScrollBox scrollen (https://www.delphipraxis.net/170462-mit-mausrad-tscrollbox-scrollen.html)

Tim-94 18. Sep 2012 16:08

Mit Mausrad in TScrollBox scrollen
 
Hallo alle zusammen :)
Ich habe eine Frage zu folgendem Code:

Delphi-Quellcode:
{-------------------------------------------------------------------} 
procedure TMainForm.FormMouseWheelUp(Sender: TObject; Shift: TShiftState;
  MousePos: TPoint; var Handled: Boolean);
begin
  if PtInRect(PScrollBox.ClientRect, ScreenToClient(MousePos)) then
    PScrollBox.OnMouseWheelUp(Sender, Shift, MousePos, Handled);

  {if PtInRect(AScrollBox.ClientRect, ScreenToClient(MousePos)) then
    AScrollBox.OnMouseWheelUp(Sender, Shift, MousePos, Handled);}
end;
{-------------------------------------------------------------------}
procedure TMainForm.FormMouseWheelDown(Sender: TObject; Shift: TShiftState;
  MousePos: TPoint; var Handled: Boolean);
begin
  if PtInRect(PScrollBox.ClientRect, ScreenToClient(MousePos)) then
    PScrollBox.OnMouseWheelDown(Sender, Shift, MousePos, Handled);

  {if PtInRect(AScrollBox.ClientRect, ScreenToClient(MousePos)) then
    AScrollBox.OnMouseWheelDown(Sender, Shift, MousePos, Handled);}
end;
{-------------------------------------------------------------------}
{-------------------------------------------------------------------}
procedure TMainForm.AScrollBoxMouseWheelDown(Sender: TObject;
  Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
var
  vsb: TControlScrollbar;
begin
  with AScrollBox do begin
    vsb := VertScrollbar;
    vsb.Position := vsb.Position + vsb.Increment;
  end;
  Handled := true;
end;
{-------------------------------------------------------------------}
procedure TMainForm.AScrollBoxMouseWheelUp(Sender: TObject;
  Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
var
  vsb: TControlScrollbar;
begin
  with AScrollBox do begin
    vsb := VertScrollbar;
    vsb.Position := vsb.Position - vsb.Increment;
  end;
  Handled := true;
end;
{-------------------------------------------------------------------}
{-------------------------------------------------------------------}
procedure TMainForm.PScrollBoxMouseWheelDown(Sender: TObject;
  Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
var
  vsb: TControlScrollbar;
begin
  with PScrollBox do begin
    vsb := VertScrollbar;
    vsb.Position := vsb.Position + vsb.Increment;
  end;
  Handled := true;
end;
{-------------------------------------------------------------------}
procedure TMainForm.PScrollBoxMouseWheelUp(Sender: TObject;
  Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
var
  vsb: TControlScrollbar;
begin
  with PScrollBox do begin
    vsb := VertScrollbar;
    vsb.Position := vsb.Position - vsb.Increment;
  end;
  Handled := true;
end;
{-------------------------------------------------------------------}

So funktioniert der Code ohne Probleme für das Scrollen in der PScrollBox.

Wenn ich nun jedoch beim "FormMouseWheelUp"- & "FormMouseWheelDown"-Ereignis jeweils den Code für die AScrollBox aus dem Kommentar nehme, scrollt immer nur noch die PScrollBox.
Wie ist das möglich?

Schonmal vielen Dank für eure Hilfe! :)

Uwe Raabe 18. Sep 2012 16:43

AW: Mit Mausrad in TScrollBox scrollen
 
Schau doch mal nach, was PScrollBox.ClientRect und AScrollBox.ClientRect jeweils zurückgeben - dann sollte es dir klar werden, was da schief geht.

Aber warum so kompliziert?


Delphi-Quellcode:
procedure TForm162.FormMouseWheel(Sender: TObject; Shift: TShiftState;
    WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
var
  vsb: TControlScrollbar;
  ctrl: TControl;
begin
  ctrl := ControlAtPos(ScreenToClient(MousePos), false, true, true);
  while (ctrl <> nil) and not (ctrl is TScrollBox) do begin
    ctrl := ctrl.Parent;
  end;
  if ctrl is TScrollBox then begin
    vsb := TScrollBox(ctrl).VertScrollBar;
    vsb.Position := vsb.Position - Sign(WheelDelta)*vsb.Increment;
    Handled := true;
  end;
end;

Tim-94 19. Sep 2012 20:57

AW: Mit Mausrad in TScrollBox scrollen
 
Danke für die Antwort.
Aber irgendwie funktioniert das mit deinem Code bei mir auch nicht.
Weiß leider auch nicht, woran das liegt.
Und wo kann ich nachgucken, was PScrollBox.ClientRect und AScrollBox.ClientRect jeweils zurückgeben?
Soll ich mir das als Text oder Zahl ausgeben lassen?
Oder wie ist das gemeint?

Danke schonmal!

Bummi 19. Sep 2012 21:14

AW: Mit Mausrad in TScrollBox scrollen
 
Der Code von Uwe ist schlank und sauber, was funktioniert nicht bei Dir und was haben die Rects damit zu tun?
Hast Du die Methode im Objektinspektor im OnMouseWheel zugewiesen?

Tim-94 20. Sep 2012 19:35

AW: Mit Mausrad in TScrollBox scrollen
 
Vielen Dank für eure Bemühungen! :)
Mittlerweile funktioniert alles, es hatte sich ein kleiner Fehler beim Übernehmen von Uwes Quelltext eingeschlichen.

CCRDude 21. Sep 2012 09:24

AW: Mit Mausrad in TScrollBox scrollen
 
Da ich mich auch gerade erst damit beschäftigt habe erstmal auch ein danke von mir für die Version von Uwe :)

Was dabei aber erwähnt werden sollte: dieser Code scrollt das Control unter der Maus. Ist auch in der Originalanfrage so, verdient aber imho der speziellen Erwähnung, weil es zu so Effekten führt dass etwa auf einmal nichts mehr scrollt, wenn die Maus über einem TButton innerhalb der Scrollbox ist.

Eine "natürlichere" Scrollvariante könnte es sein, das aktive Control zu nehmen, und, falls die nicht scrollbar ist, in der Hierarchie solange nach oben zu gehen, bis sich eines findet. Da frage ich mich gerade, ob so etwas wie "scrollbar" abfragbar ist (ist es bestimmt).

Uwe Raabe 21. Sep 2012 10:58

AW: Mit Mausrad in TScrollBox scrollen
 
Zitat:

Zitat von CCRDude (Beitrag 1183823)
Was dabei aber erwähnt werden sollte: dieser Code scrollt das Control unter der Maus. Ist auch in der Originalanfrage so, verdient aber imho der speziellen Erwähnung, weil es zu so Effekten führt dass etwa auf einmal nichts mehr scrollt, wenn die Maus über einem TButton innerhalb der Scrollbox ist.

Das sollte aber eigentlich nicht so sein. Die while-Schleife sollte eigentlich die erste übergeordnete ScrollBox finden zu der das Control unter der Maus gehört. Ist das bei dir nicht der Fall?

CCRDude 21. Sep 2012 11:16

AW: Mit Mausrad in TScrollBox scrollen
 
Ich war darauf gekommen, weil es bei eben nicht scrollt, wenn die Maus gerade auf einem TButton ist. Hab mich zugegeben noch etwas mißverständlich ausgedrückt bzw. aufgrund des möglichen Bugs etwas falsch interpretiert.

Grober Überblick (man verzeihe meine Verwendung von Klassen- statt Instanzennamen):
  • TForm -> TPanel(1) -> TScrollbox -> TPanel(2) -> TPanel(3) -> TButton,TEdit
  • Form.ActiveControl = Scrollbox

Ist die Maus nun über dem TButton, liefert ControlAtPos in DoMouseWheel (das habe ich in meiner Formoberklasse mit Deinem Code überschrieben) TPanel(1) zurück.

Ist die Maus über TPanel(3) oder über dem TEdit, dann ergibt ControlAtPos auch TPanel(3) und alles klappt.

Wechsel der Mausposition dabei ohne jegliches Klicken oder Focus-Verändern.

Bevor Du aber Zeit darauf verwendest - ich werde nochmal einen kleineren Testfall bauen; TPanel(2) wird bei mir zur Laufzeit dazwischengeschoben, nicht dass das noch Schuld ist.

bogdan 18. Sep 2013 09:31

AW: Mit Mausrad in TScrollBox scrollen
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1183452)
Schau doch mal nach, was PScrollBox.ClientRect und AScrollBox.ClientRect jeweils zurückgeben - dann sollte es dir klar werden, was da schief geht.

Aber warum so kompliziert?


Delphi-Quellcode:
procedure TForm162.FormMouseWheel(Sender: TObject; Shift: TShiftState;
    WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
var
  vsb: TControlScrollbar;
  ctrl: TControl;
begin
  ctrl := ControlAtPos(ScreenToClient(MousePos), false, true, true);
  while (ctrl <> nil) and not (ctrl is TScrollBox) do begin
    ctrl := ctrl.Parent;
  end;
  if ctrl is TScrollBox then begin
    vsb := TScrollBox(ctrl).VertScrollBar;
    vsb.Position := vsb.Position - Sign(WheelDelta)*vsb.Increment;
    Handled := true;
  end;
end;


Ich habe eine Form1 + Panel1 als Parent. Dann öffne ich eine Form2 mit Scrollbox auf dem Form1.Panel1.Parent. Ab dann funktioniert der Code nicht mehr. Muss ich da noch über Findcomponent exakt den Control zuweisen?

Sherlock 5. Sep 2014 14:32

AW: Mit Mausrad in TScrollBox scrollen
 
Bei mir klappt der eigentlich verständliche Code von Uwe ebenfalls nicht. Ich denke es liegt daran, daß ich Panels auf Panel ins Groupboxen auf einer Scrollbox habe...also beliebig verschachteltes Zeugs. Beholfen habe ich mir hiermit:
Delphi-Quellcode:
procedure TForm.ScrollBox2MouseWheel(Sender: TObject;
  Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint;
  var Handled: Boolean);
var vsb:TControlScrollbar;
begin
  MousePos := ScreenToClient(MousePos);
  if PtInRect((Sender as TScrollBox), MousePos) then
  begin
    vsb := (Sender as TScrollBox).VertScrollBar;
    vsb.Position := vsb.Position - Sign(WheelDelta) * vsb.Increment;
  end;
end;
Und ja, ich hatte Uwes Code an das FormWheel-Event gehängt ;)

Sherlock


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:19 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz