TMenuItem.GroupIndex всегда равен 1

type
  TGROUP_ID = (GROUP_AUDIO, GROUP_VIDEO, GROUP_CONTAINER);
procedure TYouTubeFrameVideo.MenuItemDownloadClick(Sender: TObject);
var
  thr : TThreadFather;
  mi : TMenuItem;
begin
  if cfg.TemporaryPath = '' then
  begin
    ShowMessage('Не указана папка для временных файлов!');
    Exit;
  end;
  mi := Sender as TMenuItem;
  if mi.GroupIndex <> Byte(GROUP_AUDIO) then //тут всегда 1
  begin
procedure TYouTubeFrameVideo.ThreadGetInfoTerminate(Sender: TObject);
var
  thr : TThreadGetInfo;
  i, n : Integer;
  pt : TPoint;
  MenuItem : TMenuItem;
begin
  thr := sender as TThreadGetInfo;

  PopupMenuDownloads.Items.Clear;

  for I := 0 to Length(VideoFormats) - 1 do
  VideoFormats[i].Destroy;
  SetLength(VideoFormats, 0);
  for I := 0 to Length(AudioFormats) - 1 do
  AudioFormats[i].Destroy;
  SetLength(AudioFormats, 0);

  for I := 0 to Length(thr.fInfoVideo) - 1 do
  begin
    n := Length(VideoFormats);
    SetLength(VideoFormats, n + 1);
    VideoFormats[n] := thr.fInfoVideo[i];
    MenuItem := TMenuItem.Create(nil);
    MenuItem.OnMeasureItem := MenuItemMeasureItem;
    MenuItem.OnDrawItem := MenuItemDrawItem;
    MenuItem.Caption := thr.fInfoVideo[i].GetDisplayString;
    MenuItem.Tag := i;
    MenuItem.GroupIndex := Byte(GROUP_VIDEO); //тут 1
    MenuItem.OnClick := MenuItemDownloadClick;
    PopupMenuDownloads.Items.Add(MenuItem);
  end;

  if Length(thr.fInfoAudio) > 0 then
  begin
    MenuItem := TMenuItem.Create(nil);
    MenuItem.Caption := '-';
    PopupMenuDownloads.Items.Add(MenuItem);
    SetLength(AudioFormats, length(thr.fInfoAudio));
    for I := 0 to Length(thr.fInfoAudio) - 1 do
    begin
      AudioFormats[i] := thr.fInfoAudio[i];
      MenuItem := TMenuItem.Create(nil);
      MenuItem.OnMeasureItem := MenuItemMeasureItem;
      MenuItem.OnDrawItem := MenuItemDrawItem;
      MenuItem.Caption := thr.fInfoAudio[i].GetDisplayString;
      MenuItem.Tag := i;
      MenuItem.GroupIndex := byte(GROUP_AUDIO); //тут 0
      MenuItem.OnClick := MenuItemDownloadClick;
      PopupMenuDownloads.Items.Add(MenuItem);
    end;
  end;

  pt := btnDownload.ClientToScreen(TPoint.Create(btnDownload.Width, 0));
  btnDownload.Enabled := True;
  PopupMenuDownloads.Popup(pt.X, pt.Y);
end;

Почему в MenuItemDownloadClick() GroupIndex всегда равно 1, хотя при создании пунктов меню во втором цикле туда присваивается 0?

у последующего пункта меню гроупиндекс по идее не может быть меньше чем у предыдущего. если меньше при создании, то скорее всего заменяется значением предыдущего

Действительно, так работает. Кто это придумал?
А что делать, если захочется или придётся изменить порядок пунктов?

Здравый смысл мне подсказывает, что логическую группу как бы и нет необходимости разрывать в меню. Иначе какая это группа? Свойство Tag лучше использовать в OnClick для тех целей, что у тебя в обработчике

Если придётся менять группы местами, то так же придётся менять их ID. Где тут здравый смысл?

Каким образом я буду использовать свойство Tag в обработчике OnClick для тех целей, которые предполагается выполнять в ThreadGetInfoTerminate()?
Я бы с радостью, только вот как?

Причем здесь ThreadGetInfoTerminate? В нем в Tag расставить нужные значения. А в OnClick анализировать их и выполнять какие-то действия. Ты же это и пытаешься сделать, только тестируешь значение GroupIndex

Ну правильно. У меня два массива, а значит и группы две. GroupIndex определяет, какой массив использовать. А в Tag хранится ID элемента массива, по которому был клик. Это делается в OnClick и создаётся еще один поток и в него передаётся содержимое ячейки массива. Но это уже к теме не относится.
Я вас не понял.

Я и сам себя не понял, просто не обратил внимание, что tag уже используется в коде )

GroupIndex же вообще для чего-то другого предназначен, и что-то там всё сложно в документации. :kolobokcrossing:
Vcl.Menus.TMenuItem.GroupIndex - RAD Studio API Documentation

В общем я бы не использовал его для такого, а например в Tag бы положил ссылку на какой-нибудь объект со всей нужной инфой (если в Дельфи там только числа можно, то индекс в массиве/коллекции этих объектов), или TDictionary, где значение — объект, а ключ — TMenuItem.

там массив структур проще всего