sourcecode
Chady
<code>
#!perl
# copyright (c) Chady Kassouf 2004
# This program is free software, it is distributed under
# the sames terms as Perl itself.
use strict;
use threads;
use threads::shared;
use Win32::Clipboard;
use Win32::GUI;
my @board : shared;
push @board, '--empty--' for 0 .. 4;
my @boxes;
my $CLIP = Win32::Clipboard();
my $thread = threads->create("monitor");
my $main = Win32::GUI::Window->new(
-name => 'main',
-text => 'Win32 Multiple Clipboard',
-width => 200,
-height => 150
);
my $icon = Win32::GUI::Icon->new('Note.ico');
my $tray = $main->AddNotifyIcon(
-name => 'tray',
-icon => $icon,
-tip => 'Win32 Multiple Clipboard'
);
foreach (0 .. 4) {
my $label = $board[$_];
$label =~ s/^(.{10})(.*)$/$1... /;
$boxes[$_] = $main->AddRadioButton(
-name => "board$_",
-text => $label,
-pos => [ 10, 10 + 20 * $_ ],
);
$boxes[$_]->{-width} = 150;
}
$main->Show();
set_clip(1);
Win32::GUI::Dialog();
##
sub set_clip {
my $which = shift;
$boxes[$_]->Checked(0) for 0..4;
$boxes[$_]->{-text} = $board[$_] for 0..4;
if ($which) {
$which--;
my $d = $board[$which];
$CLIP->Set($d);
$main->Disable();
$main->Hide();
}
}
# there must be a better way for this.
sub board0_Click {set_clip(1);1;}
sub board1_Click {set_clip(2);1;}
sub board2_Click {set_clip(3);1;}
sub board3_Click {set_clip(4);1;}
sub board4_Click {set_clip(5);1;}
sub tray_Click {
# move the window near the task bar
my $desk = Win32::GUI::GetDesktopWindow();
my $dw = Win32::GUI::Width($desk);
my $dh = Win32::GUI::Height($desk);
my $x = $dw - $main->Width();
# the taskbar is 27 pixels on Xp (no Luna)
my $y = $dh - $main->Height() - 27;
$main->Move($x, $y);
$main->Enable();
$main->Show();
set_clip(0);
1;
}
# this runs in another thread because it blo
sub monitor {
{
print "[MONITOR]: Waiting for clipboard.\n";
$CLIP->WaitForChange();
print "[MONITOR]: Clipboard changed.\n";
my $data = $CLIP->Get();
last if $data eq '___EXIT___';
# skip empty and same requests
redo if ($data eq $board[0] || $data eq '--empty--');
unshift @board, $data;
# splice @board, 5;
delete $board[$_] for 5 .. $#board + 1;
redo;
}
}
sub main_Minimize {
$main->Disable();
$main->Hide();
1;
}
sub main_Terminate {
$CLIP->Set('___EXIT___');
$thread->join();
$CLIP->Set($board[0]); # make sure we can start next time.
-1;
}
</code>
<p>I love the idea of Klipper in KDE, and I always lack that functionality in Windows; you copy some text, move around to another application, select a new text to replace and accidentally hit Ctrl+C instead of Ctrl+V. So your old text is gone, and you have to find it back and copy again.</p>
<p>This is an attempt to make a small tray application to keep your latest 5 clipboard copies and let you choose one of them.</p>
<h3>Requirements:</h3>
<ul>
<li>required perl 5.8.0 or higher.</li>
<li>[cpan://Win32::GUI].</li>
<li>[cpan://Win32::Clipboard] blocks, so I had to put this in [cpan://threads].</li>
<li>We need to share data between threads, thus [cpan://threads::shared].</li>
<li><strong>Problem</strong>: we cannot splice the array, so I'm deleting the array elements manually.</li>
</ul>
<h3>Bugs:</h3>
<ul>
<li>uses a lot of memory. Not recommended if you copy around huge amounts of data.</li>
<li>Can only handle text.</li>
</ul>
<p>I'm using ActivPerl 5.8.3 and run this with ``wperl clip.pl'' from a startup script. You will also need an icon of some sort.</p>
<p>Please post you comments, suggestions.</p>
<p><strong>Update:</strong> [http://chady.perlmonk.org/clip.png|Screenshot]</p>
Win32 Stuff
[Chady]