//文件头赋值
BITMAPFILEHEADER   p_fileheader;
p_fileheader.bfType =((WORD) ('M' << 8) | 'B');
p_fileheader.bfReserved1 =0;
p_fileheader.bfReserved2 =0;
p_fileheader.bfOffBits  =14+40; BITMAPINFOHEADER BMI;
BMI.biSize = sizeof(BITMAPINFOHEADER);
BMI.biPlanes = 1;
BMI.biCompression = BI_RGB;   // No compression
BMI.biXPelsPerMeter = 0;
BMI.biYPelsPerMeter = 0;
BMI.biClrUsed = 0;            // Always use the whole palette.
BMI.biClrImportant = 0; 
BMI.biBitCount = 24 ;
BMI.biWidth = 80;             //已经为4字节的倍数。
BMI.biHeight = 10;
BMI.biSizeImage =80*10*3;     //疑问:vc数字图像处理中的做 
                             // 法为80*10。但我估计有错。但换成80*10也不对 p_fileheader.bfSize=p_fileheader.bfOffBits+BMI.biSizeImage; //生成黑色的DIB图像
HGLOBAL hDib;
hDib = ::GlobalAlloc(GHND,p_fileheader.bfSize);
PBYTE pDib = (PBYTE)::GlobalLock(hDib);
memcpy(pDib,&p_fileheader,14);
memcpy(&pDib[14],&BMI,40);
::GlobalUnlock(hDib);
//Copy到剪贴板
OpenClipboard();
EmptyClipboard();
SetClipboardData(CF_DIB,hDib);
CloseClipboard(); //错误现象:当用Win2k的画图程序中的“编辑”菜单中的“粘贴”时报告或得剪贴板数据出错。
请问错误原因。

解决方案 »

  1.   

    BMI.biPlanes = 3;
    24位真彩色的位面数为3
      

  2.   

    HDC hWndDC = NULL;
    HDC hMemDC = NULL;
    HBITMAP hMemBmp = NULL;
    HBITMAP hOldBmp = NULL;
    RECT rect;
    int w = 0, h = 0; if(hWnd == NULL)
    {
    hWnd = ::GetDesktopWindow();
    }
    hWndDC = ::GetWindowDC(hWnd);
    hMemDC = ::CreateCompatibleDC(hWndDC);
    ::GetWindowRect(hWnd, &rect);
    w = rect.right - rect.left;
    h = rect.bottom - rect.top; hMemBmp = ::CreateCompatibleBitmap(hWndDC, w, h); hOldBmp = (HBITMAP)::SelectObject(hMemDC, hMemBmp);
    ::BitBlt(hMemDC, 0, 0, w, h, hWndDC, 0, 0, SRCCOPY); hMemBmp = (HBITMAP)::SelectObject(hMemDC, hOldBmp); ::DeleteObject(hOldBmp);
    ::ReleaseDC(NULL, hMemDC);
    ::ReleaseDC(NULL, hWndDC); return hMemBmp;
      

  3.   

    int nSize = GlobalSize(hDib);
    memcpy(chData, &nSize, sizeof(int));
    int cx = sz.cx;
    int cy = sz.cy;
    memcpy(chData+sizeof(int), &cx, sizeof(int));
    memcpy(chData+sizeof(int)*2, &cy, sizeof(int));
      

  4.   

    1.biPlans=1;有的地方说必须为1,有的没说但只用了1,真彩也没有问题呀。2. Puppyfly(清清世界):嗯,你说的是从CDC生成BITMAP,其实从CDC用HBITMAP hMemBmp = CreateDIBSection函数生成BITMAP,后我都再CDC上将之画出来了,但就是不能用SetClipboardData(CF_DIB,hMemBmp);或者SetClipboardData(CF_BITMAP,hMemBmp),copy到剪贴板上,说获得剪贴板数据出错。我估计错误在于hMemBmp中没有对BITMAPFILEHEADER块赋值。
      

  5.   

    补充说明:在VIEW的OnDraw()中
    添加代码段,然后在//Copy到剪贴板OpenClipboard();
    前添加如下代码,可以将图像画出来的呀,可是贴到剪贴板就出错了,气死我了。哪位解救解救我呀
    ::StretchDIBits(pDC-〉m_hDC,0,0,BMI.biWidth,BMI.biHeight,0,0,BMI.biWidth,BMI.biHeight,&pDib[54],(BITMAPINFO*)&BMI,DIB_RGB_COLORS,SRCCOPY);
      

  6.   

    先回去睡觉,下午在来试试Puppyfly(清清世界)之法
      

  7.   

    我已经测试成功了,可以的按照我写的办法然后调用
    //Copy到剪贴板
    OpenClipboard();
    EmptyClipboard();
    SetClipboardData(CF_DIB,hDib);
    CloseClipboard();
    关闭程序后在画图工具中粘贴成功。我的测试样例流程是这样的:得到windows屏幕BMP-->>>转换BMP到DIB,-->>>copy到剪贴板-->>>打开画图,粘贴-->>>成功
      

  8.   

    //lpRect is screen coodinate of the clip rect of screen
    //if lpRect == NULL, function will capture window Focus
    HBITMAP CopyScreenToBitmap(LPRECT lpRect, CWnd *Focus)
    {
    HDC hdcScrn, hdcMem; 
    HBITMAP hBitmap, hOldBitmap; 
    int nx, ny, nx2, ny2; 
    int nwidth, nheight; 
    int xscrn, yscrn;  hdcScrn = CreateDC("DISPLAY", NULL, NULL, NULL);
    hdcMem = CreateCompatibleDC(hdcScrn);
    xscrn = GetDeviceCaps (hdcScrn, HORZRES);
    yscrn = GetDeviceCaps (hdcScrn, VERTRES);

    if(lpRect != NULL) 
    {  
    nx = lpRect->left;
    ny = lpRect->top;
    nx2 = lpRect->right;
    ny2 = lpRect->bottom;
    if (nx<0)
    nx = 0;
    if (ny<0)
    ny = 0;
    if (nx2>xscrn)
    nx2 = xscrn;
    if (ny2>yscrn)
    ny2 = yscrn;
    nwidth = nx2 - nx;
    nheight = ny2 - ny;
    }
    else
    {
    nwidth = xscrn;
    nheight= yscrn;
    nx = 0;
    ny = 0;
    }
    hBitmap = CreateCompatibleBitmap(hdcScrn, nwidth, nheight);
    //select bitmap into memdc
    hOldBitmap = (HBITMAP)SelectObject(hdcMem, hBitmap);
    //copy screendc to memdc
    BitBlt(hdcMem, 0, 0, nwidth, nheight,hdcScrn, nx, ny, SRCCOPY);
    //select back old bitmap
    hBitmap = (HBITMAP)SelectObject(hdcMem, hOldBitmap);
    if (Focus->OpenClipboard()) 
    {
    EmptyClipboard();
    SetClipboardData(CF_BITMAP, hBitmap);
    CloseClipboard();
    }
    // CBitmap* bmp = CBitmap::FromHandle(hBitmap);
    // BITMAP bmpInfo;
    // bmp->GetBitmap(&bmpInfo);
    DeleteDC(hdcScrn);
    DeleteDC(hdcMem);
    return hBitmap;
    }
      

  9.   

    我的可能繁琐了一些,只是把BMP转换成DIB,下面是函数:
    HDIB WINAPI _BmpToDIB(HBITMAP hBitmap, HPALETTE hPal, int nBits)
    {
        BITMAP              bm;
        BITMAPINFOHEADER    bi;
        LPBITMAPINFOHEADER  lpbi;
        DWORD               dwLen;
        HANDLE              hDIB, h;
        HDC                 hDC;
        WORD                biBits;    if(!hBitmap)
            return NULL;    if(!GetObject(hBitmap, sizeof(bm), (LPSTR)&bm))
            return NULL;
        if (hPal == NULL)
            hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE);
        biBits = bm.bmPlanes * bm.bmBitsPixel;
        if (biBits <= 1)
            biBits = 1;
        else if (biBits <= 4)
            biBits = 4;
        else if (biBits <= 8)
            biBits = 8;
        else
            biBits = 24;
    if(nBits != -1)
    {
    if(nBits == 1 || nBits == 4 || nBits == 8 || nBits == 24)
    {
    biBits = nBits;
    }
    }
        bi.biSize = sizeof(BITMAPINFOHEADER);
        bi.biWidth = bm.bmWidth;
        bi.biHeight = bm.bmHeight;
        bi.biPlanes = 1;
        bi.biBitCount = biBits;
        bi.biCompression = BI_RGB;
        bi.biSizeImage = 0;
        bi.biXPelsPerMeter = 0;
        bi.biYPelsPerMeter = 0;
        bi.biClrUsed = 0;
        bi.biClrImportant = 0;
        dwLen = bi.biSize + PL_PaletteSize((LPBYTE)&bi);    hDC = GetDC(NULL);
        hPal = SelectPalette(hDC, hPal, FALSE);
        RealizePalette(hDC);
        hDIB = GlobalAlloc(GHND, dwLen);
        if (!hDIB)
        {
          SelectPalette(hDC, hPal, TRUE);
          RealizePalette(hDC);
          ReleaseDC(NULL, hDC);
          return NULL;
        }
        lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
        *lpbi = bi;
        GetDIBits(hDC, hBitmap, 0, (UINT)bi.biHeight, NULL, (LPBITMAPINFO)lpbi,
            DIB_RGB_COLORS);
        bi = *lpbi;
        GlobalUnlock(hDIB);    if (bi.biSizeImage == 0)
            bi.biSizeImage = WIDTHBYTES((DWORD)bm.bmWidth * biBits) * bm.bmHeight;
        dwLen = bi.biSize + PL_PaletteSize((LPBYTE)&bi) + bi.biSizeImage;    if (h = GlobalReAlloc(hDIB, dwLen, 0))
            hDIB = h;
        else
        {
            GlobalFree(hDIB);
            hDIB = NULL;
            SelectPalette(hDC, hPal, TRUE);
            RealizePalette(hDC);
            ReleaseDC(NULL, hDC);
            return NULL;
        }
        lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
        if (GetDIBits(hDC, hBitmap, 0, (UINT)bi.biHeight, (LPSTR)lpbi +
                (WORD)lpbi->biSize + PL_PaletteSize((LPBYTE)lpbi), (LPBITMAPINFO)lpbi,
                DIB_RGB_COLORS) == 0)
        {
            GlobalUnlock(hDIB);
            hDIB = NULL;
            SelectPalette(hDC, hPal, TRUE);
            RealizePalette(hDC);
            ReleaseDC(NULL, hDC);
            return NULL;
        }    bi = *lpbi;
        GlobalUnlock(hDIB);
        SelectPalette(hDC, hPal, TRUE);
        RealizePalette(hDC);
        ReleaseDC(NULL, hDC);    return (HDIB) hDIB;
    }
      

  10.   

    前提是已经得到HBITMAP对象,看看有没有用处。
      

  11.   

    这么一个小问题,这么多高手都搞不定?
    我觉得问题出在SetClipboardData(CF_DIB,hDib);
    如果用CF_DIB就不用把BitmapFile header copy 到 hDib中
    就是说 memcpy(&pDib[0],&BMI,40);
    ::GlobalUnlock(hDib);
    //Copy到剪贴板
    OpenClipboard();
    EmptyClipboard();
    SetClipboardData(CF_DIB,hDib);
    CloseClipboard();
    就可以了!
      

  12.   

    或者把SetClipboardData(CF_DIB,hDib);
    改成SetClipboardData(CF_BITMAP,hDib);我想也可以!
      

  13.   

    Puppyfly 果然是高手,领悟能力太强了,
    他明白了,
    你明白了吗?