Page 1 of 1

Saving ClipboardAll to a nested object does not work

Posted: 26 Dec 2017, 21:40
by mviens
I have been struggling with some much larger code that saves a copy of ClipboardAll. It seems if I save it to a nested object (e.g. someObj.someProp.someVar), then it fails. It was driving me quite mad, so I created a simple prototype to show what is going on. If I copy ClipBoardAll to a local variable or a global variable, then it works fine. There should be no different between using a variable within an object. I am definitely open to the idea I am doing something incorrect, but I have an application that is using over 20,000 lines of AHK source code and it is working just fine, so being new to this is (hopefully) not my issue...

To use this code, just run it. Select some simple text, even just a word from this source code. Then press Win-C. It will create three files, two of which should contain the saved clipboard. All three files at this point have the correct contents. Now press Win-G. The newly created fourth file will also be correct. Now press Win-B to update one of the original files. This is where referencing a nested variable that points to a ClipboardAll object fails. Here is the code:

UPDATE: I added using an Array too, which has the same issue.

Code: Select all

    #SingleInstance force
    global globalCopy
    global hack := {}
    hack.vars := {}
    hack.vars.blah := "This is not my final value...`r`n"
    global clips := []
    
    #c::
        Send, ^c
        ClipWait
        copied := ClipboardAll
        localCopy := copied
        globalCopy := localCopy
    
        FileDelete, % A_Temp . "\clip_*.txt"
        FileAppend, % copied, % A_Temp . "\clip_copied.txt"         ; this works
        FileAppend, % localCopy, % A_Temp . "\clip_localCopy.txt"   ; this works
        FileAppend, % hack.vars.blah, % A_Temp . "\clip_blah.txt"   ; this works
        hack.vars.blah := copied                                    ; copy the value to an Object for use later
        clips.Push(copied)                                          ; copy the value to an Array for use later
        return
    
    #g::
        FileAppend, % globalCopy, % A_Temp . "\clip_globalCopy.txt" ; this works
        return
    
    #b::
        FileAppend, % hack.vars.blah, % A_Temp . "\clip_blah.txt"   ; this fails... it only writes one byte (0x3F)
        return
    
    #s::
        tmpClip := clips.pop()
        FileAppend, % tmpClip, % A_Temp . "\clip_stack.txt"         ; this fails... it only writes one byte (0x3F) 
        return

Re: Saving ClipboardAll to a nested object does not work

Posted: 30 Dec 2017, 20:47
by lexikos
v1 does not support binary data except in very limited cases, such as assigning one variable to another variable (not an array element). Assigning ClipboardAll to a variable marks the variable as containing binary clipboard data. There are a bunch of special cases in the code that rely on this mark, such as for comparing binary-clip variables (but not ClipboardAll) with = and <>, copying them, writing them to file, or assigning them back to the clipboard. If this special mark is lost, you cannot assign it back to the clipboard (and the only workaround is to write it to file and then read it back with FileRead *c).

v2-alpha handles binary data better, but also replaces ClipboardAll with ClipboardAll(), which returns an object. It behaves much more consistently than binary clipboard data in v1.

If you don't want to switch to v2, there are workarounds to manually copy the data from a variable into an object. However, it is complicated and there's a big caveat: you still can't assign it back to the clipboard without first writing it to file.

Alternatively, you can look for a script library called "WinClip", which basically reinvents ClipboardAll; or you can use the Win32 clipboard functions directly (this is also complicated), as WinClip does.
FileAppend, % hack.vars.blah, % A_Temp . "\clip_blah.txt" ; this works
How do you mean "works"? It certainly won't write valid binary clipboard data.

Re: Saving ClipboardAll to a nested object does not work

Posted: 30 Dec 2017, 21:49
by jeeswg
You may find some useful information in this post.
conversion logic, v1 = -> v1 := -> v2, two-way compatibility - Page 6 - AutoHotkey Community
https://autohotkey.com/boards/viewtopic ... 68#p191068