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}