向 delphi ide 添加工具按钮时的奇怪行为

Odd behaviour when adding a toolbutton to the delphi ide

我正在尝试一些东西,想做一个 delphi IDE 扩展。 我的基本 idea 扩展了 IDE.

当前的待办事项列表功能

第一步是向 IDE 添加一个工具按钮,这将打开一个显示待办事项的表单。

但我注意到一些奇怪的事情,希望是我自己造成的,因为这意味着它可以很容易地修复。

我正在将我的工具按钮添加到 CustomToolbar,这是带有蓝色问号的那个(见后面的屏幕截图)

发生的事情:我安装了我的包,按钮添加了正确的图像,就在现有按钮的旁边。 现在我关闭带有已安装包的模态窗体,然后蓝色问号发生变化。

不要介意我使用的图标,我最终会使用不同的但没关系。
所以基本上现有项目更改为我自己的图标但由于某种原因被禁用。而且我不明白为什么会这样。

按照gu中的建议ide我在网上发现我使用了一个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 takes all the images from the given image list and adds them to the main application imagelist. It also creates an internal mapping array from the original image indices to the new indices in the main imagelist. This mapping is used by AddActionMenu to remap the ImageIndex property of the action object to the new ImageIndex. This should be the first method called when adding actions and menu items to the main application window. The return value is the first index in the main application image list of the first image in the source list. Call this function with an nil image list to clear the internal mapping array. Unlike the AddImages function from the ancestor interface, this version takes an Ident that allows the same base index to be re-used. This is useful when the IDE implements demand-loading of personalities so that the images will only get registered once and the same image indices can be used.

解决方案最终是将我的图像添加到本地图像列表中,该图像列表已添加到 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;

你不应该直接 fiddle 和 INTAServices.ImageList 左右。而是使用 INTAServices.AddMaskedINTAServices.AddImages(以防您的数据模块中有本地图像列表)。

您可以安全地使用 INTAServices.ImageList 连接到您的控件,但您不应该 Add 也不 Delete图片直接在里面。