у меня старая проблемка
вот кусочек кода вывод на печать картинки 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......
тоже дальше не работает..но и печатал бы себе черные листы, но ведь вываливается...
жду дельных советов и предложений!
зарание спасибо
Ну проблема старая Ответ однозначный — хэндлы теряются. Может, и не только здесь, а здесь надо поступать так:
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);
Здравствуйте, 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);
ибо для печати следующей мне опять он понадобиться
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. Тоже самое кстати и наоборот действует, нельзя уничтожать битмап, если он заселектен в какой-нить контекст, чревато тем же боком
Удачи
Здравствуйте, 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);
А>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
Здравствуйте, 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
на ней родимой
Так, короче я стормозил. Я подумал, что 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;
Здравствуйте, 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;
так вот так оно и делается....но всеравно вылетает....печатает черные листы
но вылетает тут!проверено..могу отловить именно на какой строке