1

I want to get Screenshots of a possible hidden Window of another application that is using drawing via direct3d or opengl. I tryed a lot of ways to receive this windows content but only got black or transparent pictures. The closest i got was by using a DWM sample here http://bartdesmet.net/blogs/bart/archive/2006/10/05/4495.aspx this paints the window onto my c# form but i cant get the pixelcolors. If ill do a form.drawtobitmap the pixels drawn by dwm are missing.

So is their any way to use DWM to recive the capture into a image or to get the image drawn onto my form?

1 Answers1

3

To answer your question: You can use GetPixel() Win32 function. But it's overkill in this situation.

Pinvoke GetPixel

MSDN GetPixel

The right way, is to get the device context and bit blit the content.

EDIT:

I've thrown together some code, by using PrintWindow. Seems to work quite well, even with media players. Note that GetWindowRect returns invalid rectangle for minimized Windows. But it's a decent start.

    [StructLayout(LayoutKind.Sequential)]
    public struct Rect
    {
        internal Rect(int left, int top, int right, int bottom)
        {
            Left = left;
            Top = top;
            Right = right;
            Bottom = bottom;
        }

        public int Left;
        public int Top;
        public int Right;
        public int Bottom;
    }

    [DllImport("user32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool PrintWindow(IntPtr hwnd, IntPtr hDC, uint nFlags);

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool GetWindowRect(IntPtr hwnd, out Rect lpRect);

    public void DumpWindow(IntPtr hwndSource, string filename)
    {
        Rect rc;
        GetWindowRect(hwndSource, out rc);

        var bmp = new Bitmap(rc.Right - rc.Left, rc.Bottom - rc.Top, PixelFormat.Format32bppArgb);
        using (Graphics gBmp = Graphics.FromImage(bmp))
        {
            IntPtr hdcBmp = gBmp.GetHdc();

            PrintWindow(hwndSource, hdcBmp, 0);

            gBmp.ReleaseHdc(hdcBmp);
        }

        bmp.Save(filename);
    }

Edit2: And if you add a second button to DWM demo form, insert this:

private void button1_Click(object sender, EventArgs e)
{
    var w = (Window)lstWindows.SelectedItem;
    DumpWindow(w.Handle, "test.bmp");
    Process.Start("test.bmp");
}

It still shows an empty image?

JonPall
  • 814
  • 4
  • 9
  • 1
    thanks for the getpixelhint i can now retrieve the color of the projected rectangle but i will give the bit blit a look too. – user3289727 Feb 09 '14 at 17:34
  • ok i tryed the bit blit method and the code you postet but both show show the same results. It should look like this http://imgur.com/07kPulZ,Hj9HSX7 (taken with windows just by using the printkey) but it ends up looking like this http://imgur.com/07kPulZ,Hj9HSX7#1 – user3289727 Feb 10 '14 at 08:32
  • And the dumped file looks like? Try out the code in edit2, and report back. – JonPall Feb 10 '14 at 09:50
  • great that you still try to help i have tryed the code and it looks like this source http://imgur.com/VsVXb9h,fjYl2An,gKaLMal dwmwindow http://imgur.com/VsVXb9h,fjYl2An,gKaLMal#1 result http://imgur.com/VsVXb9h,fjYl2An,gKaLMal#2 the capturesource is a virtual machine showing a emulated android. I think the display is rendered in opengl thats properbly the reason its so hard to capture and i was so happy that dwm nearly did the job (i got it on my own form) – user3289727 Feb 10 '14 at 16:19