You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi技术咨询:点击TMainMenu菜单项时如何添加勾选/叉号标记?

当然可以实现!在Delphi里给TMainMenu的菜单项添加勾选标记(tick)或叉号(x),有几种实用的方案,我给你逐一拆解:

方法一:利用TMenuItem自带的Checked属性(灵活可控)

Delphi的TMenuItem本身就有Checked属性,默认开启后会显示系统自带的勾选标记。如果想要替换成叉号,只需要开启**自绘模式(OwnerDraw)**自定义绘制即可:

具体步骤:

  1. 在设计器中选中目标菜单项,将OwnerDraw属性设为True;
  2. 为菜单项绑定OnDrawItem事件,在事件中自定义绘制逻辑:
procedure TYourForm.MenuItemDrawItem(Sender: TObject; ACanvas: TCanvas;
  ARect: TRect; Selected: Boolean);
var
  MenuItem: TMenuItem;
begin
  MenuItem := Sender as TMenuItem;
  
  // 先绘制菜单项的背景和文本
  if Selected then
    ACanvas.Brush.Color := clHighlight
  else
    ACanvas.Brush.Color := clMenu;
  ACanvas.FillRect(ARect);
  
  // 绘制文本(预留左侧符号的空间)
  ACanvas.Font.Color := clMenuText;
  ACanvas.TextOut(ARect.Left + 20, ARect.Top + 2, MenuItem.Caption);
  
  // 根据Checked状态绘制勾选或叉号
  if MenuItem.Checked then
  begin
    ACanvas.Pen.Color := clBlack;
    // 绘制叉号
    ACanvas.MoveTo(ARect.Left + 5, ARect.Top + 5);
    ACanvas.LineTo(ARect.Left + 15, ARect.Top + 15);
    ACanvas.MoveTo(ARect.Left + 15, ARect.Top + 5);
    ACanvas.LineTo(ARect.Left + 5, ARect.Top + 15);
    // 如果要画勾选,替换成下面的代码:
    // ACanvas.MoveTo(ARect.Left + 5, ARect.Top + 10);
    // ACanvas.LineTo(ARect.Left + 10, ARect.Top + 15);
    // ACanvas.LineTo(ARect.Left + 15, ARect.Top + 5);
  end;
end;
  1. 在菜单项的OnClick事件中切换Checked状态:
procedure TYourForm.MenuItemClick(Sender: TObject);
begin
  (Sender as TMenuItem).Checked := not (Sender as TMenuItem).Checked;
end;

这个方法的优势是完全自定义符号样式,想画什么就画什么,比如还可以换成对勾、圆点等。

方法二:直接使用Unicode特殊字符(最简单快捷)

如果不需要复杂的自定义样式,直接在菜单项的Caption前添加Unicode勾选/叉号字符是最省事的:

具体实现:

  1. 在设计时或代码中设置菜单项的初始Caption,比如:
    • 勾选状态:MenuItem.Caption := '✓ 我的功能'
    • 叉号状态:MenuItem.Caption := '✗ 我的功能'
  2. 在OnClick事件中切换字符:
procedure TYourForm.MenuItemClick(Sender: TObject);
var
  MenuItem: TMenuItem;
begin
  MenuItem := Sender as TMenuItem;
  if Pos('✓', MenuItem.Caption) > 0 then
    // 从勾选切换到叉号
    MenuItem.Caption := StringReplace(MenuItem.Caption, '✓', '✗', [rfReplaceAll])
  else if Pos('✗', MenuItem.Caption) > 0 then
    // 从叉号切换到勾选
    MenuItem.Caption := StringReplace(MenuItem.Caption, '✗', '✓', [rfReplaceAll])
  else
    // 初始状态添加勾选
    MenuItem.Caption := '✓ ' + MenuItem.Caption;
end;

这种方法不需要处理自绘,代码量极少,适合快速实现需求。

方法三:通过Windows API替换系统菜单标记(全局风格统一)

如果想要让整个程序的菜单勾选标记都换成叉号,可以用Windows API修改菜单的默认样式,比如用SetMenuItemInfo设置自定义位图:

示例代码:

uses
  Winapi.Windows, Winapi.Menus;

procedure TYourForm.FormCreate(Sender: TObject);
var
  MenuInfo: TMenuItemInfo;
  CrossBmp: TBitmap;
begin
  CrossBmp := TBitmap.Create;
  try
    // 绘制一个叉号位图(也可以从资源加载)
    CrossBmp.Width := 16;
    CrossBmp.Height := 16;
    CrossBmp.Canvas.Brush.Color := clMenu;
    CrossBmp.Canvas.FillRect(Rect(0,0,16,16));
    CrossBmp.Canvas.Pen.Color := clBlack;
    CrossBmp.Canvas.MoveTo(2,2);
    CrossBmp.Canvas.LineTo(14,14);
    CrossBmp.Canvas.MoveTo(14,2);
    CrossBmp.Canvas.LineTo(2,14);
    
    // 设置菜单项的勾选位图
    FillChar(MenuInfo, SizeOf(MenuInfo), 0);
    MenuInfo.cbSize := SizeOf(MenuInfo);
    MenuInfo.fMask := MIIM_BITMAP;
    MenuInfo.hbmpChecked := CrossBmp.Handle;
    
    SetMenuItemInfo(MainMenu1.Handle, MenuItem1.Command, False, MenuInfo);
  finally
    CrossBmp.Free;
  end;
end;

这个方法适合需要统一全局菜单样式的场景,但需要对Windows API有一定了解。


内容的提问来源于stack exchange,提问作者Minh Đạt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:43:07