Xamarin.Mac/キーボードの入力をシミュレートする

提供: MonoBook
移動: 案内検索

Mac OS Xに対してキーボードの入力をシミュレートしたい。

これが出来ると仮想キーボードショートカットキーを発射するアプリ、バーコードリーダーみたいなものなど夢が広がる。 個人的にはアプリに対して外部から通信があった際にスクリーンセーバーを解除するのに用いた。

実装1[編集]

Mac OS Xの標準ライブラリのひとつであるCoreGraphicsに各種イベントを送信するクラスが用意されている。 なぜこの手のクラスがCoreFoundationではなくCoreGraphicsにあるのかは謎である。三角形の秘密プチエンジェル事件並みに闇は深い。

なお、ここで使われるキーコードMac独自のものであり、Windowsで一般的なキーコードとはまったく別物である点に注意すること。キーコードの一覧などの詳細は「キーコード/Mac OS X」を参照。

また、仮想的にキーコードを送信する際は本物のキーボードCaps Lockの状態は無視されるので、大文字を送信する場合は「CGEventFlags.Shift」を立てる。

using System;
using AppKit;
using CoreGraphics;
 
namespace SimKeyboard
{
    static class MainClass
    {
        static void Main(string[] args)
        {
            NSApplication.Init();
 
            for (int wait = 5; 0 < wait; wait--)
            {
                System.Threading.Thread.Sleep(1000);
                Console.WriteLine(wait);
            }
 
            PostKeyWithModifiers(0, CGEventFlags.Shift); // A;
            PostKeyWithModifiers(1, CGEventFlags.Shift); // S;
            PostKeyWithModifiers(2, CGEventFlags.Shift); // D;
            PostKeyWithModifiers(3)                    ; // f;
        }
 
        static void PostKeyWithModifiers(ushort keycode, CGEventFlags modifiers = 0)
        {
            using (var source = new CGEventSource(CGEventSourceStateID.CombinedSession))
            using (var keydown = new CGEvent(source, keycode, keyDown: true))
            using (var keyup = new CGEvent(source, keycode, keyDown: false))
            {
                keydown.Flags = modifiers;
 
                // 送信
                CGEvent.Post(keydown, CGEventTapLocation.AnnotatedSession);
                CGEvent.Post(keyup  , CGEventTapLocation.AnnotatedSession);
            }
        }
    }
}

個人的にスクリーンセーバーを解除するのには送信しても他のアプリに影響の少ないであろう左矢印キーを用いた。

            PostKeyWithModifiers(123); // 「←矢印キー」を送信;

関連項目[編集]

参考文献[編集]