【问题标题】:Autohotkey clipboard variable holding values forever?Autohotkey剪贴板变量永远保存值?
【发布时间】:2019-09-07 00:18:12
【问题描述】:

我有下面的简单代码,它发送剪贴板中文本的击键,字符之间有 15 毫秒的延迟(我用它来遍历大量的树视图元素列表)。

问题:如果我将“text1”复制到剪贴板,然后复制“text2”,则此脚本会输出“text1text2”而不是单独的“text2”。

如果我重新加载脚本,它会打印“text2”。

下面的代码是否有错误,或者是在 Autohotkey 1.1.14.03 中实现 %clipboard% 的错误?

#v::
textToType=" "
textToType=%clipboard%
LoopCount:=StrLen(textToType)
;StringLen, LoopCount, textToType
Array%LoopCount%:=textToType
loop %LoopCount%
{
theChar:=Array%A_Index%
Send %theChar%
sleep 15
}
return

更新:感谢您指出更聪明的方法,但我仍然想弄清楚上面的代码有什么问题。

更新 2: 错误在于我对 AHK 语法的理解。 Array%LoopCount%:=textToType 将 textToType 中的整个字符串值分配给名为“Array”的 STRING 数组的第 (LoopCount) 个 STRING 元素。

更新 3: (感谢@John Y 的澄清)

实际上,在传统意义上,根本没有“声明”的数组。您只有一堆单独的变量,根据需要动态创建,它们的名称末尾带有数字。 Array1 和 Array2 不是某些 Array 对象中的元素。它们只是两个完全独立的变量。 AutoHotkey 提供了一种将数字粘贴到名称末尾的方法,因此您可以像使用数组一样使用它们。

【问题讨论】:

    标签: autohotkey


    【解决方案1】:

    您的脚本无法正常工作的原因是您使用pseudo-array 来存储剪贴板中的不同单词。

    我已经评论了你的代码来解释它的作用:

    #v::
        textToType  := "" ; Empty variable
        textToType  := Clipboard ; Move clipboard into variable
    
        ; Get lenght of the word
        ; Used as array index / loop count
        LoopCount := StrLen(textToType)
    
        ; Put the clipboard in an array at index 'LoopCount'
        Array%LoopCount% := textToType
    
        ; Loop through the array as many times
        ; as the string is long
        Loop % LoopCount
        {
            ; Retrieve the word at this index in the array
            theChar := Array%A_Index%
            ; Send the whole word
            Send, % theChar
            sleep 15
        }
    return
    

    您不是一次发送每个字符,而是从 Array 数组中的特定索引发送整个单词。

    假设您复制单词Dragon,该单词长度为 6 个字母。所以你把它放在Array6 中,然后你会使用同一个变量循环你的数组6次。此时循环将一次获取每个索引并将其移动到theChar。在循环的第 6 圈,您将 Array6 放入 theChar 并立即打印整个单词。

    然后你复制单词Stackoverflow。这将进入Array13,我们将循环 13 次。在第 6 圈,我们将打印出 Dragon,它位于 Array6 中,然后一直运行到第 13 圈,我们将打印 Stackoverflow,因为它位于 Array13 中。

    这就是为什么您的脚本没有按照您的意愿执行的原因。希望这会有所帮助。

    查看代码示例alpha bravo posted,这是实现您想要做的事情的正确方法。

    【讨论】:

    • 我不太明白你的解释。如果它一次性打印 'theChar' 中的整个字符串,它会打印相同的完整字符串 'LoopCount' 次。变量赋值和“发送”在同一个循环中,在大括号内。 (我同意 AHK 的新手,阅读手册和编码需要 2 分钟,但这些是基本的通用编程规则)
    • @dbza:我认为如果您手动执行代码(比如用铅笔和纸)几次迭代,您会更好地理解。当你得到一个变量时,用实际值填充它。请注意,当您处于循环迭代 1 时,除非您刚刚存储的单词长度为 1 个字符,否则该迭代不会打印任何内容,因为 Array1 不存在。在 Sidola 的示例中,Array2 也不存在。只有 Array6 和 Array13 存在。您的代码根据输入长度存储数组元素,并且循环打印从最短到最近保存的长度的每个元素。
    • 谢谢各位。事实上,匆忙阅读手册 2 分钟是我的问题。我认为 Array%LoopCount%:=textToType 的意思是声明一个带有 LoopCount 元素的字符数组并在字符串 textToType 中分配值。实际上,它创建了一个字符串数组并将 textToType 放在第 N 个字符串元素 (LoopCount) 中。我需要更多地熟悉语法。
    • @dbza:实际上,在传统意义上,根本没有“声明”的数组。您只有一堆单独的变量,根据需要动态创建,它们的名称恰好在末尾带有数字。 Array1Array2 是某些 Array 对象中的 not 元素。它们只是两个完全独立的变量。 AutoHotkey 提供了一种将数字粘贴到名称末尾的方法,因此您可以 数组一样使用它们。当您查看有关数组的 AutoHotkey 文档时,请特别注意“关联数组”和“伪数组”之间的区别。您正在使用伪数组。
    • 非常感谢@JohnY!我可能错过了关于数组的手册页中的这些基本信息,或者他们根本没有。
    【解决方案2】:

    保持简单

    #v::
    loop Parse, Clipboard
    {
        Send %A_LoopField%
        sleep 15
    }
    return

    【讨论】:

    【解决方案3】:

    在 AHK 中执行剪贴板分配一定存在错误。使用下面的代码,AHK 的行为是每次访问 dir 的值时,AHK 都会从剪贴板中获取最新的值,而不是在脚本激活时获取 dir 的值。

    ; Remove all CR+LF's from the clipboard contents:
    dir = %clipboard%
    sleep 100
    dir := StrReplace(dir, "`r`n")
    

    编辑: 为了解决这个问题,我在剪贴板分配代码之前添加了 1 秒睡眠:

    sleep 1000
    ; Remove all CR+LF's from the clipboard contents:
    dir = %clipboard%
    dir := StrReplace(dir, "`r`n")
    

    100 毫秒睡眠似乎不起作用。

    访问dir 的值现在只给出激活时最后一个剪贴板分配的值。

    【讨论】:

      猜你喜欢
      • 2019-11-24
      • 2020-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-14
      • 2020-05-05
      • 2012-08-28
      • 1970-01-01
      相关资源
      最近更新 更多