 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
deanhill1971
Joined: 30 Sep 2005 Posts: 52 Location: Fort Wayne, IN
|
Posted: Wed May 16, 2007 5:12 pm Post subject: OnClipboardChange label eventually stops responding |
|
|
I've written my own multiple clipboard code (just like many other people have done). Everything works great for maybe three hours, then I notice that the contents of my multi-clip list isn't changing. I've determined that the OnClipboardChange label is no longer being called.
Below is my code. The FileExist line was used to diagnose this problem. When I suspect a problem, I create the onclipshow.txt file to see if the label is still being called. Sure enough, the msgbox doesn't display. If I refresh my script, the msgbox does start appearing.
The multi-clip code is pretty small, but I include it into my main AHK script. All told, the script is probably 6000-7000 lines.
Has anyone else seen OnClipboardChange stop responding? Does anyone have any thoughts on how I can diagnose this further? Thanks.
| Code: |
OnClipboardChange:
if FileExist("c:\temp\onclipshow.txt")
msgbox, In OnClipboardChange label. A_EventInfo=%A_EventInfo% IgnoreClipboardChange=%IgnoreClipboardChange%
; Leave if the clipboard is empty or we are told to ignore the change
if (A_EventInfo == 0 or IgnoreClipboardChange)
{
IgnoreClipboardChange =
return
}
MultiClipboardAdd()
return
|
|
|
| Back to top |
|
 |
vital
Joined: 05 Oct 2005 Posts: 17 Location: china
|
Posted: Sat Jul 28, 2007 7:57 am Post subject: |
|
|
| i had seen the same problem , but i don't know how to diagnose it . |
|
| Back to top |
|
 |
deanhill1971
Joined: 30 Sep 2005 Posts: 52 Location: Fort Wayne, IN
|
Posted: Sat Jul 28, 2007 2:15 pm Post subject: |
|
|
Thanks for the reply. I'm still seeing OnClipbardChange stop responding (way too often).
Unless there is a fix, I'm going to start restructuring my script in the hope it resolves the issue. |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4016 Location: Pittsburgh
|
Posted: Sat Jul 28, 2007 4:01 pm Post subject: |
|
|
| Does increasing #ClipboardTimeout make a difference? Something like #ClipboardTimeout 2000? |
|
| Back to top |
|
 |
deanhill1971
Joined: 30 Sep 2005 Posts: 52 Location: Fort Wayne, IN
|
Posted: Mon Jul 30, 2007 12:07 pm Post subject: |
|
|
| Thanks for the suggestions Laszlo. I used #ClipboardTimeout 2000, but I still see the problem. I'll try setting the timeout to other values, and see what happens. |
|
| Back to top |
|
 |
deanhill1971
Joined: 30 Sep 2005 Posts: 52 Location: Fort Wayne, IN
|
Posted: Fri Oct 12, 2007 7:14 pm Post subject: |
|
|
I moved all my clipboard code into its own script. The OnClipboardChange label does remain active longer in this configuration, but it still stops being called after several hours of using the script.
Unless people have other suggestions, I'm going to stop using AHK as my "clipboard manager". |
|
| Back to top |
|
 |
urlwolf
Joined: 16 Mar 2006 Posts: 100
|
Posted: Wed Nov 07, 2007 3:28 pm Post subject: |
|
|
I'd be interested in knowing whether this is a bug, and if it's been fixed.
I use The OnClipboardChange label a lot, and having it stopping working would mean I have to abandon ahk for this project...
Thanks |
|
| Back to top |
|
 |
