图片在内存中,但是没句柄的,只有bmp的数据,现在需要显示在窗口上,请问如何做到?
写了一点比较蠢的测试代码
HBITMAP hbmp,hbmp2;//全部定义两遍
BITMAP  bmp,bmp2;
HDC     hDc,hDc2;
hbmp=(HBITMAP)::LoadImage( NULL,"abc.BMP", IMAGE_BITMAP, 0,0,    LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE );
hDc=::CreateCompatibleDC(NULL);
::SelectObject(hDc,hbmp);
::GetObject(hbmp,sizeof(BITMAP),&bmp);//至此,位图数据已经存在于bmp结构中,也有hbmp,但是我现在不能用句柄来“画”
hbmp2=::CreateBitmapIndirect(&bmp);//hbmp2是从bmp里面copy来的
hDc2=::CreateCompatibleDC(NULL);
::SelectObject(hDc2,hbmp2);
::GetObject(hbmp2,sizeof(BITMAP),&bmp2);
//执行到这里,我觉得,bmp和bmp2的内容是一样的
//(但是bmp2的bmBits是0,里面的数据是有的,这点我也理解)
//http://topic.csdn.net/t/20020710/22/864960.html 关于这点微软的技术支持解释的很清楚,我也没疑问,现在的问题是

//如果我执行这一句代码,绝对没问题,界面上显示位图了,因为我用的源是hdc
::BitBlt(this->GetDC()->m_hDC,10,10,bmp.bmWidth,bmp.bmHeight,hDc,0,0,SRCCOPY);
//但是如果我执行的是这句代码,就啥也不显示了,因为用的源是hDc2
::BitBlt(this->GetDC()->m_hDC,10,10,bmp.bmWidth,bmp.bmHeight,hDc2,0,0,SRCCOPY);
我想要的结果就是不用hdc 而用hdc2画出来,因为我的程序本身是通过网络传送数据,把位图的结构bmp数据的传送到客户端,客户端再把bmp内容画在界面上,
以上代码只是为了说明这样的问题,不知如何做,希望有人详细指点,谢谢

解决方案 »

  1.   

    有BMP数据,可以用下面的函数得到HBITMAPThe SetDIBits function sets the pixels in a bitmap using the color data found in the specified DIB . int SetDIBits(
      HDC hdc,                  // handle to DC
      HBITMAP hbmp,             // handle to bitmap
      UINT uStartScan,          // starting scan line
      UINT cScanLines,          // number of scan lines
      CONST VOID *lpvBits,      // array of bitmap bits
      CONST BITMAPINFO *lpbmi,  // bitmap data
      UINT fuColorUse           // type of color indexes to use
    );
      

  2.   

    直接用FillRect填充,不过图片是颠倒的,你需要颠倒下行序
    CDC* pDC = GetDC();
    RECT rc;
    CBitmap cBM;
    CBrush cBr;
    rc.top = 0;
    rc.left = 0;
    rc.bottom = PIC_HEIGHT;
    rc.right = PIC_WIDTH;
    cBM.CreateBitmap(PIC_WIDTH, PIC_HEIGHT, 1, 32, pBuf);  //图片宽高,色深,buffer
    cBr.CreatePatternBrush(&cBM);
    cBM.DeleteObject();
    pDC->FillRect(&rc, &cBr);
    ReleaseDC(pDC);
      

  3.   

    如果需要缩放,用StretchDIBits。
      

  4.   

    To cnzdgs 麻烦进一步指点 我SetDIBitsToDevice在这里该如何使用?我写了好象没反映,仍旧啥都不显示
      

  5.   

    应该是你第一个图位句柄(hbmp)被选进去了的原因吧,你可以使用CopyImage复制一个位图的副本出来再进行其它操作.
      

  6.   

    你直接把文件abc.BMP传过去,这样对方收到的就是已经加载到内存的文件了,再按照bmp文件格式来解析,然后显示
      

  7.   

    hbmp2=::CreateBitmapIndirect(&bmp);//hbmp2是从bmp里面copy来的
    你的bmp没有跟hbmp2关联,是空的,所以显示不了图片.
    应该先bmp.Attach(hbmp),再调用hbmp2=::CreateBitmapIndirect(&bmp);//
      

  8.   

    CreateBitmapIndirect调用完之后再
    SetBitmapBits
      

  9.   

    定义一个LPBITMAPINFO pbmi。根据位图信息进行pbmi设置,然后用SetDIBitsToDevice,呵呵。
      

  10.   

    HBITMAP hbmp,hbmp2;
    BITMAP  bmp,bmp2;
    HDC     hDc,hDc2;
    hbmp=(HBITMAP)::LoadImage( NULL,"abc.BMP", IMAGE_BITMAP, 0,0,    LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE );
    hDc=::CreateCompatibleDC(NULL);
    ::SelectObject(hDc,hbmp);
    ::GetObject(hbmp,sizeof(BITMAP),&bmp);
    hbmp2=::CreateBitmapIndirect(&bmp);
    ::SetBitmapBits(hbmp2,bmp.bmWidth*bmp.bmHeight,bmp.bmBits);////新加的,是否用法不对?hDc2=::CreateCompatibleDC(NULL);
    ::SelectObject(hDc2,hbmp2);
    ::GetObject(hbmp2,sizeof(BITMAP),&bmp2);
    bmp2.bmBits=bmp.bmBits;::BitBlt(this->GetDC()->m_hDC,10,10,bmp.bmWidth,bmp.bmHeight,hDc2,0,0,SRCCOPY);
      

  11.   

    上面代码的 bmp2.bmBits=bmp.bmBits; 这句去掉,我是指一下试试看的,不用写
      

  12.   

    CBitmap m_bitmap[4]; 
    CStatic m_static;
    m_bitmap[0].LoadBitmap(IDB_BITMAP1);  //加载图像
    m_static.Create("",WS_CHILD|WS_VISIBLE|SS_BITMAP,
    CRect(20,20,50,50),this,201);  //创建static控件
    m_static.SetBitmap((HBITMAP)m_bitmap[0]);  //再static控件上显示图片 
      

  13.   

    BITMAPINFO   binfo;   
     
    HBITMAP hbmp,hbmp2;
        BITMAP  bmp,bmp2;
        HDC     hDc,hDc2;
        hbmp=(HBITMAP)::LoadImage( NULL,"abc.BMP", IMAGE_BITMAP, 0,0,    LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE );
        hDc=::CreateCompatibleDC(NULL);
        ::SelectObject(hDc,hbmp);
        ::GetObject(hbmp,sizeof(BITMAP),&bmp);
    hbmp2=::CreateBitmap( bmp.bmWidth, bmp.bmHeight,1,24, &bmp);
    hDc2=::CreateCompatibleDC(NULL);
    ::SelectObject(hDc2,hbmp2);
    ::GetObject(hbmp2,sizeof(BITMAP),&bmp2);
      ZeroMemory(&binfo,sizeof(BITMAPINFO));   
      binfo.bmiHeader.biBitCount=24; //24bit像素格式   
      binfo.bmiHeader.biCompression=0;   
      binfo.bmiHeader.biHeight=bmp.bmHeight;   
      binfo.bmiHeader.biPlanes=1;   
      binfo.bmiHeader.biSizeImage=0;
      binfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
      binfo.bmiHeader.biWidth=bmp.bmWidth;
    ::SetDIBits(hDc2,hbmp2,1000,1000,bmp2.bmBits,&binfo,DIB_RGB_COLORS);//我是用的SetDIBits ,貌似也不行,1000我随便写写,没用bmwidth height,好像写了也一样不行    ::BitBlt(this->GetDC()->m_hDC,10,10,bmp.bmWidth,bmp.bmHeight,hDc2,0,0,SRCCOPY);
      

  14.   

    上面这些代码并没有使用SetDIBitsToDevice或StretchDIBits,如果要把内存数据直接画到窗口上,这两个函数是最直接的方法。
      

  15.   

    还是不行,算了,不弄了,结吧,呵呵::StretchDIBits(this->GetDC()->m_hDC,0,0,bmp.bmWidth,bmp.bmHeight,0,0,bmp.bmWidth,bmp.bmHeight,bmp2.bmBits,&binfo,DIB_RGB_COLORS, SRCCOPY);