123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- using System.Runtime.InteropServices;
- using Timer = System.Windows.Forms.Timer;
- namespace DummyCursor.Spy
- {
- public class SpyAgent
- {
- private readonly Action<SpiedWindow> _selectedAction;
- private readonly Timer _timer;
- private SpyAgentLocator _locator;
- public SpyAgent(Action<SpiedWindow> selectedAction)
- {
- _selectedAction = selectedAction;
- _timer = new Timer { Interval = 25, Enabled = false };
- _timer.Tick += OnTimerTicked;
- BeginSpying();
- }
- private void OnTimerTicked(object sender, EventArgs e)
- {
- ShowLocator();
- if (0 == (Control.MouseButtons & MouseButtons.Left)) return;
- EndSpying();
- _selectedAction(GetHoveredWindow());
- }
- private void ShowLocator()
- {
- var window = GetHoveredWindow();
- if (window.Handle == IntPtr.Zero)
- {
- _locator.Hide();
- return;
- }
- _locator.Location = window.Area.Location;
- _locator.Size = window.Area.Size;
- _locator.TopLevel = true;
- _locator.TopMost = true;
- _locator.Show();
- }
- public void BeginSpying()
- {
- if (_locator != null)
- {
- _locator.Close();
- _locator.Dispose();
- }
- _locator = new SpyAgentLocator();
- MakePassThrough(_locator.Handle);
- _timer.Enabled = true;
- }
- public void EndSpying()
- {
- _timer.Enabled = false;
- _locator?.Close();
- _locator?.Dispose();
- _locator = null;
- }
- private class SpyAgentLocator : Form
- {
- public SpyAgentLocator()
- {
- FormBorderStyle = FormBorderStyle.None;
- BackColor = Color.OrangeRed;
- Opacity = 0.25;
- TopLevel = true;
- TopMost = true;
- }
- }
- #region Under the Hood
- private const int GWL_EXSTYLE = -20;
- private const int WS_EX_TRANSPARENT = 0x20;
- [DllImport("user32.dll")]
- private static extern IntPtr WindowFromPoint(POINT point);
- [DllImport("user32.dll")]
- private static extern IntPtr ChildWindowFromPoint(IntPtr hWndParent, POINT point);
- [DllImport("user32.dll", SetLastError = true)]
- private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
- [DllImport("user32.dll", SetLastError = true)]
- private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
- public static SpiedWindow GetHoveredWindow()
- {
- var handle = WindowFromPoint(Cursor.Position);
- return new SpiedWindow(handle);
- }
- private static void MakePassThrough(IntPtr handle)
- {
- var exstyle = GetWindowLong(handle, GWL_EXSTYLE);
- exstyle |= WS_EX_TRANSPARENT;
- SetWindowLong(handle, GWL_EXSTYLE, exstyle);
- }
- [StructLayout(LayoutKind.Sequential)]
- private struct POINT
- {
- public readonly int X;
- public readonly int Y;
- public POINT(int x, int y)
- {
- X = x;
- Y = y;
- }
- public POINT(Point pt)
- : this(pt.X, pt.Y)
- {
- }
- public static implicit operator Point(POINT p)
- {
- return new(p.X, p.Y);
- }
- public static implicit operator POINT(Point p)
- {
- return new(p.X, p.Y);
- }
- }
- #endregion Under the Hood
- }
- }
|