AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

OnMouseWheelUp/Down nur einmal

Ein Thema von pustekuchen · begonnen am 19. Apr 2012 · letzter Beitrag vom 24. Apr 2012
Antwort Antwort
Benutzerbild von pustekuchen
pustekuchen

Registriert seit: 27. Aug 2010
265 Beiträge
 
Delphi 11 Alexandria
 
#1

OnMouseWheelUp/Down nur einmal

  Alt 19. Apr 2012, 09:33
Guten Tag,

ich habe eine Form mit dem MouseWheelUp/Down-Event. Nun ist es so, das wenn man mit der Maus mehrmals scrollt (Nicht die Windows Rad Option Vertikaler Bildlauf!) das, die Event Prozedur ausgeführt wird und dann nochmal das Event ausgelöst wird, da man ja auch mehrmals gescrollt hat.

Ich möchte es aber so haben, das während er in der OnMouseWheelUp/Down Prozedur ist, keine weiteren OnMouseWheelUp/Down Events auslöst.

Ich habe mir gedacht einfach das OnMouseWheelUp/Down der Form auf nil zu setzen und am ende wieder zuweisen. Jedoch klappt es nicht und es werden trotzdem nacheinander die Events ausgelöst.

FormMouseWheelDown:
Delphi-Quellcode:
  Handled := false;
  FPaintCtrlParent.OnMouseWheelDown := nil;
  FPaintCtrlParent.OnMouseWheelUp := nil;
  // Hier etwas tun was etwas länger dauert.
  FPaintCtrlParent.OnMouseWheelDown := FormMouseWheelDown;
  FPaintCtrlParent.OnMouseWheelUp := FormMouseWheelUp;
  Handled := true;
Hat jemand eventuell eine Lösung des Problems und kennt die Ursache?
Delphi programming is awesome.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#2

AW: OnMouseWheelUp/Down nur einmal

  Alt 19. Apr 2012, 09:44
Was ist etwas länger?
Was ist "Hier etwas tun was etwas länger dauert."? Und wird da irgendwie eine MessageBox oder Application.ProcessMessages aufgerufen?

An soein Ereignis sollte man nie etwas direkt dranhängen, was "länger" dauern könnte.
Stell dir mal vor alle Programme würden nach jeder Maus- oder Tastaturaktion ein paar Sekunden (oder gar länger) Pause machen.
Würde die Arbeit dann noch Spaß machen?

Das Event wird nur aufgerufen, wenn die ein Ereignis ansteht (Maus gescrollte) und die MessageQueue abgearbeitet wird.
oder wenn jemand die Ereignis-Methode direkt oder indirekt über SendMessage aufruft. (Letzteres geht nicht unbedingt über die MessageQueue)

PS: Wenn mehrere Ereignisse anstehn, wärend das Event abgearbeitet wird (wo du das Event abhängst) und dabei aber die MessagQueue nicht verarbeitet wird, dann bleibt das Event erhalten und wird erst ausgeführt, nachdem du die Events wieder angehängt hast.



Lager den Code aus (wenn möglich Thread) und sorge im Mausereignis nur dafür, daß die Verarbeitung gestartet wird, falls sie noch nicht läuft.


PPS: Du hast einen Debugger, da hattest/könntest du dir ansehn, wann und wie der zweite aufruf ausgelöst wird. (alternativ ein Logging einbauen)
$2B or not $2B

Geändert von himitsu (19. Apr 2012 um 09:47 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von s.h.a.r.k
s.h.a.r.k

Registriert seit: 26. Mai 2004
3.159 Beiträge
 
#3

AW: OnMouseWheelUp/Down nur einmal

  Alt 19. Apr 2012, 09:46
Du wirst viel eher Erfolg haben, wenn du einen Timer bemühst und die Funktion für x Millisekunden sperrst.

Wenn ein Nutzer am Scrollrad dreht, so wird eine Windows-Botschaft an deine Anwendung geschickt und an die entsprechende Komponente delegiert. Dein Code handelt nur eine dieser Botschaften ab. Alle weiteren sind in einer Queue und werden danach abgearbeitet. Daher hast du nur Erfolg, wenn du direkt in die Nachrichtenschleife eingreifst, oder wenn du über einen Timer agierst. Aber bitte alles mit Vorsicht genießen!
»Remember, the future maintainer is the person you should be writing code for, not the compiler.« (Nick Hodges)
  Mit Zitat antworten Zitat
Benutzerbild von pustekuchen
pustekuchen

Registriert seit: 27. Aug 2010
265 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: OnMouseWheelUp/Down nur einmal

  Alt 19. Apr 2012, 09:53
Hallo zusammen,

danke für eure Antworten. Das mit dem Timer ist mir auch in den Sinn gekommen, fand ich aber auch nicht so toll.

Zitat:
Was ist etwas länger?
100 - 2000 Ticks

Leider ist es in meinem Fall unerlässlich. Das es nicht schön ist, das es für den User zu wartezeiten kommt ist mir schon klar Und grade deswegen möchte ich auch das das Event nur einmal ausgeführt wird und nicht bei übermütigem scrollen dann zu längeren Wartezeiten kommt.

Falls niemand eine schönere Lösung einfällt, werde ich es wohl über nen Timer machen müssen.
Delphi programming is awesome.
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#5

AW: OnMouseWheelUp/Down nur einmal

  Alt 19. Apr 2012, 14:57
Ich würde FormMouseWheel mit einem Semaphore verwenden ....
Delphi-Quellcode:
procedure TForm2.FormMouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
begin
  Handled := true;
  if not FisInWheel then
    try
      FisInWheel := true;
      if ssCtrl in Shift then
      begin
        Zoom := Zoom + (0.1 * Sign(WheelDelta));
        if Zoom = 0 then
          Zoom := 0.1;
      end
      else

        if ssShift in Shift then
        Rot := Rot + (5 * Sign(WheelDelta));
      
      UpdateDisp;
    finally
      FisInWheel := false;
    end;
end;
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: OnMouseWheelUp/Down nur einmal

  Alt 24. Apr 2012, 12:33
Ich habe ein ähnliches Problem (wenn ich den Thread richtig verstehe) so gelöst:

Ein Designer enthält Controls, die recht aufwendig aufgebaut und gezeichnet werden.
Bei einer Zoomänderung werden alle Controls in der Größe und Position aktualisiert, ohne allerdings den Inhalt anzupassen. Gleichzeitig werden die Controls in eine Liste aufgenommen und ein Timer gestartet.
Der Timer veranlasst dann alle Controls nach und nach, ihren Inhalt anzupassen und entfernt sie dann aus der Liste.
Ist die Liste leer, wird der Timer deaktiviert.

So werden alle Controls sehr schnell korrekt positioniert und deren Größe angepasst. Der Inhalt wird neu angeordnet, wenn dann Zeit dafür ist.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:12 Uhr.
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