Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Delphi: Создание простого цветного TMemo или TEdit

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2 3 4 5 6 7 8 9

Открыть новую тему     Написать ответ в эту тему

ShIvADeSt



Moderator
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
StalkerSoftware

Цитата:
 
У меня тоже самое.
Если нажать один Alt, то курсор мыши меняет свою форму с курсора для набора текста, на курсор-стрелочку, а клавиатурный курсор набора текста (мигающая вертикальная палочка) либо исчезает, либо просто замирает (перестает мигать).
 
Похоже, что при нажатии Alt, memo просто теряет фокус ввода.

Ознакомьтесь с поведение окна при нажатии кнопки Альт. При нажатии на альт происходит вызов главного меню, соотв фокус уходит с ЛЮБОГО контрола. Сделайте приложение с обычным Мемо (без моей обработки) и нажмите Альт - увидите тоже самое.
 


----------
И создал Бог женщину... Существо получилось злобное, но забавное...

Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 02:40 09-09-2009
StalkerSoftware



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
ShIvADeSt

Цитата:
Ознакомьтесь с поведение окна при нажатии кнопки Альт. При нажатии на альт происходит вызов главного меню, соотв фокус уходит с ЛЮБОГО контрола. Сделайте приложение с обычным Мемо (без моей обработки) и нажмите Альт - увидите тоже самое.  

Действительно, так оно и есть. Я как то про это не подумал.
Извиняюсь, был не прав.

Всего записей: 682 | Зарегистр. 23-06-2008 | Отправлено: 14:30 09-09-2009
StalkerSoftware



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
2 All
 
Первая часть марлезонского балета:
 
Это компонент TColorMemo сделанный на базе последнего варианта кода от  
ShIvADeSt .
 
Я него добавил :  
 - свойство Separators для задания разделителей;
 - возможность подчеркивать волнистой линией слова;
 - событие OnCheckWord для задания цвета букв, фона и подчеркивания для  
   слов;
 - ну и немного доработал код, что бы он правильно работал в Design-Time.
 
Код работает в D7-D2010.
 
Вроде бы все работает нормально, но было бы неплохо что бы All, его еще  
немного погонял на ошибки, особенно на висте и Windows7.
 
Скачать TColorMemo можно здесь (9 кб).
 
Отзывы и сообщения об ошибках оставляем в этой теме.

Всего записей: 682 | Зарегистр. 23-06-2008 | Отправлено: 18:48 15-09-2009
data man



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
StalkerSoftware
Ну первая ошибка - требуется ColorEdit, но это мелочи.
Если долго держать нажатой любую символьную клавишу - очень медленно работает.
Тесты продолжаются.

----------
Любой достаточно развитый тролль неотличим от подлинно помешанного на какой-либо идее.
Кекс. Антибиотики. Ламбада.

Всего записей: 1696 | Зарегистр. 13-10-2005 | Отправлено: 18:55 15-09-2009
StalkerSoftware



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
ShIvADeSt
 
Пытался я на базе TColorMemo сделать TColorEdit, но что оно не очень.
Отрисовка идет не правильная.
 
К TEdit я добавил три свойства WordWrap, WantReturns, Alignment, что бы  
можно было в Edit визуально вводить текст в виде виде нескольких строк  
(хотя конечно реально там одна строка). Все эти свойства работают и  
отрисовывают текст нормально.
В ряде случаев такой псевдо многострочный Edit удобнее чем Memo.
 
А потом я добавил в него функциональность ColorMemo.
Само выделение текста работает вроде бы нормально, но вот отрисовка всего  
этого глючит.
Вот ссылка на код ColorEdit и небольшую демку к нему.
 
1) Периодически (но не всегда, похоже это как то задается во время компиляции)  
текст почему то центрируется в Edit.
2) При заходе в ColorEdit1 всегда выделяется текст, хотя по идее  
он должен выделятся только один раз.
3) При заходе в ColorEdit1 виден скачок текста в начало Edit, а потом  
опять по центру.
4) В ColorEdit2, где включен режим WordWrap текст дублируется по всей  
высоте Edit'а.
5) Отрисовка текста весьма плохо (или даже вообще ни как) не согласуется с  
новыми тремя свойствами.
 
Как я понимаю, основная проблема тут зарыта в обработчиках WMPaint,
WMPrintClient и в PaintLine, так где идет расчет координат и непосредственная
отрисовка текста. Пробовал их менять, но честно говоря получилось весьма не  
очень. Все же получившийся ColorMemo оказалось перенести на Edit гораздо  
сложнее, чем я первоначально думал.
 
2 ShIvADeSt: Очень нужна твоя помощь в этом вопросе.
 
Добавлено:
data man
 
Ну ты скорый, не успел выложить, ты уже смотришь
 

Цитата:
Ну первая ошибка - требуется ColorEdit, но это мелочи

