简体   繁体   English

使用wm_paint捕获游戏窗口

[英]Capture game window using wm_paint

I'm trying to capture a game window using SendMessage with wm_paint and wm_printclient . 我正在尝试使用带有wm_paintwm_printclient SendMessage捕获游戏窗口。

I already did it successfully using PrintWindow but the game can change between graphic engines and for some of them I get a white rectangle. 我已经使用PrintWindow成功完成了此任务,但是游戏可以在图形引擎之间进行更改,对于其中的一些引擎,我会得到一个白色矩形。 I was hoping using SendMessage would not have this problem. 我希望使用SendMessage不会出现此问题。

The problem is I'm getting a black rectangle as result of SendMessage , for any graphic engine and even for any program/window. 问题是,对于任何图形引擎,甚至对于任何程序/窗口,由于SendMessage一个黑色矩形。

void capture::captureProgramScreen(HWND hwnd, tImage* res)
{
    RECT rc;

    GetWindowRect(hwnd, &rc);

    //create
    HDC hdcScreen = GetDC(NULL);
    HDC hdc = CreateCompatibleDC(hdcScreen);
    HBITMAP hbmp = CreateCompatibleBitmap(hdcScreen, rc.right - rc.left, rc.bottom - rc.top);
    res->width = rc.right - rc.left - 17;
    res->height = rc.bottom - rc.top - 39;

    res->absoluteTop = rc.top;
    res->absoluteLeft = rc.left;

    SelectObject(hdc, hbmp);




    SendMessage(hwnd, WM_PRINTCLIENT, (int)hdc, PRF_CHILDREN | PRF_CLIENT | PRF_ERASEBKGND | PRF_NONCLIENT | PRF_OWNED);


    BITMAPINFO MyBMInfo = { 0 };
    MyBMInfo.bmiHeader.biSize = sizeof(MyBMInfo.bmiHeader);


    if (0 == GetDIBits(hdc, hbmp, 0, 0, NULL, &MyBMInfo, DIB_RGB_COLORS))
    {
        res->error = true;
        res->errorcode = 2;
        return;
    }


    res->v = std::vector<BYTE>(MyBMInfo.bmiHeader.biSizeImage);


    MyBMInfo.bmiHeader.biBitCount = 32;
    MyBMInfo.bmiHeader.biCompression = BI_RGB;

    MyBMInfo.bmiHeader.biHeight = abs(MyBMInfo.bmiHeader.biHeight);

    if (0 == GetDIBits(hdc, hbmp, 0, MyBMInfo.bmiHeader.biHeight, &(res->v[0]), &MyBMInfo, DIB_RGB_COLORS))
    {
        res->error = true;
        res->errorcode = 3;
        res->width = 0;
        res->height = 0;
        res->v.clear();
        return;
    }


    //4 Bytes per pixel order (B G R A) from [left to right] [bottom to top]



    return;
}

Thank you! 谢谢!

There are at least a few possible issues: 至少有一些可能的问题:

  1. Not all programs/windows implement WM_PRINTCLIENT . 并非所有程序/窗口都实现WM_PRINTCLIENT Many games don't even implement WM_PAINT, as they draw continuously at their desired frame rate rather than in response to a need to update themselves. 许多游戏甚至没有实现WM_PAINT,因为它们以所需的帧速率连续绘制,而不是响应于更新自身的需求。 Many games use newer graphics APIs that don't really draw to a Device Context. 许多游戏使用的更新的图形API并没有真正吸引到设备上下文。

  2. I'm not sure why you have two calls to GetDIBits. 我不确定为什么要打两次GetDIBits。 The first one happens before you initialize all the fields of the BITMAPINFO, so that one will fail. 第一个发生在初始化BITMAPINFO的所有字段之前,因此将失败。 It's still not completely filled out by the time you make the second call. 在您拨打第二个电话时,它仍未完全填写。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM