惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Vercel News
Vercel News
Recorded Future
Recorded Future
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
The GitHub Blog
The GitHub Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Google DeepMind News
Google DeepMind News
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Microsoft Azure Blog
Microsoft Azure Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
M
MIT News - Artificial intelligence
云风的 BLOG
云风的 BLOG
Y
Y Combinator Blog
N
News | PayPal Newsroom
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Help Net Security
Help Net Security
博客园 - Franky
SecWiki News
SecWiki News
Recent Announcements
Recent Announcements
T
Troy Hunt's Blog
The Register - Security
The Register - Security
The Last Watchdog
The Last Watchdog
Webroot Blog
Webroot Blog
S
Security Affairs
博客园 - 司徒正美
S
Schneier on Security
I
InfoQ
博客园_首页
www.infosecurity-magazine.com
www.infosecurity-magazine.com
T
Threat Research - Cisco Blogs
Forbes - Security
Forbes - Security
腾讯CDC
N
Netflix TechBlog - Medium
N
News and Events Feed by Topic
Cloudbric
Cloudbric
T
The Exploit Database - CXSecurity.com
P
Proofpoint News Feed
A
About on SuperTechFans
Engineering at Meta
Engineering at Meta
Recent Commits to openclaw:main
Recent Commits to openclaw:main
B
Blog
V
Vulnerabilities – Threatpost
C
Check Point Blog
Google DeepMind News
Google DeepMind News
Google Online Security Blog
Google Online Security Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
Hacker News - Newest:
Hacker News - Newest: "LLM"
C
Cisco Blogs
Schneier on Security
Schneier on Security
O
OpenAI News
K
Kaspersky official blog

博客园 - 秋·风

fpc aarch64-win64版编译应用时遇到一个奇怪的bug 在windows 11 on arm64系统编译lazarus出错的处理方法 修复TDBMemo只读不能使用Ctrl+C复制文字的Bug freepascal打补丁后已支持windows 11 on arm64(lazarus aarch64 windows版也可以运行了) 查看libc.so.6的版本号 Lazarus移动版启动程序 fpc 3.2.2交叉编译i386-linux链接出错 lazarus鸿蒙开发13:使用鸿蒙原生API画图--lazarus侧关键代码 lazarus鸿蒙开发12:使用鸿蒙原生API画图--鸿蒙侧关键代码 lazarus鸿蒙开发11:使用鸿蒙原生接口画图 lazarus鸿蒙开发10:lazarus一键编译、打包助手 lazarus鸿蒙开发9:使用命令行编译DevEco Studio应用 lazarus鸿蒙开发8:在DevEco Studio的日志窗口显示日志信息 lazarus鸿蒙开发7:在 Windows 上为 OpenHarmony (LoongArch64) 编译 Qt 5.15.12 SDK 指南 lazarus鸿蒙开发6:鸿蒙project配置 lazarus鸿蒙开发5:编译ohos_hap_project lazarus鸿蒙开发4:编译OHOS_QT_Lazarus lazarus鸿蒙开发3:编译libLazarusOHOS_Wrapper.so lazarus鸿蒙开发2:编译鸿蒙版本Qt5pas lazarus鸿蒙开发1:编译QT 5.12.12 鸿蒙版 fpc/lazarus for x86_64/aarch64鸿蒙版(绿色版 2026.06.03更新) fastreport报表编辑器在aarch64等非x86_64 CPU第一次打开慢的解决方案 linux/windows双系统可用的打包程序 使用FPC自带的纯 Pascal 实现的 Zlib 替代品——paszlib QFLazarus使用说明 忽略lazarus console in/output窗显示的转义序列 编译fpc遇到的怪事(2026-05-20更新) 取消树莓派的系统双击桌面图标时出现弹窗的选择提示 银河麒麟v11安装lazarus的方法 【小技巧】lazarus的应用设置某个form不在任务栏显示(linux) 用lazarus封装了linux的rsync SimpleXML-for-lazarus fastreport在windows11(lazarus)报表设计时出现的问题 用lazarus编写的deb打包工具 龙芯deepin 25系统使用旧世界软件的方法 SimpleJSON for lazarus 中文转全拼音和首字母 lazarus扩展IDE宏的方法 调整lazarus gtk2编辑控件背景颜色 fpc/lazarus可用的宏 Lazarus IDE宏列表 【原创控件】PopupMenu和MainMenu自绘单元 【原创控件】lazarus自定义mainmenu菜单栏(2026-02-26 增加菜单项图标尺寸参数) cudaText存在段落长度超过一定字数时会出现字符重叠的问题 lazarus编写的程序在Ubuntu任务栏/快捷栏不显示设定的图标 lazarus实现拖放文件 在uos使用lazarus调试时遇到的问题 【原创控件】lazarus IDE界面备份和恢复插件(2026-02-07增加恢复默认布局及官方已集成到lazarus) lazarus for arm32编译so链接出错
【原创控件】PopupMenu自绘
秋·风 · 2026-02-26 · via 博客园 - 秋·风

