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