Hallo ihr.
Ich habe drei Probleme beim Handling von vom Benutzer gedrückten Tasten:
1.: Wie kann ich unterscheiden, ob die rechte oder die linke Control-Taste gedrückt wurde? Das gleiche betrifft die ALT-Tasten.
Das klingt erstmal simpel, aber ich zerbreche mir echt den Kopf drüber.
Ich habe zwar einen Ansatz und bin auch schon recht weit, aber um euch nicht zu beeinflussen, will ich den noch zurückhalten. Vielleicht bin ich ja voll auf dem Holzweg...
2.: Wie bringe ich mein Programm dazu zu verhindern, dass Windows beim Druck auf die linke oder rechte Windows-Taste das Startmenü zeigt?
3.: Wie kann ich die Print-Taste (bei der Windows einen Screenshot macht) abfangen?
Vielen Dank und liebe Grüße, _void
Hallo _void,
zu 1: Das musst du dir merken (oder DirectInput verwenden) - wobei das Merken deutlich einfacher ist.
zu 2. + 3.: Da helfen meiner Ansicht nach nur Globale Hooks - die Forumssuche sollte da einige Ergebnisse dazu liefern.
Hi winSharp93. Die Antwort kam schneller als ich dachte. Danke.
Ja, an Hooks hatte ich auch schon gedacht. Und die PrintScreen-Taste kriege ich wirklich wenn ich die WH_KEYBOARD_LL hooke. Ist zwar etwas umständlich, aber geht.
Die Windows-Taste kriege ich aber nicht unterdrückt. Vielleicht mangelt es mir aber an der Stelle auch am entsprechenden Skill.
Aber das mit dem Merken der Control-Keys habe ich nicht verstanden... Was genau soll ich mir da merken?
_Original von void
Was genau soll ich mir da merken?
In KeyDown und KeyUp wird in den EventArgs mitgeteilt, welche Shifttaste gedrückt, bzw. losgelassen wurde.
Mir geht es nicht um die Shifttasten, sondern um die Control- und die ALT-Tasten.
Allerdings gibt es auch bei den Shifttasten keine Unterschiede bei den in den KeyEventArgs enthaltenen Properties. Oder ich sehe sie nicht, bitte zeig mir, welche du meinst.
Die Shifttasten sind aber eher deswegen kein Problem, weil die beiden Tasten verschiedene Scancodes haben. Die Control- und ALT-Tasten haben dummerweise die gleichen Scancodes und entziehen sich somit einer genaueren Unterscheidung.
Oh, Entschuldigung. Ich hatte damit gerechnet, dass Keys.RMenu bzw. Keys.RControlKey auch tatsächlich in den EventaArgs übergeben werden, wenn sie gedrückt werden.
Ich habe mich aus Interesse etwas mit DirectInput beschäftigt, vielleicht hilft dir dieser Quick&Dirty Code weiter:
public class KeyboardInput
{
private Microsoft.DirectX.DirectInput.Device device;
private AutoResetEvent resetEvent = new AutoResetEvent(false);
public KeyboardInput(Control c)
{
if (c == null)
throw new ArgumentNullException();
if (c.Handle == IntPtr.Zero)
throw new ArgumentOutOfRangeException();
this.device = new Microsoft.DirectX.DirectInput.Device(Microsoft.DirectX.DirectInput.SystemGuid.Keyboard);
this.device.SetCooperativeLevel(c, Microsoft.DirectX.DirectInput.CooperativeLevelFlags.Background | Microsoft.DirectX.DirectInput.CooperativeLevelFlags.NonExclusive);
this.device.SetEventNotification(resetEvent);
Thread t = new Thread(new ThreadStart(loop));
t.Start();
}
private void loop()
{
try
{
device.Acquire();
while (true)
{
AutoResetEvent.WaitAny(new WaitHandle[] { resetEvent });
Microsoft.DirectX.DirectInput.Key[] keys = device.GetPressedKeys();
foreach (Microsoft.DirectX.DirectInput.Key k in keys)
{
Debug.Print(k.ToString());
}
}
}
finally
{
device.Unacquire();
device.Dispose();
}
}
}
Er funktioniert soweit, dass, nachdem man ein neues KeyboardInput erstellt hat, alle Tasten, die gedrückt werden, in die Ausgabe geschrieben werden.
Hi.
Hm... eigentlich wollte ich das nicht über DirectInput machen, aber ich habe mich da mal ein bisschen eingelesen und gemerkt, dass es doch schon Vorteile birgt.
Vielen Dank für den Code, ist bestimmt eine gute Starthilfe.
_void
edit:
hm... bei mir kommt immer die Fehlermeldung
LoaderLock wurde erkannt.
Message: Die DLL "C:\WINDOWS\assembly\GAC\Microsoft.DirectX\1.0.2902.0__31bf3856ad364e35\Microsoft.DirectX.dll" unternimmt einen Versuch,
innerhalb der Sperre für den OS-Loader eine verwaltete Ausführung durchzuführen.
Versuchen Sie nicht, verwalteten Code innerhalb einer DllMain- oder Bildinitialisierungsfunktion auszuführen,
da dies ein Hängen der Anwendung zur Folge haben kann.
Hattest du die auch, bzw. weißt du, was das ist und wie man das wegkriegt?
Das mit dem LoaderLock kam bei mir auch - ist aber anscheinend nicht so tragisch (wird vom Debugger verursacht):
loaderLock wurde erkannt
Befehl lässt sich wegen "loaderlock" nicht ausführen
_Original von void
Die Control- und ALT-Tasten haben dummerweise die gleichen Scancodes und entziehen sich somit einer genaueren Unterscheidung.
Hi, stimmt und leider ist die Implementierung der VirtualKeyCodes[1] in Net3.0 noch Buggy (Debug u. Release). Damit kann man vorläufig nicht wirklich arbeiten. Ergo, bedient man sich alt Bewährtem: Mindestens eine der API Funktioen: GetKeyboardState, SetKeyboardState, GetAsyncKeyState, GetKeyState, MapVirtualKey und MapVirtualKeyEx sollte eine Abfrage/Ermittlung von VK_RCONTROL, VK_RCONTROL, VK_LMENU und VK_RMENU ermöglichen.
Das ist kein Versuch dich von DirectX abzubringen, sondern nur eine Ergänzung des bisher diskutiertem. 🙂
HTH sarabande
[1]VirtualKeyCodes != ScanCodes