捕获桌面屏幕QT / C ++ WinAPI

时间:2017-04-16 16:33:53

标签: c++ windows winapi screen-capture

我正在使用QT / C ++,我想抓住桌面的屏幕并获得像素缓冲区。

我正在使用此功能,但它会返回奇怪的像素值,有人能告诉我原因吗?

void CaptureScreen()
{
int nScreenWidth = GetSystemMetrics(SM_CXSCREEN);
int nScreenHeight = GetSystemMetrics(SM_CYSCREEN);
HWND hDesktopWnd = GetDesktopWindow();
HDC hDesktopDC = GetDC(hDesktopWnd);
HDC hCaptureDC = CreateCompatibleDC(hDesktopDC);
HBITMAP hCaptureBitmap = CreateCompatibleBitmap(hDesktopDC, nScreenWidth, nScreenHeight);
SelectObject(hCaptureDC, hCaptureBitmap);

BitBlt(hCaptureDC, 0, 0, nScreenWidth, nScreenHeight, hDesktopDC, 0,0, SRCCOPY|CAPTUREBLT);

BITMAPINFO bmi = {0};
bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
bmi.bmiHeader.biWidth = nScreenWidth;
bmi.bmiHeader.biHeight = nScreenHeight;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;

unsigned char *pPixels = new unsigned char[nScreenWidth * nScreenHeight * 4];

GetDIBits(hCaptureDC, hCaptureBitmap, 0, nScreenHeight, pPixels, &bmi,    DIB_RGB_COLORS);

for (int i = 0; i < 200; i++) {
    qDebug() << (int) pPixels[i];
}

delete[] pPixels;

ReleaseDC(hDesktopWnd, hDesktopDC);
DeleteDC(hCaptureDC);
DeleteObject(hCaptureBitmap);
}

输出为1 1 1 255 1 1 1 255 ...但屏幕顶部的第一个像素为白色。它应该是255 255 255 255等......

谢谢!

1 个答案:

答案 0 :(得分:0)

解决! 感谢RbMm评论:

[Browsable(true)]
[Editor(typeof(TestDesignProperty), typeof(UITypeEditor))]
[DefaultValue(null)]
public string SelectedObject { get; set; }

public class TestDesignProperty : UITypeEditor
{
    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    {
        return UITypeEditorEditStyle.DropDown;
    }

    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
    {

        var edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
        ListBox lb = new ListBox();
        var form1 = (Form1) Activator.CreateInstance(typeof (Form1)); //Change with your form class
        foreach (Control control in form1.Controls)
        {
            lb.Items.Add(control.Name);
        }

        if (value != null)
        {
            lb.SelectedItem = value;
        }

        edSvc.DropDownControl(lb);

        value = (string)lb.SelectedItem;

        return value;
    }
}

我刚刚用A bottom-up DIB is specified by setting the height to a positive number, while a top-down DIB is specified by setting the height to a negative number. the first line is bottom. if want another order use bmi.bmiHeader.biHeight = -nScreenHeight; 替换了这一行bmi.bmiHeader.biHeight = nScreenHeight;,我从顶行获得了像素。 它可以帮助别人:))