В TRichEdit или TMemo при нажатии Enter позиционирование курсора в позицию как в предыдущей строке
Вопрос в службу поддержки:
Что делать если я довел мышку до края коврика, а курсор не дошел до края экрана?
unit Unit1;
interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls, ComCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
RichEdit1: TRichEdit;
procedure RichEdit1KeyPress(Sender: TObject; var Key: Char);
private{ Private declarations }public{ Public declarations }end;
var
Form1: TForm1;
implementation{$R *.DFM}uses
richedit;
procedure TForm1.RichEdit1KeyPress(Sender: TObject; var Key: Char);
var
line, col, indent: integer;
S: string;
beginif key = #13 thenbegin
key := #0;
with sender as TRichEdit dobegin{figure out line and column position of caret}
line := PerForm( EM_EXLINEFROMCHAR, 0, SelStart );
Col := SelStart - Perform( EM_LINEINDEX, line, 0 );
{get part of current line in front of caret}
S:= Copy( lines[ line ], 1, col );
{count blanks and tabs in this string}
indent := 0;
while (indent < length( S )) and (S[indent + 1] in [' ', #9]) do
Inc( indent );
{insert a linebreak followed by the substring of blanks and tabs}
SelText := #13#10 + Copy(S, 1, indent);
end;
end;
end;
end.
Код, который вы предоставили, предназначен для имитации поведения, которое можно найти в некоторых текстовых редакторах, где при нажатии клавиши Enter при курсоре на краю экрана он перемещается обратно к тому же положению на предыдущей строке.
Вот как это работает:
Когда нажимается клавиша Enter (detecked by if key = #13 then), код устанавливает переменную key в null-значение (#0) и получает номер строки и столбца курсора с помощью сообщения EM_EXLINEFROMCHAR.
Затем он рассчитывает уровень отступа, счетчик количества пробелов и табов до курсора в текущей строке.
Когда вставляется новая строка, код также копирует подстроку пробелов и табов из оригинальной строки в новую.
Этот код предполагает, что вы хотите поддерживать тот же уровень отступа, что и предыдущая строка. Если вам нужно индентировать каждую последующую строку на фиксированное количество пробелов (например, 4 пробела), вы можете добавить дополнительный шаг для расчета сдвига в зависимости от текущей номер строки или других критериев.
Основной проблемой этого кода является то, что он не обрабатывает случаи, когда пользователь выбрал текст перед нажатием Enter, потому что он только учитывает позицию курсора. Если вам нужно поддерживать выбор-ориентированное поведение (например, вставка новой строки на начало выделенного блока), вам нужно модифицировать код соответствующим образом.
Вот альтернативное решение, которое должно работать и в этом случае:
procedureTForm1.RichEdit1KeyPress(Sender:TObject;varKey:Char);varLine,Col,Indent:Integer;S:String;beginifkey=#13thenbeginkey:=#0;withSenderasTRichEditdobegin// Get the line and column number of the caretLine:=Perform(EM_EXLINEFROMCHAR,0,SelStart);Col:=SelStart-Perform(EM_LINEINDEX,Line,0);// Insert a new line at the current positionSelText:=#13#10+Copy(SelText,1,Col)+' ';// Move the caret to the beginning of the new lineSelStart:=Len(SelText);end;end;end;
В этом коде просто вставляется новая строка на текущем положении и курсор перемещается к началу этой строки. Он не учитывает уровень отступа, что может быть более пользовательски для некоторых пользователей.
Пожалуйста, измените этот код или добавьте дополнительную логику, чтобы соответствовать вашим конкретным требованиям!
В статье описывается решение проблемы с позиционированием курсора в TRichEdit или TMemo при нажатии клавиши Enter, которое позволяет обеспечить его перемещение на следующую строку с сохранением прежнего положения.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS