![]() |
[gelöst] Cursortasten von Buttons fernhalten
Hallo,
ich nutze dynamisch erzeugte Buttons auf einer TScrollBox. Diese können mit der Maus frei verschoben werden (ähnlich Delphi IDE). Nun möchte ich eine Art Raster dadurch erreichen, dass der Benutzer diese Buttons ebenfalls mittels Tastatur verschieben kann und ich dann die Werte auf Vielfache von 8, 16 oder so runde. Mit einem Button allein klappt das prima. Mit 2 oder mehr nicht, weil dann mit den Cursortasten der Focus gewechselt und meine Aktion auf eine anderes Control angewendet wird. Im www stand dazu, dass man den Buttons diese Verhalten abgewöhnen kann, indem man
Delphi-Quellcode:
setzt.
Key:= 0;
Aber ganz so einfach scheint es dann doch nicht zu sein. Denn folgender Code funktioniert eben nur bedingt:
Delphi-Quellcode:
Ich vermute also, dass VK_LEFT & Co. immer noch irgendwo im Tastaturpuffer rumlungern. Wie löse ich das Problem denn richtig?
procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
var aControl : TWinControl; aButton : TButton; begin aControl:= ActiveControl; // aktives Control merken if (aControl is TButton) then begin aButton:= (aControl as TButton); case Key of VK_LEFT : aButton.Left:= aButton.Left - 16; VK_UP : aButton.Top:= aButton.Top - 16; VK_RIGHT : aButton.Left:= aButton.Left + 16; VK_DOWN : aButton.Top:= aButton.Top + 16; end; Key:= 0; // <== Tastaturpuffer gelöscht. SetFocusedControl(aControl); // <== Focus nochmal gesetzt end; end; |
AW: Cursortasten von Buttons fernhalten
Rate jetzt mal:
Ändert sich das Verhalten, wenn Du statt FormKeyUp FormKeyDown nutzt? |
AW: Cursortasten von Buttons fernhalten
Das ist das falsche Event. Dein Code gehört nicht in
Delphi-Quellcode:
sondern nach
TForm.OnKeyUp
Delphi-Quellcode:
(oder von mir aus
TApplicationEvents.OnShortCut
Delphi-Quellcode:
). Da dann einfach noch nach dem Änderung
TApplication.OnShortCut
Delphi-Quellcode:
setzen und dann ist an der Stelle Schluss mit der Verarbeitung der Taste.
Handled := True
Eine kleine Umstellung deiner Methode ist allerdings nötig, um deine Taste aus dem
Delphi-Quellcode:
-Typ zu kriegen:
TWMKey
- Der Parameter
Delphi-Quellcode:
heißt jetzt
Key
Delphi-Quellcode:
. Auch hier gehen die virtuellen Key-Codes, die du verwendest.
Msg.CharCode
- Für den
Delphi-Quellcode:
(wenn du ihn brauchst) gibt es
TShiftState
Delphi-Quellcode:
.
Forms.KeyDataToShiftState(Msg.KeyData)
|
AW: Cursortasten von Buttons fernhalten
Zitat:
Delphi-Quellcode:
Ich habe es so unschön gebaut, weil ich es unübersichtlicher gefunden hätte, 4 Mal nur wegen
procedure TForm1.ApplicationEvents1ShortCut(var Msg: TWMKey;
var Handled: Boolean); begin Handled:= True; if (ActiveControl is TButton) then begin case Msg.CharCode of VK_LEFT : (ActiveControl as TButton).Left:= (ActiveControl as TButton).Left - 16; VK_UP : (ActiveControl as TButton).Top:= (ActiveControl as TButton).Top - 16; VK_RIGHT : (ActiveControl as TButton).Left:= (ActiveControl as TButton).Left + 16; VK_DOWN : (ActiveControl as TButton).Top:= (ActiveControl as TButton).Top + 16; else Handled:= False; end end else Handled:= False; end;
Delphi-Quellcode:
ein
Handled:= True;
Delphi-Quellcode:
einzufügen. Es geht vermutlich auch schöner.
begin ... end;
Und
Delphi-Quellcode:
finde ich sogar noch besser, weil ich keine zusätzliche Komponente mit reinbasteln muss. Und schließlich und letztlich habe ich mal im Code von Vcl.AppEvnts geschnüffelt. Beim weiteren Suchen bin ich dann auf die Möglichkeit gestoßen, das ganze auch komplett über die Messages abzufangen mit z.B.
TApplication.OnShortCut
Delphi-Quellcode:
. Nachteil ist allerdings, dass es kein Handled gibt und man aufpassen muss, die nicht ausgewerteten Tasten mit Inherited schön weiterzugeben.
procedure CMDialogKey(var Message: TCMDialogKey); message CM_DIALOGKEY;
|
AW: [gelöst] Cursortasten von Buttons fernhalten
Noch ein bisserl kürzer:
Delphi-Quellcode:
procedure TForm1.ApplicationEvents1ShortCut(var Msg: TWMKey; var Handled: Boolean); begin if (ActiveControl is TButton) then begin Handled:= True; case Msg.CharCode of VK_LEFT : (ActiveControl as TButton).Left := (ActiveControl as TButton).Left - 16; VK_UP : (ActiveControl as TButton).Top := (ActiveControl as TButton).Top - 16; VK_RIGHT : (ActiveControl as TButton).Left := (ActiveControl as TButton).Left + 16; VK_DOWN : (ActiveControl as TButton).Top := (ActiveControl as TButton).Top + 16; else Handled := False; end end; end; |
AW: [gelöst] Cursortasten von Buttons fernhalten
Oder auch
Delphi-Quellcode:
procedure TForm1.ApplicationEvents1ShortCut(var Msg: TWMKey; var Handled: Boolean);
const STEP = 16; var Button: TButton; begin if (ActiveControl is TButton) then begin Button := TButton(ActiveControl); Handled := true; case Msg.CharCode of VK_LEFT : Button.Left := Button.Left - STEP; VK_UP : Button.Top := Button.Top - STEP; VK_RIGHT : Button.Left := Button.Left + STEP; VK_DOWN : Button.Top := Button.Top + STEP; else Handled := False; end; end; end; |
AW: [gelöst] Cursortasten von Buttons fernhalten
Zitat:
Delphi-Quellcode:
. Ich werde gleich mal den Code anpassen. Ich habe es übrigens bei mir auch mit einer Variable besser lesbar gemacht.
Handled:= False;
Allerdings ist die Lösung doch (noch) nicht perfekt: Wenn ich jetzt ein weiteres Fenster öffne und dort mit den Cursortasten rumhantiere, dann bewegt sich munter der jeweils auf dem Hauptform befindliche, aktive TButton. Auf dem Kindfenster passiert hingegen nichts mehr :| Das ist sehr ungünstig. Daher noch ein weiteres Codeschnipsel :lol::
Delphi-Quellcode:
procedure TForm1.ApplicationEvents1ShortCut(var Msg: TWMKey; var Handled: Boolean);
const STEP = 16; var Button: TButton; begin if (Screen.ActiveForm = self) and // Ist das gewünschte Fenster aktiv? (ActiveControl is TButton) then begin Button := TButton(ActiveControl); Handled := true; case Msg.CharCode of VK_LEFT : Button.Left := Button.Left - STEP; VK_UP : Button.Top := Button.Top - STEP; VK_RIGHT : Button.Left := Button.Left + STEP; VK_DOWN : Button.Top := Button.Top + STEP; else Handled := False; end; end; end; |
AW: [gelöst] Cursortasten von Buttons fernhalten
Passen wir es nochmal an (dann können wir auf die implizit gemachte Annahme über den Wert von Handled verzichten):
Delphi-Quellcode:
procedure TForm1.ApplicationEvents1ShortCut(var Msg: TWMKey; var Handled: Boolean);
const STEP = 16; var Button: TButton; begin Handled := False; if (Screen.ActiveForm = self) and // Ist das gewünschte Fenster aktiv? (ActiveControl is TButton) then begin Button := TButton(ActiveControl); Handled := true; case Msg.CharCode of VK_LEFT : Button.Left := Button.Left - STEP; VK_UP : Button.Top := Button.Top - STEP; VK_RIGHT : Button.Left := Button.Left + STEP; VK_DOWN : Button.Top := Button.Top + STEP; else Handled := False; end; end; end; |
AW: [gelöst] Cursortasten von Buttons fernhalten
Hmm..
Oder noch einfacher, damit dies nur auf dem einen Formular läuft: OnShortCut vom Formular verwenden, dann brauchst Du kein ApplicationEvents. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:01 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz