用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 GetObject

hWndList = []
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 = 0

    else:
        if len(hWndList) != 0:
            hWndList.clear()

    # 返回 True 以便将事件传给其它处理程序
    # 注意,这儿如果返回 False ,则鼠标事件将被全部拦截
    # 也就是说你的鼠标看起来会僵在那儿,似乎失去响应了
    return True



def 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.删除桌面的快捷方式

你可能感兴趣的:(其他,python)