Исправил, перезалил.
 
 

Цитата:
Если долго держать нажатой любую символьную клавишу - очень медленно работает.
Тесты продолжаются.

Насколько долго ее надо держать ?
У меня этого замедление не наблюдается, правда у меня довольно быстрый проц E8500, так что на более медленных машинах оно может и есть ...
 
Проявляется ли это замедление в оригинальном коде ShIvADeSt или в стандартном TMemo ?
 
Посмотри, если для первой мемки закомментировать IsUnderline := True, будет ли видно это замедление ?

Всего записей: 682 | Зарегистр. 23-06-2008 | Отправлено: 18:56 15-09-2009 | Исправлено: StalkerSoftware, 19:04 15-09-2009
data man



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
StalkerSoftware

Цитата:
Насколько долго ее надо держать ?

Да просто нажать хоть пробел и держать - набор происходит очень медленно.
Цитата:
Проявляется ли это замедление в оригинальном коде ShIvADeSt

Да проявляется.
В стандартном - нет.

Цитата:
Посмотри, если для первой мемки закомментировать IsUnderline := True, будет ли видно это замедление ?

Еще как видно - значит дело не в этом.
Будем копать дальше.
 


----------
Любой достаточно развитый тролль неотличим от подлинно помешанного на какой-либо идее.
Кекс. Антибиотики. Ламбада.

Всего записей: 1696 | Зарегистр. 13-10-2005 | Отправлено: 19:09 15-09-2009
StalkerSoftware



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
data man
 
Похоже, что тормозить оно начинает, если в ColorMemo с отключенным WordWrap ввести несколько очень длинных (200 и более символов) строк.

Всего записей: 682 | Зарегистр. 23-06-2008 | Отправлено: 19:35 15-09-2009
data man



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
StalkerSoftware
Может в WMCHAR запоминать предыдущий набранный символ и сравнивать с новым, если совпадают - не перерисовывать ?

----------
Любой достаточно развитый тролль неотличим от подлинно помешанного на какой-либо идее.
Кекс. Антибиотики. Ламбада.

Всего записей: 1696 | Зарегистр. 13-10-2005 | Отправлено: 19:56 15-09-2009
StalkerSoftware



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
data man

Цитата:
Может в WMCHAR запоминать предыдущий набранный символ и сравнивать с новым, если совпадают - не перерисовывать ?
 

Нет, думаю это не поможет. Тут ИМНО дело в другом, а именно в процедуре PainLine.
Ведь она, если я правильно понимаю, работает по всей длине строки , несмотря на то, что отрисовывается только видимая часть строки.
Соответственно ее надо изменить так, чтобы она обрабатывала только видимые части строк, тогда думаю скорость ее работы существенно увеличиться.
 
Только я не знаю, как в обработчиках WMPrintClient и WMPrint определить эту видимую часть строки в символах.

Всего записей: 682 | Зарегистр. 23-06-2008 | Отправлено: 21:22 15-09-2009
ShIvADeSt



Moderator
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
StalkerSoftware

Цитата:
Ведь она, если я правильно понимаю, работает по всей длине строки , несмотря на то, что отрисовывается только видимая часть строки.  

Немного не правильно думаете. Видимая часть строки, невидимая часть строки - фигня. Проблема в том, что при изменении даже ОДНОГО символа происходит перерисовка ВСЕГО контрола. Именно это и вызывает тормоза при отрисовке.
data man

Цитата:
Может в WMCHAR запоминать предыдущий набранный символ и сравнивать с новым, если совпадают - не перерисовывать ?

Тогда будет след ситуация - человек жмет кнопку а на экране пустота. Кнопку отпустил - опа на - строка символов нарисовалась

Цитата:
Похоже, что тормозить оно начинает, если в ColorMemo с отключенным WordWrap ввести несколько очень длинных (200 и более символов) строк.

Отрисовка идет на канве ТМемо, отрисовывается только видимая часть - так как у канвы есть границы. А то что проверяется вся строка - это не так страшно, как отрисовка всего текста.
ИМХО единственный способ уменьшить тормоза - это закэшировать весь отображаемый текст в массиве и вместо того, чтобы при отрисовке каждый раз полностью перечитывать цветовые настройки добавлять удалять нужные.
 
Короче ситуация след - основные тормоза вызывают использование LockWindowUpdate. Думаю как побороть или заменить  
 
Побороть или заменить не получилось. Нашел как сделать чтобы отрисовывалась только измененная часть, все хорошо пока по вашему окну не начинают ездить другим окном, короче забил на это, так как:
 
1) Здесь надо либо добавлять перехват оконной функции главного приложения, чтобы знать когда переключились в окно и делать перерисовку
2) Если мне не изменяет память то по идее текст должен был только выводиться
3) В принципе все работает - а тормоза, да и фиг с ними.
 
