如何在系统dpi设置下捕获窗口图像

时间:2019-06-01 18:57:50

标签: c++ windows screenshot dpi

我想通过窗口手柄抓取图像,我编写了演示,如果系统未设置dpi,则可以抓取,但是一旦设置了dpi,则围绕它捕获的图像不属于这个窗口。或标题栏没有被捕获。

应该注意,我需要基于HWND而不是全局桌面GetDesktopWindow捕获指定的窗口图像-我知道如何捕获桌面图像。

我找到了一些信息,还尝试了DwmGetWindowAttributePrintWindow,但是当我设置Win10(仅测试Win10)时,系统dpi为125%,150%,175%等是不正确的

void ShootScreen(LPCTSTR filename, HWND hWnd)
{

    INT32 ScrWidth = 0, ScrHeight = 0;
    RECT rect = { 0 };
    RECT rectWin = { 0 };

    HDC hdc = GetWindowDC(hWnd);
    RECT* prt = nullptr;
    {

        GetWindowRect(hWnd, &rectWin);
        WINDOWINFO  wi = {0};
        wi.cbSize = sizeof(wi);
        GetWindowInfo(hWnd, &wi);

        BOOL enable = FALSE;
        HRESULT hr = DwmIsCompositionEnabled(&enable);
        if (SUCCEEDED(hr) && enable)
        {
            DwmGetWindowAttribute(hWnd, DWMWA_EXTENDED_FRAME_BOUNDS, &rect, sizeof(RECT));
        }

        prt = ▭
        double scale_x = (double)GetDeviceCaps(hdc, DESKTOPHORZRES) / (double)GetDeviceCaps(hdc, HORZRES);
        double scale_y = (double)(double)GetDeviceCaps(hdc, DESKTOPVERTRES) / (double)GetDeviceCaps(hdc, VERTRES);

        ScrWidth = prt->right - prt->left;
        ScrHeight = prt->bottom - prt->top;

        ScrWidth = LONG(double(ScrWidth) * scale_x);
        ScrHeight = LONG(double(ScrHeight) * scale_y);
    }
    HDC hmdc = CreateCompatibleDC(hdc);

    HBITMAP hBmpScreen = CreateCompatibleBitmap(hdc, ScrWidth, ScrHeight);

    HBITMAP holdbmp = (HBITMAP)SelectObject(hmdc, hBmpScreen);

    BITMAP bm;
    GetObject(hBmpScreen, sizeof(bm), &bm);

    BITMAPINFOHEADER bi = { 0 };
    bi.biSize = sizeof(BITMAPINFOHEADER);
    bi.biWidth = bm.bmWidth;
    bi.biHeight = bm.bmHeight;
    bi.biPlanes = bm.bmPlanes;
    bi.biBitCount = bm.bmBitsPixel;
    bi.biCompression = BI_RGB;
    bi.biSizeImage = bm.bmHeight * bm.bmWidthBytes;
    // 图片的像素数据
    char *buf = new char[bi.biSizeImage];

    if (base::win::GetVersion() > base::win::VERSION_WIN7)
    {
        PrintWindow(hWnd, hmdc, PRF_NONCLIENT); // PW_RENDERFULLCONTENT
    }
    else
    {
        BitBlt(hmdc, 0, 0, ScrWidth, ScrHeight, hdc, prt->left, prt->top, SRCCOPY);
    }

    ReleaseDC(hWnd, hdc);

    GetDIBits(hmdc, hBmpScreen, 0L, (DWORD)ScrHeight, buf, (LPBITMAPINFO)&bi, (DWORD)DIB_RGB_COLORS);

    BITMAPFILEHEADER bfh = { 0 };
    bfh.bfType = ((WORD)('M' << 8) | 'B');
    bfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + bi.biSizeImage;
    bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
    HANDLE hFile = CreateFile(filename, GENERIC_WRITE, 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
    DWORD dwWrite;
    WriteFile(hFile, &bfh, sizeof(BITMAPFILEHEADER), &dwWrite, NULL);
    WriteFile(hFile, &bi, sizeof(BITMAPINFOHEADER), &dwWrite, NULL);
    WriteFile(hFile, buf, bi.biSizeImage, &dwWrite, NULL);
    CloseHandle(hFile);
    SelectObject(hmdc, holdbmp);
}

0 个答案:

没有答案