AGB  ·  Datenschutz  ·  Impressum  







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

Shift + NumPadX erkennen

Ein Thema von Amateurprofi · begonnen am 31. Jul 2018 · letzter Beitrag vom 23. Aug 2018
Antwort Antwort
Seite 1 von 2  1 2      
Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.064 Beiträge
 
Delphi XE2 Professional
 
#1

Shift + NumPadX erkennen

  Alt 31. Jul 2018, 18:07
Ich möchte (in FormShortcut) auf alle Tasten, die irgendein Zeichen repräsentieren, reagieren und irgendwelche Aktionen auslösen.
Ich möchte auch unterscheiden können, ob gleichzeitig die Shift-Taste gedrückt ist, oder nicht.

Bei den Tasten des Ziffernblocks macht das Probleme weil zum Beispiel bei Shift+NumPad1 nicht etwa NumPad1 als gedrückt gemeldet wird, sondern VK_End.

Mein Ausweg für Helden ist, mit GetKeyboardState den Status aller Tasten zu holen und auszuwerten.

Zu meiner Überraschung liefert GetKeyboardState teils Informationen die (meine Meinung) nicht viel mit der Realität (oder mit dem, was ich für Realität halte) zu tun hat.

Um herauszufinden, was GetKeyboardState liefert habe ich TKeyBoardState in Form einer Matrix ausgegeben, zunächst wenn Shift+NumPad1 gedrückt ist und dann, wenn End gedrückt ist und fand für folgende VK_XX die folgenden Werte.

Die Ergebnisse:
In beiden Fällen ist TKeyBoardState[VK_End] = $81, als gedrückt.
Unterschiedlich waren:
VK_LButton ( 1 bei Shift+1, 0 bei End)
VK_RButton ( 0 bei Shift+1, 1 bei End)
VK_Menu ( 1 bei Shift+1, 0 bei End)
VK_RMENU ( 0 bei Shift+1, 1 bei End)

Meine Lösung (für Shift+NumPad1) ist, dann wenn VK_End gedrückt ist, ist in TKeyBoardState zu prüfen ob bei VK_LBUTTON eine 1 steht oder nicht.
Ist da eine 1 dann interpretiere ich das so, dass Shift+NumPad1 gedrückt sind.
Analog mache ich das für NumPad2 bis 6 (andere Numpad-Tasten brauche ich nicht).
Das funktioniert, aber ich weiß nicht warum und ich weiß auch nicht, ob das nur bei mir so ist.

Nach langer Darstellung was ich mache die Frage:

Weiß jemand eine elegantere Lösung?

Code:
             Shift-1  End
01   1  VK_LBUTTON   1      0
02   2  VK_RBUTTON   0      1
08   8  VK_BACK      1      1
09   9  VK_TAB       1      1
0D 13  VK_RETURN    1      1
10  16  VK_SHIFT     1      1
12  18  VK_MENU      1      0
23  35  VK_END      81     81
24  36  VK_HOME      1      1
5B 91  VK_LWIN      1      1
5C 92  VK_RWIN      1      1
90 144  VK_NUMLOCK   1      1
A0 160  VK_LSHIFT    1      1
A2 162  VK_LCONTROL  1      1
A3 163  VK_RCONTROL  1      1
A4 164  VK_LMENU     1      1
A5 165  VK_RMENU     0      1
F0 240                1      1
F3 243                1      1
F6 246                1      1
FB 251  VK_ZOOM      1      1
TKeyBoardState, wenn Shift + Numpad1 gedrückt sind.

Code:
    0  1  2  3  4  5  6  7  8  9  A B C D E F
    -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
