The not ready for prime time, but good enough for the weekend Clipboard Helper.
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.
Code:
#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%
}