从AutoHotKey脚本捕获Windows上空文本的复制/粘贴

时间:2010-08-01 09:21:21

标签: windows copy-paste autohotkey

默认情况下,在Windows上,复制文本时,它会被放入剪贴板中。但是在尝试复制文本时,剪贴板不受影响。例如,在编辑器中选择没有文本,然后点击ctrl+c,将不会导致剪贴板发生变化。

问题是,我需要使用AutoHotKey捕获此事件。由于剪贴板未更改,我不知道如何干净地完成此操作(没有超时,即)。

有没有人知道如何做到这一点?

编辑:为了澄清,我正在从AutoHotKey中发送ctrl + c。我这样做是为了判断是否选择了任何文本,即我正在发送ctrl + c,然后检查是否有任何文本被复制到剪贴板。问题是,如果没有选择文本,AutoHotKey的剪贴板处理程序永远不会被调用,迫使我使用超时,这不是一个好习惯。

7 个答案:

答案 0 :(得分:3)

这就是我所做的。由于剪贴板是AutoHotkey中的变量,因此您可以检查它是否为空。我首先清除了剪贴板,发送控件+ c,然后查看剪贴板是否仍为空。如果需要,您可以先将当前剪贴板暂时移动到临时位置。

ClipSaved := ClipboardAll
Clipboard =     ; empties the clipboard
Send ^+{Left}   ;  I just used highlight left to select text, you can replace this with
             ; whatever your program uses to select an input.
Send ^c         ; attempt to copy text
If Clipboard =  ;  checks to see if clipboard is empty
{
    break  ; Put what you want to do if the clipboard is empty, I used break to stop a loop
}
Clipboard := ClipSaved  ; puts the original clipboard contents back

我正在从一个打开的文档中搜索文本,用户可以在其中选择向前或向后的方向。向后移动时,它会陷入文档开头的循环中。我设置了一个循环限制,以防止它成为一个无限循环,但它仍然浪费时间等待循环完成。如果剪贴板为空,我使用break函数结束循环。

为了给予信用到期的信用,我从其他帖子获得了灵感,其中有其他的东西提示。它发布了您可以使用此脚本检查空白变量。 http://www.autohotkey.net/~deleyd/xprxmp/autohotkey_expression_examples.htm#J  v:=""

If v =
    MsgBox v = ""

If (v = "")
    MsgBox v = ""

在AutoHotkey文档网站上,我了解了如何临时存储和替换剪贴板内容。 http://www.autohotkey.com/docs/misc/Clipboard.htm

ClipSaved := ClipboardAll   ; Save the entire clipboard to a variable of your choice.
    ;... here make temporary use of the clipboard, such as for pasting Unicode text via    Transform Unicode ...
Clipboard := ClipSaved   ; Restore the original clipboard. Note the use of Clipboard    (not ClipboardAll).
ClipSaved =   ; Free the memory in case the clipboard was very large.

希望这会有所帮助。 塞缪尔

答案 1 :(得分:2)

这是我目前使用的解决方案。基本上,它归结为发送ctrl+c,等待某个超时,然后查看文本是否实际被复制。如果不是,我知道没有选择。

由于Windows需要一段时间才能执行copy操作,因此无法避免等待超时。我将超时设置为0.15秒,所以它也不错。

这是我每次想要抓取剪贴板内容时使用的函数,或者检查它是否为空。我总是先调用这个函数:

clipped_text :=
clip_empty := false
ClipSaved =
is_clipped := false

clip_speed := 0.15

Clip() {
    global ClipSaved
    global clip_empty
    global clipped_text
    global is_clipped
    global clip_speed

    if (!is_clipped) {
        ClipSaved := ClipboardAll   ; Save the entire clipboard to a variable of your choice.
        ; msgbox % ClipSaved
        is_clipped := true
    }

    clipboard = ; Empty the clipboard

    Send ^{c}
    ClipWait clip_speed

    if (ErrorLevel = 1)
    {
        clip_empty := false
    }
    else
    {
        clip_empty := true
        clipped_text := clipboard
    }
}

