печать картинки API-ыми функциями
От: viya  
Дата: 05.03.03 12:57
Оценка:
Доброе время суток всем!

у меня старая проблемка
вот кусочек кода вывод на печать картинки API-ыми функциями

h_dc_pic:=CreateCompatibleDC(h_dc);
if SelectObject(h_dc_pic,img.Picture.Bitmap.Handle)<>0
then
StretchBlt(h_dc,0,0,picW,picH,h_dc_pic,0,0,img.Picture.Bitmap.Width,img.Picture.Bitmap.Height,SRCCOPY);
else ...
deleteDc(h_dc_pic);


так вот если на задание я отправляю больше чем 100 картинок (ну есть такая потребность скомпоновать их по особому и отправить на печать), получается этот кусок кода в цикле, то на печати где-то, наример 101 картинки, вместо картинки выходит абсолютно черный лист и прога вываливается сама по себе...без ошибки и еще чего-то там
когда печатается до 100 все нормально...но когда кол-во большое то прога может вывалится, а может и нет...что не очень притяно постоянно сопровождать своим присутствием печать....и если отправлено 230 страниц, а вывалится может где угодно, потом заново запускать не интересно....
может кто знает почему такая собенность и что за глюк, может у меня в коде....мое предположение, что
deleteDc(h_dc_pic);
не срабатывает и соответственно
h_dc_pic:=CreateCompatibleDC(h_dc);
if SelectObject(h_dc_pic,img.Picture.Bitmap.Handle)<>0......
тоже дальше не работает..но и печатал бы себе черные листы, но ведь вываливается...

жду дельных советов и предложений!
зарание спасибо
Re: печать картинки API-ыми функциями
От: DjAndy Россия  
Дата: 05.03.03 14:10
Оценка:
Ну проблема старая Ответ однозначный — хэндлы теряются. Может, и не только здесь, а здесь надо поступать так:
h_dc_pic:=CreateCompatibleDC(h_dc);
HBITMAP lbmp = SelectObject(h_dc_pic,img.Picture.Bitmap.Handle)
if (lbmp){
StretchBlt(h_dc,0,0,picW,picH,h_dc_pic,0,0,img.Picture.Bitmap.Width,img.Picture.Bitmap.Height,SRCCOPY);
SelectObject(h_dc_pic,lbmp);
}
else deleteDc(h_dc_pic);

Скорее всего должно помочь.
Re[2]: печать картинки API-ыми функциями
От: viya  
Дата: 05.03.03 14:50
Оценка:
Здравствуйте, DjAndy, Вы писали:

DA>Ну проблема старая Ответ однозначный — хэндлы теряются. Может, и не только здесь, а здесь надо поступать так:


теряются туточки я выставляла комментировать в логе и вылавливала вываливание проги тут

DA>h_dc_pic:=CreateCompatibleDC(h_dc);

DA>HBITMAP lbmp = SelectObject(h_dc_pic,img.Picture.Bitmap.Handle)
DA>if (lbmp){
DA> StretchBlt(h_dc,0,0,picW,picH,h_dc_pic,0,0,img.Picture.Bitmap.Width,img.Picture.Bitmap.Height,SRCCOPY);
DA> SelectObject(h_dc_pic,lbmp);
DA> }
DA>else deleteDc(h_dc_pic);

DA>Скорее всего должно помочь.



ты ввел ешо одну промежуточну "переменную" lbmp, а это зачем?
SelectObject(h_dc_pic,lbmp);
а что даст нам это строка? напиши плиз...мы создаем lbmp с помощью SelectObject, а потом как параметр обратно запихиваем его туда..
и немного не правильно код

else ...(и тут типа надо что-то делать если не выполнился SelectObject )
а в конце, когда картинка в принтер отправлена, я delete ее h_dc_pic
deleteDc(h_dc_pic);
ибо для печати следующей мне опять он понадобиться
Re[3]: печать картинки API-ыми функциями
От: DjAndy Россия  
Дата: 05.03.03 15:39
Оценка:
V>ты ввел ешо одну промежуточну "переменную" lbmp, а это зачем?
V> SelectObject(h_dc_pic,lbmp);
V>а что даст нам это строка? напиши плиз...мы создаем lbmp с помощью SelectObject, а потом как параметр обратно запихиваем его туда..

