我想在WPF应用程序中区分(条形码)扫描仪和键盘输入。 我需要的是每当我的扫描仪提供数据时发生的事件。
在我的应用程序中,有一个特殊字段,将填充扫描仪的输入。因此,如果用户已经聚焦了另一个字段,我不想在其中插入扫描的代码,而是我的专业领域。
首先,我将扫描仪的输入模式(通过USB连接)从“键盘仿真”切换为“原始”。但是我现在需要做什么呢?
答案 0 :(得分:5)
实施OPOS或 WEPOS ( WEB内容无法提供任何)的扫描程序具有包装驱动程序的COM和/或.Net组件对于设备。扫描数据时,这些组件可能会引发事件。这些标准也适用于更多,包括磁条阅读器,秤,现金抽屉,更换分配器和MICR(支票)阅读器。
如果未提供xPOS驱动程序,则可能会获得USB /串行端口驱动程序。这使得设备看起来像是通过rs232连接到Windows。然后,您可以使用System.IO.Ports.SerialPort来编写“扫描仪”抽象。
另一个选择是获取.sys和.h文件。然后你正在做一些涉及PInvoke和可能一些C。
答案 1 :(得分:2)
我已经放弃了用POS for .NET实现这一目标的方法。只要您将扫描仪处理为您感兴趣的框架的唯一相关部分,就可以自己完成它。这基本上就是我正在使用的内容:
public class RawInput
{
private static IntPtr DispatchMessage(IntPtr lParam, IEnumerable<IntPtr> fromDevices, ref object data)
{
var dataSize = UIntPtr.Zero;
if (Win32.GetRawInputData(lParam, (UIntPtr)CommandFlag.Input, IntPtr.Zero, ref dataSize, (UIntPtr)Marshal.SizeOf(typeof(Win32.RAWINPUTHEADER))) == UIntPtr.Zero)
{
var buff = Marshal.AllocHGlobal((int)dataSize);
var outSize = Win32.GetRawInputData(lParam, (UIntPtr)CommandFlag.Input, buff, ref dataSize, (UIntPtr)Marshal.SizeOf(typeof(Win32.RAWINPUTHEADER)));
Debug.Assert(outSize == dataSize);
var input = (Win32.RAWINPUT)Marshal.PtrToStructure(buff, typeof(Win32.RAWINPUT));
var hDevice = IntPtr.Zero;
if (fromDevices == null)
hDevice = input.header.hDevice;
else
hDevice = fromDevices.FirstOrDefault(h => h == input.header.hDevice);
if (hDevice != IntPtr.Zero)
{
switch ((Type)input.header.dwType)
{
case Type.HID:
var hidData = new HIDDATA()
{
count = input.hid.dwCount,
size = input.hid.dwSizeHid,
raw = new byte[input.hid.dwCount * input.hid.dwSizeHid]
};
Marshal.Copy(
new IntPtr(
buff.ToInt64() +
Marshal.SizeOf(typeof(Win32.RAWINPUTHEADER)) +
Marshal.SizeOf(typeof(Win32.RAWHID))
),
hidData.raw, 0, hidData.raw.Length
);
data = hidData;
break;
case Type.Keyboard:
data = new KEYBOARDDATA
{
makeCode = input.keyboard.MakeCode,
flags = (KeyboardFlag)input.keyboard.Flags,
vKey = input.keyboard.VKey,
message = (MessageContext)input.keyboard.Message,
extraInfo = input.keyboard.ExtraInformation
};
break;
case Type.Mouse:
var mouseData = new MOUSEDATA
{
extraInfo = input.mouse.ulExtraInformation,
flags = (MouseFlag)input.mouse.usFlags,
transitions = (MouseTransition)input.mouse.usButtonFlags,
motionX = input.mouse.lLastX,
motionY = input.mouse.lLastY
};
if (mouseData.transitions == MouseTransition.MouseWheel)
mouseData.wheelDelta = input.mouse.usButtonData;
data = mouseData;
break;
}
}
Marshal.FreeHGlobal(buff);
return hDevice;
}
else
throw new ApplicationException("An error occurred while receiving raw input data.");
}
public static bool DispatchMessage(Win32.MSG message, IEnumerable<Device> fromDevices, ref Device source, ref object data)
{
var hDevice = IntPtr.Zero;
if (message.message == MessageContext.Input)
{
if (fromDevices != null)
{
hDevice = DispatchMessage(message.lParam, fromDevices.Select(h => h.Handle), ref data);
if (hDevice != IntPtr.Zero)
source = fromDevices.First(h => h.Handle == hDevice);
}
else
{
Func<Device> getRawInputDeviceInfo = () =>
{
var name_size = UIntPtr.Zero;
Win32.GetRawInputDeviceInfo(hDevice, (UIntPtr)Win32.RIDI_DEVICENAME, IntPtr.Zero, ref name_size);
if (name_size != UIntPtr.Zero)
{
var name = Marshal.AllocHGlobal((int)name_size);
Win32.GetRawInputDeviceInfo(hDevice, (UIntPtr)Win32.RIDI_DEVICENAME, name, ref name_size);
string rid_name = (string)Marshal.PtrToStringAnsi(name);
var ridSize = (UIntPtr)Marshal.SizeOf(typeof(Win32.RID_DEVICE_INFO));
var buff = Marshal.AllocHGlobal((int)ridSize);
var outSize = Win32.GetRawInputDeviceInfo(hDevice, (UIntPtr)Win32.RIDI_DEVICEINFO, buff, ref ridSize);
Debug.Assert(outSize == ridSize);
var rid = (Win32.RID_DEVICE_INFO)Marshal.PtrToStructure(buff, typeof(Win32.RID_DEVICE_INFO));
var device = new Device()
{
Handle = hDevice,
ID = rid_name,
Type = (Type)rid.dwType,
Description = GetRawInputDeviceDescription(rid_name)
};
Marshal.FreeHGlobal(name);
return device;
}
return null;
};
hDevice = DispatchMessage(message.lParam, null, ref data);
if (hDevice != IntPtr.Zero)
source = getRawInputDeviceInfo();
}
}
return hDevice != IntPtr.Zero;
}
public static IEnumerable<Device> EnumerateDevices()
{
var ridSize = (UIntPtr)Marshal.SizeOf(typeof(Win32.RAWINPUTDEVICELIST));
var ridCnt = UIntPtr.Zero;
var list = new List<Device>();
if (Win32.GetRawInputDeviceList(IntPtr.Zero, ref ridCnt, ridSize) == UIntPtr.Zero)
{
var buff = Marshal.AllocHGlobal((int)ridCnt * (int)ridSize);
Win32.GetRawInputDeviceList(buff, ref ridCnt, ridSize);
for (int i = 0; i < (int)ridCnt; ++i)
{
var rid = (Win32.RAWINPUTDEVICELIST)Marshal.PtrToStructure(
new IntPtr((buff.ToInt64() + (int)ridSize * i)),
typeof(Win32.RAWINPUTDEVICELIST)
);
var nameSize = UIntPtr.Zero;
Win32.GetRawInputDeviceInfo(rid.hDevice, (UIntPtr)Win32.RIDI_DEVICENAME, IntPtr.Zero, ref nameSize);
if (nameSize != UIntPtr.Zero)
{
var name = Marshal.AllocHGlobal((int)nameSize);
Win32.GetRawInputDeviceInfo(rid.hDevice, (UIntPtr)Win32.RIDI_DEVICENAME, name, ref nameSize);
string rid_id = (string)Marshal.PtrToStringAnsi(name);
// filter Terminal Services and Remote Desktop devices.
if (!rid_id.ToUpper().Contains("ROOT"))
{
yield return new Device()
{
Handle = rid.hDevice,
ID = rid_id,
Type = (Type)rid.dwType,
Description = GetRawInputDeviceDescription(rid_id)
};
Marshal.FreeHGlobal(name);
}
}
}
Marshal.FreeHGlobal(buff);
}
else
throw new ApplicationException("An error occurred while retrieving a list of raw input devices");
}
public static void Register(IntPtr hwnd, REGISTERCLASS[] regs)
{
Debug.Assert(hwnd != IntPtr.Zero);
// Usage Pages and Usages:
// http://www.usb.org/developers/devclass_docs/Hut1_12.pdf
var rid = new Win32.RAWINPUTDEVICE[regs.Length];
for (int i = 0; i < regs.Length; ++i)
{
rid[i].dwFlags = (uint)regs[i].flags;
rid[i].usUsage = regs[i].usage;
rid[i].usUsagePage = (ushort)regs[i].usagePage;
rid[i].hwndTarget = hwnd;
}
if (Win32.RegisterRawInputDevices(rid, (UIntPtr)rid.Length, (UIntPtr)Marshal.SizeOf(typeof(Win32.RAWINPUTDEVICE))) == IntPtr.Zero)
throw new ApplicationException("Failed to register raw input devices");
}
public class Device
{
public static bool operator ==(Device x, Device y) { if ((object)x != null & (object)y != null) { return x.Handle == y.Handle; } else return (object)x == null && (object)y == null; }
public static bool operator !=(Device x, Device y) { return !(x == y); }
public override bool Equals(object obj) { return this == (Device)obj; }
public override int GetHashCode() { return base.GetHashCode(); }
public IntPtr Handle { get; set; }
public Type Type { get; set; }
public string ID { get; set; }
public string Description { get; set; }
}
public struct HIDDATA
{
public uint size;
public uint count;
public byte[] raw;
}
public struct KEYBOARDDATA
{
public ushort makeCode;
public KeyboardFlag flags;
public ushort vKey;
public MessageContext message;
public uint extraInfo;
}
public struct MOUSEDATA
{
public MouseFlag flags;
public MouseTransition transitions;
public ushort wheelDelta;
public int motionX;
public int motionY;
public uint extraInfo;
}
public struct REGISTERCLASS
{
public UsagePage usagePage;
public ushort usage;
public ModeFlag flags;
}
public enum KeyboardFlag : ushort
{
KeyUp = Win32.RI_KEY_BREAK,
KeyDown = Win32.RI_KEY_MAKE,
KeyLeft = Win32.RI_KEY_E0,
KeyRight = Win32.RI_KEY_E1
}
public enum MouseFlag : ushort
{
AttributesChanged = Win32.MOUSE_ATTRIBUTES_CHANGED,
MoveRelative = Win32.MOUSE_MOVE_RELATIVE,
MoveAbsolute = Win32.MOUSE_MOVE_ABSOLUTE,
VirtualDesktop = Win32.MOUSE_VIRTUAL_DESKTOP
}
public enum MouseTransition : ushort
{
LeftButtonDown = Win32.RI_MOUSE_LEFT_BUTTON_DOWN,
LeftButtonUp = Win32.RI_MOUSE_LEFT_BUTTON_UP,
MiddleButtonDown = Win32.RI_MOUSE_MIDDLE_BUTTON_DOWN,
MiddleButtonUp = Win32.RI_MOUSE_MIDDLE_BUTTON_UP,
RightButtonDown = Win32.RI_MOUSE_RIGHT_BUTTON_DOWN,
RightButtonUp = Win32.RI_MOUSE_RIGHT_BUTTON_UP,
XButton1Down = Win32.RI_MOUSE_BUTTON_4_DOWN,
XButton1Up = Win32.RI_MOUSE_BUTTON_4_UP,
XButton2Down = Win32.RI_MOUSE_BUTTON_5_DOWN,
XButton2Up = Win32.RI_MOUSE_BUTTON_5_UP,
MouseWheel = Win32.RI_MOUSE_WHEEL
}
public enum CommandFlag
{
Header = Win32.RID_HEADER,
Input = Win32.RID_INPUT
}
public enum ModeFlag : uint
{
Default = 0,
ApplicationKeys = Win32.RIDEV_APPKEYS,
CaptureMouse = Win32.RIDEV_CAPTUREMOUSE,
DeviceNotify = Win32.RIDEV_DEVNOTIFY,
Exclude = Win32.RIDEV_EXCLUDE,
ExcludeInputSink = Win32.RIDEV_EXINPUTSINK,
InputSink = Win32.RIDEV_INPUTSINK,
NoHotKeys = Win32.RIDEV_NOHOTKEYS,
NoLegacy = Win32.RIDEV_NOLEGACY,
PageOnly = Win32.RIDEV_PAGEONLY,
Remove = Win32.RIDEV_REMOVE
};
public enum UsagePage : ushort
{
Undefined = 0x00,
GenericDesktopControls = 0x01,
SimulationControls = 0x02,
VRControls = 0x03,
SportControls = 0x04,
GameControls = 0x05,
GenericDeviceControls = 0x06,
Keyboard = 0x07,
Keypad = Keyboard,
LEDs = 0x08,
Button = 0x09,
Ordinal = 0x0a,
Telephony = 0x0b,
Consumer = 0x0c,
Digitizer = 0x0d,
PIDPage = 0x0f,
Unicode = 0x10,
AlphanumericDisplay = 0x14,
MedicalInstruments = 0x40,
MonitorPage0 = 0x80,
MonitorPage1 = 0x81,
MonitorPage2 = 0x82,
MonitorPage3 = 0x83,
PowerPage0 = 0x84,
PowerPage1 = 0x85,
PowerPage2 = 0x86,
PowerPage3 = 0x87,
BarCodeScannerPages = 0x8c,
Scale = 0x8d,
MagneticStripeReadingDevices = 0x8e,
ReservedPointofSalePages = 0x8f,
CameraControlPage = 0x90,
ArcadePage = 0x91
}
/// <see cref="http://www.usb.org/developers/devclass_docs/pos1_02.pdf"/>
public enum BarCodeScannerPages : ushort
{
BarCodeScanner = 0x0002
}
public enum Type : uint
{
Mouse = Win32.RIM_TYPEMOUSE,
Keyboard = Win32.RIM_TYPEKEYBOARD,
HID = Win32.RIM_TYPEHID
}
private static string GetRawInputDeviceDescription(string deviceid)
{
string[] id = deviceid.Substring(4).Split('#');
// get registry entry by appropriate key
return ((string)Registry.LocalMachine.OpenSubKey(string.Format(
@"System\CurrentControlSet\Enum\{0}\{1}\{2}",
id[0], id[1], id[2]), false
).GetValue("DeviceDesc")).Split(';')[1];
}
}
class Win32
导入使用过的Win32 API函数并包含它们使用的一些常量:
public static class Win32
{
// mouse state flags
public const ushort MOUSE_ATTRIBUTES_CHANGED = 4, // Mouse attributes changed; application needs to query the mouse attributes.
MOUSE_MOVE_RELATIVE = 0, // Mouse movement data is relative to the last mouse position.
MOUSE_MOVE_ABSOLUTE = 1, // Mouse movement data is based on absolute position.
MOUSE_VIRTUAL_DESKTOP = 2; // Mouse coordinates are mapped to the virtual desktop (for a multiple monitor system).
// mouse transition state flags
public const ushort RI_MOUSE_LEFT_BUTTON_DOWN = 0x0001, // Left button changed to down.
RI_MOUSE_LEFT_BUTTON_UP = 0x0002, // Left button changed to up.
RI_MOUSE_MIDDLE_BUTTON_DOWN = 0x0010, // Middle button changed to down.
RI_MOUSE_MIDDLE_BUTTON_UP = 0x0020, // Middle button changed to up.
RI_MOUSE_RIGHT_BUTTON_DOWN = 0x0004, // Right button changed to down.
RI_MOUSE_RIGHT_BUTTON_UP = 0x0008, // Right button changed to up.
RI_MOUSE_BUTTON_1_DOWN = 0x0001, // RI_MOUSE_LEFT_BUTTON_DOWN
RI_MOUSE_BUTTON_1_UP = 0x0002, // RI_MOUSE_LEFT_BUTTON_UP
RI_MOUSE_BUTTON_2_DOWN = 0x0004, // RI_MOUSE_RIGHT_BUTTON_DOWN
RI_MOUSE_BUTTON_2_UP = 0x0008, // RI_MOUSE_RIGHT_BUTTON_UP
RI_MOUSE_BUTTON_3_DOWN = 0x0010, // RI_MOUSE_MIDDLE_BUTTON_DOWN
RI_MOUSE_BUTTON_3_UP = 0x0020, // RI_MOUSE_MIDDLE_BUTTON_UP
RI_MOUSE_BUTTON_4_DOWN = 0x0040, // XBUTTON1 changed to down.
RI_MOUSE_BUTTON_4_UP = 0x0080, // XBUTTON1 changed to up.
RI_MOUSE_BUTTON_5_DOWN = 0x0100, // XBUTTON2 changed to down.
RI_MOUSE_BUTTON_5_UP = 0x0200, // XBUTTON2 changed to up.
RI_MOUSE_WHEEL = 0x0400; // Raw input comes from a mouse wheel. The wheel delta is stored in usButtonData.
// keyboard scan code flags
public const ushort RI_KEY_BREAK = 1,
RI_KEY_E0 = 2,
RI_KEY_E1 = 4,
RI_KEY_MAKE = 0;
// device types
public const int RIM_TYPEMOUSE = 0,
RIM_TYPEKEYBOARD = 1,
RIM_TYPEHID = 2;
public const int RIDI_PREPARSEDDATA = 0x20000005,
RIDI_DEVICENAME = 0x20000007, // the return valus is the character length, not the byte size
RIDI_DEVICEINFO = 0x2000000b;
// mode flags
public const int RIDEV_REMOVE = 0x00000001,
RIDEV_EXCLUDE = 0x00000010,
RIDEV_PAGEONLY = 0x00000020,
RIDEV_NOLEGACY = 0x00000030,
RIDEV_INPUTSINK = 0x00000100,
RIDEV_CAPTUREMOUSE = 0x00000200, // effective when mouse nolegacy is specified, otherwise it would be an error
RIDEV_NOHOTKEYS = 0x00000200, // effective for keyboard.
RIDEV_APPKEYS = 0x00000400, // effective for keyboard.
RIDEV_EXINPUTSINK = 0x00001000,
RIDEV_DEVNOTIFY = 0x00002000,
RIDEV_EXMODEMASK = 0x000000F0;
// command flag
public const int RID_HEADER = 0x10000005,
RID_INPUT = 0x10000003;
/// <summary>
/// Contains information about a raw input device.
/// </summary>
/// <remarks>
/// typedef struct tagRAWINPUTDEVICELIST {
/// HANDLE hDevice;
/// DWORD dwType;
/// } RAWINPUTDEVICELIST, *PRAWINPUTDEVICELIST;
/// </remarks>
[StructLayout(LayoutKind.Sequential)]
public struct RAWINPUTDEVICELIST
{
public IntPtr hDevice;
[MarshalAs(UnmanagedType.U4)]
public uint dwType;
}
/// <summary>
/// Defines information for the raw input devices.
/// </summary>
/// <remarks>
/// typedef struct tagRAWINPUTDEVICE {
/// USHORT usUsagePage;
/// USHORT usUsage;
/// DWORD dwFlags;
/// HWND hwndTarget;
/// } RAWINPUTDEVICE, *PRAWINPUTDEVICE, *LPRAWINPUTDEVICE;
/// </remarks>
[StructLayout(LayoutKind.Sequential)]
public struct RAWINPUTDEVICE
{
[MarshalAs(UnmanagedType.U2)]
public ushort usUsagePage;
[MarshalAs(UnmanagedType.U2)]
public ushort usUsage;
[MarshalAs(UnmanagedType.U4)]
public uint dwFlags;
public IntPtr hwndTarget;
}
/// <summary>
/// Contains information about the state of the mouse.
/// </summary>
/// <remarks>
/// typedef struct tagRAWMOUSE {
/// USHORT usFlags;
/// union {
/// ULONG ulButtons;
/// struct {
/// USHORT usButtonFlags;
/// USHORT usButtonData;
/// };
/// };
/// ULONG ulRawButtons;
/// LONG lLastX;
/// LONG lLastY;
/// ULONG ulExtraInformation;
/// } RAWMOUSE, *PRAWMOUSE, *LPRAWMOUSE;
/// </remarks>
[StructLayout(LayoutKind.Explicit)]
public struct RAWMOUSE
{
[FieldOffset(0), MarshalAs(UnmanagedType.U2)]
public ushort usFlags;
[FieldOffset(4), MarshalAs(UnmanagedType.U4)]
public uint ulButtons;
[FieldOffset(4), MarshalAs(UnmanagedType.U2)]
public ushort usButtonFlags;
[FieldOffset(6), MarshalAs(UnmanagedType.U2)]
public ushort usButtonData;
[FieldOffset(8), MarshalAs(UnmanagedType.U4)]
public uint ulRawButtons;
[FieldOffset(12), MarshalAs(UnmanagedType.I4)]
public int lLastX;
[FieldOffset(16), MarshalAs(UnmanagedType.I4)]
public int lLastY;
[FieldOffset(20), MarshalAs(UnmanagedType.U4)]
public uint ulExtraInformation;
}
/// <summary>
/// Contains information about the state of the keyboard.
/// </summary>
/// <remarks>
/// typedef struct tagRAWKEYBOARD {
/// USHORT MakeCode;
/// USHORT Flags;
/// USHORT Reserved;
/// USHORT VKey;
/// UINT Message;
/// ULONG ExtraInformation;
/// } RAWKEYBOARD, *PRAWKEYBOARD, *LPRAWKEYBOARD;
/// </remarks>
[StructLayout(LayoutKind.Sequential)]
public struct RAWKEYBOARD
{
[MarshalAs(UnmanagedType.U2)]
public ushort MakeCode;
[MarshalAs(UnmanagedType.U2)]
public ushort Flags;
[MarshalAs(UnmanagedType.U2)]
public ushort Reserved;
[MarshalAs(UnmanagedType.U2)]
public ushort VKey;
[MarshalAs(UnmanagedType.SysUInt)]
public UIntPtr Message;
[MarshalAs(UnmanagedType.U4)]
public uint ExtraInformation;
}
/// <summary>
/// Describes the format of the raw input from a Human Interface Device (HID).
/// </summary>
/// <remarks>
/// typedef struct tagRAWHID {
/// DWORD dwSizeHid;
/// DWORD dwCount;
/// BYTE bRawData[1];
/// } RAWHID, *PRAWHID, *LPRAWHID;
/// </remarks>
[StructLayout(LayoutKind.Sequential)]
public struct RAWHID
{
[MarshalAs(UnmanagedType.U4)]
public uint dwSizeHid;
[MarshalAs(UnmanagedType.U4)]
public uint dwCount;
}
/// <summary>
/// Contains the header information that is part of the raw input data.
/// </summary>
/// <remarks>
/// typedef struct tagRAWINPUTHEADER {
/// DWORD dwType;
/// DWORD dwSize;
/// HANDLE hDevice;
/// WPARAM wParam;
/// } RAWINPUTHEADER, *PRAWINPUTHEADER;
/// </remarks>
[StructLayout(LayoutKind.Sequential)]
public struct RAWINPUTHEADER
{
[MarshalAs(UnmanagedType.U4)]
public uint dwType;
[MarshalAs(UnmanagedType.U4)]
public uint dwSize;
public IntPtr hDevice;
[MarshalAs(UnmanagedType.SysUInt)]
public UIntPtr wParam;
}
/// <summary>
/// Contains the raw input from a device.
/// </summary>
/// <remarks>
/// typedef struct tagRAWINPUT {
/// RAWINPUTHEADER header;
/// union {
/// RAWMOUSE mouse;
/// RAWKEYBOARD keyboard;
/// RAWHID hid;
/// } data;
/// } RAWINPUT, *PRAWINPUT, *LPRAWINPUT;
/// </remarks>
[StructLayout(LayoutKind.Explicit)]
public struct RAWINPUT
{
[FieldOffset(0)]
public RAWINPUTHEADER header;
#if IA32
[FieldOffset(16)]
public RAWMOUSE mouse;
[FieldOffset(16)]
public RAWKEYBOARD keyboard;
[FieldOffset(16)]
public RAWHID hid;
#elif INTEL64
[FieldOffset(24)]
public RAWMOUSE mouse;
[FieldOffset(24)]
public RAWKEYBOARD keyboard;
[FieldOffset(24)]
public RAWHID hid;
#endif
}
/// <summary>
/// Defines the raw input data coming from the specified keyboard.
/// </summary>
/// <remarks>
/// typedef struct tagRID_DEVICE_INFO_KEYBOARD {
/// DWORD dwType;
/// DWORD dwSubType;
/// DWORD dwKeyboardMode;
/// DWORD dwNumberOfFunctionKeys;
/// DWORD dwNumberOfIndicators;
/// DWORD dwNumberOfKeysTotal;
/// } RID_DEVICE_INFO_KEYBOARD, *PRID_DEVICE_INFO_KEYBOARD;
/// </remarks>
[StructLayout(LayoutKind.Sequential)]
public struct RID_DEVICE_INFO_KEYBOARD
{
[MarshalAs(UnmanagedType.U4)]
public uint dwType;
[MarshalAs(UnmanagedType.U4)]
public uint dwSubType;
[MarshalAs(UnmanagedType.U4)]
public uint dwKeyboardMode;
[MarshalAs(UnmanagedType.U4)]
public uint dwNumberOfFunctionKeys;
[MarshalAs(UnmanagedType.U4)]
public uint dwNumberOfIndicators;
[MarshalAs(UnmanagedType.U4)]
public uint dwNumberOfKeysTotal;
}
/// <summary>
/// Defines the raw input data coming from the specified mouse.
/// </summary>
/// <remarks>
/// typedef struct tagRID_DEVICE_INFO_MOUSE {
/// DWORD dwId;
/// DWORD dwNumberOfButtons;
/// DWORD dwSampleRate;
/// BOOL fHasHorizontalWheel;
/// } RID_DEVICE_INFO_MOUSE, *PRID_DEVICE_INFO_MOUSE;
/// </remarks>
[StructLayout(LayoutKind.Sequential)]
public struct RID_DEVICE_INFO_MOUSE
{
[MarshalAs(UnmanagedType.U4)]
public uint dwId;
[MarshalAs(UnmanagedType.U4)]
public uint dwNumberOfButtons;
[MarshalAs(UnmanagedType.U4)]
public uint dwSampleRate;
[MarshalAs(UnmanagedType.SysInt)]
public IntPtr fHasHorizontalWheel;
}
/// <summary>
/// Defines the raw input data coming from the specified Human Interface Device (HID).
/// </summary>
/// <remarks>
/// typedef struct tagRID_DEVICE_INFO_HID {
/// DWORD dwVendorId;
/// DWORD dwProductId;
/// DWORD dwVersionNumber;
/// USHORT usUsagePage;
/// USHORT usUsage;
/// } RID_DEVICE_INFO_HID, *PRID_DEVICE_INFO_HID;
/// </remarks>
[StructLayout(LayoutKind.Sequential)]
public struct RID_DEVICE_INFO_HID
{
[MarshalAs(UnmanagedType.U4)]
public uint dwVendorId;
[MarshalAs(UnmanagedType.U4)]
public uint dwProductId;
[MarshalAs(UnmanagedType.U4)]
public uint dwVersionNumber;
[MarshalAs(UnmanagedType.U2)]
public ushort usUsagePage;
[MarshalAs(UnmanagedType.U2)]
public ushort usUsage;
}
/// <summary>
/// Defines the raw input data coming from any device.
/// </summary>
/// <remarks>
/// typedef struct tagRID_DEVICE_INFO {
/// DWORD cbSize;
/// DWORD dwType;
/// union {
/// RID_DEVICE_INFO_MOUSE mouse;
/// RID_DEVICE_INFO_KEYBOARD keyboard;
/// RID_DEVICE_INFO_HID hid;
/// } ;
/// } RID_DEVICE_INFO, *PRID_DEVICE_INFO, *LPRID_DEVICE_INFO;
/// </remarks>
[StructLayout(LayoutKind.Explicit)]
public struct RID_DEVICE_INFO
{
[FieldOffset(0), MarshalAs(UnmanagedType.U4)]
public uint cbSize;
[FieldOffset(4), MarshalAs(UnmanagedType.U4)]
public uint dwType;
[FieldOffset(8)]
public RID_DEVICE_INFO_MOUSE mouse;
[FieldOffset(8)]
public RID_DEVICE_INFO_KEYBOARD keyboard;
[FieldOffset(8)]
public RID_DEVICE_INFO_HID hid;
}
/// <summary>
/// The POINT structure defines the x- and y- coordinates of a point.
/// </summary>
/// <remarks>
/// typedef struct tagPOINT {
/// LONG x;
/// LONG y;
/// } POINT, *PPOINT;
/// </remarks>
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
[MarshalAs(UnmanagedType.U4)]
public long x;
[MarshalAs(UnmanagedType.U4)]
public long y;
}
/// <summary>
/// Contains message information from a thread's message queue.
/// </summary>
/// <remarks>
/// typedef struct tagMSG {
/// HWND hwnd;
/// UINT message;
/// WPARAM wParam;
/// LPARAM lParam;
/// DWORD time;
/// POINT pt;
/// } MSG, *PMSG, *LPMSG;
/// </remarks>
[StructLayout(LayoutKind.Sequential)]
public struct MSG
{
public IntPtr hwnd;
[MarshalAs(UnmanagedType.SysUInt)]
public MessageContext message;
public IntPtr wParam;
public IntPtr lParam;
[MarshalAs(UnmanagedType.U4)]
public ulong time;
public POINT pt;
}
[DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
// ...
// Import other API functions used above
// ...
}
答案 2 :(得分:1)
您正在使用POS用于.Net和USB HID设备。扫描仪将为您提供数据事件。您遇到的问题以及我遇到的同样问题是,在WPF中,您无法从POSExplorer对象本机接收数据事件。这是因为POSExplorer需要Windows窗体的句柄。事实证明,由于该技术中使用的线程模型,来自对象的WPF是不可接受的。
如果微软可以为WPF创建POSExplorer,那么你将被设置,但在此之前,最简单的解决方案是使用Windows窗体创建一个单独的项目,以便您可以从POSExplorer处理数据事件。在此之后,您可以处理将该信息传递到WPF UI的次要问题。
答案 3 :(得分:0)
我试图通过使用WinAPI来实现这一点。我可以枚举键盘,鼠标和其他人机界面设备:
int main()
{
UINT num_devs;
GetRawInputDeviceList(NULL, &num_devs, sizeof(RAWINPUTDEVICELIST));
RAWINPUTDEVICELIST* dev_list = new RAWINPUTDEVICELIST[num_devs];
UINT stored_devs = GetRawInputDeviceList(dev_list, &num_devs, sizeof(RAWINPUTDEVICELIST));
for( int i = 0; i < stored_devs; ++i )
{
UINT size;
RID_DEVICE_INFO dev_info;
char dev_name[256] = {0};
size = sizeof(dev_name);
GetRawInputDeviceInfoA(dev_list[i].hDevice, RIDI_DEVICENAME, dev_name, &size);
size = sizeof(RID_DEVICE_INFO);
GetRawInputDeviceInfo(dev_list[i].hDevice, RIDI_DEVICEINFO, &dev_info, &size);
std::cout << "Device Name: " << dev_name << "Device Type: ";
switch( dev_info.dwType )
{
case RIM_TYPEHID:
std::cout << "HID";
break;
case RIM_TYPEKEYBOARD:
std::cout << "Keyboard";
break;
case RIM_TYPEMOUSE:
std::cout << "Mouse";
}
std::cout << std::endl;
}
delete dev_list;
return 0;
}
但似乎GetRawInputDeviceList还提供RDP设备和其他虚拟设备。如何识别键盘和扫描仪?