Я использую архитектуру doc / view MFC для реализации печати.Я использую двойную буферизацию, все рисую на свой буфер, который является битовой картой DIB.Чем я использую StretchBlt, чтобы скопировать этот DIB на принтер DC.
Странная вещь - предварительный просмотр печати работает хорошо!Когда я печатаю на виртуальном принтере PDF, он работает хорошо!Но когда я печатаю на реальном принтере (я тестирую на двух разных принтерах - одинаковые результаты) - он просто печатает «мусор».«Мусор» означает, что иногда он печатает полностью черную страницу, иногда он печатает несколько первых страниц несколько раз, то есть печатает неправильную часть DIB, как если бы я перепутал координаты с StretchBlt, но я ничего не испортил, я проверилнесколько раз, плюс почему тогда предварительный просмотр печати работает безупречно?
Я перепробовал множество вариантов:
- Использование памяти DC, совместимой с экраном DC, при печати.
- Используя DC памяти, совместимый с DC принтера, и выбирая в него мой DIB.
- Используя DC памяти, совместимый с DC принтера, и используя выделенный 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)
также 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) принтером, сбой при печати на реальном принтере.Что за черт? ....