Странное поведение при добавлении кнопки в delphi ide

Я пробовал кое-что и хотел создать расширение IDE для delphi. Моя основная идея заключалась в расширении функции списка дел, которая в настоящее время присутствует в среде IDE.

Первым шагом было добавление кнопки в среду IDE, которая открывала бы форму, показывающую элементы списка дел.

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

Я добавляю свою кнопку на панель CustomToolbar, которая отмечена синим вопросительным знаком (см. Снимок экрана позже)

Что происходит: я устанавливаю свой пакет, и кнопка добавляется с правильным изображением рядом с существующей кнопкой. Теперь я закрываю модальную форму с установленными пакетами, и синий вопросительный знак меняется.

введите описание изображения здесь

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

Как было предложено в руководстве, которое я нашел в Интернете, я использовал TDatamodule для реализации своего кода.

Мой код:

procedure TDatamoduleToDoList.Initialize;
var
  LResource, LhInst: Cardinal;
begin
  LhInst := FindClassHInstance(Self.ClassType);
  if LhInst > 0 then
  begin
    LResource := FindResource(LhInst, 'icon', RT_Bitmap);
    if LResource > 0 then
    begin
      FBMP := Vcl.Graphics.TBitmap.Create;
      FBMP.LoadFromResourceName(LhInst, 'icon');
    end
    else
      DoRaise('Resource not found');
  end
  else
    DoRaise('HInstance Couldn''t be found');
  FToDoAction := TTodoAction.Create(Self);
  FToDoAction.Category := actionCat;
  FToDoAction.ImageIndex := FIntaServices.ImageList.Add(FBMP, nil);
  FToDoAction.Name := 'my_very_own_action_man';
end;

procedure TDatamoduleToDoList.DataModuleCreate(Sender: TObject);
begin
  //Create extension
  if Supports(BorlandIDEServices, INTAServices, FIntaServices) then
  begin
    Initialize;
    if FToDoAction <> nil then
      FCustBut := TSpeedButton(FIntaServices.AddToolButton(sCustomToolBar, 'CstmToDoList', FToDoAction))
    else
      DoRaise('Initialize failed');
  end
  else
    DoRaise('Something went wrong');
end;

DoRaise - это моя собственная процедура, которая просто уничтожает все мои объекты и вызывает исключение, сделано это для предотвращения утечек памяти в ide.

Но, я думаю, я не делаю ничего странного, но эта проблема все же возникает.
Я надеюсь, что кто-то здесь, возможно, сделал что-то похожее и увидел ошибку в моем коде.

Заранее спасибо.

P.s. если вам нужна дополнительная информация или посмотрите остальную часть модуля, дайте мне знать и я помещу весь модуль на github или что-то в этом роде.

Изменить: Благодаря @Uwe Raabe мне удалось решить эту проблему. Проблема обнаружена в комментариях INTAServices.AddImages

AddImages берет все изображения из данного списка изображений и добавляет их в список изображений основного приложения. Он также создает внутренний массив сопоставления из исходных индексов изображений в новые индексы в основном списке изображений. Это сопоставление используется AddActionMenu для переназначения свойства ImageIndex объекта действия новому ImageIndex. Это должен быть первый метод, вызываемый при добавлении действий и пунктов меню в главное окно приложения. Возвращаемое значение - это первый индекс в списке изображений основного приложения первого изображения в списке источников. Вызовите эту функцию с нулевым списком изображений, чтобы очистить внутренний массив сопоставления. В отличие от функции AddImages из интерфейса предка, эта версия принимает идентификатор, который позволяет повторно использовать тот же базовый индекс. Это полезно, когда IDE реализует загрузку личностей по запросу, чтобы изображения регистрировались только один раз и можно было использовать одни и те же индексы изображений.

Решение в конечном итоге заключалось в добавлении моего изображения в локальный список изображений, который был добавлен в список изображений кода IntaServices:

procedure TDatamoduleToDoList.DataModuleCreate(Sender: TObject);
begin
  //Create extension
  if Supports(BorlandIDEServices, INTAServices, FIntaServices) then
  begin
    Initialize;
    if FToDoAction <> nil then
    begin
      FCustBut := TSpeedButton(FIntaServices.AddToolButton(sCustomToolBar, 'CstmToDoList', FToDoAction));
      FToDoAction.ImageIndex := FIntaServices.AddImages(FImages);//This is the fix
    end
    else
      DoRaise('Initialize failed');
  end
  else
    DoRaise('Something went wrong');
end;

person Teun Pronk    schedule 26.09.2017    source источник
comment
Какой тип возвращает AddToolButton. То, что вы должны использовать, наводит на мысль, что это не то, что вы думаете.   -  person David Heffernan    schedule 26.09.2017
comment
@DavidHeffernan, AddToolButton возвращает TControl. Я согласен с тем, что жесткий слепок здесь может быть проблематичным и даже не нужен.   -  person Uwe Raabe    schedule 26.09.2017


Ответы (1)


Вы не должны возиться напрямую с INTAServices.ImageList. Вместо этого используйте INTAServices.AddMasked или INTAServices.AddImages (если у вас есть локальный список изображений в вашем модуле данных).

Вы можете безопасно использовать INTAServices.ImageList для подключения к элементам управления, но вам не следует ни добавлять, ни удалять изображения в нем напрямую.

person Uwe Raabe    schedule 26.09.2017
comment
Спасибо за совет. Я пробовал и AddMasked, и AddImages с локальным списком изображений, но проблема все еще сохраняется. Есть другие мысли? - person Teun Pronk; 26.09.2017
comment
Приведите минимальный полный пример, показывающий эту проблему. - person Uwe Raabe; 26.09.2017
comment
Хорошо, я изучил это подробнее и решил это. Ответ действительно был в INTAServices.AddImages, в комментариях над ним. Я приму это и снова поставлю решение в вопросе. Спасибо. - person Teun Pronk; 26.09.2017