One of my customers is getting an “Image index out of bounds.” error message in his application.
The cause of this could be difficult to track down. Depending on the complexity of the form which is causing the error message, any control on the form could have an invalid value for it’s ImageIndex property.
The invalid ImageIndex might be simply an invalid property setting, or it could be that the property is incorrectly set somewhere in code. If the problem is as simple as an invalid property setting, this solution may help us find the problem….
In order to make finding the cause of the problem easier, I’ve written this button ‘OnClick’ handler which searches for all components on the form with an ImageIndex property, and for which the image index is not the default ‘-1’…
(*note: This might be useful for tracking other invalid property settings with modification, which is why I felt it was worth sharing here.*)
procedure TForm1.Button1Click(Sender: TObject); function TestImageIndex( Component: TComponent; var Found: boolean ): int32; var LContext: TRttiContext; LClass: TRttiInstanceType; Properties: TArray<TRttiProperty>; l: uint32; idx: uint32; const utImageIndex = 'IMAGEINDEX'; begin Found := False; LContext := TRttiContext.Create; LClass := LContext.GetType(Component.ClassType) as TRttiInstanceType; Properties := LClass.GetDeclaredProperties; l := length(Properties); if l>0 then begin for idx := 0 to pred(l) do begin if Uppercase(Trim(Properties[idx].Name))=utImageIndex then begin Found := True; Result := Properties[idx].GetValue(Component).AsInteger; Exit; end; end; end; end; function RecursiveSearch( Component: TComponent; Current: string ): string; var Test: boolean; Value: int32; idx: int32; begin // Test the current component Value := TestImageIndex(Component,Test); if ((Test) and (Value<>-1)) then begin Result := Current + ' ' + Component.Name; end; // Test child components if Component.ComponentCount>0 then begin for idx := 0 to pred(Component.ComponentCount) do begin Result := Result + RecursiveSearch( Component.Components[idx], Result ); end; end; end; var TestStr: string; begin TestStr := ''; TestStr := Trim(RecursiveSearch(Self,'')); if (TestStr<>'') then begin ShowMessage('Found incorrect image index: '+TestStr); end else begin ShowMessage('No incorrect image index found.'); end; end;
The following video demonstrates me using this code to track down a faulty ImageIndex property…
(* best viewed full screen *)
As you can see in the video, if the problem is so simple as an invalid property setting, we can resolve the problem using RTTI to locate the violating property. In the case of TButton, no exception is raised for the invalid property, however, other controls / third party controls may behave differently and raise the message that my customer is seeing.
Let’s hope this helps!