Benutzer mit den meisten Antworten
C#, user32.dll, globale Hotkeys

Frage
-
Als C# Anfänger habe ich mit der Hilfe von Lektüre und dem Internet ein Programm geschrieben, dass die Tastenanschläge des Benutzer in einem Fenster anzeigt. Nun habe ich allerdings 3 Dinge bei denen ich einfach nicht dahinter komme.
- Das Schwerwiegendste Problem, ist das er zwar die ausgewählten Tasten erkennt, allerdings diese auch dem System stiehlt. Wenn man schnell genug hintereinander (zb W) drückt, dann bekommt auch das Windows 7 ein paar Tasteninfos ab.
- Gibt es einen Weg, ohne alles X-mal hineinschreiben zu müssen, dass man auch Anschläge von 2, 3,.. Tasten gleichzeitig erkennt und anzeigt?
- Ich schaffe es einfach nicht, dass das Fenster nicht in den Fokus gerät. Es soll so sein, dass im Hintergrund ein Spiel läuft und das Programm im Vordergrund läuft. Leider "verläuft" sich die Maus ständig und das Fenster bekommt den Focus. Wie schaffe ich es, dass das Fenster nicht mehr wählbar ist? Bzw. dass es nur durch eine Funktionstaste wieder wählbar ist?
Das Programm ist eine Windows Form Application.
(Als Inspiration zu den Globalen Hotkeys, hat mir dieses Tutorial geholfen: http://social.technet.microsoft.com/wiki/contents/articles/30568.wpf-implementing-global-hot-keys.aspx)
Genug der Worte, hier der Code:
using System; using System.Drawing; using System.Windows.Forms; using System.Windows; using System.Runtime.InteropServices; namespace WASD { public partial class Form1 : Form { public Form1() { InitializeComponent(); //Set time for showing messages in label timer1.Interval = 400; } //// The window should not be in focus but didn't work //protected override void DefWndProc(ref Message m) //{ // const int WM_MOUSEACTIVATE = 0x21; // const int MA_NOACTIVATE = 0x0003; // switch (m.Msg) // { // case WM_MOUSEACTIVATE: // m.Result = (IntPtr)MA_NOACTIVATE; // return; // } // base.DefWndProc(ref m); //} //Invoke global hotkey (unmanaged code) [DllImport("user32.dll")] public static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc); [DllImport("user32.dll")] public static extern bool UnregisterHotKey(IntPtr hWnd, int id); //Modifiers private const int MOD_NONE = 0x0000; private const int MOD_SHIFT = 0x0004; private const int MOD_CONTROL = 0x0002; //Intercept input hotkey private const int WM_HOTKEY = 0x0312; //Creating the Rectangle private PictureBox pictureBox1 = new PictureBox(); private bool wPressed = false; private bool aPressed = false; private bool sPressed = false; private bool dPressed = false; private bool qPressed = false; private bool ePressed = false; private void Form1_Load(object sender, EventArgs e) { //Register global hotkeys. DON'T forget to unregister OnClosing // w RegisterHotKey(this.Handle, 1, MOD_NONE, (int)Keys.W); // a RegisterHotKey(this.Handle, 2, MOD_NONE, (int)Keys.A); // s RegisterHotKey(this.Handle, 3, MOD_NONE, (int)Keys.S); // d RegisterHotKey(this.Handle, 4, MOD_NONE, (int)Keys.D); // q RegisterHotKey(this.Handle, 5, MOD_NONE, (int)Keys.Q); // e RegisterHotKey(this.Handle, 6, MOD_NONE, (int)Keys.E); // W RegisterHotKey(this.Handle, 7, MOD_SHIFT, (int)Keys.W); // A RegisterHotKey(this.Handle, 8, MOD_SHIFT, (int)Keys.A); // S RegisterHotKey(this.Handle, 9, MOD_SHIFT, (int)Keys.S); // D RegisterHotKey(this.Handle, 10, MOD_SHIFT, (int)Keys.D); // Q RegisterHotKey(this.Handle, 11, MOD_SHIFT, (int)Keys.Q); // E RegisterHotKey(this.Handle, 12, MOD_SHIFT, (int)Keys.E); // F7 RegisterHotKey(this.Handle, 13, MOD_NONE, (int)Keys.F7); // F8 RegisterHotKey(this.Handle, 14, MOD_NONE, (int)Keys.F8); // F9 RegisterHotKey(this.Handle, 15, MOD_NONE, (int)Keys.F9); // F10 RegisterHotKey(this.Handle, 16, MOD_NONE, (int)Keys.F10); //Dock the PictureBox to the form pictureBox1.Dock = DockStyle.Fill; //Set background color pictureBox1.BackColor = Color.White; pictureBox1.Paint += DrawRectangle; //Add the PictureBox control to the form this.Controls.Add(pictureBox1); } protected override void WndProc(ref Message m) { wPressed = false; aPressed = false; sPressed = false; dPressed = false; qPressed = false; ePressed = false; if (m.Msg == WM_HOTKEY) { switch ((int)m.WParam) { // If pressed w or W case 1: case 7: wPressed = true; break; // If pressed a or A case 2: case 8: aPressed = true; break; // If pressed s or S case 3: case 9: sPressed = true; break; // If pressed d or D case 4: case 10: dPressed = true; break; // If pressed q or Q case 5: case 11: qPressed = true; break; // If pressed e or E case 6: case 12: ePressed = true; break; // If pressed F7 case 13: MessageBox.Show(@"Info: F7 - Show this help F8 - Hide or show title F9 - Dock window to top F10 - Prevent window beeing in focus Version: 0.2.0"); break; // If pressed F8 case 14: HideOrShowTitle(); break; // IF pressed F9 case 15: DockOrUndockWindowOnTop(); break; // IF pressed F10 then never let the window get focus case 16: break; // When pressed other keys - TODO not working default: lblMessage.Text = "asdasd"; timer1.Enabled = true; timer1.Start(); break; } } pictureBox1.Refresh(); base.WndProc(ref m); } private void HideOrShowTitle() { if (this.FormBorderStyle == FormBorderStyle.None) this.FormBorderStyle = FormBorderStyle.Sizable; else this.FormBorderStyle = FormBorderStyle.None; } private void DockOrUndockWindowOnTop() { switch (this.TopMost) { case false: this.TopMost = true; lblMessage.Text = "Docked!"; timer1.Enabled = true; timer1.Start(); break; case true: this.TopMost = false; lblMessage.Text = "Undocked!"; timer1.Enabled = true; timer1.Start(); break; } } private void PreventWindowBeeingInFocus() { } public void DrawRectangle(object sender, PaintEventArgs e) { DefineRectangle(e, new Point(40, 10), new Size(20, 20), 'W', wPressed ? Color.Crimson : Color.White); DefineRectangle(e, new Point(10, 40), new Size(20, 20), 'A', aPressed ? Color.Crimson : Color.White); DefineRectangle(e, new Point(40, 40), new Size(20, 20), 'S', sPressed ? Color.Crimson : Color.White); DefineRectangle(e, new Point(70, 40), new Size(20, 20), 'D', dPressed ? Color.Crimson : Color.White); DefineRectangle(e, new Point(10, 10), new Size(20, 20), 'Q', qPressed ? Color.Crimson : Color.White); DefineRectangle(e, new Point(70, 10), new Size(20, 20), 'E', ePressed ? Color.Crimson : Color.White); } private void DefineRectangle(PaintEventArgs e, Point p, Size s, char letter, Color c) { //Create Pen var blackPen = new Pen(Color.Black, 3); var brush = new SolidBrush(c); //Create Rectangle var rect = new Rectangle(p, s); //Drawing e.Graphics.DrawRectangle(blackPen, rect); e.Graphics.FillRectangle(brush, rect); e.Graphics.DrawString(letter.ToString(), new Font(FontFamily.GenericSerif, 12), Brushes.Black, rect); } private void timer1_Tick(object sender, EventArgs e) { lblMessage.Text = ""; timer1.Enabled = false; timer1.Stop(); } private void Form1_FormClosed(object sender, FormClosedEventArgs e) { UnregisterHotKey(this.Handle, 1); UnregisterHotKey(this.Handle, 2); UnregisterHotKey(this.Handle, 3); UnregisterHotKey(this.Handle, 4); UnregisterHotKey(this.Handle, 5); UnregisterHotKey(this.Handle, 6); UnregisterHotKey(this.Handle, 7); UnregisterHotKey(this.Handle, 8); UnregisterHotKey(this.Handle, 9); UnregisterHotKey(this.Handle, 10); UnregisterHotKey(this.Handle, 11); UnregisterHotKey(this.Handle, 12); UnregisterHotKey(this.Handle, 13); UnregisterHotKey(this.Handle, 14); UnregisterHotKey(this.Handle, 15); UnregisterHotKey(this.Handle, 16); } } }
Und hier ein Bild, wie das Programm letztlich dann aussieht:
Wie gesagt nichts großartiges, allerdings hätte ich irgendwie noch die letzten nicht funktionierenden Punkte "verstanden" bzw. behoben.
- Bearbeitet dr34mup Mittwoch, 10. Februar 2016 17:58
Antworten
-
Hallo,
Hotkeys sind mehr dafuer gedacht, dass man ein Programm per Shortcut aktivieren kann und dieses dann eine Aktion ausloest. Du braechtest eher die Funktionalitaet eines Keyloggers, welcher die Tastenanschlaege (KeyDown, KeyUp, KeyPress) abfaengt, verarbeitet und dann weiter leitet.
Es gibt im Internet diverse Beispiele die gut zeigen wie so etwas funktioniert. Damit umgehst du alle deine 3 Probleme, wenn es auch erstmal einen Neuanfang fuer dich bedeutet. Ein einfaches Beispiel gibt es hier.
Tom Lambert - .NET (C#) MVP
Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Administrator Montag, 15. Februar 2016 14:49
- Als Antwort markiert Aleksander Chalabashiev Dienstag, 1. März 2016 10:14
Alle Antworten
-
Hallo,
Hotkeys sind mehr dafuer gedacht, dass man ein Programm per Shortcut aktivieren kann und dieses dann eine Aktion ausloest. Du braechtest eher die Funktionalitaet eines Keyloggers, welcher die Tastenanschlaege (KeyDown, KeyUp, KeyPress) abfaengt, verarbeitet und dann weiter leitet.
Es gibt im Internet diverse Beispiele die gut zeigen wie so etwas funktioniert. Damit umgehst du alle deine 3 Probleme, wenn es auch erstmal einen Neuanfang fuer dich bedeutet. Ein einfaches Beispiel gibt es hier.
Tom Lambert - .NET (C#) MVP
Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Administrator Montag, 15. Februar 2016 14:49
- Als Antwort markiert Aleksander Chalabashiev Dienstag, 1. März 2016 10:14
-
Leider war das Beispiel von Codeplex nicht so, dass es mein Problem gelöst hat. Aber der Hinweis in die Richtung Keylogger zu schauen, war sehr hilfreich. So konnte ich über diese Seite: http://null-byte.wonderhowto.com/how-to/create-simple-hidden-console-keylogger-c-sharp-0132757/ endlich das gewünschte Ergebnis bekommen.
Das Beispiel von Codeplex tendiert leider wie mein voriger Code dazu, die Keys abzufangen. Jetzt werde ich bei Zeit einmal den Code vergleichen, damit ich herausfinde warum.
- Bearbeitet dr34mup Montag, 15. Februar 2016 15:44