用到的库文件
空的 btt https://www.autoahk.com/archives/35015
需求来源:
AutoHotKey群友需求
1,想借助,AHK,弄个脚本(实现鼠标悬停并弹出小弹窗,自动朗读),2,再结合快速启动软件,一起整合到小键盘上,他只要按一下键盘,电脑开机,再按另外一个键,电脑自动打开POTPLAYER,然后,他用语音说,LESSON 20 THE BUS,那么POTPLAYER自动打开第20节英语课,播放,并自动加载外挂字幕,然后我家小朋友学的过程中,有不认得的字,他用鼠标,移到外挂字幕的这个字上,就能有小弹窗出来,并且自动朗读,小弹窗上的内容不多,就只是很简要的,什么词性,翻译,音节,音标,鼠标移走,这个小弹窗就自动没了,关了,3,他学完了,不想学了,按一下小键盘,电脑退出POTPLAYER,再按另外一个键,电脑关机
—-能力有限,目前实现了简单的鼠标悬停获取鼠标下的字幕文本
#Persistent
DllCall("RegisterShellHookWindow", "Ptr", A_ScriptHwnd)
OnMessage(DllCall("RegisterWindowMessage", "Str", "ShellHook"), "窗口切换时触发")
StringCaseSense, on
BttStyle1 := {TextColor:0xffeef8f6
, BackgroundColor:0xff1b8dff
, FontSize:84}
BttStyle2 := {TextColor:0xff800000
, BackgroundColor:0xff1b8dff
, FontSize:84}
a := 1
SetTimer, aa, 1000
Return
aa:
if (A_Cursor = "Unknown") && (GetClass() = "PotPlayer64") {
Clipboard := ""
Send, {LButton}
ClipWait, 1
if (clipls != Clipboard) {
clipls := Clipboard
注释等信息 := 获取更多信息()
btt(注释等信息, 500, 350, 9, BttStyle1)
btt(Clipboard, 500, 200, 10, BttStyle2)
TTS语音播报(Clipboard)
}
}
If ((A_Cursor = "Arrow") && (GetClass() = "PotPlayer64")) || ((GetClass() != "PotPlayer64"))
{
btt(,,,10)
btt(,,,9)
btt(,,,8)
Gui, Destroy
}
Return
GetClass(){
MouseGetPos, , , winId
WinGetClass, winclass, % "ahk_id " winId
Return winclass
}
TTS语音播报(txt, 音量:= 100, 语速:=0, 音高:=0) {
SAPI := ComObjCreate("SAPI.SpVoice")
, SAPI.volume := 音量 ; 音量从 0 到 100。默认值是 100
, SAPI.rate := 语速 ; 语速从 -10 到 10。默认值是 0
, SAPI.Speak("<pitch absmiddle = '" 音高 "'/>",0x20) ; 音高从 -10 到 10。默认值是 0
, SAPI.Speak(txt)
}
获取更多信息(){
Return "这些只是用来布局占位`n这些只是用来布局占位`n这些只是用来布局占位"
}
AutoHotKey群 Tebayaki+ahk2 提供了一个通过 鼠标钩子和消息 的方式
这个方法更稳定
代码是V2,一共两个文件
效果
文件1–PotPlayerHelper.ah2
; 在字幕关键词搜索设置中添加命令行, 指向trigger.ah2 如:
; D:\AutoHotkey2\AutoHotkey64.exe D:\Code\AutoHotkey\PotPlayer\Trigger.ah2 %%SS
; 运行PotPlayerHelper, 脚本会安装鼠标钩子, 当光标移动到字幕上时, PotPlayer将打开Trigger并传关键词参数, 然后Trigger将该关键词发送给主脚本使用
; 不轮询, 不依赖剪贴板, 速度和可靠性都可以
Persistent
CoordMode("Mouse", "Client")
OnMessage 0x004A, WM_COPYDATA_Handler ; WM_COPYDATA
; 注册鼠标钩子
hook := MouseHook(CallbackCreate(LowLevelMouseProc, "F"))
; 鼠标移动时就会触发
LowLevelMouseProc(nCode, wp, lp) {
Critical
static last_timestamp := 0, flag := 1
if nCode
return
if A_Cursor !== "Unknown"
return (flag := 1, 0)
if !flag
return
if (MouseGetPos(&x, &y, , &ctrl), ctrl) !== "Afx:00007FF80E7D0000:b:0000000000010003:0000000000900011:00000000000000003"
return
hook.ptr := lp
if hook.time - last_timestamp < 200
return
SendMessage(0x0202, 0, x | y << 16, , "ahk_class PotPlayer64") ; WM_LBUTTONUP
last_timestamp := hook.time
flag := 0
}
; 处理Trigger发送过来的关键词
WM_COPYDATA_Handler(wp, lp, *) {
ptr := NumGet(lp, 16, "ptr")
str := StrGet(ptr)
ToolTip(str, 250, 420)
return 1
}
class MouseHook {
__New(callback) => this.Hook := DllCall("SetWindowsHookEx", "int", 14, "ptr", callback, "ptr", 0, "uint", 0, "ptr")
__Delete() => DllCall("UnhookWindowsHookEx", "ptr", this.Hook)
ptr := 0
size := 32
x => NumGet(this, "int")
y => NumGet(this, 4, "int")
data => NumGet(this, 8, "uint")
flag => NumGet(this, 12, "uint")
time => NumGet(this, 16, "uint")
extraInfo => NumGet(this, 24, "ptr")
}
文件2–Trigger.ah2
#SingleInstance Off
#NoTrayIcon
DetectHiddenWindows(true)
if !A_Args.Length || !hwnd := WinExist("PotPlayerHelper ahk_class AutoHotkey")
return
NumPut("ptr", (StrLen(A_Args[1]) + 1) * 2, "ptr", StrPtr(A_Args[1]), cps := Buffer(24), 8)
SendMessage(0x4a, 0, cps, , hwnd, , , , 1000) ; WM_COPYDATA.