首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

急火烧眉毛!截取屏幕保存为16色BMP文件 代码有错,请大哥看看 100分相送!不够再给,该如何处理

2012-01-15 
急!火烧眉毛!截取屏幕保存为16色BMP文件 代码有错,请大哥看看 100分相送!不够再给//该函数为截取屏幕保存

急!火烧眉毛!截取屏幕保存为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

热点排行