Access violation with TMSFNCGridGetCellLayout

Hi,

I have an Issue with TMSFNCGridGetCellLayout. When I put the application in the full screen I have an access violation. I reproduce it with the Demo. This is my code I add in your demo : TMS FNC UI Pack\Demos\LCL\Grid\Database\MemDataSet

procedure TForm1.TMSFNCGrid1GetCellLayout(Sender: TObject; ACol, ARow: Integer;
ALayout: TTMSFNCGridCellLayout; ACellState: TTMSFNCGridCellState);
var
activeRecord, c, i : Integer;
monChamp: TField;
maGrille : TTMSFNCGrid;
monAdaptateurGrille : TTMSFNCGridDataBaseAdapter;
begin

magrille := TTMSFNCGrid(Sender);
if (ARow <= magrille.FixedRows - 1) then
Exit;

c := ACol - magrille.FixedColumns;

if (c >= 0) and (c <= magrille.Columns.Count - 1) then
begin
monAdaptateurGrille := TTMSFNCGridDataBaseAdapter(TMSFNCGridDatabaseAdapter1);
if monAdaptateurGrille.CheckDataSet then
begin
activeRecord := monAdaptateurGrille.DataLink.ActiveRecord;
try
monAdaptateurGrille.SetActiveRecord(ARow);
monChamp := monAdaptateurGrille.FieldAtColumn[3];
if Assigned(monChamp) then
begin
i := 0;
if TryStrToInt(monChamp.AsString, i) then
begin
if i > 50000 then // ou autre chose
begin
ALayout.Fill.Color := gcRed;
end;
end;
end;
finally
monAdaptateurGrille.DataLink.ActiveRecord := activeRecord;
end;
end;
end;
end;

Can you provide more info about the access violation? Put a screenshot of the error?

2022-10-28_08h25_11.zip (2.9 MB)
Find in attachement the video

The error appears after several passages in the code: TryStrToInt(monChamp.AsString, i)

Supposedly the issue is that the OnGetCellLayout is triggered with a row that lies beyond the buffercount, which is potentially the reason for the issue. I suggest to add the required check before trying the access the data. Similar to what is done internally in the grid database adapter.

procedure TForm1.TMSFNCGrid1GetCellLayout(Sender: TObject; ACol, ARow: Integer;
  ALayout: TTMSFNCGridCellLayout; ACellState: TTMSFNCGridCellState);
var
  activeRecord, c, i: Integer;
  monChamp: TField;
  maGrille: TTMSFNCGrid;
  monAdaptateurGrille: TTMSFNCGridDatabaseAdapter;
  o: Integer;
begin

  maGrille := TTMSFNCGrid(Sender);
  if (ARow <= maGrille.FixedRows - 1) then
    Exit;

  c := ACol - maGrille.FixedColumns;

  if (c >= 0) and (c <= maGrille.Columns.Count - 1) then
  begin
    monAdaptateurGrille := TTMSFNCGridDatabaseAdapter
      (TMSFNCGridDatabaseAdapter1);
    if monAdaptateurGrille.CheckDataSet then
    begin
      activeRecord := monAdaptateurGrille.DataLink.activeRecord;
      try
        o := monAdaptateurGrille.DataLink.ActiveRecord;

        monAdaptateurGrille.SetActiveRecord(ARow);

        if (monAdaptateurGrille.DataLink.ActiveRecord < 0) or ((monAdaptateurGrille.DataLink.ActiveRecord >= monAdaptateurGrille.DataLink.BufferCount) and
          not ((monAdaptateurGrille.DataLink.ActiveRecord = monAdaptateurGrille.DataLink.BufferCount) and (monAdaptateurGrille.DataSetType = adsNonSequenced))) then
        begin
          monAdaptateurGrille.DataLink.ActiveRecord := o;
          Exit;
        end;

        monChamp := monAdaptateurGrille.FieldAtColumn[3];
        if Assigned(monChamp) then
        begin
          i := 0;
          if TryStrToInt(monChamp.AsString, i) then
          begin
            if i > 50000 then // ou autre chose
            begin
              ALayout.Fill.Color := gcRed;
            end;
          end;
        end;
      finally
        monAdaptateurGrille.DataLink.activeRecord := activeRecord;
      end;
    end;
  end;
end;      

Thanks it's work well now

This topic was automatically closed 60 minutes after the last reply. New replies are no longer allowed.