Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Key wird nicht gelöscht, warum? (https://www.delphipraxis.net/195064-key-wird-nicht-geloescht-warum.html)

Fukiszo 30. Jan 2018 11:44

Key wird nicht gelöscht, warum?
 
Hallo, hier mein Aufruf

Delphi-Quellcode:
procedure TForm1.Button1KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
 case key of
  Windows.VK_SPACE : ZeigeWas;
  Windows.VK_RETURN: ; // <- hier soll nichts passieren, tastendruck übersprungen werden, aber "ZeigeWas" wird ausgelöst
  Windows.VK_ESCAPE: Application.Terminate;
 end;
 Key := 0; // <- ich dachte das hier macht exakt das (key puffer leeren)
 //Application.ProcessMessages;
end;
Also ich reagiere auf einen Knopf und werte Tastenanschläge aus, ist evtl. KeyDown event falsch dafür?
Sinn und Zweck soll sein, bei gedrückter Eingabe-Taste soll nichts passieren/ausgelöst werden.

Für einen kleinen Anstoss in die richtige Richtung wäre ich dankbar,

Grüße

TiGü 30. Jan 2018 11:55

AW: Key wird nicht gelöscht, warum?
 
Mal testweise in KeyUp reingehangen?

Der schöne Günther 30. Jan 2018 11:58

AW: Key wird nicht gelöscht, warum?
 
Du muss das schon mit richtig mit dem Debugger machen. Deine Beobachtung "Meine Prozedur zweigewas() wird ausgelöst" kommt wohl eher daher dass du dein
Delphi-Quellcode:
OnClick
auch damit belegt hast, oder?

Denn das OnKeyDown-Event wird bei einem Druck auf Return überhaupt nicht ausgelöst, das sieht man eigentlich im Debugger.

Fukiszo 30. Jan 2018 12:09

AW: Key wird nicht gelöscht, warum?
 
@Der schöne Günther: Genau
@TiGü: noch nicht probiert, mach ich gleich mal

OnClick und VK.Space sollen beide "ZeigeWas" aufrufen,
im OnClick steht nur "ZeigeWas" aber ich will halt das "VK.Return" da raus haben,
deswegen das KeyDown Event.
Eine Idee wie ich das anstellen kann?

Grüße

LTE5 30. Jan 2018 12:12

AW: Key wird nicht gelöscht, warum?
 
Das hört sich für mich stark so an, als ob du verzweifelt nach einer Lösung suchst und nur deswegen das KeyDown versuchst zu nutzen.

Wäre es vielleicht nicht sogar das Beste, das nochmal neu zu machen?

himitsu 30. Jan 2018 12:16

AW: Key wird nicht gelöscht, warum?
 
OnKeyDown
OnKeyPres
OnKeyUp

Nicht alle Tastenevents werden an gleicher Stelle behandelt.
Manches wird beim Drücken ausgelöst (inkl. Key-Repeat-Calls) und manches erst beim Loslassen.

Buttons z.B. :
per Tastatur [ENTER] beim Drücken,
das [Space] beim Loslassen,
deren ShortCuts/HotKeys beim Drücken
und per Maus auch erst beim Loslassen.

Die SpeedButtons in ScrollBars und beim UpDownButtons reagieren dagegen wieder auf's Drücken, mit RepeatTimer und stoppen beim Loslassen.


Wir hatten z.B. ein Fenster im Programm, das ging bei F2-KeyDown zu, aber im übergeordneten Fenster wird es beim beim F2-KeyUp geöffnet, also beim Schließen via F2 wurde es sofort wieder geöffnet. :wall:


Aber wieso soll "ein" Knopf verschiedene Funktionen haben?
ein Button mit Cancel=True reagiert auf ESC
und ein anderer Button mit Default=True auf das Enter.
Bei ESC immer. Bei ENTER nur wenn die Knöpfe keinen Fokus haben, ansonsten macht bei Enter/Space jeder Button das, wofür er da ist.

Fukiszo 30. Jan 2018 12:17

AW: Key wird nicht gelöscht, warum?
 
Ja klar, Event ist nur dafür da das VK.Return zu unterbinden/abzufangen.
Wenn ich's neu mach, käm ich doch wieder bei einem Key-Event raus?
Ich verstehe bestimmt wiedermal nicht wie ich's anders als mit einem Key-Event zu lösen wäre damit:
- OnClick > ZeigeWas
- Vk.Space > ZeigeWas
- Vk.Return > überspringen
als endresultat rauskommt.

Grüße


Delphi-Quellcode:
per Tastatur [ENTER] beim Drücken
also KeyDown event scheint das richtige zu sein, oder versteh ich's falsch?

Der schöne Günther 30. Jan 2018 12:21

AW: Key wird nicht gelöscht, warum?
 
Zitat:

Zitat von Fukiszo (Beitrag 1392543)
- OnClick > ZeigeWas
- Vk.Space > ZeigeWas
- Vk.Return > überspringen

Ich will dich ja nicht zwanghaft konvertieren, aber warum sollte man das tun? Mach es doch einfach so wie sich jede Standard-Windows-Anwendung auch verhält: Buttons lassen sich mit Maus/Touch/Stift drücken und (wenn er den Fokus hat) mit der Tastatur über Enter/Return/Space. Da reicht ein einfaches
Delphi-Quellcode:
OnClick
.

Escape hat dir himitsu weiter oben schon erklärt wie man das eigentlich "richtig" macht.

himitsu 30. Jan 2018 12:25

AW: Key wird nicht gelöscht, warum?
 
Enter/Space lösen OnClick aus.

Also einfach nur das ENTER blocken und den Rest durchlassen.



Aber IMHO ist es eher unglücklich, wenn "Standard"-Komponenten vom standardmäßigen Verhalten des OS abweichen.

himitsu 30. Jan 2018 12:28

AW: Key wird nicht gelöscht, warum?
 
Hatte meinen Text da oben noch etwas ergänzt.

Zitat:

Zitat von Fukiszo (Beitrag 1392543)
Delphi-Quellcode:
per Tastatur [ENTER] beim Drücken
also KeyDown event scheint das richtige zu sein, oder versteh ich's falsch?

Da kommt es dann darauf an, wo/wie das Standardverhalten der Komponente genau implementiert ist
und vorallem ob es vor oder nach dem KeyPress-Event behandelt wird.

Theoretisch wäre KeyDown schon richtig, um das ENTER abzufangen.

Fukiszo 30. Jan 2018 12:33

AW: Key wird nicht gelöscht, warum?
 
ok nochmal ausführlicher:
in meiner TForm hab ich einen Knopf der permanent den Fokus bekommt wenn nicht gerade ein "Edit" passiert.
Alle funktionen enden damit den knopf den fokus zu geben (ist von hause aus DefaultButton)
Ob nun ein Escape darin vorkommt oder nicht lass ich jetzt mal so im raum stehen da ja mein problem die Return-Taste ist.

Hat jemand einen konstruktiven Vorschlag wie ich Return da rausbekommen kann?
Oder muss ich eine Button class erstellen die sowas verhindert, sich "normal wie unter windows" zu benehmen?

Grüße und verzeiht falls ich das eine oder andere falsch versteh

himitsu 30. Jan 2018 12:43

AW: Key wird nicht gelöscht, warum?
 
Vorschlag:
Nicht der Button bekommt den Fokus, sondern die Form, also
Delphi-Quellcode:
Form.SetFocus
oder besser
Delphi-Quellcode:
Form.ActiveControl:=nil;
.

Der Knopf bekommt nicht Default=True. hat der Knopf den Fokus, dann kann Enter/Space/Maus das OnClick normal auslösen.
Space wird im OnKeyPress/Down/Up der Form behandelt. (KeyPreview=False)
Und das ESC kann über Cancel=True eines anderen Buttons oder auch über OnKeyPress/Down/Up der Form behandelt werden.



Die Dialog-Standard-Funktionen (Cancel und Default) werden über die ganze Form/Dialog behandelt.
Nur z.B. Memos behandeln ihr [ENTER] vorher und geben es nicht an die Form weiter.
Wie gesagt, ENTER/ESC haben Sonderaufgaben und werden von Windows bissl anders behandelt. Ist wie beim Strg+Alt+Entf, was sich auch nicht so leicht abschalten/überschreiben lässt.

Fukiszo 30. Jan 2018 12:49

AW: Key wird nicht gelöscht, warum?
 
Das klingt gut, danke fürs umdenken.
Jetzt muss ich den knopf eh umarbeiten da er momentan nur sichtbar wird wenn er den fokus bekommt.
teufelskreis hehe aber ich pflanz den nun immer sichtbar rein und versuch es so wie du vorgeschlagen hast.

Danke!

Delphi-Quellcode:
Wie gesagt, ENTER/ESC haben Sonderaufgaben und werden von Windows bissl anders behandelt
danke auch nochmals für erläuterung!

Delphi.Narium 30. Jan 2018 12:50

AW: Key wird nicht gelöscht, warum?
 
Eventuell im Form KeyPreview auf True und dann im OnKeyDown des Forms bei Return Key auf 0 setzen?
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
  KeyPreview := True; // Kann man auch im Objektinspektor setzen.
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  case key of
    // Windows.VK_SPACE : ZeigeWas; // ist nicht erforderlich, da beim Betätigen der Leertaste,
    // mit Focus auf dem Button, sowieso das OnClick des Buttons ausgelöst wird.
    Windows.VK_RETURN : key := 0;
    // Windows.VK_ESCAPE : Application.Terminate;
    Windows.VK_ESCAPE : Close; // Halte ich für sinnvoller.
  end;
end;

LTE5 30. Jan 2018 12:51

AW: Key wird nicht gelöscht, warum?
 
Ich habe mal denselben Fehler gemacht wie du, und habe mich abhängig von irgendwelchen Sichtbarkeiten gemacht.
Ich sag nur.... tu's nicht :thumb:

Fukiszo 30. Jan 2018 19:06

AW: Key wird nicht gelöscht, warum?
 
Zitat:

Zitat von LTE5 (Beitrag 1392558)
Ich habe mal denselben Fehler gemacht wie du, und habe mich abhängig von irgendwelchen Sichtbarkeiten gemacht.
Ich sag nur.... tu's nicht :thumb:

Ja danke, bin schon dabei hehe
War halt ein netter Fade in/out effekt der nun flöten geht, funktionalität hat vorrang.

Grüße

Fukiszo 30. Jan 2018 23:11

AW: Key wird nicht gelöscht, warum?
 
Liste der Anhänge anzeigen (Anzahl: 2)
Da es mich doch irgendwie nicht loslässt hab ich mal ein Beispiel "Spiel" gebastelt wo die Eingabe-Taste der Feind ist.
Kann jemand dafür eine Lösung finden das Return nicht zum Sieg des "Spiels" führt?

Ich bin gespannt ob das machbar ist ansonsten..... Catch the Button :D

Im Anhang ist nur der komplette Source, standard VCL programmiert.

Viel Spass beim spielen,


Grüße

Redeemer 31. Jan 2018 09:55

AW: Key wird nicht gelöscht, warum?
 
TApplicationEvents.OnShortcut?

Fukiszo 31. Jan 2018 10:34

AW: Key wird nicht gelöscht, warum?
 
Der Source ist ja nur 5.4kb groß, bitte runterladen und deine methode testen.
Mir sagt "TApplicationEvents.OnShortcut" leider nichts, wahrscheinlich wegen meinem alten Delphi 7.
Aber ich besser mich ja schon was Delphi 7 betrifft, D2010 kommt nun rauf.

Grüße

Delphi.Narium 31. Jan 2018 10:53

AW: Key wird nicht gelöscht, warum?
 
Es gibt auch in Delphi 7 die Komponente TApplicationEvents. Die pappt man auf's Formular und nutzt das Ereignis OnShortcut.

Redeemer 31. Jan 2018 11:06

AW: Key wird nicht gelöscht, warum?
 
Zitat:

Zitat von Fukiszo (Beitrag 1392656)
Der Source ist ja nur 5.4kb groß, bitte runterladen und deine methode testen.
Mir sagt "TApplicationEvents.OnShortcut" leider nichts, wahrscheinlich wegen meinem alten Delphi 7.

Wir sind nicht dazu da, deine Hausaufgaben zu machen. Du musst schon selbst was tun und nicht darauf warten, dass dir die Lösung auf dem Silbertablett präsentiert wird. Und dass man etwas, das man nicht kennt, mal eben in die Delphi-Hilfe eingibt, das ist wohl das Mindeste, was man erwarten kann. Und nicht: "Lade dir meinen Source herunter, implementiere deinen Lösungsvorschlag und prüfe, er in meinem speziellen Fall alle meine Anforderungen erfüllt."
Ganz abgesehen davon, dass ich nicht überprüfen kann, ob das in deinem speziellen Delphi 7 funktioniert.

Fukiszo 31. Jan 2018 12:15

AW: Key wird nicht gelöscht, warum?
 
Ich schrieb ja das ich diese funktion noch nicht kenne, leider ist meine hilfe nicht so umfangreich und enthält keine beispiele wie man es anwendet.
Nach ein wenig herumprobieren bin ich hier gelandet:

Delphi-Quellcode:
procedure TForm1.aplctnvnts1ShortCut(var Msg: TWMKey;
  var Handled: Boolean);
begin
(*
  TWMKey = packed record
    Msg: Cardinal;
    CharCode: Word;
    Unused: Word;
    KeyData: Longint;
    Result: Longint;
  end;
*)
{
 MessageDlg('Msg: '+IntToStr(Msg.Msg)+#13#13+
            'CharCode: '+IntToStr(Msg.CharCode)+#13#13+
            'Unused: '+IntToStr(Msg.Unused)+#13#13+
            'KeyData: '+IntToStr(Msg.KeyData)+#13#13+
            'Result: '+IntToStr(Msg.Result)
            , mtInformation, [mbOk], 0);
}
// CharCode 13 = VK.Return
 if Msg.CharCode = Windows.VK_RETURN then
 begin
  //Msg.CharCode := Windows.VK_SPACE;
  Msg.Result := 1;
  ZeigeWas;
 end;
end;
Wenn Msg.Result <> 0 dann schluckt der die taste.
Ein Msg.CharCode := Windows.VK_SPACE funktioniert nicht (ich versuchte die taste return auf taste space umzulegen)
Diese Funktion ist auf jedenfall eine möglichkeit das "normale" windows verhalten zu umgehen, super tipp, danke!

Jetzt meine Frage, ruf ich es so richtig auf oder mach ich da was falsch?
Ich würd gerne von euch lernen!


Grüße


edit ps:
Delphi-Quellcode:
aplctnvnts1: TApplicationEvents;
<- so in der Deklaration
edit2: nun hab ich Result := 1 mit Handled := True ersetzt, scheint die bessere lösung aber ob's richtig ist... hmmm...

hoika 31. Jan 2018 13:55

AW: Key wird nicht gelöscht, warum?
 
Hallo,
nimm statt dem KeyDown das KeyPress mit Key:= #0.

Fukiszo 31. Jan 2018 14:58

AW: Key wird nicht gelöscht, warum?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Bei Key-Down/Up/Press greift immer der Delphi/Windows Standard ein = Knopf wird gedrückt. (Jedenfalls bei meinen Tests)

So hab ich's jetzt und es klappt prima, ob es richtig so ist weiß ich nicht aber das Resultat stimmt.
Ich les noch ein wenig bei Emarcadero, aber Beispiele dafür zu finden ist schwer.

Delphi-Quellcode:
procedure TForm1.aplctnvnts1ShortCut(var Msg: TWMKey; var Handled: Boolean);
begin
 if ((Form1.Focused) or (Button1.Focused)) then // nur eingreifen wenn Form oder Knopf aktiv ist
 if Msg.CharCode = Windows.VK_RETURN then      // Taste Return abfangen
 begin
  ZeigeWas;                                    // was soll passieren wenn Return gedrückt wird
  Handled := True;                             // zurück zum Delphi/Windows Tastatur-Handler
 end;
end;

Grüße


Edit:
Danke an alle für Eure Vorschläge und das nun alles bestens funktioniert.
Falls jemand mag/brauch/will, im Anhang überarbeitete version.

Vielen Dank + Thema abgeschlossen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:00 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