| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > SynUniHighlighter и SynEdit > Исправления и моды SynEdit из пакета SynMix |
| Автор: mr.Anderson 29.7.2007, 19:14 | ||||||||||||||||||||||||||||||||||||||||
| Тему, я думаю, стоит закрепить. И вообще все, что связано с SynEdit из пакета SynMix, надо бы перенести в эту тему, мне кажется. Итак. Поскольку SynEdit из пакета SynMix мне нужно использовать в своей программе как основной, мне пришлось изрядно перерыть его, чтобы заставить-таки работать, как надо. Привожу здесь мои добавления, произведенные в файле SynEdit.pas, а также обнаруженные и исправленные баги. Примечание: прошу обратить внимание на то, что номера строк, где происходило добавление, приведены для моего, уже исправленного и дополненного файла SynEdit.pas. В стандартном файле, разумеется, этих добавлений/исправлений нет, и по указанным номерам строк находится совсем другой код. Фикс №1 Строка 11664: пофиксен баг с отображением скрытого текста. Собственно фикс в том, что я увеличил добавляемые пробелы с пяти до шести.
До этого исправления, например, когда мы сворачивали примерно такой блок кода:
То в подсказке получали следующее:
Разницу видим?
В подсказке отображалось
Т.е. тоже обрезался последний (и в данном случае единственный) символ открывающейся скобки. Фикс №2 Строки 4017 и 4021: пофиксен баг с размещением [...]. Раньше было так, что при простом сворачивании блока кода, ограниченного { и }, блок [...] наезжал на переплет, а если блок был ограничен, например, begin и end, то [...] наезжал на слово begin. Теперь все нормально (###фикс - исправлено наезжание [...] на первую строку блока кода).
Фикс №3 В строках 12772 и 12773 добавлен код, предотвращающий ошибку в случае, если выделить первую строку свернутого блока и нажать Ctrl + Backspace (///###mod error with Ctrl+Backspace when SelAvail = True).
Мод №1 Добавлена общедоступная функция IsLineCollapsed() (в строке 786 - в классе, а в 6798-6801 - реализация). Функция принимает целый параметр - номер строки, с которой начинается блок кода. Функция возвращает True, если этот блок свернут, и False, если нет. Код крайне прост и занимает всего одну строчку.
Обнаруженный и грубовато исправленный баг Вынес это исправление в отдельную "категорию". Смысл таков: в SynEdit из пакета SynMix НЕ РАБОТАЕТ клавиша Delete! Я вообще был в шоке от этого. Жму Delete - ноль эмоций! Но зато если выделить часть текста и нажать Delete - все нормально. Поскольку я не смог поймать нажатие Delete в классе TCustomSynEdit (читайте ниже, почему), пришлось исправлять баг грубыми методами. О них - в модах №2 и №3. Мод №2 Добавлена общедоступная процедура Del() (строка 788 - объявление, 6808-6811 - реализация).
По сути, эта процедура - грубая замена нажатия клавиши Delete в SynEdit, создана для облегчения пользования этой неработающей клавишей. Для ее активации придется в программе переопределять метод AppMsg или WndProc, ловить там нажатие Delete и использовать эту функцию. Например, это может быть такой код:
Мод №3 Добавлена общедоступная процедура DeleteSelText() (строка 787 - объявление, 6803-6806 - реализация). По сути своей это просто синоним вышеописанной процедуры Del(), но может быть более привычно и удобно использовать понятную по своему действию процедуру DeleteSelText(), чем просто Del().
Обнаруженный и НЕ исправленный баг Если свернутую строку кода выделить и нажать Delete, то строка удаляется. Однако попытки отменить это (SynEdit.Undo()) ни к чему не приводят - отмены удаления не происходит. Я, кстати, вообще не смог отловить нажатие Delete. Ставил бряки на TCustomSynEdit.KeyPress, TCustomSynEdit.KeyDown, TCustomSynEdit.KeyUp, даже на TCustomSynEdit.WndProc() - бесполезно. Ловятся все клавиши, кроме Delete. Именно поэтому я и не смог отловить данный баг. В своей программе мне пришлось искусственно запретить срабатывание любых клавиш на строке, где находится свернутый блок (кроме Enter, клавиш вверх-вниз-влево-вправо, Home и End - это сделано для того, чтобы юзер не думал, что это еще один глюк). Объемный мод №4 В класс TCustomSynEdit добавлено свойство только для чтения CurrentHL. Это свойство нового перечислимого типа TCurrentHL, содержит словесный и числовой эквиваленты текущей подсветки. Иногда бывает нужно (мне вот понадобилось) узнать, какая сейчас в редакторе подсветка. Как это узнать обычными методами? А никак. Свойство Highlighter у TCustomSynEdit имеет тип TSynCustomHighlighter, а конкретный тип, например, TSynPasSyn, я не смогу узнать никакими методами. Поэтому я и добавил такую возможность в виде вышеназванного свойства. Теперь собственно о том, какой код был добавлен. Все, связанное с этим модом, помечено как
Повторю, все изменения производились в файле SynEdit.pas. Первое. В строках 216-224 добавлен тип TCurrentHL. Он содержит имена всех типов подсветки из пакета SynMix (например, TSynPasSyn, TSynVBScriptSyn и так далее). С компонентом UniHighlighter этот тип никак не связан и с ним использовать данный мод бесполезно.
Тип, разумеется, общедоступный и может использоваться в основной программе, где размещен компонент SynEdit. Второе. В строке 430 добавлена переменная fCurrentHL типа TCurrentHL. Эта переменная и содержит имя текущей подсветки.
Третье. В строке 737 объявлена процедура UpdateCurrentHL(). Она вводит в переменную fCurrentHL имя текущей подсветки (тип TCurrentHL).
Четвертое. В строке 935 прописано свойство CurrentHL (только для чтения, повторюсь).
Пятое. В строке 1550 (это код конструктора класса TCustomSynEdit) добавлена, по моему мнению, упущенная инициализация свойства Highlighter. Это даже к моду не относится, в принципе, это скорее фикс. А вот в строчке 1551 добавлен вызов вышеназванной процедуры UpdateCurrentHL(), которая, как мы увидим дальше по ее коду, в данном случае проинициализирует переменную fCurrentHL как lngNone (это одно из имен типа TCurrentHL, означающее, что текущей подсветки нет, т.к. свойство Highlighter равно nil).
Шестое. В строках 7266-7323 находится реализация процедуры UpdateCurrentHL().
И последняя часть кода, относящаяся к данному моду - это строчка 7348. В этой строке добавлен вызов UpdateCurrentHL(). Вызов находится в коде функции SetHighlighter() класса TCustomSynEdit, которая, как можно догадаться, изменяет свойство Highlighter. Поэтому вызов процедуры обновления переменной текущей подсветки находится именно в этом месте кода.
Теперь в любом месте вашей программы вы можете узнать текущую подсветку, проанализировав свойство CurrentHL компонента SynEdit. Например, так:
|
| Автор: winsoft 10.8.2007, 23:36 |
| mr.Anderson, пока еще не проверил, как все работает, но заранее большое спасибо за проделанную работу! |
| Автор: mr.Anderson 14.8.2007, 21:50 |
| Не за что. Отпишитесь плз, как у вас успехи с проверкой исправлений. |
| Автор: iddqd2 14.1.2008, 18:33 | ||
| По поводу бага с несрабатыванием клавиши Delete Происходит это из-за того, что клавиша Delete вызывает только событие KeyUp а не KeyDown, в то время как в SynEdit обработка событий стандартных клавиш происходит в KeyDown. Все необходимое для отработки нажатия Delete там есть. Так что делаем так:
|
| Автор: mr.Anderson 15.1.2008, 13:56 |
| iddqd2, супер |
| Автор: BenderM 12.6.2009, 17:02 | ||
| mr.Anderson Про выявление имени хайлайтера вы конечно перемудрили Добавлено через 4 минуты и 51 секунду Думаю этот код пригодился бы Вам полтора года назад
|
| Автор: K0T9I 20.10.2010, 15:50 | ||||||
когда делаем так, то удаление клавишей Delete возможно только при нажатии/отпускании клавиши по 1 символу за раз, при удерживании удаляется тоже 1 символ. если тоже самое, что подсказал iddqd2 вставить в KeyDown, все начинает работать как надо
|