1 Star 0 Fork 0

chaoskey / SharpKnife

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
CtrlRich.ahk 26.45 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813
;@Ahk2Exe-SetProductName Ctrl增强
;@Ahk2Exe-SetProductVersion 2021.12.30
;@Ahk2Exe-SetDescription Ctrl增强
;@Ahk2Exe-SetFileVersion 2021.12.30
;@Ahk2Exe-SetCopyright @2021-2025
;@Ahk2Exe-SetLanguage 0x0804
;@Ahk2Exe-SetOrigFilename CtrlRich
;@Ahk2Exe-SetLegalTrademarks chaoskey
;@Ahk2Exe-SetCompanyName chaoskey
;@Ahk2Exe-SetMainIcon images\CtrlRich.ico
#SingleInstance, force
FileEncoding , UTF-8-RAW
#Include lib\util.ahk
#Include lib\ClipHistory.ahk
#Include lib\CustomGUI.ahk
; 托盘提示
Menu, Tray,Tip , Ctrl增强
icoName := "images\" StrReplace(A_ScriptName, ".ahk" , ".ico")
if FileExist(icoName){
Menu, Tray, Icon, %icoName%
}
; 启动GDI+支持
startupGdip()
; Clip历史管理
global clipHist := new ClipHistory()
; 光标或鼠标跟随控件
global followList := new FollowListBox()
global follSingleLineEdit := new FollowSingleLineEdit()
global follMultiLineEdit := new FollowMultiLineEdit()
; 启动“Ctrl+命令”死循环
startCtrlCmdLoop()
return ; 自动运行段结束
/*
最终命令(RCtrl松开执行的命令)
【系统复制】RCtrl + c
【系统粘贴】RCtrl + v
【系统剪切】RCtrl + x
【截图复制】RCtrl + cc
鼠标选择屏幕上任何矩形区域(先Ctrl+cc,后选择)
【图片粘贴】RCtrl + vv
鼠标选择粘贴屏幕任意位置,也可以将复制文本作为图片粘贴 (先Ctrl+cc,后选择)
Clipboard浏览管理(RCtrl未松开执行的命令)
【下一个clip浏览】 RCtrl + vs(x) 如果以x结尾,则表示松开后也不执行(下同)
【上一个clip浏览】 RCtrl + vf(x)
【删除当前clip】 RCtrl + vd(x)
【删除全部】 RCtrl + va(x)
贴图管理(Ctrl未松开执行的命令)
【下一个贴图】 RCtrl + vvs(x)
【上一个贴图】 RCtrl + vvf(x)
【删除当前贴图】 RCtrl + vvd(x)
【删除全部贴图】 RCtrl + vva(x)
组合命令(Ctrl松开后)
RCtrl + c[a|s|d|f]* = RCtrl + c
RCtrl + v[a|s|d|f]* = RCtrl + v
RCtrl + c[a|s|d|f]*c = RCtrl + cc
RCtrl + v[a|s|d|f]*v = RCtrl + vv
*/
$>^c::
$>^v::
$>^x::
$>^s::
$>^d::
$>^a::
$>^f::
$>^e::
$>^w::
$>^t::
$>^r::
RCtrlHandler()
return
/*
RCtrl+命令 拦截
*/
RCtrlHandler(){
Critical
global runingCtrlRich ; CtrlRich模块运行状态
global rctrlCmd ; RCtrl+命令
if (not ctlCmd){
ctlCmd := ""
}
if (not runingCtrlRich){
return
}
c_ := SubStr(A_ThisHotkey, 4)
rctrlCmd := rctrlCmd c_
; 等待c_对应的字母键松开(增强程序稳定性)
KeyWait, %c_%
}
#IfWinActive 沙拉查词-独立查词窗口
Esc::WinClose
#IfWinActive
/*
“Ctrl+命令”处理之死循环
*/
startCtrlCmdLoop(){
; RCtrl+命令
global rctrlCmd := ""
; 跟随提示位置坐标(Ctrl按下和松开之间保持不变)
global tooltipPosX
global tooltipPosY
; 用于跟随提示的显示位图的句柄
global hWNDToolTip := 0
global runingSnipaste := False ; snipaste是否安装并启动
global runingChrome := False ; 谷歌浏览器是否安装并启动
global installedTesseract := False ; OCR引擎tesseract是否安装并可调用
global installedMagick := False ; imagemagick是否已经安装 【关闭相关处理,因为tesseract5支持二值化处理】
global runingCtrlRich := False ; 本模块是否已经启动
; 【这段注释掉的代码含有如何运行PowerShell.exe中的命令? 如何启动Win商店版程序,具有参考价值】
; 启动Snipaste
; familyName := ""
; Clip_Saved:=ClipboardAll
; try{
; Clipboard:=""
; RunWait, PowerShell.exe -Command &{Get-AppxPackage -Name "*45479liulios*" | CLIP},, hide
; ClipWait,2
; familyName := Clipboard
; ; PackageFamilyName : 45479liulios.17062D84F7C46_p7pnf6hceqser
; if RegExMatch(familyName, "O)PackageFamilyName\s+:\s+(.+)\r?\n", SubPat) {
; familyName := Trim(SubPat.Value(1))
; Run, explorer shell:AppsFolder\%familyName%!Snipaste
; runingSnipaste := True
; }
; }catch{}
; ini文件
iniPath := A_ScriptFullPath
if (idx := InStr(iniPath, "." , , 0) ){
iniPath := SubStr(iniPath, 1 , idx-1)
}
iniPath := iniPath ".ini"
; 读取Snipaste.exe路径
IniRead, snipastePath, %iniPath%, CtrlRich, snipaste
iniError1 := (snipastePath == "ERROR")
if iniError1 {
snipastePath := "Snipaste.exe"
}
; 读取浏览器路径
IniRead, browserPath, %iniPath%, CtrlRich, browser
iniError2 := (browserPath == "ERROR")
if iniError2 {
browserPath := "Google Chrome|Chrome.exe"
}
; 读取OCR引擎tesseract路径
IniRead, tesseractPath, %iniPath%, CtrlRich, tesseract
iniError3 := (tesseractPath == "ERROR")
if iniError3 {
tesseractPath := "tesseract.exe"
}
if iniError1 or iniError2 or iniError3 {
IniWrite,
(
; 如果没有正确配置好,意味着对应的功能不被本程序(脚本)支持
; Snipaste.exe默认在PATH路径中,否则需要自行配置全路径 【无窗口】
snipaste=%snipastePath%
; 浏览器启动后的窗口标题|浏览器路径, 默认是谷歌浏览器并且在PATH路径中,否则需要自行配置全路径
; 目前谷歌浏览器和微软Edge浏览器已经通过测试
browser=%browserPath%
; OCR引擎tesseract默认在tesseract在PATH路径中,否则需要自行修改为全路径
; 如果不在指定位置(包括PATH路径中),意味着不支持OCR
tesseract=%tesseractPath%
;
), %iniPath%, CtrlRich
}
tmp1 := StrSplit(browserPath, "|")
if (tmp1.Length() < 2){
MsgBox, [CtrlRich]中的browser请按“浏览器启动后的窗口标题|浏览器路径”格式配置!
ExitApp
}
browserWinTitle := tmp1[1]
browserPath := tmp1[2]
SplitPath, snipastePath , snipasteFileName
SplitPath, browserPath , browserFileName
; 检查OCR引擎tesseract是否可调用
Clip_Saved:=ClipboardAll
Clipboard := ""
Run, %comSpec% /c "which "%tesseractPath%" | CLIP",, hide
ClipWait,2
installedTesseract := (Trim(Clipboard, " `t`r`n") != "")
Clipboard:=Clip_Saved
; 确保谷歌浏览器运行中(确保普通权限)
Clip_Saved:=ClipboardAll
Clipboard := ""
Run, %comSpec% /c "tasklist | find /i "%browserFileName%" | CLIP",, hide
ClipWait,2
runingChrome := (Trim(Clipboard, " `t`r`n") != "")
Clipboard:=Clip_Saved
if (not runingChrome){
Run, %browserPath% , , Hide UseErrorLevel
runingChrome := (ErrorLevel != "ERROR")
if (not runingChrome) {
FollowToolTip(browserFileName "尚未安装或不在运行路径下,不支持其扩展功能!", 5000)
}else {
SetTitleMatchMode, 2 ; 临时改成部分匹配
WinWait, %browserWinTitle%, , 30
if (ErrorLevel = 1) {
MsgBox, %browserFileName%运行中,但没有标题为%browserWinTitle%的窗口,`n`n请在配置文件中设置正确的标题, 然后重新启动。
ExitApp
}
; 类似于按下 Alt+F4 或点击窗口标题栏的关闭按钮的效果:
PostMessage, 0x0112, 0xF060,,, %browserWinTitle% ; 0x0112 = WM_SYSCOMMAND, 0xF060 = SC_CLOSE
SetTitleMatchMode, 1 ; 恢复默认精确匹配
}
}
; 如果不是管理员身份脚本未提升,请以管理员身份终止当前实例并重新启动
; 之所以放这里,是因为前面的Chrome要求用普通权限运行
full_command_line := DllCall("GetCommandLine", "str")
if not (A_IsAdmin or RegExMatch(full_command_line, " /restart(?!\S)"))
{
try ; 导致脚本以管理员身份重新启动
{
if A_IsCompiled
Run *RunAs "%A_ScriptFullPath%" /restart
else
Run *RunAs "%A_AhkPath%" /restart "%A_ScriptFullPath%"
}
ExitApp
}
; 确保Snipaste运行中(确保管理员权限)
Clip_Saved:=ClipboardAll
Clipboard := ""
Run, %comSpec% /c "tasklist | find /i "%snipasteFileName%" | CLIP",, hide
ClipWait,2
runingSnipaste := (Trim(Clipboard, " `t`r`n") != "")
Clipboard:=Clip_Saved
if (not runingSnipaste){
Run, %snipastePath% , , UseErrorLevel
runingSnipaste := (ErrorLevel != "ERROR")
if (not runingSnipaste) {
FollowToolTip("Snipaste尚未安装或不在运行路径下,不支持截图和贴图的功能!", 5000)
}
}
runingCtrlRich := True ; CtrlRich模块运行中
working := False
SetBatchLines, 10ms
loop{
if (not working){
; 等待CTRL按下
KeyWait, Control, D
}
keyIsDown := GetKeyState("RCTRL" , "P")
if keyIsDown{
if (not working){
; 进入工作状态
working := True
SetBatchLines -1
}
; RCtrl+命令 (RCtrl未松开)
execCtrlDownCmd()
}else if working {
; RCtrl+命令 (RCtrl松开)
execCtrlDownUPCmd()
; 工作完成,状态复原
working := False
clipHist.reset()
rctrlCmd := ""
tooltipPosX :=
tooltipPosY :=
SetBatchLines, 10ms
}
}
}
/*
RCtrl+命令 (RCtrl未松开)
*/
execCtrlDownCmd(){
global rctrlCmd ; RCtrl+命令
if (rctrlCmd = "vs") or (rctrlCmd = "vvs"){ ; 显示下一个clip
rctrlCmd := SubStr(rctrlCmd, 1 , -1)
clearToolTip()
clipHist.nextClip()
showClip()
return
}
if (rctrlCmd = "vf") or (rctrlCmd = "vvf"){ ; 显示上一个clip
rctrlCmd := SubStr(rctrlCmd, 1 , -1)
clearToolTip()
clipHist.prevClip()
showClip()
return
}
if (rctrlCmd = "vd") or (rctrlCmd = "vvd"){ ; 删除当前clip
rctrlCmd := SubStr(rctrlCmd, 1 , -1)
clearToolTip()
clipHist.deleteClip()
return
}
if (rctrlCmd = "va") or (rctrlCmd = "vva"){ ; 删除所有clip
rctrlCmd := SubStr(rctrlCmd, 1 , -1)
clearToolTip()
clipHist.deleteClipAll()
return
}
}
/*
RCtrl+命令 (RCtrl松开)
*/
execCtrlDownUPCmd(){
global rctrlCmd ; RCtrl+命令
global runingSnipaste ; snipaste是否安装并启动
global runingChrome ; Chrome是否安装并启动
global installedTesseract ; OCR引擎tesseract是否安装并可调用
TransClip := False ; 默认不翻译剪切板
; 截图OCR识别文字保存到剪切板, 命令不妨取 RCtrl-cr
if (SubStr(rctrlCmd, 1, 2) = "cr") and (SubStr(rctrlCmd, 0) != "x"){
clearToolTip()
if runingSnipaste and installedTesseract {
Ocr2Clip()
}
rctrlCmd := SubStr(rctrlCmd, 3)
if (rctrlCmd = ""){
return
}
TransClip := True ; 翻译剪切板
}
; 沙拉查词-独立查词窗口, 命令不妨取 RCtrl-wf
; 如果没有选择,则弹出空的查词窗口
; 如果选择了,则对当前所选内容查词
if (rctrlCmd = "cwf"){
rctrlCmd := "wf"
TransClip := True ; 剪切板查词
}
if (rctrlCmd = "wf"){
clearToolTip()
if runingChrome{
SelectTranslate("沙拉查词-独立查词窗口", "^+2", TransClip)
}
return
}
; 独立翻译窗口 - 划词翻译, 命令不妨取 RCtrl-ff
; 如果没有选择,则弹出空的翻译窗口
; 如果选择了,则翻译当前所选内容
if (rctrlCmd = "cff"){
rctrlCmd := "ff"
TransClip := True ; 剪切板翻译
}
if (rctrlCmd = "ff"){
clearToolTip()
if runingChrome{
SelectTranslate("独立翻译窗口 - 划词翻译", "^+1", TransClip)
}
return
}
if (rctrlCmd = "ct"){ ; 修改当前剪切板(c)标签(t) , 所以命令取: RCtrl-ct
clearToolTip()
follSingleLineEdit.show(clipHist.getClipTag(), "setClipTag", clipHist)
return
}
if (rctrlCmd = "ww"){ ; 进入白板(w)模式, 所以命令取: RCtrl-ww
clearToolTip()
if runingSnipaste {
SnipasteWhiteboard()
}
return
}
if (rctrlCmd = "ce"){ ; 只对文本剪切板(c)编辑(e), 所以命令取: RCtrl-ce
clearToolTip()
clipHist.moveClip()
clip := Trim(clipboard, "`r`n")
if (clip != "") {
tag := clipHist.getClipTag()
if (tag != ""){
tag := "[" tag "]"
}
follMultiLineEdit.show(tag clip, "saveTextToClipAndPaste")
}
return
}
if (rctrlCmd = "sv"){ ; 进入搜索(s)粘贴(v)模式, 所以命令取: RCtrl-sv
clearToolTip()
follSingleLineEdit.show("", "searchTextClipForPaste")
return
}
if (rctrlCmd = "cc"){ ; RCtrl+cc 截图复制, 命令取: RCtrl-cc 表示加强版复制
clearToolTip()
if runingSnipaste {
SnipasteS()
}
return
}
if (rctrlCmd = "vv"){ ; RCtrl+vv 粘贴到屏幕, 命令取: RCtrl-vv 表示加强版复制粘贴
clearToolTip()
if runingSnipaste {
SnipasteP()
}
return
}
if (rctrlCmd = "cv"){ ; RCtrl+cv 先截图复制(c)然后直接粘贴(v)到屏幕上, 所以命令取: RCtrl-cv
clearToolTip()
if runingSnipaste {
SnipasteSP()
}
return
}
if (StrLen(rctrlCmd) = 1) { ; 保证拦截的“Ctrl+单字符命令”的系统原生功能不变
if (rctrlCmd = "c") or (rctrlCmd = "x"){ ; 复制剪切前清空剪贴板,方便后续判定
clip1:=ClipboardAll
clipboard := ""
}else if (rctrlCmd = "v"){
clearToolTip()
}
Send, ^%rctrlCmd%
if (rctrlCmd = "c") or (rctrlCmd = "x") { ; 如果新内容,则新加一条历史记录
ClipWait, 1 , 1 ; 等待剪贴板中出现数据.
if (ErrorLevel = 1) {
return
}
clip2 := ClipboardAll
IF clip1 <> %clip2%
{
clipHist.addClip()
}
return
}if (rctrlCmd = "v"){ ; 粘贴后的记录作为最新记录
clipHist.moveClip()
return
}
return
}
if (SubStr(rctrlCmd, 0) = "x"){ ; 放弃(x)原本的动作,所以: RCtrl-[cvxsdafewt]+x 表示放弃
clearToolTip()
return
}
; 其它的情况无动作
}
/*
清空已有提示
*/
clearToolTip(){
global hWNDToolTip ; 用于跟随提示的显示位图的句柄
global runingSnipaste ; snipaste是否安装并启动
if (not hWNDToolTip) {
ToolTip
return
}
if (not runingSnipaste){
Gui, %hWNDToolTip%:Destroy
hWNDToolTip := 0
return
}
; 关闭贴图(确保贴图在激活状态下发送Snipaste内置快捷键`Shift+ESC`销毁贴图)
WinActivate , ahk_id %hWNDToolTip%
WinWaitActive , ahk_id %hWNDToolTip%
hWND := WinExist("A")
Send +{ESC}
WinWaitNotActive, ahk_id %hWND%
hWNDToolTip := 0
}
/*
显示当前剪切板内容
*/
showClip(){
global runingSnipaste ; snipaste是否安装并启动
if runingSnipaste {
toolTipSnipaste()
}else {
pBitmap := Gdip_CreateBitmapFromClipboard()
if (pBitmap < 0) {
toolTipClip(Clipboard)
}else{
toolTipImage(pBitmap)
}
}
}
/*
文本跟随提示
*/
toolTipClip(tooltip_){
global tooltipPosX ; 跟随提示位置坐标X(Ctrl按下和松开之间保持不变)
global tooltipPosY ; 跟随提示位置坐标Y(Ctrl按下和松开之间保持不变)
tag := clipHist.getClipTag()
if (tag != ""){
tag := "[" tag "]"
}
clip := tag tooltip_
if (not tooltipPosX){
; 当前光标或鼠标位置
CoordMode, Caret, Screen
if (not A_CaretX){
CoordMode, Mouse, Screen
MouseGetPos, tooltipPosX, tooltipPosY
tooltipPosX := tooltipPosX + 10
}else {
tooltipPosX := A_CaretX
tooltipPosY := A_CaretY + 20
}
}
CoordMode, ToolTip, Screen
ToolTip, %clip%, %tooltipPosX%, %tooltipPosY%
}
/*
图片跟随提示
*/
toolTipImage(pBitmap){
global tooltipPosX ; 跟随提示位置坐标X(Ctrl按下和松开之间保持不变)
global tooltipPosY ; 跟随提示位置坐标Y(Ctrl按下和松开之间保持不变)
global hWNDToolTip ; 用于跟随提示的显示位图的句柄
if (not tooltipPosX){
; 当前光标或鼠标位置
CoordMode, Caret, Screen
if (not A_CaretX){
CoordMode, Mouse, Screen
MouseGetPos, tooltipPosX, tooltipPosY
tooltipPosX := tooltipPosX + 10
}else {
tooltipPosX := A_CaretX
tooltipPosY := A_CaretY + 20
}
}
; 贴图
;scale := "h" A_ScreenHeight*0.2
hWNDToolTip := pasteImageToScreen(pBitmap, , tooltipPosX "," tooltipPosY) ;, , scale)
Gdip_DisposeImage(pBitmap)
}
; 利用Snipaste进行剪切板浏览
toolTipSnipaste(){
global tooltipPosX ; 跟随提示位置坐标X(Ctrl按下和松开之间保持不变)
global tooltipPosY ; 跟随提示位置坐标Y(Ctrl按下和松开之间保持不变)
global hWNDToolTip ; 用于跟随提示的显示位图的句柄
if (not tooltipPosX){
; 当前光标或鼠标位置
CoordMode, Caret, Screen
if (not A_CaretX){
CoordMode, Mouse, Screen
MouseGetPos, tooltipPosX, tooltipPosY
tooltipPosX := tooltipPosX + 10
}else {
tooltipPosX := A_CaretX
tooltipPosY := A_CaretY + 20
}
}
tag := clipHist.getClipTag()
if (tag != ""){
tag := "[" tag "]"
}
; 判断剪切板是否是文本
isText := False
if (tag != "") {
Ptr := A_PtrSize ? "UPtr" : "UInt"
if DllCall("IsClipboardFormatAvailable", "uint", 1){
DllCall("OpenClipboard", Ptr, 0)
isText := (not (not DllCall("GetClipboardData", "uint", 1, Ptr)))
DllCall("CloseClipboard")
}
}
; 贴图,确保获取贴图句柄
oldclip := ClipboardAll
if (tag != "") and isText{
Clipboard := tag Clipboard
}
RunWait, % "Snipaste paste --clipboard --pos " tooltipPosX " " tooltipPosY
; 如果被浏览的clip和桌面已有贴图内容重复,会闪烁后处于非激活状态
; 所以必须设置超时时间,假设2s等待激活超时,就是遇到了这种情况
WinWaitActive, Paster - Snipaste , , 2
; 无论是否超时,这个贴图对应的窗口已经存在,所以可以直接获取窗口句柄
; 并且这个贴图是最近激活过的,所以不会错误获取桌面其它已有的无关贴图窗口句柄
hWNDToolTip := WinExist("Paster - Snipaste")
Clipboard := oldclip
}
/*
进入搜索粘贴模式
只搜索单行文本剪切板内容,因为常用需要粘贴都是单行的
凡是搜索过的内容,都不会被“全部删除命令a”删除,但可以被“删除命令d”删除
*/
searchTextClipForPaste(search){
global matchedSingleLineClip := [] ; 匹配到的所有单行文本
global matchedSingleLineClipIndex :=[] ; 匹配到的所有单行文本在cliparray中的索引
; 空值无动作
if (Trim(search) == ""){
return
}
; 搜索
clipHist.searchClip(matchedSingleLineClip, matchedSingleLineClipIndex, search)
; 弹出建议窗口
if (matchedSingleLineClip.Length() > 0)
{
; 弹出提示窗口
followList.show(matchedSingleLineClip, "SearchPasteHandler")
}
}
/*
搜索后选择后的粘贴处理
*/
SearchPasteHandler(index){
; index 提示列表栏选择的序号
global matchedSingleLineClipIndex ; 匹配到的所有单行文本在cliparray中的索引
; 凡是搜索选择过的内容,都认为是比较重要的,所以特别添加到.clip\clip.tag中标记之
aclip := matchedSingleLineClipIndex[index]
tag := clipHist.getClipTag(aclip)
if (tag = ""){
tag := "★"
}
clipHist.setClipTag(tag, aclip)
; 读入到剪切板
clipHist.readClip(aclip)
; 主动将剪切板的内容粘贴
Send, ^v
; 将选择的clip移到最新(并且读入到剪切板)
clipHist.moveClip(aclip)
}
/*
将文本内容保存到当前粘贴板,然后粘贴
*/
saveTextToClipAndPaste(saveText){
if clipHist.saveClip(saveText){
; 主动将剪切板的内容粘贴
Send, ^v
; 将选择的clip移到最新(并且读入到剪切板)
clipHist.moveClip()
}
}
; 【基于Snipaste】鼠标选择截图 或 点击窗口截图 到 剪切板
SnipasteS(){
oldClip := clipboardAll
Run, % "Snipaste snip -o clipboard"
; 先等待操作窗口激活,再等待该窗口消失,这个动作才算完成
; 无论什么情况返回,如果剪切板有变化,则添加到clip历史记录中
WinWaitActive, Snipper - Snipaste
hWND := WinExist("A")
WinWaitNotActive, ahk_id %hWND%
newClip := clipboardAll
IF oldClip <> %newClip%
{
clipHist.addClip()
}
}
; 【基于Snipaste】鼠标选择截图 或 点击窗口截图 到 剪切板
SnipasteP(){
Run, % "Snipaste paste --clipboard"
clipHist.moveClip()
}
; 【基于Snipaste】截图后直接贴图
SnipasteSP(){
oldClip := clipboardAll
Run, % "Snipaste snip -o clipboard"
; 先等待操作窗口激活,再等待该窗口消失,这个动作才算完成
; 无论什么情况返回,如果剪切板有变化,则添加到clip历史记录中
WinWaitActive, Snipper - Snipaste
hWND := WinExist("A")
WinWaitNotActive, ahk_id %hWND%
newClip := clipboardAll
IF oldClip <> %newClip%
{
clipHist.addClip()
Run, % "Snipaste paste --clipboard"
}
}
; 【基于Snipaste】启动白板
SnipasteWhiteboard(){
oldClip := clipboardAll
Run, Snipaste whiteboard
; 先等待操作窗口激活,再等待该窗口消失,这个动作才算完成
; 无论什么情况返回,如果剪切板有变化,则添加到clip历史记录中
WinWaitActive, Snipper - Snipaste
hWND := WinExist("A")
WinWaitNotActive, ahk_id %hWND%
newClip := clipboardAll
IF oldClip <> %newClip%
{
clipHist.addClip()
}
}
; 选择翻译, 如果没有选择则鼠标取词翻译(默认不翻译剪切板)
SelectTranslate(WinName, HotKeyStr, TransClip := False) {
; 先复制
clip1 := ClipboardAll
if (not TransClip) {
Clipboard := ""
Send, ^c
}
ClipWait, 1 , 1 ; 等待剪贴板中出现数据.
if (ErrorLevel = 0) {
StringReplace, clipboard, clipboard, `r, , All
StringReplace, clipboard, clipboard, `n, %A_Space% , All
clip2 := ClipboardAll
IF clip1 <> %clip2%
{
clipHist.addClip()
}
Send, %HotKeyStr%
}else{
Send, %HotKeyStr%
WinWaitActive, %WinName%, , 10
if (ErrorLevel = 1){
runingChrome := False
}
Clipboard := clip1
}
}
; 截图OCR识别文字保存到剪切板
Ocr2Clip(options := "-l eng+chi_sim+chi_tra") {
global installedMagick ; imagemagick是否已经安装
; 清空旧的截图临时文件
tmpsnip := A_ScriptDir "\tmpsnip.png"
if FileExist(tmpsnip){
FileDelete, %tmpsnip%
}
; 截图,并且确保已完成或已放弃
Run, %comSpec% /c "snipaste snip -o "%tmpsnip%,,hide
WinWaitActive, Snipper - Snipaste
WinWaitNotActive, Snipper - Snipaste
; 截图临时文件存在则继续
if FileExist(tmpsnip){
if installedMagick {
; 需要先对图片进行二值化
; https://imagemagick.org/script/command-line-options.php#auto-threshold
; Kapur(区分度有点差) OTSU(还是用这个效果好) Triangle(太粗)
RunWait, % comSpec " /c magick mogrify -auto-threshold OTSU " tmpsnip,,hide UseErrorLevel
installedMagick := (ErrorLevel != "ERROR")
}
clip1 := ClipboardAll
if installedMagick {
; 判断二值化后是白底黑字还是黑底白字
; https://imagemagick.org/script/escape.php
Clipboard := ""
RunWait, % comSpec " /c magick identify -format ""%[min] %[mean] %[max]"" " tmpsnip " | CLIP",,hide
ClipWait, 1 ; 等待剪贴板中出现数据.
clips := StrSplit(Trim(Clipboard, " `t`r`n"), " ")
if (clips.Length() = 3) and (clips[2] < (clips[1] + clips[3])/2) {
; 将黑底白字转换称白底黑字
; https://imagemagick.org/script/color-thresholding.php
RunWait, % comSpec " /c magick mogrify -color-threshold 'sRGB(0,0,0)-sRGB(127,127,127)' " tmpsnip,,hide
}
}
; 第一次尝试OCR 【大范围截图: 全自动页面分割,但没有 OSD。 对大部分情况有效】
Clipboard := ""
RunWait, % comSpec " /c tesseract " tmpsnip " stdout " options " | CLIP",,hide
ClipWait, 1 ; 等待剪贴板中出现数据.
clip := ""
if (ErrorLevel = 0) {
clip := Trim(Clipboard, " `t`r`n")
}
; 第二次尝试OCR 【小范围截图: 假设有一个统一的文本块】
if (clip = "") and (InStr(options, "--psm") = 0){
Clipboard := ""
; --psm 6 假设有一个统一的文本块。
RunWait, % comSpec " /c tesseract " tmpsnip " stdout " options " --psm 6 | CLIP",,hide
ClipWait, 1 ; 等待剪贴板中出现数据.
if (ErrorLevel = 0) {
clip := Trim(Clipboard, " `t`r`n")
}
}
; 第三次尝试OCR 【小范围截图: 将图像视为一个词】
if (clip = "") and (InStr(options, "--psm") = 0){
Clipboard := ""
; --psm 8 将图像视为一个词。
RunWait, % comSpec " /c tesseract " tmpsnip " stdout " options " --psm 8 | CLIP",,hide
ClipWait, 1 ; 等待剪贴板中出现数据.
if (ErrorLevel = 0) {
clip := Trim(Clipboard, " `t`r`n")
}
}
if (clip != "") { ; OCR若有结果,则存入剪切板
Clipboard := clip
clip2 := ClipboardAll
IF clip1 <> %clip2%
{
clipHist.addClip()
}
}else{ ; OCR若无结果,则恢复旧的剪切板
Clipboard := clip1
}
}
}
AutoHotkey
1
https://gitee.com/chaoskey/SharpKnife.git
git@gitee.com:chaoskey/SharpKnife.git
chaoskey
SharpKnife
SharpKnife
master

搜索帮助