AGB  ·  Datenschutz  ·  Impressum  







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

Einstellung Scrollen Zeilen

Ein Thema von Ykcim · begonnen am 21. Mai 2014 · letzter Beitrag vom 26. Mär 2019
Antwort Antwort
Ykcim

Registriert seit: 29. Dez 2006
Ort: NRW
804 Beiträge
 
Delphi 10.4 Sydney
 
#1

Einstellung Scrollen Zeilen

  Alt 21. Mai 2014, 11:52
Hallo Zusammen,

ich habe ein StringGrid, in dem mit der Maus gescrollt werden kann. Jetzt springt die Markierung aber immer gleich 3 Zeilen weiter. Wo kann ich einstellen, dass sie nur eine Zeile weitersprongen soll. Dass müsste doch eigentlich im OI einstellbarsein, oder?

Vielen Dank
Patrick
Patrick
  Mit Zitat antworten Zitat
Perlsau
(Gast)

n/a Beiträge
 
#2

AW: Einstellung Scrollen Zeilen

  Alt 22. Mai 2014, 00:35
Dazu deklarierst du dir erstmal einen Message-Handler als private Procedure:
Delphi-Quellcode:
PRIVATE { Private-Deklarationen }
  Procedure HandleOnMessage(var Msg: TMsg; var Handled: Boolean);
Danach erstellst du mit der Tastenkombination Shift-Strg-C den entsprechenden Procedure-Rumpf:
Delphi-Quellcode:
procedure TFormMain.HandleOnMessage(var Msg: TMsg; var Handled: Boolean);
begin

end;
Dort schreibst du nun hinein, wie mit der Message WM_MOUSEWHEEL umgegangen werden soll:
Delphi-Quellcode:
// ---------- Wandelt Mouse-Wheel-Bewegungen in Cursur-Runter bzw. Cursor-Hoch-Messages um (nur TjvDBGrid) ------------------------------
Procedure TFormMain.HandleOnMessage(var Msg: TMsg; var Handled: Boolean);
begin
  case Msg.message OF
   WM_MOUSEWHEEL:
   begin
      if (Screen.ActiveForm.ActiveControl <> nil)
      and
      (Screen.ActiveForm.ActiveControl.ClassName = 'TJvDBGrid') // TJvDBGrid ersetzen durch die gewünschte Komponente, z.B. TStringGrid
      then
      begin // die Mousewheel Message wird in einen Tastendruck umgewandelt
         Msg.message := WM_KEYDOWN;
         Msg.lParam := 0;
         if Msg.wParam > 0 then
            Msg.wParam := VK_UP else
            Msg.wParam := VK_DOWN;
         Handled := False;
      end;
   end; // WM_MOUSEWHEEL
  end; // case
end;
Nun mußt du nur noch die Messagebehandlung auf deine Procedure "umbiegen":
Delphi-Quellcode:
Procedure TFormMain.FormCreate(Sender: TObject);
begin
  Application.OnMessage := Self.HandleOnMessage; // Scrollrad to Cursor up + down
end;
Ab jetzt wird im gesamten Programm beim Scrollen in einem StringGrid immer nur eine Position weitergeschaltet, gerade so, als ob du mit den Hoch-Runter-Cursortasten navigieren würdest. All die Messages, die von deiner Procedure nicht erledigt werden, bleiben natürlich erhalten und geistern weiter durch die Weiten deines Windows, bis sie ihrem Schicksal begegnen (irgend einem anderen Message-Handler).

Geändert von Perlsau (22. Mai 2014 um 00:39 Uhr)
  Mit Zitat antworten Zitat
Ykcim

Registriert seit: 29. Dez 2006
Ort: NRW
804 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: Einstellung Scrollen Zeilen

  Alt 22. Mai 2014, 08:58
Hallo Zusammen,

ich war davon ausgegangen, dass man das in jedem StringGrid einstellen kann. Ich nutze das TMSGrid und dabei geht es mit:

StringGrid1.MouseActions.WheelIncrement:=1;

Vielen Dank
Patrick
Patrick
  Mit Zitat antworten Zitat
Perlsau
(Gast)

n/a Beiträge
 
#4

AW: Einstellung Scrollen Zeilen

  Alt 22. Mai 2014, 09:09
Daß du nicht, wie im Eingangsposting geschrieben, ein normales TStringGrid verwendest, konnte ich natürlich nicht erahnen. Ich gehe stets davon aus, daß man das, was man schreibt, auch meint. Da dein (kommerzielles) Grid ja bereits über eine entsprechende Möglichkeit verfügt, hättest du dir die Frage und ich mir die Zeit für die Antwort sparen können.

ich war davon ausgegangen, dass man das in jedem StringGrid einstellen kann. Ich nutze das TMSGrid und dabei geht es mit: StringGrid1.MouseActions.WheelIncrement:=1;
Weil Komfort zu implementieren Arbeit ist, sind komfortablere Komponenten meist nicht umsonst zu haben.
  Mit Zitat antworten Zitat
Benmik

Registriert seit: 11. Apr 2009
542 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Einstellung Scrollen Zeilen

  Alt 25. Mär 2019, 16:28
Und erst knapp fünf Jahre später ...

