MFC документ / вид архитектуры, GDI рисунок / печать.У меня есть буфер DIB, который мне нужно отобразить и напечатать.
После долгой и мучительной дороги я пришел к выводу, что мне нужно использовать DIB, созданный с помощью CreateDIBSection (а не DDB, созданный с помощью CreateCompatibleBitmap), и у меня естьперетащить его на принтер постоянного тока с помощью StretchDIBits (а не StretchBlt).
Но я не могу заставить эту вещь работать.
Вот что я делаю:
В моей подпрограмме инициализации я установил backbuffer, как это:
// Prepare device context:
CClientDC aDC(this);
OnPrepareDC(&aDC);
// Setup proper backbuffer:
_pMemDc = new CDC;
_pMemDc->CreateCompatibleDC(&aDC);
memset(&_bitmapInfo, 0, sizeof(BITMAPINFO));
_bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
_bitmapInfo.bmiHeader.biWidth = _sizeBackBuffer.cx;
_bitmapInfo.bmiHeader.biHeight = -_sizeBackBuffer.cy; // top-down
_bitmapInfo.bmiHeader.biPlanes = 1;
_bitmapInfo.bmiHeader.biBitCount = 24; // Maybe 32?
_bitmapInfo.bmiHeader.biCompression = BI_RGB;
HANDLE hMemBitmap = CreateDIBSection(aDC.GetSafeHdc(), &_bitmapInfo, DIB_RGB_COLORS, (void**)&_pBitmapRawBits, 0, 0);
_hOldSelBitmap = (HBITMAP)_pMemDc->SelectObject(hMemBitmap);
Переменные с подчеркиванием являются (приватными) переменными-членами, объявленными так:
CDC *_pMemDc; // Backbuffer memory dc
HBITMAP _hOldSelBitmap;
BITMAPINFO _bitmapInfo; // Backbuffer DIB (header-only)
unsigned char *_pBitmapRawBits; // Pointer to pixel data of DIB
SIZE _sizeBackBuffer; // Size of backbuffer, i.e. size of that DIB
Теперь вот чтоЯ делаю в своем переопределении OnDraw:
Сначала я получаю область, которая будет нарисована следующим образом (упрощенный код):
CRect rectClipBoxPlayground;
if (pDC->IsPrinting())
{
rectClipBoxPlayground = _printingParams.pPrintInfo->m_rectDraw;
}
else
{
pDC->GetClipBox(&rectClipBoxPlayground);
}
Затем я вычисляю соответствующие прямоугольные координаты в моем буфере, которыйобычно (намного) больше, чем DC.Детали этого вычисления здесь не имеют значения, я просто говорю, что
CRect rectClipBoxBackBuffer;
представляет соответствующий прямоугольник backbuffer (в пиксельных координатах backbuffer).
Затем я рисую на свой backbuffer, используя_pMemDc memory dc.
И, наконец, наступает момент, когда у меня возникают проблемы: перетаскивание моего DIB на целевой dc (экран или принтер).Вот что я делаю:
// Copy back buffer to screen/printer dc:
pDC->SetStretchBltMode(HALFTONE);
SetBrushOrgEx(pDC->GetSafeHdc(), 0, 0, 0);
// BELOW COMMENTED CODE OF StretchBlt WORKS(!) INSTEAD OF StretchDIBits.
//
//BOOL bSuccess = pDC->StretchBlt(rectClipBoxPlayground.left, rectClipBoxPlayground.top,
// rectClipBoxPlayground.Width(), rectClipBoxPlayground.Height(),
// _pMemDc, rectClipBoxBackBuffer.left, rectClipBoxBackBuffer.top,
// rectClipBoxBackBuffer.Width(), rectClipBoxBackBuffer.Height(), SRCCOPY);
HBITMAP hMemBitmap = (HBITMAP)_pMemDc->SelectObject(_hOldSelBitmap);
DWORD dwLines = StretchDIBits(pDC->GetSafeHdc(),
rectClipBoxPlayground.left, rectClipBoxPlayground.top, rectClipBoxPlayground.Width(), rectClipBoxPlayground.Height(),
rectClipBoxBackBuffer.left, rectClipBoxBackBuffer.top, rectClipBoxBackBuffer.Width(), rectClipBoxBackBuffer.Height(),
_pBitmapRawBits, &_bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
_pMemDc->SelectObject(hMemBitmap);
Проблема в том, что закомментированный код StretchBlt работает безупречно (за исключением печати на некоторых принтерах), но я не могу использовать его, потому что у некоторых принтеров есть проблемы с ним,Поэтому я должен использовать StretchDIBits.Обратите внимание, что сначала я временно отменяю выбор DIB из его памяти dc, чтобы он не был связан ни с одним dc.Тогда я использую StretchDIBits, но все просто не работает!Вывод искажен, как будто я даю неправильные координаты, области отведены от места, где они должны быть нарисованы, и иногда полностью черные.Так что я должен что-то упустить (может быть, что-то очень тривиальное).Помогите!Я попытался изменить знаки rectClipBoxBackBuffer.top и bitmapInfo.bmiHeader.biHeight, результаты изменились, но ничего не работает, как должно.
Что я делаю не так ?? *