[gelöst] UTF8Key: Return/Enter vom Zahlenblock erkennen.

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Erwin
Beiträge: 286
Registriert: Mi 16. Sep 2009, 14:15
OS, Lazarus, FPC: Xubuntu 22.04 / x86_64_linux-gtk 2 / L 2.2.0 / FPC 3.2.2

[gelöst] UTF8Key: Return/Enter vom Zahlenblock erkennen.

Beitrag von Erwin »

Hallo Zusammen.

Leider komme ich nicht drum herum, mich mal wieder bemerkbar zu machen. Ich stehe da vor ein Problem, dass ich trotz Forum-Suche und testen meines Programms (habe alle 255 UTF8Key ausprobiert) nicht heraus fand. Derzeit habe ich folgenden Code, um den Return bei den Buchstaben abzufangen.

Code: Alles auswählen

procedure TForm1.Edit1UTF8KeyPress(Sender: TObject; var UTF8Key: TUTF8Char);
begin
  if UTF8Key=#13 then Eigene_Proze_Starten;
end;
Leider geht das nur mit dem Enter/Return bei den Buchstaben. Die Nummer für die Entertaste bei dem Zahlenblock fand ich ärgerlicherweise nicht heraus. Was mich besonders irritiert: Wie bereits geschrieben, habe ich alle 255 durch probiert!? Habe ich da was übersehen? Oder vor lauter durch testen etwas nicht bemerkt?

Danke.

Gruß, Erwin.
Zuletzt geändert von Erwin am Do 28. Sep 2023, 11:00, insgesamt 1-mal geändert.
Lazarus 2.2.0 / FP 3.2.4

Benutzeravatar
theo
Beiträge: 10500
Registriert: Mo 11. Sep 2006, 19:01

Re: UTF8Key: Return/Enter vom Zahlenblock erkennen.

Beitrag von theo »

OnKeypress ist für beliebige Tastendrücke eigentlich nicht geeignet.
Nimm OnKeyUp (oder -Down) und vergleiche mit den Virtual Keys (VK_..) in unit LCLType.

Code: Alles auswählen

procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  If Key=VK_Return then ShowMessage('Return');
end;  

Erwin
Beiträge: 286
Registriert: Mi 16. Sep 2009, 14:15
OS, Lazarus, FPC: Xubuntu 22.04 / x86_64_linux-gtk 2 / L 2.2.0 / FPC 3.2.2

Re: UTF8Key: Return/Enter vom Zahlenblock erkennen.

Beitrag von Erwin »

Danke für Deinen Vorschlag, Thoe. Dennoch ist leider das Deinige für mich etwas umständlicher, auch wenn dort beides (Enter und Return) als gleich betrachtet wird. Ich habe mich mit meinen Code etwas kurz gehalten, um nicht unnötig viel zum lesen mit zu schreiben ... mit zu geben. Es geht nicht nur allein um die 13, auch nicht allein um ein Edit. Da hängt noch viel mehr mit dran. Unter anderem:

Code: Alles auswählen

  if UTF8Key=#13 then Eigene_Proze_Starten
  else Arbeits_String := Arbeits_String+UTF8Key;
Mit KeyUp hätte ich das Problem, dass dies keinen Unterschied mit klein oder groß macht. Müsste also einiges mehr abfangen (wurde die Shift-Taste gedrückt, oder nicht?) und bearbeiten (müsste ich dann jedes einzeln machen oder geht das mit ... Groß Key + (oder Minus) Feste Zahl wenn Shift feht?).

Beides will ich auch nicht unbedingt verwenden. Also das Return nur in KeyUp (was dann zwar klappen würde, aber wegen dem einen ... doppelte Abfrage welche Taste gedrückt wurde?). Nein, da fühle ich mich unwohl. Außerdem, da ich unter UTF8Key es nicht abfangen kann, kann es sein, dass dennoch was ausgelöst wird, und dann alles durcheinander kommt.
Lazarus 2.2.0 / FP 3.2.4

wp_xyz
Beiträge: 4895
Registriert: Fr 8. Apr 2011, 09:01

Re: UTF8Key: Return/Enter vom Zahlenblock erkennen.

Beitrag von wp_xyz »

