/根据窗口句柄后台截图保存成BMP位图文件并且显示到picture 控件上void GetScreenBmp(HWND hwnd, int left, int top, int width, int height, CHAR*path)
{
HDC pDC;//源DC//判断是不是窗口句柄如果是的话不能使用GetDC来获取DC 不然截图会是黑屏
if (hwnd==::GetDesktopWindow())
{
pDC= CreateDCA("DISPLAY", NULL, NULL, NULL);
}else{
pDC= ::GetDC(hwnd);//获取屏幕DC(0为全屏,句柄则为窗口)
}int BitPerPixel = ::GetDeviceCaps(pDC, BITSPIXEL);//获得颜色模式
if (width == 0 && height == 0)//默认宽度和高度为全屏
{
width= ::GetDeviceCaps(pDC, HORZRES); //设置图像宽度全屏
height = ::GetDeviceCaps(pDC, VERTRES); //设置图像高度全屏
}
HDC memDC;//内存DC
memDC =::CreateCompatibleDC(pDC);
HBITMAP memBitmap, oldmemBitmap;//建立和屏幕兼容的bitmap
memBitmap =::CreateCompatibleBitmap(pDC, width, height);
oldmemBitmap= (HBITMAP)::SelectObject(memDC, memBitmap);//将memBitmap选入内存DC
if (hwnd==::GetDesktopWindow())
{
BitBlt(memDC,0, 0, width, height, pDC, left, top, SRCCOPY);//图像宽度高度和截取位置
}else{bool bret =::PrintWindow(hwnd, memDC, PW_CLIENTONLY);if (!bret)
{
BitBlt(memDC,0, 0, width, height, pDC, left, top, SRCCOPY);//图像宽度高度和截取位置
}
}//以下代码保存memDC中的位图到文件
BITMAP bmp;
::GetObject(memBitmap,sizeof(BITMAP), &bmp);;//获得位图信息
FILE *fp;
fopen_s(&fp, path, "w+b");//图片保存路径和方式
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;//宽度
BITMAPFILEHEADER bfh= { 0 };//位图文件头
bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);//到位图数据的偏移量
bfh.bfSize = bfh.bfOffBits + bmp.bmWidthBytes * bmp.bmHeight;//文件总的大小
bfh.bfType = (WORD)0x4d42;
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);
HWND sBitHwnd=GetDlgItem(g_Hwnd, IDC_STATIC_IMG);/*返回内存中的位图句柄 还原原来的内存DC位图句柄 不能直接用 memBitmap我测试好像是不行不知道为什么*/HBITMAP oleImage=(HBITMAP)::SelectObject(memDC, oldmemBitmap);
oleImage=(HBITMAP)SendMessage(sBitHwnd, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)oleImage);#if 0
/*这种方法也能把位图显示到picture 控件上*/HDC bitDc=NULL;
bitDc=::GetDC(sBitHwnd);
BitBlt(bitDc,0, 0, bmp.bmWidth, bmp.bmHeight, memDC, 0, 0, SRCCOPY); //内存DC映射到屏幕DC
ReleaseDC(sBitHwnd, bitDc);/*如果需要把位图转换*/
/*CImage image;
image.Create(nWidth, nHeight, nBitPerPixel);
BitBlt(image.GetDC(), 0, 0, nWidth, nHeight, hdcSrc, 0, 0, SRCCOPY);
::ReleaseDC(NULL, hdcSrc);
image.ReleaseDC();
image.Save(path, Gdiplus::ImageFormatPNG);//ImageFormatJPEG*/
#endifDeleteObject(memBitmap);
DeleteObject(oleImage);
DeleteDC(memDC);
ReleaseDC(hwnd,pDC);
}