Вывод текста через API

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Вывод текста через API

Сообщение ctm » 17.03.2010 16:25:33

Есть исходный код по дельфи, где используется 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
ctm
новенький
 
Сообщения: 21
Зарегистрирован: 03.03.2010 16:34:29

Re: Вывод текста через API

Сообщение Mr.Smart » 17.03.2010 16:35:18

Если хотите использовать WinAPI, пользуйтесь функциями из модуля Windows.
Mr.Smart
долгожитель
 
Сообщения: 1796
Зарегистрирован: 29.03.2008 01:01:11
Откуда: из леса!

Re: Вывод текста через API

Сообщение ctm » 17.03.2010 17:04:02

а как туда передавать прямые handle'ы?
те, к которым есть доступ (например, Canvas.Handle) - это не API-handle, а указатель на экземпляр какого-то класса QT
ctm
новенький
 
Сообщения: 21
Зарегистрирован: 03.03.2010 16:34:29

Re: Вывод текста через API

Сообщение Mr.Smart » 17.03.2010 17:10:37

Бррр... Я что-то вас не понимаю. Какие вы виджеты используете? Какая ос?
Mr.Smart
долгожитель
 
Сообщения: 1796
Зарегистрирован: 29.03.2008 01:01:11
Откуда: из леса!

Re: Вывод текста через API

Сообщение Vadim » 17.03.2010 17:20:29

ctm
А при чём тут Qt? :)
Вы не пробовали вместо dc этот самый Canvas.Handle подставлять?
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Вывод текста через API

Сообщение скалогрыз » 17.03.2010 18:17:56

похоже, что человек ctm не уверен в правильности переноса кода от WinAPI на (праведный) lclintf.

проверил на 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;
У вас нет необходимых прав для просмотра вложений в этом сообщении.
скалогрыз
долгожитель
 
Сообщения: 1803
Зарегистрирован: 03.09.2008 02:36:48

Re: Вывод текста через API

Сообщение ctm » 18.03.2010 09:51:28

Спасибо за совет:)
внутри OnPaint работает как надо.
а можно как-то заставить это работать с хендлом невидимой битмапы, для которой к тому же вызван BeginUpdate()?
так изначально стоит задача :(
Попробую сам разобраться...
ctm
новенький
 
Сообщения: 21
Зарегистрирован: 03.03.2010 16:34:29

Re: Вывод текста через API

Сообщение скалогрыз » 18.03.2010 10:51:00

ctm писал(а):а можно как-то заставить это работать с хендлом невидимой битмапы, для которой к тому же вызван BeginUpdate()?
так изначально стоит задача :(

Код: Выделить всё
var b: TBitmap;

ExtTextOut(b.Canvas.Handle, ...);
скалогрыз
долгожитель
 
Сообщения: 1803
Зарегистрирован: 03.09.2008 02:36:48

Re: Вывод текста через API

Сообщение ctm » 18.03.2010 11:04:57

логично, но это же будет ВНЕ OnPaint евента?

Добавлено спустя 42 секунды:
в смысле onpaint для этой битмапы
ctm
новенький
 
Сообщения: 21
Зарегистрирован: 03.03.2010 16:34:29

Re: Вывод текста через API

Сообщение Vadim » 18.03.2010 11:14:43

У TBitmap нет такого события - OnPaint.
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Вывод текста через API

Сообщение ctm » 18.03.2010 12:08:20

а если я вывожу текст в компоненте (унаследован от TCustomPanel), у которой есть этот самый невидимый битмап,
то внутри чьего OnPaint'а нужно выводить текст в картинку (контрола или формы)?

и почему так происходит?
это из-за Widget.BeginPaint() / Widget.EndPaint() ?

Добавлено спустя 1 час 37 минут 30 секунд:
все, кажется разобрался.
у меня делается Bitmap.BeginUpdate(), потом вывод текста через API :(
ctm
новенький
 
Сообщения: 21
Зарегистрирован: 03.03.2010 16:34:29

Re: Вывод текста через API

Сообщение скалогрыз » 18.03.2010 15:45:10

1) в битмап можно рисовать в любой момент времени

2)
ctm писал(а): и почему так происходит?

композитный движок Qt (в частности огромное желание припахать видео карту к процессу рендеринга ГУИ).
Все жалобы к бывшему TrollTech.

3)
ctm писал(а):а если я вывожу текст в компоненте (унаследован от TCustomPanel), у которой есть этот самый невидимый битмап, то внутри чьего OnPaint'а нужно выводить текст в картинку (контрола или формы)?

