キーの置き換えをwpfで行おうとしました
方法としては、SetWindowHookEXとWH_KEYBOARD_LLでグローバルフックを行い
SendInput、またはkeybd_eventで仮想キーを送ろうとしました
しかし、仮想キーを送ろうとすると
WM_KEYDOWN nVirtKey:'0' cRepeat:34 ScanCode:00 fExtended:0 fAltDown:0 fRepeat:1 fUp:0
とspy++で調べた所、1入力に対し34回の出力を繰り返しているようです
グローバルフックを使わずにSendInputをコントロール内で行った場合は、1入力に対し1回の出力
SendInput等を使わずにグローバルフックをしてSystem.Windows.Forms.SendKeys.SendWait("a");
とした場合も1入力に対し1回の出力
となったのですが、何故グローバルフックをしてSendInputを行うと34回も繰り返してしまうのでしょうか
using System;
using System.Windows;
using System.Windows.Input;
using System.Runtime.InteropServices;
using System.Diagnostics;
public Key start = Key.B; // キーをセット
int count = 0; // 回数
[DllImport("user32.dll")]
public static extern uint keybd_event(byte bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo);
//----------------------------------------------------------
private delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
private const int WH_KEYBOARD_LL = 0x0D;
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern bool UnhookWindowsHookEx(int idHook);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr GetModuleHandle(String lpModuleName);
private static int hHook = 0;
HookProc KeyboardHookProcedure;
private int KeyboardHookProc(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode < 0)
{
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
else
{
// 動作の記述 -----------------------------------------------
if (Keyboard.IsKeyDown(start))
{
keybd_event(0x30, 0, 0, (UIntPtr)0);
count++;
textBlock1.Text = count.ToString();
}
// ----------------------------------------------------
}
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
}
// キーフック開始
if (hHook == 0)
{
using (Process process = Process.GetCurrentProcess())
using (ProcessModule module = process.MainModule)
{
KeyboardHookProcedure = new HookProc(KeyboardHookProc);
hHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, GetModuleHandle(module.ModuleName), 0);
}
}
else
{
bool ret = UnhookWindowsHookEx(hHook);
//If the UnhookWindowsHookEx function fails.
if (ret == false)
{
System.Windows.MessageBox.Show("UnhookWindowsHookEx Failed");
return;
}
hHook = 0;
}