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
}

Reply via email to