excludesHwnds := GetClipboardFormatListenerList() ; 阻止一些剪贴板工具窗口触发
; 当剪贴板数据被请求后显示一个msgbox, 一次性
f1::ClipboardDelayRender(A_Clipboard, () => MsgBox("剪贴板文字已被获取"), excludesHwnds)
; 粘贴后自动还原剪贴板
f2::PasteSend("剪贴板已还原")
PasteSend(str){
old := A_Clipboard
ClipboardDelayRender(str, () => A_Clipboard := old, excludesHwnds)
Send("^v")
}
/*
@param str string 当剪贴板数据被请求时提交至剪贴板的字符串
@param callback func 提交后执行的函数
@param excludes Map 排除的窗口句柄
*/
ClipboardDelayRender(str, callback := unset, excludes := unset) {
OnMessage(0x0305, WM_RENDERFORMAT, 0) ; 确保回调被更新
OnMessage(0x0305, WM_RENDERFORMAT)
DllCall("OpenClipboard", "ptr", A_ScriptHwnd)
DllCall("EmptyClipboard")
DllCall("SetClipboardData", "uint", 1, "ptr", 0, "ptr")
DllCall("CloseClipboard")
WM_RENDERFORMAT(*) {
; 很多剪贴板工具会自动读取剪贴板并触发这段代码, 没有很好的方法精确排除这些窗口
if IsSet(excludes) && excludes.Has(DllCall("GetOpenClipboardWindow", "ptr"))
return 0
hGlobal := DllCall("GlobalAlloc", "uint", 0x0042, "uptr", StrPut(str, "cp0"), "ptr")
StrPut(str, DllCall("GlobalLock", "ptr", hGlobal, "ptr"), "cp0")
DllCall("GlobalUnlock", "ptr", hGlobal)
DllCall("SetClipboardData", "uint", 1, "ptr", hGlobal, "ptr")
DllCall("ReplyMessage", "ptr", 0)
IsSet(callback) && callback()
OnMessage(0x0305, WM_RENDERFORMAT, 0)
return 0
}
}
GetClipboardFormatListenerList(){
tmp := A_Clipboard
listeners := Map()
OnMessage(0x0305, WM_RENDERFORMAT)
DllCall("OpenClipboard", "ptr", A_ScriptHwnd)
DllCall("EmptyClipboard")
DllCall("SetClipboardData", "uint", 1, "ptr", 0, "ptr")
DllCall("CloseClipboard")
Sleep(250)
OnMessage(0x0305, WM_RENDERFORMAT, 0)
A_Clipboard := tmp
return listeners
WM_RENDERFORMAT(*) => listeners[DllCall("GetOpenClipboardWindow", "ptr")] := 0
}
声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。

评论(0)