我在格式化这个问题的标题时遇到了麻烦,因为我不确定我是否会以正确的方式处理这个问题,所以让我解释一下。
我想尝试将右键单击上下文菜单添加到我没有源代码的现有程序中。wxpython通常是我的选择框架。我认为有几种方法可以做到这一点:
1)创建一个透明的wx.frame,该帧与现有程序的顶部绑定并位于拦截鼠标事件的顶部。如果我这样做,我不确定是否可以将鼠标事件传递到基础窗口。我喜欢此选项,因为它可以在覆盖层中添加更多有用的信息。
2)创建一个无头的程序,该程序在全球截取右键单击事件,并在满足某些条件时在指针位置产生上下文菜单。根据我到目前为止所做的研究,如果不连续进行小鼠位置进行轮询,这似乎并不可能。
我想念什么?有一个更优雅的解决方案吗?这甚至可以使用Python?
编辑:我有一个部分概念证明工作,看起来像这样:
import wx
import win32gui
import win32api
import win32con
class POC_Frame(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, id=wx.ID_ANY, title='POC', pos=(0,0), size=wx.Size(500, 500), style=wx.DEFAULT_FRAME_STYLE)
self.ToggleWindowStyle(wx.STAY_ON_TOP)
extendedStyleSettings = win32gui.GetWindowLong(self.GetHandle(), win32con.GWL_EXSTYLE)
win32gui.SetWindowLong(self.GetHandle(), win32con.GWL_EXSTYLE,
extendedStyleSettings | win32con.WS_EX_LAYERED | win32con.WS_EX_TRANSPARENT)
win32gui.SetLayeredWindowAttributes(self.GetHandle(), win32api.RGB(0,0,0), 100, win32con.LWA_ALPHA)
self.Bind(wx.EVT_RIGHT_DOWN, self.onRightDown)
self.Bind(wx.EVT_RIGHT_UP, self.onRightUp)
self.CaptureMouse()
def onRightDown(self, event):
print(event)
def onRightUp(self, event):
print(event)
app = wx.App(False)
MainFrame = POC_Frame(None)
MainFrame.Show()
app.MainLoop()
这似乎可以正常工作,因为它将右键单击事件传递到基础窗口,同时仍然识别它们,但仅一次就可以。一旦失去焦点,它就会停止工作,而我没有试图将重点恢复到它似乎有效。
我一直在用pyhook而不是wx钩上全局鼠标和键盘事件的好运。这是一个简单的例子:
import pyHook
import pyHook.cpyHook # ensure its included by cx-freeze
class ClickCatcher:
def __init__(self):
self.hm = None
self._is_running = True
self._is_cleaned_up = False
self._is_quitting = False
self.set_hooks()
# this is only necessary when not using wx
# def send_quit_message(self):
# import ctypes
# win32con_WM_QUIT = 18
# ctypes.windll.user32.PostThreadMessageW(self.pump_message_thread.ident, win32con_WM_QUIT, 0, 0)
def __del__(self):
self.quit()
def quit(self):
if not self._is_running:
return
self._is_quitting = True
self._is_running = False
if self.hm:
# self.hm.UnhookKeyboard()
self.hm.UnhookMouse()
# self.send_quit_message()
self._is_cleaned_up = True
def set_hooks(self):
self._is_running = True
self._is_cleaned_up = False
self.hm = pyHook.HookManager()
self.hm.MouseRightUp = self.on_right_click
# self.hm.HookKeyboard()
self.hm.HookMouse()
def on_right_click(self):
# create your menu here
pass
如果您不使用wx
,则必须使用pythoncom.PumpMessages
将鼠标和键盘事件推向程序,但是App.Mainloop()
完成了同样的事情(如果您使用pumpmessages和mainloop一起使用,则大约一半的事件不会推入您的程序)。
创建一个wx.menu非常容易。您可以使用wx.GetMousePosition()