我正在使用Raw Input API从键盘(实际上是模拟键盘的磁条卡读卡器)获取按键的集合.这里有几个代码摘录,所以你可以知道我是如何获得密钥的.
[StructLayout(LayoutKind.Sequential)]
internal 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.U4)]
public uint Message;
[MarshalAs(UnmanagedType.U4)]
public uint ExtraInformation;
}
[StructLayout(LayoutKind.Explicit)]
internal struct RAWINPUT
{
[FieldOffset(0)]
public RAWINPUTHEADER header;
[FieldOffset(16)]
public RAWMOUSE mouse;
[FieldOffset(16)]
public RAWKEYBOARD keyboard;
[FieldOffset(16)]
public RAWHID hid;
}
Queue<char> MyKeys = new Queue<char>();
// buffer has the result of a GetRawInputData() call
RAWINPUT raw = (RAWINPUT)Marshal.PtrToStructure(buffer, typeof(RAWINPUT));
MyKeys.Enqueue((char)raw.keyboard.VKey);
Run Code Online (Sandbox Code Playgroud)
运行代码时,读卡器输出字符串%B40^TEST,但在MyKeys集合中,我有以下值:
{ 16 …Run Code Online (Sandbox Code Playgroud) 我有一个仅消息窗口(ATL :: CWindowImpl),它使用RIDEV_INPUTSINK标志为原始输入注册自己,这意味着无论窗口是否是前台窗口,它都会获得所有输入.当只有一个窗口的实例时,这很有效.
但是,当我创建多个窗口实例时,只有一个接收WM_INPUT消息(我当前正在创建两个消息,并且只有第二个要创建消息).
在创建两个窗口期间,RegisterRawInputDevices(使用RIDEV_INPUTSINK | RIDEV_NOLEGACY)正在成功.此外,没有接收原始输入的窗口仍在接收其他消息,因此窗口本身不存在问题......
如果它是相关的,我正在使用VC11测试版,并创建窗口并在不同的线程上调度消息(使用std :: thread).
这是API限制(即每个进程只限一个输入接收器)吗?或者有没有办法让这个工作?
提前致谢.
编辑:
现在我当前的解决方法是只有一个窗口,并将输入消息传递给其他窗口,但这是一个烂摊子,并且在我希望它工作的情况下不能工作(我有我的地方) app加载可能需要原始输入的插件,我不希望他们必须注册我的应用程序,除非我真的必须这样做...).
目前,我正在制作一个拦截特定键盘击键的程序(使用其HID进行过滤).因此,为了知道特定设备发送了哪些击键,我使用了RawInput技术,受到这个伟大教程的启发:
http://www.codeproject.com/Articles/17123/Using-Raw-Input-from-C-to-handle-multiple-keyboard
现在,它工作得很好:我可以获得击键并知道哪个键盘生成了它.
我的项目的难点在于拦截和阻止来自这个特定键盘的击键,以避免这些击键到达聚焦应用程序(聚焦意味着操作系统带来的前景窗口).
因此,在具有窗口句柄的所有当前线程上,自然解决方案是低级全局钩子.
我使用并调整了此页面中的代码来执行此操作:
http://blogs.msdn.com/b/toub/archive/2006/05/03/589423.aspx
我在visual studio中创建了一个新项目,以避免在我的工作中乱七八糟.经过一些研究,我能够通过在回调函数中返回值(-1)来阻止所有应用程序的击键:
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
//Check if we have a key to pass
if (
nCode >= 0 && (
(wParam == (IntPtr)WM_KEYDOWN) || (wParam == (IntPtr)WM_KEYUP) )
)
{
int vkCode = Marshal.ReadInt32(lParam);
if ((Keys)vkCode == Form1.KeysToIgnore)
{
return (IntPtr)(-1);
}
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
Run Code Online (Sandbox Code Playgroud)
为了将所有内容(钩子程序和击键检测)放在一起,我在最终项目中创建了两个线程:
1st:使用RawInput识别每个键击并将其附加到设备
第二:用于挂钩所有窗口并阻止某些击键
线程1被设计为发送键击以阻止线程2,线程2读取发送到所有窗口应用程序的所有消息和来自特定键盘的垃圾键击.我确切地知道这两个线程是同步的.
问题是钩子似乎是在执行Rawinput之前执行的,所以我无法识别发送击键的键盘.我不知道怎么做,也许改变钩子的类型(避免使用低级键盘钩,但使用用户空间级键盘钩).
或者也许有人知道一种聪明的方式来做我想做的事情?
我知道这个请求真的很复杂,请不要犹豫,询问更多细节.
我希望能够从用户(通过raw_input()或模块)获得输入,并且能够自动输入可以添加,删除或修改的文本.我在javascript中知道当你使用提示时,你可以这样做
var = prompt("Enter your name: ","put name here")
Run Code Online (Sandbox Code Playgroud)
它将显示为:
Enter your name:
put name here
Run Code Online (Sandbox Code Playgroud)
这里'put name here'是在文本框中,并可以修改.我希望在shell环境(我使用unix)而不是窗口中实现它.
有什么办法吗?
哦,告诉我是否需要澄清我希望的更多内容.
我不认为你们明白我想做什么.
我基本上想要在输入中包含提示,但让用户能够退出提示/编辑它,如果他们想要的话.
该脚本可能用于简单的基于shell的单行文本编辑器和制表符完成类型的东西.
我正在构建跨平台的游戏引擎,现在我专注于输入系统.
我编写了一个抽象的输入系统,它传递消息并由平台相关模块提供,在单独的线程中运行.
在Windows中,我创建了"仅消息"窗口,该窗口向输入系统提供来自RAWINPUT的消息(转换为独立于平台).
现在我有麻烦想弄清楚如何在基于unix的系统上做类似的事情.有没有方便的方法从内核获取输入(keyup,keydown,mousemove ...)?或者任何其他方式,而不需要显示任何窗口?
编辑
我不希望我的输入系统依赖于我的渲染器.当应用程序焦点改变时,渲染器应该只通知输入...所以我希望输入系统在与渲染器不同的线程上运行.
我是python的新手,我正在尝试安装win32clipboard以便能够使用此代码:
import win32clipboard
win32clipboard.OpenClipboard()
win32clipboard.SetClipboardText('testing 123')
win32clipboard.CloseClipboard()
# get clipboard data
win32clipboard.OpenClipboard()
data = win32clipboard.GetClipboardData()
win32clipboard.CloseClipboard()
print data
raw_input()
Run Code Online (Sandbox Code Playgroud)
我如何准确安装必要的模块才能这样做?我正在使用python版本2.72.
我是python的新手,我正在尝试使用raw_input和函数为程序创建一个命令.由于某种原因,它一直没有奏效.这是我一直在测试的代码:
raw_input()
def test():
print "hi, this will be amazing if it works"
Run Code Online (Sandbox Code Playgroud) 只是尝试编写一个程序,将用户输入并将其添加到列表'数字':
print "Going to test my knowledge here"
print "Enter a number between 1 and 20:"
i = raw_input('>> ')
numbers = []
while 1 <= i <= 20 :
print "Ok adding %d to numbers set: " % i
numbers.append(i)
print "Okay the numbers set is now: " , numbers
Run Code Online (Sandbox Code Playgroud)
但是,当我执行程序时,它只运行到raw_input()
Going to test my knowledge here
Enter a number between 1 and 20:
>>> 4
Run Code Online (Sandbox Code Playgroud)
我在这里缺少一些基本规则吗?
我正在从Learn Python The Hard Way做ex13
我正试图通过:
python ex13.py raw_input() raw_input() raw_input()
Run Code Online (Sandbox Code Playgroud)
我的代码如下:
from sys import argv
script, first, second, third = argv
print "The script is called:", script
print "Your first variable is:", first
print "Your second variable is:", second
print "Your third variable is:", third
Run Code Online (Sandbox Code Playgroud)
我一直得到的错误是:
Traceback (most recent call last):
File "ex13.py", line 5, in <module>
script, first, second, third = argv
ValueError: too many values to unpack
Run Code Online (Sandbox Code Playgroud)
我想知道为什么我会收到此错误以及如何解决此问题
当我在通过 RDP 登录时尝试从lLastX, 和结构lLastY成员更新我的鼠标位置RAWMOUSE时,我得到了一些非常奇数的数字(例如两者都大于 30,000)。我在 Windows 7、8、8.1 和 10 上注意到了这种行为。
usFlags 成员返回 的值MOUSE_MOVE_ABSOLUTE | MOUSE_VIRTUAL_DESKTOP。关于MOUSE_MOVE_ABSOLUTE,我在我的代码中处理绝对定位和相对定位。但是,虚拟桌面标志让我有点困惑,因为我认为该标志用于多显示器设置。我有一种感觉,这与那面旗帜和我得到的奇怪数字有关。不幸的是,我真的不知道如何在没有参考点的情况下调整值,我什至不知道如何获得参考点。
当我在本地运行代码时,一切正常。
那么有没有人知道为什么 RDP + 原始输入会给我这样混乱的鼠标 lastx/lasty 值?如果是这样,有没有办法将它们转换为更合理的值?