Mehrfaches MouseWheel Ereignis

Rund um die LCL und andere Komponenten
Antworten
lzuser
Beiträge: 97
Registriert: Sa 20. Jun 2009, 16:00
OS, Lazarus, FPC: Win10 20H2, Laz 2.0.8 auch Linux Mint Mate 20, Laz 2.0.6
CPU-Target: 64Bit

Mehrfaches MouseWheel Ereignis

Beitrag von lzuser »

Win 10, Laz 1.6
Übliches Ziel: MouseWheel über einem Image (in Scrollbox auf Formular) soll das Image und die beinhaltete Grafik vergrößern.
Wenn ich das Rad nur ein Raster bewege - egal in welcher Geschw., wird das Wheel-Ereignis aber 3 mal ausgelöst, so dass meine Proportionalrechnung nicht mehr stimmt.
In einem vorhandenen Grafik-Programm funktioniert es: bei jedem Raster-Dreh genau eine Stufe.

Was läuft da falsch? Was habe ich evtl. nicht verstanden?
Danke

Nixsager
Beiträge: 168
Registriert: Sa 8. Okt 2016, 08:38
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Wohnort: Polska

Re: Mehrfaches MouseWheel Ereignis

Beitrag von Nixsager »

Hi

Ich habe Win 7 und Lazarus 1.6, und habe es mit folgendem Code getestet. Die Variabel 'TI' ist eine globale Uint32-Variabel.
Und der Wert ändert sich bei mir um 1 je Mausrad-Klick.
Ich würde mal vermuten es liegt erstens an deiner Mauseinstellung, oder an dem Zusammenspiel mit Lazarus und Win 10.

Code: Alles auswählen

 
procedure TForm1.Image1MouseWheelUp(Sender: TObject; Shift: TShiftState;
  MousePos: TPoint; var Handled: Boolean);
begin
  Dec(TI);
  Form1.ScrollBar1.Position:=TI;
  Form1.Canvas.TextOut(0,0,'                                                            ');
  Form1.Canvas.TextOut(0,0,'Image-MouseWheel-Wert: ' + IntToStr(TI));
  Form1.Canvas.TextOut(0,15,'                                                            ');
  Form1.Canvas.TextOut(0,15,'ScrollBar-Postion-Wert: ' + IntToStr(ScrollBar1.Position));
end;
 
procedure TForm1.Image1MouseWheelDown(Sender: TObject; Shift: TShiftState;
  MousePos: TPoint; var Handled: Boolean);
begin
  Inc(TI);
  Form1.ScrollBar1.Position:=TI;
  Form1.Canvas.TextOut(0,0,'                                                            ');
  Form1.Canvas.TextOut(0,0,'Image-MouseWheel-Wert: ' + IntToStr(TI));
  Form1.Canvas.TextOut(0,15,'                                                            ');
  Form1.Canvas.TextOut(0,15,'ScrollBar-Postion-Wert: ' + IntToStr(ScrollBar1.Position));
end;
 


Gruß vom Nixsager
Jeder der sagt, ich könnte programmieren, der hat noch weniger Ahnung vom programmieren als ich!!!

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Mehrfaches MouseWheel Ereignis

Beitrag von Socke »

lzuser hat geschrieben:Wenn ich das Rad nur ein Raster bewege - egal in welcher Geschw., wird das Wheel-Ereignis aber 3 mal ausgelöst, so dass meine Proportionalrechnung nicht mehr stimmt.
In einem vorhandenen Grafik-Programm funktioniert es: bei jedem Raster-Dreh genau eine Stufe.

Was läuft da falsch? Was habe ich evtl. nicht verstanden?

In den Windows-Einstellungen zum Mausrad kann eingestellt werden, wie viele Zeilen mit einem Rasterschritt gescrollt werden sollen; der Standardwerte beträgt 3 Zeilen. Diese kannst du über Mouse.WheelScrollLines (Unit Controls) abfragen.

