You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何用Delphi VCL的TPopupMenu实现自定义OwnerDraw样式及垂直分隔线?

用TPopupMenu实现自定义菜单外观(补充垂直分隔线)

当然可以通过TPopupMenu的OwnerDraw模式实现你想要的自定义菜单效果!看你已经完成了大部分UI逻辑,只需要补充图标与文本间的垂直分隔线绘制代码,同时还要注意内存泄漏的问题,我来帮你完善:

完善后的完整代码

procedure TForm1.pmiProjectCopyDrawItem(Sender: TObject; ACanvas: TCanvas; ARect: TRect; Selected: Boolean);
var 
  bt: TBitmap;
  menuItem: TMenuItem;
  shortcutText: string;
begin
  bt := TBitmap.Create;
  try
    menuItem := TMenuItem(Sender);
    shortcutText := ShortCutToText(menuItem.ShortCut);
    
    with ACanvas do
    begin
      // 绘制菜单背景
      Brush.Color := clWhite;
      FillRect(ARect);
      
      // 设置字体样式
      Font.Size := 8;
      Font.Name := 'Noto Sans';
      Font.Color := IfThen(Selected, $006C4E1F, $00757575);

      if menuItem.Caption = '-' then
      begin
        // 绘制水平分隔线
        Pen.Color := $00E5DFD7;
        MoveTo(ARect.Left + 25, ARect.Top + 3);
        LineTo(ARect.Right - 10, ARect.Top + 3);
      end
      else
      begin
        // 绘制菜单图标
        ImageList1.GetBitmap(menuItem.ImageIndex, bt);
        Draw(ARect.Left + 3, ARect.Top + 3, bt);
        
        // 绘制图标与文本间的垂直分隔线
        Pen.Color := $00E5DFD7; // 和水平分隔线同色,保持风格统一
        MoveTo(ARect.Left + 22, ARect.Top + 2); // 调整X坐标适配图标宽度
        LineTo(ARect.Left + 22, ARect.Bottom - 2); // 上下留空白避免贴边
        
        // 调整文本绘制区域,避开分隔线
        ARect.Left := ARect.Left + 28;
        
        // 绘制菜单文本(垂直居中)
        DrawText(Handle, PChar(menuItem.Caption), Length(menuItem.Caption), ARect, DT_SINGLELINE or DT_VCENTER);
        
        // 绘制快捷键文本(右对齐+垂直居中)
        DrawText(Handle, PChar(shortcutText), Length(shortcutText), ARect, DT_SINGLELINE or DT_RIGHT or DT_VCENTER);
      end;
    end;
  finally
    bt.Free; // 必须释放Bitmap,避免内存泄漏!
  end;
end;

关键修改点说明

  • 修复内存泄漏:之前的代码没有释放创建的TBitmap,现在用try...finally块确保资源被正确回收
  • 添加垂直分隔线:在图标绘制完成后,用MoveToLineTo绘制一条垂直直线,坐标可以根据你的图标大小调整(这里假设图标是16x16,所以X坐标设为ARect.Left + 22,留出一点间距)
  • 调整文本区域:把ARect.Left向右偏移更多,避免文本和分隔线重叠
  • 统一颜色风格:垂直分隔线用和水平分隔线相同的颜色$00E5DFD7,保持UI一致性

额外提示

如果你的图标大小不是16x16,可以根据实际尺寸调整分隔线的X坐标,比如图标宽度是20,那么分隔线X坐标可以设为ARect.Left + 23,确保和图标之间有合适的留白,视觉效果会更舒服。

内容的提问来源于stack exchange,提问作者userhi

火山引擎 最新活动