Python pywin32 win32gui.PumpWaitingMessages()位置
我试图编写一些python代码来检测Windows中的监视器更改事件;我使用的是pywin32,主要基于。似乎Python pywin32 win32gui.PumpWaitingMessages()位置,python,winapi,pywin32,Python,Winapi,Pywin32,我试图编写一些python代码来检测Windows中的监视器更改事件;我使用的是pywin32,主要基于。似乎PumpWaitingMessages的位置会有所不同;下面的代码确实检测到监视器更改(即运行OnDeviceChange),但lp参数为0,因此我无法从中获取任何有用的信息(即监视器标识符) 但是,如果我将while True循环从代码的最末端移动到\uuuu init\uuuu方法的末端,那么lp参数将被填充,并且我可以获得所需的信息 你知道为什么while循环的位置会有所不同吗?虽
PumpWaitingMessages
的位置会有所不同;下面的代码确实检测到监视器更改(即运行OnDeviceChange
),但lp
参数为0,因此我无法从中获取任何有用的信息(即监视器标识符)
但是,如果我将while True
循环从代码的最末端移动到\uuuu init\uuuu
方法的末端,那么lp
参数将被填充,并且我可以获得所需的信息
你知道为什么while循环的位置会有所不同吗?虽然它是借用的代码的一部分,但我还是建议将变量
filter
重命名为其他名称,因为它是阴影(我编辑帖子时没有改变自己,因为我无法发布说明我为什么这么做的评论)。此外,您可能希望添加缺少的部分以获得一个工作代码段:导入、定义(例如,GUID\u deviceinterface\u MONITOR
,我浏览了Ioevent.h,并且我既找不到USB也找不到与显示相关的GUID)
我怀疑这一行为有两个原因:
- 将PyQt(它有自己的windows处理)与普通WinAPI(正如我在评论中所写的)混合使用,以及其中一个可能会踩到另一个的脚
- Python作用域()
TestDeviceNotifications
结束时,hdev
(由RegisterDeviceNotification
返回)超出了范围
这里也会发生同样的情况:退出\uuuu init\uuuu
后,(当消息开始发送到窗口时)hdev
将是一个无效的句柄。要更正此问题,请将其设为全局句柄:
- 在模块级声明它(在
之前),例如:Foo
hdev=None
- 指示
对全局变量进行操作,而不是创建具有相同名称的新局部变量。在\uuuu init\uuuu
的某个地方,在\uuuuuu init\uuuu
之前
添加hdev=win32gui。RegisterDeviceNotification
,它将是持久的全局hdev
- 通常,所有创建的资源都应该在不再需要时释放。这是使用
和wc
应该做的。关于hwnd
,没有提到任何关于调用hdev
(或类似的smth)的内容,所以我认为,这很好CloseHandle
HWND\u message
作为父线程传递来生成窗口消息dow参数到CreateWindow()
,但我不确定这是否会使您的窗口不符合设备通知的条件。我看到Foo
扩展了QObject
。您也在使用PyQt吗?如果是,因为Qt有自己的windows处理机制,可以将其与普通的WinAPI混合使用吗?我同时使用PyQt和pywin32;设备更改事件不是ex这是否回答了你的问题?
class Foo(QObject):
def OnDeviceChange(self, hwnd, msg, wp, lp):
info = win32gui_struct.UnpackDEV_BROADCAST(lp)
print("Device change notification:", wp, str(info)) #
return True
def __init__(self):
wc = win32gui.WNDCLASS()
wc.lpszClassName = 'test_devicenotify'
wc.style = win32con.CS_GLOBALCLASS|win32con.CS_VREDRAW | win32con.CS_HREDRAW
wc.hbrBackground = win32con.COLOR_WINDOW + 1
wc.lpfnWndProc = {win32con.WM_DEVICECHANGE: self.OnDeviceChange}
class_atom = win32gui.RegisterClass(wc)
hwnd = win32gui.CreateWindow(wc.lpszClassName,
'Waiting for Monitor Change',
# no need for it to be visible.
win32con.WS_CAPTION,
100, 100, 900, 900, 0, 0, 0, None)
filter = win32gui_struct.PackDEV_BROADCAST_DEVICEINTERFACE(
GUID_DEVINTERFACE_MONITOR)
hdev = win32gui.RegisterDeviceNotification(hwnd, filter,
win32con.DEVICE_NOTIFY_WINDOW_HANDLE)
f = Foo()
while True:
win32gui.PumpWaitingMessages()
time.sleep(0.01)