Autor Beitrag
g1o2k4
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 493



BeitragVerfasst: Di 31.03.09 17:49 
tag

beim onkeydown event meiner form will ich die gedrückten tasten (speziell die pfeiltasten) auswerten.
es wird auch gemacht, was passieren soll, aber beim pfeiltastendruck verschiebt sich auch je nach pfeiltaste der focus auf verschiedenene buttons in der form, wie kann ich das verhindern ?

ich will einfach, dass beim pfeiltastendruck meine aktion ausgeführt wird sonst nichts. und bei anderen tasten wie zum beispiel buchstaben sollen sie normal im inhalt der form wie zum beispiel einem memo ankommen.


Moderiert von user profile iconNarses: Topic aus Sonstiges (Delphi) verschoben am Di 31.03.2009 um 19:45
JayEff
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2971

Windows Vista Ultimate
D7 Enterprise
BeitragVerfasst: Di 31.03.09 18:14 
Form1.KeyPreview im Objektmanager auf True stellen, dann im onKeyPress Ereigniss deine Behandlung durchführen und falls ein Tastendruck nicht weiterhin bearbeitet werden soll, einfach Key := #0 setzen :zustimm: müsste klappen.

Edit: ... werden Pfeiltasten nicht von KeyPreview abgefangen?? :motz:

Edit: Dreck, das Ereigniss wird bei mir durch Pfeiltasten nur ausgelöst, wenn kein Button den Fokus hat - Der Button selber reagiert nichtmal darauf :evil:

_________________
>+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
g1o2k4 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 493



BeitragVerfasst: Di 31.03.09 20:01 
ja das ist das problem...bei mir wird es immer bei pfeiltasten ausgelöst und selbst wenn das event mit key = ck_up oder sowas, abgearbeitet wurde springt der button focus immer noch durch die gegend.

was auch komisch ist: ich habe das event form1.onkeydown benutzt, um meinen code unterzubringen, aber wenn ich den button einmal runterdrücke und dort halte, wird mein quelltext solange ausgeführt bis ich den button loslasse. warum ist das so ? eigentlich sollte onkeydown doch nur einmal aufgerufen werden wenn der button runtergedrückt wird und nicht wenn er dort bleibt.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 31.03.09 20:05 
user profile icong1o2k4 hat folgendes geschrieben Zum zitierten Posting springen:
eigentlich sollte onkeydown doch nur einmal aufgerufen werden wenn der button runtergedrückt wird und nicht wenn er dort bleibt.
Nein, das ist schon richtig so, du kannst in der Systemsteuerung unter Hardware und Sound --> Tastatur die Wiederholverzögerung und -rate einstellen. Danach wird das Ereignis erneut ausgelöst.
g1o2k4 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 493



BeitragVerfasst: Di 31.03.09 20:28 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
user profile icong1o2k4 hat folgendes geschrieben Zum zitierten Posting springen:
eigentlich sollte onkeydown doch nur einmal aufgerufen werden wenn der button runtergedrückt wird und nicht wenn er dort bleibt.
Nein, das ist schon richtig so, du kannst in der Systemsteuerung unter Hardware und Sound --> Tastatur die Wiederholverzögerung und -rate einstellen. Danach wird das Ereignis erneut ausgelöst.


achso interessant. ich will nämlich, dass zum einen >>einmal<< eine zeile über das was gemacht wird im log erscheint und zum anderen soll über die com schnittstelle ein zeichen gesendet werden. das musste ich so wie unten gezeigt lösen, nämlich durch eine schleife, die dazu dient den code fortlauf aufzuhalten und mein zeichen zu senden, solange der key unten ist....d.h. wenn die schleife fehlt, kommt solange bis ich los lasse eine neue log zeile und das zeichen wird gesendet, dadurch wird das log halt unübersichtlich was ich vermeiden will.
das find ich ziemlich unelegant, wenn jemand eine bessere kürzere methode kennt das problem zu lösen - nur her damit :P

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if (ZylSerialPort.IsConnected <> spNone) and
    (DriveWA.Checked = true) then
  begin
    if Key = VK_UP then
    begin
      Log.Lines.Add('Fahre vorwärts.');
      while GetAsyncKeyState(VK_UP) <> 0 do
      begin
        ZylSerialPort.SendString('f');
      end;
    end
    else if Key = VK_DOWN then
    begin
      Log.Lines.Add('Fahre rückwärts.');
      while GetAsyncKeyState(VK_DOWN) <> 0 do
      begin
        ZylSerialPort.SendString('b');
      end;
    end
....
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 31.03.09 20:31 
Nimm einen Timer und prüfe dort den Tastenstatus nur mit GetAsyncKeyState. ;-)
Den kannst du ja auch mit KeyDown und Up ein- und ausschalten.

