Reputation: 8043
How can I send an hint message to the application? I've tried with a little test:
TForm1 = class(TForm)
ApplicationEvents1: TApplicationEvents;
Memo1: TMemo;
procedure ApplicationEvents1Hint(Sender: TObject);
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
private
{ Private declarations }
public
{ Public declarations }
end;
procedure TForm1.ApplicationEvents1Hint(Sender: TObject);
begin
Memo1.Lines.Add(Application.Hint);
end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
Application.Hint := 'Hello';
end;
Observing Memo1's lines, it seems that an empty hint message is sent everytime I set 'Hello'.
In a real scenario, the empty hint message will hide my hint message and I don't understand what I'm doing wrong, is this the wrong approach?
Upvotes: 0
Views: 1755
Reputation: 595827
I suspect what you are really trying to do is tweak the currently displayed hint while the mouse is moving over a control. To do that, you can use the TApplication.OnShowHint
or TApplicationEvents.OnShowHint
event, or subclass the target control to handle the CM_HINTSHOW
message. Any of those will provide access to a THintInfo
record that you can customize, eg:
procedure TForm1.ApplicationEvents1ShowHint(var HintStr: string;
var CanShow: Boolean; var HintInfo: THintInfo)
begin
// HintInfo.HintControl is the control that is about to display a hint
if HintInfo.HintControl = Memo1 then
begin
// HintInfo.CursorPos is the current mouse position within the HintControl
HintStr := Format('Hello, cursor = %d,%d', [HintInfo.CursorPos.X, HintInfo.CursorPos.Y]);
// the hint will remain active until it times out (see
// TApplication.HintHidePause and THintInfo.HideTimeout) or
// the mouse moves outside of the HintInfo.CursorRect. In
// the latter case, a new hint will be displayed. This allows
// you to change the hint for different sections of the
// HintControl. The CursorRect is set to the HintControl's
// whole client area by default.
// In this example, setting the new CursorRect to a 1x1 square
// around the current CursorPos will display a new hint string
// on each mouse movement...
HintInfo.CursorRect := Rect(HintInfo.CursorPos.X, HintInfo.CursorPos.Y, HintInfo.CursorPos.X, HintInfo.CursorPos.Y);
end;
end;
Note that customizing the displayed hint in this manner will not trigger the TApplication.OnHint
/TApplicationEvents.OnHint
event on each hint change, only when a new hint popup is displayed. OnShowHint
/CM_HINTSHOW
allows you to perform live updates of an existing hint popup.
Upvotes: 4
Reputation: 612884
You are not supposed to set Application.Hint
directly. The framework does so from TApplication.Idle
. It does this like so:
Control := DoMouseIdle;
if FShowHint and (FMouseControl = nil) then
CancelHint;
Application.Hint := GetLongHint(GetHint(Control));
Here Control
is whatever control is under the mouse. Since you have not specified the Hint
property for any controls in your program, whenever this code executes it sets Application.Hint
to ''
.
So, here is what happens:
Application.Hint
.TApplication.OnIdle
executes.Application.Hint
back to ''
.And then you go back to the start and repeat the back and forth.
So, yes, this really is the wrong approach. Exactly what the right approach is, I cannot really tell because I don't know your real problem. Normally you set the Hint
property for components like actions, menu items, buttons, tool buttons, etc. But perhaps your needs are more dynamic. I cannot speak to them, but I believe I have explained why you observe this behaviour.
The other point that I feel is worth making is that hints are quite funny beasts. You don't ever show a hint in a synchronous fashion. You wait until the system decides that a hint is to be shown, and then provide it with the content of the hint, one way or another. And hints get shown when the application becomes idle, commonly when the mouse stops moving. Your code trying to force a hint to show in an OnMouseMove
event is best described as that code working at cross-purposes to the framework.
Upvotes: 4