原因也和mainmenu一样,linux采用系统原生的PopupMenu,用户无法设定PopupMenu颜色等参数
Demo:

unit menu_unit;

{$mode objfpc}{$H+}
interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, clipbrd,
  Menus, Messages, Buttons, ExtCtrls, ComCtrls, MATH, Spin, CheckLst, LazUTF8,
  LazUtils, cp936, LConvEncoding, LazUnicode, LazUTF16, LazSysUtils,
  LazUtilities, Types, Grids, StyledMenuUnit, PopupMenuExt;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    MainMenu1: TMainMenu;
    Memo1: TMemo;
    MenuItem1: TMenuItem;
    MenuItem10: TMenuItem;
    MenuItem11: TMenuItem;
    MenuItem12: TMenuItem;
    MenuItem13: TMenuItem;
    MenuItem14: TMenuItem;
    Separator2: TMenuItem;
    Separator1: TMenuItem;
    MenuItem2: TMenuItem;
    MenuItem3: TMenuItem;
    MenuItem4: TMenuItem;
    MenuItem5: TMenuItem;
    MenuItem6: TMenuItem;
    MenuItem7: TMenuItem;
    MenuItem8: TMenuItem;
    MenuItem9: TMenuItem;
    Panel1: TPanel;
    PopupMenu1: TPopupMenu;
    procedure FormCreate(Sender: TObject);
  private
    FStyleBar:TStyledMenuBar;
    MyMenuStyle: TPopupMenuStyle;
  public

  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin

  FStyleBar:=TStyledMenuBar.Create(Self);
  FStyleBar.parent:=Self;
  //FStyleBar.Align:=alBottom;// alTop;
  FStyleBar.BarColor:=$00F8E7DA;//clSkyblue;
  FStyleBar.MainMenu:=MainMenu1;
  //FStyleBar.TextColor:=clBlack;
  FStyleBar.ItemHoverColor:=clhighlight;
  FStyleBar.TextHoverColor:=clYellow;
  FStyleBar.PopupColor:=$00F8E7DA;//clGreen;
  //FStyleBar.IconSize:=24;
  FStyleBar.Font.Size := 10;
  FStyleBar.Font.Name := '微软雅黑';

  // 1. 配置样式
  MyMenuStyle := DefaultMenuStyle; // 获取默认值

  MyMenuStyle.FontName := 'Microsoft YaHei'; // 微软雅黑,Linux下如无此字体会自动降级
  MyMenuStyle.FontSize := 10;                // 字体变大
  MyMenuStyle.FontColor := clBlack;
  MyMenuStyle.BgColor :=  $00F0F0F0;          // 浅灰背景
  MyMenuStyle.SelectedBgColor := $00FFCC00;  // 选中时背景
  MyMenuStyle.SelectedFontColor := clBlack;  // 选中时黑色字体
  MyMenuStyle.ItemPadding := 6;              // 增加垂直间距

  // 2. 应用样式到 PopupMenu1
  PopupMenu1.ApplyStyle(@MyMenuStyle);

end;

end.

在银河麒麟使用系统原生的popmenu:

 2026-02-26_14-55-31
使用扩展功能后:

image

unit PopupMenuExt;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Graphics, Menus, LCLType, LCLIntf, Controls, Forms,
  StdCtrls, ExtCtrls, Math, LMessages, ImgList, LCLProc;

type
  TPopupMenuStyle = record
    FontName: String;
    FontSize: Integer;
    FontColor: TColor;
    BgColor: TColor;
    SelectedFontColor: TColor;
    SelectedBgColor: TColor;
    DisabledFontColor: TColor;
    SeparatorColor: TColor;
    ItemPadding: Integer;
    IconSize: Integer;
  end;
  PPopupMenuStyle = ^TPopupMenuStyle;

  TPopupMenu = class;

  // 统一的模拟弹出窗口
  TSimulatedPopupForm = class(TCustomForm)
  private
    FStyle: PPopupMenuStyle;
    FMenuItems: TList;
    FItemRects: array of TRect;
    FSelectedIndex: Integer;
    FRootMenu: TPopupMenu;
    FParentPopup: TSimulatedPopupForm;
    FChildPopup: TSimulatedPopupForm;
    FImageList: TCustomImageList;

    procedure SetStyle(AValue: PPopupMenuStyle);
    procedure CalculateSizes;
    procedure DrawMenu;
    procedure SetSelectedIndex(Index: Integer);
    procedure CMMouseLeave(var Message: TLMessage); message CM_MOUSELEAVE;
    procedure ShowSubMenu(Index: Integer);
    procedure CloseChain;
    function GetImageList: TCustomImageList;
  protected
    procedure Paint; override;
    procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
    procedure DoShow; override;
    procedure Deactivate; override;
    // 增加键盘支持 (Esc 关闭)
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
  public
    constructor CreateNew(AOwner: TComponent; Num: Integer = 0); override;
    destructor Destroy; override;

    procedure Popup(AX, AY: Integer; AMenu: TPopupMenu); overload;
    procedure Popup(AX, AY: Integer; AItem: TMenuItem; AParent: TSimulatedPopupForm); overload;

    property Style: PPopupMenuStyle read FStyle write SetStyle;
  end;

  // 菜单拦截器
  TPopupMenu = class(Menus.TPopupMenu)
  private
    procedure SetStylePtr(Value: PPopupMenuStyle);
    function GetStylePtr: PPopupMenuStyle;
  protected
    procedure Popup(X, Y: Integer); override;
  public
    procedure ApplyStyle(Style: PPopupMenuStyle);
    property StylePtr: PPopupMenuStyle read GetStylePtr write SetStylePtr;
  end;

function DefaultMenuStyle: TPopupMenuStyle;

implementation

var
  GStyleList: TList;

type
  TMenuStyleLink = class
    Menu: TPopupMenu;
    Style: PPopupMenuStyle;
  end;

function DefaultMenuStyle: TPopupMenuStyle;
begin
  Result.FontName := 'default';
  Result.FontSize := 10;
  Result.FontColor := clBlack;
  Result.BgColor := clWhite;
  Result.SelectedFontColor := clWhite;
  Result.SelectedBgColor := clHighlight;
  Result.DisabledFontColor := clGray;
  Result.SeparatorColor := clSilver;
  Result.ItemPadding := 4;
  Result.IconSize := 24;
end;

function GetStyleForMenu(AMenu: TPopupMenu): PPopupMenuStyle;
var
  i: Integer;
  Link: TMenuStyleLink;
begin
  Result := nil;
  if not Assigned(GStyleList) then Exit;
  for i := 0 to GStyleList.Count - 1 do
  begin
    Link := TMenuStyleLink(GStyleList[i]);
    if Link.Menu = AMenu then Exit(Link.Style);
  end;
end;

procedure RegisterStyle(AMenu: TPopupMenu; AStyle: PPopupMenuStyle);
var
  Link: TMenuStyleLink;
  i: Integer;
begin
  if not Assigned(GStyleList) then GStyleList := TList.Create;
  for i := GStyleList.Count - 1 downto 0 do
  begin
    Link := TMenuStyleLink(GStyleList[i]);
    if Link.Menu = AMenu then begin GStyleList.Delete(i); Link.Free; end;
  end;
  Link := TMenuStyleLink.Create;
  Link.Menu := AMenu;
  Link.Style := AStyle;
  GStyleList.Add(Link);
end;

