EtheaDev / SVGIconImageList

Three engines to render SVG (Delphi Image32, Skia4Delphi, Direct2D wrapper) and four components to simplify use of SVG images (resize, fixedcolor, grayscale...)
Apache License 2.0
321 stars 93 forks source link

Out of range error in function TSVGIconImage.SVGIconItem #198

Closed luebbe closed 3 years ago

luebbe commented 3 years ago

I have a strange error which I don't understand.

on a form I have a TSVGIconImage. In FormCreate I assign the imagelist and -index as follows:

  svgArrow.ImageList := dmResources.imlEnabledButtons;
  svgArrow.ImageIndex := cImgRight;

When this image should be painted I receive an "Out of range exception" in

function TSVGIconImage.SVGIconItem: TSVGIconItem;
var
  {$IFDEF D10_3+}
  LVirtualImageList: TVirtualImageList;
  LItem: TVirtualImageListItem;
  {$ENDIF}
  LSVGIconItems: TSVGIconItems;
begin
  Result := nil;
  if FImageList is TSVGIconImageListBase then
  begin
    LSVGIconItems := TSVGIconImageListBase(FImageList).SVGIconItems;
    Result := LSVGIconItems[FImageIndex];
  end;
  {$IFDEF D10_3+}
  if (FImageList is TVirtualImageList) then
  begin
    LVirtualImageList := TVirtualImageList(FImageList);
    if LVirtualImageList.ImageCollection is TSVGIconImageCollection then
    begin
      LSVGIconItems := TSVGIconImageCollection(LVirtualImageList.ImageCollection).SVGIconItems;
      LItem := LVirtualImageList.Images[FImageIndex];
      if Assigned(LItem) then
        Result := LSVGIconItems[LItem.Collectionindex]; <--- Exception here, because LItem.CollectionIndex = -1
    end;
  end;
  {$ENDIF}
end;

because LItem.CollectionIndex = -1

When I initialize the icon with

  svgArrow.ImageList := dmResources.imlEnabledButtons;
  svgArrow.ImageIndex := cImgRight -1;

the icon is painted.

How can it happen that the collectionindex is -1? Is there perhaps a problem with the icon name, because it is similar to a standard property? There must be something to it, because the exception also happens with icons named "Top" or "Right". I only access icons by index, never by name.

luebbe commented 3 years ago

Until now I found out that this is also a very nasty side effect of the combination of gettext translation and SVGIconImageList. At some point it still translates the icon names. When I switch the application's language to English, everything is fine. Have you ever tried what happens, when an icon's name is changed?

This is what I see in the debugger when I put a breakpoint on the exception line: grafik The original item name hasn't changed, but due to some "magic" LItem: TVirtualImageListItem was translated from "stop" to "beenden"

I put a breakpoint here:

procedure TVirtualImageListItem.SetName(const AValue: String);
begin
  FName := AValue;
end;

but this method was never entered.

The solution is again to put a component on gettext's ignore list:

TP_GlobalIgnoreClass(TVirtualImageList);

luebbe commented 3 years ago

Added information to the "Known issues" Wiki page

pyscripter commented 3 years ago

The solution is again to put a component on gettext's ignore list:

TP_GlobalIgnoreClass(TVirtualImageList);

I have been using: TP_GlobalIgnoreClassProperty(TObject,'ImageName');

ImageName should not be translated in any component.

luebbe commented 3 years ago

Should I add this to the Wiki https://github.com/EtheaDev/SVGIconImageList/wiki/Known-issues? I thought it would be better to ignore any property of the List instead of a specific property of any object.

pyscripter commented 3 years ago

I tried to "kill many birds with one stone". ImageName is present in many components (for example CustomButton, MenuItem, Action), and should never be be translated.

luebbe commented 3 years ago

ok, I'll add yours as an alternative solution to the Wiki entry