キーストロークをサードパーティのアプリケーションに送信する必要があるオンスクリーンキーボードを使用しています。それらはWindowsXPで実行されています。米国英語キーボードでは使用できない小さな文字セット(「å」やñなど)をサポートする必要があります。SendInputを確認した後、最も安全なのは、文字の16進Unicode値をキーストロークシーケンスとして送信することであるように思われました。「Alt」および「Add」キーダウンイベントを送信し、続いてAltキーORを使用した4文字のUnicodeシーケンスのキーダウンおよびアップイベントを送信し、最後に「Add」および「Alt」キーアップイベントを送信するコードを作成しました。私のC#テストアプリで。私はKeyPreviewを使用していますが、確かにすべてのイベントが発生していますが、ビープ音だけが鳴り、キャラクターは鳴りません。キーストロークを手動で入力した場合と同じ情報を取得しました。
このようにSendInputを使用することは可能ですか?データを調べるためにフックを使用したことはありませんが、SendInputイベントに何らかの「挿入された」フラグが付加されていることを示す投稿を見ました。これにより、シーケンスが失敗する可能性がありますか?
このデモコードはキーイベントを正常に送信しますが、Unicode文字を生成することを目的とした一連のキーイベントは失敗します。
private const uint KEYEVENTF_KEYDOWN = 0x0000;
private const uint KEYEVENTF_EXTENDEDKEY = 0x0001;
private const uint KEYEVENTF_KEYUP = 0x0002;
private const int INPUT_KEYBOARD = 1;
[DllImport ("user32.dll", SetLastError = false)]
static extern IntPtr GetMessageExtraInfo ();
[DllImport ("user32.dll", SetLastError = true)]
static extern uint SendInput (uint nInputs, [MarshalAs (UnmanagedType.LPArray, SizeConst = 1)] INPUT[] pInputs, int cbSize);
[StructLayout (LayoutKind.Sequential, Size = 24)]
private struct KEYBDINPUT
{
public ushort wVk;
public ushort wScan;
public uint dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}
[StructLayout (LayoutKind.Explicit)]
private struct INPUT
{
[FieldOffset (0)]
public int type;
[FieldOffset (4)]
public KEYBDINPUT ki;
}
private void PressKey (Keys k)
{
PressKeyDown (k);
PressKeyUp (k);
}
private void PressKeyDown (Keys k)
{
INPUT input = new INPUT ();
input.type = INPUT_KEYBOARD;
input.ki.wVk = (byte)k;
input.ki.wScan = 0;
input.ki.time = 0;
uint flags = KEYEVENTF_KEYDOWN;
if ((33 <= (byte)k && (byte)k <= 46) || (91 <= (byte)k) && (byte)k <= 93)
flags |= KEYEVENTF_EXTENDEDKEY;
input.ki.dwFlags = flags;
input.ki.dwExtraInfo = GetMessageExtraInfo ();
Output ("Sending key down {0}. Flags:{1}", k, flags);
INPUT[] inputs = new INPUT[] { input };
uint result = SendInput ((uint)inputs.Length, inputs, Marshal.SizeOf (typeof (INPUT)));
if ((uint)inputs.Length != result)
MessageBox.Show ("PressKeyDown result = " + Marshal.GetLastWin32Error ());
}
private void PressKeyUp (Keys k)
{
INPUT input = new INPUT ();
input.type = INPUT_KEYBOARD;
input.ki.wVk = (byte)k;
input.ki.wScan = 0;
input.ki.time = 0;
uint flags = KEYEVENTF_KEYUP;
if ((33 <= (byte)k && (byte)k <= 46) || (91 <= (byte)k) && (byte)k <= 93)
flags |= KEYEVENTF_EXTENDEDKEY;
input.ki.dwFlags = flags;
input.ki.dwExtraInfo = GetMessageExtraInfo ();
Output ("Sending key up {0}", k);
INPUT[] inputs = new INPUT[] { input };
uint result = SendInput ((uint)inputs.Length, inputs, Marshal.SizeOf (typeof (INPUT)));
if ((uint)inputs.Length != result)
MessageBox.Show ("PressKeyUp result = " + Marshal.GetLastWin32Error ());
}
private void TestSend ()
{
System.Threading.Thread.CurrentThread.Join (1000);
Keys k = Keys.Menu;
PressKeyDown (k);
System.Threading.Thread.Sleep (100);
k = Keys.Add;
k |= Keys.Alt;
PressKeyDown (k);
System.Threading.Thread.Sleep (100);
k = Keys.NumPad0;
k |= Keys.Alt;
PressKey (k);
System.Threading.Thread.Sleep (100);
k = Keys.NumPad0;
k |= Keys.Alt;
PressKey (k);
System.Threading.Thread.Sleep (100);
k = Keys.E;
k |= Keys.Alt;
PressKey (k);
System.Threading.Thread.Sleep (100);
k = Keys.NumPad5;
k |= Keys.Alt;
PressKey (k);
System.Threading.Thread.Sleep (100);
PressKeyUp (Keys.Add);
PressKeyUp (Keys.Menu);
}