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.
精彩评论