mirror of
https://github.com/immense/Remotely.git
synced 2025-10-26 11:27:15 +00:00
122 lines
4.3 KiB
C#
122 lines
4.3 KiB
C#
using System;
|
|
using System.Drawing;
|
|
using System.Drawing.Imaging;
|
|
using System.IO;
|
|
using System.Runtime.InteropServices;
|
|
using System.Timers;
|
|
using System.Windows.Forms;
|
|
using Remotely.Shared.Win32;
|
|
using Remotely.Shared.Models;
|
|
using Remotely.Desktop.Core.Interfaces;
|
|
|
|
namespace Remotely.Desktop.Win.Services
|
|
{
|
|
/// <summary>
|
|
/// A class that can be used to watch for cursor icon changes.
|
|
/// </summary>
|
|
public class CursorIconWatcherWin : ICursorIconWatcher
|
|
{
|
|
public CursorIconWatcherWin()
|
|
{
|
|
ChangeTimer = new System.Timers.Timer(25);
|
|
ChangeTimer.Elapsed += ChangeTimer_Elapsed;
|
|
ChangeTimer.Start();
|
|
}
|
|
public event EventHandler<CursorInfo> OnChange;
|
|
private System.Timers.Timer ChangeTimer { get; set; }
|
|
private string PreviousCursorHandle { get; set; }
|
|
|
|
private User32.CursorInfo cursorInfo;
|
|
|
|
|
|
public CursorInfo GetCurrentCursor()
|
|
{
|
|
try
|
|
{
|
|
var ci = new User32.CursorInfo();
|
|
ci.cbSize = Marshal.SizeOf(ci);
|
|
User32.GetCursorInfo(out ci);
|
|
if (ci.flags == User32.CURSOR_SHOWING)
|
|
{
|
|
if (ci.hCursor.ToString() == Cursors.IBeam.Handle.ToString())
|
|
{
|
|
return new CursorInfo(new byte[0], Point.Empty, "text");
|
|
}
|
|
|
|
using (var icon = Icon.FromHandle(ci.hCursor))
|
|
{
|
|
using (var ms = new MemoryStream())
|
|
{
|
|
using (var cursor = new Cursor(ci.hCursor))
|
|
{
|
|
var hotspot = cursor.HotSpot;
|
|
icon.ToBitmap().Save(ms, ImageFormat.Png);
|
|
return new CursorInfo(ms.ToArray(), hotspot);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return new CursorInfo(new byte[0], Point.Empty, "default");
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
return new CursorInfo(new byte[0], Point.Empty, "default");
|
|
}
|
|
}
|
|
|
|
private void ChangeTimer_Elapsed(object sender, ElapsedEventArgs e)
|
|
{
|
|
if (OnChange == null)
|
|
{
|
|
return;
|
|
}
|
|
try
|
|
{
|
|
cursorInfo = new User32.CursorInfo();
|
|
cursorInfo.cbSize = Marshal.SizeOf(cursorInfo);
|
|
User32.GetCursorInfo(out cursorInfo);
|
|
if (cursorInfo.flags == User32.CURSOR_SHOWING)
|
|
{
|
|
var currentCursor = cursorInfo.hCursor.ToString();
|
|
if (currentCursor != PreviousCursorHandle)
|
|
{
|
|
if (currentCursor == Cursors.IBeam.Handle.ToString())
|
|
{
|
|
OnChange?.Invoke(this, new CursorInfo(new byte[0], Point.Empty, "text"));
|
|
}
|
|
else
|
|
{
|
|
using (var icon = Icon.FromHandle(cursorInfo.hCursor))
|
|
{
|
|
using (var ms = new MemoryStream())
|
|
{
|
|
using (var cursor = new Cursor(cursorInfo.hCursor))
|
|
{
|
|
var hotspot = cursor.HotSpot;
|
|
icon.ToBitmap().Save(ms, ImageFormat.Png);
|
|
OnChange?.Invoke(this, new CursorInfo(ms.ToArray(), hotspot));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
PreviousCursorHandle = currentCursor;
|
|
}
|
|
}
|
|
else if (PreviousCursorHandle != "0")
|
|
{
|
|
PreviousCursorHandle = "0";
|
|
OnChange?.Invoke(this, new CursorInfo(new byte[0], Point.Empty, "default"));
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
OnChange?.Invoke(this, new CursorInfo(new byte[0], Point.Empty, "default"));
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|