Qt:由于快速屏幕采样导致鼠标光标闪烁

Qt: mouse cursor flickering due to fast screen sampling

你好,我使用这段代码快速(大约 60 times/second)对屏幕进行采样并找到它的平均颜色:

samplerWorker::samplerWorker(int newId)
{
    this->id = newId;
    this->screenWidth = GetSystemMetrics(SM_CXSCREEN);
    this->screenHeight = GetSystemMetrics(SM_CYSCREEN);
    this->hDesktopWnd = GetDesktopWindow();
    this->hDesktopDC = GetDC(this->hDesktopWnd);
    this->hCaptureDC = CreateCompatibleDC(this->hDesktopDC);
}

void samplerWorker::sampleAvgColor(int workerId)
{
    if(workerId != this->id)
    {
        return;
    }
    HBITMAP hCaptureBitmap = CreateCompatibleBitmap(this->hDesktopDC, this->screenWidth, this->screenHeight);
    SelectObject(hCaptureDC, hCaptureBitmap);

    BitBlt(this->hCaptureDC, 0, 0, this->screenWidth, this->screenHeight, this->hDesktopDC, 0,0, SRCCOPY|CAPTUREBLT);

    BITMAPINFO bmi = {0};
    bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
    bmi.bmiHeader.biWidth = this->screenWidth;
    bmi.bmiHeader.biHeight = this->screenHeight;
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biBitCount = 32;
    bmi.bmiHeader.biCompression = BI_RGB;
    int size = this->screenWidth * this->screenHeight * 4;
    unsigned char *pPixels = new unsigned char[size];

    GetDIBits(this->hCaptureDC, hCaptureBitmap, 0, this->screenHeight, pPixels, &bmi,    DIB_RGB_COLORS);

    unsigned int avgR = 0;
    unsigned int avgG = 0;
    unsigned int avgB = 0;
    size = size /4;
    for (int i = 0; i < size; i++) {
        avgB = avgB + pPixels[4*i + 0];
        avgG = avgG + pPixels[4*i + 1];
        avgR = avgR + pPixels[4*i + 2];
    }

    avgR = avgR / (size);
    avgG = avgG / (size);
    avgB = avgB / (size);

    emit returnAvgColor(avgR,avgG,avgB);

    delete[] pPixels;

    DeleteObject(hCaptureBitmap);
}

samplerWorker是一个工作在几个独立线程中的对象,每个samplerWorker在一个单独的线程中,它们被一个接一个地调用,所以第一个截图是id == 0的samplerWorker,然后是id == 1,依此类推,直到所有这些都被调用,然后它 returns 返回给 id == 0 的采样器工作人员。但是由于某种原因,当我足够快地截取屏幕(超过 10-15 fps)时,我的光标开始闪烁。什么可能导致此问题?

参考:Raymond Chen Discusses the Case of the Disappearing Cursor

These translucent windows, known as layered windows, are not normally included by the BitBlt function when reading pixels from the screen. In order to get them, you have to pass the CAPTUREBLT flag.

The mouse cursor is just another composition object and therefore would be captured by the CAPTUREBLT flag. To prevent this from happening during a screen capture, the composition engine has to hide the cursor, do the CAPTUREBLT, and then re-show the cursor.

相关案例:Cursor disappears on bitblt