Just thought i'd add some code if you're still playing around with this. Put a stringgrid on a form and assign these 2 events onsetedittext and onkeyup. You'll also need a global boolean variable (i called mine newrow) to see if a new row is needed.

[code=delphi]
procedure TForm1.StringGrid1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
{ if user presses return and new row is allowed then add 1 to row count, set the cursor to the first cell in new row (allowing for fixed columns) }
if (Key=VK_RETURN) and (newrow) then begin
StringGrid1.RowCount:=StringGrid1.RowCount+1;
StringGrid1.Col:=StringGrid1.FixedCols;
StringGrid1.Row:=StringGrid1.RowCount-1;
end;
end;

procedure TForm1.StringGrid1SetEditText(Sender: TObject; ACol, ARow: Integer; const Value: string);
var
k : Integer;
begin
{are we editing the last cell in the row? if not, we don't need to check and newrow is not needed(false) }
with StringGrid1 do begin
if (EditorMode) and (ACol=ColCount-1) and (ARow=RowCount-1) then begin
newrow:=True; //default is new row needed
{loop through columns (allowing for fixed ones)
for k:=FixedCols to ColCount-1 do
if Cells[k,Row]='' then begin
{if any cell is blank then stop the loop and new row isn't needed }
newrow:=false;
Break;
end;
end
else newrow:=false;
end;
end;
[/code]