我想通过窗口手柄抓取图像,我编写了演示,如果系统未设置dpi,则可以抓取,但是一旦设置了dpi,则围绕它捕获的图像不属于这个窗口。或标题栏没有被捕获。
应该注意,我需要基于HWND
而不是全局桌面GetDesktopWindow
捕获指定的窗口图像-我知道如何捕获桌面图像。
我找到了一些信息,还尝试了DwmGetWindowAttribute
和PrintWindow
,但是当我设置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);
}