Захват скрытого окна в Vista - PullRequest
0 голосов
/ 12 апреля 2009

Мое понимание Vista - то, что каждое окно получает свой собственный экранный буфер, который затем альфа-смешивается и т. Д. Для создания экрана.

Итак, есть ли способ сделать снимок экрана с экрана, который затемнен или частично скрыт за счет непосредственного чтения этих буферов? Vista делает это, когда вы нажимаете Alt-Tab или наводите курсор мыши на панель задач.

Я делаю это в Delphi, но кода на любом языке будет достаточно.

Ответы [ 6 ]

2 голосов
/ 12 апреля 2009

Я полагаю, что эти буферы не существуют, когда эти окна находятся за пределами экрана. Или только частично существуют, когда частично за кадром.

Если вы обратите внимание на миниатюры окон, вы обнаружите, что они не будут обновляться, когда эти окна свернуты или находятся вне экрана. WM_PAINT сработает при перетаскивании окна из-за экрана в другое, что снова означает, что эти данные где-то еще не буферизованы.

0 голосов
/ 08 мая 2009

Сделай это (C #)

    public static Bitmap PrintWindow(IntPtr hwnd)
    {
        RECT rc;
        WinUserApi.GetWindowRect(hwnd, out rc);

        Bitmap bmp = new Bitmap(rc.Width, rc.Height, PixelFormat.Format32bppArgb);
        Graphics gfxBmp = Graphics.FromImage(bmp);
        IntPtr hdcBitmap = gfxBmp.GetHdc();
        bool succeeded = WinUserApi.PrintWindow(hwnd, hdcBitmap, 0);
        gfxBmp.ReleaseHdc(hdcBitmap);
        if (!succeeded)
        {
            gfxBmp.FillRectangle(new SolidBrush(Color.Gray), new Rectangle(Point.Empty, bmp.Size));
        }
        IntPtr hRgn = WinGdiApi.CreateRectRgn(0, 0, 0, 0);
        WinUserApi.GetWindowRgn(hwnd, hRgn);
        Region region = Region.FromHrgn(hRgn);
        if (!region.IsEmpty(gfxBmp))
        {
            gfxBmp.ExcludeClip(region);
            gfxBmp.Clear(Color.Transparent);
        }
        gfxBmp.Dispose();
        return bmp;
    }
0 голосов
/ 15 апреля 2009

Я думаю, что в новом DWM APi (Desktop Windows Manager) может быть что-то, что позволит вам писать и устанавливать собственные менеджеры рабочего стола с доступом к тем же миниатюрам, которые вы видите во Flip3d и других видах.

0 голосов
/ 14 апреля 2009

у вас есть перехват сообщения wm_paint? Автор «Программирование графики Windows: Win32 GDI и DirectDraw» Фэн Юань сделал образец DLL по этому вопросу. Я думаю, что таким образом можно захватывать окна DirectXed тоже (который имеет экран в буфере в любое время). Пожалуйста, обратитесь к http://www.fengyuan.com/article/wmprint.html Вы можете найти рабочие примеры Delphi через Google. также проверьте expterts-exchange.com

0 голосов
/ 13 апреля 2009

Что-нибудь полезное в этой теме ?: http://www.eggheadcafe.com/conversation.aspx?messageid=31543575&threadid=31543575

0 голосов
/ 12 апреля 2009

Вот код, который я давно написал на C # для приложения для захвата экрана. Он использует функцию Win32 GetWindowRect, чтобы получить границы окна, которое вы хотите захватить, создать растровое изображение с этим размером, а затем использовать функцию Win32 PrintWindow, чтобы попросить окно напечатать себя на этом растровом изображении:

RECT lRectangle = new RECT();
if (!GetWindowRect(lWindow.HWnd, ref lRectangle))
{
    MessageBox.Show(this, "An error occured while measuring the selected window.", Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
    return;
}

fCapturedImage = new Bitmap(lRectangle.Right - lRectangle.Left, lRectangle.Bottom - lRectangle.Top, PixelFormat.Format32bppArgb);
using (Graphics lGraphics = Graphics.FromImage(fCapturedImage))
{
    HDC lHdc = lGraphics.GetHdc();
    PrintWindow(lWindow.HWnd, lHdc, 0);
    lGraphics.ReleaseHdc(lHdc);
}
...