function DBGridVisibleDataRows(AGrid: TDBGrid): Integer; var LTemTitulo : Boolean; LLinhaBase : Integer; r0, r1 : TRect; rowH, topData, visH : Integer; begin if (AGrid = nil) or (AGrid.ClientHeight <= 0) then Exit(0); LTemTitulo := dgTitles in AGrid.Options; LLinhaBase := Ord(LTemTitulo); // 0 sem títulos, 1 com títulos // mede altura real de uma linha usando dois retângulos consecutivos r0 := AGrid.CellRect(0, LLinhaBase); r1 := AGrid.CellRect(0, LLinhaBase + 1); rowH := r1.Top - r0.Top; // fallback se ainda não deu para medir (grid vazio/não pintado) if rowH <= 0 then rowH := AGrid.DefaultRowHeight + 1; // não usa GridLineWidth (protected) // topo da área de dados if r0.Top > 0 then topData := r0.Top else if LTemTitulo then topData := AGrid.DefaultRowHeight + 1 else topData := 0; visH := AGrid.ClientHeight - topData; if (rowH <= 0) or (visH <= 0) then Exit(0); Result := Max(0, visH div rowH); end;