对外部程序,以记事本为例,xaml中设置模拟按键的控件 Focusable="False":
/// <summary>
/// 发送按键
/// </summary>
/// <param name="asiiCode">键盘ascii码</param>
private void SendKey(byte asiiCode)
{
try
{
int getFocus = ;
AttachThreadInput(true, ref getFocus);
Win32API.SetForegroundWindow((IntPtr)getFocus); Win32API.Keybd_event(asiiCode, 0x45, 0x1 | , );//keydowm
Win32API.Keybd_event(asiiCode, 0x45, 0x1 | 0x2, );//keyup
AttachThreadInput(false, ref getFocus); //取消线程亲和的关联
}
catch (Exception ex)
{
MessageBox.Show("SendKey:" + ex.ToString());
}
} /// <summary>
/// 设置线程亲和,附到前台窗口所在线程,只有在线程内才可以获取线程内控件的焦点
/// </summary>
/// <param name="b">是否亲和</param>
private void AttachThreadInput(bool b,ref int hwnd)
{
try
{
Process[] processes = Process.GetProcessesByName("notepad");
if (processes.Length == )
{
return;
}
int processId = processes[].Id;
hwnd = processes[].MainWindowHandle.ToInt32(); Win32API.AttachThreadInput(
processId,
Win32API.GetCurrentThreadId(), Convert.ToInt32(b));
}
catch (Exception ex)
{
MessageBox.Show("AttachThreadInput:" + ex.ToString());
}
}
对内部窗口(可引用该虚拟键盘组件的),不用考虑焦点问题(焦点在哪就在哪输出),做好Keybd_event就行了
不推荐SendMessage、PostMessage等方法发送按键,实在不行推荐使用SendWait
以上相关底层调用方法:
[DllImport("user32.dll", EntryPoint = "keybd_event")]
public static extern void Keybd_event(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo); [DllImport("user32.dll")]
public static extern int AttachThreadInput(
int idAttach,
int idAttachTo,
int fAttach); [DllImport("kernel32.dll")]
public static extern int GetCurrentThreadId(); [DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);