Features:
* preview of captured clips
* delete captured clips
* random clip selection
* keyboard and mouse interface
Usage:
* show CH (Control+Insert or Control+v)
* show/hide CH from Tray (left-button click)
* hide CH (Escape)
* delete selected clip (context menu via right-button click)
* paste clip (Enter or left-button double-click)
* select clip (left-button click)
* browse clips (mouse or arrow up/down, home, end)
Note: Enter will paste a single clip and hide CH. However, left-button double-click will only paste a single clip.
#SingleInstance, Ignore DetectHiddenWindows, On ; -- ignore existing clipboard content -- ignore_clipboard_change := true ; -- construct TRAY menu -- Menu, TRAY, Icon, %A_WinDir%\system32\clipbrd.exe Menu, TRAY, NoStandard Menu, TRAY, Add, Show Clipboard Helper, TRAY$ShowClipboardHelper Menu, TRAY, Add Menu, TRAY, Add, Exit Program, TRAY$ExitProgram ; -- construct main window -- Gui, +AlwaysOnTop -MinimizeBox -Resize Gui, Add, Text, x5 y5, Target: Gui, Add, Edit, x45 y5 w360 h20 ReadOnly vTarget Gui, Add, ListBox, x5 y35 w400 h200 vClipboardList Gui, Add, Edit, x5 y240 w400 h100 HScroll ReadOnly vTextPreview Gui, Show, w410 h345 Hide, Clipboard Helper WinGet, hw_ClipboardHelper, ID, Clipboard Helper ahk_class AutoHotkeyGUI ; -- activate message handlers -- WM_KEYUP = 0x101 OnMessage( WM_KEYUP, "HandleMessage" ) WM_LBUTTONUP = 0x202 OnMessage( WM_LBUTTONUP, "HandleMessage" ) WM_LBUTTONDBLCLK = 0x203 OnMessage( WM_LBUTTONDBLCLK, "HandleMessage" ) WM_RBUTTONUP = 0x0205 OnMessage( WM_RBUTTONUP, "HandleMessage" ) AHK_NOTIFYICON = 0x404 OnMessage( AHK_NOTIFYICON, "HandleMessage" ) return HandleMessage( p_w, p_l, p_m, p_hw ) { global WM_KEYUP, WM_LBUTTONUP, WM_LBUTTONDBLCLK, WM_RBUTTONUP, AHK_NOTIFYICON global timer_PasteItem@m, timer_ShowMenu@l, timer_ShowMenu@hw global hw_ClipboardHelper, ClipboardList?menu@item if ( p_m = AHK_NOTIFYICON and p_l = WM_LBUTTONUP ) { SetTimer, timer_ToggleClipboardHelper, 10 } else if ( A_GuiControl = "ClipboardList" ) { if ( p_m = WM_KEYUP ) { if ( p_w = 13 ) { timer_PasteItem@m := p_m SetTimer, timer_PasteItem, 10 } else if ( p_w = 0x26 or p_w = 0x28 or p_w = 0x23 or p_w = 0x24 ) { SetTimer, timer_ShowPreview, 10 } else if ( p_w = 0x2E ) { SetTimer, timer_DeleteItem, 10 } } else if ( p_m = WM_LBUTTONUP ) { SetTimer, timer_ShowPreview, 10 } else if ( p_m = WM_LBUTTONDBLCLK ) { timer_PasteItem@m := p_m SetTimer, timer_PasteItem, 10 } else if ( p_m = WM_RBUTTONUP ) { timer_ShowMenu@l := p_l SetTimer, timer_ShowMenu, 10 } } return timer_ToggleClipboardHelper: SetTimer, timer_ToggleClipboardHelper, off if ( DllCall( "IsWindowVisible", "uint", hw_ClipboardHelper ) ) Gosub, HideClipboardHelper else Gosub, ShowClipboardHelper return timer_PasteItem: SetTimer, timer_PasteItem, off ;LB_GETCOUNT SendMessage, 0x18B, 0, 0, ListBox1, ahk_id %hw_ClipboardHelper% if ( ErrorLevel = 0 ) return GuiControlGet, item,, ClipboardList if ( timer_PasteItem@m = WM_KEYUP ) Gosub, HideClipboardHelper PasteItem( item ) return timer_ShowPreview: SetTimer, timer_ShowPreview, off GuiControlGet, item,, ClipboardList ShowPreview( item ) return timer_ShowMenu: SetTimer, timer_ShowMenu, off ;LB_ITEMFROMPOINT SendMessage, 0x1A9, 0, timer_ShowMenu@l, ListBox1, ahk_id %hw_ClipboardHelper% if ( ErrorLevel = 0x1FFFF or ( ErrorLevel & 0x10000 ) ) return ClipboardList?menu@item := ErrorLevel+1 GuiControl, Choose, ClipboardList, %ClipboardList?menu@item% Gosub, timer_ShowPreview if ClipboardList?menu= { Menu, ClipboardList?menu, Add, Delete, ClipboardList?menu$delete } Menu, ClipboardList?menu, Show return timer_DeleteItem: SetTimer, timer_DeleteItem, off ;LB_GETCURSEL SendMessage, 0x188, 0, 0, ListBox1, ahk_id %hw_ClipboardHelper% DeleteItem( ErrorLevel ) return } TRAY$ExitProgram: ExitApp TRAY$ShowClipboardHelper: Gosub, ShowClipboardHelper return ClipboardList?menu$delete: DeleteItem( ClipboardList?menu@item-1 ) return GuiEscape: HideClipboardHelper: SetTimer, timer_MonitorTarget, off Gui, Hide return ~LButton:: SetTimer, timer_MonitorTarget, off return ~LButton up:: SetTimer, timer_MonitorTarget, on return ^v:: +Insert:: ShowClipboardHelper: WinGet, hw_active, ID, A ControlGetFocus, control_active, A UpdateTarget( hw_active, control_active ) Gui, Show ControlFocus, ListBox1, ahk_id %hw_ClipboardHelper% SetTimer, timer_MonitorTarget, 200 return timer_MonitorTarget: WinGet, hw_active, ID, A ControlGetFocus, control_active, A UpdateTarget( hw_active, control_active ) return OnClipboardChange: if ( ignore_clipboard_change ) ignore_clipboard_change := false else if ( A_EventInfo = 1 ) AddItem( Clipboard ) return AddItem( p_item ) { global hw_ClipboardHelper fill := Chr( 1 ) StringReplace, p_item, p_item, |, %fill%, All ;LB_GETCOUNT SendMessage, 0x18B, 0, 0, ListBox1, ahk_id %hw_ClipboardHelper% items := ErrorLevel loop, %items% { ;LB_GETTEXTLEN SendMessage, 0x18A, A_Index-1, 0, ListBox1, ahk_id %hw_ClipboardHelper% len := ErrorLevel VarSetCapacity( text, len, 1 ) ;LB_GETTEXT SendMessage, 0x189, A_Index-1, &text, ListBox1, ahk_id %hw_ClipboardHelper% if ( p_item = text ) { GuiControl, Choose, ClipboardList, %A_Index% ShowPreview( p_item ) p_item= break } } if p_item!= { GuiControl,, ClipboardList, %p_item% items++ GuiControl, Choose, ClipboardList, %items% ShowPreview( p_item ) MsgBox, 4160, Clipboard Helper, Capture complete!, 0.4 } } DeleteItem( p_item ) { global hw_ClipboardHelper ;LB_DELETESTRING SendMessage, 0x182, p_item, 0, ListBox1, ahk_id %hw_ClipboardHelper% p_item++ if ( p_item > 1 ) p_item-- GuiControl, Choose, ClipboardList, %p_item% GuiControlGet, item,, ClipboardList ShowPreview( item ) } PasteItem( p_item ) { global target?hw, target?control, ignore_clipboard_change fill := Chr( 1 ) StringReplace, p_item, p_item, %fill%, |, All ignore_clipboard_change := true Clipboard := p_item ControlFocus, %target?control%, ahk_id %target?hw% Send, +{Insert} } ShowPreview( p_item ) { fill := Chr( 1 ) StringReplace, p_item, p_item, %fill%, |, All GuiControl,, TextPreview, %p_item% } UpdateTarget( p_hw, p_control ) { global hw_ClipboardHelper, target?hw, target?control if ( p_hw = hw_ClipboardHelper ) return target?hw := p_hw target?control := p_control WinGetTitle, title, ahk_id %target?hw% GuiControl,, Target, %title% }