{ TSimulatedPopupForm (Windows & Linux Unified) }

constructor TSimulatedPopupForm.CreateNew(AOwner: TComponent; Num: Integer);
begin
  inherited CreateNew(AOwner, Num);
  FMenuItems := TList.Create;
  FSelectedIndex := -1;
  BorderStyle := bsNone;
  FormStyle := fsStayOnTop;
  ControlStyle := ControlStyle + [csOpaque]; // 防止闪烁

  // 设置 KeyPreview 以捕获键盘事件
  KeyPreview := True;
end;

destructor TSimulatedPopupForm.Destroy;
begin
  if Assigned(FParentPopup) then FParentPopup.FChildPopup := nil;
  if Assigned(FChildPopup) then FreeAndNil(FChildPopup);

  FMenuItems.Free;
  inherited Destroy;
end;

procedure TSimulatedPopupForm.SetStyle(AValue: PPopupMenuStyle);
begin
  FStyle := AValue;
  if Assigned(FStyle) then Color := FStyle^.BgColor;
end;

function TSimulatedPopupForm.GetImageList: TCustomImageList;
begin
  if Assigned(FRootMenu) then Result := FRootMenu.Images
  else Result := nil;
end;

procedure TSimulatedPopupForm.DoShow;
begin
  inherited DoShow;
  SetFocus;
end;

procedure TSimulatedPopupForm.Deactivate;
begin
  inherited Deactivate;
  // 如果点击了其他程序,关闭菜单链
  if Assigned(FChildPopup) and FChildPopup.Visible then Exit;
  CloseChain;
end;

procedure TSimulatedPopupForm.CloseChain;
begin
  if Assigned(FChildPopup) then
  begin
    FChildPopup.CloseChain;
    FreeAndNil(FChildPopup);
  end;
  Close;
end;

// 键盘事件处理:Esc 关闭
procedure TSimulatedPopupForm.KeyDown(var Key: Word; Shift: TShiftState);
begin
  inherited;
  if Key = VK_ESCAPE then
  begin
    CloseChain;
    Key := 0;
  end;
end;

procedure TSimulatedPopupForm.Popup(AX, AY: Integer; AMenu: TPopupMenu);
var
  i: Integer;
begin
  FRootMenu := AMenu;
  FParentPopup := nil;
  FMenuItems.Clear;
  for i := 0 to AMenu.Items.Count - 1 do FMenuItems.Add(AMenu.Items[i]);
  FImageList := AMenu.Images;

  CalculateSizes;

  // 屏幕边界修正
  if AX + Width > Screen.Width then AX := Screen.Width - Width;
  if AY + Height > Screen.Height then AY := Screen.Height - Height;

  Left := AX; Top := AY;
  Show;
end;

procedure TSimulatedPopupForm.Popup(AX, AY: Integer; AItem: TMenuItem; AParent: TSimulatedPopupForm);
var
  i: Integer;
begin
  FRootMenu := AParent.FRootMenu;
  FParentPopup := AParent;
  AParent.FChildPopup := Self;

  FMenuItems.Clear;
  for i := 0 to AItem.Count - 1 do FMenuItems.Add(AItem.Items[i]);
  FImageList := FRootMenu.Images;

  CalculateSizes;

  // 屏幕边界修正
  if AX + Width > Screen.Width then AX := AParent.Left - Width; // 如果右边放不下,放左边
  if AY + Height > Screen.Height then AY := Screen.Height - Height;

  Left := AX; Top := AY;
  Show;
end;

procedure TSimulatedPopupForm.CalculateSizes;
var
  i: Integer;
  Item: TMenuItem;
  H, MaxW, CurW: Integer;
  R: TRect;
  S: String;
