- This topic has 3 replies, 3 voices, and was last updated 12 years, 6 months ago by Support.
-
AuthorPosts
-
May 3, 2012 at 2:16 pm #35193PrimaryPowerParticipant
I found a strange issue in my application when updating to latest version of the library (7.64), I was using 7.24 before and it was working properly
The issue lies in TsPageControl component, somehow, when I demaximize the form (After it has been maximized) an error (Scanline index out of range) is raised.
After digging into the code I found the source of the error and made a fix, but I wish you to take a look and fix it in official version.
in procedure TsPageControl.AcPaint(var Message: TWMPaint) on line 781 it calls PaintItemBG(FCommonData, CI, 0, R, Point(Left + R.Left, Top + r.Top), FCommonData.FCacheBmp)
In PaintItemBG routine, on line 1008 it calls PaintAddons(ItemBmp)
In PaintAddons in line 946 it calls FillRect32(aBmp, aRect, Color), but debugging the input parameters I found that aRect values is out of aBmp boundaries. The aBmp is of 256×446 (WidthXHeight) and aRect values are (Top 0, Left 0, Bottom 450, Right 256), since the rect has a 450 value for bottom and the aBmp is lower than that (446) when it calls FillRect32 it raises an exception of Scanline index out of range.
To fix the issue I have added some boundary checks in procedure TacFast32.FillRect:
if (R.Left < 0) then R.Left := 0; if (R.Right > FBitmap.Width) then R.Right := FBitmap.Width;
if (R.Top < 0) then R.Top := 0; if (R.Bottom > FBitmap.Height) then R.Bottom := FBitmap.Height;
The final fixed routine will be
procedure TacFast32.FillRect;
var
i, w, h: Integer;
P: PRGBAArray;
begin
if (R.Left >= R.Right) or (R.Top >= R.Bottom) then Exit;
if (R.Left < 0) then R.Left := 0; if (R.Right > FBitmap.Width) then R.Right := FBitmap.Width;
if (R.Top < 0) then R.Top := 0; if (R.Bottom > FBitmap.Height) then R.Bottom := FBitmap.Height;
TsColor(Color).A := MaxByte;
h := R.Bottom -1;
w := WidthOf(R, True);
for i := R.Top to h do begin
P := FBitmap.Scanline;
FillLongword(P[R.Left], w, Cardinal(Color));
end;
end;
I had to remove the “const” qualifier in routine interface: procedure FillRect(R : TRect; var Color : TColor). This is because I´m changing the value of R if it is out of boundaries
You should always check boundaries before writting to memory!
Can you please check my solution and apply to official library?
Thanks
May 4, 2012 at 3:21 pm #48313molParticipantThere must be something else going on in your code because I cannot confirm what you're saying. Reducing the main form's size after maximizing doesn't throw an error here.
Where do you position the tabs of the tabsheet? At the bottom by any chance?
.
May 4, 2012 at 5:06 pm #48314PrimaryPowerParticipantIndeed there must be something else going on… But I couldn´t reproduce it either with a clean project, just in my project that is populated with a lot of controls… so, it must be difficult to find.. but anyway, I believe that routine is flawed because it never checks for the rect size before applying the fill
May 11, 2012 at 11:34 am #48325SupportKeymaster'PrimaryPower' wrote:so, it must be difficult to findCan you send me Dfm-file for this form?
This routine haven't checks parameters because all data checked before a routine calling…
-
AuthorPosts
- You must be logged in to reply to this topic.