Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Listen for system wide click using Mono and C#?

Tags:

c#

windows

mono

I want to use mono to write a simple CL tool that registers every click around the system. I understand that I can access this from Windows Forms? Which is like the wrapper around the internal Windows API?

Sorry I this is a real stupid question but coming from a JS background where its just AddEventListener this is kind of confusing, or badly documented. Thanks

like image 905
Niels Avatar asked Dec 06 '25 20:12

Niels


1 Answers

What you're looking for is in user32.dll


Here're some links about it:

http://pinvoke.net/default.aspx/user32.GetAsyncKeyState

https://msdn.microsoft.com/en-us/library/windows/desktop/ms646293(v=vs.85).aspx

looking up that the user press a key or not?


The first link contains examples of how to use the dll.

You can do multiple things with this dll. For example, what you're after is

[DllImport("User32.dll")]
private static extern short GetAsyncKeyState(System.Windows.Forms.Keys vKey);
[DllImport("User32.dll")]
private static extern short GetAsyncKeyState(System.Int32 vKey);

For this, you'll need to check the key every time you want to check whether the key is down. You can either use the virtual key code or use the Keys class.


If you also want to simulate mouse events, e.g send a left click to the system, the following code is what you're after. (more info here)

[DllImport("user32.dll")]
static extern void mouse_event(uint dwFlags, int dx, int dy, uint dwData, int dwExtraInfo);

I did a similar thing not long ago, however I was hooking into the keyboard and not the mouse. The process is similar, however it is a lot easier to hook into a specific program. The code is below on how I solved my problem.

In the following code, I created an event which triggered whenever a key was pressed and sent the Key Code as the event argument.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace KeyHook {
    public class KeyHook {
        const int WH_KEYBOARD_LL = 13;

        const int WM_KEYDOWN = 0x0100;
        const int WM_KEYUP = 0x0101;

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

        LowLevelKeyboardProc _proc { get; set; }

        IntPtr _hookID { get; set; }

        public delegate void KeyHandler(Keys k);
        public event KeyHandler OnKeyDown;
        public event KeyHandler OnKeyUp;

        public KeyHook() {
            Initialize();
            _hookID = SetHook(_proc);
        }

        void Initialize() {
            this._proc = HookCallback;
            this._hookID = IntPtr.Zero;
            Application.ApplicationExit += Application_ApplicationExit;
        }

        void Application_ApplicationExit(object sender, EventArgs e) {
            UnhookWindowsHookEx(_hookID);
        }

        IntPtr SetHook(LowLevelKeyboardProc proc) {
            using (Process curProcess = Process.GetCurrentProcess()) {
                using (ProcessModule curModule = curProcess.MainModule) {
                    return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle

(curModule.ModuleName), 0);
                }
            }
        }

        IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) {
            if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN) {
                if (this.OnKeyDown != null) {
                    this.OnKeyDown((Keys)Marshal.ReadInt32(lParam));
                }
            } else if (nCode >= 0 && wParam == (IntPtr)WM_KEYUP) {
                if (this.OnKeyUp != null) {
                    this.OnKeyUp((Keys)Marshal.ReadInt32(lParam));
                }
            }
            return CallNextHookEx(_hookID, nCode, wParam, lParam);
        }

        #region dll Imports
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, 

uint dwThreadId);


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


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


        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern IntPtr GetModuleHandle(string lpModuleName);
        #endregion
    }
}

like image 52
artman41 Avatar answered Dec 08 '25 10:12

artman41



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!