00  00 01 00 00 00 00 00 00 01 01 00 00 00 01 00 00
10  01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00
20  00 00 00 81 01 00 00 00 00 00 00 00 00 00 00 00
30  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
40  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
50  00 00 00 00 00 00 00 00 00 00 00 01 01 00 00 00
60  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90  01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
A0  01 00 01 01 01 00 00 00 00 00 00 00 00 00 00 00
B0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
C0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
D0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
E0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
F0  01 00 00 01 00 00 01 00 00 00 00 01 00 00 00 00
Delphi-Quellcode:
procedure TMain.FormShortCut(var Msg: TWMKey; var Handled: Boolean);
var Key:Word; Shift:TShiftState;
//------------------------------------------------------------------------------
FUNCTION GetKeyCode:Boolean;
begin
   Key:=Msg.CharCode;
   if Key in [VK_Shift,VK_Control,VK_Menu] then Exit(False); // Nur Shift, Ctrl, Alt
   Shift:=[ssShift,ssCtrl,ssAlt]*KeyDataToShiftState(Msg.KeyData);
   Result:=True;
end;
//------------------------------------------------------------------------------
FUNCTION HandlePianoKey:Boolean;
var Index:Integer; Tone:Byte; KeyState:TKeyBoardState;
begin
   Result:=(ActiveControl<>reEditor) and (Shift*[ssCtrl,ssAlt]=[]) and (Key<=$FF);
   if Result then begin
      if Key in [VK_End,VK_Down,VK_Next,VK_Left,VK_Clear,VK_Right] then begin
         GetKeyboardState(KeyState);
         if KeyState[VK_LButton]=1 then begin
            case Key of
               VK_End : Key:=VK_NumPad1;
               VK_Down : Key:=VK_NumPad2;
               VK_Next : Key:=VK_NumPad3;
               VK_Left : Key:=VK_NumPad4;
               VK_Clear : Key:=VK_NumPad5;
               VK_Right : Key:=VK_NumPad6;
               else Exit(False);
            end;
            Shift:=[ssShift];
         end;
      end;
      Index:=KeyToToneIndex[Key];
      if Index<Length(KeyToTone) then
         with KeyToTone[Index] do begin
            if Shift=[] then Tone:=Tone1 else Tone:=Tone2;
            PianoPlayTone(Tone);
            Exit;
         end;
   end;
   Result:=False;
end;
//------------------------------------------------------------------------------
//PROCEDURE StoreKeyStates;
//var I:Integer; KeyState:TKeyBoardState; S:String;
//begin
// GetKeyboardState(KeyState);
// S:=' 0 1 2 3 4 5 6 7 8 9 A B C D E F'#13#10+
// ' -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --'#13#10;
// for I:=0 to High(KeyState) do begin
// if I and 15=0 then S:=S+IntToHex(I and $F0,2)+' ';
// S:=S+IntToHex(KeyState[I],2)+' ';
// if I and 15=15 then S:=S+#13#10;
// end;
// ClipBoard.AsText:=S;
//end;
//------------------------------------------------------------------------------
begin {FormShortCut}
   Handled:=GetKeyCode;
   if not Handled then Exit; // war nur Shift, Ctrl, Alt
// StoreKeyStates;
   ...
   ...
   if HandlePianoKey then Exit;
   Handled:=False;
end; {FormShortCut}
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.490 Beiträge
 
Delphi 7 Professional
 
#2

AW: Shift + NumPadX erkennen

  Alt 31. Jul 2018, 18:39
Frage, was hast Du vor?

Um auf Tastendrücke zu reagieren setze ich KeyPreview des Forms auf True und fülle OnKeyUp mit Leben.

Da kann man Key (Word) (also z. B. die $81) und Shift (TShiftState) abfragen. Man bekommt beides als Parameter in die Ereignisroutine geliefert.
procedure TForm.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); Man kann dann in Shift abfragen, ob Strg, Alt oder Shift oder auch 'ne beliebige Kombination daraus betätigt wurde, in Key steht der nummerische Wert der Taste. Kann man dann mit VK_wieauchimmer vergleichen ...

Wäre das 'ne Alternative oder hast Du weiterreichende Anforderungen, die in dem Ereignis nicht umzusetzen sind?
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.275 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: Shift + NumPadX erkennen

  Alt 31. Jul 2018, 19:23
Hallo,
kennt Du das hier schon?
Das geht doch in Deine Richtung.

https://social.msdn.microsoft.com/Fo...rum=vblanguage
Heiko
  Mit Zitat antworten Zitat
Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.064 Beiträge
 
Delphi XE2 Professional
 
#4

AW: Shift + NumPadX erkennen

  Alt 31. Jul 2018, 19:42
Frage, was hast Du vor?

Um auf Tastendrücke zu reagieren setze ich KeyPreview des Forms auf True und fülle OnKeyUp mit Leben.

Da kann man Key (Word) (also z. B. die $81) und Shift (TShiftState) abfragen. Man bekommt beides als Parameter in die Ereignisroutine geliefert.
procedure TForm.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); Man kann dann in Shift abfragen, ob Strg, Alt oder Shift oder auch 'ne beliebige Kombination daraus betätigt wurde, in Key steht der nummerische Wert der Taste. Kann man dann mit VK_wieauchimmer vergleichen ...

Wäre das 'ne Alternative oder hast Du weiterreichende Anforderungen, die in dem Ereignis nicht umzusetzen sind?
Was ich wollte?:
Ich schriebs explizit: Auf z.B. NumPad1 reagieren und unterscheiden können, ob die Shift-Taste gleichzeitig gedrückt ist.


Und genau das funktioniert nicht mit FormKeyUp.
Wenn du NumPad1 drückst, wird im FormKeyUp korrekt als Key $61 geliefert und not (ssShift in Shift).
Aber wenn du Shift+NumPad1 drückst wird im FormKeyUp als Key $23 = 35 = VK_End und ebenfalls not (ssShift in Shift) geliefert.
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.064 Beiträge
 
Delphi XE2 Professional
 
#5

AW: Shift + NumPadX erkennen

  Alt 31. Jul 2018, 19:50
Hallo,
kennt Du das hier schon?
Das geht doch in Deine Richtung.

https://social.msdn.microsoft.com/Fo...rum=vblanguage
Auch das funktioniert nicht.
Drücke ich NUR NumPad1 funktioniert das; klar.
Aber drücke ich Shift + Numpad1 wird als Key VK_End geliefert UND Shift NICHT gedrückt.
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Shift + NumPadX erkennen

  Alt 31. Jul 2018, 20:16
Wie sah Dein Code mit procedure TForm.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); aus?

Ps: Kann es sein das Du das eventuell mit Num-Lock Abfrage realisieren musst?
Gruß vom KodeZwerg

Geändert von KodeZwerg (31. Jul 2018 um 20:18 Uhr)
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.490 Beiträge
 
Delphi 7 Professional
 
#7

AW: Shift + NumPadX erkennen

  Alt 31. Jul 2018, 20:17
Meine Frage "Frage, was hast Du vor?" zielte daraufhin, welche Aufgabe mit dem Erkennen von den Tastaturdruckkombinationen erreicht werden soll. Das beim Druck von Shift+NumPad1 eben genau diese Kombination festgestellt werden soll, ist schon klar.

Habe mal ein bisserl rumprobiert:

Beim Drücken von Strg und/oder Alt plus einer NumPad-Taste bekommt man die entsprechende Info. Ob man dabei Shift betätigt oder nicht, ändert nichts am Ergebnis. Shift ist nie dabei.

Wenn man nun aber Numlock ausschaltet, dann erfährt man auch, ob Shift in der Tastenkombination plus einer NumPad-Taste dabei ist.

Meine Googlelitis brachte auch nix zum Vorschein, außer: Du bist nicht alleine mit diesem Problem.
  Mit Zitat antworten Zitat
Redeemer
Online

Registriert seit: 19. Jan 2009
Ort: Kirchlinteln (LK Verden)
1.051 Beiträge
 