Auf Stackoverflow (https://stackoverflow.com/questions/194 ... age-return) gibt es einen Beitrag, in dem die WMKeyDown-Nachricht abgefangen und ein Bit im CharCode-Element des Message-Record ausgewertet wird, an dem man unterscheiden kann, welche Enter-Taste gedrückt wurde. Damit kann man z.B. eine globale boolsche Status-Variable NumericEnter setzen und diese dann im eigentlichen KeyPress-Ereignis abfragen.

Das folgende funktioniert definitiv unter Windows, evtl auch unter anderen Widgetsets:

Code: Alles auswählen

uses
  LCLType, LMessages,
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls;

type

  TMemo = class(StdCtrls.TMemo)
  private
    procedure WMKeyDown(var Message: TLMKeyDown); message LM_KeyDown;
  end;

  { TForm1 }

  TForm1 = class(TForm)
    Memo1: TMemo;
    procedure Memo1KeyPress(Sender: TObject; var Key: char);
  private

  public

  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

var
  NumericEnter: Boolean;

{ TForm1 }

procedure TForm1.Memo1KeyPress(Sender: TObject; var Key: char);
begin
  if NumericEnter then
    Memo1.Lines.Add('Numeric ENTER')
  else
    Memo1.Lines.Add(Key);
end;

// https://stackoverflow.com/questions/1949168/delphi-can-i-differentiate-between-numpads-enter-key-and-carriage-return
procedure TMemo.WMKeyDown(var Message: TLMKeyDown);
const
  // Message.KeyData format:
  // [0..15 repCount][16..23 scan code][24 extended bit][25..28 reserved]
  // [29 context][30 previous state][31 transition state]
  KD_IS_EXTENDED = 1 shl 24;
begin
  NumericEnter := false;
  if Message.CharCode <> VK_RETURN then
  begin
    inherited;
    Exit;
  end;
  if (KD_IS_EXTENDED and Message.KeyData) <> 0 then
    NumericEnter := true;
end;
In dem Beispiel wird diese Spezialbehandlung für ein Memo implementiert (direkt mit TForm, wie in stackoverflow geschrieben, funktioniert nicht, wenn ein Control den Fokus hat), aber ich denke mal, das müsste man auch irgendwie in der Message-Loop der Anwendung unterbringen können.

Erwin
Beiträge: 286
Registriert: Mi 16. Sep 2009, 14:15
OS, Lazarus, FPC: Xubuntu 22.04 / x86_64_linux-gtk 2 / L 2.2.0 / FPC 3.2.2

Re: UTF8Key: Return/Enter vom Zahlenblock erkennen.

Beitrag von Erwin »

Beim weiterem testen habe ich festgestellt, dass bei KeyUp der Zahlenblock gar nicht erkannt wird. Wenn ich diese Zahlen nutze, kommen kleine Buchstaben dabei heraus. Angefangen bei e ungefähr. Also KeyUp kommt für mich überhaupt nicht in Frage. Viel zu viel durcheinander. Dennoch danke, Theo. Weil in einem anderem Programm von mir nutze ich noch KeyUp, was ich dann (jetzt wo ich von dem Problem weis) demnächst ändern kann/werde, bevor dieser Umstand mir noch wirklich Ärger bereitet.

@ wp_xyz
Für mich ist das wieder mal ganz schon komplex, also schwere Kost. Aber mir fiel dabei auf, dass Du nicht UTF8KeyPress nutzt, sondern das normale KeyPress. Auf der Suche für einfache (bzw. Kurze (Code)) Lösung meines Problems (also dass die Taste/Zeichen zum String hinzu gefügt wird), bin ich auf UTF8KeyPress gestoßen, wo es auch noch hieß, das UTF8KeyPress besser sei, weshalb ich gleich dies nahm. Nun habe ich aber das einfache KeyPress inzwischen etwas ausprobiert. Das einfache KeyPress kennt nicht so viele Zeichen, wie UTF8KeyPress, aber das sind eh jene, die vermutlich nie brauchen werde (²³¼½¬). Letzte weiß ich nicht mal, was das ist. Aber dafür wird bei KeyPress Enter und Return beides als #13 erkannt. Somit hat, was mich betrifft, der Umstieg von UTF8KeyPress auf KeyPress scheinbar (ganz gründlicher Test steht noch bevor) mein Problem behoben. Danke.
Lazarus 2.2.0 / FP 3.2.4

Benutzeravatar
theo
Beiträge: 10500
Registriert: Mo 11. Sep 2006, 19:01

Re: UTF8Key: Return/Enter vom Zahlenblock erkennen.

Beitrag von theo »

Erwin hat geschrieben:
Do 28. Sep 2023, 10:59
Beim weiterem testen habe ich festgestellt, dass bei KeyUp der Zahlenblock gar nicht erkannt wird. Wenn ich diese Zahlen nutze, kommen kleine Buchstaben dabei heraus. Angefangen bei e ungefähr. Also KeyUp kommt für mich überhaupt nicht in Frage. Viel zu viel durcheinander. Dennoch danke, Theo.
Du hast den Unterschied nicht verstanden.
Bei OnKeyUp/Down bekommst du die Taste, bei OnKeyPress das übersetze Zeichen.

Was du beim Parameter "Key" bekommst, ist der Tastencode. Du bekommst also nicht z.B. beim Zahlenblock Taste 0 das Zeichen "0" sondern VK_NUMPAD0.
So weisst du, dass die Taste beim Zahlenblock gedrückt wurde und nicht irgend eine "0".

Code: Alles auswählen

procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
 If Key=VK_NUMPAD0 then ShowMessage('Null vom Numpad');
end;  

Erwin
Beiträge: 286
Registriert: Mi 16. Sep 2009, 14:15
OS, Lazarus, FPC: Xubuntu 22.04 / x86_64_linux-gtk 2 / L 2.2.0 / FPC 3.2.2

Re: UTF8Key: Return/Enter vom Zahlenblock erkennen.

Beitrag von Erwin »

theo hat geschrieben:
Do 28. Sep 2023, 12:28
Du hast den Unterschied nicht verstanden.
Bei OnKeyUp/Down bekommst du die Taste, bei OnKeyPress das übersetze Zeichen.

Was du beim Parameter "Key" bekommst, ist der Tastencode. Du bekommst also nicht z.B. beim Zahlenblock Taste 0 das Zeichen "0" sondern VK_NUMPAD0.
So weisst du, dass die Taste beim Zahlenblock gedrückt wurde und nicht irgend eine "0".
Ok, ändert aber leider nichts daran, dass wenn man dies nicht abfängt, dann dennoch kleine Buchstaben dabei heraus bzw. ankommen. Wenn ich also will, dass beim Druck auf die Tasten VK_NUMPAD0 bis VK_NUMPAD9 auch 0..9 dabei herauskommt, muss ich ja doch jedes einzeln abfangen, oder? Vermutlich würde ich dadurch zwar anderseits auf Nummer sicher gehen, dass im Gegensatz zu OnKeyPress nicht mittendrin ein Zeichen doch falsch Übersetzt wird. Und auch sonst kann vermutlich mit OnKeyUp und OnKeyDown jede Taste verarbeiten/benutzen, während bei OnKeyPress scheinbar Pfeil-Tasten und F-Tasten (1-12) ignoriert werden. Allerdings würde dies auch verdammt viel Schreibarbeit bedeuten, alle ... (2x26 Buchstaben, 2x10 Zahlen, + 10-20 ...) jedenfalls über 100 ... wow. Da frage ich mich auch, ob danach das Programm noch flüssig läuft?

Danke für die weitere Erklärung. Somit blicke ich jedenfalls wieder etwas weiter durch bei dem Ganzem.
Lazarus 2.2.0 / FP 3.2.4

Benutzeravatar
theo
Beiträge: 10500
Registriert: Mo 11. Sep 2006, 19:01

Re: [gelöst] UTF8Key: Return/Enter vom Zahlenblock erkennen.

Beitrag von theo »

Nochmal: Taste (bzw. Tastenkombination) ist nicht gleich Zeichen.

Wenn du wissen willst, welche Tastenkombination gedrückt wird, nimm OKeyDown/-Up.
Wenn du wissen willst, welches Zeichen das ergibt, nimm OnKeyPress.

Beispiel:
OKeyDown/-Up sagt dir: Es wurde AltGr + E gedrückt.
OnKeyPress sagt dir: "€".

Da bei Funktions- und Pfeiltasten kein Zeichen dazugehört, kommt da auch nichts bei OnKeyPress.

Welches davon du brauchst, musst du selber wissen.

Erwin
Beiträge: 286
Registriert: Mi 16. Sep 2009, 14:15
OS, Lazarus, FPC: Xubuntu 22.04 / x86_64_linux-gtk 2 / L 2.2.0 / FPC 3.2.2

Re: [gelöst] UTF8Key: Return/Enter vom Zahlenblock erkennen.

Beitrag von Erwin »

theo hat geschrieben:
Do 28. Sep 2023, 13:45
Wenn du wissen willst, welche Tastenkombination gedrückt wird, nimm OKeyDown/-Up.
Wenn du wissen willst, welches Zeichen das ergibt, nimm OnKeyPress.

Beispiel:
OKeyDown/-Up sagt dir: Es wurde AltGr + E gedrückt.
OnKeyPress sagt dir: "€".
Das habe ich so weit begriffen, danke. Aber ändert eben nichts daran, wenn ich das so wie bei KeyPress mache (nämlich zum String das UTF8Key (Zeichen) hinzufüge), dies bei KeyDown/-Up (in dem Fall Word zum String hinzufüge), letztendlich dann beim Drücken von + vom Zahlenblock (Numpad) dann ein kleines k ankommt im String (bzw. Edit2, womit ich es getestet habe). Es geht mir weniger darum, ein Dutzend Tasten und Tasten-Kombinationen abzufangen, sondern wenn ich dann ein Teilprogramm starte, ab da bis zum Ende des Vorgangs, alles was ich an Buchstaben und Zeichen drücke, in meinen String geschrieben werden soll. Mit KeyDown/-Up bedeutet dies dann viel Arbeit, weil sonst im String totaler Murks an kommt. Mit KeyPress ist das halt einfacher zu realisieren. 2,3 Code-Zeilen statt über 100!!
Anderseits ... werden im laufe der Zeit auch Tastenkombinationen und mehr dazu kommen. Vermutlich komme ich eh nicht um ein Aufgeblähtes KeyDown/-Up herum? Naja, eigentlich sollte auch Tausend-Lange Code-Zeilen (allein) selbst in solch einer Procedure kaum was ausmachen. Aber wohl fühle ich mich bei so was dennoch nicht.

Der Merkbare Unterschied zwischen KeyDown und und KeyUp ist doch der, dass bei Down ein Art Dauerfeuer möglich ist, oder?
Lazarus 2.2.0 / FP 3.2.4

Benutzeravatar
theo
Beiträge: 10500
Registriert: Mo 11. Sep 2006, 19:01

Re: [gelöst] UTF8Key: Return/Enter vom Zahlenblock erkennen.

Beitrag von theo »

Erwin hat geschrieben:
Do 28. Sep 2023, 14:19
Das habe ich so weit begriffen, danke. Aber ändert eben nichts daran, wenn ich das so wie bei KeyPress mache (nämlich zum String das UTF8Key (Zeichen) hinzufüge), dies bei KeyDown/-Up (in dem Fall Word zum String hinzufüge), letztendlich dann beim Drücken von + vom Zahlenblock (Numpad) dann ein kleines k ankommt im String
Nein, du hast es nicht begriffen.
Der Parameter Key:Word bei KeyDown/-Up ist kein Buchstabe oder ein sonstiges Zeichen.
Der Parameter Key ist der Tastencode!!!
Der Datentyp "Word" hat auch nichts mit Zeichen zu tun (falls dich das irritiert), das sind nur zwei Byte.

Wenn du ein "k" bei "+" bekommst, dann verwendest du den Parameter "Key" falsch.
KeyDown/-Up gibt keine Zeichen zurück! Keine!

Der Tastencode für die Taste "+" auf dem Numpad ist VK_ADD (Siehe Unit LCLType).
Den bekommst du in "Key" und sonst gar nichts.

Du kannst Key so eigentlich nur für Vergleiche verwenden (Ist es ein VK_SUBTRACT oder ein VK_RIGHT oder ein VK_F12...)

Du musst ja auch nur die abfangen, welche dich interessieren.

Erwin
Beiträge: 286
Registriert: Mi 16. Sep 2009, 14:15
OS, Lazarus, FPC: Xubuntu 22.04 / x86_64_linux-gtk 2 / L 2.2.0 / FPC 3.2.2

Re: [gelöst] UTF8Key: Return/Enter vom Zahlenblock erkennen.

Beitrag von Erwin »

theo hat geschrieben:
Do 28. Sep 2023, 14:32
Nein, du hast es nicht begriffen.
Doch, ich denke schon, dass ich das habe.
theo hat geschrieben:
Do 28. Sep 2023, 14:32
Wenn du ein "k" bei "+" bekommst, dann verwendest du den Parameter "Key" falsch.
Klar verwende ich ihn falsch. Weil richtig verwenden bedeutet doch in abzufangen, zu bearbeiten? Oder? Für jedes Zeichen eine Code-Zeile, sozusagen. Viel Aufwand.
theo hat geschrieben:
Do 28. Sep 2023, 14:32
Du musst ja auch nur die abfangen, welche dich interessieren.
Mich interessieren bzw. benötige für mein Vorhaben (Art eigenes Memo mit eigener gezeichneter Grafik) aber fast alle. Hm... aber mir fällt jetzt gerade ein Umweg ein, der vielleicht klappen könnte?
Lazarus 2.2.0 / FP 3.2.4

ArchChem
Beiträge: 83
Registriert: Mo 11. Jul 2022, 10:41

Re: [gelöst] UTF8Key: Return/Enter vom Zahlenblock erkennen.

Beitrag von ArchChem »

Erwin hat geschrieben:
Do 28. Sep 2023, 15:07
Klar verwende ich ihn falsch. Weil richtig verwenden bedeutet doch in abzufangen, zu bearbeiten?
In der von Theo erwähnten Methode FormKeyUp wird die Variable Key als Referenz übergeben (Call by Reference). Das kannst du daran sehen, dass im Prozedurenkopf ein var vor Key steht. Damit kannst du die Variable Key einfach bearbeiten, wenn du es brauchst. Das musst du aber nicht.

Code: Alles auswählen

procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
Nach dieser Prozedur wird der Key (modifiziert oder nicht) an die betreffende Komponente weitergegeben, die diesen dann weiter bearbeitet (zum Beispiel würde ein TEdit Text schreiben, etc.). Möchtest du das vermeiden (also ein Abfangen im klassischen Sinne), setzt du in der Prozedur den Key auf VK_Unknown. Damit erfolgt keine Reaktion mehr.

Code: Alles auswählen

procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
Begin
  Key := VK_Unknown;
End;

Erwin
Beiträge: 286
Registriert: Mi 16. Sep 2009, 14:15
OS, Lazarus, FPC: Xubuntu 22.04 / x86_64_linux-gtk 2 / L 2.2.0 / FPC 3.2.2

Re: [gelöst] UTF8Key: Return/Enter vom Zahlenblock erkennen.

Beitrag von Erwin »

ArchChem hat geschrieben:
Do 28. Sep 2023, 16:47
... Damit erfolgt keine Reaktion mehr.

Code: Alles auswählen

procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
Begin
  Key := VK_Unknown;
End;
Danke. Werde wegen besserer Kontrolle doch den längeren Weg (KeyDown) machen. Da kann ich dies vermutlich auch brauchen.
Lazarus 2.2.0 / FP 3.2.4

ArchChem
Beiträge: 83
Registriert: Mo 11. Jul 2022, 10:41

Re: [gelöst] UTF8Key: Return/Enter vom Zahlenblock erkennen.

Beitrag von ArchChem »

Mit der Prozedur KeyDown funktioniert es genau so.

Erwin
Beiträge: 286
Registriert: Mi 16. Sep 2009, 14:15
OS, Lazarus, FPC: Xubuntu 22.04 / x86_64_linux-gtk 2 / L 2.2.0 / FPC 3.2.2

Re: [gelöst] UTF8Key: Return/Enter vom Zahlenblock erkennen.

Beitrag von Erwin »

ArchChem hat geschrieben:
Do 28. Sep 2023, 18:12
Mit der Prozedur KeyDown funktioniert es genau so.
Dachte ich mir schon. Ist ja beides im Prinzip das selbe, finde ich, außer dass man bei KeyDown ein Dauerfeuer machen kann. Was ich teils Sinnvoller finde ... wenn man schreibt, aber ansonsten ... eher doch nicht?

Die Liste der Bezeichnungen ist lange. VK_Unknown ist mir nicht aufgefallen. Komisch? Vielleicht übersehen? Aber anderes, wie VK_Browser, Media und dererlei Bezeichnungen fiel mir auf. Aber dafür bräuchte man vermutlich eh eine spezielle Tastatur? Denke, ich habe alle wesentlichen Bezeichnungen von der Wiki abgetippt. Mal sehen, wie lange ich dann brauche, um all das einzupflegen. Aber je mehr ich mich damit befasse ... theo hat mit KeyDown/KeyUp recht: Habe inzwischen auch den Eindruck, damit kann man es besser Kontrollieren, was wirklich passieren soll. Ist aber leider mit verdammt viel Schreibarbeit verbunden ... die hoffentlich nicht den KeyDown überfordert?
Lazarus 2.2.0 / FP 3.2.4

Antworten