P.S. In dem Event OnMouseWheel gibt es den Parameter WheelDelta, über den auch die Drehrichtung erfasst werden kann. Bei mir war dieser jedoch (unabhängig von den Windows Einstellungen) immer +/-960.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

martin_frb
Beiträge: 572
Registriert: Mi 25. Mär 2009, 21:12
OS, Lazarus, FPC: Laz trunk / fpc latest release / Win and other
CPU-Target: mostly 32 bit

Re: Mehrfaches MouseWheel Ereignis

Beitrag von martin_frb »

960 erscheint mir sehr hoch....

IIRC ist der default 60 (aber kann mich irren). 60 = 1 click.

Wenn eine Mouse z.b halbe clicks reported, dann waere der Wert 30. Die App muss den Wert ueber mehrere Events addieren, und jesdesmal wenn 60 voll sind, ist das 1 click (120 = 2 click)

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Mehrfaches MouseWheel Ereignis

Beitrag von Socke »

martin_frb hat geschrieben:960 erscheint mir sehr hoch....

Zumindest war 960 der Wert, den mir der Debugger in OnMouseWheel gezeigt hat.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

lzuser
Beiträge: 97
Registriert: Sa 20. Jun 2009, 16:00
OS, Lazarus, FPC: Win10 20H2, Laz 2.0.8 auch Linux Mint Mate 20, Laz 2.0.6
CPU-Target: 64Bit

Re: Mehrfaches MouseWheel Ereignis

Beitrag von lzuser »

Win10, Laz 1.6
So, zur Information: Ich habe mein System daraufhin getestet.
Einstellung der Maus auf _1_ Zeile blättern und sogar Neustart des Rechners
keine Änderung im Programm: Bei _1_ Rasterbewegung wird das Ereignis MouseWheelUp oder -Down immer noch _3_ mal ausgelöst.
Ebenso übrigens das Ereignis MouseWheel auch 3 mal. Dabei werden mir als WheelDelta 120, 960, 120 oder die entsprechenden negativen Werte angezeigt.
Mein Browserfenster - z.B. hier das LazForum - scrollt jetzt aber wie eingestellt entsprechend langsamer beim Mausrad-Drehen.
Die Einstellung muss ich also wieder auf 3 ändern.
Nun bin ich ratlos.
Noch irgendeine Idee, was hier nicht richtig läuft?

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Mehrfaches MouseWheel Ereignis

Beitrag von Socke »

Mein erster Test bezog sich auf Windows 7 64 bit; die Lazarus-Version kann ich gerne nachreichen.

Ein Test unter Windows 10 64 bit mit 32-Bit LCL-Anwendung (FPC 3.1.1, Lazarus SVN 52913) ergibt: nur ein OnMouseWheel bei jedem Scrollen; die Variable WheelDelta ist konstant 30.

P.S: hast du mal mit unterschiedlichen Mäusen getestet?
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Frank Ranis
Beiträge: 201
Registriert: Do 24. Jan 2013, 21:22

Re: Mehrfaches MouseWheel Ereignis

Beitrag von Frank Ranis »

Hallo ,

Bei Lazarus unter WIN-XP und WIN-7 ist mir ein Mehrfachaufruf noch nicht untergekommen , WIN-10 habe ich jetzt nicht.

Aber unter Delphi hatte ich das Problem auch , bei mir waren es nicht 3 Aufrufe , sondern nur 2 .

Habe da lange drann rumprobiert und bin dann drauf gekommen , das man die Variable 'handled' in den Ereignisroutinen auf true setzten sollte.

Schmeiß dir mal ein Edit und zwei Checkboxen auf den Schirm und probier mal folgendes.
Mal mit eingeschalteten Checkboxen , mal ohne probieren.

Danach war bei Delphi ruhe und es gab nur einen Aufruf für ein Mausrad-Raster.
Vieleicht hilft das bei LAZ ja auch.

Code: Alles auswählen

