PrintWindow:屏幕截图有时会被抵消

时间:2015-01-16 16:51:08

标签: winapi screenshot

我正在使用PrintWindow()截取Windows的屏幕截图。这适用于以下代码。

这大部分时间都有用 - 我经常在连续循环中调用它 - 但有时会失败。我开始保存失败次数的截图。有时它们只是黑色,但有时候捕获窗口的ClientArea会以某种方式偏移,只能在图片的一半上看到。为什么会这样?

编辑: PrintWindow功能是否可以保证工作,即使它被称为~100次/秒?令我惊讶的是,在每个打印窗口之后,我实际上验证了两个像素,这些像素在启动时存储为COLORREF。该计划表示他们几乎一直都在匹配。尽管如此,一旦我使用GetPixel,其他像素的返回值不时只是黑色或白色(绝不应该是这种情况)。一旦我将HDC / HBITMAP保存为屏幕截图(之前我称之为GdiFlush),屏幕截图就是纯黑色(不应该是这种情况,正如我所说,我之前检查了两个像素......)。 那么现在,回到最初的问题:这绝对是我的错,或者PrintWindow可能不时给出随机结果,而不会返回错误?

好的,这是新代码:

    /* Try printing the window 10times, in case it fails. */
for (int i = 0; i <= NUM_ITERATIONS_PREP; i++) {
    releaseSurface();
    prepared_HWND = hwnd;
    window_dc = GetWindowDC(hwnd);
    surface = CreateCompatibleDC(window_dc);
    if (surface) {
        RECT r;
        GetWindowRect(hwnd, &r);
        bmp = CreateCompatibleBitmap(window_dc, r.right - r.left, r.bottom - r.top);
        if (!ReleaseDC(hwnd, window_dc)) {
            writeLog("ReleaseDC failed.", black, true);
        }
        if (bmp) {
            old_surface_bmp = SelectBitmap(surface, bmp);
            //InvalidateRect(hwnd, 0, TRUE);
            //UpdateWindow(hwnd);
            int result = PrintWindow(hwnd, surface, 0);
            if (result != 0) {
                if (!verify || verifySurface())
                    break;
                else {
                    writeLog("Surface could not be verified on iteration " + std::to_string(i) + ". Saving screenshot.", black, true);
                    saveDebugScreenshot();
                    QThread::msleep(2);
                }
            } else {
                writeLog("PrintWindow() failed.", black, true);
            }
        }
        else {
            writeLog("BMP creation failed.", black, true);
        }
    }
    else {
        writeLog("HDC creation failed.", black, true);
    }
}

新的RELEASE CODE:

/* If you call prepareSurface(), call this once the surface isn't need anymore. */
void ClientProfile::releaseSurface() {
    SelectObject(surface, old_surface_bmp);
    DeleteDC(surface);
    DeleteObject(bmp);
    prepared_HWND = NULL;
}

releaseSurface()在prepareSurface()的开头调用,另外每次我都处理完一个表(这意味着每次prepareSurface()都会调用一次。这是一个问题吗?)。

哦,old_surface_bmp,bmp和surface被声明为私有类属性。

0 个答案:

没有答案