1

My TListView control has ShowHints enabled and handles the OnInfoTip event. The message in the popup InfoTip box is set in the OnInfoTip handler. However, the position of the popup InfoTip box is relative to the position of the mouse when hovering over an item in the list. There doesn't appear to be a way to customise the position.

Is it possible set the position of the hint popup, for example in a specific area of the TListView or even elsewhere on the form outside the bounds of the TListView control? Ideally, I'd like to display the hint popup in such a way to minimise (or eliminate) obscuring any other item in the TListView.

AlainD
  • 5,413
  • 6
  • 45
  • 99

2 Answers2

3

It is possible to display the hint, that you define in the OnInfoTip() event in e.g. a StatusPanel of a StatusBar (at the bottom of the form).

For example:

procedure TForm1.ListView1InfoTip(Sender: TObject; Item: TListItem;
  var InfoTip: string);
begin
  InfoTip := '';
  StatusBar1.Panels[0].Text := 'ListView Infotip, Item '+IntToStr(Item.Index);
end;
Tom Brunberg
  • 20,312
  • 8
  • 37
  • 54
  • Nice, simple solution! Does require unused space somewhere on the form to display the hint details, though. – AlainD Dec 19 '17 at 11:02
3

First you have to expose the CMHintShow of the TListView as following:

  type
   TListView = class(Vcl.ComCtrls.TListView)
      private
         FPos: TPoint;
      protected
         procedure CMHintShow(var Message: TCMHintShow); message CM_HINTSHOW;
      published
         property MyPos: TPoint  read FPos write FPos;
   end;


  TfrmMain = class(TForm)
    ...
    ListView1: TListView;

Then at the OnInfoTip event you set the desired Position. At my example, I get the coords of the TopLeft Corner of a ScrollBox (sbxFilter - which is located under the TlistView) and pass the Coords to the TListView property MyPos.

procedure TfrmMain.ListView1InfoTip(Sender: TObject; Item: TListItem; var InfoTip: string);
var
   p: TPoint;
begin
   InfoTip := 'Test';
   p := sbxFilter.ClientToScreen(point(0, 0));
   ListView1.MyPos := p;
end;


{ TListView }

procedure TListView.CMHintShow(var Message: TCMHintShow);
begin
   inherited;
   Message.HintInfo.HintPos := FPos;
end;
MaGiC
  • 311
  • 1
  • 4
  • 1
    This works nicely. I named my TListView sub-class `THintPostListView` and put the declaration and functions in a separate base unit so that any form can use the control as required. At the top of a form using the control simply declare `TListView = class(THintPosListView);` as in this example. – AlainD Dec 19 '17 at 11:00