WPF 发送键盘消息 三种解决方案
如下适合一般的键盘发送消息,不适合DX消息机制。
第一种----------------------------
using System.Windows.Forms;
System.Windows.Forms.SendKeys.SendWait("{Left}");//原来写法
SendKeys.SendWait("{Left}");
第二种-----------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Input;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.ComponentModel;
namespace KinectController
{
class KeyboardToolkit
{
internal static class NativeMethods
{
#region User32
// Various Win32 constants
internal const int KeyeventfKeyup = 0x0002;
internal const int KeyeventfScancode = 0x0008;
internal const int InputKeyboard = 1;
// Various Win32 data structures
[StructLayout(LayoutKind.Sequential)]
internal struct INPUT
{
internal int type;
internal INPUTUNION union;
};
[StructLayout(LayoutKind.Explicit)]
internal struct INPUTUNION
{
[FieldOffset(0)]
internal MOUSEINPUT mouseInput;
[FieldOffset(0)]
internal KEYBDINPUT keyboardInput;
};
[StructLayout(LayoutKind.Sequential)]
internal struct MOUSEINPUT
{
internal int dx;
internal int dy;
internal int mouseData;
internal int dwFlags;
internal int time;
internal IntPtr dwExtraInfo;
};
[StructLayout(LayoutKind.Sequential)]
internal struct KEYBDINPUT
{
internal short wVk;
internal short wScan;
internal int dwFlags;
internal int time;
internal IntPtr dwExtraInfo;
};
// Importing various Win32 APIs that we need for input
[DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
internal static extern int GetSystemMetrics(int nIndex);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
internal static extern int MapVirtualKey(int nVirtKey, int nMapType);
[DllImport("user32.dll", SetLastError = true)]
internal static extern int SendInput(int nInputs, ref INPUT mi, int cbSize);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
internal static extern short VkKeyScan(char ch);
#endregion User32
}
public static class Keyboard
{
/// <summary>
/// Presses down a key.
/// </summary>
/// <param name="key">The key to press.</param>
public static void Press(Key key)
{
SendKeyboardInput(key, true);
}
/// <summary>
/// Releases a key.
/// </summary>
/// <param name="key">The key to release.</param>
public static void Release(Key key)
{
SendKeyboardInput(key, false);
}
/// <summary>
/// Resets the system keyboard to a clean state.
/// </summary>
public static void Reset()
{
foreach (Key key in Enum.GetValues(typeof(Key)))
{
if (key != Key.None && (System.Windows.Input.Keyboard.GetKeyStates(key) & KeyStates.Down) > 0)
{
Release(key);
}
}
}
/// <summary>
/// Performs a press-and-release operation for the specified key, which is effectively equivallent to typing.
/// </summary>
/// <param name="key">The key to press.</param>
public static void Type(Key key)
{
Press(key);
//System.Threading.Thread.Sleep(100);
Release(key);
}
[PermissionSet(SecurityAction.Assert, Name = "FullTrust")]
private static void SendKeyboardInput(Key key, bool press)
{
PermissionSet permissions = new PermissionSet(PermissionState.Unrestricted);
permissions.Demand();
NativeMethods.INPUT ki = new NativeMethods.INPUT();
ki.type = NativeMethods.InputKeyboard;
ki.union.keyboardInput.wVk = (short)KeyInterop.VirtualKeyFromKey(key);
ki.union.keyboardInput.wScan = (short)NativeMethods.MapVirtualKey(ki.union.keyboardInput.wVk, 0);
int dwFlags = 0;
if (ki.union.keyboardInput.wScan > 0)
{
dwFlags |= NativeMethods.KeyeventfScancode;
}
if (!press)
{
dwFlags |= NativeMethods.KeyeventfKeyup;
}
ki.union.keyboardInput.dwFlags = dwFlags;
ki.union.keyboardInput.time = 0;
ki.union.keyboardInput.dwExtraInfo = new IntPtr(0);
if (NativeMethods.SendInput(1, ref ki, Marshal.SizeOf(ki)) == 0)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
}
}
}
KeyboardToolkit.Keyboard.Type(Key.Right);//按下右键
第三种-------------------------------
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace KinectController
{
public class WinIo
{
private const int KBC_KEY_CMD = 0x64;
private const int KBC_KEY_DATA = 0x60;
[DllImport("winio32.dll")]
private static extern bool InitializeWinIo();
[DllImport("winio32.dll")]
private static extern bool GetPortVal(IntPtr wPortAddr, out int pdwPortVal, byte bSize);
[DllImport("winio32.dll")]
private static extern bool SetPortVal(uint wPortAddr, IntPtr dwPortVal, byte bSize);
[DllImport("winio32.dll")]
private static extern byte MapPhysToLin(byte pbPhysAddr, uint dwPhysSize, IntPtr PhysicalMemoryHandle);
[DllImport("winio32.dll")]
private static extern bool UnmapPhysicalMemory(IntPtr PhysicalMemoryHandle, byte pbLinAddr);
[DllImport("winio32.dll")]
private static extern bool GetPhysLong(IntPtr pbPhysAddr, byte pdwPhysVal);
[DllImport("winio32.dll")]
private static extern bool SetPhysLong(IntPtr pbPhysAddr, byte dwPhysVal);
[DllImport("winio32.dll")]
private static extern void ShutdownWinIo();
[DllImport("user32.dll")]
private static extern int MapVirtualKey(uint Ucode, uint uMapType);
private WinIo()
{
IsInitialize = true;
}
public static void Initialize()
{
ShutdownWinIo();
if (InitializeWinIo())
{
KBCWait4IBE();
IsInitialize = true;
}
else
{
//MessageBox.Show("键盘驱动加载失败!");
}
}
public static void Shutdown()
{
if (IsInitialize)
ShutdownWinIo();
IsInitialize = false;
}
private static bool IsInitialize { get; set; }
///等待键盘缓冲区为空
private static void KBCWait4IBE()
{
int dwVal = 0;
do
{
bool flag = GetPortVal((IntPtr)0x64, out dwVal, 1);
}
while ((dwVal & 0x2) > 0);
}
/// 模拟键盘标按下
public static void KeyDown(Keys vKeyCoad)
{
if (!IsInitialize) return;
int btScancode = 0;
btScancode = MapVirtualKey((uint)vKeyCoad, 0);
KBCWait4IBE();
SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, 1);
KBCWait4IBE();
SetPortVal(KBC_KEY_DATA, (IntPtr)0x60, 1);
KBCWait4IBE();
SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, 1);
KBCWait4IBE();
SetPortVal(KBC_KEY_DATA, (IntPtr)btScancode, 1);
}
/// 模拟键盘弹出
public static void KeyUp(Keys vKeyCoad)
{
if (!IsInitialize) return;
int btScancode = 0;
btScancode = MapVirtualKey((uint)vKeyCoad, 0);
KBCWait4IBE();
SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, 1);
KBCWait4IBE();
SetPortVal(KBC_KEY_DATA, (IntPtr)0x60, 1);
KBCWait4IBE();
SetPortVal(KBC_KEY_CMD, (IntPtr)0xD2, 1);
KBCWait4IBE();
SetPortVal(KBC_KEY_DATA, (IntPtr)(btScancode | 0x80), 1);
}
}
}
private WinIo winIo;
WinIo.KeyDown(Keys.A);
WinIo.KeyUp(Keys.A); // 松开A
WinIo.Shutdown(); // 用完后注销


浙公网安备 33010602011771号