首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在打印机上打印DIB后台缓冲区- GDI,MFC

如何在打印机上打印DIB后台缓冲区- GDI,MFC
EN

Stack Overflow用户
提问于 2012-01-26 14:32:24
回答 1查看 1.3K关注 0票数 1

我使用MFC的doc/view架构来实现打印。我使用双缓冲,我把所有的东西都画到我的后台缓冲区,也就是DIB位图。而不是使用StretchBlt将DIB复制到打印机DC。

奇怪的是-打印预览工作得很好!当我在虚拟PDF打印机上打印时,它工作得很好!但是当我在实际的打印机上打印时(我在两台不同的打印机上测试--相同的结果)--它只是打印“垃圾”。“垃圾”意味着有时它打印完全黑色的页面,有时它重复打印前几页,即打印错误的DIB部分,就像我把坐标弄糟到StretchBlt,但我没有搞砸任何事情,我检查了多次,加上为什么打印预览是完美的?

我尝试了许多变体:

当printing.

  • Using内存DC兼容打印机DC,并选择my时,
  1. 使用与打印机DC兼容的存储器DC,
  2. 使用与打印机DC兼容的存储器DC,并使用专用DIB复制原来的后台缓冲区DIB。

等人

但结果是一样的。下面是我创建DIB的代码。我认为DIB格式可能是问题所在,所以如果有什么问题,请提出建议。我尝试了24位和32位作为bmiHeader.biBitCount的值。

代码语言:javascript
复制
// 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的代码(这里没有什么特别的):

代码语言:javascript
复制
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。问题还是一样的!下面是我目前使用的代码:

代码语言:javascript
复制
// 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)打印机一起工作,当它在实际打印机上打印时失败。搞什么鬼?..。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-01-26 18:41:44

确保一次不会将DIBSECTION选择到多个DC中。会导致各种不可预测的行为。

对于打印,如果让bmipBitmapRawBits保持在方便的位置,您可能可以完全绕过内存DC。确保DIBSECTION没有被选中到任何DC中,然后调用SetDIBitsToDeviceStretchDIBits将图像传输到打印机DC。

如果您仍然有问题,您可能需要检查您的打印机的功能。并非所有驱动程序都支持所有位图传输方法。我相信印刷系统应该对你隐瞒这些差异,但也许不是。打电话给打印机DC上的GetDeviceCaps,检查RASTERCAPS上的RC_BITBLT和朋友。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9019645

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档