各位大侠,我用的是wince系统。在执行下面的程序时,一旦点击保存按钮button1,调用Save32BitmapToFile,就会弹出对话框,说out of memory.是不是程序中位图头文件的大小设置的问题?对这个不是很懂,请指教。
    void Cwince位图Dlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
Save32BitmapToFile(hBitmap,TEXT("aa.bmp"));}int Cwince位图Dlg::Save32BitmapToFile(HBITMAP hBitmap, LPCTSTR lpFileName)
{
HWND hWnd = ::FindWindow(NULL,L"wince位图");
    if ( IsWindow( hWnd ) )
    {
       hdc = ::GetDC( hWnd ); // 得到指定主窗口的DC,主窗口改名字,这里也得改
    }

HDC hOffDC=CreateCompatibleDC(hdc);
    SelectObject(hOffDC,hBitmap);//将兼容窗口句柄存到hBitmap中
    
    BITMAP Bitmap;
    GetObject(hBitmap,sizeof(BITMAP),&Bitmap);
    
    HANDLE fh=CreateFile  (lpFileName,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,NULL);
    if(fh == INVALID_HANDLE_VALUE )
        return FALSE;    BITMAPFILEHEADER bfh;
    memset(&bfh,0,sizeof(bfh));
    bfh.bfType=0x4D42/*((WORD) ('M' << 8) | 'B')*/;//是"BM"类型的意思
    //bfh.bfSize= sizeof(bfh)+4*Bitmap.bmWidth*Bitmap.bmHeight+sizeof(BITMAPFILEHEADER);
bfh.bfSize= sizeof(bfh)+(Bitmap.bmWidth*Bitmap.bmHeight)/8;
    bfh.bfOffBits=sizeof(BITMAPINFOHEADER)+sizeof(BITMAPFILEHEADER);
    
    DWORD dwWritten=0;
    WriteFile(fh,&bfh,sizeof(bfh),&dwWritten,NULL);
    BITMAPINFOHEADER bih;
    memset(&bih,0,sizeof(bih));
    bih.biSize=sizeof(bih);
    bih.biWidth=Bitmap.bmWidth;
    bih.biHeight=Bitmap.bmHeight;
    bih.biPlanes=1;
    bih.biBitCount=8;
    bih.biCompression=BI_BITFIELDS;        if( !WriteFile(fh,&bih,sizeof(bih),&dwWritten,NULL))
    {
        return FALSE;
    }
    
    BITMAPINFO bitmapInfo;
    memset((void *)&bitmapInfo,0,sizeof(BITMAPINFO));
    bitmapInfo.bmiHeader=bih;
    bitmapInfo.bmiColors[0].rgbRed=255;
    bitmapInfo.bmiColors[0].rgbGreen=255;
    bitmapInfo.bmiColors[0].rgbBlue=255;        HDC hMemDC=CreateCompatibleDC(hdc);    
    //BYTE *m_lpBitBmp=new BYTE[4*Bitmap.bmWidth*Bitmap.bmHeight];
BYTE *m_lpBitBmp=new BYTE[Bitmap.bmWidth*Bitmap.bmHeight];
    HBITMAP hDibBitmap=CreateDIBSection(hMemDC,&bitmapInfo,DIB_RGB_COLORS,(void **)&m_lpBitBmp,NULL,0);
    if(hDibBitmap != 0)
    {
        ::SelectObject(hMemDC,hDibBitmap);
        BitBlt(hMemDC,0,0,Bitmap.bmWidth,Bitmap.bmHeight,hOffDC,0,0,SRCCOPY);
        //WriteFile(fh,m_lpBitBmp,4*Bitmap.bmWidth*Bitmap.bmHeight,&dwWritten,NULL);
WriteFile(fh,m_lpBitBmp,Bitmap.bmWidth*Bitmap.bmHeight,&dwWritten,NULL);
    }
    
    DeleteObject(hDibBitmap);
    DeleteDC(hdc);
    DeleteDC(hMemDC);    CloseHandle(fh); return 0;
}