unit Unit1;
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, Types;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    CheckBox1: TCheckBox;
    CheckBox2: TCheckBox;
    Edit1: TEdit;
    procedure FormMouseWheelDown(Sender: TObject; Shift: TShiftState;
      MousePos: TPoint; var Handled: Boolean);
    procedure FormMouseWheelUp(Sender: TObject; Shift: TShiftState;
      MousePos: TPoint; var Handled: Boolean);
  private
    { private declarations }
  public
    { public declarations }
  end;
 
var
  Form1: TForm1;
  i:integer;
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure TForm1.FormMouseWheelDown(Sender: TObject; Shift: TShiftState;
  MousePos: TPoint; var Handled: Boolean);
begin
 Handled:=checkbox2.Checked; // <---- Handled für Runterdrehen
 dec(i);
 edit1.text:=inttostr(i);
end;
 
procedure TForm1.FormMouseWheelUp(Sender: TObject; Shift: TShiftState;
  MousePos: TPoint; var Handled: Boolean);
begin
 Handled:=checkbox1.Checked; // <---- Handled für Hochdrehen
 inc(i);
 edit1.text:=inttostr(i);
end;
 
end.       
 

In der Delphi-Hilfe war folgendes zu finden .

Code: Alles auswählen

Der Typ TMouseWheelUpDownEvent wird in den Ereignissen OnMouseWheelUp und OnMouseWheelDown verwendet.
 
Unit
 
Controls
 
type TMouseWheelUpDownEvent = procedure(Sender: TObject; Shift: TShiftState; MousePos: TPoint; var Handled: Boolean) of object;
 
Beschreibung
 
Sender ist das Objekt, das die Mausereignisse abfängt.
 
Shift ist der Status der Alt-, Strg-, Umschalt- und Maustaste.
 
MousePos ist die Position des Mauszeigers.
 
Handled gibt an, ob das Steuerelement das Ereignis bearbeitet hat. Wenn Sie Handled den Wert False zuweisen, wird das Ereignis vom übergeordneten Objekt des Steuerelements behandelt.
 

Der letzte Satz scheint das Geheimnis :
Die Application als übergeordneten Objekt der Form bekommt 2,3 oder wer weis wie viele Mausradbotschaten pro Mausrad-Raster geliefert und ruft jedes mal die MouseWheelUpDown-Routine auf.
Setzt man nun handled:=True , wir der Application mitgeteilt , das man den Mausrad-Dreher verstanden hat und verhindert dann einen weiteren Aufruf für diesen einen Mausrad-Raster.

Die olle Delphi6-Hilfe ist echt super , so was wünsch ich mir für LAZ auch.
Kann man die Delphi-Hilfe irgend wie ans LAZ koppeln ?


Gruß

Frank
www.flz-vortex.de

lzuser
Beiträge: 97
Registriert: Sa 20. Jun 2009, 16:00
OS, Lazarus, FPC: Win10 20H2, Laz 2.0.8 auch Linux Mint Mate 20, Laz 2.0.6
CPU-Target: 64Bit

Re: Mehrfaches MouseWheel Ereignis

Beitrag von lzuser »

Danke für deine ausführliche Erklärung. Das war schon mal sehr hilfreich.
Handled:=true bewirkt, dass das Ereignis nur 1 mal ausgelöst wird.
aber:
Meine Konstruktion ist Image in Scrollbox auf Formular. Alle haben das MouseWheel. So dachte ich nach deinen Ausführungen es kämen so die 3 Auslöser zustande. Wenn ich aber das Image direkt auf das Formular platziere, wird auch ohne Handled:=true das Ereignis nur einmal ausgelöst (Delta=120).
(Bei sehr schneller Drehung mit mehreren Rastern auch Delta=240,360,...)
Folgerung: Die Scrollbox ist für die zusätzlichen 2 Auslöser verantwortlich (Delta=960 und nochmals 120 oder umgekehrt).
Interessieren täte mich schon, warum das so ist.

Auch aus der Delphi6-Hilfe: "WheelDelta zeigt an, wie oft das Rad gedreht wurde."
Was soll mir denn mein Zahlenwert 120 für ein Raster Drehung sagen?

Das Problem ist jedoch gelöst. Danke.

Antworten