begin
  if not Assigned(FStyle) then Exit;
  Canvas.Font.Name := FStyle^.FontName;
  Canvas.Font.Size := FStyle^.FontSize;

  SetLength(FItemRects, FMenuItems.Count);
  MaxW := 150; // 初始最小宽度

  // 1. 计算最大宽度
  for i := 0 to FMenuItems.Count - 1 do
  begin
    Item := TMenuItem(FMenuItems[i]);
    if Item.IsLine then Continue;

    // 基础宽度 = 图标 + 间距
    CurW := FStyle^.IconSize + 10;
    // 标题宽度
    CurW := CurW + Canvas.TextWidth(Item.Caption);

    // 快捷键宽度
    if Item.ShortCut <> 0 then
    begin
      S := ShortCutToText(Item.ShortCut);
      CurW := CurW + Canvas.TextWidth(S) + 20;
    end;

    // 子菜单箭头宽度
    if Item.Count > 0 then
      CurW := CurW + 25;

    if CurW > MaxW then MaxW := CurW;
  end;

  // 2. 统一分配矩形区域
  R.Top := 0;
  for i := 0 to FMenuItems.Count - 1 do
  begin
    Item := TMenuItem(FMenuItems[i]);

    if Item.IsLine then H := 6
    else H := Canvas.TextHeight('Wg') + (FStyle^.ItemPadding * 2);

    R.Left := 0;
    R.Right := MaxW; // 统一使用最大宽度
    R.Bottom := R.Top + H;
    FItemRects[i] := R;

    R.Top := R.Bottom;
  end;

  ClientWidth := MaxW;
  ClientHeight := R.Top;
end;

procedure TSimulatedPopupForm.Paint;
begin
  DrawMenu;
end;

procedure TSimulatedPopupForm.DrawMenu;
var
  i: Integer;
  Item: TMenuItem;
  R: TRect;
  IconRect: TRect;
  TargetIconSize: Integer;
  TempBmp: TBitmap;
  ShortCutTxt: String;
  TextY: Integer;
  ArrowSpace: Integer;
begin
  if not Assigned(FStyle) then Exit;

  TargetIconSize := FStyle^.IconSize;

  // 绘制背景
  Canvas.Brush.Color := FStyle^.BgColor;
  Canvas.FillRect(ClientRect);

  Canvas.Font.Name := FStyle^.FontName;
  Canvas.Font.Size := FStyle^.FontSize;

  for i := 0 to FMenuItems.Count - 1 do
  begin
    Item := TMenuItem(FMenuItems[i]);
    R := FItemRects[i];

    // 绘制高亮背景
    if i = FSelectedIndex then
    begin
      Canvas.Brush.Color := FStyle^.SelectedBgColor;
      Canvas.Font.Color := FStyle^.SelectedFontColor;
      Canvas.FillRect(R);
    end else
    begin
      Canvas.Brush.Color := FStyle^.BgColor;
      if Item.Enabled then Canvas.Font.Color := FStyle^.FontColor
      else Canvas.Font.Color := FStyle^.DisabledFontColor;
    end;

    if Item.IsLine then
    begin
      Canvas.Pen.Color := FStyle^.SeparatorColor;
      Canvas.Line(R.Left + TargetIconSize + 4, R.CenterPoint.Y, R.Right - 2, R.CenterPoint.Y);
    end else
    begin
      // 1. 绘制图标 (统一缩放)
      IconRect.Left := R.Left + 2;
      IconRect.Right := IconRect.Left + TargetIconSize;
      IconRect.Top := R.Top + (R.Height - TargetIconSize) div 2;
      IconRect.Bottom := IconRect.Top + TargetIconSize;

      if Assigned(FImageList) and (Item.ImageIndex >= 0) then
      begin
        TempBmp := TBitmap.Create;
        try
          TempBmp.SetSize(TargetIconSize, TargetIconSize);
          TempBmp.Canvas.Brush.Color := FStyle^.BgColor; // 背景色填充
          TempBmp.Canvas.FillRect(0, 0, TargetIconSize, TargetIconSize);
          FImageList.Draw(TempBmp.Canvas, 0, 0, Item.ImageIndex, dsNormal, itImage);
          Canvas.StretchDraw(IconRect, TempBmp);
        finally
          TempBmp.Free;
        end;
      end else if not Item.Bitmap.Empty then
      begin
        Canvas.StretchDraw(IconRect, Item.Bitmap);
      end;

      TextY := R.Top + FStyle^.ItemPadding;

      // 2. 绘制子菜单箭头 (最右侧)
      ArrowSpace := 0;
      if Item.Count > 0 then
      begin
        ArrowSpace := 20;
        Canvas.TextOut(R.Right - 15, TextY, '');
      end;

      // 3. 绘制快捷键 (右对齐,在箭头左侧)
      if Item.ShortCut <> 0 then
      begin
        ShortCutTxt := ShortCutToText(Item.ShortCut);
        Canvas.TextOut(R.Right - ArrowSpace - Canvas.TextWidth(ShortCutTxt) - 5, TextY, ShortCutTxt);
      end;

      // 4. 绘制标题
      // 使用 TextRect 确保标题过长时不会覆盖右侧的快捷键
      R.Left := TargetIconSize + 6;
      Canvas.TextRect(R, R.Left, TextY, Item.Caption);
    end;
  end;
