Динамическое создание подменю в Delphi - PullRequest
3 голосов
/ 16 февраля 2009

У меня есть всплывающее меню, и я хочу, чтобы один из пунктов открыл подменю с динамически создаваемым списком (это список пользовательских флагов). Вот как я создаю пункты меню (FlagAs - это пункт меню, к которому я хочу прикрепить подменю):

lNewMenuItems: array[0..flagCount] of tMenuItem;

for I := 0 to flagCount do
begin
  { Create a new menu item }
  lNewMenuItems[I] := tMenuItem.Create(FlagAs);
  lNewMenuItems[I].Caption := FlagNames[I];
  lNewMenuItems[I].Tag := I; { Tag with the flag number }
  lNewMenuItems[I].OnClick := miFlagClick;
end;

FlagAs.Add(lNewMenuItems);

Обработчик miFlagClick просто переключает проверенный статус своего отправителя:

procedure TMyForm.miFlagClick(Sender: TObject);
begin
  (Sender as tMenuItem).Checked := not (Sender as tMenuItem).Checked;
end;

Элементы добавляются отлично, но они не проверяются, когда я нажимаю на них. Обработчик события вызывается РЕДАКТИРОВАТЬ: и отправитель является правильным пунктом меню, но флажок не появляется в следующий раз, когда я открываю меню. Что я делаю не так? Или я неправильно создаю меню? (Примечание flagCount может измениться в будущем, но определяется как константа в коде)

РЕДАКТИРОВАТЬ: вышеописанное действительно работает - см. Мой ответ ниже

Ответы [ 4 ]

4 голосов
/ 16 февраля 2009

В Delphi 2009 я попробовал следующее, и все заработало:

procedure TForm5.FormCreate(Sender: TObject);
var
  i : Integer;
  mis : array[0..3] of TMenuItem;
begin
  for i := 0 to 3 do begin
    mis[i] := tMenuItem.Create(SubMenu);
    NewMenu(mis[i]);
  end;
  SubMenu.Add(mis);
end;

procedure TForm5.NewMenu(var mi: TMenuItem);
begin
  mi.Caption := 'Test';
  mi.OnClick := TestClick;
end;

procedure TForm5.TestClick(Sender: TObject);
begin
 (Sender as tMenuItem).Checked := not (Sender as tMenuItem).Checked;
end;
2 голосов
/ 17 февраля 2009

Просто в стороне (я знаю, вы нашли причину)

Почему вы используете lNewMenuItems: array [0..flagCount] of tMenuItem; вместо использования единственной переменной?

Кроме того, есть ли причина не использовать свойство AutoCheck?

 var
    NewMenuItem: TMenuItem;
    I : Integer;
  begin
    for I := 0 to flagCount do
    begin
      { Create a new menu item }
      NewMenuItem := TMenuItem.Create(FlagAs);
      NewMenuItem.Caption := FlagNames[I];
      NewMenuItem.Tag := I; { Tag with the flag number }
      // NewMenuItem.OnClick := miFlagClick;
      NewMenuItem.AutoCheck := True;
      FlagAs.Add(NewMenuItem);
    end;
  end;
0 голосов
/ 16 февраля 2009

Возможно, к FlagAs присоединен обработчик событий, который очищает ваши отмеченные флаги?

0 голосов
/ 16 февраля 2009

Это была моя ошибка - еще одна часть моего кода изменяла статус Checked, о котором я забыл. Я чувствую себя глупо сейчас. Извините за трату времени ...

...