Good day!
I recently found a 2003 wxPerl script for taking screen shots on Perl
Monks. After restructuring and cleaning up several bugs, I have it working.
However, the results are inconsistent. The entire screen is not captured
every time it's run. I know that events and "main-line code" run
asynchronously. What am I missing? Is there a way to select a specific
window among many to capture. I had to force the example window to the top
the get it captured. Otherwise the lower level windows gets captured. Code
listed below...
Thanks, James
#! /usr/bin/perl
#
# Capture Screen to a file. Written in wxPerl. Tested on Citrus Perl 5.16
and wxWidgets 2.8.x.
#
# This is a hard coded example that needs to be generalized into
a package.
#
# There seems to be a race condition between getting the sample
written to the
# screen and capturing the screen to the output file. Sometimes
it captures an
# incomplete screen. The sample screen does not paint smoothly.
It paints in two segments. Jerky.
# It makes a difference where the Update and TakeScreenShot calls
# are placed(see comments below). Why????
#
# Reference: GetScreenShot C++ code page 139 of "The wxBook" -
# Cross-Platform GUI Programming with wxWidgets -
# Smart, Hock, and Csomor
#
# Original author: "PodMaster" from Perl Monks-2003 (no idea of real
identity-not active for 6+ years)
#
# Modified by: James M. Lynes. Jr.
# Modified Date: October 17, 2012
#
#
use strict;
use warnings;
use lib '/home/pete/CitrusPerl/perl/vendor/lib/GD/Graph';
#where colour.pm is found in Citrus Perl distro
use Wx qw( :everything );
use colour qw( :everything );
use Wx::Event qw( EVT_PAINT );
#
# Main Application
#
my $app = Wx::SimpleApp->new;
my $frame = Wx::Frame->new(undef, -1, "Screen Capture", wxDefaultPosition,
wxDefaultSize , wxDEFAULT_FRAME_STYLE | wxMAXIMIZE | wxSTAY_ON_TOP);
EVT_PAINT( $frame, \&onPaint);
our $file = text_entry_dialog($frame); # get the output filename
$frame->Show;
#$frame->Update; # doesn't work to have
these calls in main loop????? why???
#TakeScreenshot($frame, $file); # ditto - they must be in
onPaint sub???
$app->MainLoop;
#
# Copy the screen to the output file-similar to wxBook pg 139 example.
#
sub TakeScreenshot {
my($self, $cfile ) = @_;
my $screen = Wx::ScreenDC->new();
my( $x, $y) = $screen->GetSizeWH();
my $bitmap = Wx::Bitmap->new($x,$y,-1);
my $memory = Wx::MemoryDC->new();
$memory->SelectObject( $bitmap );
$memory->Blit(0,0,$x,$y, $screen, 0, 0); #
copy the screen to the bitmap
$bitmap->SaveFile( $cfile , wxBITMAP_TYPE_BMP ) ; # copy the
bitmap to the output file
}
#
# Ask for the output filename
#
sub text_entry_dialog {
my( $self ) = @_;
my $dialog = Wx::TextEntryDialog->new
( $self, "Enter the Screen Capture output filename\n(Cancel will use
the default filename shown below)\n",
"Screen Capture File Entry",
"capture.bmp", wxOK | wxCANCEL );
my $textvalue = "capture.bmp";
if( $dialog->ShowModal == wxID_OK ) {
$textvalue = $dialog->GetValue;
}
$dialog->Destroy;
return $textvalue;
}
#
# Generate the sample graphic screen to capture
#
sub onPaint{
my($self,$event)=@_;
my $screen = Wx::PaintDC->new($self);
$screen->SetBackgroundMode( wxTRANSPARENT );
$screen->SetFont(Wx::Font->new( 12, wxFONTFAMILY_ROMAN, wxNORMAL,
wxBOLD));
for(0..17){
my $c = $_ * 15;
$screen->SetTextForeground( Wx::Colour->newRGB(0,0,$c));
$screen->DrawRotatedText("wxPerl",100 ,100 ,$c);
}
$screen->DrawRotatedText("wxPerl and PodMaster",000 ,400
,0);
$screen->DrawRotatedText("are messing up your screen",000
,450 ,0);
for(0..17){
my $c = $_ * 15;
$screen->SetTextForeground( Wx::Colour->newRGB(0,$c,0));
$screen->DrawRotatedText("wxPerl",200 ,200 ,$c);
}
$screen->DrawRotatedText("wxPerl and PodMaster",100 ,500
,0);
$screen->DrawRotatedText("are messing up your screen",100
,550 ,0);
for(0..17){
my $c = $_ * 15;
$screen->SetTextForeground( Wx::Colour->newRGB($c,0,0));
$screen->DrawRotatedText("wxPerl",300 ,300 ,$c);
}
$screen->DrawRotatedText("wxPerl and PodMaster",200 ,600
,0);
$screen->DrawRotatedText("are messing up your screen",200
,650 ,0);
$self->Update; # Force a screen repaint before capture
to make
# sure all items are written to the screen
TakeScreenshot($self, $file); # Capture the screen
}