有时在晚上,我喜欢躺在床上看电影,或者在网上看电视节目。这很方便,因为我的电脑就在我的办公桌旁边,所以我只需旋转我的一个显示器,关闭另一个屏幕,然后将鼠标拖到上面。第二天我搬回办公桌时,如果不重新布线,我的键盘就不能正常工作。有时当我看电影的时候,我的朋友们会试着和我说话,我希望我能够在不跳起来、不旋转显示器、不把鼠标向后移动并再次坐在椅子上的情况下与我交谈。
我想做的是做一个屏幕上的键盘来和鼠标一起使用--但是是一个T9手机键盘风格的键盘,以(希望)最小化鼠标的点击次数和移动的量,遗漏目标。我想用Python来做这件事,因为我已经熟悉了这门语言,但我不确定从哪里开始。
有一件事我不太确定,那就是如何点击屏幕上的键盘,而不把焦点从聊天窗口上移开。这能做到吗?或者,应用程序可以记住最后一个焦点窗口中的最后一个焦点控件,并向其发送击键吗?
另外,我是否需要一个外部库来执行这些窗口管理和按键发送?
非常感谢帮助,如果这样的事情已经存在(在任何语言中),给我指出它也会非常感谢。
如果我开发它,我一定会将它开源,并在这里发布一个到该项目的链接,以防其他人会发现这类东西很有用:)
发布于 2010-07-03 22:35:30
大约12年前,我为Windows编写了一个程序,它位于任务栏中,当某些窗口获得焦点时,它会向它们发送击键。我不再有代码,我已经忘记了所有的细节。
尽管如此,这个过程还是会像这样工作。
对于您的图形用户界面,如果使用Python,您可能希望使用PyQT或wxPython。这两个库都使得编写GUI应用程序变得很容易(尽管您可以直接使用Windows API)。
不过,如果是我,我会推迟图形用户界面编程,而使用PythonWin。使用它的图形用户界面工具(源代码中有很多示例)来创建一个简单的对话框(也是一个Window)来进行事件处理。
您的应用程序可能有几种方法来选择target窗口。虚拟键盘窗口可能必须窃取焦点(以接收鼠标事件),但它需要知道将击键发送到哪个窗口。
WM_FOCUS),您可以查询上一个具有焦点的窗口,也可以keep tabs on which windows have focus并使用您注意到的最后一个窗口。在这两种情况下,一旦有了目标窗口的句柄,就可以使用SendMessage将击键发送到目标窗口。我建议一开始只转发常规的击键,然后再担心捕获鼠标点击的问题。
编辑我能够将这些拼凑在一起,以便将击键发送到另一个窗口。
import win32ui
import win32con
import time
from ctypes import *
PUL = POINTER(c_ulong)
class KeyBdInput(Structure):
_fields_ = [("wVk", c_ushort),
("wScan", c_ushort),
("dwFlags", c_ulong),
("time", c_ulong),
("dwExtraInfo", PUL)]
class HardwareInput(Structure):
_fields_ = [("uMsg", c_ulong),
("wParamL", c_short),
("wParamH", c_ushort)]
class MouseInput(Structure):
_fields_ = [("dx", c_long),
("dy", c_long),
("mouseData", c_ulong),
("dwFlags", c_ulong),
("time",c_ulong),
("dwExtraInfo", PUL)]
class Input_I(Union):
_fields_ = [("ki", KeyBdInput),
("mi", MouseInput),
("hi", HardwareInput)]
class Input(Structure):
_fields_ = [("type", c_ulong),
("ii", Input_I)]
def send_char(char):
FInputs = Input * 1
extra = c_ulong(0)
ii_ = Input_I()
KEYEVENTF_UNICODE = 0x4
ii_.ki = KeyBdInput( 0, ord(char), KEYEVENTF_UNICODE, 0, pointer(extra) )
x = FInputs( ( 1, ii_ ) )
windll.user32.SendInput(1, pointer(x), sizeof(x[0]))
if __name__ == '__main__':
wnd = win32ui.FindWindow(None, '* Untitled - Notepad2 (Administrator)')
type_this = 'jaraco'
wnd.SetFocus()
wnd.SetForegroundWindow()
for char in type_this:
send_char(char)我发现PostMessage技术不能很好地工作(我根本不能让它为我工作)。
我还在identifying the last active window上找到了这篇文章。
https://stackoverflow.com/questions/3171045
复制相似问题