冥界3大法王 发表于 2024-10-9 08:52

求教,为啥得不到子菜单项Caption ?

本帖最后由 冥界3大法王 于 2024-10-10 10:19 编辑

添加一个 MainMenu1,随便加1个主菜单名,3个子菜单名
要求得到 子菜单名的 Caption {:301_974:}

procedure TForm13.FormCreate(Sender: TObject);
var
I: Integer;
begin
// 假设MainMenu1已经添加到窗体中,并且有多个菜单项
for I := 0 to MainMenu1.Items.Count - 1 do
begin
    // 为每个菜单项关联事件处理程序
    MainMenu1.Items.OnClick := MainMenu1Click;
end;
end;

procedure TForm13.MainMenu1Click(Sender: TObject);
var
MenuItem: TMenuItem;
begin
// 确保Sender是TMenuItem类型
if Sender is TMenuItem then
begin
    MenuItem := TMenuItem(Sender);      // 获取并显示菜单项的Caption
    ShowMessage(MenuItem.Caption);
end;
end;

homejun 发表于 2024-10-9 09:23

本帖最后由 homejun 于 2024-10-9 09:26 编辑

procedure TForm1.FormCreate(Sender: TObject);
var
I,j: Integer;
begin
// 假设MainMenu1已经添加到窗体中,并且有多个菜单项
for I := 0 to MainMenu1.Items.Count - 1 do
begin
    // 为每个菜单子项关联事件处理程序
    for j := 0 to MainMenu1.Items.Count - 1 do
    begin
      MainMenu1.Items.Items.OnClick := MainMenu1Click;
    end;

end;

end;

冥界3大法王 发表于 2024-10-9 12:47

@homejun

那如果是这种子菜单的呢?
脑袋笨,又晕了。{:301_1008:}

lies2014 发表于 2024-10-9 15:25

冥界3大法王 发表于 2024-10-9 12:47
@homejun

那如果是这种子菜单的呢?

你这是粗心了吧?



for z := 0 to PopupMenu1.Items.Items.Count - 1 do

冥界3大法王 发表于 2024-10-10 10:11

本帖最后由 冥界3大法王 于 2024-10-10 10:18 编辑

lies2014 发表于 2024-10-9 15:25
冥界3大法王 发表于 2024-10-9 12:47
@homejun


@homejun
@lies2014
要是下面这种又当如何?

Unit13.dfm
object Form13: TForm13
Left = 0
Top = 0
Caption = 'Form13'
ClientHeight = 280
ClientWidth = 607
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -18
Font.Name = 'Segoe UI'
Font.Style = []
PopupMenu = PopupMenu1
OnCreate = FormCreate
PixelsPerInch = 144
TextHeight = 25
object PopupMenu1: TPopupMenu
    AutoHotkeys = maManual
    Left = 56
    Top = 40
    object N1: TMenuItem
      Caption = #27604#36739#24037#20855
      object AAA1: TMenuItem
      Caption = 'AAA'
      end
      object BBB1: TMenuItem
      Caption = 'BBB'
      end
    end
    object N2: TMenuItem
      Caption = #32534#36753#24037#20855
      object N1111: TMenuItem
      Caption = '111'
      end
      object N2221: TMenuItem
      Caption = '222'
      end
    end
    object N3: TMenuItem
      Caption = #21453#27719#32534
      object N4: TMenuItem
      Caption = 'x64dbg'
      end
      object N5: TMenuItem
      Caption = 'Ollydbg'
      object N8881: TMenuItem
          Caption = '888'
      end
      object N7771: TMenuItem
          Caption = '777'
      end
      end
    end
end
end

unit13.pas
unit Unit13;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Menus;

type
TForm13 = class(TForm)
    PopupMenu1: TPopupMenu;
    N1: TMenuItem;
    AAA1: TMenuItem;
    BBB1: TMenuItem;
    N2: TMenuItem;
    N1111: TMenuItem;
    N2221: TMenuItem;
    N3: TMenuItem;
    N4: TMenuItem;
    N5: TMenuItem;
    N8881: TMenuItem;
    N7771: TMenuItem;
    procedure FormCreate(Sender: TObject);
private
    procedure MainMenu1Click(Sender: TObject);
    { Private declarations }
public
    { Public declarations }
end;

var
Form13: TForm13;

implementation

{$R *.dfm}

procedure TForm13.MainMenu1Click(Sender: TObject);
var
MenuItem: TMenuItem;
begin
if Sender is TMenuItem then            //确保Sender是TMenuItem类型
begin
    MenuItem := TMenuItem(Sender);       //获取并显示菜单项的Caption
    ShowMessage(MenuItem.Caption);
end;
end;
/////