Смысл такой, что в мсдн есть указание:
An application should always replace a new object with the original, default object after it has finished drawing with the new object.
Это в описании SelectObject.
А зачем это делать, не сказано, но скорее всего, что в контексте теперь находится реально существующий битмап, что не позволяет корректно уничтожить контекст. SelectObject возвращает предыдущий объект заданного типа, его мы сохраняем в lbmp, а потом возвращаем обратно, и тем самым выпихиваем из контекста наш битмап. Всё, теперь имеем право уничтожить контекст. Тоже самое и с HBRUSH, HPEN и HFONT. Если много всего селектится, то имеет смысл использовать команды SaveDC и RestoreDC. Тоже самое кстати и наоборот действует, нельзя уничтожать битмап, если он заселектен в какой-нить контекст, чревато тем же боком
Удачи
Re[4]: печать картинки API-ыми функциями
От: viya  
Дата: 05.03.03 16:15
Оценка:
Здравствуйте, DjAndy, Вы писали:

DA>Удачи

спасибо! код поменяю и посмотрим...прога то уже выложена и работает буду отлавливать
Re[4]: печать картинки API-ыми функциями
От: Аноним  
Дата: 11.03.03 15:25
Оценка:
Здравствуйте, DjAndy, Вы писали:
DA>Удачи
вооооот...шо хАчу сказать...
ааааааааааа не работаИть
сделала

h_dc_pic:=CreateCompatibleDC(h_dc);
lbmp:=SelectObject(h_dc_mem,img2.Picture.Bitmap.Handle);
if lbmp<>0
then
begin
StretchBlt (h_dc,0,0,picW,picH,h_dc_mem,0,0,img2.Picture.Bitmap.Width,img2.Picture.Bitmap.Height,SRCCOPY);
SelectObject(h_dc_mem,lbmp);
end
else Log('');//запись в лог
deleteDc(h_dc_mem);

может чаго не так в коде наваяла??
Re[5]: печать картинки API-ыми функциями
От: DjAndy Россия  
Дата: 12.03.03 11:41
Оценка:
А>h_dc_pic:=CreateCompatibleDC(h_dc);
А>lbmp:=SelectObject(h_dc_mem,img2.Picture.Bitmap.Handle);
А>if lbmp<>0
А>then
А>begin
А> StretchBlt (h_dc,0,0,picW,picH,h_dc_mem,0,0,img2.Picture.Bitmap.Width,img2.Picture.Bitmap.Height,SRCCOPY);
А> SelectObject(h_dc_mem,lbmp);
А>end
А>else Log('');//запись в лог
А>deleteDc(h_dc_mem);

А>может чаго не так в коде наваяла??


Ну привет, а зачем делать так?

h_dc_pic:=CreateCompatibleDC(h_dc);
lbmp:=SelectObject(h_dc_mem,img2.Picture.Bitmap.Handle);
if lbmp<>0
...
deleteDc(h_dc_mem);

Ясное дело, что в только что созданном контексте заселектен "никакой" битмап. Я правда не проверял, но подозреваю что там именно NULL. Ну и что у тебя получается, создался контекст, в него успешно заселектился твой битмап, в lbmp попал тот битмап, который там был раньше, т.е. никакой, после проверки это и выясняется, стретч не выполняется, и далее сразу идёт DeleteDC, т.о. старая ситуация . Никакая проверка не нужна, я просто не уверен, корректно ли не запоминать результат селекта, а потом перед DeleteDC селектить в контекст NULL, но перед делетом так или иначе нужно сделать селект. Лучше в дебаге уточнить конечно, так ли всё происходит.

ЗЫ. Так ты на дельфе пишешь, а я то думаю откуда в сях взялся Then
Re[6]: печать картинки API-ыми функциями
От: viya  
Дата: 13.03.03 12:40
Оценка:
Здравствуйте, DjAndy, Вы писали:

