开发者

Unique hints for TCheckListBox items?

How can I show a hint that is specific to the item under the mouse as a user moves their mouse down a list of items 开发者_如何转开发in a TCheckListBox?

In Delphi 2010.

Tom


The way I do this is to make use of the TApplication.OnShowHint event. This allows you to customise the HintStr parameter and in you can do this based on the position contained in the HintInfo parameter.

As Remy points out in the comments, you can also handle CM_HINTSHOW to achieve the same effect and this can be cleaner to implement in some ways if you are already subclassing the standard VCL controls.

I have implemented a interface based framework to make use of this throughout my app. Basically in TApplication.OnShowHint, HintInfo.HintControl is asked if it supports this interface. If so then it is given an opportunity to customise the hint text. It works beautifully.

Basing hints off raw MouseMove events works perfectly well but it seems a little wasteful to call ItemAtPos on every MouseMove event rather than waiting until it's actually time to show the hint. That's why I have a slight preference for the approach described above.


Create a TCheckListBox with four items called "alpha", "beta", "gamma", and "delta" (for instance). Then do

const
  CheckListBoxHints: array[0..3] of string = ('first hint', 'second hint', 'third hint', 'fourth hint');

var
  prevIndex: integer = -1;

procedure TForm1.CheckListBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var
  index: integer;
begin
  index := CheckListBox1.ItemAtPos(point(X, Y), true);
  if index <> -1 then
    CheckListBox1.Hint := CheckListBoxHints[index]
  else
    CheckListBox1.Hint := '';
  if index <> prevIndex then
    Application.CancelHint;
  prevIndex := index;
end;

end;


There's only one way I know of - doing it the hard way...

You can query the element the mouse is hovering over and set the hint like this:

procedure TForm2.CheckListBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var hintItem : Integer;
    point    : TPoint;
begin
     point.X := X;
     point.Y := y;
     hintItem := CheckListBox1.ItemAtPos(point,true);
     if hintItem >= 0 then begin
        CheckListBox1.Hint := CheckListBox1.Items[hintItem];
        CheckListBox1.ShowHint := true;
     end else begin
        CheckListBox1.Hint := '';
        CheckListBox1.ShowHint := false;
     end;
end;

A little more tweaking would make it even more elegant. I for one would only hide the hint on MouseMove and start (or reset) a timer to redisplay it. So it will appear when the mouse didn't move for a while and will immediately disappear when you start moving the mouse.

This would be the behaviour one expects from windows. My implementation as given above will be kind of unusual, because the hint stays visible even if you move your mouse. This is because the mouse doesn't leave the element (TCheckListBox).

Oh, another thing: You should also make the hint disappear on MouseLeave.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