title: Capturing the screen in windows using ctypes
body: <p>I've been searching for some alternative solutions to capturing the screen to a bitmap on a windows machine.</p>
  
  <p>Now, I am aware that PIL has an ImageGrab library and I will probably end up using it. 
  However, during my searches I came across a solution that uses ctypes to access gdi32.dll functions and use those to capture the screen.
  There was one particular solution I came across which doesn't work, and I've been trying to figure out what's wrong it.</p>
  
  <p>Here's the source code:</p>
  
  <pre><code>from ctypes import *
  
  class Bitmap(Structure):
      _fields_ = [("bitmapType", c_long),
                  ("width", c_long),
                  ("height", c_long),
                  ("widthBytes", c_long),
                  ("planes", c_short),
                  ("bitsPerPixel", c_short),
                  ("data", POINTER(c_ulong))]
  
  if __name__ == "__main__":
      user32 = WinDLL("user32.dll")
      gdi32 = WinDLL("gdi32.dll")
  
      #Constants
      SM_CXSCREEN = 0
      SM_CYSCREEN = 1
      SRCCOPY = 0xCC0020
  
      #Capture the Bitmap
      width = user32.GetSystemMetrics(SM_CXSCREEN)
      height = user32.GetSystemMetrics(SM_CYSCREEN)
      screenDC = user32.GetWindowDC(user32.GetDesktopWindow())
      captureDC = gdi32.CreateCompatibleDC(screenDC)
      captureBitmap = gdi32.CreateCompatibleBitmap(screenDC, width, height)
      gdi32.SelectObject(captureDC, captureBitmap)
      gdi32.BitBlt(captureDC, 0, 0, width, height, screenDC, 0, 0, SRCCOPY)
  
      picture = Bitmap()
      gdi32.GetObjectA(captureBitmap, 24, byref(picture))
  </code></pre>
  
  <p>Now, to me it seems that in the end of the program, the author tries to copy the bitmap to the Bitmap object, but:
  1. I have failed to find documentation of the gdi32.GetObjectA function
  2. When trying to view the data inside picutre.data (I hope I was not wrong by accessing picture.data.contents), I get a Value error: "NULL pointer access".</p>
  
  <p>Now, in the page where I found this code snippet, there was an answer to the problem, but it was a bit vague and not very informative. The answer read:</p>
  
  <pre>
  You must allocate the integer array for the data pointer of the BITMAP structure.
  GetObject doesn't it for you.
  </pre>
  
  <p>Shouldn't the gdi32.CreateCompatibleBitmap function already allocate that memory, and doesn't the GetObject just copy the pointer to the Python representation of the bitmap structure?</p>
  
  <p>I'm really confused here, any light shed on this problem would be really appreciated.
  (I already have like 15 open tabs with MSDN gdi32 references and 15 more with ctypes references, but seeing as I don't have a solid grasp on either, I feel like I'm going around in circles)</p>