у TCustomPanel, как и любого другого контрола, есть protected метод Paint. этот метод занимается отрисовкой содержимого контрола. Т.е. он сам по себе что-нибудь рисует что-нибудь, и вызывает (может вызывать) event OnPaint, чтобы пользователь компонента, тоже мог в него что-нибудь нарисовать.

Вывод: рисовать в битмап можно когда угодно (например при изменении каких-нибудь свойств компонента унаследованного от TCustomPanel). А выводить битмап на этот самый компонент, следует исключительно во время Paint.
скалогрыз
долгожитель
 
Сообщения: 1803
Зарегистрирован: 03.09.2008 02:36:48

Re: Вывод текста через API

Сообщение ctm » 18.03.2010 16:13:13

я так и делаю.
проблема-то в другом (как я теперь только допер).
прорисовка (все кроме текста) в битмап делается низкуровнево: получаем адрес начального прикселя, зная размеры и глубину цвета - можно все нарисовать. Текст по-красивому так не выведешь - поэтому в начальном варианте (под дельфи) прорисовка графики делалась через прямое обращение к памяти, а текст - через функции WinAPI и все работало.

В лазарусе - можно получить адрес начального пикселя и прорисовать через RawImage.Data, но только внутри Begin/EndUpdate. Именно п
ри этом всякие TextOut'ы не работают.
Пока не нашел я способа одновременного доступа через RawImage.Data и через стандартные функции, и не понятно если он вообще:(

P.S. Опыт программирования на дельфи у меня большой, а на лазарусе практически никакого - не судите строго :D
ctm
новенький
 
Сообщения: 21
Зарегистрирован: 03.03.2010 16:34:29

Re: Вывод текста через API

Сообщение скалогрыз » 18.03.2010 17:57:08

ctm писал(а):прорисовка (все кроме текста) в битмап делается низкуровнево: получаем адрес начального прикселя, зная размеры и глубину цвета - можно все нарисовать. Текст по-красивому так не выведешь - поэтому в начальном варианте (под дельфи) прорисовка графики делалась через прямое обращение к памяти, а текст - через функции WinAPI и все работало.

между BeginBitmap...EndBitmap, создаётся пиксельная копия из начального
по EndBitmap (если особых флагов не использовалось) содержимое системного bitmap-а (читай битмапа в хендле), заменяется на содержимое записанное в пиксельной копии.

Такой шаг связан с тем, что не на каждом widgetset-е, можно получить прямой доступ к пикселям изображения. Но от каждого изображения всегда можно получить пиксельную копию и скопировать содержимое. На кажущийся "тормоз" это правильно, ибо безопасность, и портируемость.
Например такая схема довольно просто ложится на отрисовку с помощью 3d карточки (directx,opengl) (опять вспоминаем гламурные движки аля Аэро или Компиз)

а есть ли причина делать Низкоуровневую отрисовку?

Добавлено спустя 36 минут 18 секунд:
вот пример использования совместно:
а) ручной отрисовки через RawImage
b) отрисовки используя разные "виды" LCL (через LCLIntf и Canvas)

так же отрисовка происходит в своём контроле (наследнике от TCustomPanel)

ctm, протестируй пожалуйста!
У вас нет необходимых прав для просмотра вложений в этом сообщении.
скалогрыз
долгожитель
 
Сообщения: 1803
Зарегистрирован: 03.09.2008 02:36:48

Re: Вывод текста через API

Сообщение ctm » 19.03.2010 09:38:22

между BeginBitmap...EndBitmap, создаётся пиксельная копия из начального
по EndBitmap (если особых флагов не использовалось) содержимое системного bitmap-а (читай битмапа в хендле), заменяется на содержимое записанное в пиксельной копии

я так и понял - видно по поведению.

про портируемость тоже понятно - но у нас стоит другая задача:
нужно использовать бесплатный продукт разработки ПО, портируемость не нужна совсем, нужно максимально использовать старые наработки на delphi6.
При переносе обнаружилось множество отличий (что вполне логично)...

За ваш пример спасибо, он у меня заработал после третьего пинка - видимо особенности версии имли QT - непонятно...
менял я инкремент до следующего пикселя (4 вместо 3) и пришлось указать честный rect для текста - а то не выводил.

Что касается низкоуровневой графики - скорость требуется при достаточно большом количестве мелких графических примитивов, а софт должен быть расчитан на слабое железо.
ctm
новенький
 
Сообщения: 21
Зарегистрирован: 03.03.2010 16:34:29

След.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot] и гости: 34

Рейтинг@Mail.ru