procedure TForm13.FormCreate(Sender: TObject);
var
I, j: Integer;
begin
// 假设MainMenu1已经添加到窗体中,并且有多个菜单项
for I := 0 to PopupMenu1.Items.Count - 1 do
begin
    // 为每个菜单子项关联事件处理程序
    for j := 0 to PopupMenu1.Items.Count - 1 do
    begin
      PopupMenu1.Items.Items.OnClick := MainMenu1Click;
    end;
end;
end;

end.


Project6.dpr
program Project6;

uses
Vcl.Forms,
Unit13 in 'Unit13.pas' {Form13};

{$R *.res}

begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm13, Form13);
Application.Run;
end.


希望再好好的演示一下? {:301_974:}
怎么去判断不是子菜单,而是子菜单项???

冥界3大法王 发表于 2024-10-10 10:42

本帖最后由 冥界3大法王 于 2024-10-10 10:47 编辑

procedure TForm13.MainMenu1Click(Sender: TObject);
var
MenuItem: TMenuItem;
begin
if (Sender is TMenuItem) and (MenuItem.Parent <> nil) then            //这样写不行!MenuItem.Parent <> MenuItem.Parent)也不行。
begin
    MenuItem := TMenuItem(Sender);
    ShowMessage(MenuItem.Caption);
end;
end;
//这样写不行!

homejun 发表于 2024-10-10 11:35

本帖最后由 homejun 于 2024-10-10 11:36 编辑

// 假设PopupMenu1已经添加到窗体中,并且有多个菜单项
for I := 0 to PopupMenu1.Items.Count - 1 do
begin
    // 为每个菜单子项关联事件处理程序
    for j := 0 to PopupMenu1.Items.Count - 1 do
    begin
      if PopupMenu1.Items.Items.Count = 0 then
      PopupMenu1.Items.Items.OnClick := MainMenu1Click;
      for z := 0 to PopupMenu1.Items.Items.Count - 1 do
      begin
      if PopupMenu1.Items.Items.Items.Count = 0 then
          PopupMenu1.Items.Items.Items.OnClick := MainMenu1Click;
      end;
    end;
end;

lies2014 发表于 2024-10-10 11:42

本帖最后由 lies2014 于 2024-10-10 11:53 编辑

冥界3大法王 发表于 2024-10-10 10:11
@homejun
@lies2014
要是下面这种又当如何?

这种用递归实现比较简单,逻辑也清晰,不管多少层菜单,一个函数搞定

unit Unit1;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Menus;
type

{ TForm1 }

TForm1 = class(TForm)
    AAA1: TMenuItem;
    BBB1: TMenuItem;
    N7771: TMenuItem;
    N8881: TMenuItem;
    N5: TMenuItem;
    N4: TMenuItem;
    N2221: TMenuItem;
    N1111: TMenuItem;
    N3: TMenuItem;
    N2: TMenuItem;
    N1: TMenuItem;
    PopupMenu1: TPopupMenu;
    procedure FormCreate(Sender: TObject);
private
    procedure MainMenu1Click(Sender: TObject);
    procedure SetItem(tmpItems: TMenuItem);
public

end;

var
Form1: TForm1;

implementation

{$R *.dfm}

{ TForm1 }

procedure TForm1.MainMenu1Click(Sender: TObject);
var
MenuItem: TMenuItem;
begin
if Sender is TMenuItem then            //确保Sender是TMenuItem类型
begin
    MenuItem := TMenuItem(Sender);       //获取并显示菜单项的Caption
    ShowMessage(MenuItem.Caption);
end;
end;

procedure TForm1.SetItem(tmpItems: TMenuItem);
var
i: Integer;
begin
for i := 0 to tmpItems.Count - 1 do
begin
    if tmpItems.Count = 0 then tmpItems.OnClick := MainMenu1Click
    else SetItem(tmpItems);
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
SetItem(PopupMenu1.Items);
end;

end.

冥界3大法王 发表于 2024-10-10 11:54


@lies2014
实在是搞不定了,只能打包完整传上来解决了。https://wwgc.lanzouj.com/i968c2c5nmuf


lies2014 发表于 2024-10-10 13:50

冥界3大法王 发表于 2024-10-10 11:54
@lies2014
实在是搞不定了,只能打包完整传上来解决了。https://wwgc.lanzouj.com/i968c2c5nmuf

用我上面的递归函数就能解决

链接:https://pan.baidu.com/s/17VFRFe2BA_s2X7hUouBVZA
提取码:i8ec

实际上问题不在于实现的方式,在于菜单项下面还有子菜单的时候,鼠标移过去是会自动展开下级菜单的,即在代码里自动执行了一个鼠标点击动作,所以就会执行你的点击函数出现弹窗
我的递归代码只在最末级菜单弹窗,因此就避免了这个问题
页: [1] 2
查看完整版本: 求教,为啥得不到子菜单项Caption ?