if (loadimage(_T("ClockBackchain.png"), &lpData, &nSize, &nHeight, &nWidth, &nPitch))
{
CDC dcMemory;
CBitmap bitmap;
CBitmap *oldbitmap; if (bitmap.CreateBitmap(nWidth, nHeight, 1, 24, (void *)lpData))
{
dcMemory.CreateCompatibleDC(pDC);
oldbitmap = dcMemory.SelectObject(&bitmap);
pDC->BitBlt(0, 0, nWidth, nHeight, &dcMemory, 0, 0, SRCCOPY);
bitmap.DeleteObject();
dcMemory.SelectObject(oldbitmap);
dcMemory.DeleteDC();
}
CString tmp;
tmp.Format("%d", GetLastError());
AfxMessageBox(tmp);

free(lpData);
}其中loadimage里,我用了第三方库...
&lpData, &nSize, &nHeight, &nWidth, &nPitch))
lpData是像素矩阵,已经对齐.上下不变..
nSize已不用
nPitch指的是一行的像素数..(扫描线)其实,也没用了我可以确保,像素是对的.都是对的.(像素我用ULTRAEDIT看过了)
为什么,CreateBitmap一直返回错先谢谢各位了

解决方案 »

  1.   

    对可不保证满足CreateBitmap的要求,你读入的象素格式是什么样的?
      

  2.   

    我读入的是png用第三方库,转为BMP..(内存中)
    那个函数之后,传出来的是四字节对齐的,像素矩阵..高宽都对.可以保证是24位
      

  3.   

    宽、高是多少,太大了可能资源不足,失败时GetLastError看看错误码是多少。
    另外你后面的代码也有问题:
    如果运行环境的显示模式不是24色,SelectObject会失败;
    当位图被SelectObject之后,DeleteObject会失败;
    CDC、CBitmap类在析构时会自动做清理,使用局部对象不需要自己DeleteDC、DeleteObject。
      

  4.   

    宽高都是628
    错误码是0
    不过,,刚才,我改为了32
    也就是说那个函数里面..也改32了..
    可以了...晕倒.可是,哪位能讲下,为什么24位不行吗?
    还有CreateBitmap第三个参数为什么,,一定设1吗?
    还有..SelectObject 之后,,DeleteObject没有失败.
    我已经把那一句改在最后了.非常感谢两位.
    万分感谢.
      

  5.   

    CreateBitmap创建的是DDB(设备相关位图),因此对于像素阵列数据的组织形式与DIB有不同,具体说来,有:
    1)扫描行从上至下
    2)每扫描行按字(16bits)对齐!CreateBitmap的最后一个参数接受的应该是一个DDB的内存像素阵列指针,单色的话还好说,但若要是彩色的,经验说明,似乎传递按照一般DIB的数据结构都会错误。总之,这个函数只适合用来创建单色DDB,不适合用来创建初始化彩色的DDB。若要创建初始化彩色的DDB,需要另一个函数:CreateDIBitmap。这个函数从DIB(就是楼主调用的第三方库返回的数据)创建DDB。可以满足要求。还有一种方法,就是直接创建DIB,这样避免了调用CreateDIBitmap过程中因为顾及设备兼容带来的色彩失真。这个函数是CreateDIBSection。因此,楼主可以从这几方面入手Debug。
    以上是个人的一些愚见,希望能给楼主以启发。
      

  6.   

    --〉5楼
    因为CreateBitmap创建的是DDB,就是和你目前的显示相关的,一般我们的Windows的显示属性中的颜色质量都是32位,所以这个函数的第4个参数必须要和这个兼容。楼主可以把桌面颜色质量改为24位(有的话)试试,原来的参数24的估计就可以正常创建了。
      

  7.   

    Windows NT 对于已经选入场景的GDI对象可以调用DeleteObject,并且可以成功运行。
      

  8.   

    还有能给个
    CreateDIBSection的例子吗?
      

  9.   

    宽、高都很小,应该创建不会失败,你是调试发现CreateBitmap失败的吗?
    位图颜色位数必须与显示设备一致,SelectObject才能成功。
    “SelectObject之后,DeleteObject没有失败”,如果SelectObject失败了,DeleteObject就不会失败。
      

  10.   

    CreateBitmap失败的时候,进不去..后面的没执行.成功的时候,是可以删的..而且不错..返回值是1
    我刚试过
      

  11.   

    “位图颜色位数必须与显示设备一致,SelectObject才能成功”记得好像不是这样,我就用CreateBitmap创建过单色位图,在32位显示环境中,选入场景后绘制正常。
      

  12.   

    一个用CreateDIBSection创建32*32的32位位图的代码段DWORD nWidth = 32;
    DWORD nHeight = 32;
    PVOIL pBits = NULL;
    BITMAPINFO bi;
    bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bi.bmiHeader.biWidth = nWidth;
    bi.bmiHeader.biHeight = nHeight;
    bi.bmiHeader.biPlanes = 1;
    bi.bmiHeader.biBitCount = 32;
    bi.bmiHeader.biCompression = BI_RGB;
    bi.bmiHeader.biSizeImage = nHeight * nWidth * 4;
    CreateDIBSection(NULL, &bi, DIB_RGB_COLORS, &pBits, NULL, NULL);每行是4字节对齐的,32位的比较简单,对于其它色深,通用公式(设置biSizeImage):
    BytesPerScanLine = 4 * ((nWidth * nBitCount + 31) / 32)
      

  13.   

    结帖够快的,再补充说明一下:MSDN的CGdiObject::DeleteObject说明中提到:
    An application should not call DeleteObject on a CGdiObject object that is currently selected into a device context.
    这句话只说不要删除选入DC的对象,“删除会失败”是自己得出的结论,可能不是所有情况都失败的。MSDN的CreateBitmap说明中提到:
    However, the bitmap can only be selected into a device context if the bitmap and the DC have the same format.
    我以前试过256色以上的位图都必须与系统的显示模式的颜色位数相同才行,单色估计不太可能用到,所以没试。