[align=left] BITMAPINFO bmi;
::ZeroMemory(&bmi.bmiHeader, sizeof(BITMAPINFOHEADER));
DWORD biSizeImage = iWidth*iHeight*64;
bmi.bmiHeader.biWidth = iWidth;
bmi.bmiHeader.biHeight = -(iHeight); //negative indicate top down, not bottom up
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biSizeImage = biSizeImage; 
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biClrUsed = 0;
bmi.bmiHeader.biClrImportant = 0;
bmi.bmiHeader.biCompression = BI_RGB;
VOID *pvBits;
TCHAR szName[]=TEXT("MyFileMappingObject"); DWORD biBufferSize = biSizeImage + iWidth*64;


HANDLE _hFile = CreateFile("test.bmp", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(!_hFile)
return NULL;

HANDLE hMap=CreateFileMapping(_hFile, NULL, PAGE_READWRITE|SEC_COMMIT, 0, biBufferSize,szName);
if (hMap != NULL) 
{
        // We might have a winner
        if (GetLastError() == ERROR_ALREADY_EXISTS) { 
            CloseHandle(hMap); 
        } else {
}
} //HANDLE hMap=CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, biBufferSize,szName);

if(_hFile)
{
CloseHandle(_hFile);
_hFile = NULL;
}

LPVOID   pBuffer   =   MapViewOfFile(hMap,   FILE_MAP_WRITE,   0,   0,   biSizeImage);   
if(pBuffer == NULL)
{
DWORD ErrNo = GetLastError();
}


HBITMAP hBitmap = ::CreateDIBSection(iHDC, &bmi, DIB_RGB_COLORS, &pvBits, hMap, 0); if(hBitmap == NULL)
{
DWORD ErrNo = GetLastError();
} UnmapViewOfFile(pBuffer);
CloseHandle(hMap);
if(_hFile)
CloseHandle(_hFile);
return hBitmap;
使用以上代码用内存映射的方法,创建一个大的位图,如果位图的尺寸太大的话,MapViewOfFile和CreateDIBSection都会失败,请各位专家指教,这时应该怎么处理?

解决方案 »

  1.   

    iWidth*iHeight*64为何要乘64?32位色只占4字节,改成4。
      

  2.   

    我的目的是想将几个图片合并到一个大图片去并保存到文件,如果是位图的话,可能有两到三GB。最开始我也是用的是4,但因为所需内存还是太大,也一样不成功,通过查网上资料说MapViewOfFile遵从64字节对齐方式,所以才改成64试试。
      

  3.   

    用64你的位图结构就已经错了,所以CreateDIBSection会失败。
    因为你CreateFile指定CREATE_ALWAYS参数,文件是新创建的,大小是0,所以MapViewOfFile会失败。
      

  4.   

    但我如果将位图的大小调小的话就都能成功,所以应该不是这些参数的问题,而是所创建的内存映射文件太大。
    比如说我将iWidth和iHeight的大小都设为1024*1024的话就都能成功,但设成10240*10240就不行。
      

  5.   

    刚验证了一下,文件大小不足时系统会自动增大文件,所以不是文件大小的问题。因为MSDN中有一段话:“An attempt to map a file with a length of 0 (zero) fails with an error code of ERROR_FILE_INVALID. Applications should test for files with a length of 0 (zero) and reject those files.”所以我一直以为文件大小必须足够才可以。这样看来你遇到的问题应该是磁盘空间不足,CreateFileMapping的时候要把文件大小调到参数中给出的尺寸,磁盘空间不足则失败。
    另外,你在CreateFileMapping用if (hMap != NULL)判断的如果成功,这时再GetLastError是没有意义的。
      

  6.   

    CreateFileMapping我测试过,一直都是成功的,不成功的是MapViewOfFile和CreateDIBSection。
    并且CreateFile,调用后,在硬盘上也能找到相映的文件,以及大小也是我所创建的大小。
      

  7.   

    如果你用10240*10240*64结果是6400MB,大于4GB了,超出了DWORD变量的保存范围。
      

  8.   

    谢谢cnzdgs!
    今天验证了一下:
    bmi.bmiHeader.biSizeImage   =   biSizeImage;确实有问题,
    改为:
    bmi.bmiHeader.biSizeImage   =   0;就可以。
    结贴。