原来的Input结构体为如下,导致只能在32位下运行,
using System;
using System.Runtime.InteropServices;
using System.Drawing;
namespace CAXA.MES.ScreenKeyboard {
[StructLayout(LayoutKind.Sequential)]
internal struct MOUSEINPUT {
public int dx;
public int dy;
public int mouseData;
public int dwFlags;
public int time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
internal struct KEYBDINPUT {
public short wVk;
public short wScan;
public int dwFlags;
public int time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Explicit)]
internal struct Input {
[FieldOffset(0)]
public int type;
[FieldOffset(4)]
public MOUSEINPUT mi;
[FieldOffset(4)]
public KEYBDINPUT ki;
[FieldOffset(4)]
public HARDWAREINPUT hi;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HARDWAREINPUT {
public int uMsg;
public short wParamL;
public short wParamH;
}
internal class INPUT {
public const int MOUSE = 0;
public const int KEYBOARD = 1;
public const int HARDWARE = 2;
}
internal static class NativeMethods {
[DllImport("User32.dll", CharSet = CharSet.Auto, SetLastError = false)]
internal static extern IntPtr GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("User32.dll", CharSet = CharSet.Auto, SetLastError = false)]
internal static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("User32.dll", EntryPoint = "SendInput", CharSet = CharSet.Auto)]
internal static extern UInt32 SendInput(UInt32 nInputs, Input[] pInputs, Int32 cbSize);
[DllImport("Kernel32.dll", EntryPoint = "GetTickCount", CharSet = CharSet.Auto)]
internal static extern int GetTickCount();
[DllImport("Kernel32.dll")]
public static extern IntPtr GetModuleHandle(string name);
[DllImport("User32.dll", EntryPoint = "GetKeyState", CharSet = CharSet.Auto)]
internal static extern short GetKeyState(int nVirtKey);
[DllImport("User32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
internal static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
}
}
调用,
private void SendKeyDown(short key)
{
Input[] input = new Input[1];
input[0].type = INPUT.KEYBOARD;
input[0].mkhi.ki.wVk = key;
input[0].mkhi.ki.time = NativeMethods.GetTickCount();
if (SendInput((uint)input.Length, input, Marshal.SizeOf(input[0])) < input.Length)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
测试的时候发现只能运行在32位下,在64位下运行,始终按键不能发送到文本框中。
经过很长时间的搜索,终于在Stackoverflow上找到了正确答案,虽然原因还是理解不透,
https://stackoverflow.com/questions/6830651/sendinput-and-64bits
问题出在Input结构体上,64位是8个字节的偏移,这个网友给出的答案,
[StructLayout(LayoutKind.Explicit)]
struct MouseKeybdHardwareInputUnion
{
[FieldOffset(0)]
public MOUSEINPUT mi;
[FieldOffset(0)]
public KEYBDINPUT ki;
[FieldOffset(0)]
public HARDWAREINPUT hi;
}
[StructLayout(LayoutKind.Sequential)]
struct Input
{
public uint type;
public MouseKeybdHardwareInputUnion mkhi;
}
改为上面这个就好了32位和64位都能发送。

博客内容讲述了在使用User32-SendInput函数模拟数字键盘输入时遇到的32位和64位兼容性问题。原来的方法仅能在32位系统下运行,而在64位系统中,SendInput无法将按键发送到文本框。作者通过在Stackoverflow上找到的解决方案,调整了Input结构体,解决了在64位环境下运行的问题。
6892

被折叠的 条评论
为什么被折叠?



