本文章是第一次更新,更新于 2022年4月4日
準備作業??
方案設想
前面我們使用 Python 撰寫了快捷鍵自動剪貼板加水印小工具,昨天我又想到了一個問題,
在用 Typora 通過視頻寫學習筆記的時候,遇到沒聽懂的點,需要把視頻往前拖幾秒,這時候因為當前活動視窗是 Typora 所以需要先回到瀏覽器視窗,然后再拖動視頻進度,十分麻煩,
于是我想能不能寫一個全域快捷鍵,直接通過快捷鍵的形式拖動視頻進度
程式流程

參考資料
下面是我參考過的資料
- How To Send Inputs to Multiple Windows and Minimized Windows with Python - LearnCodeByGaming.com
- SendMessage function (winuser.h) - Win32 apps | Microsoft Docs
- winapi - Python win32api SendMesage - Stack Overflow
- Send some keys to inactive window with python - Stack Overflow
- Virtual-Key Codes (Winuser.h) - Win32 apps | Microsoft Docs
- Handling the keyboard — pynput 1.7.6 documentation
- SetForegroundWindow,SetActiveWindow, or ShowWindow? - SegmentFault
代碼下載
代碼:WMDVideo.zip

如果文章字體過小,請調整瀏覽器頁面縮放,Windows: Ctrl + 滑鼠滾輪
本篇文章代碼注釋可能使用了 vscode 的 better-comments 拓展
視頻演示
多屏用戶真是爽呆了!
程式撰寫
我們需要引入兩個必備的庫,一個是 win32api ,一個是 pynput ,前者負責視窗獲取和發送資訊,后者負責監控全域快捷鍵,
獲取視頻視窗
def list_window_names(keyword):
items = []
def winEnumHandler(hwnd, ctx):
if win32gui.IsWindowVisible(hwnd):
name = win32gui.GetWindowText(hwnd)
# print(hex(hwnd), '"' + name + '"')
if name.lower().find(keyword) != -1:
items.append(hwnd)
win32gui.EnumWindows(winEnumHandler, None)
print("find windows:", len(items))
return items
這里使用了 win32gui 的列舉器,對可見視窗進行列舉,對每個視窗的名字進行匹配,如果匹配成功則將視窗句柄添加進入 items 陣列,
獲取舊視窗
def get_old_window():
oldhwnd = win32gui.GetForegroundWindow()
return oldhwnd
在切換視窗前先獲取當前視窗,用于最后回傳,
發送按鍵資訊
def press_key(keyword, char, key):
newhwnds = list_window_names(keyword)
oldhwnd = get_old_window()
print(newhwnds, oldhwnd)
for hwnd in newhwnds:
hwnd = win32gui.GetWindow(hwnd, win32con.GW_CHILD)
try:
# if hwnd != oldhwnd:
sleep(0.1)
win32gui.SetForegroundWindow(hwnd)
if hwnd == oldhwnd:
print("not working")
# pyautogui.press(key)
else:
win32api.SendMessage(hwnd, win32con.WM_KEYDOWN, char, 0)
sleep(0.1)
win32gui.SetForegroundWindow(oldhwnd)
except:
pass
-
如果此時視窗已經是視頻視窗,則不會進行作業,這是一個bug,我用了兩個庫都沒有效果,暫時不想解決,
-
sleep函式是必須的,否則按鍵訊息將發送不到具體視窗, -
hwnd = win32gui.GetWindow(hwnd, win32con.GW_CHILD)這部分其實是多余的,相當于獲取子視窗句柄,去掉也能作業, -
win32gui.SetForegroundWindow(hwnd)將當前視窗提至最前, -
win32api.SendMessage(hwnd, win32con.WM_KEYDOWN, char, 0)對特定視窗發送按鍵資訊,具體可以看微軟的檔案,
監控按鍵資訊
def on_activate_VK_LEFT():
print('VK_LEFT')
press_key("youtube", VK_LEFT, "left")
def on_activate_VK_RIGHT():
print('VK_RIGHT')
press_key("youtube", VK_RIGHT, "right")
with keyboard.GlobalHotKeys({
'<ctrl>+<alt>+,': on_activate_VK_LEFT,
'<ctrl>+<alt>+.': on_activate_VK_RIGHT
}) as h:
h.join()
阻塞式多全域按鍵寫法,具體可以看 pynput 的官方檔案,
其他代碼
獲取當前視窗
import win32gui
# 獲取視窗句柄
hwnd = win32gui.GetForegroundWindow()
# 獲取視窗標題
win32gui.GetWindowText(hwnd)
查找視窗
import win32gui
# 根據標題查找視窗
title = '檔案'
hwnd = win32gui.FindWindow(None, title)
設定當前視窗
import win32gui
# 根據句柄
hwnd = 5378992 #句柄應該是其他方法獲取到的
win32gui.SetForegroundWindow(hwnd)
打包exe
在當前終端執行如下命令,film.ico 是我另外加的圖示
pyinstaller -i film.ico --onefile work.py

設定鍵盤宏

這里我用了 via ,設定宏,比如 {KC_LCTL,KC_LALT,KC_COMM}
順便炫一下我的小鍵盤

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/455542.html
標籤:Python
上一篇:IO流(序列化流和反序列化流)