deanhill1971
Joined: 30 Sep 2005 Posts: 52 Location: Fort Wayne, IN
|
Posted: Wed Nov 07, 2007 5:08 pm Post subject: |
|
|
So far, vital and I have both run across this problem.
If urlwolf or anyone else wants to try and reproduce the problem, then run the script below.
To test, do copies and pastes throughout the day. Every hour or so, do a copy, then press Ctrl+Shift+V to popup the multi-clipboard menu. Make sure the item you just copied is the first item in the list.
If it is not, then you have reproduced that OnClipboardChange is no longer being called. To confirm even further, create a file named c:\temp\onclipshow.txt. Do another copy, and you shouldn't see a message box. Reload the multi-clipboard script. On an initial load, OnClipboardChange always gets called. Because the text file is present, you will see a messagebox popup. Copy another item, and the message box will show again. This proves OnClipboardChange starts working again after reloading the script.
| Code: |
; Used in DoNothingLbl to indicate if a menu choice was selected vs
; the menu being cancelled with Escape
MenuItemWasSelected =
; Set the following to 1 before changing the clipboard to
; make multi-clipboard ignore the change. This is useful when
; this script is include inside another script that messes
; with the clipboard.
IgnoreClipboardChange =
; Indicate the number of clipboards and the variables where
; the data is held
MaxMultiClipboards = 5
MultiClipboard1 =
MultiClipboard2 =
MultiClipboard3 =
MultiClipboard4 =
MultiClipboard5 =
MultiClipboardAll1 =
MultiClipboardAll2 =
MultiClipboardAll3 =
MultiClipboardAll4 =
MultiClipboardAll5 =
; Show multiclipboard
^+v::
MultiClipboardShow()
return
; For testing, write the clipboard contents to files
#F9::
MultiClipboardPersist()
return
; ===========================================================================
; Write all multi-clipboard items to files.
; ===========================================================================
MultiClipboardPersist()
{
global
local OutputDir, ClipTemp
OutputDir = c:\temp
Loop %MaxMultiClipboards%
{
; Write plain text version
ClipTemp := MultiClipboard%A_Index%
FileDelete, %OutputDir%\MultiClip%A_Index%.clip
FileAppend, %ClipTemp%, %OutputDir%\MultiClip%A_Index%.clip
; Write binary version
ClipTemp := MultiClipboardAll%A_Index%
FileDelete, %OutputDir%\MultiClipAll%A_Index%.clip
FileAppend, %ClipTemp%, %OutputDir%\MultiClipAll%A_Index%.clip
}
}
; ===========================================================================
; Shows the multi-clipboard items to the user.
; ===========================================================================
MultiClipboardShow()
{
global
local Idx, MultiClipboardShort, MultiClipboardPlain, RawPasteKeyState
; === Build and show the menu of clipbard items ===
Idx = 1
Loop
{
if MultiClipboardAll%Idx% =
MultiClipboardShort = (empty)
else if MultiClipboard%Idx% =
MultiClipboardShort = (non-text data)
else
{
; Remove all non-text characters
MultiClipboardPlain := RegExReplace(MultiClipboard%Idx%, "[\x00-\x1f\x7f-\xff]")
StringLeft, MultiClipboardShort, MultiClipboardPlain, 80
}
; Add the clipboard item to the menu
Menu, MyMenu, Add, &%Idx%: %MultiClipboardShort%, DoNothingLbl
Idx++
if (Idx > MaxMultiClipboards)
break
}
MenuItemWasSelected =
Menu, MyMenu, Show, %A_CaretX%, %A_CaretY%
; === Process the selected menu item ===
if MenuItemWasSelected
{
GetKeyState, RawPasteKeyState, Space
IgnoreClipboardChange = 1
Clipboard = ; Clear the clipboard
IgnoreClipboardChange = 1
; If the data is text, then paste it as plain text.
; If non-text or the spacebar is being held down, then paste the raw data
if (MultiClipboard%A_ThisMenuItemPos% = "" or RawPasteKeyState = "D")
; Paste raw data
Clipboard := MultiClipboardAll%A_ThisMenuItemPos%
else
; Paste text data
Clipboard := MultiClipboard%A_ThisMenuItemPos%
ClipWait, 5, 1
; Console Window, aka DOS Window or Cmd.exe
IfWinActive, ahk_class ConsoleWindowClass
SendInput, !{Space}ep ; Paste text
else
SendInput, {Control down}v{Control up}
}
Menu, MyMenu, DeleteAll
}
; ===========================================================================
; Adds the current clipboard item to multi-clipboard.
; ===========================================================================
MultiClipboardAdd()
{
; Assume all vars are global vars except ones defined 'local'
global
local Idx, IdxPrev, MultiClipboardAllCurr, MultiClipboardAllTemp
; ClipboardAll always shows empty unless copied into a temp variable
MultiClipboardAllCurr := ClipboardAll
; If the item is already in multi-clipboard, then leave
Loop %MaxMultiClipboards%
{
MultiClipboardAllTemp := MultiClipboardAll%A_Index%
if MultiClipboardAllCurr = %MultiClipboardAllTemp%
{
return
}
}
; Move all items up one position, and put the new item a position 1
Idx := MaxMultiClipboards
Loop
{
IdxPrev := Idx - 1
MultiClipboard%Idx% := MultiClipboard%IdxPrev%
MultiClipboardAll%Idx% := MultiClipboardAll%IdxPrev%
if IdxPrev < 2
break
Idx := IdxPrev
}
MultiClipboard1 := Clipboard
MultiClipboardAll1 := ClipboardAll
}
DoNothingLbl:
MenuItemWasSelected = 1
return
; ===========================================================================
; This label is launched whenever any application (even this script) changes
; the clipboard contents.
; ===========================================================================
OnClipboardChange:
Critical
if FileExist("c:\temp\onclipshow.txt")
msgbox, In OnClipboardChange label. A_EventInfo=%A_EventInfo% IgnoreClipboardChange=%IgnoreClipboardChange%
; Leave if the clipboard is empty or we are told to ignore the change
if (A_EventInfo == 0 or IgnoreClipboardChange)
{
IgnoreClipboardChange =
return
}
MultiClipboardAdd()
return
|
|
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4016 Location: Pittsburgh
|
Posted: Wed Nov 07, 2007 5:54 pm Post subject: |
|
|
The script above does not prove that OnClipboardChange is no longer being called, if the last content of the clipboard is not shown on the top of the Ctrl-Shift-V list. From the MultiClipboardAdd() function you return “if MultiClipboardAllCurr = %MultiClipboardAllTemp%”. These are binary variables, compared as strings. The comparison terminates at the first NUL’s, which can result in equality for very different clipboards.
You could use dll calls for binary comparisons, but I am not sure, if it was necessary, at all.
If you really want to know if OnClipboardChange is no longer called, add these two lines | Code: | OCC++
Traytip,,%OCC% | to the top of the OnClipboardChange subroutine. After you copy something to the clipboard, you should see its sequence number shown at the tray. If you don’t, you got a proof for lost OnClipboardChange events. |
|
| Back to top |
|
 |
