return hBit; }HANDLE CNetControlView::DDBtoDIB(HBITMAP bitmap) { //Define Variable BITMAP bm; BITMAPINFOHEADER bi; LPBITMAPINFOHEADER lpbi; DWORD dwLen; HANDLE hDib; HANDLE handle; HDC hdc; HPALETTE hPal; hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE ); // get bitmap information GetObject(bitmap,sizeof(bm),(LPSTR)&bm); // initialize the bitmapinfoheader bi.biSize = sizeof(BITMAPINFOHEADER); bi.biWidth = bm.bmWidth; bi.biHeight = bm.bmHeight; bi.biPlanes = 1; //bi.biBitCount = bm.bmPlanes * bm.bmBitsPixel; bi.biBitCount = 8; bi.biCompression = BI_RGB; bi.biSizeImage = 0; bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrUsed = 0; bi.biClrImportant = 0; // compute the size of the infoheader and the color table int ncolors = (1 << bi.biBitCount); dwLen = bi.biSize + ncolors * sizeof(RGBQUAD); // we need a device context to get the dib from hdc = ::GetDC(NULL); hPal = SelectPalette(hdc,hPal,FALSE); RealizePalette(hdc); // allocate enough memory to hold bitmapinfoheader and color table hDib = GlobalAlloc(GMEM_FIXED,dwLen); if (!hDib){ SelectPalette(hdc,hPal,FALSE); ::ReleaseDC(NULL,hdc); return NULL; } lpbi = (LPBITMAPINFOHEADER)hDib; *lpbi = bi; // call getdibits with a NULL lpbits param, so the device driver // will calculate the bisizeimage field GetDIBits(hdc, bitmap, 0L, (DWORD)bi.biHeight, (LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS ); bi = *lpbi; // if the driver did not fill in the bisizeimage field, then compute it // each scan line of the image is aligned on a dword (32bit) boundary if (bi.biSizeImage == 0) { bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8) * bi.biHeight; } // realloc the buffer so that it can hold all the bits dwLen += bi.biSizeImage; if (handle = GlobalReAlloc(hDib, dwLen, GMEM_MOVEABLE)) hDib = handle; else { GlobalFree(hDib); // reselect the original palette SelectPalette(hdc,hPal,FALSE); ::ReleaseDC(NULL,hdc); return NULL; } // get the bitmap bits lpbi = (LPBITMAPINFOHEADER)hDib; // finally get the dib BOOL bgotbits = GetDIBits( hdc, bitmap, 0L, // start scan line (DWORD)bi.biHeight, // # of scan lines (LPBYTE)lpbi // address for bitmap bits + (bi.biSize + ncolors * sizeof(RGBQUAD)), (LPBITMAPINFO)lpbi, // address of bitmapinfo (DWORD)DIB_RGB_COLORS); // use rgb for color table if( !bgotbits ) { GlobalFree(hDib);
可以抓屏显示到view中。不过没有实现保存
lz参考下吧
void CNetControlView::OnActionPrintscreen()
{
// TODO: Add your command handler code here
HANDLE hDib;
HBITMAP hBit;
POINT BitScale; BitScale.x = BMPWIDTH;
BitScale.y = BMPHEIGHT; //截图
hBit = GetSrcBit(BitScale.x,BitScale.y); //位图转换
hDib = DDBtoDIB(hBit); DWORD bitSize = GlobalSize(hDib); //显示位图
HDC hdc;
HDC hdcmem;
RECT rect;
HBITMAP hbitmap;
HBITMAP hbitmapOld; hbitmap = (HBITMAP)hDib; hdc = ::GetDC(this->m_hWnd);
::GetClientRect(this->m_hWnd,&rect);
hdcmem=CreateCompatibleDC(hdc);
hbitmapOld=(HBITMAP)SelectObject(hdcmem,hBit);
SetStretchBltMode(hdc, STRETCH_HALFTONE);
StretchBlt(hdc,0,0,BMPWIDTH,BMPHEIGHT,hdcmem,0,0,BMPWIDTH_2,BMPHEIGHT_2,SRCCOPY); //CClientDC dc(this);
//dc.MoveTo(0,0);
//dc.LineTo(50,50); SelectObject(hdcmem,hbitmapOld);
DeleteObject(hbitmap);
DeleteDC(hdcmem);
::ReleaseDC(this->m_hWnd,hdc);
DeleteDC(hdc); SetBitmap(hBit);
m_nFirstDraw++;
}HBITMAP CNetControlView::GetSrcBit(DWORD BitWidth, DWORD BitHeight)//截图,用桌面HDC覆盖HBITMAP
{
HDC hdcmy;
HDC hbufferdc;
HBITMAP hBit;
HBITMAP hOldBitmap; //Create DesktopDC
hdcmy = CreateDC("DISPLAY",NULL,NULL,NULL);//creates a device context (DC) for a device by using the specified name "DISPLAY" for a display driver
hbufferdc = CreateCompatibleDC(hdcmy);// creates a memory device context (DC) compatible with the specified device. //Create Hbitmap
hBit = CreateCompatibleBitmap(hdcmy, BitWidth, BitHeight);// creates a bitmap compatible with the device that is associated with the specified device context. //Get bit to Buffer
hOldBitmap = (HBITMAP)SelectObject(hbufferdc, hBit);
StretchBlt(hbufferdc, 0, 0, BitWidth, BitHeight,
hdcmy, 0, 0,BitWidth,BitHeight, SRCCOPY); //Get finally bit
hBit = (HBITMAP)SelectObject(hbufferdc, hOldBitmap);
//Release Memory
DeleteObject(hOldBitmap);
//ReleaseDC(NULL,hdcmy);
//ReleaseDC(NULL,hbufferdc);
::ReleaseDC(NULL,hdcmy);
::ReleaseDC(NULL,hbufferdc);
return hBit;
}HANDLE CNetControlView::DDBtoDIB(HBITMAP bitmap)
{
//Define Variable
BITMAP bm;
BITMAPINFOHEADER bi;
LPBITMAPINFOHEADER lpbi;
DWORD dwLen;
HANDLE hDib;
HANDLE handle;
HDC hdc;
HPALETTE hPal; hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE ); // get bitmap information
GetObject(bitmap,sizeof(bm),(LPSTR)&bm); // initialize the bitmapinfoheader
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bm.bmWidth;
bi.biHeight = bm.bmHeight;
bi.biPlanes = 1;
//bi.biBitCount = bm.bmPlanes * bm.bmBitsPixel;
bi.biBitCount = 8;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0; // compute the size of the infoheader and the color table
int ncolors = (1 << bi.biBitCount);
dwLen = bi.biSize + ncolors * sizeof(RGBQUAD); // we need a device context to get the dib from
hdc = ::GetDC(NULL);
hPal = SelectPalette(hdc,hPal,FALSE);
RealizePalette(hdc); // allocate enough memory to hold bitmapinfoheader and color table
hDib = GlobalAlloc(GMEM_FIXED,dwLen); if (!hDib){
SelectPalette(hdc,hPal,FALSE);
::ReleaseDC(NULL,hdc);
return NULL;
} lpbi = (LPBITMAPINFOHEADER)hDib; *lpbi = bi; // call getdibits with a NULL lpbits param, so the device driver
// will calculate the bisizeimage field
GetDIBits(hdc, bitmap, 0L, (DWORD)bi.biHeight,
(LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS ); bi = *lpbi; // if the driver did not fill in the bisizeimage field, then compute it
// each scan line of the image is aligned on a dword (32bit) boundary
if (bi.biSizeImage == 0)
{
bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8)
* bi.biHeight;
} // realloc the buffer so that it can hold all the bits
dwLen += bi.biSizeImage;
if (handle = GlobalReAlloc(hDib, dwLen, GMEM_MOVEABLE))
hDib = handle;
else
{
GlobalFree(hDib); // reselect the original palette
SelectPalette(hdc,hPal,FALSE);
::ReleaseDC(NULL,hdc);
return NULL;
} // get the bitmap bits
lpbi = (LPBITMAPINFOHEADER)hDib; // finally get the dib
BOOL bgotbits = GetDIBits( hdc, bitmap,
0L, // start scan line
(DWORD)bi.biHeight, // # of scan lines
(LPBYTE)lpbi // address for bitmap bits
+ (bi.biSize + ncolors * sizeof(RGBQUAD)),
(LPBITMAPINFO)lpbi, // address of bitmapinfo
(DWORD)DIB_RGB_COLORS); // use rgb for color table if( !bgotbits )
{
GlobalFree(hDib);
SelectPalette(hdc,hPal,FALSE);
::ReleaseDC(NULL,hdc);
return NULL;
} SelectPalette(hdc,hPal,FALSE);
::ReleaseDC(NULL,hdc);
return hDib;
}void CNetControlView::SetBitmap(HBITMAP bmp)
{
m_CurrentBmp = bmp;
}
#include <gdiplus.h>
#include <stdio.h>
using namespace Gdiplus;
#pragma comment (lib, "gdiplus.lib")
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
int GetEncoderClsid(LPCWSTR format, CLSID* pClsid)
{
UINT num = 0;
UINT size = 0;
ImageCodecInfo* pImageCodecInfo = NULL;
GetImageEncodersSize(&num, &size);
if(size == 0)
return -1;
pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
if(pImageCodecInfo == NULL)
return -1;
GetImageEncoders(num, size, pImageCodecInfo);
for(UINT j = 0; j < num; ++j)
{
if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
{
*pClsid = pImageCodecInfo[j].Clsid;
free(pImageCodecInfo);
return j;
}
}
free(pImageCodecInfo);
return -1;
}
// 参数
// xs = 图象x轴大小
// ys = 图象y轴大小
// quality = jpeg图象质量
VOID SaveCurScreenJpg(LPCWSTR pszFileName, int xs, int ys, int quality)
{
HWND hwnd = ::GetDesktopWindow();
HDC hdc = GetWindowDC(NULL);
int x = GetDeviceCaps(hdc, HORZRES);
int y = GetDeviceCaps(hdc, VERTRES);
HBITMAP hbmp = ::CreateCompatibleBitmap(hdc, x, y), hold;
HDC hmemdc = ::CreateCompatibleDC(hdc);
hold = (HBITMAP)::SelectObject(hmemdc, hbmp);
BitBlt(hmemdc, 0, 0, x, y, hdc, 0, 0, SRCCOPY);
SelectObject(hmemdc, hold);
{
Bitmap bit(xs, ys), bit2(hbmp, NULL);
Graphics g(&bit);
g.ScaleTransform((float)xs/x, (float)ys/y);
g.DrawImage(&bit2, 0, 0);
CLSID encoderClsid;
EncoderParameters encoderParameters;
encoderParameters.Count = 1;
encoderParameters.Parameter[0].Guid = EncoderQuality;
encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
encoderParameters.Parameter[0].NumberOfValues = 1;
encoderParameters.Parameter[0].Value = &quality;
GetEncoderClsid(L"image/jpeg", &encoderClsid);
bit.Save(pszFileName, &encoderClsid, &encoderParameters);
}
::DeleteObject(hbmp);
::DeleteObject(hmemdc);
return;
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
::SaveCurScreenJpg(L".\\cap.400.300.30.jpg", 400, 300, 30);
::SaveCurScreenJpg(L".\\cap.800.600.100.jpg", 800, 600, 100);
::SaveCurScreenJpg(L".\\cap.800.600.100.jpg", 640, 480, 50);
GdiplusShutdown(gdiplusToken);
return 0;
}
//把指定HDC存放为指定大小指定比例指定类型文件
VOID SaveHdcToImageFile(LPCWSTR pszFileName,HDC hdc, int startX, int startY, int xSize, int ySize, float fScaleX=1,float fScaleY =1, LPCWSTR format=L"image/jpeg")
{
int x = GetDeviceCaps(hdc, HORZRES);
int y = GetDeviceCaps(hdc, VERTRES);
HBITMAP hbmp = ::CreateCompatibleBitmap(hdc, x, y);
HDC hmemdc = ::CreateCompatibleDC(hdc);
HBITMAP hold = (HBITMAP)::SelectObject(hmemdc, hbmp);
BitBlt(hmemdc, 0, 0, xSize, ySize, hdc, startX, startY, SRCCOPY);
SelectObject(hmemdc, hold);
Bitmap bit(xSize*fScaleX, ySize*fScaleY);
Bitmap bit2(hbmp, NULL);
Graphics g(&bit);
g.ScaleTransform(fScaleX, fScaleY);
g.DrawImage(&bit2, 0, 0); CLSID encoderClsid; GetEncoderClsid(format, &encoderClsid);
bit.Save(pszFileName, &encoderClsid, NULL);
::DeleteObject(hbmp);
::DeleteObject(hmemdc);
return;
}