Screen capture in Haskell? Screen capture in Haskell? windows windows

Screen capture in Haskell?


The Approach Tikhon mentioned is correct. Just to add some code to the answer he gave above

import Graphics.Win32.Windowimport Graphics.Win32.GDI.Bitmapimport Graphics.Win32.GDI.HDCimport Graphics.Win32.GDI.Graphics2Dmain = do desktop   <- getDesktopWindow -- Grab the Hwnd of the desktop, GetDC 0, GetDC NULL etc all work too          hdc       <- getWindowDC (Just desktop) -- Get the dc handle of the desktop          (x,y,r,b) <- getWindowRect desktop -- Find the size of the desktop so we can know which size the destination bitmap should be                                             -- (left, top, right, bottom)          newDC     <- createCompatibleDC (Just hdc) -- Create a new DC to hold the copied image. It should be compatible with the source DC          let width  = r - x -- Calculate the width          let height = b - y -- Calculate the Height          newBmp    <- createCompatibleBitmap hdc width height -- Create a new Bitmap which is compatible with the newly created DC          selBmp    <- selectBitmap newDC newBmp -- Select the Bitmap into the DC, drawing on the DC now draws on the bitmap as well          bitBlt newDC 0 0 width height hdc 0 0 sRCCOPY -- use SRCCOPY to copy the desktop DC into the newDC          createBMPFile "Foo.bmp" newBmp newDC  -- Write out the new Bitmap file to Foo.bmp          putStrLn "Bitmap image copied" -- Some debug message          deleteBitmap selBmp -- Cleanup the selected bitmap          deleteBitmap newBmp -- Cleanup the new bitmap          deleteDC newDC      -- Cleanup the DC we created.

This was just quickly put together, but it saves a screenshot of to a file named Foo.bmp. Ps. To whomever wrote the Win32 Library, nicely done :)


You can also do it in a cross-platform way with GTK.

That would not be much different from doing it with C: Taking a screenshot with C/GTK.

{-# LANGUAGE OverloadedStrings #-}import Graphics.UI.Gtkimport System.Environmentimport Data.Text as Tmain :: IO ()main = do    [fileName] <- getArgs    _ <- initGUI    Just screen <- screenGetDefault    window <- screenGetRootWindow screen    size <- drawableGetSize window    origin <- drawWindowGetOrigin window    Just pxbuf <-        pixbufGetFromDrawable            window            ((uncurry . uncurry Rectangle) origin size)    pixbufSave pxbuf fileName "png" ([] :: [(T.Text, T.Text)])


You should be able to do this with the Win32 API. Based on What is the best way to take screenshots of a Window with C++ in Windows?, you need to get the context of the window and then copy the image from it using GetWindowDC and BitBlt respectively.

Looking around the Haskell Win32 API documentation, there is a getWindowDC function in Graphics.Win32.Window. This returns an IO HDC. There is a bitblt function in Graphics.Win32.GDI.Graphics2D. This function takes an HDC along with a bunch of INTs which presumably correspond to the arguments it takes in C++.

Unfortunately, I don't have a Windows machine handy, so I can't write the actual code. You'll have to figure out how to use the Win32 API functions yourself, which might be a bit of a bother.

When you do, it would be great if you factored it into a library and put it up on Hackage--Windows does not usually get much love in Haskell land (as I myself show :P), so I'm sure other Windows programmers would be grateful for an easy way to take screenshots.