我把那位大哥的代码用到了这里,编译可通过,可是执行的时候却出错误,请各位多多指导!!菜鸟有礼了.
HBITMAP CMultimediaDoc::CopyScreenToBitmap(LPRECT lpRect)
//lpRect 代表选定区域
{
HDC hScrDC,hMemDC;
// 屏幕和内存设备描述表
HBITMAP hBitmap,hOldBitmap;
// 位图句柄
int nX,nY,nX2,nY2;
// 选定区域坐标
int nWidth,nHeight;
// 位图宽度和高度
int xScrn,yScrn;
// 屏幕分辨率
// 确保选定区域不为空矩形
if (IsRectEmpty(lpRect))
return NULL;
//为屏幕创建设备描述表
CDC pDC=AfxGetMainWnd()->GetDC();
hScrDC = pDC.GetSafeHdc();
//hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
//为屏幕设备描述表创建兼容的内存设备描述表
hMemDC = ::CreateCompatibleDC(hScrDC);
// 获得选定区域坐标
nX = lpRect->left;
nY = lpRect->top;
nX2 = lpRect->right;
nY2 = lpRect->bottom;
// 获得屏幕分辨率
xScrn = GetDeviceCaps(hScrDC, HORZRES);
yScrn = GetDeviceCaps(hScrDC, VERTRES);
//确保选定区域是可见的
if (nX < 0)
nX = 0;
if (nY < 0)
nY = 0;
if (nX2 > xScrn)
nX2 = xScrn;
if (nY2 > yScrn)
nY2 = yScrn;
nWidth = nX2 - nX;
nHeight = nY2 - nY;
// 创建一个与屏幕设备描述表兼容的位图 hBitmap = CreateCompatibleBitmap(hScrDC, nWidth, nHeight);
// 把新位图选到内存设备描述表中 hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap); // 把屏幕设备描述表拷贝到内存设备描述表中 BitBlt(hMemDC,0,0,nWidth, nHeight,hScrDC, nX, nY, SRCCOPY); //得到屏幕位图的句柄 hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap); //清除 DeleteDC(hScrDC); DeleteDC(hMemDC); // 返回位图句柄 return hBitmap;}int CMultimediaDoc::SaveBitmapToFile(HBITMAP hBitmap , LPCTSTR lpFileName) //hBitmap 为刚才的屏幕位图句柄{ //lpFileName 为位图文件名
HDC hDC;
//设备描述表
int iBits;
//当前显示分辨率下每个像素所占字节数
WORD wBitCount;
//位图中每个像素所占字节数
//定义调色板大小,位图中像素字节大小,位图文件大小,写入文件字节数
DWORD dwPaletteSize=0,
dwBmBitsSize,
dwDIBSize,
dwWritten; BITMAP Bitmap;
//位图属性结构
BITMAPFILEHEADER bmfHdr;
//位图文件头结构
BITMAPINFOHEADER bi;
//位图信息头结构
LPBITMAPINFOHEADER lpbi;
//指向位图信息头结构
HANDLE fh, hDib;HPALETTE hOldPal=NULL, hPal;
//定义文件,分配内存句柄,调色板句柄
//计算位图文件每个像素所占字节数
hDC = CreateDC("DISPLAY",NULL,NULL,NULL);
iBits = GetDeviceCaps(hDC, BITSPIXEL) *
GetDeviceCaps(hDC, PLANES);
DeleteDC(hDC);
if (iBits <= 1) wBitCount = 1; else if (iBits <= 4) wBitCount = 4; else if (iBits <= 8) wBitCount = 8; else if (iBits <= 24) wBitCount = 24; //计算调色板大小 if (wBitCount <= 8) dwPaletteSize = (1 << wBitCount)*sizeof(RGBQUAD);
//设置位图信息头结构 GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap); bi.biSize = sizeof(BITMAPINFOHEADER); bi.biWidth = Bitmap.bmWidth; bi.biHeight = Bitmap.bmHeight; bi.biPlanes = 1; bi.biBitCount = wBitCount; bi.biCompression = BI_RGB; bi.biSizeImage = 0; bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrUsed = 0; bi.biClrImportant = 0;dwBmBitsSize = ((Bitmap.bmWidth*wBitCount+31)/32)*4*Bitmap.bmHeight ;
//为位图内容分配内存 hDib=GlobalAlloc(GHND,dwBmBitsSize+dwPaletteSize+sizeof(BITMAPINFOHEADER)); lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib); *lpbi = bi; // 处理调色板 hPal =(HPALETTE) GetStockObject(DEFAULT_PALETTE); if (hPal) { hDC = GetDC(NULL); hOldPal = SelectPalette(hDC, hPal, FALSE); RealizePalette(hDC); } // 获取该调色板下新的像素值 GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight, (LPSTR)lpbi + sizeof(BITMAPINFOHEADER) +dwPaletteSize, (BITMAPINFO*) lpbi, DIB_RGB_COLORS); //恢复调色板 if (hOldPal) {
SelectPalette(hDC, hOldPal, TRUE);
RealizePalette(hDC);
ReleaseDC(NULL, hDC);
} //创建位图文件 fh = CreateFile(lpFileName, GENERIC_WRITE,
0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL |
FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (fh == INVALID_HANDLE_VALUE) return FALSE; // 设置位图文件头 bmfHdr.bfType = 0x4D42; // "BM" dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize; bmfHdr.bfSize = dwDIBSize; bmfHdr.bfReserved1 = 0; bmfHdr.bfReserved2 = 0; bmfHdr.bfOffBits = (DWORD)sizeof (BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize; // 写入位图文件头WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL); // 写入位图文件其余内容 WriteFile(fh, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL); //清除 GlobalUnlock(hDib); GlobalFree(hDib); CloseHandle(fh);
return 0;}BOOL CMultimediaDoc::OnSaveDocument(LPCTSTR lpszPathName)
{
// TODO: Add your specialized code here and/or call the base class
// HBITMAP CopyScreenToBitmap(LPRECT lpRect)
LPRECT lpRect;
lpRect->left=20;
lpRect->top=20;
lpRect->right=400;
lpRect->bottom=300;
HBITMAP map=CopyScreenToBitmap(lpRect);
SaveBitmapToFile(map,lpszPathName);
return CDocument::OnSaveDocument(lpszPathName);
}
HBITMAP CMultimediaDoc::CopyScreenToBitmap(LPRECT lpRect)
//lpRect 代表选定区域
{
HDC hScrDC,hMemDC;
// 屏幕和内存设备描述表
HBITMAP hBitmap,hOldBitmap;
// 位图句柄
int nX,nY,nX2,nY2;
// 选定区域坐标
int nWidth,nHeight;
// 位图宽度和高度
int xScrn,yScrn;
// 屏幕分辨率
// 确保选定区域不为空矩形
if (IsRectEmpty(lpRect))
return NULL;
//为屏幕创建设备描述表
CDC pDC=AfxGetMainWnd()->GetDC();
hScrDC = pDC.GetSafeHdc();
//hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
//为屏幕设备描述表创建兼容的内存设备描述表
hMemDC = ::CreateCompatibleDC(hScrDC);
// 获得选定区域坐标
nX = lpRect->left;
nY = lpRect->top;
nX2 = lpRect->right;
nY2 = lpRect->bottom;
// 获得屏幕分辨率
xScrn = GetDeviceCaps(hScrDC, HORZRES);
yScrn = GetDeviceCaps(hScrDC, VERTRES);
//确保选定区域是可见的
if (nX < 0)
nX = 0;
if (nY < 0)
nY = 0;
if (nX2 > xScrn)
nX2 = xScrn;
if (nY2 > yScrn)
nY2 = yScrn;
nWidth = nX2 - nX;
nHeight = nY2 - nY;
// 创建一个与屏幕设备描述表兼容的位图 hBitmap = CreateCompatibleBitmap(hScrDC, nWidth, nHeight);
// 把新位图选到内存设备描述表中 hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap); // 把屏幕设备描述表拷贝到内存设备描述表中 BitBlt(hMemDC,0,0,nWidth, nHeight,hScrDC, nX, nY, SRCCOPY); //得到屏幕位图的句柄 hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap); //清除 DeleteDC(hScrDC); DeleteDC(hMemDC); // 返回位图句柄 return hBitmap;}int CMultimediaDoc::SaveBitmapToFile(HBITMAP hBitmap , LPCTSTR lpFileName) //hBitmap 为刚才的屏幕位图句柄{ //lpFileName 为位图文件名
HDC hDC;
//设备描述表
int iBits;
//当前显示分辨率下每个像素所占字节数
WORD wBitCount;
//位图中每个像素所占字节数
//定义调色板大小,位图中像素字节大小,位图文件大小,写入文件字节数
DWORD dwPaletteSize=0,
dwBmBitsSize,
dwDIBSize,
dwWritten; BITMAP Bitmap;
//位图属性结构
BITMAPFILEHEADER bmfHdr;
//位图文件头结构
BITMAPINFOHEADER bi;
//位图信息头结构
LPBITMAPINFOHEADER lpbi;
//指向位图信息头结构
HANDLE fh, hDib;HPALETTE hOldPal=NULL, hPal;
//定义文件,分配内存句柄,调色板句柄
//计算位图文件每个像素所占字节数
hDC = CreateDC("DISPLAY",NULL,NULL,NULL);
iBits = GetDeviceCaps(hDC, BITSPIXEL) *
GetDeviceCaps(hDC, PLANES);
DeleteDC(hDC);
if (iBits <= 1) wBitCount = 1; else if (iBits <= 4) wBitCount = 4; else if (iBits <= 8) wBitCount = 8; else if (iBits <= 24) wBitCount = 24; //计算调色板大小 if (wBitCount <= 8) dwPaletteSize = (1 << wBitCount)*sizeof(RGBQUAD);
//设置位图信息头结构 GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap); bi.biSize = sizeof(BITMAPINFOHEADER); bi.biWidth = Bitmap.bmWidth; bi.biHeight = Bitmap.bmHeight; bi.biPlanes = 1; bi.biBitCount = wBitCount; bi.biCompression = BI_RGB; bi.biSizeImage = 0; bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrUsed = 0; bi.biClrImportant = 0;dwBmBitsSize = ((Bitmap.bmWidth*wBitCount+31)/32)*4*Bitmap.bmHeight ;
//为位图内容分配内存 hDib=GlobalAlloc(GHND,dwBmBitsSize+dwPaletteSize+sizeof(BITMAPINFOHEADER)); lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib); *lpbi = bi; // 处理调色板 hPal =(HPALETTE) GetStockObject(DEFAULT_PALETTE); if (hPal) { hDC = GetDC(NULL); hOldPal = SelectPalette(hDC, hPal, FALSE); RealizePalette(hDC); } // 获取该调色板下新的像素值 GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight, (LPSTR)lpbi + sizeof(BITMAPINFOHEADER) +dwPaletteSize, (BITMAPINFO*) lpbi, DIB_RGB_COLORS); //恢复调色板 if (hOldPal) {
SelectPalette(hDC, hOldPal, TRUE);
RealizePalette(hDC);
ReleaseDC(NULL, hDC);
} //创建位图文件 fh = CreateFile(lpFileName, GENERIC_WRITE,
0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL |
FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (fh == INVALID_HANDLE_VALUE) return FALSE; // 设置位图文件头 bmfHdr.bfType = 0x4D42; // "BM" dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize; bmfHdr.bfSize = dwDIBSize; bmfHdr.bfReserved1 = 0; bmfHdr.bfReserved2 = 0; bmfHdr.bfOffBits = (DWORD)sizeof (BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize; // 写入位图文件头WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL); // 写入位图文件其余内容 WriteFile(fh, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL); //清除 GlobalUnlock(hDib); GlobalFree(hDib); CloseHandle(fh);
return 0;}BOOL CMultimediaDoc::OnSaveDocument(LPCTSTR lpszPathName)
{
// TODO: Add your specialized code here and/or call the base class
// HBITMAP CopyScreenToBitmap(LPRECT lpRect)
LPRECT lpRect;
lpRect->left=20;
lpRect->top=20;
lpRect->right=400;
lpRect->bottom=300;
HBITMAP map=CopyScreenToBitmap(lpRect);
SaveBitmapToFile(map,lpszPathName);
return CDocument::OnSaveDocument(lpszPathName);
}
解决方案 »
- 一个读取内存并将内容显示到桌面上的程序的小问题。
- 窗口显示的问题
- 怎么 %SystemRoot% 转换成系统的目录,有没有这样的API
- 大家画流程图一般用什么工具?
- QQ群发软件的原理是什么,有哪位知道吗?高分请教!有源码的给100分!
- 如何确保一个对象在一台计算机上只有一个实例在运行?
- 求助:想做一个地址栏,类似于windows中那样
- 如何改变Button的Caption
- 求教位高手,哪位知道在VC++下如何读写硬盘的FAT和分区表,我具体应该做些什么呢?不胜感激!!!
- 我想在我的对话筐中放一个打印按钮,然后点一下,先出来预览,该怎么做
- 如何实现背景位图呀?还要带双缓冲技术。感谢!!
- "找工作,在上海,欢迎大家来坐坐,给分"新开一帖,热情欢迎大家再来坐坐^_^
=========================================================int GetDIBPixelSize(const BITMAPINFOHEADER & bmih)
{
if ( bmih.biSizeImage )
return bmih.biSizeImage;
else
return ( bmih.biWidth * bmih.biBitCount + 31 ) / 32 * 4 * bmih.biPlanes * abs(bmih.biHeight);
}int GetDIBColorCount(const BITMAPINFOHEADER & bmih)
{
if ( bmih.biBitCount <= 8 )
if ( bmih.biClrUsed )
return bmih.biClrUsed;
else
return 1 << bmih.biBitCount;
else if ( bmih.biCompression==BI_BITFIELDS )
return 3 + bmih.biClrUsed;
else
return bmih.biClrUsed;
}BOOL SaveDIBToBmp(const char* pFileName, const BITMAPINFO *pBMI, const BYTE *pBits)
{
if(pFileName==NULL){
return FALSE;
} HANDLE handle = CreateFile(pFileName, GENERIC_WRITE, FILE_SHARE_READ,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(handle == INVALID_HANDLE_VALUE){
return FALSE;
} BITMAPFILEHEADER bmFH; int nHeadSize = sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * GetDIBColorCount(pBMI->bmiHeader); bmFH.bfType = 0x4D42;
bmFH.bfSize = nHeadSize + GetDIBPixelSize(pBMI->bmiHeader);
bmFH.bfReserved1 = 0;
bmFH.bfReserved2 = 0;
bmFH.bfOffBits = nHeadSize + sizeof(BITMAPFILEHEADER); DWORD dwRead = 0;
WriteFile(handle, & bmFH, sizeof(bmFH), & dwRead, NULL); if(pBits==NULL) // packed DIB
pBits = (BYTE *) pBMI + nHeadSize;
WriteFile(handle, pBMI, nHeadSize, & dwRead, NULL);
WriteFile(handle, pBits, GetDIBPixelSize(pBMI->bmiHeader), & dwRead, NULL); CloseHandle(handle); return TRUE;
}BOOL CImageBmp::SaveFile(const char * pFileName)
{
return SaveAsBmp(pFileName);
}BITMAPINFO * BitmapToDIB(HPALETTE hPal, // palette for color conversion
HBITMAP hBmp, // DDB for convert
int nBitCount, int nCompression) // format wanted
{
typedef struct
{
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[256+3];
} DIBINFO; BITMAP ddbinfo;
DIBINFO dibinfo; // retrieve DDB information
if ( GetObject(hBmp, sizeof(BITMAP), & ddbinfo)==0 )
return NULL; // fill out BITMAPINFOHEADER based on size and required format
memset(&dibinfo, 0, sizeof(dibinfo)); dibinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
dibinfo.bmiHeader.biWidth = ddbinfo.bmWidth;
dibinfo.bmiHeader.biHeight = ddbinfo.bmHeight;
dibinfo.bmiHeader.biPlanes = 1;
dibinfo.bmiHeader.biBitCount = nBitCount;
dibinfo.bmiHeader.biCompression = nCompression; HDC hDC = GetDC(NULL); // screen DC
HGDIOBJ hpalOld;
if ( hPal )
hpalOld = SelectPalette(hDC, hPal, FALSE);
else
hpalOld = NULL; // query GDI for image size
GetDIBits(hDC, hBmp, 0, ddbinfo.bmHeight, NULL, (BITMAPINFO *) & dibinfo, DIB_RGB_COLORS); int nInfoSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * GetDIBColorCount(dibinfo.bmiHeader);
int nTotalSize = nInfoSize + GetDIBPixelSize(dibinfo.bmiHeader); BYTE * pDIB = new BYTE[nTotalSize]; if ( pDIB )
{
memcpy(pDIB, & dibinfo, nInfoSize);
if ( ddbinfo.bmHeight != GetDIBits(hDC, hBmp, 0, ddbinfo.bmHeight, pDIB + nInfoSize, (BITMAPINFO *) pDIB, DIB_RGB_COLORS) )
{
delete [] pDIB;
pDIB = NULL;
}
} if ( hpalOld )
SelectObject(hDC, hpalOld); ReleaseDC(NULL, hDC); return (BITMAPINFO *) pDIB;
}
HBITMAP CaptureWindow(HWND hWnd)
{
RECT wnd; if ( ! GetWindowRect(hWnd, & wnd) )
return NULL; HDC hDC = GetWindowDC(hWnd); HBITMAP hBmp = CreateCompatibleBitmap(hDC, wnd.right - wnd.left, wnd.bottom - wnd.top); if ( hBmp )
{
HDC hMemDC = CreateCompatibleDC(hDC);
HGDIOBJ hOld = SelectObject(hMemDC, hBmp); BitBlt(hMemDC, 0, 0, wnd.right - wnd.left, wnd.bottom - wnd.top,
hDC, 0, 0, SRCCOPY); SelectObject(hMemDC, hOld);
DeleteObject(hMemDC);
}
ReleaseDC(hWnd, hDC); return hBmp;
}void SaveWindowToFile(HWND hWnd, const char *filename, int nBitCount, int nCompression)
{
HBITMAP hBmp = CaptureWindow(hWnd); if(hBmp)
{
BITMAPINFO * pDIB = BitmapToDIB(NULL, hBmp, nBitCount, nCompression);
if(pDIB)
{
SaveDIBToBmp(filename, pDIB, NULL);
delete [](BYTE *) pDIB;
}
DeleteObject(hBmp);
}
}