Hallo,
ich habe ein Problem zu lösen und komme nicht weiter.
Es geht darum, dass ich Tastatur / Maus Daten abfangen will. Das habe ich sowohl mit Hooks als auch mit Raw Input probiert und auch gelöst bekommen, bzw Programmcode gefunden der mir dabei hilft.
Ich kann außerdem ermitteln von welcher Maus/Tastatur die Eingabe kommt. Wenn jeweils zwei an den Pc angeschlossen sind.
Ich muss nun nur noch lösen, wie ich die Daten abfange, sodass sie nicht ausgegebn werden. Also tippt der Benutzer ein a auf der Tastatur dann soll diese nicht ausgegeben werden, das aber Systemweit. ich habe folgende Lösung für ein Fenster:
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Text;
namespace KeyboardInput
{
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")]
class Form1 : Form
{
// The following Windows message value is defined in Winuser.h.
private int WM_KEYDOWN = 0x100;
CustomTextBox CustomTextBox1 = new CustomTextBox();
[STAThread]
public static void Main()
{
Application.EnableVisualStyles();
Application.Run(new Form1());
}
public Form1()
{
this.AutoSize = true;
this.Controls.Add(CustomTextBox1);
CustomTextBox1.KeyPress +=
new KeyPressEventHandler(CustomTextBox1_KeyPress);
}
// Consume and modify several character keys.
void CustomTextBox1_KeyPress(object sender, KeyPressEventArgs e)
{
switch (e.KeyChar)
{
// Consume 'A' and 'a'.
case (char)65:
case (char)97:
Console.WriteLine("Control.KeyPress: '" +
e.KeyChar.ToString() + "' consumed.");
e.Handled = true;
break;
// Detect 'B', modify it to 'A', and forward the key.
case (char)66:
Console.WriteLine("Control.KeyPress: '" +
e.KeyChar.ToString() + "' replaced by 'A'.");
//e.KeyChar = (char)65;
e.Handled = true;
break;
// Detect 'b', modify it to 'a', and forward the key.
case (char)98:
Console.WriteLine("Control.KeyPress: '" +
e.KeyChar.ToString() + "' replaced by 'a'.");
//e.KeyChar = (char)97;
//True = Key geblockt!
e.Handled = true;
break;
default:
Console.WriteLine("Standard Fall");
e.Handled = true;
break;
}
}
}
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")]
public class CustomTextBox : TextBox
{
// The following Windows message value is defined in Winuser.h.
private int WM_KEYDOWN = 0x100;
public CustomTextBox()
{
this.Size = new Size(100, 100);
this.AutoSize = false;
}
// Detect F1 through F9 during preprocessing and modify F3.
public override bool PreProcessMessage(ref Message m)
{
if (m.Msg == WM_KEYDOWN)
{
Keys keyCode = (Keys)m.WParam & Keys.KeyCode;
// Detect F1 through F9.
switch (keyCode)
{
case Keys.F1:
case Keys.F2:
case Keys.F3:
case Keys.F4:
case Keys.F5:
case Keys.F6:
case Keys.F7:
case Keys.F8:
case Keys.F9:
MessageBox.Show("Control.PreProcessMessage: '" +
keyCode.ToString() + "' pressed.");
// Replace F3 with F1, so that ProcessKeyMessage will
// receive F1 instead of F3.
if (keyCode == Keys.F3)
{
m.WParam = (IntPtr)Keys.F1;
MessageBox.Show("Control.PreProcessMessage: '" +
keyCode.ToString() + "' replaced by F1.");
}
break;
}
}
// Send all other messages to the base method.
return base.PreProcessMessage(ref m);
}
// Detect F1 through F9 during processing.
protected override bool ProcessKeyMessage(ref Message m)
{
if (m.Msg == WM_KEYDOWN)
{
Keys keyCode = (Keys)m.WParam & Keys.KeyCode;
// Detect F1 through F9.
switch (keyCode)
{
case Keys.F1:
case Keys.F2:
case Keys.F3:
case Keys.F4:
case Keys.F5:
case Keys.F6:
case Keys.F7:
case Keys.F8:
case Keys.F9:
MessageBox.Show("Control.ProcessKeyMessage: '" +
keyCode.ToString() + "' pressed.");
break;
}
}
// Send all messages to the base method.
return base.ProcessKeyMessage(ref m);
}
}
}
Das funktioniert wunderbar, aber ich brauche das nicht nur für ein spezielles Fenster!! Sondern egal für welches. Also ich starte mein Programm und egal ob im Browser oder im Editor das abfangen soll funktionieren.
Ich muss also irgendwie die Anweisung
CustomTextBox1.KeyPress +=
new KeyPressEventHandler(CustomTextBox1_KeyPress);
nicht nur an das Fenster "CustomTextBox" binden sondern irgendwie Systemweit.
Ein erster ansatz von mir war mit "GetForegroundWindow()" das aktuelle Fenster zu ermitteln. Aber wie hänge ich daran den KeyPressHandler?
Weiß jemand Rat? Bitte mit einem Codebeispiel wenn es geht, da ich C# Einsteiger bin würde mir das leichter beim Verständniss helfen.
Vielen Dank
Torwald
Wie du schon geschrieben hast, geht das nur mit einem "System Hook". Da könnte dir dann diese Komponente helfen: Globale Hooks mit c# (nichtnur lowlevel)
Hallo,
Danke für die rasche Antwort.
Also es ist aber prinzipiell möglich?
Um mal genauer zu werden sollte ich mal erläutern was ich überhaupt lösen möchte / muss.
Also:
An einem Pc sollen 2 Tastaturen, 2 Mäuse und 2 Monitore angeschlossen werden. Also sozusagen zwei getrennte Terminals. Wenn an Terminal 1 gearbeitet wird soll Terminal 2 gesperrt sein. Solange bis Terminal 1 5sec lang keine Eingabe gemacht hat.
Gelöst habe ich das Problem Tatstaturen und Mäuse zu unterscheiden und sämtliche Eingaben also einem genauen Gerät zuzuordnen. Mein einziges Problem besteht nun darin, das ich ein terminal deaktivieren muss, bzw die Eingaben abfangen und nicht durchlassen!!!
Oder hast Du vielleicht eine andere Idee wie ich ein Terminal deaktivieren kann.
Mein anderer ansatz ist daran gescheitert, das ich mit Hilfe von "devcon" zwar die Maus deaktivieren kann, aber aus welchem Grund auch immer die Tastatur leider nicht!
Torwald
kann man nicht iwie programmatisch einen Usb-Eingang zumachen?
Der frühe Apfel fängt den Wurm.
Hallo,
ja das war auch mein erster Gedanke und das wäre meiner Meinung nach die beste Möglichkeit, hab nur leider bisher keine Lösung gefunden. Vielleicht mit einem FilterTreiber? Oder sowas in der Art, jedenfalls glaube ich das es mit Hilfe der Win32 API nicht möglich ist.
Vielleicht kennt ja jemand eine Möglichkeit
Hallo,
nein nicht brauchbar, da ich zwei tastaturen und Mäuse am Pc habe aber nur jeweils ein Gerät soll deaktiviert sein.
Bei Block Input werden alle Geräte deaktiviert soweit ich weiß!
Schönen Gruß