#include <stdio.h>
#include <windows.h>
#include <iostream>
#include <vector>
#include <atlimage.h>
using namespace std;
#define ENTERFUNCTION printf("%s() >\n",__FUNCTION__);
#define LEAVEFUNCTION(iRtn) printf("%s() < iRtn = %d.\n",__FUNCTION__,iRtn);
// 定义错误
#define ERROR_PARAMETER 0x100
#define ERROR_SYSTEM 0x101
typedef enum
{
BMP,
JPG
}IMG_TYPE;
struct ALLMONITORINFO
{
HMONITOR hMonitor;
RECT rect;
bool isPrimary;
};
BOOL CALLBACK MonitorEnumProc(__in HMONITOR hMonitor, __in HDC hdcMonitor, __in LPRECT lprcMonitor, __in LPARAM dwData)
{
vector<ALLMONITORINFO>& infoArray = *reinterpret_cast<vector<ALLMONITORINFO>*>(dwData);
ALLMONITORINFO monitorInfo;
monitorInfo.hMonitor = hMonitor;
monitorInfo.rect = *lprcMonitor;
infoArray.push_back(monitorInfo);
return TRUE;
}
void ScreenBMP(HWND hwnd, int left, int top, int width, int height,const char* path)
{
// 获取指定窗口的句柄
HDC sourceDC = GetWindowDC(hwnd);
// 根据源DC获取创建兼容内存DC
HDC memDC = ::CreateCompatibleDC(sourceDC);
// 根据原DC创建兼容位图
HBITMAP memBitmap;
memBitmap = ::CreateCompatibleBitmap(sourceDC, width, height);
// 将兼容位图写入内存DC
SelectObject(memDC, memBitmap);
// 截图
BitBlt(memDC, 0, 0, width, height, sourceDC, left, top, SRCCOPY);
BITMAP bmp;
GetObject(memBitmap, sizeof(BITMAP), &bmp);
FILE* fp;
fopen_s(&fp, path, "w+b");
BITMAPFILEHEADER bfh = { 0 };
bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bfh.bfType = (WORD)0x4d42;
BITMAPINFOHEADER bih = { 0 };
bih.biBitCount = bmp.bmBitsPixel;
bih.biCompression = BI_RGB;
bih.biHeight = bmp.bmHeight;
bih.biPlanes = 1;
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biSizeImage = bmp.bmWidthBytes * bmp.bmHeight;
bih.biWidth = bmp.bmWidth;
fwrite(&bfh, 1, sizeof(BITMAPFILEHEADER), fp);
fwrite(&bih, 1, sizeof(BITMAPINFOHEADER), fp);
byte* p = new byte[bmp.bmWidthBytes * bmp.bmHeight];
GetDIBits(memDC, (HBITMAP)memBitmap, 0, height, p, (LPBITMAPINFO)&bih, DIB_RGB_COLORS);
fwrite(p, 1, bmp.bmWidthBytes * bmp.bmHeight, fp);
delete[]p;
fclose(fp);
DeleteObject(memBitmap);
DeleteObject(memDC);
ReleaseDC(hwnd, sourceDC);
}
void ScreenJPG(HWND hwnd, int left, int top, int width, int height, const char* path)
{
// 获取指定窗口的句柄
HDC sourceDC = GetWindowDC(hwnd);
// 根据源DC获取创建兼容内存DC
HDC memDC = ::CreateCompatibleDC(sourceDC);
// 根据原DC创建兼容位图
HBITMAP memBitmap;
memBitmap = ::CreateCompatibleBitmap(sourceDC, width, height);
// 将兼容位图写入内存DC
SelectObject(memDC, memBitmap);
// 截图
BitBlt(memDC, 0, 0, width, height, sourceDC, left, top, SRCCOPY);
CImage sImage;
sImage.Attach(memBitmap);
CString strPath;
strPath.Format(_T("%s"), path);
sImage.Save((LPCTSTR)strPath);
DeleteObject(memBitmap);
DeleteObject(memDC);
ReleaseDC(hwnd, sourceDC);
}
/**
* @brief:抓取主屏幕的图像,并保存在指定目录
* @param path:图像保存目录
* @return int:0 OK,else failed.
*/
int CaptureMainScreen()
{
int iRtn = 0;
// param check
ENTERFUNCTION
do
{
HWND desktopHwnd = GetDesktopWindow();
SetForegroundWindow(desktopHwnd);
RECT deskRect;
GetWindowRect(desktopHwnd, &deskRect);
ScreenBMP(desktopHwnd, deskRect.left, deskRect.top, deskRect.right - deskRect.left, deskRect.bottom - deskRect.top, "c:/capture/mainScreen.bmp");
ScreenJPG(desktopHwnd, deskRect.left, deskRect.top, deskRect.right - deskRect.left, deskRect.bottom - deskRect.top, "c:/capture/mainScreen.jpg");
} while (0);
LEAVEFUNCTION(iRtn);
return iRtn;
}
int CaptureAllScreen()
{
int iRtn = 0;
HWND desktopHwnd = GetDesktopWindow();
SetForegroundWindow(desktopHwnd);
RECT deskRect;
GetWindowRect(desktopHwnd, &deskRect);
vector<ALLMONITORINFO> mInfo;
mInfo.clear();
mInfo.reserve(GetSystemMetrics(SM_CMONITORS));
EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, reinterpret_cast<LPARAM>(&mInfo));
int width = 0;
int height = 0;
int minleft = 0;
int mintop = 0;
int maxright = 0;
int maxbottom = 0;
for (int i = 0; i < mInfo.size(); i++)
{
if (minleft > mInfo[i].rect.left)
{
minleft = mInfo[i].rect.left;
}
if (mintop > mInfo[i].rect.top)
{
mintop = mInfo[i].rect.top;
}
if (maxright < mInfo[i].rect.right)
{
maxright = mInfo[i].rect.right;
}
if (maxbottom < mInfo[i].rect.bottom)
{
maxbottom = mInfo[i].rect.bottom;
}
}
width = maxright - minleft;
height = maxbottom - mintop;
ScreenBMP(desktopHwnd, 0, 0, width, height, "c:/capture/desktop_all.bmp");
return 0;
}
int main()
{
int iRtn = 0;
do
{
iRtn = CaptureMainScreen();
iRtn = CaptureAllScreen();
} while (0);
return iRtn;
}
使用windows api屏幕截图(支持多显示器)
最新推荐文章于 2024-01-29 10:57:33 发布