none
半角/全角 のキーを送る RRS feed

  • 質問

  • フォーカスが来ないボタン

    というスレッドを立ててお世話になった者です。

     環境:WindowsXP sp2,.Net Framework v2.0,VS2005,Windowsフォーム


     C#にて、ソフトキーボードの制作を行っています。

    現在、メモ帳などの別アプリにキーを送信する機能を制作しています。

    AやEnterなどのキーは、

            private void aButton_Click(object sender, EventArgs e)
            {
                SendKeys.Send("{a}");
            }

    というふうにしています。

    しかし、半角/全角 はSendKeysでは送ることができないことがわかりました。

    具体的には、半角/全角というボタンをクリックしたら別アプリでの半角/全角のon/offを切り替えたいと思っておりますが、どのようにするのかがわからない状況であります。

    初歩的なことかもしれませんが、宜しければアドバイス等お願いします。

    2006年8月27日 14:11

回答

  • SendInputが推奨されているんですね。Orz      すみません。

    そういうわけでSendInputでテストコード書いてみました。一応、動いています。

    
    const int KEYEVENTF_KEYUP = 0x2;
    const int VK_KANJI = 0x19;
    
    const int INPUT_MOUSE = 0;
    const int INPUT_KEYBOARD = 1;
    const int INPUT_HARDWARE = 2;
    
    [DllImport("user32.dll")]
    static extern int SendInput(int nInputs, ref INPUT pInputs, int cbSize);
    
    [DllImport("user32.dll")]
    static extern IntPtr GetMessageExtraInfo();
    
    private struct MOUSEINPUT
    {
      public int dx;
      public int dy;
      public uint mouseData;
      public uint dwFlags;
      public uint time;
      public IntPtr dwExtraInfo;
    }
    
    private struct KEYBDINPUT
    {
      public ushort wVk;
      public ushort wScan;
      public uint dwFlags;
      public uint time;
      public IntPtr dwExtraInfo;
    }
    
    private struct HARDWAREINPUT
    {
      public uint uMsg;
      public ushort wParamL;
      public ushort wParamH;
    }
    
    [StructLayout(LayoutKind.Explicit)]
    private struct INPUT
    {
      [FieldOffset(0)]
      public uint type;
      [FieldOffset(4)]
      public MOUSEINPUT mi;
      [FieldOffset(4)]
      public KEYBDINPUT ki;
      [FieldOffset(4)]
      public HARDWAREINPUT hi;
    }
    
    
    private void cbtn_sendInput_Click(object sender, EventArgs e)
    {
      textBox1.Focus();
    
      INPUT input = new INPUT();
      input.type = INPUT_KEYBOARD;
      input.ki.wScan = 0;
      input.ki.time = 0;
      input.ki.dwExtraInfo = GetMessageExtraInfo();
    
      input.ki.wVk = (ushort)VK_KANJI;
      input.ki.dwFlags = 0;      //Key Down
    
      SendInput(1, ref input, Marshal.SizeOf(typeof(INPUT)));
    
      input.ki.wVk = (ushort)VK_KANJI;
      input.ki.dwFlags = KEYEVENTF_KEYUP;  //Key Up
    
      SendInput(1, ref input, Marshal.SizeOf(typeof(INPUT)));
    }
    
    2006年8月28日 6:51
    モデレータ

すべての返信

  • Win32API の SendInput 関数を使った方が早いかも。

    2006年8月28日 3:15
  • keybd_eventでVK_KANJIを使うという方法もあるかもしれません。

    2006年8月28日 4:02
    モデレータ
  • SendInputを使ったほうがいいということで、検索をしてみました。

    http://www.bcap.co.jp/hanafusa/VBHLP/SendInput.htm

    上記のようなページがヒットしましたが、如何せんVBのため少し手間取っています。

    もしよろしければ、C#でのSendInputのサンプル等(ボタンをクリックで半角/全角を切り替える等)をアドバイスしていただけるとうれしいです。

    2006年8月28日 4:32
  • SendInputが推奨されているんですね。Orz      すみません。

    そういうわけでSendInputでテストコード書いてみました。一応、動いています。

    
    const int KEYEVENTF_KEYUP = 0x2;
    const int VK_KANJI = 0x19;
    
    const int INPUT_MOUSE = 0;
    const int INPUT_KEYBOARD = 1;
    const int INPUT_HARDWARE = 2;
    
    [DllImport("user32.dll")]
    static extern int SendInput(int nInputs, ref INPUT pInputs, int cbSize);
    
    [DllImport("user32.dll")]
    static extern IntPtr GetMessageExtraInfo();
    
    private struct MOUSEINPUT
    {
      public int dx;
      public int dy;
      public uint mouseData;
      public uint dwFlags;
      public uint time;
      public IntPtr dwExtraInfo;
    }
    
    private struct KEYBDINPUT
    {
      public ushort wVk;
      public ushort wScan;
      public uint dwFlags;
      public uint time;
      public IntPtr dwExtraInfo;
    }
    
    private struct HARDWAREINPUT
    {
      public uint uMsg;
      public ushort wParamL;
      public ushort wParamH;
    }
    
    [StructLayout(LayoutKind.Explicit)]
    private struct INPUT
    {
      [FieldOffset(0)]
      public uint type;
      [FieldOffset(4)]
      public MOUSEINPUT mi;
      [FieldOffset(4)]
      public KEYBDINPUT ki;
      [FieldOffset(4)]
      public HARDWAREINPUT hi;
    }
    
    
    private void cbtn_sendInput_Click(object sender, EventArgs e)
    {
      textBox1.Focus();
    
      INPUT input = new INPUT();
      input.type = INPUT_KEYBOARD;
      input.ki.wScan = 0;
      input.ki.time = 0;
      input.ki.dwExtraInfo = GetMessageExtraInfo();
    
      input.ki.wVk = (ushort)VK_KANJI;
      input.ki.dwFlags = 0;      //Key Down
    
      SendInput(1, ref input, Marshal.SizeOf(typeof(INPUT)));
    
      input.ki.wVk = (ushort)VK_KANJI;
      input.ki.dwFlags = KEYEVENTF_KEYUP;  //Key Up
    
      SendInput(1, ref input, Marshal.SizeOf(typeof(INPUT)));
    }
    
    2006年8月28日 6:51
    モデレータ
  • 早速のお返事有難うございます。

    テストコードを実際に使用してみました。

    ビルドをすると、

    名前'input'は現在のコンテキスト内に存在しません。

    というエラーが出てしまいます。

    2006年8月28日 7:24
  • ボタンクリックのイベントプロシージャ内で、
    INPUT input = new INPUT();
    の後の数行が抜けており、投稿した後にすぐに追加訂正したので、すみませんが、もう一度投稿したソースをよく見ていただけませんか?
    2006年8月28日 7:38
    モデレータ
  • 有難うございます。

    ご指摘の通りにしてみたところ、無事にできました。

    ほかのキーにたいしてもtrapemiya様のソースを参考に制作してみます。

    2006年8月28日 7:51