Delphi проста задачка richedit яку потрібно вирішити до того як ви зважитеся його використовувати,
Як пророкувати символ на якому стоїть курсор?
Якщо ваш досвід підказує конструкцію на зразок:
- то ваш досвід не вірний!
І якщо вам цікаво - то правильна відповідь можна побачити під катом ...
Число узяте незрозуміло звідки? - ну не скажіть! все має логічне пояснення, просто потрібно один раз розібратися!
А все тому, що властивість RichEdit.Text має тип String. а в типі String - нульовий символ зберігає довжину рядка, і тільки після цього йде власне текст: таким чином перший символ в рядку (у нас це "0") має номер "1".
Нумерація символів у властивості RichEdit.SelStart починається з нуля (перший символ має номер = 0), а нумерація символів в рядку (властивість RichEdit.Text. Тип String) йде з одиниці (перший символ має номер = 1)
Друге.
Документація нам вказує, що властивість SelStart вказує на номер символу в тексті. І тут необхідно згадати про символ генерується при перекладі рядка (натисканні на клавішу «Enter») - в текст додаються 2 байта (символу) йдуть підряд: 0x0D і 0x0A.
Нижче опис дане цим символам в Вікіпедії.
Повернення каретки (англ. Carriage return, CR) - керуючий символ ASCII (0x0D, 1310, '\ r'), при виведенні якого курсор переміщається до лівого краю поля, не переходячи на інший рядок. Цей керуючий символ вводиться клавішею «Enter». Будучи записаний у файлі, окремо розглядається як новий рядок тільки в системах Macintosh.
Подача рядки (від англ. Line feed, LF - «подача [паперу] на рядок») - керуючий символ ASCII (0x0A, 10 в десятковій системі числення, '\ n'), при виведенні якого курсор переміщається на наступний рядок. У разі принтера це означає зрушення папера вгору, в разі дисплея - зсув курсору вниз, якщо ще залишилося місце, і прокручування тексту вгору, якщо курсор знаходився на нижньому рядку. Чи повертається при цьому курсор до лівого краю чи ні, залежить від реалізації.
Так ось SelStart вважає ці два байти (повернення каретки - 0х0D. Переклад рядка - 0x0A) - одним символом!
А ось у властивості RichEdit.Text у нього буде номер 7.
Для того щоб все стало зовсім зрозумілим я намалював табличку (перший стовпець - індекс, другий SelStart - відповідність індексу SelStart символу, третій CharPos - відповідність Text [індекс] символу):

І навпаки, знаючи позицію символу в тексті RichEdit.Text зможете провести зміну його атрибутів: