Вывод текста через API
Модератор: Модераторы
Вывод текста через API
Есть исходный код по дельфи, где используется WinAPI для вывода текста:
dc := Canvas.Handle;
rect.Left := 0; rect.Top := 0; rect.Right := 300; rect.Bottom := 250;
ExtTextOut(dc, 0, 0, ETO_CLIPPED, @rect, 'asddfg', 6, NIL);
при использовании этих исходников в Lazarus текст не выводится.
lclintf подключил, пробовал явно указывать
lclintf.ExtTextOut(dc, 0, 0, ETO_CLIPPED, @rect, 'asddfg', 6, NIL);
В чем может быть проблема?
Lazarus 0.9.29 QT WinXP SP3
dc := Canvas.Handle;
rect.Left := 0; rect.Top := 0; rect.Right := 300; rect.Bottom := 250;
ExtTextOut(dc, 0, 0, ETO_CLIPPED, @rect, 'asddfg', 6, NIL);
при использовании этих исходников в Lazarus текст не выводится.
lclintf подключил, пробовал явно указывать
lclintf.ExtTextOut(dc, 0, 0, ETO_CLIPPED, @rect, 'asddfg', 6, NIL);
В чем может быть проблема?
Lazarus 0.9.29 QT WinXP SP3
Если хотите использовать WinAPI, пользуйтесь функциями из модуля Windows.
а как туда передавать прямые handle'ы?
те, к которым есть доступ (например, Canvas.Handle) - это не API-handle, а указатель на экземпляр какого-то класса QT
те, к которым есть доступ (например, Canvas.Handle) - это не API-handle, а указатель на экземпляр какого-то класса QT
Бррр... Я что-то вас не понимаю. Какие вы виджеты используете? Какая ос?
ctm
А при чём тут Qt?
Вы не пробовали вместо dc этот самый Canvas.Handle подставлять?
А при чём тут Qt?
Вы не пробовали вместо dc этот самый Canvas.Handle подставлять?
похоже, что человек ctm не уверен в правильности переноса кода от WinAPI на (праведный) lclintf.
проверил на Win32 widgetset-е. Работает.
скорее всего ctm пытается рисовать вне OnPaint евента.
ctm, проверь у себя (на Qt) приложенный проект (если будут проблемы с открытием проекта, просто скопируй FormPaint в свой проект, и назначь обработчик у формы OnPaint).
----
рисует следующим кодом:
проверил на Win32 widgetset-е. Работает.
скорее всего ctm пытается рисовать вне OnPaint евента.
ctm, проверь у себя (на Qt) приложенный проект (если будут проблемы с открытием проекта, просто скопируй FormPaint в свой проект, и назначь обработчик у формы OnPaint).
----
рисует следующим кодом:
Код: Выделить всё
uses ...LCLType, LCLIntf;
procedure TForm1.FormPaint(Sender:TObject);
var
dc : HDC;
rect : TRect;
begin
dc := Canvas.Handle;
rect.Left := 0; rect.Top := 0; rect.Right := 300; rect.Bottom := 250;
ExtTextOut(dc, 0, 0, ETO_CLIPPED, @rect, 'asddfg', 6, NIL);
end;
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Спасибо за совет:)
внутри OnPaint работает как надо.
а можно как-то заставить это работать с хендлом невидимой битмапы, для которой к тому же вызван BeginUpdate()?
так изначально стоит задача
Попробую сам разобраться...
внутри OnPaint работает как надо.
а можно как-то заставить это работать с хендлом невидимой битмапы, для которой к тому же вызван BeginUpdate()?
так изначально стоит задача
Попробую сам разобраться...
ctm писал(а):а можно как-то заставить это работать с хендлом невидимой битмапы, для которой к тому же вызван BeginUpdate()?
так изначально стоит задача
Код: Выделить всё
var b: TBitmap;
ExtTextOut(b.Canvas.Handle, ...);
логично, но это же будет ВНЕ OnPaint евента?
Добавлено спустя 42 секунды:
в смысле onpaint для этой битмапы
Добавлено спустя 42 секунды:
в смысле onpaint для этой битмапы
У TBitmap нет такого события - OnPaint.
а если я вывожу текст в компоненте (унаследован от TCustomPanel), у которой есть этот самый невидимый битмап,
то внутри чьего OnPaint'а нужно выводить текст в картинку (контрола или формы)?
и почему так происходит?
это из-за Widget.BeginPaint() / Widget.EndPaint() ?
Добавлено спустя 1 час 37 минут 30 секунд:
все, кажется разобрался.
у меня делается Bitmap.BeginUpdate(), потом вывод текста через API
то внутри чьего OnPaint'а нужно выводить текст в картинку (контрола или формы)?
и почему так происходит?
это из-за Widget.BeginPaint() / Widget.EndPaint() ?
Добавлено спустя 1 час 37 минут 30 секунд:
все, кажется разобрался.
у меня делается Bitmap.BeginUpdate(), потом вывод текста через API
1) в битмап можно рисовать в любой момент времени
2)
композитный движок Qt (в частности огромное желание припахать видео карту к процессу рендеринга ГУИ).
Все жалобы к бывшему TrollTech.
3)
у TCustomPanel, как и любого другого контрола, есть protected метод Paint. этот метод занимается отрисовкой содержимого контрола. Т.е. он сам по себе что-нибудь рисует что-нибудь, и вызывает (может вызывать) event OnPaint, чтобы пользователь компонента, тоже мог в него что-нибудь нарисовать.
Вывод: рисовать в битмап можно когда угодно (например при изменении каких-нибудь свойств компонента унаследованного от TCustomPanel). А выводить битмап на этот самый компонент, следует исключительно во время Paint.
2)
ctm писал(а): и почему так происходит?
композитный движок Qt (в частности огромное желание припахать видео карту к процессу рендеринга ГУИ).
Все жалобы к бывшему TrollTech.
3)
ctm писал(а):а если я вывожу текст в компоненте (унаследован от TCustomPanel), у которой есть этот самый невидимый битмап, то внутри чьего OnPaint'а нужно выводить текст в картинку (контрола или формы)?
у TCustomPanel, как и любого другого контрола, есть protected метод Paint. этот метод занимается отрисовкой содержимого контрола. Т.е. он сам по себе что-нибудь рисует что-нибудь, и вызывает (может вызывать) event OnPaint, чтобы пользователь компонента, тоже мог в него что-нибудь нарисовать.
Вывод: рисовать в битмап можно когда угодно (например при изменении каких-нибудь свойств компонента унаследованного от TCustomPanel). А выводить битмап на этот самый компонент, следует исключительно во время Paint.
я так и делаю.
проблема-то в другом (как я теперь только допер).
прорисовка (все кроме текста) в битмап делается низкуровнево: получаем адрес начального прикселя, зная размеры и глубину цвета - можно все нарисовать. Текст по-красивому так не выведешь - поэтому в начальном варианте (под дельфи) прорисовка графики делалась через прямое обращение к памяти, а текст - через функции WinAPI и все работало.
В лазарусе - можно получить адрес начального пикселя и прорисовать через RawImage.Data, но только внутри Begin/EndUpdate. Именно п
ри этом всякие TextOut'ы не работают.
Пока не нашел я способа одновременного доступа через RawImage.Data и через стандартные функции, и не понятно если он вообще:(
P.S. Опыт программирования на дельфи у меня большой, а на лазарусе практически никакого - не судите строго
проблема-то в другом (как я теперь только допер).
прорисовка (все кроме текста) в битмап делается низкуровнево: получаем адрес начального прикселя, зная размеры и глубину цвета - можно все нарисовать. Текст по-красивому так не выведешь - поэтому в начальном варианте (под дельфи) прорисовка графики делалась через прямое обращение к памяти, а текст - через функции WinAPI и все работало.
В лазарусе - можно получить адрес начального пикселя и прорисовать через RawImage.Data, но только внутри Begin/EndUpdate. Именно п
ри этом всякие TextOut'ы не работают.
Пока не нашел я способа одновременного доступа через RawImage.Data и через стандартные функции, и не понятно если он вообще:(
P.S. Опыт программирования на дельфи у меня большой, а на лазарусе практически никакого - не судите строго
ctm писал(а):прорисовка (все кроме текста) в битмап делается низкуровнево: получаем адрес начального прикселя, зная размеры и глубину цвета - можно все нарисовать. Текст по-красивому так не выведешь - поэтому в начальном варианте (под дельфи) прорисовка графики делалась через прямое обращение к памяти, а текст - через функции WinAPI и все работало.
между BeginBitmap...EndBitmap, создаётся пиксельная копия из начального
по EndBitmap (если особых флагов не использовалось) содержимое системного bitmap-а (читай битмапа в хендле), заменяется на содержимое записанное в пиксельной копии.
Такой шаг связан с тем, что не на каждом widgetset-е, можно получить прямой доступ к пикселям изображения. Но от каждого изображения всегда можно получить пиксельную копию и скопировать содержимое. На кажущийся "тормоз" это правильно, ибо безопасность, и портируемость.
Например такая схема довольно просто ложится на отрисовку с помощью 3d карточки (directx,opengl) (опять вспоминаем гламурные движки аля Аэро или Компиз)
а есть ли причина делать Низкоуровневую отрисовку?
Добавлено спустя 36 минут 18 секунд:
вот пример использования совместно:
а) ручной отрисовки через RawImage
b) отрисовки используя разные "виды" LCL (через LCLIntf и Canvas)
так же отрисовка происходит в своём контроле (наследнике от TCustomPanel)
ctm, протестируй пожалуйста!
У вас нет необходимых прав для просмотра вложений в этом сообщении.
между BeginBitmap...EndBitmap, создаётся пиксельная копия из начального
по EndBitmap (если особых флагов не использовалось) содержимое системного bitmap-а (читай битмапа в хендле), заменяется на содержимое записанное в пиксельной копии
я так и понял - видно по поведению.
про портируемость тоже понятно - но у нас стоит другая задача:
нужно использовать бесплатный продукт разработки ПО, портируемость не нужна совсем, нужно максимально использовать старые наработки на delphi6.
При переносе обнаружилось множество отличий (что вполне логично)...
За ваш пример спасибо, он у меня заработал после третьего пинка - видимо особенности версии имли QT - непонятно...
менял я инкремент до следующего пикселя (4 вместо 3) и пришлось указать честный rect для текста - а то не выводил.
Что касается низкоуровневой графики - скорость требуется при достаточно большом количестве мелких графических примитивов, а софт должен быть расчитан на слабое железо.