Delphi 2009 Professional
 
#8

AW: Shift + NumPadX erkennen

  Alt 31. Jul 2018, 20:55
Ich weiß ja nicht, was du machst, aber das hier funktioniert problemlos bei mir und das ist auch, wie man TShortcutEvent verwendet:
Delphi-Quellcode:
procedure TollesEvent(var Msg: TWMKey; var Handled: Boolean);
var
  ss: TShiftState;
begin
  ss := KeyDataToShiftState(Msg.KeyData);
  if ss = [ssShift] then
  if Msg.Charcode = VK_NUMPAD0 then // =96
  TueTolleSachen();
end;
Wenn man nicht weiß, was eigentlich los ist:
Delphi-Quellcode:
uses Menus;

procedure TollesEvent(var Msg: TWMKey; var Handled: Boolean);
var
  ss: TShiftState;
begin
  ss := KeyDataToShiftState(Msg.KeyData);
  Caption := IfThen(ssCtrl in ss, 'Strg+')
           + IfThen(ssShift in ss, 'Umsch+')
           + IfThen(ssAlt in ss, 'Alt+')
           + ShortCutToText(Msg.CharCode) + '/'
           + IntToStr(Msg.CharCode);
end;
Janni
2005 PE, 2009 PA, XE2 PA
  Mit Zitat antworten Zitat
Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.064 Beiträge
 
Delphi XE2 Professional
 
#9

AW: Shift + NumPadX erkennen

  Alt 31. Jul 2018, 21:02
Wie sah Dein Code mit procedure TForm.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); aus?

Ps: Kann es sein das Du das eventuell mit Num-Lock Abfrage realisieren musst?
Delphi-Quellcode:
procedure TMain.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
   Info(piInfo,IntToHex(Key,2)+' '+IntToStr(Ord(ssShift in Shift)));
end;
"Info" ist eine meiner Standard-Prozeduren, die einen Text in dem durch den ersten Parameter definierten Panel der Statusbar ausgibt.

NumLock ist na klar "down".
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.064 Beiträge
 
Delphi XE2 Professional
 
#10

AW: Shift + NumPadX erkennen

  Alt 31. Jul 2018, 21:16
Ich weiß ja nicht, was du machst, aber das hier funktioniert problemlos bei mir und das ist auch, wie man TShortcutEvent verwendet:
Delphi-Quellcode:
procedure TollesEvent(var Msg: TWMKey; var Handled: Boolean);
var
  ss: TShiftState;
begin
  ss := KeyDataToShiftState(Msg.KeyData);
  if ss = [ssShift] then
  if Msg.Charcode = VK_NUMPAD0 then // =96
  TueTolleSachen();
end;
Wenn man nicht weiß, was eigentlich los ist:
Delphi-Quellcode:
uses Menus;

procedure TollesEvent(var Msg: TWMKey; var Handled: Boolean);
var
  ss: TShiftState;
begin
  ss := KeyDataToShiftState(Msg.KeyData);
  Caption := IfThen(ssCtrl in ss, 'Strg+')
           + IfThen(ssShift in ss, 'Umsch+')
           + IfThen(ssAlt in ss, 'Alt+')
           + ShortCutToText(Msg.CharCode) + '/'
           + IntToStr(Msg.CharCode);
end;
Ich vermute "TollesEvent" ist "FormShortCut"
Hab deinen Code im FormShortCut unverändert eingefügt - und funktioniert nicht (bei Shift + NumPadX)
Unter "funktioniert" verstehe ich, um bei deinem erstgenannten Code zu bleiben, dass die Prozedur TueTolleSachen() ausgeführt wird, wenn ich Shift + Numpad1 (bei deinem Beispiel NumPad0) drücke.

Falls es dir entgangen ist:
So ziemlich genau das, was du vorschlägst mach ich in dem in #1 gezeigten FormShortcut.
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 12:35 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