我正在使用MFC的doc/view體系結構來實現打印。我使用雙緩衝,我將所有東西都繪製到我的後臺緩衝區,這是DIB位圖。比我使用StretchBlt將該DIB複製到打印機DC上。如何在打印機上打印DIB backbuffer - GDI,MFC
奇怪的是 - 打印預覽效果很好!當我在虛擬PDF打印機上打印時,它運行良好!但是當我在實際打印機上打印時(我正在測試兩臺不同的打印機 - 相同的結果) - 它只是打印「垃圾」。 「垃圾」有時意味着它會打印完全黑色的頁面,有時它會重複打印前幾頁,即它會打印DIB的錯誤部分,就像我將座標搞亂到StretchBlt一樣,但我沒有弄亂任何東西,我檢查了多次,再加上爲什麼打印預覽工作完美無瑕呢?
我嘗試了許多變化:
- 使用內存DC兼容屏幕DC,打印時。
- 使用與打印機DC兼容的內存DC,並選擇我的DIB。
- 使用與打印機DC兼容的內存DC,並使用專用的DIB將複製我的原始backbuffer DIB的專用DIB。 等
但結果是一樣的。下面是我創建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)
是也是如此。
更新:Adrian的評論後,我改變了我的代碼使用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)打印機一起工作,在實際打印機上打印時失敗。這到底是什麼?......
您需要使用設備兼容的位圖而不是我猜測的DIB。 –
我無法使用CreateCompatibleBitmap,因爲它對於大型位圖而言失敗。 –