其他|用pywinhook或pyhook监听鼠标事件

【其他|用pywinhook或pyhook监听鼠标事件】一位在读研的好朋友有一天找到我,问我制作PC端软件有啥好的语言,我问:“这是咋了?”,朋友答曰:在实验室电脑前总是不知不觉开始摸鱼,自制力不够,想搞个提醒学习的东西,在摸鱼时弹出自己的学习计划,提醒自己做点正事(巴巴托斯躺枪ing)。
我寻思这不我copy 写个python程序就行了。朋友提出更具体的功能需求:鼠标移动到屏幕外的时候会丝滑地出现一个小窗口,比如移动到右上角会出现一张自己设置的图片,从而时时刻刻提醒自己有什么样的ddl。
之后,通过我一番面向搜索引擎编程,做出:使用pyhook监听鼠标事件,当鼠标移动到显示器左上角,3乘以3像素的范围内,系统会打开同目录下“bananabaozi-notice.txt”文件,总共最多能打开三次,除非再关掉一个txt窗口,就可以再打开一次。朋友可以通过这个txt写下ddl从而时不时把鼠标晃到左上角猛地看到ddl然后停止摸鱼行为开始认真学习。当然效果怎么样俺也不知道,待会问问去。
代码贴在下面。我使用win10 64位、python3.8开发,在这之前要pip安装pywin32和pyHook。
在网上搜安装pyhook库死活装不上,于是找到安装pywinhook的办法,使用import pyWinhook as pyHook还是用上了pyhook。然后再搜一下使用pyinstaller打包py程序为exe,且exe打开后隐藏黑窗口,就完事了。

# -*- coding: utf-8 -*- import pyWinhook as pyHook import pythoncom import os,sys import win32gui import win32api, win32con from win32com.client import GetObjecthWndList = [] flag = 0 def onMouseEvent(event): global flag global hWndList # 监听鼠标事件 # if event.Position == (0, 0): 区域放大点好了 if event.Position[0] < 3 and event.Position[1] < 3 and flag == 0: flag = 1 win32gui.EnumWindows(lambda hWnd, param: param.append(hWnd), hWndList) cnt = 0 for h in hWndList: str = show_window_attr(h) if "bananabaozi-notice.txt" in str: cnt = cnt + 1 if cnt < 1: # print(cnt,"***************************************") if os.path.exists('./bananabaozi-notice.txt') is True: try: os.system("start bananabaozi-notice.txt") except: win32api.MessageBox(0, "打开bananabaozi-notice.txt异常", os.path.basename(sys.argv[0])+"提示", win32con.MB_OK) print("打开bananabaozi-notice.txt异常") else: win32api.MessageBox(0, "bananabaozi-notice.txt不存在", os.path.basename(sys.argv[0])+"提示", win32con.MB_OK) print("bananabaozi-notice.txt不存在") else: win32api.MessageBox(0, "已打开bananabaozi-notice.txt", os.path.basename(sys.argv[0])+"提示", win32con.MB_OK) print("已打开bananabaozi-notice.txt") flag = 0else: if len(hWndList) != 0: hWndList.clear()# 返回 True 以便将事件传给其它处理程序 # 注意,这儿如果返回 False ,则鼠标事件将被全部拦截 # 也就是说你的鼠标看起来会僵在那儿,似乎失去响应了 return Truedef gbk2utf8(s): #return s.decode('gbk').encode('utf-8') return s.encode('utf-8')def show_window_attr(hWnd): ''' 显示窗口的属性 :return: ''' if not hWnd: return ""# 中文系统默认title是gb2312的编码 title = win32gui.GetWindowText(hWnd) title = gbk2utf8(title)# print("窗口句柄:", hWnd) # print("窗口标题:", str(title, encoding="utf-8"))#字节流转字符串 # print("窗口类名:", clsname) return str(title, encoding="utf-8")# 返回窗口标题字符串def main(): wmi = GetObject('winmgmts:') processes = wmi.ExecQuery('Select * from Win32_Process where Name = "'+os.path.basename(sys.argv[0])+'"') if len(processes) > 2: win32api.MessageBox(0, os.path.basename(sys.argv[0])+"已在后台运行,请勿重复打开", os.path.basename(sys.argv[0])+"提示", win32con.MB_OK) os._exit(0) try: # 创建一个“钩子”管理对象 hm = pyHook.HookManager()# 监听所有鼠标事件 hm.MouseAll = onMouseEvent # 设置鼠标“钩子” hm.HookMouse()# 进入循环,如不手动关闭,程序将一直处于监听状态 pythoncom.PumpMessages() except: print("运行失败")if __name__ == "__main__": main()

打包发给朋友后,写了个【使用说明】:
注:此程序经测试适用于win10 64位操作系统,32位不确定
1.打开过程
解压此压缩包到任意文件夹
打开文件夹
双击exe文件,程序即开始在后台运行
2.使用方法
在bananabaozi-notice.txt文件内可以写下待办事项、提醒事项
当鼠标移动到屏幕左上角时,系统会打开文件夹里的bananabaozi-notice.txt文件,弹出窗口,使用户看到提醒
最多打开三次,如果打开的bananabaozi-notice.txt数量超过三个,那么系统不会再打开,请看到提醒后及时关闭
3.退出程序
如果想要退出程序,请到任务栏右键,打开任务管理器
找到对应的exe关闭
需注意的是:任务管理器中会有两个同名txt-notice.exe进程,退出时要注意这两个都要消失。第二个进程是实际的程序,而第一个进程是在程序退出或崩溃后清理临时目录。
4.设置开机自启动
如果想设置开机自启动程序,则设置步骤如下:
0.右键exe文件—发送到—桌面快捷方式
1.键盘按win+R
2.输入shell:startup
3.确定
4.会弹出一个文件夹的窗口
5.把桌面的快捷方式拖入文件夹窗口内即可
6.删除桌面的快捷方式

    推荐阅读