急!火烧眉毛!截取屏幕保存为16色BMP文件 代码有错,请大哥看看 100分相送!不够再给
//该函数为截取屏幕保存到文件,该函数没有问题,但转16色的函数调用不成功!
int SaveClientToFile(HWND hWnd, LPCTSTR szFName)
{
HDC hDC, hMemDC,hDC1;
HANDLE hBits, hFile;
HBITMAP hBitmap, hTmpBmp,hBitmap1;
HPALETTE hPal;
LPVOID lpBits;
RGBQUAD RGBQuad;
DWORD ImgSize, plSize, dwWritten;
int i, CRes, Height, Width;
BITMAPFILEHEADER bmFH;
LPBITMAPINFO pBmInfo, pBmInfoMem;
LPLOGPALETTE lp;
if((hFile = CreateFile(szFName, GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL)) == NULL)
return 1; //按照参数szFName指定的路径创建文件
//SetCursor(LoadCursor(NULL, IDC_WAIT)); if(hWnd==HWND_DESKTOP)
{
Width = GetSystemMetrics(SM_CXSCREEN);
Height = GetSystemMetrics(SM_CYSCREEN);
}
else
{
RECT rc;
GetClientRect(hWnd,&rc);
Width = rc.right-rc.left;
Height = rc.bottom-rc.top;
}
hDC = GetDC(hWnd); //获取指定的DC
hDC1 = CreateDC( "DISPLAY ", NULL, NULL, NULL);
hMemDC = CreateCompatibleDC(hDC);
//hBitmap1= CreateCompatibleBitmap(hDC, Width, Height);
hBitmap = ColorBitmap(hDC1,hBitmap1,1);
//!!!★这里调用转16色的函数,但没用,转不过来
hTmpBmp= CreateCompatibleBitmap(hDC, 8, 8);
pBmInfoMem = (LPBITMAPINFO)GlobalAlloc(GHND, sizeof(BITMAPINFO)+256*sizeof(RGBQUAD));
pBmInfo = (LPBITMAPINFO)GlobalLock(pBmInfoMem);
SelectObject(hMemDC, hBitmap);
BitBlt(hMemDC,0,0,Width,Height,hDC,0,0,SRCCOPY);
SelectObject(hMemDC, hTmpBmp);
ZeroMemory(pBmInfo, sizeof(BITMAPINFO));
pBmInfo-> bmiHeader.biSize = (DWORD)sizeof(BITMAPINFOHEADER);
pBmInfo-> bmiHeader.biWidth = Width;
pBmInfo-> bmiHeader.biHeight = Height;
pBmInfo-> bmiHeader.biPlanes = 1;
pBmInfo-> bmiHeader.biBitCount = (WORD)GetDeviceCaps(hDC, BITSPIXEL);
pBmInfo-> bmiHeader.biCompression = BI_RGB;
//pBmInfo-> bmiHeader.biCompression = BI_RLE8;
GetDIBits(hDC, hBitmap, 0,Height, NULL, pBmInfo, DIB_RGB_COLORS);
if(!pBmInfo-> bmiHeader.biSizeImage)
pBmInfo-> bmiHeader.biSizeImage = ((((pBmInfo-> bmiHeader.biWidth * pBmInfo-> bmiHeader.biBitCount) + 31) & ~31) / 8)
* pBmInfo-> bmiHeader.biHeight;
CRes = GetDeviceCaps(hDC, SIZEPALETTE);
plSize = CRes*sizeof(RGBQUAD);
ImgSize= pBmInfo-> bmiHeader.biSizeImage;
bmFH.bfType = 0x4d42; // "BM "
bmFH.bfOffBits = plSize + sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER);
bmFH.bfSize = ImgSize + bmFH.bfOffBits;
bmFH.bfReserved1 = 0;
bmFH.bfReserved2 = 0;
WriteFile(hFile, &bmFH, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
WriteFile(hFile, &(pBmInfo-> bmiHeader), sizeof(BITMAPINFOHEADER), &dwWritten, NULL);
if(CRes)
{
hPal=(HPALETTE)GlobalAlloc(GHND, sizeof(LOGPALETTE) + (CRes*sizeof(PALETTEENTRY)));
lp=(LPLOGPALETTE)GlobalLock(hPal);
lp-> palNumEntries=(WORD)CRes;
lp-> palVersion=0x0300;
GetSystemPaletteEntries(hDC, 0, CRes, lp-> palPalEntry);
RGBQuad.rgbReserved=0;
for(i=0; i <CRes; i++)
{
RGBQuad.rgbRed = lp-> palPalEntry[i].peRed;
RGBQuad.rgbGreen = lp-> palPalEntry[i].peGreen;
RGBQuad.rgbBlue = lp-> palPalEntry[i].peBlue;
WriteFile(hFile, &RGBQuad, sizeof(RGBQUAD), &dwWritten, NULL);
}
GlobalUnlock(hPal);
GlobalFree(hPal);
}
hBits = GlobalAlloc(GHND, pBmInfo-> bmiHeader.biSizeImage);
lpBits = (LPVOID)GlobalLock(hBits);
GetDIBits(hDC, hBitmap, 0,Height, lpBits, pBmInfo, DIB_RGB_COLORS);
WriteFile(hFile,lpBits,ImgSize,&dwWritten,NULL);
GlobalUnlock(hBits);
GlobalFree(hBits);
GlobalUnlock(pBmInfo);
GlobalFree(pBmInfoMem);
DeleteObject(hTmpBmp);
DeleteObject(hBitmap);
DeleteDC(hMemDC);
ReleaseDC(hWnd,hDC);
CloseHandle(hFile);
//SetCursor(LoadCursor(NULL,IDC_ARROW));
return 0;
}
//转16色的函数
HBITMAP ColorBitmap(HDC hdc,HBITMAP hBmpSrc,UINT nColor)
{
HBITMAP hCreate = NULL;
char * lpHeader = NULL;
char * lpBits = NULL;
__try{
__try{
BITMAP bmp;
if(GetObject(hBmpSrc,sizeof(BITMAP),&bmp) == 0){
__leave;
}
BITMAPINFOHEADER bmpInfo;
memset(&bmpInfo,0,sizeof(BITMAPINFOHEADER));
bmpInfo.biSize = sizeof(BITMAPINFOHEADER);
bmpInfo.biWidth = bmp.bmWidth;
bmpInfo.biHeight = bmp.bmHeight;
bmpInfo.biPlanes = 1;
//设置新的位图的颜色数
//可以设置的数值有
//1 - 2色
//4 - 16色
//8 - 256色
//16 - 16位色
//24 - 24位色
bmpInfo.biBitCount = nColor;
//256色(包含256)以下的位图需要调色版,
//下面是计算所需调色版空间大小
int nHeadSize = nColor > 8 ? 0 : 1 < < nColor;
nHeadSize *= sizeof(RGBQUAD);
//加上位图信息头的空间大小
nHeadSize += sizeof(BITMAPINFOHEADER);
//为信息头和调色版分配空间
lpHeader = new char[nHeadSize];
BITMAPINFOHEADER * lpBmpInfo =
(BITMAPINFOHEADER *)lpHeader;
* lpBmpInfo = bmpInfo;
//GetBIBits 取得存储位图数据所需空间
if(::GetDIBits(hdc,
hBmpSrc,
0, //数据开始的扫描线,从0开始
bmp.bmHeight,//数据结束的扫描线,位图高
NULL, //数据存储缓冲区,= NULL则会返需求量
(LPBITMAPINFO)lpBmpInfo,
DIB_RGB_COLORS) == 0)
{
__leave;
}
//为位图数据分配空间
lpBits = new char[lpBmpInfo-> biSizeImage];
//GetBIBits 取得存储位图数据
if(::GetDIBits(hdc,
hBmpSrc,
0,
bmp.bmHeight,
lpBits,
(LPBITMAPINFO)lpBmpInfo,
DIB_RGB_COLORS) == 0)
{
__leave;
}
//生成新位图
hCreate = ::CreateCompatibleBitmap(hdc , bmp.bmWidth, bmp.bmHeight);
if(hCreate == NULL){
__leave;
}
//将位图数据写入新位图中
::SetDIBits(hdc,
hCreate,
0,
bmp.bmHeight,
lpBits,
(LPBITMAPINFO)lpBmpInfo,
DIB_RGB_COLORS);
}__except(EXCEPTION_EXECUTE_HANDLER){
__leave;
}
}__finally{
if(lpHeader != NULL){
delete [] lpHeader;
}
if(lpBits != NULL){
delete [] lpBits;
}
}
return hCreate;
}
[解决办法]
查查MSDN吧,GDI容易搞定的!
[解决办法]
这个单步调试下就知道哪里出错了,遇到问题时就跳进去看看。
[解决办法]
hBitmap = ColorBitmap(hDC1,hBitmap1,1);
改成
hBitmap = ColorBitmap(hDC1,hBitmap1,4);
试试
[解决办法]
谢谢lz,我也正在学习中
[解决办法]
用IPicture吧
[解决办法]
你用api转效果是差点,要想效果好自己写转16位的算法吧。
要不就用Gdiplus