Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Deluxe Clipboard


  • Please log in to reply
4 replies to this topic
Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
I needed a tool to help rearranging brainstorming texts into structured documents. Named clipboards were of a great help, with instructive names like Introduction, Actions, Function, References, etc. To facilitate these I wrote the following Deluxe Clipboard AHK script. Currently it only works with text, because of the limitations of ClipBoardAll (interference with MS Word and no Append possible). With the changes indicated (and accepting unwanted Word bookmarks) the Copy, Cut and Paste functions work with any selection and clipboard content.

I tried to write the shortest and easiest to maintain script. Any suggestions for improvements?
; Deluxe Clipboard
; AutoHotkey Version: 1.0.30+
; Language:  English
; Platform:  Win2000/XP
; Author:    Laszlo Hars <www.Hars.US>
;
; Script Function:
;       Provides unlimited number of private, named clipboards to
;          Copy, Cut, Paste, Append or CutAppend of selected text
;       Private clipboard names can consist of numbers, letters, # _ @ $ ? [ ]
;          OK:  01, Greetings, gut_und_schlecht, $5
;          BAD: 1.1, You&Me, Mon Amis
;          The already used names are listed in a sorted drop down list with
;              incremental search (beginning of a name and Up or Down arrow)
;          The last-used name is pre-selected, Enter accepts
;       Repeated hotkeys provide their original functions (auto exit)
;       Esc, Click on Cancel or [x]: escapes out
;       Enter, Alt-underlined, Click: performs action with typed/selected name
;
; Limitations:
;       ClipBoardAll was not used, because
;          it interferes with MS Word (adds bookmarks)
;          non-text clipboards cannot be merged (appended)
;       Removing the Append and CutAppend functions and
;       using ClipBoardAll at the indicated places
;       makes Copy, Cut and Paste of general clipboards possible
;
; Version 1.0: 2005.03.05 Initial creation

names =                         ; | after each name, || after last used (default)

$^!c::                          ; Ctrl-Alt-C hotkey = copy to private clipboard
HKey = c
Actn = &Copy
GoTo WINDOW                     ; return from there

$^!v::                          ; Ctrl-Alt-V hotkey = paste from private clipboard
HKey = v
Actn = &Paste
GoTo WINDOW

$^!x::                          ; Ctrl-Alt-X hotkey = cut to private clipboard
HKey = x
Actn = &Cut
GoTo WINDOW

$^!a::                          ; Ctrl-Alt-A hotkey = append to private clipboard
HKey = a
Actn = &Append
GoTo WINDOW

$^!y::                          ; Ctrl-Alt-Y hotkey = cut+append to private clipboard
HKey = y
Actn = Cut&Append
GoTo WINDOW