解决方案 »

  1.   

    调色板好像也没有设置啊。
    这样不够啊。
    bitmapInfo.bmiColors[0].rgbRed=255; 
        bitmapInfo.bmiColors[0].rgbGreen=255; 
        bitmapInfo.bmiColors[0].rgbBlue=255;    
      

  2.   

    Save32BitmapToFile()函数的问题吧,我刚刚完成一个wince保存位图的函数,发给你试试
      

  3.   

    哦,搞错了,我这是个抓屏函数,不过你可以参考一下,做一些修改就可以了
    void OnScreenSave(const char *filename,HDC  hScrDC)

    HDC  hMemDC;         
    int  width, height; 
     
    //指向象素缓冲
    BYTE  *lpBitmapBits = NULL; 
            
    //创建设备上下文
    //hScrDC = CreateDC(_T("DISPLAY"), NULL, NULL, NULL);  //屏幕大小
    width = GetDeviceCaps(hScrDC, HORZRES);
    height = GetDeviceCaps(hScrDC, VERTRES);  //内存DC
    hMemDC = CreateCompatibleDC(hScrDC);  //初始化 BITMAPINFO
    //为了在WINCE上使用 CreateDIBSection ,每个象素都存储为24位,且无压缩biCompression=0) 
    BITMAPINFO RGB24BitsBITMAPINFO; 
    ZeroMemory(&RGB24BitsBITMAPINFO, sizeof(BITMAPINFO));
    RGB24BitsBITMAPINFO.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    RGB24BitsBITMAPINFO.bmiHeader.biWidth = width;
    RGB24BitsBITMAPINFO.bmiHeader.biHeight = height;
    RGB24BitsBITMAPINFO.bmiHeader.biPlanes = 1;
    RGB24BitsBITMAPINFO.bmiHeader.biBitCount = 24; //使用 CreateDIBSection 建立一个HBITMAP,以获得 图像数据指针 lpBitmapBits 
    HBITMAP directBmp = CreateDIBSection(hMemDC, (BITMAPINFO*)&RGB24BitsBITMAPINFO, 
    DIB_RGB_COLORS, (void **)&lpBitmapBits, NULL, 0);
    //SelectObject 将directBmp选入内存DC
    HGDIOBJ previousObject = SelectObject(hMemDC, directBmp);  //将屏幕DC拷贝到内存DC
    BitBlt(hMemDC, 0, 0, width, height, hScrDC, 0, 0, SRCCOPY); //if you only want to get the every pixel color value, 
    //you can begin here and the following part of this function will be unuseful;
    //the following part is in order to write file;  //位图文件头
    BITMAPFILEHEADER bmBITMAPFILEHEADER;
    ZeroMemory(&bmBITMAPFILEHEADER, sizeof(BITMAPFILEHEADER));
    bmBITMAPFILEHEADER.bfType = 0x4d42;  //bmp  
    bmBITMAPFILEHEADER.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
    bmBITMAPFILEHEADER.bfSize = bmBITMAPFILEHEADER.bfOffBits + ((width*height)*3); ///3=(24 / 8) //写入文件
    FILE *mStream = NULL;
    if((mStream = fopen(filename, "wb")))
    {  
    //写文件头
    fwrite(&bmBITMAPFILEHEADER, sizeof(BITMAPFILEHEADER), 1, mStream);
    //写位图信息
    fwrite(&(RGB24BitsBITMAPINFO.bmiHeader), sizeof(BITMAPINFOHEADER), 1, mStream);
    //写象素值
    fwrite(lpBitmapBits, 3*width*height, 1, mStream);
    //关闭文件
    fclose(mStream);
    } //释放资源
    DeleteObject(hMemDC);
    DeleteObject(hScrDC);
    DeleteObject(directBmp);
    DeleteObject(previousObject);
      

  4.   

    我将BYTE *m_lpBitBmp=new BYTE[Bitmap.bmWidth*Bitmap.bmHeight];改成BYTE *m_lpBitBmp;就不会报错了。可是还是只有文件,没有内容。
     
    谢谢各位,我先试试hhwei1985的方法。
      

  5.   

    非常非常感谢hhwei1985,你的程序可以用,把窗口句柄改成我需要的控件句柄就行了。可是我的程序问题还是没有解决啊!!
    帖子再留两天,希望大家关注~~