DA>Ясное дело, что в только что созданном контексте заселектен "никакой" битмап.
что значит "никакой" битмап, када там определенный битмап...
DA>Я правда не проверял, но подозреваю что там именно NULL.
нет там NULL, там все нормальные значения
DA>Ну и что у тебя получается, создался контекст, в него успешно заселектился твой битмап, в lbmp DA>попал тот битмап, который там был раньше, т.е. никакой,
да, h_dc_pic каждый раз новое, а вот lbmp (но ведь ты же посоветовал его ввести...) так вот
lbmp:=SelectObject(h_dc_pic,img.Picture.Bitmap.Handle)
возвращает handle,но ...каждый раз одно и тоже значение...и что...как-то же оно печатает 269 страничек? а может и вывалиться при печати 70
DA>после проверки это и выясняется, стретч не выполняется, и далее сразу идёт DeleteDC, т.о. старая DA>ситуация . Никакая проверка не нужна,
в каком смысле никакая проверка не нужна?
DA>я просто не уверен, корректно ли не запоминать результат селекта,
так мы же запоминаем результат селекта в lbmp
DA>а потом перед DeleteDC селектить в контекст NULL, но перед делетом так или иначе нужно сделать DA>селект. Лучше в дебаге уточнить конечно, так ли всё происходит.
а вот как раз
deleteDc(h_dc_pic);
не изменяет значение h_dc_pic...
воооот
да и что значит "селектить в контекст NULL"?

DA>ЗЫ. Так ты на дельфе пишешь, а я то думаю откуда в сях взялся Then

на ней родимой
Re[7]: печать картинки API-ыми функциями
От: DjAndy Россия  
Дата: 13.03.03 15:09
Оценка:
Привет

Так, короче я стормозил. Я подумал, что SelectObject вернёт NULL, потому что контекст только что создан, и битмап в него ещё никакой не селектили

Я чего не понял, если честно, вот у тебя в коде создался h_dc_pic, и больше нигде не юзится, зато есть h_dc_mem, который нигде не создаётся, зато в конце удаляется Ничего не перепутала?
Вот этот код должен работать, если не заработает, значит ошибка где-то в другом месте:

h_dc_pic:=CreateCompatibleDC(h_dc);
if(h_dc_pic <> NULL) then begin
lbmp:=SelectObject(h_dc_pic,img2.Picture.Bitmap.Handle);
if(lbmp <> 0) then begin
StretchBlt(h_dc,0,0,picW,picH,h_dc_pic,0,0,img2.Picture.Bitmap.Width,img2.Picture.Bitmap.Height,SRCCOPY);
SelectObject(h_dc_pic,lbmp);
end
else Log('');//запись в лог
DeleteDc(h_dc_mem);
end;
Re[8]: печать картинки API-ыми функциями
От: viya  
Дата: 13.03.03 15:43
Оценка:
Здравствуйте, DjAndy, Вы писали:

DA>Привет

прУвет
DA>Вот этот код должен работать, если не заработает, значит ошибка где-то в другом месте:

DA>h_dc_pic:=CreateCompatibleDC(h_dc);

DA>if(h_dc_pic <> NULL) then begin
DA> lbmp:=SelectObject(h_dc_pic,img2.Picture.Bitmap.Handle);
DA> if(lbmp <> 0) then begin
DA> StretchBlt(h_dc,0,0,picW,picH,h_dc_pic,0,0,img2.Picture.Bitmap.Width,img2.Picture.Bitmap.Height,SRCCOPY);
DA> SelectObject(h_dc_pic,lbmp);
DA> end
DA> else Log('');//запись в лог
поправка извеняюсь мАя опечатка, действительно тут должно быть не DeleteDc(h_dc_mem), а
DeleteDc(h_dc_pic)
DA> end;

так вот так оно и делается....но всеравно вылетает....печатает черные листы
но вылетает тут!проверено..могу отловить именно на какой строке
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.