WINDOW:
WinGetActiveTitle WinTitle      ; where was the hotkey pressed?
if WinTitle = Deluxe Clipboard
{                               ; hotkey pressed the second time
   Gui Destroy
   WinActivate ahk_id %CallerID%
   Send ^!%HKey%                ; if you change: MATCH hotkey modifiers here and at GUI Text!
   return
}
WinGet CallerID, ID, A          ; save caller's ID at first press of HotKey
Gui Font, s10, MS Sans Serif    ; ADJUST BELOW FOR YOUR SCREEN RESOLUTION
Gui Add, ComboBox,x026 y064 w220 h20 r5 Sort vName, %names%     ; 1st Gui Add = active
Gui Add, Button,  x146 y104 w100 h30, Cancel
Gui Add, Button,  x026 y104 w100 h30  Default, %Actn%
Gui Add, Text,    x028 y014 w220 h40, For Ctrl-Alt-%HKey% repeat, or`nName your private clipboard
Gui Show, h163 w271 Center, Deluxe Clipboard
return

GuiClose:
GuiEscape:
ButtonCancel:
Gui Destroy
return

ButtonCopy:
Gosub GoBack
ClipBoard0 = %ClipBoard%        ; save original clipboard (ClipBoardAll)
Send ^c                         ; copy data to clipboard
CB_%Name%  = %ClipBoard%        ; transfer new clipboard to variable (ClipBoardAll)
ClipBoard  = %ClipBoard0%       ; restore original clipboard
return

ButtonPaste:
Gosub GoBack
ClipBoard0 = %ClipBoard%        ; save original clipboard (ClipBoardAll)
Clipboard := CB_%Name%          ; set clipboard from variable
Send ^v                         ; paste data to window
ClipBoard  = %ClipBoard0%       ; restore original clipboard
return

ButtonCut:
Gosub GoBack
ClipBoard0 = %ClipBoard%        ; save original clipboard (ClipBoardAll)
Send ^x                         ; cut data to clipboard
CB_%Name%  = %ClipBoard%        ; transfer new clipboard to variable (ClipBoardAll)
ClipBoard  = %ClipBoard0%       ; restore original clipboard
return

ButtonAppend:                   ; only works with *text* clipboards
Gosub GoBack
ClipBoard0 = %ClipBoard%        ; save original clipboard (ClipBoardAll)
Send ^c                         ; copy new data to clipboard
cb := CB_%Name%                 ; get private clipboard
CB_%Name% = %cb%%ClipBoard%     ; append new clipboard to variable
ClipBoard = %ClipBoard0%        ; restore original clipboard
return

ButtonCutAppend:                ; only works with *text* clipboards
Gosub GoBack
ClipBoard0= %ClipBoard%         ; save original clipboard (ClipBoardAll)
Send ^x                         ; cut data to clipboard
cb := CB_%Name%                 ; get private clipboard
CB_%Name% = %cb%%ClipBoard%     ; append new clipboard to variable
ClipBoard = %ClipBoard0%        ; restore original clipboard
return

GoBack:
Gui Submit                      ; assign gui variables
Gui Destroy                     ; GUI's done its task
WinActivate ahk_id %CallerID%   ; get back to caller window
StringReplace names,names,||,|  ; remove last-used marker
StringGetPos Pos, names,%Name%| ; was this clipboard name used?
if Pos < 0                      ; new name appended
   names = %names%%Name%||
else                            ; old name marked as last used
   StringReplace names,names,%Name%|,%Name%||
return

Here is the latest version:
; Deluxe Clipboard
; AutoHotkey Version: 1.0.35+
; Language:  English
; Platform:  Win2000/XP
; Author:    Laszlo Hars <www.Hars.US>
;
; Script Function:
;     Provides unlimited number of private, named clipboards
;     Hotkeys = CapsLock & …
;        c: Copy, x: Cut, v: Paste, a: Append and y: CutAppend any selections
;     In applications using ^c, ^x, ^v for copy, cut, paste to/from the Windows clipboard
;     Private clipboard names consist of any ANSI characters except "|"
;        The already used names are shown in a sorted drop down list with
;            incremental search (beginning of a name and Up or Down arrow)
;        The last-used name is pre-selected, Enter accepts
;     New hotkey replaces function
;
; Version history:
;     1.0: 2005.03.05 Initial creation
;     1.1: 2005.03.07 Error check added for clipboard names
;                     Legible version of A_ThisHotKey in Gui 3:text
;                     2nd hotkey while 1st is active replaces function
;                     Repeated hotkey is detected from saved current hotkey
;     1.2: 2005.03.12 Append: by arrays of private clipboards, $ separated
;                     Paste: each entry of the array one-by-one
;                     ClipBoardAll is used
;     1.3: 2005.05.01 ClipWait up to 2s added for handling large clipboards
;                     Sleep between setup the clipboard and pasting it
;                     ClipBoardAll is used at Append and CutAppend
;     2.0: 2005.10.03 CapsLock & … hotkeys
;                     Use functions, Simplified code
;                     ClipBoard Name -> hex, avoiding naming restrictions, except "|"

#SingleInstance Force
AutoTrim Off
names =                          ; | after each name, || after last used (default)

CapsLock & c::WINDOW("&Copy")    ; COPY to private clipboard
CapsLock & v::WINDOW("&Paste")   ; PASTE from private clipboard
CapsLock & x::WINDOW("&Cut")     ; CUT to private clipboard
CapsLock & a::WINDOW("&Append")  ; APPEND to private clipboard
CapsLock & y::WINDOW("Cut&Append") ; CUT+APPEND to private clipboard

WINDOW(Actn)
{
   Global
   Gui 3:Destroy                 ; needed for 2nd hotkey while 1st is active
   WinGet CallerID, ID, A        ; save caller's ID as the window to return to

   Gui 3:Font, s10, Arial        ; ADJUST BELOW FOR YOUR SCREEN RESOLUTION
   Gui 3:Add, Text,    x028 y14 w220 h40, Private clipboard name:
   Gui 3:Add, ComboBox,x026 y44 w220 h20 r5 Sort vName, %names%
   Gui 3:Add, Button,  x146 y84 w100 h30, Cancel
   Gui 3:Add, Button,  x026 y84 w100 h30  Default, %Actn%
   Gui 3:Show, h133 w271 Center, Deluxe Clipboard
}

3GuiClose:
3GuiEscape:
3ButtonCancel:
   Gui 3:Destroy
Return

3ButtonCopy:
   Gosub GoBack
   IfEqual NameError,1, Return   ; Gui remains after wrong name
   Loop % %HexName%_0
      %HexName%_%A_Index% =      ; clear memory used by the array, if any
   %HexName%_0 = 1               ; chain length = 1
   ClipBoard0  = %ClipBoardAll%  ; save original clipboard
   ClipBoard   =
   Send ^c                       ; copy new data to clipboard
   ClipWait 2, 1                 ; wait up to 2 seconds or until clipboard contains data
   %HexName%_1 = %ClipBoardAll%  ; transfer new clipboard to array
   ClipBoard   = %ClipBoard0%    ; restore original clipboard
Return

3ButtonPaste:
   Gosub GoBack
   IfEqual NameError,1, Return   ; Gui remains after wrong name
   ClipBoard0 = %ClipBoardAll%   ; save original clipboard (ClipBoardAll)
   Loop % %HexName%_0
   {                             ; load clipboard from array
     Clipboard =
     Clipboard := %HexName%_%A_Index%
     ClipWait 3                  ; wait for new ClipBoard content
     Send ^v                     ; paste data to window
   }
   ClipBoard  = %ClipBoard0%     ; restore original clipboard
return

3ButtonCut:
   Gosub GoBack
   IfEqual NameError,1, Return   ; Gui remains after wrong name
   Loop % %HexName%_0
     %HexName%_%A_Index% =       ; clear memory used by the array, if any
   %HexName%_0 = 1               ; chain length = 1
   ClipBoard0  = %ClipBoardAll%  ; save original clipboard
   ClipBoard   =
   Send ^x                       ; copy new data to clipboard
   ClipWait 2, 1                 ; wait up to 2 seconds or until clipboard contains data
   %HexName%_1 = %ClipBoardAll%  ; transfer new clipboard to array
   ClipBoard   = %ClipBoard0%    ; restore original clipboard
Return

3ButtonAppend:                   ; Problems with MS Office
   Gosub GoBack
   IfEqual NameError,1, Return   ; Gui remains after wrong name
   ClipBoard0 = %ClipBoardAll%   ; save original clipboard
   ClipBoard  =
   Send ^c                       ; copy new data to clipboard
   ClipWait 2, 1                 ; wait up to 2 seconds or until clipboard contains data
   %HexName%_0++                 ; increment number of clipboards in the chain
   idx := %HexName%_0
   %HexName%_%idx%=%ClipBoardAll% ; store new clipboard at the next array location
   ClipBoard = %ClipBoard0%      ; restore original clipboard
Return

3ButtonCutAppend:                ; Problems with MS Office
   Gosub GoBack
   IfEqual NameError,1, Return   ; Gui remains after wrong name
   ClipBoard0= %ClipBoardAll%    ; save original clipboard
   ClipBoard =
   Send ^x                       ; copy new data to clipboard
   ClipWait 2, 1                 ; wait up to 2 seconds or until clipboard contains data
   %HexName%_0++                 ; increment number of clipboards in the chain, init = 1
   idx := %HexName%_0
   %HexName%_%idx%= %ClipBoardAll% ; store new clipboard at the next array location
   ClipBoard = %ClipBoard0%      ; restore original clipboard
Return

GoBack:
   Gui 3:Submit, NoHide          ; assign Gui variables
   NameError =
   IfEqual Name,, SetEnv NameError,1
   If Name contains |
      NameError = 1
   IfEqual NameError, 1, {
      WinGet GuiID, ID, A        ; save Gui ID as the window to return to
      MsgBox,,,Please provide a valid`nClipboard Name!,2
      WinActivate ahk_id %GuiID%   ; get back to GUI
      return
   }
   Gui 3:Destroy                 ; GUI's done its task
   WinActivate ahk_id %CallerID% ; get back to caller window
   StringReplace names,names,||,|  ; remove marker of last-used name
   StringGetPos Pos, names,%Name%| ; was this clipboard name used?
   if Pos < 0                    ; new name appended
      names = %names%%Name%||
   else                          ; old name marked as last used
      StringReplace names,names,%Name%|,%Name%||
   HexName := String2Hex(Name)
