C# PrintWindow возвращает черное изображение

У меня Windows XP, и я пытаюсь захватить окно.

Но когда я захватываю окно, я получаю заголовок окна (имя и значок), но все содержимое окна черное.

При попытке сохранить изображение все изображение прозрачно.

Это мой код:

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

    [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
    public static extern IntPtr GetForegroundWindow();

    [DllImport("user32.dll")]
    private static extern bool GetWindowRect(IntPtr handle, ref Rectangle rect);

    public void CaptureWindow(IntPtr handle)
    {
        Rectangle rect = new Rectangle();
        GetWindowRect(handle, ref rect);
        rect.Width = rect.Width - rect.X;
        rect.Height = rect.Height - rect.Y;
        try
        {
            Bitmap bmp = new Bitmap(rect.Width, rect.Height);
            Graphics memoryGraphics = Graphics.FromImage(bmp);
            IntPtr hdc = memoryGraphics.GetHdc();
            PrintWindow(handle, hdc, 0);
            ResultsPB.Image = bmp;
            memoryGraphics.ReleaseHdc(hdc);
        }
        catch (Exception)
        {
            throw;
        }
    }

person user779444    schedule 26.07.2011    source источник
comment
я бы рекомендовал bitblt pinvoke.net/default.aspx/gdi32/BitBlt.html   -  person Wowa    schedule 26.07.2011
comment
Хорошо, но мне это нужно для игры, и я помню, что PrintWindow работает для игр (в XP). Думаю, мне просто нужен правильный код для PrintWindow. Я не могу использовать ваш метод, потому что GetWindowDC() возвращает null в игре, в которой я его пытаюсь использовать.   -  person user779444    schedule 26.07.2011
comment
Игра, вероятно, использует DirectX или OpenGL. Чтобы захватить эти экраны, вы должны захватить экран с помощью DirectX/OpenGL.   -  person Wowa    schedule 26.07.2011
comment
Ну, как мне это сделать? (И я не уверен, что это правильный путь, поскольку я могу даже захватить его с помощью экрана печати)   -  person user779444    schedule 26.07.2011


Ответы (1)


Посмотрите на C# Capturing Direct 3D Screen. Принтскрин захватывает видимую область, а не ручку.

DirectX и OpenGL рисуют напрямую через аппаратное обеспечение. С помощью PrintScreen вы можете захватить только экран дескриптора, который рисуется под управлением Windows.

Если вам нужна только видимая область, используйте Graphics.CaptureFromScreen.

Я попробовал BitBlt и PrintScreen с демонстрацией OpenGL с сайта http://magnum.dimajix.de/download/demos.shtml безуспешно. PrintScreen вернул только пустое растровое изображение, а BitBlt вернул старый захват (вероятно, из первого и единственного сообщения WM_PAINT).

Просто попробуйте запустить игру и прослушать ее оконные сообщения. Вы увидите, что сообщения WM_PAINT нет. Таким образом, Windows даже не знает, изменилось ли что-нибудь.

person Wowa    schedule 26.07.2011