我使用此函数实际获取剪贴板的内容或检查它是否为空:

IsTextSelected() {
    global ClipSaved
    global clip_empty
    global clipped_text

    if (clip_empty == true) {
        return true
    }
    else {
        return false
    }
}

要获取剪贴板的内容,我只需查看clipped_text变量。

执行“Clip()”操作后,我总是调用以下函数来恢复剪贴板(对于多次调用Clip(),此函数被称为一次):

UnClip() {
    global ClipSaved
    global clip_empty
    global clipped_text
    global is_clipped

    is_clipped := false
    Clipboard := ClipSaved
    ClipSaved =
}

答案 2 :(得分:2)

虽然不是这个问题的实际答案,但如果您正在寻找一种方法来捕捉粘贴文字并在粘贴之前对其进行修改,那么谷歌搜索可能会引导您到这里。

这是在 CTRL + V 上从剪贴板粘贴的文本中删除空格的脚本:

~^v::
Trimmed := RegExReplace(Clipboard, "^\s+", "")
Trimmed := RegExReplace(Trimmed, "\s+$", "")
Clipboard = %Trimmed%
SendInput ^v
return

答案 3 :(得分:0)

也许您应该热键Ctrl + C,这样,只要按下该热键,您就会知道。

您可能希望确保将正常的Ctrl + C操作发送到Windows,以便您可以复制。 考虑这个例子:

~^c::
msgbox, % "Clipboard Changed even if you didnt copy anything"
        . "(...not really but you tried at least)"
return

即使您没有将任何内容复制到剪贴板,每次按Ctrl + C时都会触发该消息。同时,您将向Windows发送Ctrl + C的本机功能,这样如果您复制了某些内容,剪贴板将会改变。

从帮助文件中:

  

:当热键触发时,其键的本机功能将不会被阻止(从系统中隐藏)。

您可能还需要onClipboardChange来检查剪贴板何时真正更改。

答案 4 :(得分:0)

我想我有一个解决方案。留出当前剪贴板,然后复制。将您复制的内容与空字符串进行比较..如果它相等,则复制了一些内容;否则,没有复制。然后,将剪贴板恢复为您保存的内容。这是一个展示原理的代码示例。

^#x::
   ClipSaved := ClipboardAll   ; Save the entire clipboard to a variable of your choice.
   ; ... here make temporary use of the clipboard, such as for pasting Unicode text via Transform Unicode ...
   Clipboard := ; Clear the clipboard
   Send, {CTRLDOWN}c{CTRLUP}
   if (Clipboard = "") {
      Send, you copied nothing
   } else {
      Send, you copied something
   }
   Clipboard := ClipSaved   ; Restore the original clipboard. Note the use of Clipboard (not ClipboardAll).
   ClipSaved =   ; Free the memory in case the clipboard was very large.
return

实际上,我希望还有另一种方法可以简单地测试光标当前是否正在选择任何东西。我在AutoHotkey论坛上问过这个问题(http://www.autohotkey.com/forum/posting.php?mode=reply&t=69468),但是如果有更好的答案,我将使用以上方法

答案 5 :(得分:0)

巴比伦的脚本(firefox的中鼠标键):

MButton::
SetTitleMatchMode, 2
send {LButton}{LButton}
Send ^c
sleep, 100
send {F10}
sleep, 100
SendInput {Raw}%clipboard%
send {enter}
Return

答案 6 :(得分:0)

我有同样的问题 - 我会发送复制命令,但它不会复制任何东西。我尝试与计时器合作无济于事。

这是我最终做的事情(尝试不同的模式):

thisclipboard := clipboard . a_now  ;add NOW so that it won't possibly be the same as the contents of the clipboard
    sendplay,^c
    if(clipboard == thisclipboard){
        sendinput,^c
    }
    if(clipboard == thisclipboard){
        send,^c
    }