return

String2Hex(x)                    ; Convert a string to hex digits
{
   format = %A_FormatInteger%
   SetFormat Integer, H
   hex = X
   Loop Parse, x
   {
      y := ASC(A_LoopField)      ; 2 digit ASCII code of chars of x, 15 < y < 256
      StringTrimLeft y, y, 2     ; Remove leading 0x
      hex = %hex%%y%
   }
   SetFormat Integer, %format%
   Return hex
}


Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
It looks useful; thanks for sharing it.

Concerning the problem with ClipboardAll, I'd like to try to fix that, even though I'm a little dismayed that the fix might exist mostly for MS Word and not help with much else.

This is the ClipboardCore idea I described in that other topic.

RG
  • Members
  • 17 posts
  • Last active: Oct 26 2005 01:45 PM
  • Joined: 09 Feb 2005
Very nice work, Laszlo! :D
RG

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
Thanks! In the mean time I developed it further. The last version uses arrays to simulate append (store and paste each piece individually), and it works with any clipboard content, not only with text. However, MS Word behaves funny with saved clipboards, so I wait for the ClipBoardLimited Chris promised, to see if it gives an improvement. I will post the next version whenever AHK has this new feature.

tinypig
  • Members
  • 16 posts
  • Last active: Aug 29 2014 12:36 AM
  • Joined: 12 Mar 2005
I've had your code in my "main" script for a while now and it helped me to complete a task today. Thanks!