让菜单项显示Hint

Delphi的菜单项,就算设置了Hint,它也不会显示,因为没有ShowHint属性。
Delphi自身给出的解决方法是通过一个StatusBar来接收菜单的Hint。
但是,用过Java的Swing的人都知道,在Swing里对一个菜单设置Hint是有效的,它能够被显示出来。
那么是否Delphi也能够显示呢?本文即是给出了一种解决方案。

首先,我们先对Delphi自己的THintWindow类进行一个分析,当用户把鼠标移到TEdit或是其他的带有Hint的控件上时,将触发THintWindow类内的ActivateHint()方法,而鼠标移到菜单项上时,不论是否设置了Hint,都不会触发这个方法。因此,第一步就是要截获鼠标移入菜单的事件,其次就是手动的让Hint窗口显示出来。

我不知道鼠标移入菜单会触发什么消息,但是我知道一定与菜单有关,于是打开Messages.pas,搜一下MENU,可以在这个单元内,发现一些以WM_开头的,带有MENU的消息,稍做推测加测试即可知道,鼠标移入菜单时,触发了WM_MENUSELECT消息。

然后事情就简单了,自己覆盖一下Form的消息循环:

procedure  TForm1.WndProc( var  msg: TMessage);
begin
case  msg.Msg  of
    WM_MENUSELECT: ShowHintOnMenu(Handle, msg.WParamLo);
end ;
inherited  WndProc(msg);
end ;

ShowHintMenu()的实现如下:

procedure  TForm1.ShowHintOnMenu(h: HWND; wParam: Integer);
var
buf:  array [0..255]  of  Char;
AHint:  string ;
p: TPoint;
begin
case  wParam  of
    0..99 :
     begin
      GetMenuString(GetMenu(h), wParam, buf, Length(buf), MF_BYPOSITION);
       if  buf = EmptyStr  then
        GetMenuString(GetMenu(h), wParam, buf, Length(buf), MF_BYCOMMAND);
     end ;
    100..$F000 :
      begin
       GetMenuString(GetMenu(h), wParam, buf, Length(buf), MF_BYCOMMAND);
      end ;
    $F001..$FFFF :
     begin
      GetMenuString(GetSystemMenu(h, False), wParam, buf, Length(buf), MF_BYCOMMAND);
     end ;
end ;
memo1.Lines.Add(buf);
AHint := GetMenuHintByCaption(buf,  nil );
memo1.Lines.Add(AHint);
if  AHint <> EmptyStr  then
begin
    GetCursorPos(p);
     if  ht =  nil then
      ht := THintWindow.Create( nil );
    ht.ActivateHint(Rect(p.x + 10,p.y+5,p.x+200,p.y+30),AHint);
end ;
end ;

其中还有一个GetMenuHintByCaption()方法,实现如下:

function  TForm1.GetMenuHintByCaption(ACaption:  string ; AMenuItem: TMenuItem):  string ;
var
mi: TMenuItem;
begin
Result := EmptyStr;
if  AMenuItem =  nil then
begin
     for  mi  in  MainMenu1.Items  do
     begin
       if  mi.Caption = ACaption  then
       begin
        Result := mi.Hint;
        Break;
       end ;
       if  Result = EmptyStr  then
         if  mi.Count > 0  then
          Result := GetMenuHintByCaption(ACaption, mi);
     end ;
end
else
begin

     for  mi  in  AMenuItem  do
     begin
       if  mi.Caption = ACaption  then
       begin
        Result := mi.Hint;
        Break;
       end ;
       if  Result = EmptyStr  then
         if  mi.Count > 0  then
          Result := GetMenuHintByCaption(ACaption, mi);
     end ;
end ;
end ;

这样,我们就能在鼠标移入菜单项时,显示出Hint了。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值