需求

在学习Lua,习惯边看pdf边做笔记,经常用sumatra竖屏看PDF,有道云笔记横屏做笔记。一般双手在键盘上,有时候用的蓝牙键盘直接键盘放在腿上,总之不方便也不想频繁从键盘切换到鼠标上,但是看完当前页有翻页的需求。

解决办法

1 最开始想到的是有两个键盘或者输入设备,分别控制,比如一个键盘一个蓝牙翻页器,键盘打字,翻页器翻页。但是一般来说操作的项目有限,或者只针对激活敞口。
2 pdf 自动翻页,但是存在阅读和笔记同步问题,比如某一页内容简单做完了笔记还没翻页,或者比较复杂正在做笔记结果翻页了,甚至有时候有向前翻页的需求。
3 接触过一些windows编程,知道可以向指定窗口发送按键消息,同时配合上全局快捷键,这样就可以一直激活有道云笔记窗口,在里面编辑笔记,在需要的时候按下特定按键组合控制pdf翻页,最终也是采用的这种方案。

实现

由于当时时间有限,加上只是需要这么个功能,最终实现采用了python+autohotkey的方案,有一些硬编码的东西,只是满足了当时的需求。python提供翻页功能,autohotkey提供快捷键激发执行功能。
解决问题有几个步骤需要解决:获取到翻页意图,执行翻页,最终采用的方案是通过autohotkey获取输入,当按下ctrl+[时候向前翻页,当按下ctrl+]时向后翻页。通过执行不同脚本实现翻阅,对应内容如下。

快捷键部分

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

^[::Run F:\tmp\TestSendKey\up.vbs
^]::Run F:\tmp\TestSendKey\down.vbs

相当于按下ctrl+[或者]后分别执行对应的脚本。之所以使用vbs是为了避免脚本执行时候出现的弹窗。

翻页部分

翻页采用的python,用到了win32gui相关的库。核心做法就是找到目标窗口,然后向目标窗口发送特定的按键信息。
经过简单的测试,没能通过进程名称找到窗口,没进一步研究,改用窗口class name倒是可以,class name通过openark查询获得。
执行流程是vbs调用bat,bat调用python,python执行非激活窗口的翻页。
以向上翻页为例,
vbs内容:

Set shell = Wscript.CreateObject("WScript.Shell")
a = shell.run ("F:\tmp\TestSendKey\up.bat",0)

bat 内容:

python PageUp.py

python 内容:

from asyncio.windows_events import NULL
import win32api
import win32gui
import win32con
import time
 
hwndMain = win32gui.FindWindow(None, "Lua程序设计.pdf - [Programming in Lua] - SumatraPDF")
#print(hwndMain)
win32gui.PostMessage(hwndMain,win32con.WM_KEYDOWN , win32con.VK_LEFT, 0)
#time.sleep(0.1)
win32gui.PostMessage(hwndMain,win32con.WM_KEYUP, win32con.VK_LEFT, 0)

后续优化

实际上通过参数方式控制,并不需要将上翻页下翻页做成两套独立的东西。而且当时时间比较紧迫,没花太多时间,完成功能就结束了,如果更完善一点,至少可以有个配置界面,用来选择设置的快捷键以及要对哪个窗口做控制。