косвенно отвечаю на вопрос:
-----------------------------
я как-то делал печать из досовских текстовых файлов (с псевдографикой) на принтер. у меня получились две версии печати: 1) работает долго, но печатает на всех принтерах (на hp pcl6 тоже!). 2) работает быстро, но не на всяких принтерных драйверах работает StretchBlt(..) -- например, на hp 1000 laserjet. Но это лечится установкой PS-драйвера! (обычно к принетру есть несколько версий драйверов)
Правда, битмапы я не печатал (а только текст, хоть и ДОСовсктй (OEM)), но первый случай именно с печатью битмапа и связан:
1. вывод текста на контекст, совместимый с экраном ->hDcScr
2. копирование hDcScr на контекст, совместимый с hDcScr ->hDcScr2
3. копирование hDcScr2 на контекст, совместимый с контекстом принтера, т.е. с hDcPrn -> hDcPrn2
4. копирование hDcPrn2 на контекст принтера, то есть на hDcPrn
то есть задействовано 4 контекста, из них один (hDcPrn — получаемый при соединении с принтером) -- получаемый, и три -- создаваемых:
hDcScr=CreateCompatibleDC(GetDC(hWnd)));
hDcScr2=CreateCompatibleDC(hDcScr);
hDcPrn2=CreateCompatibleDC(hDcPrn);
общая схема такая: битмап можно отправить на любой капризный принтер через промежуточное копирование между СОВМЕСТИМЫМИ контекстами (hDcScr2 и hDcPrn2):
int PagePrnCalls(HDC hDcPrn){
HDC hDc, hDcScr, hDcScr2, hDcPrn2;
HBITMAP hBmTmp, hBmTmp2, hBmTmp3;
HGDIOBJ hObj1, hObj2;
int iWidth, iHeight;
//размеры листа на принтере с учётом всяких полей:
physW=GetDeviceCaps(hDcPrn, PHYSICALWIDTH);
physH=GetDeviceCaps(hDcPrn, PHYSICALHEIGHT);
hDc=GetDC(hWnd); //hWnd - дескриптор главного окна приложения (можно попробовать hWnd=NULL)
hDcScr=CreateCompatibleDC(hDc);
ReleaseDC(hWnd, hDc);
hBmTmp=CreateCompatibleBitmap(hDcScr, iWidth, iHeight);
hObj1=SelectObject(hDcScr, hBmTmp);
PatBlt(hDcScr, 0, 0, iWidth, iHeight, PATCOPY); //очищение битмапа
//..здесь происходит вывод всякого барахла на hDcScr (соответственно, на первый рабочий битмап hBmTmp)
//, типа TextOut и прочее.. можно и свой битмап StretchBlt-нуть
hDcScr2=CreateCompatibleDC(hDcScr);
hBmTmp2=CreateCompatibleBitmap(hDcScr2, iWidth, iHeight); //второй рабочий битмап
hObj2=SelectObject(hDcScr2, hBmTmp2);
StretchBlt(hDcScr2, 0, 0, jWidth, jHeight, hDcScr, 0, 0, iWidth, iHeight, SRCCOPY); //копирование на второй битмап
SelectObject(hDcScr, hObj1);
DeleteObject(hBmTmp); //удаление первого раб. бмп.
DeleteDC(hDcScr);
hDcPrn2=CreateCompatibleDC(hDcPrn);
hBmTmp3=CreateCompatibleBitmap(hDcPrn2, iWidth, iHeight);//наконец, третий рабочий бмп.
hObj1=SelectObject(hDcPrn2, hBmTmp3);
StretchBlt(hDcPrn2, 0, 0, kWidth, kHeight, hDcScr2, 0, 0, iWidth, iHeight, SRCCOPY);
SelectObject(hDcScr2, hObj2); //удаление второго раб. бмп.
DeleteObject(hBmTmp2);
DeleteDC(hDcScr2);
//и только теперь вывод на принтер!
StretchBlt(hDcPrn, 0, 0, iWidth, iHeight, hDcPrn2, 0, 0, iWidth, iHeight, SRCCOPY);
SelectObject(hDcPrn2, hObj1);
DeleteObject(hBmTmp3);
DeleteDC(hDcPrn2);
return 0
}
во второй версии, в кот. печать проходит быстро, я всё барахло (TextOut в основном) делаю сразу на контекст принтера..
----------------------------------
отвечаю непосредственно на вопрос:
сдаётся мне (могу ошибиться), что контекст экрана необходим только CreateCompatibleBitmap -- какая-то проблема в несовместимости палитры экрана и принтера (а ведь твой bmp имеет палитру экрана! смотришь ты его на экране! у меня был как-то dib-файл, так его даже на разных экранах не удавалось просмотреть, хотя dib=аппаратно-независимый растр). поэтому можно сделать два StretchBmp:
1. на контекст(с выбранным в него bitmap'ом), совместимый с экраном
2. скопировать результат на контекст, совместимый с принтером..
тогда, (я думаю), палитра правильно зальётся
хотя, если и так всё работает.. чего мешать
---------------------
Кстати: функция BitBlt() работает намного дольше, чем StretchBlt