热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Delphi中Menu设置Images属性后快捷按键下划线被隐藏解决方法

现象:MainMenu设置Images属性后,看不到快捷按键的下划线,如:新建(&N)分析:VCL中Menus.pas单元的代码,看到如下语句procedureTMenuItem.Adva

现象:
MainMenu设置Images属性后,看不到快捷按键的下划线,如:新建(&N)

 

分析:
VCL中Menus.pas单元的代码,看到如下语句
procedure TMenuItem.AdvancedDrawItem(ACanvas: TCanvas; ARect: TRect;
  State: TOwnerDrawState; TopLevel: Boolean);
//...
if Win2K and (odNoAccel in State) then
  DrawStyle := DrawStyle or DT_HIDEPREFIX;
//...

DT_HIDEPREFIX就是隐藏下划线 //用DrawText()测试一下就知道

在设置Images属性后(odNoAccel in State)为真

看来需要自绘菜单,响应OnAdvancedDrawItem事件

当然,自绘菜单的代码写起来就多了,还好AdvancedDrawItem()声明在protected部分
我们可以通过继承TMenuItem来访问AdvancedDrawItem()
type
  TMenuItemAccess = class(TMenuItem);

现在就要想办法使那个条件不成立,先从Win2K入手
当Images设置后"Win2K and (odNoAccel in State)"这个条件成立

分析单元中Win2K变量是这样得到的
Win2K := (Win32MajorVersion > 4) and (Win32Platform = VER_PLATFORM_WIN32_NT);

那么我们就可以通过修改Win32MajorVersion或者Win32Platform常量使其不成立

参考代码:

type

  TForm1 = class(TForm)

    MainMenu1: TMainMenu;

    ImageList1: TImageList;

    MenuItemFile: TMenuItem;

    MenuItemNew: TMenuItem;

    MenuItemOpen: TMenuItem;

    PopupMenu1: TPopupMenu;

    MenuItemCopy: TMenuItem;

    MenuItemPaste: TMenuItem;

    procedure FormCreate(Sender: TObject);

  private

    { Private declarations }

    procedure MenuItemAdvancedDrawItem(Sender: TObject; ACanvas: TCanvas;

      ARect: TRect; State: TOwnerDrawState);

  public

    { Public declarations }

  end;

 

var

  Form1: TForm1;

 

implementation

 

{$R *.dfm}

 

type

  TMenuItemAccess = class(TMenuItem);

 

procedure TForm1.MenuItemAdvancedDrawItem(Sender: TObject; ACanvas: TCanvas;

  ARect: TRect; State: TOwnerDrawState);

var

  vWin32Platform: Integer;

begin

  vWin32Platform := PInteger(@Win32Platform)^;

  PInteger(@Win32Platform)^ := -1;

  TMenuItemAccess(Sender).OnAdvancedDrawItem := nil;

  try

    TMenuItemAccess(Sender).AdvancedDrawItem(ACanvas, ARect, State,

      TMenuItemAccess(Sender).GetParentComponent is TMainMenu);

  finally

    TMenuItemAccess(Sender).OnAdvancedDrawItem := MenuItemAdvancedDrawItem;

    PInteger(@Win32Platform)^ := vWin32Platform;

  end;

end;

 

procedure TForm1.FormCreate(Sender: TObject);

var

  I: Integer;

begin

  for I := 0 to ComponentCount - 1 do

    if Components[I] is TMenuItem then

      TMenuItem(Components[I]).OnAdvancedDrawItem := MenuItemAdvancedDrawItem

    else if Components[I] is TMenu then

      TMenu(Components[I]).OwnerDraw := True;

end;


推荐阅读
author-avatar
rare懿然
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有