如何通过代码发送提示消息?
How to send an hint message by code?
如何向应用程序发送提示消息?
我试过一点测试:
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;
观察Memo1的台词,好像每次设置'Hello'.
都会发送一个空提示信息
在实际场景中,空的提示消息会隐藏我的提示消息,我不明白我做错了什么,这是错误的做法吗?
您不应该直接设置 Application.Hint
。该框架从 TApplication.Idle
开始这样做。它是这样做的:
Control := DoMouseIdle;
if FShowHint and (FMouseControl = nil) then
CancelHint;
Application.Hint := GetLongHint(GetHint(Control));
这里Control
是鼠标下的任何控件。由于您没有为程序中的任何控件指定 Hint
属性,因此无论何时执行此代码,它都会将 Application.Hint
设置为 ''
。
所以,事情是这样的:
- 您移动鼠标:
- 您的鼠标移动处理程序通过设置
Application.Hint
来响应。
- 消息队列清空,
TApplication.OnIdle
执行。
- 这会将
Application.Hint
更新回 ''
。
然后你回到开始,来回重复。
所以,是的,这确实是错误的方法。究竟什么是正确的方法,我真的不能说,因为我不知道你真正的问题。通常,您为操作、菜单项、按钮、工具按钮等组件设置 Hint
属性。但也许您的需求更加动态。我不能和他们说话,但我相信我已经解释了为什么你会观察到这种行为。
我觉得值得提出的另一点是提示是非常有趣的野兽。您永远不会以同步方式显示提示。您等到系统决定显示提示,然后以某种方式向其提供提示的内容。当应用程序空闲时,通常会在鼠标停止移动时显示提示。您的代码试图强制在 OnMouseMove
事件中显示提示,最好将其描述为与框架交叉工作的代码。
我怀疑您真正想做的是在鼠标移到控件上时调整当前显示的提示。为此,您可以使用 TApplication.OnShowHint
或 TApplicationEvents.OnShowHint
事件,或子类化目标控件来处理 CM_HINTSHOW
消息。其中任何一个都将提供对您可以自定义的 THintInfo
记录的访问权限,例如:
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;
请注意,以这种方式自定义显示的提示不会在每次提示更改时触发 TApplication.OnHint
/TApplicationEvents.OnHint
事件,只有在显示新的提示弹出窗口时才会触发。 OnShowHint
/CM_HINTSHOW
允许您对现有提示弹出窗口执行实时更新。
如何向应用程序发送提示消息? 我试过一点测试:
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;
观察Memo1的台词,好像每次设置'Hello'.
都会发送一个空提示信息在实际场景中,空的提示消息会隐藏我的提示消息,我不明白我做错了什么,这是错误的做法吗?
您不应该直接设置 Application.Hint
。该框架从 TApplication.Idle
开始这样做。它是这样做的:
Control := DoMouseIdle;
if FShowHint and (FMouseControl = nil) then
CancelHint;
Application.Hint := GetLongHint(GetHint(Control));
这里Control
是鼠标下的任何控件。由于您没有为程序中的任何控件指定 Hint
属性,因此无论何时执行此代码,它都会将 Application.Hint
设置为 ''
。
所以,事情是这样的:
- 您移动鼠标:
- 您的鼠标移动处理程序通过设置
Application.Hint
来响应。 - 消息队列清空,
TApplication.OnIdle
执行。 - 这会将
Application.Hint
更新回''
。
然后你回到开始,来回重复。
所以,是的,这确实是错误的方法。究竟什么是正确的方法,我真的不能说,因为我不知道你真正的问题。通常,您为操作、菜单项、按钮、工具按钮等组件设置 Hint
属性。但也许您的需求更加动态。我不能和他们说话,但我相信我已经解释了为什么你会观察到这种行为。
我觉得值得提出的另一点是提示是非常有趣的野兽。您永远不会以同步方式显示提示。您等到系统决定显示提示,然后以某种方式向其提供提示的内容。当应用程序空闲时,通常会在鼠标停止移动时显示提示。您的代码试图强制在 OnMouseMove
事件中显示提示,最好将其描述为与框架交叉工作的代码。
我怀疑您真正想做的是在鼠标移到控件上时调整当前显示的提示。为此,您可以使用 TApplication.OnShowHint
或 TApplicationEvents.OnShowHint
事件,或子类化目标控件来处理 CM_HINTSHOW
消息。其中任何一个都将提供对您可以自定义的 THintInfo
记录的访问权限,例如:
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;
请注意,以这种方式自定义显示的提示不会在每次提示更改时触发 TApplication.OnHint
/TApplicationEvents.OnHint
事件,只有在显示新的提示弹出窗口时才会触发。 OnShowHint
/CM_HINTSHOW
允许您对现有提示弹出窗口执行实时更新。