【问题标题】:Odd behaviour when adding a toolbutton to the delphi ide向delphi ide添加工具按钮时的奇怪行为
【发布时间】:2018-03-07 11:14:50
【问题描述】:

我正在尝试一些东西并想做一个 delphi IDE 扩展。 我的基本想法是扩展当前在 IDE 中的 ToDo 列表功能。

第一步是向 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 中的内存泄漏。

但是,我认为,我没有做任何奇怪的事情,但是却出现了这个问题。
所以我希望这里有人可能做了类似的事情并在我的代码中看到错误。

提前致谢。

附:如果您需要更多信息或查看单元的其余部分,请告诉我,我会将整个单元放在 github 或类似的东西上。

编辑: 感谢@Uwe Raabe,我设法解决了这个问题。 在 INTAServices.AddImages 的 cmets 中发现问题

AddImages 从给定的图像列表中获取所有图像并添加它们 到 主要应用程序图像列表。它还从 原始图像索引到主图像列表中的新索引。这 映射由 AddActionMenu 用于重新映射 ImageIndex 属性 动作对象到新的 ImageIndex。这应该是第一种方法 在向主应用程序窗口添加操作和菜单项时调用。 返回值是主应用程序图像列表中的第一个索引 源列表中的第一个图像。用 nil 调用这个函数 图像列表清除内部映射数组。与来自的 AddImages 函数不同 祖先接口,此版本采用允许相同基本索引的 Ident 可以重复使用。这在 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;

【问题讨论】:

  • AddToolButton 返回什么类型。你必须投射表明它不是你认为的那样。
  • @DavidHeffernan,AddToolButton 返回一个 TControl。我同意硬演员在这里可能会出现问题,甚至根本不需要。

标签: delphi delphi-10.2-tokyo delphi-ide timagelist


【解决方案1】:

您不应该直接摆弄INTAServices.ImageList。而是使用INTAServices.AddMaskedINTAServices.AddImages(如果您的数据模块中有本地图像列表)。

您可以安全地使用INTAServices.ImageList 连接到您的控件,但您不应该直接添加删除其中的图像。

【讨论】:

  • 感谢您的建议。我使用本地图像列表尝试了 AddMasked 和 AddImages,但问题仍然存在。还有其他想法吗?
  • 提供一个最小的、完整的例子来说明这个问题。
  • 好吧,我对此进行了更多研究,并解决了它。答案确实在 INTAServices.AddImages 中,它在它上面的 cmets 中。我会接受这一点并再次将解决方案放在问题中。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多