如何截取第二个屏幕监视器的屏幕截图?
Posted
技术标签:
【中文标题】如何截取第二个屏幕监视器的屏幕截图?【英文标题】:How to take a screenshot of a second screen monitor? 【发布时间】:2015-03-14 05:59:41 【问题描述】:我需要获取第二个屏幕监视器的屏幕截图。 我找到了一种制作屏幕截图的简单方法,但仅适用于主显示器的屏幕截图。代码如下:
#include <windows.h>
void ScreenShot(char*BmpName)
HWND DesktopHwnd = GetDesktopWindow();
RECT DesktopParams;
HDC DevC = GetDC(DesktopHwnd);
GetWindowRect(DesktopHwnd, &DesktopParams);
DWORD Width = DesktopParams.right - DesktopParams.left;
DWORD Height = DesktopParams.bottom - DesktopParams.top;
DWORD FileSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (sizeof(RGBTRIPLE) + 1 * (Width*Height * 4));
char *BmpFileData = (char*)GlobalAlloc(0x0040, FileSize);
PBITMAPFILEHEADER BFileHeader = (PBITMAPFILEHEADER)BmpFileData;
PBITMAPINFOHEADER BInfoHeader = (PBITMAPINFOHEADER)&BmpFileData[sizeof(BITMAPFILEHEADER)];
BFileHeader->bfType = 0x4D42; // BM
BFileHeader->bfSize = sizeof(BITMAPFILEHEADER);
BFileHeader->bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
BInfoHeader->biSize = sizeof(BITMAPINFOHEADER);
BInfoHeader->biPlanes = 1;
BInfoHeader->biBitCount = 24;
BInfoHeader->biCompression = BI_RGB;
BInfoHeader->biHeight = Height;
BInfoHeader->biWidth = Width;
RGBTRIPLE *Image = (RGBTRIPLE*)&BmpFileData[sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)];
RGBTRIPLE color;
HDC CaptureDC = CreateCompatibleDC(DevC);
HBITMAP CaptureBitmap = CreateCompatibleBitmap(DevC, Width, Height);
SelectObject(CaptureDC, CaptureBitmap);
BitBlt(CaptureDC, 0, 0, Width, Height, DevC, 0, 0, SRCCOPY | CAPTUREBLT);
GetDIBits(CaptureDC, CaptureBitmap, 0, Height, Image, (LPBITMAPINFO)BInfoHeader, DIB_RGB_COLORS);
DWORD Junk;
HANDLE FH = CreateFileA(BmpName, GENERIC_WRITE, FILE_SHARE_WRITE, 0, CREATE_ALWAYS, 0, 0);
WriteFile(FH, BmpFileData, FileSize, &Junk, 0);
CloseHandle(FH);
GlobalFree(BmpFileData);
int main()
ScreenShot("Hello.bmp");
但这仅对默认监视器进行屏幕截图。
如果在演示模式下使用 2 台显示器,我需要拍摄第二台显示器的屏幕截图。
我正在尝试在
上编写相同的代码EnumDisplayMonitors
像这样:
#include <windows.h>
BOOL CALLBACK MonitorEnumProcCallback(_In_ HMONITOR hMonitor, _In_ HDC DevC, _In_ LPRECT lprcMonitor, _In_ LPARAM dwData)
screenCounter++;
char*BmpName;
if (screenCounter == 1)
BmpName = "1 screen.bmp";
else
BmpName = "2 screen.bmp";
MONITORINFO info;
info.cbSize = sizeof(MONITORINFO);
BOOL monitorInfo = GetMonitorInfo(hMonitor, &info);
if (monitorInfo)
DWORD Width = info.rcMonitor.right - info.rcMonitor.left;
DWORD Height = info.rcMonitor.bottom - info.rcMonitor.top;
DWORD FileSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (sizeof(RGBTRIPLE) + 1 * (Width*Height * 4));
char *BmpFileData = (char*)GlobalAlloc(0x0040, FileSize);
PBITMAPFILEHEADER BFileHeader = (PBITMAPFILEHEADER)BmpFileData;
PBITMAPINFOHEADER BInfoHeader = (PBITMAPINFOHEADER)&BmpFileData[sizeof(BITMAPFILEHEADER)];
BFileHeader->bfType = 0x4D42; // BM
BFileHeader->bfSize = sizeof(BITMAPFILEHEADER);
BFileHeader->bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
BInfoHeader->biSize = sizeof(BITMAPINFOHEADER);
BInfoHeader->biPlanes = 1;
BInfoHeader->biBitCount = 24;
BInfoHeader->biCompression = BI_RGB;
BInfoHeader->biHeight = Height;
BInfoHeader->biWidth = Width;
RGBTRIPLE *Image = (RGBTRIPLE*)&BmpFileData[sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)];
RGBTRIPLE color;
HDC CaptureDC = CreateCompatibleDC(DevC);
HBITMAP CaptureBitmap = CreateCompatibleBitmap(DevC, Width, Height);
SelectObject(CaptureDC, CaptureBitmap);
BitBlt(CaptureDC, 0, 0, Width, Height, DevC, 0, 0, SRCCOPY | CAPTUREBLT);
GetDIBits(CaptureDC, CaptureBitmap, 0, Height, Image, (LPBITMAPINFO)BInfoHeader, DIB_RGB_COLORS);
DWORD Junk;
HANDLE FH = CreateFileA(BmpName, GENERIC_WRITE, FILE_SHARE_WRITE, 0, CREATE_ALWAYS, 0, 0);
WriteFile(FH, BmpFileData, FileSize, &Junk, 0);
CloseHandle(FH);
GlobalFree(BmpFileData);
return TRUE;
int main()
EnumDisplayMonitors(NULL, NULL, MonitorEnumProcCallback, 0);
return 0;
但这会返回给我两个黑色图像。
【问题讨论】:
一个相当明显的错误是您仍然将 0, 0 传递给 BitBlt() 而不是显示器的左上角。 【参考方案1】:感谢@Hans Passant 的帮助。
我改变左上角的值
但我犯了另一个错误,我在 EnumDisplayMonitors 中为第一个参数发送了 NULL。
这里是变化:
BOOL CALLBACK MonitorEnumProcCallback(_In_ HMONITOR hMonitor, _In_ HDC DevC, _In_ LPRECT lprcMonitor, _In_ LPARAM dwData)
screenCounter++;
char*BmpName;
if (screenCounter == 1)
BmpName = "1 screen.bmp";
else
BmpName = "2 screen.bmp";
MONITORINFO info;
info.cbSize = sizeof(MONITORINFO);
BOOL monitorInfo = GetMonitorInfo(hMonitor, &info);
if (monitorInfo)
DWORD Width = info.rcMonitor.right - info.rcMonitor.left;
DWORD Height = info.rcMonitor.bottom - info.rcMonitor.top;
DWORD FileSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (sizeof(RGBTRIPLE) + 1 * (Width*Height * 4));
char *BmpFileData = (char*)GlobalAlloc(0x0040, FileSize);
PBITMAPFILEHEADER BFileHeader = (PBITMAPFILEHEADER)BmpFileData;
PBITMAPINFOHEADER BInfoHeader = (PBITMAPINFOHEADER)&BmpFileData[sizeof(BITMAPFILEHEADER)];
BFileHeader->bfType = 0x4D42; // BM
BFileHeader->bfSize = sizeof(BITMAPFILEHEADER);
BFileHeader->bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
BInfoHeader->biSize = sizeof(BITMAPINFOHEADER);
BInfoHeader->biPlanes = 1;
BInfoHeader->biBitCount = 24;
BInfoHeader->biCompression = BI_RGB;
BInfoHeader->biHeight = Height;
BInfoHeader->biWidth = Width;
RGBTRIPLE *Image = (RGBTRIPLE*)&BmpFileData[sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)];
RGBTRIPLE color;
HDC CaptureDC = CreateCompatibleDC(DevC);
HBITMAP CaptureBitmap = CreateCompatibleBitmap(DevC, Width, Height);
SelectObject(CaptureDC, CaptureBitmap);
BitBlt(CaptureDC, 0, 0, Width, Height, DevC, info.rcMonitor.left, info.rcMonitor.top, SRCCOPY | CAPTUREBLT);
GetDIBits(CaptureDC, CaptureBitmap, 0, Height, Image, (LPBITMAPINFO)BInfoHeader, DIB_RGB_COLORS);
DWORD Junk;
HANDLE FH = CreateFileA(BmpName, GENERIC_WRITE, FILE_SHARE_WRITE, 0, CREATE_ALWAYS, 0, 0);
WriteFile(FH, BmpFileData, FileSize, &Junk, 0);
CloseHandle(FH);
GlobalFree(BmpFileData);
return TRUE;
int main()
HDC DevC = GetDC(NULL);
BOOL b = EnumDisplayMonitors(DevC, NULL, MonitorEnumProcCallback, 0);
return 0;
【讨论】:
以上是关于如何截取第二个屏幕监视器的屏幕截图?的主要内容,如果未能解决你的问题,请参考以下文章