deanhill1971
Joined: 30 Sep 2005 Posts: 52 Location: Fort Wayne, IN
|
Posted: Wed Nov 07, 2007 7:50 pm Post subject: |
|
|
Laszlo: Good point about my binary comparison. If I ever get OnClipboardChange to work the way I need, I'll research a long-term solution.
Your Traytip code is a good addition. It serves a similar purpose to the code which checks for the existence of the "onclipshow.txt" file. |
|
| Back to top |
|
 |
deanhill1971
Joined: 30 Sep 2005 Posts: 52 Location: Fort Wayne, IN
|
Posted: Wed Nov 07, 2007 8:27 pm Post subject: |
|
|
Laszlo: Actually, the AHK help file says the following about comparing binary ClipboardAll variables. My interpretation is that my comparison will work fine. Your thoughts?
| Quote: | Variables to which ClipboardAll has been assigned can be compared to each other (but not directly to ClipboardAll) by means of the <> and = operators. In the following example, the length of each variable is checked first. If that is not enough to make the determination, the contents are compared to break the tie:
if ClipSaved1 <> %ClipSaved2% ; This must be an old-style IF statement, not an expression.
MsgBox The two saved clipboards are different. |
|
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4016 Location: Pittsburgh
|
Posted: Wed Nov 07, 2007 9:08 pm Post subject: |
|
|
You are right, according to the Help your script should work. But the help is not correct.
I did an experiment, with the following script: | Code: | ^#a::A := ClipBoardAll
^#b::B := ClipBoardAll
^#c::
If A = %B%
MsgBox EQUAL
Else
MsgBox DIFFERENT | In MS Word I selected a word (“Help”), pressed Ctrl-C, Ctrl-Win-A to copy the clipboard to the variable A. Then Ctrl-Win-B, and Ctrl-Win-C tells the saved ClipboardAll variables are the same, as they should be. (52790 bytes used of 52814 bytes allocated).
Now extend the selection one character longer (“Help ”). Ctrl-C and Ctrl-Win-B, then Ctrl-Win-C tells the saved ClipboardAll variables are different, as they should be. (B: 52794 bytes used of 52818 bytes allocated).
Next go back and select the original word again. Ctrl-C and Ctrl-Win-B, then Ctrl-Win-C tells the saved ClipboardAll variables are different, although they are the same. Only the reserved space is larger for B than it is for A. Even if we reset this space with VarSetCapacity(B,0) beforehand, (so it will be expanded to the same length as A), AHK still tells that A and B are different.
So, contrary to the Help, AHK cannot tell the equality of these binary variables. Or, they are internally different, although the exact same selection is copied to the ClipBoard. In any case, checking the equality of saved ClipboardAll’s is not trustworthy. |
|
| Back to top |
|
 |
