C# Maus und Tastatur-Ereignisse

Zhen

Lt. Junior Grade
Registriert
Aug. 2009
Beiträge
299
Hallo Leute,
da ich jetzt leider doch noch nicht SO bewandert bin in C# und mir die ganzen
Google-Ergebnisse auch nicht wirklich weiter helfen... frage ich mal einfach hier nach.

Ich schreibe gerade an einer Konsolen-Applikation in C# die mir in einer Endlosschleife Images vom aktuellen Desktop (bzw. allgemein Bildschirm) an meinen Rechner schickt.

Nun das klappt auch wunderbar und läuft ganz gut. Ich habe da nur ein Problem... ich will dass die Pics nur dann gemacht und verschickt werden wenn sich irgendwas ändert (z.B. die Maus bewegt, Maustaste gedrückt oder Tastatur gedrückt wird... oder aber auch irgendein Fenster oder eine Meldung aufgeht).

Also sich in irgendeiner Art und Weise was am PC tut, dann sollen die Pics verschickt werden, aber eben nicht dauerhaft in einer Schleife da dass eben doch zu viel Traffic verursacht.

Ich hoffe ihr könnt mir da weiter helfen.

Danke schon mal im Vorraus.
 
Hiho.
Bei einer Änderung des Desktops (Programm öffnen,...) wird das schwierig. Du kannst allerdings einen Mouselistener und einen Keyboardlistener einbauen. Google einfach nach Mouse-Keyboardlistener
 
So, hast ja schon gewisse Kriterien gefunden:
-Allgemein Nachrichten von Eingabegeräten

Moment...

Du bist erstens zu faul um sowas einfaches zu googlen, dann wird es wohl eh an der Umsetzung scheitern und du solltest dich erstmal mit deiner Arbeitshaltung und deinen Grundlagen befassen.
Zweitens verstehe ich nicht, was man mit so einem Programm erreichen will, wenn nicht die Beobachtung Dritter ohne deren Befugnis.
Unter diesen Umständen wird aus rechtlichen Gründen im Forum keine Hilfe angeboten.
 
1. ich bin nicht zu faul, Ich finde nur leider nichts HILFREICHES bei google (zumindestens nichts dass gut genug erklärt ist)
2. das mit beobachtung da hast du nicht ganz unrecht... jedoch dient das nicht der beobachtung sondern ist für ein remote tool nötig.

Ich arbeite gerade an einem Remote Tool (sowas wie rdp) in C#. Muss halt was eigenes sein/werden. Das ganze bewerkstellige ich eben dadurch, dass ein Client Tool Screens macht in einer Endlosschleife und diese an mein Root Programm übermittelt dass die Images sofort ladet. Jedoch ist es mir eben zu viel Traffic wenn es die Screens übermittelt obwohl alles genauso ist wie beim letzten Screen weil weder Maus noch Keys gedrückt/bewegt wurden.

PS: Hätte ich Dritte beobachten wollen, dann hätte ich es als Dienst bewerkstelligt und nicht als Konsolenapplikation die man nicht mal ins Tray minimieren kann! ;-)
 
Zuletzt bearbeitet:
Ich habe sowas zwar noch nicht gemacht, aber verbinde das Stichwort system hooks damit.

Das sollte es dir ermöglichen die richtigen Timings zu erhalten.
 
Du kannst ja nach einem Screenshot das Bild auch lokal merken, dann per Timer alle xy ms einen neuen Screenshot und die beiden vergleichen, sind sie gleich nicht verschicken. Sind sie gleich verschicken und als neuen letzten Screenshot merken. :cool_alt:

Aber besser einen fertigen Vnc nehmen.
 
naja leider bringt mir ein fertiges vnc nichts. ich habe nämlich ein programm das verschiedene features bietet und da will ich eben auch das remote dabei haben. ist außerdem wichtig dass es was eigenes ist.

PS: das ding ist nämlich ich mache das für meinen betrieb (bin noch in ausbildung allerdings). irgendwann wenn das ganze ausgereift genug ist wollen wir das nämlich aktiv einsetzen und auch vermarkten.
 
Eigentlich kannst du keine Befehle (aus Sicherheitsgründen) beeinflussen! D.H., Mouse und KeyBoard abfragen können ohne eingriffe in den Kernel nicht manipuliert werden! Daher sind ja auch die meisten Remotetools oder fast alle sogar, kostenpflichtig.

Eventuell erzähle ich mist, aber wenn ich ein Betriebssystem programmiere, würde ich selbst aus SecReason nicht erlauben Maus und Keyboard vom Netzwerk beeinflussbar machen!
 
@roker002: Das stimmt so nicht. In C# habe ich selbst schon beides abgefangen und so z.b. für Inputfelder gewissen Zeichen nur zugelassen.
Dazu muss men z.b einfach nen KeyDown-Event (nennen wir diesen Parameter e) abfangen und mittels "s.surpressKeyPress = true" bzw. false wird gesteuert ob der Tastendruck weitergeleitet wird oder nicht. (sollte auch mit mausklick/-bewegung funktionieren).
Das Senden eines Tastaten-Drucks ist dann das geringere Problem.
 
