Delphi правильно позиционирует всплывающую подсказку, связанную с элементом списка - PullRequest
0 голосов
/ 11 января 2019

Как мне убедиться, что подсказка, которую я хочу связать с элементом списка, правильно размещена так, чтобы он находился рядом с рассматриваемым элементом и всегда отображал полный текст шара на экране?

Например, если я введу недопустимый символ при редактировании имени файла в проводнике Windows, появится всплывающая подсказка с сообщением о недопустимых символах. Весь воздушный шар всегда отображается на экране, даже если элемент списка находится рядом с краем экрана или частично находится вне экрана. Хвост всегда располагается в средней части элемента списка. Пузырь обычно находится справа внизу от хвоста, но может быть над ним или слева, если элемент списка находится около нижнего и / или правого краев экрана.

Прежде всего, я не могу заставить пузырь и хвост держаться близко к пункту списка.

procedure TForm1.ListEdited(Sender: TObject; Item: TListItem;
var S: string);
var
  AHint: string;
  R: TRect;
  B : TBalloonHint;
begin
  if TRegEx.IsMatch(S, '[\\/:*?"<>|]') then
  begin
    AHint := 'A file name cannot contain any of the following' + sLineBreak +
      'characters:  \/:*?"<>|';
    R := Item.DisplayRect(drBounds);
    R.TopLeft := ClientToScreen(R.TopLeft);
    R.BottomRight := ClientToScreen(R.BottomRight);

    B := TBalloonHint.Create(Self);
    B.Description := AHint;
    B.HideAfter := 5000;
    B.ShowHint(R);

    S := TRegEx.Replace(S, '[\\/:*?"<>|]', '');
  end;
end;

Я пробовал различные перегрузки ShowHint, а также компонент подсказки JEDI. Я также настроил свойство Top прямоугольника, которое может лучше позиционировать воздушный шар, когда элемент находится в определенной области экрана, но тогда баллон находится в нерабочем положении, когда элемент находится в какой-то другой части экрана.

Delphi 10,3 Rio, Win 7 x64.

1 Ответ

0 голосов
/ 11 января 2019

DisplayRect дает клиентские координаты относительно списка, содержащего элемент, а не форму. Следовательно, при преобразовании в экранные координаты вы должны использовать представление списка в качестве основы, а не форму:

R := Item.DisplayRect(drBounds);
R.TopLeft := ListView1.ClientToScreen(R.TopLeft);         // <--
R.BottomRight := ListView1.ClientToScreen(R.BottomRight); // <--
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...