Просто я перелопатил исходники самописного контрола - по части отрисовки они идентичны моим, но там практически нет тормозов, так как там НЕТ подавления родного поведения контрола, которое мне приходится делать при помощи LockWindowUpdate, что уже само по себе не есть гуд.  
 
Если будет время и желание поковыряться, то еще посмотрю. Может доделаю теперешний вариант (с отрисовкой только измененных строк).

----------
И создал Бог женщину... Существо получилось злобное, но забавное...

Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 03:13 16-09-2009 | Исправлено: ShIvADeSt, 06:52 16-09-2009
ShIvADeSt



Moderator
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Поборол лень, добил баг - теперь вроде все нормально работает.
Подробнее...
На моем компе при печати и если просто зажать кнопку - то отрисовка происходит достаточно быстро.

----------
И создал Бог женщину... Существо получилось злобное, но забавное...

Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 08:35 16-09-2009
StalkerSoftware



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
ShIvADeSt

Цитата:
На моем компе при печати и если просто зажать кнопку - то отрисовка происходит достаточно быстро.
 

 
Попробовал на старом компе новый код, вроде бы тормозов теперь нет при длительном нажатии одной клавиши.
 
Кстати говоря, там коде осталась процедура SetWindowRedraw - похоже на остатки от твоих экспериментов.

Всего записей: 682 | Зарегистр. 23-06-2008 | Отправлено: 15:00 16-09-2009
ShIvADeSt



Moderator
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
StalkerSoftware

Цитата:
Кстати говоря, там коде осталась процедура SetWindowRedraw - похоже на остатки от твоих экспериментов.

Угу, это я пробовал отказаться от LockWindowUpdate. Но так как процедура нигде не вызывается- то компилятор на нее не ругнулся и я забыл про нее.

----------
И создал Бог женщину... Существо получилось злобное, но забавное...

Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 15:11 16-09-2009
StalkerSoftware



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
ShIvADeSt
 
Процедура WMPrintClient
перед GetForegroundWindow стоит строка
Size:=TextExtent(s);
 
откуда там возьмется значение s,  если до этой строки оно не определено ?
Может вместо s, там должен быть пробел ?
 
И еще:
в начало WMPrintClient ты добавил проверку
  if (StartCaretPos.cx=0) then
как в WMPrint.
Она там точно нужна ? Ведь client это отрисовка куска memo, а не его целиком ?

Всего записей: 682 | Зарегистр. 23-06-2008 | Отправлено: 15:51 16-09-2009
ShIvADeSt



Moderator
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
StalkerSoftware

Цитата:
Процедура WMPrintClient
перед GetForegroundWindow стоит строка
Size:=TextExtent(s);
 
откуда там возьмется значение s,  если до этой строки оно не определено ?
Может вместо s, там должен быть пробел ?  

Да должно быть  
Size:=TextExtent(' ');

Цитата:
в начало WMPrintClient ты добавил проверку
  if (StartCaretPos.cx=0) then
как в WMPrint.
Она там точно нужна ? Ведь client это отрисовка куска memo, а не его целиком ?  

Данное ветвление выполняется только один раз, поэтому можешь убрать, в принципе его по хорошему надо вообще в конструктор засунуть и убрать из процедуры отрисовки и там и там.
Здесь идет получение самой левой верхней позиции каретки, чтобы была точка отсчета для рисования текста. Так что будет желание - добавь конструктор и засунь стартовую инициализацию туда.
 
Кстати были обнаружены и убиты баги, если текст выделен, а потом переключаешься на другое окно и обратно - достаточно мерзкая картинка получалась Код прилагаю. При этом заодно поборол мерцание рабочего стола при различных событиях. По крайней мере у меня больше нет мерцания, а раньше при переключении с рабочего стола или другого приложения перерисовывался весь десктоп. Вот обновленный код
Подробнее...


----------
И создал Бог женщину... Существо получилось злобное, но забавное...

Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 02:11 17-09-2009 | Исправлено: ShIvADeSt, 05:21 17-09-2009
StalkerSoftware



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
ShIvADeSt

Цитата:
Кстати были обнаружены и убиты баги, если текст выделен, а потом переключаешься на другое окно и обратно - достаточно мерзкая картинка получалась Код прилагаю. При этом заодно поборол мерцание рабочего стола при различных событиях. По крайней мере у меня больше нет мерцания, а раньше при переключении с рабочего стола или другого приложения перерисовывался весь десктоп.

В коде от "08:35 16-09-2009" я честно говоря такого не увидел.
 
А вот в новом коде "05:21 17-09-2009" уже увидел это мерцание.
 
