When a mouse is over a component (a TButton, for example) if ShowHint property is True and there is some text in the Hint property, the hint / tooltip window will be displayed for the component.
Hints for Menu Items?By (Windows) design, even if you set the value for the Hint property to a Menu item, the popup hint will not get displayed.
However, the Windows Start Menu items do display hints, and the Favorites menu in the Internet Explorer also displays menu item hints.
It is quite common to use the OnHint event of the global Application variable, in Delphi applications, to display menu item (long) hints in a status bar.
Windows do not expose the messages needed to support a traditional OnMouseEnter event. However, the WM_MENUSELECT message is sent when the user selects a menu item.
The WM_MENUSELECT implementation of the TCustomForm (ancestor of the TForm) sets the menu item hint into Application.Hint that can be used in the Application.OnHint event.
If you want to add menu item popup hints (tooltips) to your Delphi application menus you *only* need to handle the WM_MenuSelect message properly.
The TMenuItemHint class - popup hints for menu items!Since you cannot rely on the Application.ActivateHint method to display the hint window for menu items (as menu handling is completely done by Windows), to get the hint window displayed you must create your own version of the hint window - by deriving a new class from the THintWindow.
Here's how to create a TMenuItemHint class - a hint widow that actually gets displayed for menu items!
Note: download the full source to explore it more easily.
First, you need to handle the WM_MENUSELECT Windows message:
type TForm1 = class(TForm) ... private procedure WMMenuSelect(var Msg: TWMMenuSelect) ; message WM_MENUSELECT; end ... implementation ... procedure TForm1.WMMenuSelect(var Msg: TWMMenuSelect) ; var menuItem : TMenuItem; hSubMenu : HMENU; begin inherited; // from TCustomForm (so that Application.Hint is assigned) menuItem := nil; if (Msg.MenuFlag <> $FFFF) or (Msg.IDItem <> 0) then begin if Msg.MenuFlag and MF_POPUP = MF_POPUP then begin hSubMenu := GetSubMenu(Msg.Menu, Msg.IDItem) ; menuItem := Self.Menu.FindItem(hSubMenu, fkHandle) ; end else begin menuItem := Self.Menu.FindItem(Msg.IDItem, fkCommand) ; end; end; miHint.DoActivateHint(menuItem) ; end; (*WMMenuSelect*)
Quick info: the WM_MENUSELECT message is sent to a menu's owner window (Form1 !) when the user selects (not clicks!) a menu item. Using the FindItem method of the TMenu class, you can get the menu item currently selected. Parameters of the FindItem function relate to the properties of the message received. Once we know what menu item the mouse is over, we call the DoActivateHint method of the TMenuItemHint class. Note: the miHint variable is defined as "var miHint : TMenuItemHint" and is created in the Form's OnCreate event handler.
Now, what's left is the implementation of the TMenuItemHint class.
Here's the interface part:
You can find the full implementation in the sample project.
TMenuItemHint = class(THintWindow) private activeMenuItem : TMenuItem; showTimer : TTimer; hideTimer : TTimer; procedure HideTime(Sender : TObject) ; procedure ShowTime(Sender : TObject) ; public constructor Create(AOwner : TComponent) ; override; procedure DoActivateHint(menuItem : TMenuItem) ; destructor Destroy; override; end;
Basically, the DoActivateHint function calls the ActivateHint method of the THintWindow using the TMenuItem's Hint property (if it is assigned).
The showTimer is used to ensure that the HintPause (of the Application) elapses before the hint is displayed. The hideTimer uses Application.HintHidePause to hide the hint window after a specified interval.