Re: печать и dc печати
От: savosin_sergey  
Дата: 07.12.04 12:04
Оценка: 1 (1)
косвенно отвечаю на вопрос:
-----------------------------
я как-то делал печать из досовских текстовых файлов (с псевдографикой) на принтер. у меня получились две версии печати: 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
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.