Что бы ты мог его увидеть сделай следующее:
В процедуре GotoXY убери строку с SetFocus, а в самой демке в редакторе TabOrder, сделай memo вторым (т.е. что бы оно не получало фокус при старте демки.
Запусти демку и нажми мышкой в memo. Хорошо видно как вздрогнула нижняя часть экрана и почему то выделился текст от начала memo до курсора мышки. При дальнейшей работе с демкой и переключениях контролов и приложений этого бага нет.

Всего записей: 682 | Зарегистр. 23-06-2008 | Отправлено: 15:15 17-09-2009 | Исправлено: StalkerSoftware, 15:17 17-09-2009
ShIvADeSt



Moderator
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
StalkerSoftware
Ну тады используй тот который больше нравится У меня были глюки я их поправил. Хотя возможно они появились вследствие моих манипуляций и кривых ручек

----------
И создал Бог женщину... Существо получилось злобное, но забавное...

Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 15:41 17-09-2009
StalkerSoftware



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
ShIvADeSt

Цитата:
Ну тады используй тот который больше нравится

Ну вообще то хотелось бы использовать не код который больше нравиться, а тот который более правильный.
 
А у тебя что, то что я описал не воспроизводится ?
 
И еще:
В обработчике WMMouseMove
Delphi ругается, что переменная Locked может быть не определена, и в общем то Delphi тут права.
Наверное в начала обработчика ей надо установить значение в False ?
 
Добавлено:
ShIvADeSt

Цитата:
Так что будет желание - добавь конструктор и засунь стартовую инициализацию туда

В конструктор его похоже нельзя.
После переноса инициализации StartCaretPos в конструктор, курсор стал ходить в memo по середине символом. Так что я эту установку вернул назад в WMPaint.

Всего записей: 682 | Зарегистр. 23-06-2008 | Отправлено: 16:04 17-09-2009 | Исправлено: StalkerSoftware, 16:18 17-09-2009
ShIvADeSt



Moderator
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
StalkerSoftware

Цитата:
Delphi ругается, что переменная Locked может быть не определена, и в общем то Delphi тут права.
Наверное в начала обработчика ей надо установить значение в False ?  

По дефолту и так фолс, но попробуй инициализировать вначале.

Цитата:
В конструктор его похоже нельзя.
После переноса инициализации StartCaretPos в конструктор, курсор стал ходить в memo по середине символом. Так что я эту установку вернул назад в WMPaint.

Забыл про это отписаться, да есть такая тема. Потому что при креейте текст еще не загрузился и позиция курсора хз где (0,0). В итоге я поэтому и оставил на месте.

Цитата:
Ну вообще то хотелось бы использовать не код который больше нравиться, а тот который более правильный.
 
А у тебя что, то что я описал не воспроизводится ?  

Я не пробовал с 2 мемо еще, седня потестирую. У меня была ситуация, когда поверх моего приложения висит таск менеджер и я делаю выделение - то весь десктоп мерцает. После исправлений - все отлично, мерцаний нет.
Подробнее...
Попробывал с двумя мемами - была куча глюков. По одному убил - результат выше. Тестируй.
 
Добавлено позже
Подробнее...
Сделал отдельным куском, так как может кто нить предыдущий код уже взял. Устранил мерцание при разворачивании окна (мерцал весь рабочий стол по крайней мере у меня).

----------
И создал Бог женщину... Существо получилось злобное, но забавное...

Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 01:51 18-09-2009 | Исправлено: ShIvADeSt, 09:38 18-09-2009
StalkerSoftware



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
ShIvADeSt
Посмотрел твой последний код.
 
1) Несколько небольших вопросов по GetTextStart
1.1) Как я понимаю это вместо GotoXY ?
1.2) Наверное GetFocus лучше написать как Windows.GetFocus, что бы четко было видно чей он.
1.3) Правильно ли я понимаю, что для того что бы GetCaretPos выдал правильные координаты для нашего memo он должен быть в этом момент в фокусе ?
 
2) Просто для информации: если данный код превратить в компонент и в WMPaint не поменять
 
Код:
if StartCaretPos.cx = 0 then GetTextStart();
на
Код:
if not (csDesigning in ComponentState) and (StartCaretPos.cx = 0) then GetTextStart();
то Delphi при загрузке формы с таким memo валится в кору.
 
3) Небольшая недоработка: Если в ColorMemo выделить текст, а потом табом или мышью перейти на другой компонент, то это выделение останется.
В стандартном memo оно снимается.
 
4) ColorMemo при своей отрисовке не учитывает свойство Alignment.
 
 

Всего записей: 682 | Зарегистр. 23-06-2008 | Отправлено: 17:32 18-09-2009 | Исправлено: StalkerSoftware, 17:47 18-09-2009
Открыть новую тему     Написать ответ в эту тему

Страницы: 1 2 3 4 5 6 7 8 9

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Delphi: Создание простого цветного TMemo или TEdit


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru