Delphi正确定位与listview项关联的引出序号提示

Delphi正确定位与listview项关联的引出序号提示,delphi,listitem,Delphi,Listitem,如何确保要与listview项目关联的气球提示正确定位,使其位于相关项目旁边,并始终在屏幕上显示完整的气球文本 例如,如果在Windows资源管理器中编辑文件名时输入了无效字符,则会弹出一个气球,说明无效字符是什么。即使列表项靠近屏幕边缘或部分离开屏幕,整个引出序号始终在屏幕上。尾部始终位于列表项的中间底部。气泡通常位于尾部的右下角,但如果列表项靠近屏幕的底部和/或右边缘,则气泡可能位于其上方或左侧 主要是,我无法让气泡和尾巴靠近列表项 procedure TForm1.ListEdited(S

如何确保要与listview项目关联的气球提示正确定位,使其位于相关项目旁边,并始终在屏幕上显示完整的气球文本

例如,如果在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;
程序TForm1.listeded(发送方:TObject;项:TListItem;
变量S:字符串);
变量
AHint:字符串;
R:TRect;
B:TBalloonHint;
开始
如果TRegEx.IsMatch(S,'[\\/:*?“|]'),那么
开始
AHint:=“文件名不能包含以下任何内容”+sLineBreak+
'字符:\/:*?“|';
R:=Item.DisplayRect(drBounds);
R.TopLeft:=客户端到屏幕(R.TopLeft);
R.BottomRight:=客户端到屏幕(R.BottomRight);
B:=TBalloonHint.Create(Self);
B.说明:=AHint;
B.HideAfter:=5000;
B.ShowHint(R);
S:=TRegEx.Replace(S,'[\\/:*?“|]','';
结束;
结束;
我尝试了ShowHint的各种重载,以及绝地气球提示组件。我还调整了矩形的Top属性,当项目位于屏幕的某个区域时,可以更好地定位气球,但当项目位于屏幕的其他部分时,气球则处于关闭位置


Delphi 10.3 Rio,Win 7 x64。

DisplayRect
提供了相对于包含项目的列表视图而非表单的客户端坐标。因此,在转换为屏幕坐标时,必须使用列表视图作为基础,而不是表单:

R := Item.DisplayRect(drBounds);
R.TopLeft := ListView1.ClientToScreen(R.TopLeft);         // <--
R.BottomRight := ListView1.ClientToScreen(R.BottomRight); // <--
R:=Item.DisplayRect(drBounds);
R.TopLeft:=ListView1.ClientToScreen(R.TopLeft)//