Dann hängt dein Programm dabei auch nicht und du hast einen gewissen Einfluss auf die Frequenz (auch wenn ein Timer nicht so besonders genau ist).
g1o2k4 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 493



BeitragVerfasst: Di 31.03.09 20:39 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Nimm einen Timer und prüfe dort den Tastenstatus nur mit GetAsyncKeyState. ;-)
Den kannst du ja auch mit KeyDown und Up ein- und ausschalten.

Dann hängt dein Programm dabei auch nicht und du hast einen gewissen Einfluss auf die Frequenz (auch wenn ein Timer nicht so besonders genau ist).



timer wäre ungünstig, ich brauche mindestens 2400Baud aber mit nem timer bekomm ich maximal 1000.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 31.03.09 20:43 
user profile icong1o2k4 hat folgendes geschrieben Zum zitierten Posting springen:
aber mit nem timer bekomm ich maximal 1000.
Noch deutlich weniger. Wenn es so viele Zeichen pro Sekunde sein müssen, dann kannst du es mit direkten Delphimitteln nur so lösen wie du es hast.
g1o2k4 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 493



BeitragVerfasst: Di 31.03.09 20:47 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
user profile icong1o2k4 hat folgendes geschrieben Zum zitierten Posting springen:
aber mit nem timer bekomm ich maximal 1000.
Noch deutlich weniger. Wenn es so viele Zeichen pro Sekunde sein müssen, dann kannst du es mit direkten Delphimitteln nur so lösen wie du es hast.



schade, ich finde man sollte in delphi ne poperty machen mit der man die aktualisierungsrate bzw das was du sagtest was sich in windows von hand einstellen lässt, ändern kann.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 31.03.09 20:54 
Es ist nun einmal eine Systemeinstellung und es wäre nun einmal keine gute Idee dies einfach irgendwo zu ändern. Als Benutzer stelle ich das ja so ein wie ich es gerne hätte. In allen Programmen.

Gehen tut es ja über SystemParametersInfo. Aber eine derart hohe Geschwindigkeit und niedrige Verzögerung ist sicherlich so nicht möglich. Denn es geht dabei ja um das schreiben von Text und nichts anderes. Alles andere sind Ausnahmen, die man dann wie du lösen muss.

Für Spiele z.B. gibt es ja entsprechende Möglichkeiten via DirectInput, deshalb eben die Einschränkung "mit direkten Delphimitteln".
JayEff
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2971

Windows Vista Ultimate
D7 Enterprise
BeitragVerfasst: Di 31.03.09 21:10 
Wie sieht es mit Application.onIdle mit Done := False aus? Wieviel Baud bekommt man damit maximal, wenn man den Status pollt? Ich wollt mir eben ein Programm schreiben um das zu testen aber hab dabei was falsch gemacht und hab eigentlich nicht die zeit den fehler zu finden :mrgreen:

_________________
>+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 31.03.09 21:15 
Ich komme auf etwa 110.000 im Leerlauf und 9.000 mit Ausgabe auf einem Label. Das wäre also vielleicht eine Möglichkeit.
Lannes
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2352
Erhaltene Danke: 4

Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
BeitragVerfasst: Di 31.03.09 21:57 
Hallo,

ja, die lieben Pfeiltasten, die werden direkt an die Elemente weitergereicht, trotz KeyPreview=True.
Da musst Du Dich einklinken mit einer Kombination aus CMDialogKey abfangen und Form.OnKeyDown benutzen.

Das folgende Beispiel sollte Dir weiterhelfen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
//...
  private
     procedure CMDialogKey(var Message: TCMDialogKey); message CM_DIALOGKEY;
//...
var
  Form1: TForm1;
 
implementation
 
{$R *.DFM}
procedure TForm1.CMDialogKey(var Message: TCMDialogKey);
begin
  with message do begin
    case charcode of
    vk_down: showmessage('Pfeil nach unten');
    else
      inherited;//Standardverhalten sicherstellen
    end;
  end;
end;
 
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key = vk_down then
    showmessage('Pfeil nach unten');
end;
 
end.

_________________
MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )
JayEff
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2971

Windows Vista Ultimate
D7 Enterprise
BeitragVerfasst: Di 31.03.09 22:20 
user profile iconLannes hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden Delphi-Quelltext
1:
message CM_DIALOGKEY;					
:motz: in meinen Experimenten vor dem Post mit onIdle hab ich fieberhaft nach einer Message gesucht, die gesendet wird, wenn die Pfeiltasten gedrückt werden :autsch: Aber MSDN ist ja so vorbildlich sortiert ... :shock: bzw MSDN kennt die Nachricht garnicht. Wo hast du die gefunden? Sämtliche Konstanten in Messages.pas durchgehen kann ja nicht im Sinne des Erfinders sein :|

Hab mir schon überlegt, die wndproc zu überschreiben :lol:

_________________
>+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Di 31.03.09 22:44 
user profile iconJayEff hat folgendes geschrieben Zum zitierten Posting springen:
Aber MSDN ist ja so vorbildlich sortiert ... :shock: bzw MSDN kennt die Nachricht garnicht. Wo hast du die gefunden?
Es handelt sich um eine VCL-interne Botschaft. Diese ist deshalb auch nicht in Messages.pas sondern in Controls.pas deklariert.
Diese senden die delphiinternen Routinen, wenn eine Botschaft mit einem entsprechenden Tastendruck empfangen wird, die auch OnKeyDown ggf. auslösen.
JayEff
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2971

Windows Vista Ultimate
D7 Enterprise
BeitragVerfasst: Mi 01.04.09 00:30 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Es handelt sich um eine VCL-interne Botschaft. Diese ist deshalb auch nicht in Messages.pas sondern in Controls.pas deklariert.
Diese senden die delphiinternen Routinen, wenn eine Botschaft mit einem entsprechenden Tastendruck empfangen wird, die auch OnKeyDown ggf. auslösen.
Interessant. Und wie findet man sowas raus? :(

_________________
>+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 01.04.09 00:38 
Zum Beispiel indem man sich die VCL-Quelltexte anschaut, die sind ja bei Delphi dabei (außer bei den Trials und PEs). Auch bei Turbo Delphi, man kann sich diese also auch kostenlos anschauen.

Der Quelltext insgesamt ist auch recht interessant, deshalb blättere ich da ganz gerne mal drin. Auch jetzt im Hinblick auf XStyleForm, denn einiges an den Interna hat sich in den letzten Versionen grundlegend geändert. Teilweise wegen den vielen neuen Features, teilweise wegen Vista, ...

Und dann gibt es Seiten wie diese, auf denen viele Botschaften aufgelistet sind:
mh-nexus.de/en/delphimessages.php
JayEff
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2971

Windows Vista Ultimate
D7 Enterprise
BeitragVerfasst: Mi 01.04.09 00:43 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Und dann gibt es Seiten wie diese, auf denen viele Botschaften aufgelistet sind:
mh-nexus.de/en/delphimessages.php
:zustimm: Danke!

_________________
>+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
g1o2k4 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 493



BeitragVerfasst: Do 02.04.09 01:02 
danke für die tips!
aber ich glaube für ein privates testprogramm ist mir das jetzt zuviel arbeit es perfekt zu machen.
ich werde es vorerst so lassen wie ich es oben beschrieben habe. für alle die dasselbe problem haben und ne grobe lösung brauchen:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
//Form1.KeyPreview auf true setzen
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if (ZylSerialPort.IsConnected <> spNone) and
    (DriveWA.Checked = true) then
  begin
    if Key = VK_UP then
    begin
      Log.Lines.Add('Fahre vorwärts.');
      while GetAsyncKeyState(VK_UP) <> 0 do
      begin
        ZylSerialPort.SendString('f');
      end;
    end
    else if Key = VK_DOWN then
    begin
      Log.Lines.Add('Fahre rückwärts.');
      while GetAsyncKeyState(VK_DOWN) <> 0 do
      begin
        ZylSerialPort.SendString('b');
      end;
    end
    else if Key = VK_LEFT then
    begin
      Log.Lines.Add('Fahre links.');
      while GetAsyncKeyState(VK_LEFT) <> 0 do
      begin
        ZylSerialPort.SendString('l');
      end;
    end
    else if Key = VK_RIGHT then
    begin
      Log.Lines.Add('Fahre rechts.');
      while GetAsyncKeyState(VK_RIGHT) <> 0 do
      begin
        ZylSerialPort.SendString('r');
      end;
    end;
  end
  else if (DriveWA.Checked = true) then
  begin
    Log.Lines.Add('Es ist keine serielle Verbindung geöffnet.');
    while GetAsyncKeyState(Key) <> 0 do //Abfangschleife, da sonst das
      ; //Event immer wieder ausgeführt wird
  end;
end;


komisch find ich nur dass ab und zu, also nicht jedesmal, beim loslassen der taste anscheinend die ganze procedure noch einmal ausgeführt wird, d.h. hier bekommt man pro tastendruck 1-2 lines im memo.

aber meinen asuro stört es zum glück nicht, sondern er fährt schön nach den gedrückten pfeiltasten ;P