title: Java - Window Image
body: <p>Does anyone know how to capture a screen shot in Java (not it's own screen, but any other window on the desktop and they <strong>don't</strong> necessarily have to be the <strong>active</strong> window) in Windows? There are a number of threads here on this similar subject, but I have yet to find an answer. </p>
  
  <p>I've tried using JNA, but became stuck after a few attempts. For example...</p>
  
  <pre><code>public class Main {
  
      public static void main(String[] args) {
          Main m = new Main();
  
          List&lt;WindowInfo&gt; list = m.getWindows();
  
          for (int i=0;i&lt;list.size();i++) 
          {
              WindowInfo info = list.get(i);
              System.out.println(info.getTitle());
          }
  
          WindowInfo wi = list.get(0);
  
          W32API.HDC hdcSrc = User32.instance.GetWindowDC(wi.getHwnd());
  
          W32API.HDC hdcMemory = Gdi32.instance.CreateCompatibleDC(hdcSrc);
  
          //W32API.HBITMAP hBitmapMemory = Gdi32.instance.CreateCompatibleBitmap(hdcSrc, int width, int height);
          int width = wi.getRect().right - wi.getRect().left;
          int height = wi.getRect().bottom - wi.getRect().top;
  
          W32API.HBITMAP hBitmapMemory  = Gdi32.instance.CreateCompatibleBitmap(hdcSrc, width, height);
  
          W32API.HANDLE hOld  = Gdi32.instance.SelectObject(hdcMemory, hBitmapMemory);
  
  
          Gdi32.instance.BitBlt(hdcMemory, 0, 0, width, height, hdcSrc, width+2, height+2, 0x00CC0020);
  
  
          /* # now how do we convert to a BufferedImage???  */
  
          // clean up
          Gdi32.instance.SelectObject(hdcMemory, hOld);
          Gdi32.instance.DeleteDC(hdcMemory);
          Gdi32.instance.DeleteObject(hBitmapMemory);
          User32.instance.ReleaseDC(wi.getHwnd(), hdcSrc);
  
  
      }
  
  
      /**
       *
       * @return
       */
      private List&lt;WindowInfo&gt; getWindows() {
  
          final List&lt;WindowInfo&gt; list = new ArrayList&lt;WindowInfo&gt;();
  
  
          User32.instance.EnumWindows(new WndEnumProc() {
              public boolean callback(int hWnd, int lParam) {
                  if (User32.instance.IsWindowVisible(hWnd)) {
                      RECT r = new RECT();
                      User32.instance.GetWindowRect(hWnd, r);
                      byte[] buffer = new byte[1024];
                      User32.instance.GetWindowTextA(hWnd, buffer, buffer.length);
                      String title = Native.toString(buffer);
                      if (title!=null&amp;&amp;title.length()&gt;0) {
                          list.add(new WindowInfo(hWnd, r, title));
                      }
                  }
                  return true;
              }
          }, 0);
  
          Collections.sort(list, new Comparator&lt;WindowInfo&gt;() {
              public int compare(WindowInfo o1, WindowInfo o2) {
                  int i1 = (o1.getTitle()!=null&amp;&amp;o1.getTitle().length()&gt;0?o1.getTitle():" ").charAt(0);
                  int i2 = (o2.getTitle()!=null&amp;&amp;o2.getTitle().length()&gt;0?o2.getTitle():" ").charAt(0);
                  return i1 - i2;
              }
          });
  
          return list;
      }
  }
  </code></pre>
  
  <p>I've also tried the equivalent of "PrintWindow()" API...</p>
  
  <pre><code>Graphics g = form.CreateGraphics();
  Bitmap bmp = new Bitmap(form.Size.Width, form.Size.Height, g);
  Graphics memoryGraphics = Graphics.FromImage(bmp);
  IntPtr dc = memoryGraphics.GetHdc();
  bool success = PrintWindow(form.Handle, dc, 0);
  memoryGraphics.ReleaseHdc(dc);
  // bmp now contains the screenshot
  </code></pre>
  
  <p>Or do I have to use JNI, or any other tool?</p>