end;

procedure TSimulatedPopupForm.SetSelectedIndex(Index: Integer);
begin
  if FSelectedIndex <> Index then
  begin
    FSelectedIndex := Index;
    Invalidate;

    if Assigned(FChildPopup) then
    begin
      FChildPopup.Free;
      FChildPopup := nil;
    end;

    if (Index >= 0) then
      ShowSubMenu(Index);
  end;
end;

procedure TSimulatedPopupForm.ShowSubMenu(Index: Integer);
var
  Item: TMenuItem;
  ChildForm: TSimulatedPopupForm;
  P: TPoint;
begin
  Item := TMenuItem(FMenuItems[Index]);
  if (Item.Count = 0) or (not Item.Enabled) then Exit;

  P.X := Left + Width;
  P.Y := Top + FItemRects[Index].Top;

  ChildForm := TSimulatedPopupForm.CreateNew(nil);
  ChildForm.Style := FStyle;
  ChildForm.Popup(P.X, P.Y, Item, Self);
end;

procedure TSimulatedPopupForm.CMMouseLeave(var Message: TLMessage);
begin
  if not (Assigned(FChildPopup) and FChildPopup.Visible) then
    SetSelectedIndex(-1);
  inherited;
end;

procedure TSimulatedPopupForm.MouseMove(Shift: TShiftState; X, Y: Integer);
var
  i: Integer;
  P: TPoint;
begin
  inherited;
  P := Point(X, Y);
  for i := 0 to High(FItemRects) do
    if PtInRect(FItemRects[i], P) then begin SetSelectedIndex(i); Exit; end;
end;

procedure TSimulatedPopupForm.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  i: Integer;
  P: TPoint;
  Item: TMenuItem;
  Root: TSimulatedPopupForm;
begin
  inherited;
  if Button <> mbLeft then Exit;
  P := Point(X, Y);
  for i := 0 to High(FItemRects) do
  begin
    if PtInRect(FItemRects[i], P) then
    begin
      Item := TMenuItem(FMenuItems[i]);
      if (not Item.IsLine) and Item.Enabled and (Item.Count = 0) then
      begin
        if Assigned(FRootMenu) then FRootMenu.Close;

        Root := Self;
        while Assigned(Root.FParentPopup) do Root := Root.FParentPopup;
        Root.CloseChain;

        Item.Click;
      end;
      Exit;
    end;
  end;
end;

{ TPopupMenu 拦截器 }

procedure TPopupMenu.SetStylePtr(Value: PPopupMenuStyle);
begin
  RegisterStyle(Self, Value);
end;

function TPopupMenu.GetStylePtr: PPopupMenuStyle;
begin
  Result := GetStyleForMenu(Self);
end;

procedure TPopupMenu.ApplyStyle(Style: PPopupMenuStyle);
begin
  StylePtr := Style;
end;

procedure TPopupMenu.Popup(X, Y: Integer);
var
  Frm: TSimulatedPopupForm;
  PStyle: PPopupMenuStyle;
begin
  PStyle := GetStyleForMenu(Self);
  if not Assigned(PStyle) then begin inherited Popup(X, Y); Exit; end;

  Frm := TSimulatedPopupForm.CreateNew(nil);
  Frm.Style := PStyle;
  Frm.Popup(X, Y, Self);
end;

initialization
  GStyleList := TList.Create;

finalization
  while GStyleList.Count > 0 do begin TObject(GStyleList[0]).Free; GStyleList.Delete(0); end;
  GStyleList.Free;

end.