@roker002: das mit mouse oder Keyboard abfangen bzw. darauf reagieren soll über das lokale Programm funktionieren (nicht übers netzwerk).

@black_panter: ja das mit keydown, keyup oder keypress event weiß ich schon. allerdings funktioniert das ganze nur für das formular wenn es den fokus hat. nicht wenn das formular jedoch im hintergrund ist.

aber so oder so... ich bin da ein kleines stück weiter. immerhin weiß ich jetzt dass ich ohne die user32.dll nicht weiter komme. allem anschein nach muss ich einfach nun mal darauf zurückgreifen wenn ich die systemweiten ereignisse abfangen will.

danke jedoch trotzdem für die hilfe =)
 
Neulich war hier schon mal eine ähnliche Diskussion und ich habe aus mehreren verlinkten Hinweisen eine Klasse geschrieben die beides Keyboard & Mouse-Input abfangen kann, vielleicht hilft Dir das ja weiter:

Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;

class InterceptKeysAndMouse {
    private const int WH_KEYBOARD_LL = 13;
    private const int WH_MOUSE_LL = 14;
    private const int WM_KEYDOWN = 0x0100;
    private const int WM_SYSKEYDOWN = 0x0104;
    private static LowLevelKeyboardProc _procKeyboard = HookCallbackKeyboard;
    private static IntPtr _hookIDKeyboard = IntPtr.Zero;
    private static LowLevelMouseProc _procMouse = HookCallbackMouse;
    private static IntPtr _hookIDMouse = IntPtr.Zero;

    public static void Main() {
        _hookIDKeyboard = SetHook(WH_KEYBOARD_LL, _procKeyboard);
        _hookIDMouse    = SetHook(WH_MOUSE_LL, _procMouse);
        Application.Run();
        if (_hookIDKeyboard != IntPtr.Zero) UnhookWindowsHookEx(_hookIDKeyboard);
        if (_hookIDMouse    != IntPtr.Zero) UnhookWindowsHookEx(_hookIDMouse);
    }

    private static IntPtr SetHook(int idHook, Delegate proc) {
        using (Process curProcess = Process.GetCurrentProcess())
            using (ProcessModule curModule = curProcess.MainModule)
                return SetWindowsHookEx(idHook, proc, GetModuleHandle(curModule.ModuleName), 0);
    }

    private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);

    private static IntPtr HookCallbackKeyboard(int nCode, IntPtr wParam, IntPtr lParam) {
            if (nCode >= 0 && (wParam == (IntPtr)WM_KEYDOWN || wParam == (IntPtr)WM_SYSKEYDOWN)) {
            int vkCode = Marshal.ReadInt32(lParam);
            Console.WriteLine((Keys)vkCode);
        }
        return CallNextHookEx(_hookIDKeyboard, nCode, wParam, lParam);
    }

    private delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam);

    private static IntPtr HookCallbackMouse(int nCode, IntPtr wParam, IntPtr lParam) {
        if (nCode >= 0 && MouseMessages.WM_LBUTTONDOWN == (MouseMessages)wParam) {
            MSLLHOOKSTRUCT hookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
            Console.WriteLine(hookStruct.pt.x + ", " + hookStruct.pt.y);
        }
        return CallNextHookEx(_hookIDMouse, nCode, wParam, lParam);
    }

    private enum MouseMessages {
        WM_LBUTTONDOWN = 0x0201,
        WM_LBUTTONUP = 0x0202,
        WM_MOUSEMOVE = 0x0200,
        WM_MOUSEWHEEL = 0x020A,
        WM_RBUTTONDOWN = 0x0204,
        WM_RBUTTONUP = 0x0205
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct POINT {
        public int x;
        public int y;
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct MSLLHOOKSTRUCT {
        public POINT pt;
        public uint mouseData;
        public uint flags;
        public uint time;
        public IntPtr dwExtraInfo;
    }

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr SetWindowsHookEx(int idHook, Delegate lpfn, IntPtr hMod, uint dwThreadId);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool UnhookWindowsHookEx(IntPtr hhk);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr GetModuleHandle(string lpModuleName);
}
 
hey extremen dank.
ich werds mir gleich mal angucken. hoffe dass ich da dann mal durchblicke und es verwenden kann/darf =)

danke nochmals =)
 
Nur mal so nebenbei, du sagst "aktiv einsetzen und auch vermarkten."

In dem Fall würde ich dringend dazu raten an C++ ran zugehen ;). Da nun demnächst auch das Google Betriebssystem auf die Reise geschickt wird (sinnloser Weise hat diese Unternehmen dutzende Fans) und auch Apple immer mehr genutzt wird, ist ggf ratsam eine Sprache zu verwenden die damit umgehen kann. (Bei dem Google Sys bin ich mir nicht sicher).

Zudem weiß ich aus Erfahrung (bin auch noch nicht solange dabei^^), dass man sowas zig mal neu schreiben wird, ggf solltes du also mit etwas einfacherem dich an die Sprache ranarbeiten.

Ansonsten Viel Erfolg beim Programmieren :freaky:
 
Zurück
Oben