Ich möchte mittels der Maus immer das nächste / vorige Bild in ein TImage laden und habe mich auch daran gestört, dass die Scrollgeschwindigkeit zu hoch war.
Der folgende (modifizierte) Code von Perlsau tut, was ich will:
Delphi-Quellcode:
procedure TFrmSB.HandleOnMessage(var Msg: TMsg; var Handled: Boolean);
begin
  If (Msg.message = WM_MOUSEWHEEL) and (Screen.ActiveForm.ActiveControl <> nil)
  and (Screen.ActiveForm.ActiveControl.ClassName = 'TImage') then
  begin
    If Msg.wParam > 0 then
      SetzeNächstesBild(bwVor) else
      SetzeNächstesBild(bwZurück);
    If GetKeyState(VK_CONTROL) >= 0 then
      Sleep(50);
    Handled := True;
  end;
end;
Nun folgende zwei Fragen:

Um die Scrollrate herabzusetzen, habe ich ein Sleep eingebaut, das man mit STRG übergehen kann.
Ich weiß aber, dass man für die Verwendung von Sleep in die Delphi-Hölle kommt, obwohl es hier genau das tut, was ich möchte. Wie würde ein Himmelsaspirant das machen, oder habe ich die weltweit erste legale Verwendung von Sleep gefunden?

Wichtiger noch: Soweit ich das verstehe, werde jetzt alle Zehntausende Nachrichten über diese Prozedur umgeleitet und einer Prüfung unterzogen. Macht sich das in der Praxis bemerkbar? Mein Program ist nicht übermäßig zeitkritisch, aber dennoch.
  Mit Zitat antworten Zitat
peterbelow
Online

Registriert seit: 12. Jan 2019
Ort: Hessen
672 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Einstellung Scrollen Zeilen

  Alt 26. Mär 2019, 09:22
Und erst knapp fünf Jahre später ...

Ich möchte mittels der Maus immer das nächste / vorige Bild in ein TImage laden und habe mich auch daran gestört, dass die Scrollgeschwindigkeit zu hoch war.
Der folgende (modifizierte) Code von Perlsau tut, was ich will:
Delphi-Quellcode:
procedure TFrmSB.HandleOnMessage(var Msg: TMsg; var Handled: Boolean);
begin
  If (Msg.message = WM_MOUSEWHEEL) and (Screen.ActiveForm.ActiveControl <> nil)
  and (Screen.ActiveForm.ActiveControl.ClassName = 'TImage') then
  begin
    If Msg.wParam > 0 then
      SetzeNächstesBild(bwVor) else
      SetzeNächstesBild(bwZurück);
    If GetKeyState(VK_CONTROL) >= 0 then
      Sleep(50);
    Handled := True;
  end;
end;
Nun folgende zwei Fragen:

Um die Scrollrate herabzusetzen, habe ich ein Sleep eingebaut, das man mit STRG übergehen kann.
Ich weiß aber, dass man für die Verwendung von Sleep in die Delphi-Hölle kommt, obwohl es hier genau das tut, was ich möchte. Wie würde ein Himmelsaspirant das machen, oder habe ich die weltweit erste legale Verwendung von Sleep gefunden?

Wichtiger noch: Soweit ich das verstehe, werde jetzt alle Zehntausende Nachrichten über diese Prozedur umgeleitet und einer Prüfung unterzogen. Macht sich das in der Praxis bemerkbar? Mein Program ist nicht übermäßig zeitkritisch, aber dennoch.
Was Du da machst ist ein bißchen overkill, Du kannst einfach dem Form selbst einen Handler für WM_MOUSEWHEEL verpassen. Das Sleep sollte unnötig sein und macht auch nicht unbedingt das, was Du willst. Wenn der Benutzer einfach zu schnell am Rad dreht akkumulieren die Messages schneller in der message queue als sie verarbeitet werden können, was dann zu "Nachlauf" führt. Um das zu vermeiden mußt Du nicht die Verarbeitungszeit künstlich verlängern sondern die überschüssigen messages aus der Queue entfernen, z. B. mit dem hier:

Delphi-Quellcode:
{!
<summary>
Remove all mouse messages from the calling thread's message queue.</summary>
}

procedure EmptyMouseQueue;
var
  Msg: TMsg;
begin
  while PeekMessage(Msg, 0, WM_MOUSEFIRST, WM_MOUSELAST,
    PM_REMOVE or PM_NOYIELD) do
    ;
end;
Peter Below
  Mit Zitat antworten Zitat
Benmik

Registriert seit: 11. Apr 2009
542 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Einstellung Scrollen Zeilen

  Alt 26. Mär 2019, 18:02
Vielen Dank, Peter. Diesen Trick kannte ich schon, hatte ihn aber völlig vergessen. Merke ich mir hoffentlich für das nächste Mal.

Eine Verzögerung brauche ich dennoch, weil ich nicht nur den "Nachlauf" verhindern möchte, sondern anstrebe, dass pro Mausradbetätigung nur einmal das Bild gewechselt wird, so dass man nicht dauernd aufpassen muss, nicht zuviel zu drehen.

Ich habe jetzt von den Nachrichten ganz Abschied genommen und das Ganze in OnMouseWheel verlagert (BeimRollen ist eine globale Variable, auch verpönt, ich weiß):
Delphi-Quellcode:
procedure TFrmSB.AnzeigeMouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
var Richtung:integer; GTC:Cardinal;
begin
  Richtung := IfThen(WheelDelta = 0,-1,1);
  If BeimRollen then
  begin
    Handled := True;
    exit;
  end;
  BeimRollen := True;
  GTC := GetTickCount;
  Try
    If Richtung = 1 then
      SetzeNächstesBild(bwVor) else
      SetzeNächstesBild(bwZurück);
    While (GetKeyState(VK_CONTROL) >= 0) and (GetTickCount < (GTC + 250)) do
      Application.ProcessMessages;
  Finally
    BeimRollen := False;
  end;
end;
Das macht genau, was ich will.
  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 13:02 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