Reputation: 9
I am trying to detect user activity by "keyboard and mouse" on any program in Windows.
I detect Keyboard activity and mouse click by GetAsyncKeyState()
in user32.Dll
".
I detect Mouse Movement by System.Windows.Forms.Cursor.Position;
I am searching to find a way for detecting mouse wheel scrolling on any program in windows and any position on screen.
I know it possible by user32.Dll
function like GetMessage()
.
I am never use widows form control event like MouseWheel
Event, Because it work only on current program, not at all.
thanks.
Upvotes: 0
Views: 1262
Reputation: 25
I edited answer of ang elus a bit, it works for me now, maybe it would for you.
using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Forms;
using MouseEventArgs = System.Windows.Forms.MouseEventArgs;
using ScrollEventArgs = System.Windows.Forms.ScrollEventArgs;
using ScrollEventType = System.Windows.Forms.ScrollEventType;
namespace WpfApp1
{
public static class Win32Api
{
[StructLayout(LayoutKind.Sequential)]
public class POINT
{
public int X;
public int Y;
}
[StructLayout(LayoutKind.Sequential)]
public class MouseHookStruct
{
public POINT pt;
public int hwnd;
public int wHitTestCode;
public int dwExtraInfo;
}
public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern bool UnhookWindowsHookEx(int idHook);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam);
}
public class MouseHook
{
private Win32Api.POINT point;
private Win32Api.POINT POINT
{
//get { return point; }
set
{
if (point != value)
{
point = value;
if (MouseMoveEvent != null)
{
var e = new MouseEventArgs(MouseButtons.None, 0, point.X, point.Y, 0);
MouseMoveEvent(this, e);
//MouseClickEvent(this, new MouseEventArgs(MouseButtons.None, 0, point.X, point.Y, 0));
//MouseDownEvent(this, new MouseEventArgs(MouseButtons.None, 0, point.X, point.Y, 0));
//MouseUpEvent(this, new MouseEventArgs(MouseButtons.None, 0, point.X, point.Y, 0));
}
}
}
}
private int hHook;
private const int WM_MOUSEMOVE = 0x200;
private const int WM_LBUTTONDOWN = 0x201;
private const int WM_RBUTTONDOWN = 0x204;
private const int WM_MBUTTONDOWN = 0x207;
private const int WM_LBUTTONUP = 0x202;
private const int WM_RBUTTONUP = 0x205;
private const int WM_MBUTTONUP = 0x208;
private const int WM_LBUTTONDBLCLK = 0x203;
private const int WM_RBUTTONDBLCLK = 0x206;
private const int WM_MBUTTONDBLCLK = 0x209;
private const int WM_MOUSEWHEEL = 0x20A;
public const int WH_MOUSE_LL = 14;
public Win32Api.HookProc hProc;
public MouseHook()
{
this.POINT = new Win32Api.POINT();
}
public int SetHook()
{
hProc = new Win32Api.HookProc(MouseHookProc);
hHook = Win32Api.SetWindowsHookEx(WH_MOUSE_LL, hProc, IntPtr.Zero, 0);
return hHook;
}
public void UnHook()
{
Win32Api.UnhookWindowsHookEx(hHook);
}
private IntPtr wParam;
private IntPtr lParam;
private int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam)//, LPARAM Addtl_Info_L
{
this.wParam = wParam;
this.lParam = lParam;
Win32Api.MouseHookStruct MyMouseHookStruct = (Win32Api.MouseHookStruct)Marshal.PtrToStructure(this.lParam, typeof(Win32Api.MouseHookStruct));
if (nCode < 0)
{
return Win32Api.CallNextHookEx(hHook, nCode, this.wParam, this.lParam);
}
else
{
if (MouseClickEvent != null)
{
MouseButtons button = MouseButtons.None;
int clickCount = 0;
switch ((Int32)this.wParam)
{
case WM_LBUTTONDOWN:
button = MouseButtons.Left;
clickCount = 1;
if (MouseDownEvent != null) MouseDownEvent(this, new MouseEventArgs(button, clickCount, point.X, point.Y, 0));
break;
case WM_RBUTTONDOWN:
button = MouseButtons.Right;
clickCount = 1;
if (MouseDownEvent != null) MouseDownEvent(this, new MouseEventArgs(button, clickCount, point.X, point.Y, 0));
break;
case WM_MBUTTONDOWN:
button = MouseButtons.Middle;
clickCount = 1;
if (MouseDownEvent != null) MouseDownEvent(this, new MouseEventArgs(button, clickCount, point.X, point.Y, 0));
break;
case WM_LBUTTONUP:
button = MouseButtons.Left;
clickCount = 1;
if (MouseUpEvent != null) MouseUpEvent(this, new MouseEventArgs(button, clickCount, point.X, point.Y, 0));
break;
case WM_RBUTTONUP:
button = MouseButtons.Right;
clickCount = 1;
if (MouseUpEvent != null) MouseUpEvent(this, new MouseEventArgs(button, clickCount, point.X, point.Y, 0));
break;
case WM_MBUTTONUP:
button = MouseButtons.Middle;
clickCount = 1;
if (MouseUpEvent != null) MouseUpEvent(this, new MouseEventArgs(button, clickCount, point.X, point.Y, 0));
break;
case WM_MOUSEWHEEL:
MSLLHOOKSTRUCT mouseData = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(this.lParam, typeof(MSLLHOOKSTRUCT));
Console.WriteLine("out " + mouseData.mouseData + " " + mouseData.dwExtraInfo + " " + mouseData.flags + " " + mouseData.pt);
if (MousescrollEvent != null) MousescrollEvent(this, new ScrollEventArgs(ScrollEventType.SmallIncrement, mouseData.pt.Y < 1e-316?1:-1));
break;
default:
break;
}
var e = new MouseEventArgs(button, clickCount, point.X, point.Y, 0);
MouseClickEvent(this, e);
}
this.POINT = new Win32Api.POINT { X=MyMouseHookStruct.pt.X, Y=MyMouseHookStruct.pt.Y };
return Win32Api.CallNextHookEx(hHook, nCode, this.wParam, this.lParam);
}
}
[StructLayout(LayoutKind.Sequential)]
private struct MSLLHOOKSTRUCT
{
public Point pt; //<-this is what needed (Y part to be precise)
public int mouseData; //<-this is time difference
public int flags; //<-this and lower, always constant, don't know what is it
public int time;
public long dwExtraInfo;
}
public delegate void MouseMoveHandler(object sender, MouseEventArgs e);
public event MouseMoveHandler MouseMoveEvent;
public delegate void MouseClickHandler(object sender, MouseEventArgs e);
public event MouseClickHandler MouseClickEvent;
public delegate void MouseDownHandler(object sender, MouseEventArgs e);
public event MouseDownHandler MouseDownEvent;
public delegate void MouseUpHandler(object sender, MouseEventArgs e);
public event MouseUpHandler MouseUpEvent;
public delegate void MousescrollHandler(object sender, ScrollEventArgs e);
public event MousescrollHandler MousescrollEvent;
}
}
And this is test window
using System.Windows;
using System.Windows.Forms;
namespace WpfApp1
{
public partial class MainWindow : Window
{
MouseHook mhM = new MouseHook();
public MainWindow()
{
InitializeComponent();
mhM.SetHook();
mhM.MouseClickEvent += (object sender, MouseEventArgs e) =>
{ label1.Content = "" + e.Button + " " + e.Clicks + " " + e.X + " " + e.Y; };
mhM.MousescrollEvent += (object sender, ScrollEventArgs e) =>
{ label2.Content = "" + e.NewValue; };
Timer timer = new Timer();
timer.Interval = 1000000;
timer.Tick += Timer_Tick;
timer.Start();
}
private void Timer_Tick(object sender, System.EventArgs e)
{
mhM.UnHook();
}
}
}
Upvotes: 1
Reputation: 11
https://coderedirect.com/questions/511479/mouse-wheel-event-to-work-with-hovered-control https://gist.github.com/HamzaAnis/90d53662a1659be9d2c74f1dc490cb88 https://learn.microsoft.com/en-gb/windows/win32/api/winuser/ns-winuser-msllhookstruct?redirectedfrom=MSDN helpful links
good question
if this helps below is a class that has most of the mouse hooks so you can pick and choose make an to use it you have to assign the standard click
var mhM = new MouseHook();
mhM.SetHook();
mhM.MouseClickEvent += (object sender, MouseEventArgs e) =>
{ };
public class MouseHook
{
private Point point;
private Point Point
{
get { return point; }
set
{
if (point != value)
{
point = value;
if (MouseMoveEvent != null)
{
var e = new MouseEventArgs(MouseButtons.None, 0, point.X, point.Y, 0);
MouseMoveEvent(this, e);
//MouseClickEvent(this, new MouseEventArgs(MouseButtons.None, 0, point.X, point.Y, 0));
//MouseDownEvent(this, new MouseEventArgs(MouseButtons.None, 0, point.X, point.Y, 0));
//MouseUpEvent(this, new MouseEventArgs(MouseButtons.None, 0, point.X, point.Y, 0));
}
}
}
}
private int hHook;
private const int WM_MOUSEMOVE = 0x200;
private const int WM_LBUTTONDOWN = 0x201;
private const int WM_RBUTTONDOWN = 0x204;
private const int WM_MBUTTONDOWN = 0x207;
private const int WM_LBUTTONUP = 0x202;
private const int WM_RBUTTONUP = 0x205;
private const int WM_MBUTTONUP = 0x208;
private const int WM_LBUTTONDBLCLK = 0x203;
private const int WM_RBUTTONDBLCLK = 0x206;
private const int WM_MBUTTONDBLCLK = 0x209;
private const int WM_MOUSEWHEEL = 0x20A;
public const int WH_MOUSE_LL = 14;
public Win32Api.HookProc hProc;
public MouseHook()
{
this.Point = new Point();
}
public int SetHook()
{
hProc = new Win32Api.HookProc(MouseHookProc);
hHook = Win32Api.SetWindowsHookEx(WH_MOUSE_LL, hProc, IntPtr.Zero, 0);
return hHook;
}
public void UnHook()
{
Win32Api.UnhookWindowsHookEx(hHook);
}
private int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam)//, LPARAM Addtl_Info_L
{
Win32Api.MouseHookStruct MyMouseHookStruct = (Win32Api.MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(Win32Api.MouseHookStruct));
if (nCode < 0)
{
return Win32Api.CallNextHookEx(hHook, nCode, wParam, lParam);
}
else
{
//Console.WriteLine("mouse" + MouseClickEvent.ToString());
if (MouseClickEvent != null)
{
MouseButtons button = MouseButtons.None;
int clickCount = 0;
switch ((Int32)wParam)
{
case WM_LBUTTONDOWN:
button = MouseButtons.Left;
clickCount = 1;
if (MouseDownEvent != null) MouseDownEvent(this, new MouseEventArgs(button, clickCount, point.X, point.Y, 0));
break;
case WM_RBUTTONDOWN:
button = MouseButtons.Right;
clickCount = 1;
if (MouseDownEvent != null) MouseDownEvent(this, new MouseEventArgs(button, clickCount, point.X, point.Y, 0));
break;
case WM_MBUTTONDOWN:
button = MouseButtons.Middle;
clickCount = 1;
if (MouseDownEvent != null) MouseDownEvent(this, new MouseEventArgs(button, clickCount, point.X, point.Y, 0));
break;
case WM_LBUTTONUP:
button = MouseButtons.Left;
clickCount = 1;
if (MouseUpEvent != null) MouseUpEvent(this, new MouseEventArgs(button, clickCount, point.X, point.Y, 0));
break;
case WM_RBUTTONUP:
button = MouseButtons.Right;
clickCount = 1;
if (MouseUpEvent != null) MouseUpEvent(this, new MouseEventArgs(button, clickCount, point.X, point.Y, 0));
break;
case WM_MBUTTONUP:
button = MouseButtons.Middle;
clickCount = 1;
if (MouseUpEvent != null) MouseUpEvent(this, new MouseEventArgs(button, clickCount, point.X, point.Y, 0));
break;
case WM_MOUSEWHEEL:
int data = GET_WHEEL_DELTA_WPARAM(lParam.ToInt32());
MSLLHOOKSTRUCT mouseData = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
int wheelMovement = GET_WHEEL_DELTA_WPARAM(mouseData.mouseData);
Console.WriteLine("out" + wheelMovement.ToString());
// int zDelta = GET_WHEEL_DELTA_WPARAM(wParam);
if (MousescrollEvent != null) MousescrollEvent(this, new ScrollEventArgs(ScrollEventType.SmallDecrement, wheelMovement));
break;
default:
Console.WriteLine(((Int32)lParam).ToString());
break;
}
var e = new MouseEventArgs(button, clickCount, point.X, point.Y, 0);
MouseClickEvent(this, e);
}
this.Point = new Point(MyMouseHookStruct.pt.x, MyMouseHookStruct.pt.y);
return Win32Api.CallNextHookEx(hHook, nCode, wParam, lParam);
}
}
[StructLayout(LayoutKind.Sequential)]
private struct MSLLHOOKSTRUCT
{
public Point pt;
public int mouseData;
public int flags;
public int time;
public long dwExtraInfo;
}
private static int GET_WHEEL_DELTA_WPARAM(int wparam)
{
return (int)(wparam >> 16);
}
public delegate void MouseMoveHandler(object sender, MouseEventArgs e);
public event MouseMoveHandler MouseMoveEvent;
public delegate void MouseClickHandler(object sender, MouseEventArgs e);
public event MouseClickHandler MouseClickEvent;
public delegate void MouseDownHandler(object sender, MouseEventArgs e);
public event MouseDownHandler MouseDownEvent;
public delegate void MouseUpHandler(object sender, MouseEventArgs e);
public event MouseUpHandler MouseUpEvent;
public delegate void MousescrollHandler(object sender, ScrollEventArgs e);
public event MousescrollHandler MousescrollEvent;
// public delegate void MouseUpHandler(object sender, MouseEventArgs e);
//public event MouseUpHandler Mow;
}
Upvotes: 1