我使用MFC的doc/view架构来实现打印。我使用双缓冲,我把所有的东西都画到我的后台缓冲区,也就是DIB位图。而不是使用StretchBlt将DIB复制到打印机DC。
奇怪的是-打印预览工作得很好!当我在虚拟PDF打印机上打印时,它工作得很好!但是当我在实际的打印机上打印时(我在两台不同的打印机上测试--相同的结果)--它只是打印“垃圾”。“垃圾”意味着有时它打印完全黑色的页面,有时它重复打印前几页,即打印错误的DIB部分,就像我把坐标弄糟到StretchBlt,但我没有搞砸任何事情,我检查了多次,加上为什么打印预览是完美的?
我尝试了许多变体:
当printing.
等人
但结果是一样的。下面是我创建DIB的代码。我认为DIB格式可能是问题所在,所以如果有什么问题,请提出建议。我尝试了24位和32位作为bmiHeader.biBitCount的值。
// Setup proper backbuffer:
_CleanupBackBufferStuff();
_pMemDc = new CDC;
_pMemDc->CreateCompatibleDC(&aDC);
BITMAPINFO bmi;
memset(&bmi, 0, sizeof(BITMAPINFO));
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = _sizeBackBuffer.cx;
bmi.bmiHeader.biHeight = -_sizeBackBuffer.cy; // top-down
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 24; // Tried 32 as well
bmi.bmiHeader.biCompression = BI_RGB;
unsigned char *pBitmapRawBits = 0;
HANDLE hMemBitmap = CreateDIBSection(aDC.GetSafeHdc(), &bmi, DIB_RGB_COLORS, (void**)&pBitmapRawBits, 0, 0);
_hOldSelBitmap = (HBITMAP)_pMemDc->SelectObject(hMemBitmap);这里还有StretchBlt的代码(这里没有什么特别的):
pDC->SetStretchBltMode(HALFTONE);
SetBrushOrgEx(pDC->GetSafeHdc(), 0, 0, 0);
BOOL bSuccess = pDC->StretchBlt(rectClipBoxPlayground.left, rectClipBoxPlayground.top, rectClipBoxPlayground.Width(), rectClipBoxPlayground.Height(),
_pMemDc, rectClipBoxBackBuffer.left, rectClipBoxBackBuffer.top, rectClipBoxBackBuffer.Width(), rectClipBoxBackBuffer.Height(), SRCCOPY);StretchBlt返回true,(pDC->GetDeviceCaps(RASTERCAPS) & RC_STRETCHBLT)也是true。
更新:禤浩焯发表评论后,我将代码更改为使用StretchDIBits。问题还是一样的!下面是我目前使用的代码:
// Copy back buffer to screen dc:
pDC->SetStretchBltMode(HALFTONE);
SetBrushOrgEx(pDC->GetSafeHdc(), 0, 0, 0);
HBITMAP hMemBitmap = (HBITMAP)_pMemDc->SelectObject(_hOldSelBitmap);
DWORD dwLines = StretchDIBits(pDC->GetSafeHdc(),
rectClipBoxPlayground.left, rectClipBoxPlayground.top, rectClipBoxPlayground.Width(), rectClipBoxPlayground.Height(),
rectClipBoxBackBuffer.left, _sizeBackBuffer.cy - rectClipBoxBackBuffer.top - rectClipBoxBackBuffer.Height(), rectClipBoxBackBuffer.Width(), rectClipBoxBackBuffer.Height(),
_pBitmapRawBits, &_bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
_pMemDc->SelectObject(hMemBitmap);它仍然表现为源坐标不正确。它要么打印前几页中的一个(无论我选择什么页面),要么打印几乎完全黑色的页面。打印预览是完美的工作,所以这使我认为应该没有问题,我的坐标计算代码。它在预览中工作,它与虚拟(pdf)打印机一起工作,当它在实际打印机上打印时失败。搞什么鬼?..。
发布于 2012-01-26 18:41:44
确保一次不会将DIBSECTION选择到多个DC中。会导致各种不可预测的行为。
对于打印,如果让bmi和pBitmapRawBits保持在方便的位置,您可能可以完全绕过内存DC。确保DIBSECTION没有被选中到任何DC中,然后调用SetDIBitsToDevice或StretchDIBits将图像传输到打印机DC。
如果您仍然有问题,您可能需要检查您的打印机的功能。并非所有驱动程序都支持所有位图传输方法。我相信印刷系统应该对你隐瞒这些差异,但也许不是。打电话给打印机DC上的GetDeviceCaps,检查RASTERCAPS上的RC_BITBLT和朋友。
https://stackoverflow.com/questions/9019645
复制相似问题