Xamarin.Macでマウスカーソルの位置を取得する

マウスカーソルの位置を取得するには、Event Monitorを使用します。

アプリケーションがアクティブなときはLocal Event Monitorを使用して、マウスカーソルの座標を取得します。

localEventMonitor = NSEvent.AddLocalMonitorForEventsMatchingMask(
    NSEventMask.MouseMoved,
    (theEvent) => /* イベント処理 */; )

アプリケーションがアクティブでないときはGlobal Event Monitorを使用して、マウスカーソルの座標を取得します。

globalEventMonitor = NSEvent.AddGlobalMonitorForEventsMatchingMask(
    NSEventMask.MouseMoved,
    (theEvent) => /* イベント処理 */; );

モニタリングを終了するときは、NSEvent.RemoveMonitor()を使用します。

NSEvent.RemoveMonitor(globalEventMonitor);
NSEvent.RemoveMonitor(localEventMonitor);

NSEventから画面上の座標を取得する

Global Monitorのときは、NSEventのLocationInWindowで画面上の座標を取得できます。

Local Monitorのときは、マウスカーソルがアプリケーションのウィンドウ上にあるときはウィンドウ上の座標、マウスカーソルがアプリケーションのウィンドウ外にあるときは画面上の座標を返します。

マウスカーソルがウィンドウ外にあるときはNSEventのWindowがnullになるようなので、この値を使って判定しました。

CGPoint p;
if (theEvent.Window != null)
{
    var rect = theEvent.Window.ConvertRectToScreen(new CGRect(theEvent.LocationInWindow, new CGSize(0, 0)));
    p = rect.Location;
}
else
{
    p = theEvent.LocationInWindow;
}

画面上の座標からウィンドウ上の座標に変換するには、ConvertScreenToBase()を使用します。

var localPoint = this.View.Window.ConvertScreenToBase(p);

ソースコード

ソースコードの一部を掲載します。

public partial class ViewController : NSViewController
{
    private NSObject globalEventMonitor;
    private NSObject localEventMonitor;

    public override void ViewDidLoad()
    {
        base.ViewDidLoad();

        // Do any additional setup after loading the view.
        CheckBoxMonitoring.Activated += (sender, e) =>
        {
            if (CheckBoxMonitoring.State == NSCellStateValue.On)
                StartMonitoring();
            if (CheckBoxMonitoring.State == NSCellStateValue.Off)
                StopMonitoring();
        };
    }
    private void PrintMouseLocation(string monitor, CGPoint p)
    {
        LabelMonitor.StringValue = $"Monitor: {monitor}";
        LabelScreen.StringValue = $"Screen Pos: {p.X:F4} {p.Y:F4}";
        var localPoint = this.View.Window.ConvertScreenToBase(p);
        LabelWindow.StringValue = $"Window Pos: {localPoint.X:F4} {localPoint.Y:F4}";
    }
}

サンプルアプリケーション

こちらからソースコード一式をダウンロードできます。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください