RichMemo/ru: what changed
Revision 2 to 3. Removed lines have a minus sign; added lines have a plus sign.
| Old | New | Line | |
|---|---|---|---|
| 1 | 1 |  | |
| 2 | 2 | ||
| 3 | 3 | **RichMemo** - это пакет, который включает компонент для замены компонента Delphi TRichEdit. Он разработан кросс-платформенным способом, поэтому его реализация возможна для следующих платформ: Win32, MacOSX и Linux. Поскольку [[RichMemo/ru|кроссплатформенность]] является основной целью, нативный API RichMemo может быть [[RichMemo/ru|расширен]], чтобы сделать его совместимым с Delphi RichEdit. | |
| 4 | 4 | ||
| 5 | 5 | Его основными характеристиками являются: | |
| 6 | 6 | ||
| 7 | 7 | - Подсветка текста | |
| 8 | 8 | - Системная поддержка редактирования Юникода | |
| 9 | 9 | ||
| 10 | 10 | Планируется: (исправления приветствуются) | |
| 11 | 11 | ||
| 12 | 12 | - Добавление изображений в текст | |
| 13 | 13 | - Встраивание элементов управления LCL? | |
| 14 | 14 | ||
| 15 | 15 | Загружаемый файл содержит компонент, установочный пакет и демонстрационное приложение, которое иллюстрирует возможности компонента, а также некоторые инструменты для оценки диаграммы в данной системе. | |
| 16 | 16 | ||
| 17 | 17 | Пожалуйста, добавляйте ваши багрепорты/функции на [Github](https://github.com/skalogryz/richmemo/issues). | |
| 18 | 18 | ||
| 19 | 19 | ## Лицензия | |
| 20 | 20 | ||
| 21 | 21 | Автор: Дмитрий 'скалогрыз' Бояринцев | |
| 22 | 22 | ||
| 23 | 23 | [modified](http://svn.freepascal.org/svn/lazarus/trunk/COPYING.modifiedLGPL) [LGPL](http://svn.freepascal.org/svn/lazarus/trunk/COPYING.LGPL) (так же, как FPC RTL и Lazarus LCL). Вы можете связаться с автором, если измененный LGPL не работает с вашим проектом лицензирования. | |
| 24 | 24 | ||
| 25 | 25 | ## Загрузка | |
| 26 | 26 | ||
| 27 | 27 | Последняя версия доступна здесь: | |
| 28 | 28 | ||
| 29 | 29 | [`https://github.com/skalogryz/richmemo`](https://github.com/skalogryz/richmemo) | |
| 30 | 30 | ||
| 31 | 31 | Прим.перев.: Существует также [форк](https://github.com/mrandreastoth/richmemo) данного компонента на гитхабе от [Andreas Toth](https://github.com/mrandreastoth) aka mrandreastoth. | |
| 32 | 32 | ||
| 33 | 33 | ## Change Log | |
| 34 | 34 | ||
| 35 | 35 | - Version 1.0.0 22th Jun 2009 | |
| 36 | 36 | - Version 0.8.0 Jun 2009 | |
| 37 | 37 | ||
| 38 | 38 | ## Зависимости / Системные требования | |
| 39 | 39 | ||
| 40 | 40 | - Lazarus 1.0.0 | |
| 41 | 41 | ||
| 42 | 42 | Статус: выпущен. | |
| 43 | 43 | ||
| 44 | 44 | ## Установка | |
| 45 | 45 | ||
| 46 | 46 | - Скачайте исходники пакета | |
| 47 | 47 | - Установите пакет в Lazarus и пересоберите его | |
| 48 | 48 | - TRichMemo добавится в закладку 'Common Controls'. | |
| 49 | 49 | ||
| 50 | 50 |  | |
| 51 | 51 | ||
| 52 | 52 | ## TRichMemo | |
| 53 | 53 | ||
| 54 | 54 | ### Параметры шрифта | |
| 55 | 55 | ||
| 56 | 56 | Параметры шрифта обычно представлены записью `TFontParams`. Тип используется для описания атрибутов шрифта **rich**. Некоторые атрибуты выходят за рамки класса `TFont`, поэтому необходим дополнительный тип. Однако большинство типов данных, связанных с `TFont`, используются повторно (т.е. `TFontStyles`). | |
| 57 | 57 | ||
| 58 | 58 | - `Name` - название шрифта (семейство). | |
| 59 | 59 | - `Size` - размер шрифта в пунктах (передача отрицательного значения может привести к неожиданным результатам). | |
| 60 | 60 | - `Color` - цвет шрифта. | |
| 61 | 61 | - `Style` - стили шрифта, включая полужирный, курсив, зачеркнутый, подчеркивание. | |
| 62 | 62 | - `HasBkClr` - логический флаг, если текст для должен иметь цвет фона (если true, поле BkColor используется, в противном случае BkColor игнорируется). Прозрачность не поддерживается. | |
| 63 | 63 | - `BkColor` - цвет фона (или подсветка) для текста. | |
| 64 | 64 | - `VScriptPos` - вертикальная настройка текста . | |
| 65 | 65 | - `vpNormal` - нет особой позиции. | |
| 66 | 66 | - `vpSubscript` - текст - нижний индекс. | |
| 67 | 67 | - `vpSuperscript` - текст - верхний индекс. | |
| 68 | 68 | ||
| 69 | 69 | ||
| 70 | 70 | Фактическое вертикальное смещение индексов верх/низ зависит от реализации ОС и в настоящее время не может контролироваться. | |
| 71 | 71 | ||
| 72 | 72 | Вы можете присвоить `FontParams` из структуры `TFont`. Для этого вам нужно использовать функцию `GetFontParams(afont: TFont)`. Обратите внимание, что для большинства элементов управления LCL для `TFont` установлены значения по умолчанию. Это не фактические значения, а скорее указание на то, что следует использовать шрифт по умолчанию для элемента управления (аналогично `crDefault` для `TColor`). | |
| 73 | 73 | ||
| 74 | 74 | Функция `GetFontParams` разрешает имя шрифта по умолчанию и возвращает фактическое имя семейства шрифтов. | |
| 75 | 75 | ||
| 76 | 76 | ## Методы | |
| 77 | 77 | ||
| 78 | 78 | ### SetTextAttributes | |
| 79 | 79 | ||
| 80 | 80 | ``` pascal | |
| 81 | 81 | procedure SetTextAttributes(TextStart, TextLen: Integer; AFont: TFont); | |
| 82 | 82 | ``` | |
| 83 | 83 | ||
| 84 | 84 | - `TextStart : Integer` - первый символ, который будет изменен | |
| 85 | 85 | - `TextLen : Integer` - количество символов для изменения | |
| 86 | 86 | - `AFont : TFont` - шрифт, который должен быть применен к части текста | |
| 87 | 87 | ||
| 88 | 88 | ``` pascal | |
| 89 | 89 | procedure SetTextAttributes(TextStart, TextLen: Integer; const TextParams: TFontParams); | |
| 90 | 90 | ``` | |
| 91 | 91 | ||
| 92 | 92 | - `TextStart : Integer` - первый символ, который будет изменен | |
| 93 | 93 | - `TextLen : Integer` - количество символов для изменения | |
| 94 | 94 | - `TextParams : TFontParams` - параметры шрифта, которые будут установлены | |
| 95 | 95 | ||
| 96 | 96 | Методы `SetTextureAttributes` изменяют указанный стиль текстового диапазона. Параметры шрифта передаются в обоих методах, параметром `AFont` (объект LCL `TFont`) или `TFontParams` (объявлено в RichMemo) | |
| 97 | 97 | ||
| 98 | 98 | Установка атрибутов текста не меняет текущий выбор. Если необходимо изменить стиль выделенного в данный момент текста, вам следует выбрать `SelStart` и `SelLength` в качестве значений текстового диапазона: | |
| 99 | 99 | ||
| 100 | 100 | ``` pascal | |
| 101 | 101 | RichMemo1.SetTextAttributes(RichMemo1.SelStart, RichMemo1.SelLength, FontDialog1.Font); | |
| 102 | 102 | ``` | |
| 103 | 103 | ||
| 104 | 104 | ### GetTextAttributes | |
| 105 | 105 | ||
| 106 | 106 | ``` pascal | |
| 107 | 107 | function GetTextAttributes(TextStart: Integer; var TextParams: TFontParams): Boolean; virtual; | |
| 108 | 108 | ``` | |
| 109 | 109 | ||
| 110 | 110 | - `TextStart : Integer` - позиция символа для запроса параметров шрифта | |
| 111 | 111 | - `var TextParams : TFontParams` - выходное значение, заполненное атрибутами символа шрифта. Если метод завершается неудачно и возвращает `false`, значения поля записи будут неопределенными. | |
| 112 | 112 | ||
| 113 | 113 | Заполняет параметры шрифта символа в позиции `TextStart`. Метод возвращает `True`, если `TextStart` является действительной позицией символа, и `False` в противном случае. | |
| 114 | 114 | ||
| 115 | 115 | ### GetStyleRange | |
| 116 | 116 | ||
| 117 | 117 | ``` pascal | |
| 118 | 118 | function GetStyleRange(CharPos: Integer; var RangeStart, RangeLen: Integer): Boolean; virtual; | |
| 119 | 119 | ``` | |
| 120 | 120 | ||
| 121 | 121 | Возвращает диапазон символов с одинаковыми параметрами шрифта, т.е. все символы в диапазоне имеют одинаковые имя, размер, цвет и стили шрифта. | |
| 122 | 122 | ||
| 123 | 123 | - `CharPos : Integer` - символ, который принадлежит диапазону стилей. Позиция не обязательно быть в начале диапазона стилей. Она может быть в середине конца диапазона стилей. Первая позиция символа возвращается параметром `RangeStart`. | |
| 124 | 124 | - `var RangeStart : Integer` - первый символ в диапазоне | |
| 125 | 125 | - `var RangeLen : Integer` - количество символов в диапазоне | |
| 126 | 126 | ||
| 127 | 127 | Метод возвращает `true` в случае успеха. Метод возвращает `false`, если `CharPos` имеет неправильное значение - больше доступных символов или какая-либо другая ошибка. | |
| 128 | 128 | ||
| 129 | 129 | ### CharAtPos | |
| 130 | 130 | ||
| 131 | 131 | ``` pascal | |
| 132 | 132 | function CharAtPos(x,y: Integer): Integer; virtual; | |
| 133 | 133 | ``` | |
| 134 | 134 | ||
| 135 | 135 | Возвращает смещение символа от нулевой позиции (не позиция UTF8). Возвращает -1 в случае неудачи. | |
| 136 | 136 | ||
| 137 | 137 | - `x, y` - точка в клиентской области элемента управления RichMemo. | |
| 138 | 138 | ||
| 139 | 139 | Метод знает о состоянии прокрутки элемента управления. Таким образом, два вызова `CharAtPos(0,0)` могут возвращать разные значения, если между вызовами изменяется позиция прокрутки. Смотрите "examples/hittest" для \[получения\] примера использования. | |
| 140 | 140 | ||
| 141 | 141 | Если указанные `x,y` будут вне содержимого RichMemo, возвращаемое значение \[будет\] неопределенным. \[Поведение\] остается \[на усмотрение\] набора виджетов, который либо возвращает -1, либо закрывает доступный символ. | |
| 142 | 142 | ||
| 143 | 143 | ### SetRangeColor | |
| 144 | 144 | ||
| 145 | 145 | ``` pascal | |
| 146 | 146 | procedure SetRangeColor(TextStart, TextLength: Integer; FontColor: TColor); | |
| 147 | 147 | ``` | |
| 148 | 148 | ||
| 149 | 149 | Метод устанавливает цвет символов в указанном диапазоне для FontColor. Другие параметры шрифта (имя, размер, стили) остаются без изменений. | |
| 150 | 150 | ||
| 151 | 151 | - `TextStart: Integer` - первый символ в диапазоне | |
| 152 | 152 | - `TextLength: Integer` - количество символов в диапазоне | |
| 153 | 153 | - `FontColor: TColor` - цвет, который должен быть установлен | |
| 154 | 154 | ||
| 155 | 155 | ### SetRangeParams | |
| 156 | 156 | ||
| 157 | 157 | ``` pascal | |
| 158 | 158 | procedure SetRangeParams(TextStart, TextLength: Integer; ModifyMask: TTextModifyMask; | |
| 159 | 159 | const fnt: TFontParams; AddFontStyle, RemoveFontStyle: TFontStyles); overload; | |
| 160 | 160 | ``` | |
| 161 | 161 | ||
| 162 | 162 | Метод изменяет параметры шрифта в указанном диапазоне. | |
| 163 | 163 | ||
| 164 | 164 | - `TextStart` - первый символ в диапазоне | |
| 165 | 165 | - `TextLength` - количество символов в диапазоне | |
| 166 | 166 | - `ModifyMask` - показывает, какие именно атрибуты шрифта должны быть обновлены. Маска принимает любую комбинацию из следующих значений: | |
| 167 | 167 | - `tmm_Color` - Цвет шрифта будет изменен (поле `fnt.Color` должно быть заполнено) | |
| 168 | 168 | - `tmm_Name` - имя шрифта будет изменено (поле `fnt.Name` должно быть заполнено) | |
| 169 | 169 | - `tmm_Size` - размер шрифта будет изменен (поле `fnt.Size` должно быть заполнено) | |
| 170 | 170 | - `tmm_Styles` - стили шрифта будут изменены в соответствии с параметрами `AddFontStyle, RemoveFontStyle` | |
| 171 | 171 | - `tmm_BackColor` - Цвет подсветки текста (фона) будет изменен. (поля `fnt.HasBkClr` и `fnt.BkColor` должны быть заполнены) | |
| 172 | 172 | - Отправка пустой маски приведет к возврату метода без внесения каких-либо изменений. | |
| 173 | 173 | - `fnt` - Параметры шрифта, которые будут использоваться, в зависимости от значений `ModifyMask`. | |
| 174 | 174 | - `AddFontStyle` - набор стилей, которые должны применяться к диапазону (используется только если `tmm_Style`s в `ModifyMask`, в противном случае игнорируется) | |
| 175 | 175 | - `RemoveFontStyle` - набор стилей шрифта должен быть удален из диапазона (используется только если `tmm_Styles` в `ModifyMask`, в противном случае игнорируется) | |
| 176 | 176 | ||
| 177 | 177 | ``` pascal | |
| 178 | 178 | procedure SetRangeParams(TextStart, TextLength: Integer; | |
| 179 | 179 | ModifyMask: TTextModifyMask; const FontName: String; | |
| 180 | 180 | FontSize: Integer; FontColor: TColor; | |
| 181 | 181 | AddFontStyle, RemoveFontStyle: TFontStyles); | |
| 182 | 182 | ``` | |
| 183 | 183 | ||
| 184 | 184 | Перегруженная версия метода. Это просто оболочка вокруг параметра, использующая структуру `TFontParams`. Метод не поддерживает изменение цвета фона, вы должны использовать версию `TFontParams` | |
| 185 | 185 | ||
| 186 | 186 | - `FontName` - имя шрифта, которое должно быть установлено (используется только если `tmm_Name` в `ModifyMask`, в противном случае игнорируется) | |
| 187 | 187 | - `FontColor` - Цвет шрифта, который должен быть установлен (используется только если `tmm_Color` в `ModifyMask`, в противном случае игнорируется) | |
| 188 | 188 | ||
| 189 | 189 | Например, если используется следующий код | |
| 190 | 190 | ||
| 191 | 191 | ```delphi | |
| 192 | 192 | RichMemo1.SetRangeParams ( | |
| 193 | 193 | RichMemo1.SelStart, RichMemo1.SelLength, | |
| 194 | 194 | [tmm_Styles, tmm_Color], // только изменение цвета и стиля | |
| 195 | 195 | '', // имя шрифта - оно не используется, поэтому мы можем оставить его пустым | |
| 196 | 196 | 0, // размер шрифта - это размер шрифта, мы можем оставить его пустым | |
| 197 | 197 | clGreen, // сделать весь текст в выбранной области зеленым цветом | |
| 198 | 198 | [fsBold, fsItalic], // добавление жирного и курсивного стилей | |
| 199 | 199 | [] | |
| 200 | 200 | ); | |
| 201 | 201 | ``` | |
| 202 | 202 | ||
| 203 | 203 | ### GetParaAlignment | |
| 204 | 204 | ||
| 205 | 205 | Получает выравнивание абзаца | |
| 206 | 206 | ||
| 207 | 207 | ``` pascal | |
| 208 | 208 | function GetParaAlignment(TextStart: Integer; var AAlign: TParaAlignment): Boolean; | |
| 209 | 209 | ``` | |
| 210 | 210 | ||
| 211 | 211 | - `TextStart` - позиция символа, который принадлежит абзацу | |
| 212 | 212 | - `AAlign` - получение выравнивания абзаца. | |
| 213 | 213 | ||
| 214 | 214 | **Примечание**: | |
| 215 | 215 | ||
| 216 | 216 | - Win32 - выравнивание по ширине не работает в Windows XP и более ранних версиях. | |
| 217 | 217 | - OSX - из-за ограничений Carbon, это не работает в Carbon, но работает для виджетов Cocoa. | |
| 218 | 218 | ||
| 219 | 219 | ### SetParaAlignment | |
| 220 | 220 | ||
| 221 | 221 | Устанавливает выравнивание абзаца | |
| 222 | 222 | ||
| 223 | 223 | ``` pascal | |
| 224 | 224 | procedure SetParaAlignment(TextStart, TextLen: Integer; AAlign: TParaAlignment); | |
| 225 | 225 | ``` | |
| 226 | 226 | ||
| 227 | 227 | **Примечание**: | |
| 228 | 228 | ||
| 229 | 229 | - Win32 - выравнивание по ширине не работает в Windows XP и более ранних версиях. | |
| 230 | 230 | - OSX - из-за ограничений Carbon, это не работает в Carbon, но работает для виджетов Cocoa. Также необходимо, чтобы правильное выравнивание было загружено из файла RTF. | |
| 231 | 231 | ||
| 232 | 232 | ### GetParaMetric | |
| 233 | 233 | ||
| 234 | 234 | Возвращает отступ метрики абзаца для данного абзаца  | |
| 235 | 235 | ||
| 236 | 236 | - `FirstLine` - смещение для первой строки (в пунктах) абзаца от начала элемента управления \[(т.н. "красная строка")\] | |
| 237 | 237 | - `TailIndent` - смещение для каждой строки (в пунктах), за исключением первой строки, абзаца от конца элемента управления | |
| 238 | 238 | - `HeadIndent` - смещение для каждой строки (в пунктах) абзаца от начала элемента управления | |
| 239 | 239 | - `SpaceBefore` - дополнительное место перед абзацем (в пунктах) | |
| 240 | 240 | - `SpaceAfter` - дополнительное место после абзаца (в пунктах) | |
| 241 | 241 | - `LineSpacing` - коэффициент, используемый для расчета межстрочного интервала между строками в абзаце. Коэффициент применяется к размеру шрифта (самый высокий в строке), а не к высоте строки. Таким образом, это соответствует свойству CSS line-height. Обратите внимание, что нормальный межстрочный интервал равен 1,2. То есть шрифт размером 12 пт, фактический межстрочный интервал (равный 1,2) приведет к высоте строки 14 пт. | |
| 242 | 242 | - не поддерживается в WinXP или более ранних версиях | |
| 243 | 243 | - в большинстве систем не будет разрешено, если для межстрочного интервала установлено значение меньше 1,2. Значение будет проигнорировано, и оно по умолчанию будет равно 1,2 | |
| 244 | 244 | ||
| 245 | 245 | **Примечание** | |
| 246 | 246 | ||
| 247 | 247 | - Параметры абзаца RichEdit указываются в пикселях, а не в точках, поэтому вам нужно либо преобразовать эти размеры самостоятельно, либо использовать метод RichMemoHelper. | |
| 248 | 248 | - обозначение смещений «влево»/«вправо» исключено, чтобы избежать путаницы для RTL. | |
| 249 | 249 | ||
| 250 | 250 | ``` pascal | |
| 251 | 251 | function GetParaMetric(TextStart: Integer; var AMetric: TParaMetric): Boolean; | |
| 252 | 252 | ``` | |
| 253 | 253 | ||
| 254 | 254 | ### SetParaMetric | |
| 255 | 255 | ||
| 256 | 256 | Устанавливает метрики абзаца | |
| 257 | 257 | ||
| 258 | 258 | ``` pascal | |
| 259 | 259 | procedure SetParaMetric(TextStart, TextLen: Integer; const AMetric: TParaMetric); | |
| 260 | 260 | ``` | |
| 261 | 261 | ||
| 262 | 262 | Рекомендуется использовать функцию `InitParaMetric` для инициализации структуры `TParaMetric`. В противном случае обнуление структуры равно ее размеру (т.е. достаточно `FillChar(m, sizeof(TParaMetric), 0)`. Если значения `TParaMetric` получены из вызова `GetParaMetric`, то структура считается правильно инициализированной). | |
| 263 | 263 | ||
| 264 | 264 | ### GetParaRange | |
| 265 | 265 | ||
| 266 | 266 | Возвращает диапазон символов для абзаца. Абзац идентифицируется символом. | |
| 267 | 267 | ||
| 268 | 268 | ``` pascal | |
| 269 | 269 | function GetParaRange(CharOfs: Integer; var ParaRange: TParaRange): Boolean; | |
| 270 | 270 | function GetParaRange(CharOfs: Integer; var TextStart, TextLength: Integer): Boolean; | |
| 271 | 271 | ``` | |
| 272 | 272 | ||
| 273 | 273 | `CharOfs` - символ, который принадлежит абзацу, диапазон которого возвращается. `TParaRange` - это структура, которая возвращает 3 поля | |
| 274 | 274 | ||
| 275 | 275 | - `start` - первый символ в абзаце | |
| 276 | 276 | - `lengthNoBr` - длина абзаца, за исключением символа разрыва строки | |
| 277 | 277 | - `length` - длина абзаца, включая разрыв строки, если присутствующая последняя строка в элементе управления не содержит символа перевода строки, следовательно, `длина = lengthNoBr`. | |
| 278 | 278 | ||
| 279 | 279 | ### SetParaTabs | |
| 280 | 280 | ||
| 281 | 281 | Устанавливает набор табуляций для абзацев указанной длины. | |
| 282 | 282 | ||
| 283 | 283 | ``` pascal | |
| 284 | 284 | procedure SetParaTabs(TextStart, TextLen: Integer; const AStopList: TTabStopList); | |
| 285 | 285 | ``` | |
| 286 | 286 | ||
| 287 | 287 | - `TextStart` | |
| 288 | 288 | - `TextLen` | |
| 289 | 289 | - `AStopList` - структура, которая содержит массив табуляций. | |
| 290 | 290 | - `Count` - указывает количество инициализированных элементов. | |
| 291 | 291 | - `Tabs` - массив содержит описание каждой позиции табуляции, состоящее из `Offset` и `Alignment`. | |
| 292 | 292 | - `Offset` - смещение точки табуляции в пунктах (с левой стороны элемента управления) | |
| 293 | 293 | - `Align` - выравнивание позиции табуляции (`tabLeft` - по умолчанию, `tabCenter, tabRight, tabDecimal`). | |
| 294 | 294 | ||
| 295 | 295 | **Примечание** | |
| 296 | 296 | ||
| 297 | 297 | Renamefest | |
| 298 | 298 | до r4140 перечисляемыми значениями `TTabAlignment` были `taLeft, taCenter, taRight, taDecimal`, но они вступали в противоречие с объявлениями `Classes.TAlignment`. Таким образом суффикс был изменен. | |
| 299 | 299 | ||
| 300 | 300 | win32 | |
| 301 | 301 | позволяет не более 32 табуляций | |
| 302 | 302 | ||
| 303 | 303 | gtk2 | |
| 304 | 304 | поддерживается только выравнивание `tabLeft` | |
| 305 | 305 | ||
| 306 | 306 | carbon | |
| 307 | 307 | не реализовано | |
| 308 | 308 | ||
| 309 | 309 | ### GetParaTabs | |
| 310 | 310 | ||
| 311 | 311 | Получает массив табуляции. Если конкретные вкладки не указаны (по умолчанию виджет табуляции), счетчик AStopList будет установлен в 0. | |
| 312 | 312 | ||
| 313 | 313 | ``` pascal | |
| 314 | 314 | function GetParaTabs(CharOfs: Integer; var AStopList: TTabStopList): Boolean; | |
| 315 | 315 | ``` | |
| 316 | 316 | ||
| 317 | 317 | ### SetRangeParaParams | |
| 318 | 318 | ||
| 319 | 319 | Выборочно устанавливает метрики абзаца | |
| 320 | 320 | ||
| 321 | 321 | ``` pascal | |
| 322 | 322 | procedure SetRangeParaParams(TextStart, TextLength: Integer; ModifyMask: TParaModifyMask; const ParaMetric: TParaMetric); | |
| 323 | 323 | ``` | |
| 324 | 324 | ||
| 325 | 325 | - `TextStart` - символ первого абзаца, чтобы тоже применить стиль | |
| 326 | 326 | - `TextLength` - количество символов, которые должны изменить свойства абзаца | |
| 327 | 327 | - `ModifyMask` - Маска определяет, какой показатель должен быть установлен для каждого абзаца в блоке `TextStart..TextLength`.Другие символы останутся без изменений. Являются членами набора | |
| 328 | 328 | - `pmm_FirstLine` - изменяет отступ первой строки. Поле `FirstLine` константы `ParaMetric` должно быть инициализировано | |
| 329 | 329 | - `pmm_HeadIndent` - изменяет отступ абзаца с головы. Поле `HeadIndent` константы `ParaMetric` должно быть инициализировано | |
| 330 | 330 | - `pmm_TailIndent` - изменяет отступ абзаца с хвоста. Поле `TailIndent` константы `ParaMetric` должно быть инициализировано | |
| 331 | 331 | - `pmm_SpaceBefore` - меняет пробел до абзаца. Поле `SpaceBefore` константы `ParaMetric` должно быть инициализировано | |
| 332 | 332 | - `pmm_SpaceAfter` - меняет пробел после (ниже) абзаца. Поле `SpaceAfter` константы `ParaMetric` должно быть инициализировано | |
| 333 | 333 | - `pmm_LineSpacing` - межстрочный интервал внутри абзаца. Поле `LineSpace` константы `ParaMetric` должно быть инициализировано | |
| 334 | 334 | - `ParaMetric` - структура, содержащая значения, которые будут установлены. Только поля, указанные \[структурой\] `ModifyMask` должны быть инициализированы | |
| 335 | 335 | ||
| 336 | 336 | ### LoadRichText | |
| 337 | 337 | ||
| 338 | 338 | ``` pascal | |
| 339 | 339 | function LoadRichText(Source: TStream): Boolean; virtual; | |
| 340 | 340 | ``` | |
| 341 | 341 | ||
| 342 | 342 | - `Source: TStream` - поток для чтения данных из форматированного текста | |
| 343 | 343 | ||
| 344 | 344 | Метод загружает данные в формате RTF из указанного потока. Возвращает true в случае успеха и false в противном случае. Если source равно nil, метод возвращает false. | |
| 345 | 345 | ||
| 346 | 346 | Содержимое TRichMemo полностью заменяется содержимым в исходном потоке. Текущий выбор текста сбрасывается. | |
| 347 | 347 | ||
| 348 | 348 | ### SaveRichText | |
| 349 | 349 | ||
| 350 | 350 | ``` pascal | |
| 351 | 351 | function SaveRichText(Dest: TStream): Boolean; virtual; | |
| 352 | 352 | ``` | |
| 353 | 353 | ||
| 354 | 354 | - `Source: TStream` - поток для записи данных форматированного текста | |
| 355 | 355 | ||
| 356 | 356 | Метод сохраняет RTF-кодированные данные в указанном потоке. Возвращает true в случае успеха и false в противном случае. Если source равно nil, метод возвращает false. | |
| 357 | 357 | ||
| 358 | 358 | Текущее состояние TRichMemo не меняется после возврата метода. | |
| 359 | 359 | ||
| 360 | 360 | ### Search | |
| 361 | 361 | ||
| 362 | 362 | ``` pascal | |
| 363 | 363 | function Search(const ANiddle: string; Start, Len: Integer; const SearchOpt: TSearchOptions): Integer; | |
| 364 | 364 | ``` | |
| 365 | 365 | ||
| 366 | 366 | - `ANiddle: string` - текст для поиска. | |
| 367 | 367 | - `Start: Integer` - позиция символа, с которой начинается поиск, если -1 или 0 - поиск сначала. | |
| 368 | 368 | - `Len: Integer` - длина (в символах, а не в байтах) текста для поиска посередине. | |
| 369 | 369 | - `SearchOpt: TSearchOptions` | |
| 370 | 370 | - `soMatchCase` - поиск с учетом регистра. | |
| 371 | 371 | - `soBackward` - поиск от конца документа до символа, обозначенного параметром "Start". | |
| 372 | 372 | - `soWholeWord` - поиск всего слова. | |
| 373 | 373 | ||
| 374 | 374 | Метод возвращает положение символа найденной подстроки. Позиция подходит для использования в свойстве `SelStart`. Тем не менее, может быть невозможно использовать для операции прямого копирования, если в коде присутствуют символы Unicode. Вместо этого следует использовать UTF8Copy. | |
| 375 | 375 | ||
| 376 | 376 | Если `ANiddle` не был найден в тексте, возвращается -1 | |
| 377 | 377 | ||
| 378 | 378 | ``` pascal | |
| 379 | 379 | function Search(const ANiddle: string; Start, Len: Integer; const SearchOpt: TSearchOptions; | |
| 380 | 380 | var TextStart, TextLength: Integer): Boolean; | |
| 381 | 381 | ``` | |
| 382 | 382 | ||
| 383 | 383 | (Метод введен с r5115) | |
| 384 | 384 | ||
| 385 | 385 | - `ANiddle: string` - текст для поиска. | |
| 386 | 386 | - `Start: Integer` - позиция символа, с которой начинается поиск, если -1 или 0 - поиск сначала. | |
| 387 | 387 | - `Len: Integer` - длина (в символах, а не в байтах) текста для поиска посередине. | |
| 388 | 388 | - `SearchOpt: TSearchOptions` | |
| 389 | 389 | - `soMatchCase` - поиск с учетом регистра | |
| 390 | 390 | - `soBackward` - поиск от конца документа до символа, обозначенного параметром "Start". | |
| 391 | 391 | - `soWholeWord` - поиск всего слова. | |
| 392 | 392 | - `(output) ATextStart` - позиция найденного текста (в символах) | |
| 393 | 393 | - `(output) ATextLength` - длина найденного текста (в символах (позиции курсора!)) | |
| 394 | 394 | ||
| 395 | 395 | Метод возвращает значение true, если искомая подстрока найдена, в противном случае - значение false. | |
| 396 | 396 | ||
| 397 | 397 | Возвращенные значения `ATextStart` и `ATextLength` подходят для использования в свойствах `SelStart` и `SelLength`. | |
| 398 | 398 | ||
| 399 | 399 | > **Note:** для сложных сценариев найденный текст может совпадать с искомой подстрокой. Поведение поиска (в сложных сценариях) зависит от набора виджетов. Таким образом, поиск одной и той же строки в разных наборах виджетов (например, win32 или gtk2) может привести к разным результатам. Если вам нужны одинаковые результаты и вы их не получили, создайте отчет об ошибке. | |
| 400 | 400 | ||
| 401 | 401 | Если вам нужно извлечь найденный текст, вы должны использовать метод `GetText()` (передавая значения `ATextStart` и `ATextLength`). | |
| 402 | 402 | ||
| 403 | 403 | ### GetText, GetUText | |
| 404 | 404 | ||
| 405 | 405 | ``` pascal | |
| 406 | 406 | function GetText(TextStart, TextLength: Integer): String; | |
| 407 | 407 | function GetUText(TextStart, TextLength: Integer): UnicodeString; | |
| 408 | 408 | ``` | |
| 409 | 409 | ||
| 410 | 410 | - `TextStart: Integer` -позиция символа для начала извлечения (0 - это первый символ в тексте). | |
| 411 | 411 | - `TextLength: Integer` - длина (в символах, а не в байтах) текста для извлечения | |
| 412 | 412 | ||
| 413 | 413 | `GetText()` возвращает подстроку UTF8 | |
| 414 | 414 | ||
| 415 | 415 | `GetUText()` возвращает подстроку UTF16 | |
| 416 | 416 | ||
| 417 | 417 | Текущее выделение не будет зависеть от операции. (Если вы видите, что выделение пострадало, пожалуйста, сообщите о проблеме). | |
| 418 | 418 | ||
| 419 | 419 | Вы не должны учитывать \[абстрактную\] эффективность любого метода. Например, WinAPI внутренне работает с символами UTF16, поэтому `GetUText()` **может** быть более эффективным для него. В то время как Gtk2 работает с UTF8 и вызов `GetText()` **может** быть более эффективным для него. Вместо того, чтобы думать о базовой системе, вы должны учитывать потребности вашей задачи. | |
| 420 | 420 | ||
| 421 | 421 | ### Redo | |
| 422 | 422 | ||
| 423 | 423 | ``` pascal | |
| 424 | 424 | procedure Redo; | |
| 425 | 425 | ``` | |
| 426 | 426 | ||
| 427 | 427 | Метод восстанавливает последнее предыдущее изменение [undone](http://lazarus-ccr.sourceforge.net/docs/lcl/stdctrls/tcustomedit.undo.html). | |
| 428 | 428 | ||
| 429 | 429 | Вы всегда можете вызвать для проверки [[RichMemo/ru|CanRedo]], если есть какие-либо действия\[, которые\] могут быть переделаны. | |
| 430 | 430 | ||
| 431 | 431 | ## Свойства | |
| 432 | 432 | ||
| 433 | 433 | ### ZoomFactor | |
| 434 | 434 | ||
| 435 | 435 | ``` pascal | |
| 436 | 436 | property ZoomFactor: double | |
| 437 | 437 | ``` | |
| 438 | 438 | ||
| 439 | 439 | Read/Write свойство. Управляет масштабированием содержимого RichMemo. 1.0 - без увеличения. Менее \< 1,0 - уменьшить масштаб, более 1,0 - увеличить масштаб. Если установлено 0 - \[приводится к\] значению по умолчанию равным 1,0 коэффициенту масштабирования (без увеличения). | |
| 440 | 440 | ||
| 441 | 441 | ### HideSelection | |
| 442 | 442 | ||
| 443 | 443 | ``` pascal | |
| 444 | 444 | property HideSelection: Boolean default false | |
| 445 | 445 | ``` | |
| 446 | 446 | ||
| 447 | 447 | Read/Write свойство. Если True, то выделение RichMemo скрыто, пока элемент управления не в фокусе. Если False, выделение отображается постоянно. | |
| 448 | 448 | ||
| 449 | 449 | ### CanRedo | |
| 450 | 450 | ||
| 451 | 451 | ``` pascal | |
| 452 | 452 | property CanRedo: Boolean | |
| 453 | 453 | ``` | |
| 454 | 454 | ||
| 455 | 455 | Если \[возвращаемое значение\] True, в очереди отмены есть действия, которые можно повторить. Если \[возвращаемое\] значение False, в очереди отмены нет действий, которые можно повторить. Вызов Redo не будет иметь никакого эффекта. | |
| 456 | 456 | ||
| 457 | 457 | ### RTF | |
| 458 | 458 | ||
| 459 | 459 | ``` pascal | |
| 460 | 460 | property Rtf: String | |
| 461 | 461 | ``` | |
| 462 | 462 | ||
| 463 | 463 | Read/Write свойство, которое позволяет читать или записывать текст в формате RTF для всего элемента управления. Назначение свойства - иметь возможность устанавливать Rich-Text во время разработки, однако свойство также будет работать во время выполнения. | |
| 464 | 464 | ||
| 465 | - | ||
| 465 | + |  | |
| 466 | 466 | ||
| 467 | 467 | Если значение свойства является пустой строкой, то свойство Lines используется как простой текст для инициализации значения элемента управления во время загрузки. | |
| 468 | 468 | ||
| 469 | 469 | > **Note:** Свойство доступно только в классе TRichMemo, оно недоступно (или вообще не реализовано) в классе TCustomRichMemo. Рекомендуется использовать LoadRichText/SaveRichText для изменения содержимого страницы только потому, что они могут занимать меньше памяти, чем копирование всего расширенного текста в память. | |
| 470 | 470 | ||
| 471 | 471 | > **Note:** **для кроссплатформенной и прямой совместимости** - в настоящее время свойство реализовано на основе набора виджетов, обеспечивающего чтение/запись в формате Rich-text. Весьма вероятно, что в ближайшем будущем оно будет изменено на использование кода чтения/записи RichMemo только RTF-stream. Проблема в том, что старые системы могут не поддерживать последнюю версию RTF. | |
| 472 | 472 | ||
| 473 | 473 | Так что прямо сейчас вы можете столкнуться с проблемой, когда вы создадите проект в Gtk2 и сохраните richmemo время разработки, содержащее символы Unicode. Затем, если вы попытаетесь загрузить его на компьютер с XP и использовать собственный загрузчик widgetset, вы можете увидеть символы, отсутствующие или неправильно отображенные. Переход на использование \[механизмов\] RichMemo загрузки/сохранения RTF предотвратит эту проблему. В настоящее время вы также можете избежать этого, зарегистрировав загрузчики RichMemo (вызовите процедуры RegisterRTFLoader, RegisterRTFSaver при инициализации проекта перед загрузкой любого RichMemo) | |
| 474 | 474 | ||
| 475 | 475 | ## События | |
| 476 | 476 | ||
| 477 | 477 | ### OnSelectionChange | |
| 478 | 478 | ||
| 479 | 479 | ``` pascal | |
| 480 | 480 | property OnSelectionChange: TNotifyEvent | |
| 481 | 481 | TNotifyEvent = procedure (Sender: TObject) of object; | |
| 482 | 482 | ``` | |
| 483 | 483 | ||
| 484 | 484 | Событие запускается всякий раз, когда в RichMemo изменяется выделение: либо программно, либо из-за действий пользователя. | |
| 485 | 485 | ||
| 486 | 486 | ## TRichEditForMemo | |
| 487 | 487 | ||
| 488 | 488 | Помощник класса, который реализует программный интерфейс RichEdit. Помощник объявлен в модуле RichEditHelpers, поэтому вы должны добавить его в раздел использования. Помощники доступны в FPC 2.6.0 или старше. | |
| 489 | 489 | ||
| 490 | 490 | ### Методы | |
| 491 | 491 | ||
| 492 | 492 | #### FindText | |
| 493 | 493 | ||
| 494 | 494 | Поиск заданного диапазона в тексте для целевой строки | |
| 495 | 495 | ||
| 496 | 496 | ### Свойства | |
| 497 | 497 | ||
| 498 | 498 | #### SelAttributes | |
| 499 | 499 | ||
| 500 | 500 | Читает/Изменяет атрибуты символа текущего выделения | |
| 501 | 501 | ||
| 502 | 502 | ### Paragraph | |
| 503 | 503 | ||
| 504 | 504 | Читает/Изменяет атрибуты абзаца текущего выделения. | |
| 505 | 505 | ||
| 506 | 506 | ### RichMemoUtils | |
| 507 | 507 | ||
| 508 | 508 | Представлен модуль, добавляющий некоторые полезные функции, специфичные для ОС, для работы с RichMemo. | |
| 509 | 509 | ||
| 510 | 510 | #### InsertImageFromFile | |
| 511 | 511 | ||
| 512 | 512 | `function InsertImageFromFile (const ARichMemo: TCustomRichMemo; APos: Integer;`\ | |
| 513 | 513 | ` const FileNameUTF8: string;`\ | |
| 514 | 514 | ` const AImgSize: TSize`\ | |
| 515 | 515 | `): Boolean = nil;` | |
| 516 | 516 | ||
| 517 | 517 | *Отказ от ответственности: функция будет вставлять файл изображения в RichMemo (если он реализован набором виджетов), но очень неэффективным способом. Изображение будет прочитано снова, и память будет перераспределяться для изображения каждый раз. Поэтому, пожалуйста, не используйте его для смайликов в чате. Наилучшим \[выбором будет\] API (с кэшированием данных). (Вот почему этот метод не является частью класса TCustomRichMemo).* | |
| 518 | 518 | ||
| 519 | 519 | - `APos` - позиция в тексте | |
| 520 | 520 | - `AImgSize` - размер, который нужно выставлять в **ТОЧКАХ**, а не в пикселях! Если и `cx`, и `cy` равны 0, размер изображения не будет изменен вообще. Если только один \[из размеров\] - `cx, cy` - равен нулю, результаты \[будут\] неопределенными. | |
| 521 | 521 | ||
| 522 | 522 | Есть также служебная функция **InsertImageFromFileNoResize**, которая вызывает InsertImageFromFile, передавая размер как 0. | |
| 523 | 523 | ||
| 524 | 524 | Пример использования | |
| 525 | 525 | ||
| 526 | 526 | ``` pascal | |
| 527 | 527 | procedure TForm1.Button1Click(Sender: TObject); | |
| 528 | 528 | begin | |
| 529 | 529 | // вызов диалога для выбора картинки для вставки | |
| 530 | 530 | if OpenDialog1.Execute then | |
| 531 | 531 | // вставка картинки в текущую позицию курсора RichMemo | |
| 532 | 532 | InsertImageFromFileNoResize(RichMemo1, RichMemo1.SelStart, OpenDialog1.FileName); | |
| 533 | 533 | end; | |
| 534 | 534 | ``` | |
| 535 | 535 | ||
| 536 | 536 | ### InsertStyledText, InsertColorStyledText, InsertFontText | |
| 537 | 537 | ||
| 538 | 538 | Набор функций, которые упрощают добавление и замену стилизованного текста. Указанный стиль текста применяется к вставке. Общее правило для всех функций, если `InsPos` (позиция вставки) отрицательна - текст добавляется в конец. Для вставки текста в начало теста `InsPos` должна быть установлена в 0. | |
| 539 | 539 | ||
| 540 | 540 | Вставленный текст не обязательно должен находиться на новой строке или добавлять новую строку. Возможно, вы захотите добавить символ `LineFeed` в параметр `TextUTF8`, чтобы вставленный текст был новой строкой. | |
| 541 | 541 | ||
| 542 | 542 | ``` pascal | |
| 543 | 543 | procedure InsertStyledText( | |
| 544 | 544 | const ARichMemo: TCustomRichMemo; | |
| 545 | 545 | const TextUTF8: String; | |
| 546 | 546 | AStyle: TFontStyles; | |
| 547 | 547 | InsPos : Integer = -1 ) | |
| 548 | 548 | ``` | |
| 549 | 549 | ||
| 550 | 550 | `InsertStyledText` вставляет стилизованный текст в указанную позицию. | |
| 551 | 551 | ||
| 552 | 552 | ``` pascal | |
| 553 | 553 | procedure InsertColorStyledText( | |
| 554 | 554 | const ARichMemo: TCustomRichMemo; | |
| 555 | 555 | const TextUTF8: String; | |
| 556 | 556 | AColor: TColor; | |
| 557 | 557 | AStyle: TFontStyles; | |
| 558 | 558 | InsPos : Integer = -1 ) | |
| 559 | 559 | ``` | |
| 560 | 560 | ||
| 561 | 561 | `InsertColorStyledText` вставляет текст с указанным стилем и цветом в указанной позиции (по умолчанию в конец RichMemo). | |
| 562 | 562 | ||
| 563 | 563 | ``` pascal | |
| 564 | 564 | procedure InsertFontText( | |
| 565 | 565 | const ARichMemo: TCustomRichMemo; | |
| 566 | 566 | const TextUTF8: String; | |
| 567 | 567 | const prms: TFontParams; | |
| 568 | 568 | InsPos : Integer = -1 ) | |
| 569 | 569 | ``` | |
| 570 | 570 | ||
| 571 | 571 | `InsertFontText` вставляет текст и применяет к нему указанные FontParams. | |
| 572 | 572 | ||
| 573 | 573 | Возможно, вы захотите создать помощник класса для реализации этих функций в качестве методов для RichMemo. Осторожно, если вы используете [[RichMemo/ru|Delphi-совместимый помощник]] - вы можете \[попасть\] в конфликт. | |
| 574 | 574 | ||
| 575 | 575 | ## Установка | |
| 576 | 576 | ||
| 577 | 577 | - Получить последнюю версию из SVN | |
| 578 | 578 | - Откройте пакет и установите его, пересоберите IDE | |
| 579 | 579 | - TRichMemo будет добавлен на вкладку 'Common Controls' | |
| 580 | 580 | ||
| 581 | 581 | ## Часто задаваемые вопросы | |
| 582 | 582 | ||
| 583 | 583 | ### Использование RichMemo в общих библиотеках | |
| 584 | 584 | ||
| 585 | 585 | [Issue \#17412](http://bugs.freepascal.org/view.php?id=17412) Если вам нужно использовать компонент в разделяемой библиотеке, вам может понадобиться добавить ключ -fPIC к опции компилятора «пакета» и «проекта». | |
| 586 | 586 | ||
| 587 | 587 | ## (Delphi) RichEdit-подобный интерфейс | |
| 588 | 588 | ||
| 589 | 589 | [Issue \#14632](http://bugs.freepascal.org/view.php?id=14632) Типичная проблема - портирование существующего кода, использующего RichEdit из Delphi. Интерфейс RichMemo не совпадает с RichEdit во многих отношениях. Но есть два способа справиться с этим: | |
| 590 | 590 | ||
| 591 | 591 | - вы можете создать подкласс из TCustomRichMemo (или RichMemo) и реализовать методы Delphi RichEdit; | |
| 592 | 592 | - вы можете использовать модуль RichMemoHelpers (требуется fpc 2.6.0 или более поздняя версия) и использовать методы, предоставляемые классом Helpers; в настоящее время реализованы свойства SelAttributes и Paragraph. | |
| 593 | 593 | ||
| 594 | 594 | ``` pascal | |
| 595 | 595 | uses ... RichMemo, RichMemoHelpers; | |
| 596 | 596 | ||
| 597 | 597 | TForm = class | |
| 598 | 598 | RichMemo1 : TRichMemo; | |
| 599 | 599 | ||
| 600 | 600 | // Свойство SelAttributes недоступно в базовом классе, | |
| 601 | 601 | // но добавлено помощником, определенным в модуле RichMemoHelpers | |
| 602 | 602 | RichMemo1.SelAttributes.Name := 'Courier New'; | |
| 603 | 603 | ``` | |
| 604 | 604 | ||
| 605 | 605 | ## Добавление смешанного цветного текста в конец RichMemo | |
| 606 | 606 | ||
| 607 | 607 | Если вам просто нужна простая раскраска, то вот пример, который будет каждый раз добавлять новую строку со случайным цветом (протестировано в Windows): | |
| 608 | 608 | ||
| 609 | 609 | ``` pascal | |
| 610 | 610 | procedure TForm1.Button1Click(Sender: TObject); | |
| 611 | 611 | var | |
| 612 | 612 | i, j: integer; | |
| 613 | 613 | str: string; | |
| 614 | 614 | begin | |
| 615 | 615 | with Richmemo1 do | |
| 616 | 616 | begin | |
| 617 | 617 | str := 'Newline text'; | |
| 618 | 618 | i := Length(Lines.Text) - Lines.Count; // CR(перевод каретки) как #10#13 считается только один раз, так что вычтите его один раз | |
| 619 | 619 | j := Length(str) + 1; // +1 сделать CR в том же формате | |
| 620 | 620 | Lines.Add(str); | |
| 621 | 621 | SetRangeColor(i, j, Round(random * $FFFFFF)); | |
| 622 | 622 | end; | |
| 623 | 623 | end; | |
| 624 | 624 | ``` | |
| 625 | 625 | ||
| 626 | 626 | ` ``Newline text`\ | |
| 627 | 627 | ` ``NewLine text`\ | |
| 628 | 628 | ` ``NewLine text` | |
| 629 | 629 | ||
| 630 | 630 | Альтернативный пример простой раскраски (протестировано на Windows): | |
| 631 | 631 | ||
| 632 | 632 | ``` pascal | |
| 633 | 633 | procedure TForm1.Button2Click(Sender: TObject); | |
| 634 | 634 | begin | |
| 635 | 635 | with RichMemo1 do | |
| 636 | 636 | begin | |
| 637 | 637 | Lines.Add('Line in red'); | |
| 638 | 638 | SetRangeColor(Length(Lines.Text) - Length(Lines[Lines.Count - 1]) - Lines.Count - 1, Length(Lines[Lines.Count - 1]), clRed); | |
| 639 | 639 | ||
| 640 | 640 | Lines.Add('Line in blue'); | |
| 641 | 641 | SetRangeColor(Length(Lines.Text) - Length(Lines[Lines.Count - 1]) - Lines.Count - 1, Length(Lines[Lines.Count - 1]), clBlue); | |
| 642 | 642 | ||
| 643 | 643 | Lines.Add('Normal line.'); | |
| 644 | 644 | Lines.Add('Normal line.'); | |
| 645 | 645 | ||
| 646 | 646 | Lines.Add('Line in green '); | |
| 647 | 647 | SetRangeColor(Length(Lines.Text) - Length(Lines[Lines.Count - 1]) - Lines.Count - 1, Length(Lines[Lines.Count - 1]), clGreen); | |
| 648 | 648 | end; | |
| 649 | 649 | end; | |
| 650 | 650 | ``` | |
| 651 | 651 | ||
| 652 | 652 | ` ``Line in red`\ | |
| 653 | 653 | ` ``Line in blue`\ | |
| 654 | 654 | ` ``Normal line.`\ | |
| 655 | 655 | ` ``Normal line.`\ | |
| 656 | 656 | ` ``Line in green` | |
| 657 | 657 | ||
| 658 | 658 | Если вам нужна смешанная раскраска, то это пример, который добавит новую строку с несколькими разноцветными словами (протестировано в Windows): | |
| 659 | 659 | ||
| 660 | 660 | ``` pascal | |
| 661 | 661 | procedure TForm1.Button3Click(Sender: TObject); | |
| 662 | 662 | procedure AddColorStr(s: string; const col: TColor = clBlack; const NewLine: boolean = true); | |
| 663 | 663 | begin | |
| 664 | 664 | with RichMemo1 do | |
| 665 | 665 | begin | |
| 666 | 666 | if NewLine then | |
| 667 | 667 | begin | |
| 668 | 668 | Lines.Add(''); | |
| 669 | 669 | Lines.Delete(Lines.Count - 1); // избегаем двойного межстрочного интервала | |
| 670 | 670 | end; | |
| 671 | 671 | ||
| 672 | 672 | SelStart := Length(Text); | |
| 673 | 673 | SelText := s; | |
| 674 | 674 | SelLength := Length(s); | |
| 675 | 675 | SetRangeColor(SelStart, SelLength, col); | |
| 676 | 676 | ||
| 677 | 677 | // отменяем выделение вставленной строки и помещаем курсор в конец текста | |
| 678 | 678 | SelStart := Length(Text); | |
| 679 | 679 | SelText := ''; | |
| 680 | 680 | end; | |
| 681 | 681 | end; | |
| 682 | 682 | begin | |
| 683 | 683 | AddColorStr('Black, '); | |
| 684 | 684 | AddColorStr('Green, ', clGReen, false); | |
| 685 | 685 | AddColorStr('Blue, ', clBlue, false); | |
| 686 | 686 | AddColorStr('Red', clRed, false); | |
| 687 | 687 | end; | |
| 688 | 688 | ``` | |
| 689 | 689 | ||
| 690 | 690 | ` ``Black, ``Green, ``Blue, ``Red`\ | |
| 691 | 691 | ` ``Black, ``Green, ``Blue, ``Red`\ | |
| 692 | 692 | ` ``Black, ``Green, ``Blue, ``Red` | |
| 693 | 693 | ||
| 694 | 694 | ## Разбор языка разметки | |
| 695 | 695 | ||
| 696 | 696 |  Нативные элементы управления rich-edit не поддерживают синтаксический анализ языка разметки. | |
| 697 | 697 | ||
| 698 | 698 | Вам нужно написать эту \[функциональность\] самостоятельно, как показано в примере с mlparse. | |
| 699 | 699 | ||
| 700 | 700 | ## Что внутри | |
| 701 | 701 | ||
| 702 | 702 | ### Матрица поддержки платформы | |
| 703 | 703 | ||
| 704 | 704 | Ожидается, что значения в матрице не будут статическими (за исключением столбца "carbon"), каждая система должна поддерживать все функции, объявленные RichMemo. | |
| 705 | 705 | ||
| 706 | 706 | Обратите внимание, что таблица содержит больше функций, чем опубликовано выше. Это означает, что API-интерфейсы уже доступны в RichMemo, но, поскольку они нестабильны (на некоторых платформах), они считаются «экспериментальными», а не обещанными. | |
| 707 | 707 | ||
| 708 | 708 | | Особенность | Win32 | Gtk2 | Qt | Cocoa | Carbon | | |
| 709 | 709 | |------------------------------------|-------|------|-----|-------|--------| | |
| 710 | 710 | | Выбор цвета и стиля шрифта | | | | | | | |
| 711 | 711 | | Цвет фона шрифта | | | | | | | |
| 712 | 712 | | Подстрочный, надстрочный \[текст\] | | | | | | | |
| 713 | 713 | | \[функция\] GetStyleRange | | | | | | | |
| 714 | 714 | | Выравнивание абзаца | | | | | | | |
| 715 | 715 | | Метрика абзаца | | | | | | | |
| 716 | 716 | | Отступы абзаца | | | | | | | |
| 717 | 717 | | Масштабирование | | | | | | | |
| 718 | 718 | | Печать | | | | | | | |
| 719 | 719 | | Загрузка/сохранение RTF | | | | | | | |
| 720 | 720 | | Возможность вставки | | | | | | | |
| 721 | 721 | ||
| 722 | 722 | ### Win32 | |
| 723 | 723 | ||
| 724 | 724 |   | |
| 725 | 725 | ||
| 726 | 726 | - [RichEdit](https://msdn.microsoft.com/en-us/library/windows/desktop/bb787605%28v=vs.85%29.aspx) используется в качестве системного виджета. Последний известный .dll загружается и инициализируется при запуске. Обратите внимание, что RichEdit 1.0 не поддерживает большинство функций. | |
| 727 | 727 | - Внутренняя оболочка RichEditManager предоставляется для совместимости с Win 9x. Однако это никогда не испытывалось и не проверялось. Также ожидается, что объект TOM может быть упакован как одна из реализаций RichEditManager. Однако имеющийся на месте «менеджер» может быть полностью удален. | |
| 728 | 728 | - Согласно Интернету, элемент управления RichEdit не был обновлен Microsoft для поддержки рисования тем (начиная с XP и до Windows 8.1). Таким образом, RichEdit всегда может выглядеть как старый Win9x в 3D-элементе управления. На основе патча, предоставленного в [опубликованной проблеме](http://bugs.freepascal.org/view.php?id=25111) способ переопределить [WM_NCPAINT](https://msdn.microsoft.com/en-us/library/windows/desktop/dd145212%28v=vs.85%29.aspx) был представлен в r4153. | |
| 729 | 729 | ||
| 730 | 730 | Win32RichMemo предоставляет глобальную переменную NCPaint. Это обработчик рисования не-клиентской области. По умолчанию он пытается нарисовать тематическую границу (см. Win32RichMemo.ThemedNCPaint для реализации). Он обеспечивает хорошие результаты по темам Windows XP, но в более поздних темах (где используются анимация) результаты не так хороши и должны быть обновлены. | |
| 731 | 731 | ||
| 732 | 732 | Чтобы система могла выполнять только NCPaint (т.е. реализация LCL вызывает проблемы или новые окна обновляли RichEdit для правильного рисования границ), вы можете изменить значение NCPaint во время выполнения, сбросив его в nil: | |
| 733 | 733 | ||
| 734 | 734 | ``` pascal | |
| 735 | 735 | uses | |
| 736 | 736 | RichMemo, .. | |
| 737 | 737 | {$ifdef WINDOWS} | |
| 738 | 738 | Win32RichMemo | |
| 739 | 739 | {$endif} | |
| 740 | 740 | ||
| 741 | 741 | initialization | |
| 742 | 742 | {$ifdef WINDOWS} | |
| 743 | 743 | Win32RichMemo.NCPaint:=nil; | |
| 744 | 744 | {$endif} | |
| 745 | 745 | ``` | |
| 746 | 746 | ||
| 747 | 747 | Вы также можете предоставить собственную реализацию NCPaint. Однако, если вы реализуете правильную анимацию рисунка темы, пожалуйста, предоставьте патч. | |
| 748 | 748 | ||
| 749 | 749 | Поведение зависит от реализации Windows и не должно (и не будет) частью интерфейса RichMemo. | |
| 750 | 750 | ||
| 751 | 751 | ### Gtk2 | |
| 752 | 752 | ||
| 753 | 753 | - В качестве системного виджета используется [GtkTextView](https://developer.gnome.org/gtk2/stable/GtkTextView.html). | |
| 754 | 754 | - Subscript и Superscript изначально не поддерживаются, в gtk2richmemo реализован дополнительный код для их реализации. | |
| 755 | 755 | - Маркированные и нумерованные списки эмулируются. | |
| 756 | 756 | ||
| 757 | 757 | ### Gtk3 | |
| 758 | 758 | ||
| 759 | 759 | API между Gtk2 и [Gtk3](https://developer.gnome.org/gtk3/stable/GtkTextView.html) на самом деле не отличаются. Основное отличие в отрисовке. Для Gtk3 активно используется Cairo Canvas. Единственная область, на которую это влияет - "внутренности". Если кто-то хочет внести свой вклад в реализацию Gtk2 - пожалуйста, создайте отдельные модули gtk3richmemoXXX. Не нужно создавать {\$ ifdefs} в модулях gtk2. | |
| 760 | 760 | ||
| 761 | 761 | ### Cocoa | |
| 762 | 762 | ||
| 763 | 763 | - Для Cocoa в качестве системного виджета используется [NSTextView](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSTextView_Class/index.html). | |
| 764 | 764 | - Не каждое семейство шрифтов предоставляет «курсивный» шрифт. Таким образом, даже если вы передадите fsItalic как часть Style для шрифта, он может быть проигнорирован. | |
| 765 | 765 | ||
| 766 | 766 | ### Qt | |
| 767 | 767 | ||
| 768 | 768 | - Используется [QTextEdit](http://doc.qt.io/qt-4.8/qtextedit.html) виджет. В современных C-отображениях для Qt отсутствует множество API-интерфейсов RichText, поэтому полная реализация в настоящее время невозможна. | |
| 769 | 769 | - Следующие классы должны быть сопоставлены с C-функциями: | |
| 770 | 770 | - [QTextBlockFormatH](http://doc.qt.io/qt-4.8/qtextblockformat.html) необходим для выравнивания абзацев (например, отступы абзаца, межстрочный интервал и табуляции). QTextEdit предоставляет только выравнивание абзаца. | |
| 771 | 771 | - [QTextCharFormatH](http://doc.qt.io/qt-4.8/qtextcharformat.html) необходим для дополнительного форматирования символов (то есть вертикальное выравнивание, поддержка ссылок). QTextEdit предоставляет только стили шрифтов. | |
| 772 | 772 | ||
| 773 | 773 | ## См. также | |
| 774 | 774 | ||
| 775 | 775 | - [[RichMemo/Features]] - комментирует некоторые функции в процессе. | |
| 776 | 776 | - [[RichMemo/WorkArounds]] - некоторые заметки о функциях еще не завершены. | |
| 777 | 777 | - [[RichMemo/Defines]] - дополнительные переключатели пакетов, которые позволяют решить проблемы компиляции/времени выполнения | |
| 778 | 778 | - [[RichMemo/Samples]] - еще примеры | |
| 779 | 779 | - [MyNotex](https://sites.google.com/site/mynotex) приложение, которое использует модифицированный пакет Massimo Nardello RichMemo для Linux-Gtk2 | |
| 780 | 780 | - [[TMemo]] | |
| 781 | 781 | - [[KControls|KMemo control]] | |
| 782 | 782 | ||
| 783 | 783 | --- | |
| 784 | 784 | *From the Free Pascal wiki, page "RichMemo/ru", as it stood on 2022-02-28 after a change by Zoltanleo, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).* |
