//文件头赋值
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的画图程序中的“编辑”菜单中的“粘贴”时报告或得剪贴板数据出错。
请问错误原因。
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的画图程序中的“编辑”菜单中的“粘贴”时报告或得剪贴板数据出错。
请问错误原因。
24位真彩色的位面数为3
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;
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));
添加代码段,然后在//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);
//Copy到剪贴板
OpenClipboard();
EmptyClipboard();
SetClipboardData(CF_DIB,hDib);
CloseClipboard();
关闭程序后在画图工具中粘贴成功。我的测试样例流程是这样的:得到windows屏幕BMP-->>>转换BMP到DIB,-->>>copy到剪贴板-->>>打开画图,粘贴-->>>成功
//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;
}
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;
}
我觉得问题出在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();
就可以了!
改成SetClipboardData(CF_BITMAP,hDib);我想也可以!
他明白了,
你明白了吗?