deanhill1971
Joined: 30 Sep 2005 Posts: 52 Location: Fort Wayne, IN
|
Posted: Wed Nov 07, 2007 9:47 pm Post subject: |
|
|
I ran your test in Word, but I wrote the clips out to files then did a binary diff. Word creates two different binary clips even if you copy the exact same data twice in a row. Strange, but true.
Running the test in a Notepad yields two binary clips that are identical. Of course, this is a simplistic test since there is no formatting in Notepad.
So, I ran the test again using Internet Explorer. I highlighted the "Advanced Search" hyperlink on the Google home page and copied it twice. I did a diff of the two binary clips, and they were identical. Also, the AHK "=" operator finds them to be identical.
So, AHK seems to work exactly as the help file indicates. |
|
| Back to top |
|
 |
Laszlo
Joined: 14 Feb 2005 Posts: 4016 Location: Pittsburgh
|
Posted: Wed Nov 07, 2007 10:26 pm Post subject: |
|
|
Interesting! However, if the same selection might yield different clipboard data in some applications, checking for equality does not always make sense.
The real problem is with the opposite case, which is harder to test. Different clipboards might test to be equal. You could pop up the traytip if equality is detected. Then you can see if it is for real or not. An unexpected equality could look like a dropped OnClipBoard event. |
|
| Back to top |
|
 |
Guest
|
Posted: Wed Feb 27, 2008 4:08 am Post subject: |
|
|
Has anyone figured out the cause of this bug or a workaround yet?
One thing I've discovered when using onClipboardChange specifically with some Citrix Metaframe applications is that the clipboard in citrix and in Windows (which should normally be identical) become desynchronized whenever onClipboard change is called.
I imagine Citrix has some bidirectional clipboard functionality where a change in the citrix apps clipboard resulted in a change in the windows clipboard, and vice versa. Any script I use with onClipboardChange seemed to break that functionality in one direction.
Copying something in windows seemed to have no effect on what was pasted in the the Citrix app; it is only able to paste data that was copied within it's client. Strangely though, something copied within the citrix application still pasted seamlessly in Windows. |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|