4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

C# の 64bit アプリケーションで SendInput を使うときのワナ

Posted at

背景

これまで C# を使って 32bit で作成していた Windows アプリケーションを 64bit に変更したら、キー入力が反映されなくなった。ログを追ってみると、どうも SendInput で送出しているキー入力が無視されているようだ。

調査に当たっては以下の記事が参考になったので、備忘として残しておく。

改修ポイント

32bit の時は、上の記事と同じように、SendInput に渡す構造体を次のように定義していた。

    [StructLayout(LayoutKind.Explicit)]
    private struct INPUT
    {
        [FieldOffset(0)] public int type;
        [FieldOffset(4)] public MOUSEINPUT mi;
        [FieldOffset(4)] public KEYBDINPUT ki;
        [FieldOffset(4)] public HARDWAREINPUT hi;
    };

これだと、先頭の type と次の miki との間が 4 バイトしか差がないことになるが、64bit アプリケーションでは、ここにパディングが入って 8バイトのオフセットが必要だった。

下の記事では、32bit/64bit 両方に対応するため、次のような定義になっている。

    [StructLayout(LayoutKind.Sequential)]
    struct Input
    {
        public int Type;
        public InputUnion ui;
    }

    [StructLayout(LayoutKind.Explicit)]
    struct InputUnion
    {
        [FieldOffset(0)]
        public MouseInput Mouse;
        [FieldOffset(0)]
        public KeyboardInput Keyboard;
        [FieldOffset(0)]
        public HardwareInput Hardware;
    }

もう一点、次の修正も必要だった。

    [StructLayout(LayoutKind.Sequential)]
    private struct KEYBDINPUT
    {
        public short wVk;
        public short wScan;
        public int dwFlags;
        public int time;
//      public int dwExtraInfo;
        public IntPtr ExtraInfo;    // IntPtr に変更
    };

int から IntPtr に変更することで、バイト幅は 4バイトから 8バイトに増えるわけだが、その明確な理由は見つけられなかった。理由をご存じの方はご教示いただけると幸いです。

4
5
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?