http://www.perlmonks.org?node_id=158059

flofloh has asked for the wisdom of the Perl Monks concerning the following question:

Hi,
I'm searching for a way to capture the screen or a predetermined window to clipboard/file with a script. I didn't find *any* hints on that (google/cpan/perl monks).
I found one app (nonperl) which can be called from the command line and which is capable of capturing the screen/a window to a file - but I'd naturally prefer to have this task done by a perl script.
Anybody knows if/how this is possible?

Thanks for all help. Regards, Florian

Replies are listed 'Best First'.
Re: How to capture screen under Win32?
by jplindstrom (Monsignor) on Apr 10, 2002 at 19:12 UTC
    Win32::GUI to the rescue.
    1. Find out the DC (device context). You can use Win32::GUI or perhaps something like Win32::ActAcc. Note: If you can find out the hwind (window handler), you can get the DC.
    2. Grab it with Win32::GUI::DIBitmap (check out the newFromDC method).

    I don't think you can put images in the clipboard with Win32::Clipboard, only text.

    /J

      Actually you can put images into Win32::Clipboard but the gotcha is that if your screen depth is set to 32bit and NOT 24bit, the resulting BMP is not valid for most apps.

      I have some ugly code to fix 32bit BMPs to 24bit, let me know if you want to see it.

      as for the code to put a screenshot into the clipboard, see below

      use strict; use Win32::OLE; use Win32::Clipboard; use Win32::GuiTest qw(FindWindowLike GetWindowText SetForegroundWindow + SendKeys); my $ie; my $image; # use existing instance if Internet Explorer is already running eval {$ie = Win32::OLE->GetActiveObject('InternetExplorer.Application' +)}; die "IE not installed" if $@; unless (defined $ie) { $ie = Win32::OLE->new('InternetExplorer.Application', sub {$_[0]->Qu +it;}) or die "Oops, cannot start IE"; } $ie->{Visible} = 1; # get the handle and use it to force IE to the foreground SetForegroundWindow($ie->HWND); # use send keys # How Do I Maximise The Current Window, Without Using The Mouse? # Press (SHIFT + ALT + SPACEBAR) then press X SendKeys("%+{SPACEBAR}{PAUSE 5}X"); # How do I get a screen grab, use Print Screen to grab entire screen # use ALT + PRTSCR to get current window or dialog NOT screen ! SendKeys("%{PRTSCR}"); $image = Win32::Clipboard::GetBitmap(); # $image now contains your .BMP

      Cheers

      Cheshire Cat

Re: How to capture screen under Win32?
by lshatzer (Friar) on Apr 10, 2002 at 17:04 UTC
    I was unable to do this, but this might get you in the right area, I assume this is for Windows, if not, sorry.

    Try the Win32::API module, and I belive the Win32 API call is GetDC() in user32.dll. The quick test script I ran segfaulted perl, so I doubt this will work, but I just put 5 minutes into looking, and trying it out, this will at least point you in the right direction.

    Just so you see my test script (which might be wrong with the Win32 API call, since I've never used this module):
    use Win32::API; my $screenshot = new Win32::API("user32", "GetDC", '', 'N'); my $shot = $screenshot->Call();
    Update It appears there is also another GetDC in Windows land that is dealing with Getting the Domain Controler, unlike this one, which is Device Control, or something like that. Hope this helps.
      I could be wrong, and probably am :), but I think GetDC is much likelier to be in GDI32 (the graphics engine) than user32.

      I think your $screenshot handle is probably undefined.
      --
      Mike

        Using a quickview program, in USER32.dll, it has GetDC()listed. In GDI32.dll it had stuff like GetDCBrushColor and some other various ones like that. Output from $screenshot handle from original code (before the $screenshot->Call() via Data::Dumper:
        $VAR1 = bless( { 'dllname' => 'user32', 'dll' => 2011234304, 'proc' => 2011246207, 'out' => 1, 'in' => [] }, 'Win32::API' );
Re: How to capture screen under Win32?
by tachyon (Chancellor) on Apr 10, 2002 at 19:58 UTC
Re: How to capture screen under Win32?
by flofloh (Initiate) on Apr 14, 2002 at 22:26 UTC
    Hi and thanks for all the comments (especially to Cheshire Cat)!

    I found that Win32::GuiTest offers the easiest to use methods to find, control and activate windows (FindWindowLike GetWindowText SetForegroundWindow). Easier than the Win32::API-Calls - at least for me :)

    To capture the screen I took the SendKeys-Function of Win32::GuiTest. It's not as nifty as Win32::API Calls, but works fine for me. With Win32::Clipboard::GetBitmap() the script pulls the image data out of the Clipboard and saves it to HD. Probably process it with ImageMagick.

    Thanks to all again!
    Florian