procedure TFrmCboxInMemo.Button1Click(Sender: TObject);
var
clientPos: TPoint;
lineHeight: Integer;
tmpFont: TFont;
begin
GetCaretPos(clientPos);
{Use the following calculation of line height only if you want your combobox
to appear below the char position you are referencing.}
tmpFont := Canvas.Font;
Canvas.Font := Memo1.Font;
lineHeight := Canvas.TextHeight('Xy');
Canvas.Font := tmpFont;
with ComboBox1 do
begin
{Adjustment of Top by lineHeight only necessary if combobox is to appear below line.}
Top := clientPos.Y + Memo1.Top + lineHeight;
Left := clientPos.X + Memo1.Left;
Visible := true;
SetFocus;
end;
end;
procedure TFrmCboxInMemo.ComboBox1Exit(Sender: TObject);
begin
ComboBox1.Visible := false;
end;
procedure TFrmCboxInMemo.ComboBox1Click(Sender: TObject);
begin
ComboBox1.Visible := false;
end;
Программный код, который вы предоставили, является хорошим стартом, но он не учитывает случай, когда курсор находится в конце строки в мемо. В таких случаях комбобокс будет появляться ниже последней символа на экране, что может не соответствовать вашим ожиданиям.
Чтобы исправить это, вы можете рассчитать верхнюю позицию комбобокса на основе вертикальной позиции скролла мемо и высоты выбранного текста.
Вот обновленная версия вашего кода:
procedureTFrmCboxInMemo.Button1Click(Sender:TObject);varclientPos:TPoint;linePosition,lineHeight:Integer;beginGetCaretPos(clientPos);linePosition:=Memo1.GetCharIndexAt(clientPos.X)-1;// вычитаем один для получения правильной строкиiflinePosition>=0thenbeginMemo1.LineEnd(linePosition,lineHeight);// получаем высоту выбранного текстаwithComboBox1dobeginTop:=clientPos.Y+Memo1.Top;Left:=clientPos.X+Memo1.Left;Visible:=True;SetFocus;end;end;end;procedureTFrmCboxInMemo.ComboBox1Exit(Sender:TObject);beginComboBox1.Visible:=False;end;procedureTFrmCboxInMemo.ComboBox1Click(Sender:TObject);beginComboBox1.Visible:=False;end;
В этом коде мы рассчитываем позицию строки курсора, вызывая метод GetCharIndexAt и вычитая один для получения правильной строки. Затем мы используем эту позицию строки для расчета верхней позиции комбобокса.
Обратите внимание, что этот код предполагает, что вы хотите, чтобы комбобокс появлялся внизу выбранного текста, а не обязательно ниже курсора. Если вам нужно, чтобы комбобокс всегда был виден ниже курсора,regardless of scrolling and line wrapping, вам потребуется более сложное решение.
Чтобы сделать pop-up Combobox по позиции курсора в Memo, можно использовать процедуру GetCaretPos для получения координат курсора и затем задать положение Combobox на основе полученных данных.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.