locked
Capture screen, display it on other window RRS feed

  • Question

  • Dear all,

    I would like to do function that user can capture specific screen area, and display them on other window. How can I do it with wpf?

    The capture function look like "Rectangular Marquee Tool" of Adobe Photoshop but how can I get data of selected-screen.

    I come with idea:
      1.  Make a transparent window
      2.  Capture selected screen behind it
      3.  Force selected-screen into image buffer
      4.  Open new window and display image buffer.

    What are wpf controls should I use for this purpose?

    Thank for any recommendation.

    Best,
    Wednesday, July 9, 2008 2:02 AM

Answers

  • Hi Marco Zhou,

    Its not work for me. And I saved as file and load file again to display image in wpf control.

    Thanks
    • Marked as answer by Marco Zhou Wednesday, July 16, 2008 10:09 AM
    Wednesday, July 16, 2008 8:50 AM

All replies

  • U can try with some API functions for capturing screen.
    Thursday, July 10, 2008 6:22 AM
  • Thank you for you comment.

    Could you give me some guide more detail?

    Best,
    Thursday, July 10, 2008 7:45 AM
  • -> What are wpf controls should I use for this purpose?

    System.Windows.Controls.Image should be able to do the trick, you could call the GDI GetDesktopDC to do the trick, capture the screen into hBimtap, and bring the hBimtap into WPF world using Imaging.CreateBitmapSourceFromHBitmap() method.

    hope this helps
    Friday, July 11, 2008 3:32 AM
  • Thank for your guide.

    But I can not get data. What is it wrong?

             {
                  int screenWidth = (int)System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width;
                  int screenHeight= (int)System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height;
                  IntPtr hwnd       = NativeMethods.GetDesktopWindow();
                  IntPtr windowDC   = NativeMethods.GetWindowDC(hwnd);
                  IntPtr memDC      = NativeMethods.CreateCompatibleDC(windowDC);
                  IntPtr hbm        = NativeMethods.CreateCompatibleBitmap(windowDC, screenWidth, screenHeight);
                  IntPtr oldbm      = NativeMethods.SelectObject(memDC, hbm);

                  bool b = NativeMethods.BitBlt(memDC, 0, 0, screenWidth, screenHeight, windowDC, 0, 0, 0x40CC0020);
                  System.Drawing.Bitmap tempBitmap  = System.Drawing.Image.FromHbitmap(hbm);
                  IntPtr                tempHBitmap = tempBitmap.GetHbitmap();

                  bitmapSrc = Imaging.CreateBitmapSourceFromHBitmap(tempHBitmap, IntPtr.Zero, Int32Rect.Empty,
                                                                                 BitmapSizeOptions.FromEmptyOptions());
                  NativeMethods.SelectObject(memDC, oldbm);
                  NativeMethods.DeleteObject(hbm);
                  NativeMethods.DeleteDC(memDC);
                  NativeMethods.ReleaseDC(hwnd, windowDC);
                  NativeMethods.DeleteObject(tempHBitmap);
                  tempBitmap.Dispose();             
              }

     class NativeMethods
        {
            // This is a call to unmanaged code.     
            [DllImport("user32.dll")]
            //Get a pointer to the desktop window
            public extern static IntPtr GetDesktopWindow();

            [DllImport("user32.dll")]
            //Get a device context from the desktop window
            public static extern IntPtr GetWindowDC(IntPtr hwnd);
            //[DllImport("gdi32.dll", EntryPoint = "CreateCompatibleDC")]
            [DllImport("gdi32.dll")]
            public static extern IntPtr CreateCompatibleDC(IntPtr hdc);
            [DllImport("gdi32.dll")]
            public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight);
            [DllImport("gdi32.dll")]
            public static extern IntPtr SelectObject(IntPtr hdc, IntPtr bmp);       
            [DllImport("gdi32.dll")]
            public static extern IntPtr DeleteObject(IntPtr hDc);
            [DllImport("gdi32.dll")]
            public static extern IntPtr DeleteDC(IntPtr hDc);
            [DllImport("user32.dll")]
            public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDc);


            [System.Runtime.InteropServices.DllImport("gdi32.dll")]
            public static extern bool BitBlt
                 (IntPtr hDestDC,       // handle to destination DC
                 int nXDest,            // X-coordinate of destination upper-left corner
                 int nYDest,            // Y-coordinate of destination upper-left corner
                 int nWidthDest,        // Width of destination rectangle
                 int nHeightDest,       // Height of destination rectangle
                 IntPtr hSrcDC,         // Handle to source DC
                 int nXSrc,             // X-coordinate of source upper-left corner
                 int nYSrc,             // Y-coordinate of source upper-left corner
                 int rasterOp  // raster operation code
                );
        }

    Monday, July 14, 2008 8:33 AM
  • Have you tried directly passing the hBitmap returned from CreateCompatibleBitmap() to the Imaging.CreateBitmapSourceFromHBitmap() method without kicking off the System.Drawing.Bitmap intermediary at all?

    I've done that before, and if I remember correctly, it can do the trick, let me know if it works for you.

    Thanks
    Tuesday, July 15, 2008 10:34 AM
  • Hi Marco Zhou,

    Its not work for me. And I saved as file and load file again to display image in wpf control.

    Thanks
    • Marked as answer by Marco Zhou Wednesday, July 16, 2008 10:09 AM
    Wednesday, July 16, 2008 8:50 AM