As for your first question:
setting the check marks per row requires you to have an array of TCheckBoxState That maintains the values of each row.
Using the "OnGetCheckBoxState" event, you can report the value of each of these indexs per aRow as it comes in.
In other words, use the aROW as the index into the Array of TCheckBoxState you have.
Using the "OnSetCheckBoxState" is where you define the Array of TCheckBoxState but here you can examine the current value of the incoming state and if it's ON (cbChecked), you set the value within the array of that aROW and set all the others in the Array to cbUnChecked.
WHen the user clicks or toggles the state of a checkmark, the value will reflect when the "OnSetCheckBoxState" is called.
If you need an example I could write one up.
As for your second request, I don't know. Not sure what you are really asking?
I decided to give you an example.
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, Grids, StdCtrls;
type
{ TForm1 }
TForm1 = class(TForm)
StringGrid1: TStringGrid;
procedure StringGrid1GetCheckboxState(Sender: TObject; ACol, ARow: Integer;
var Value: TCheckboxState);
procedure StringGrid1SetCheckboxState(Sender: TObject; ACol, ARow: Integer;
const Value: TCheckboxState);
private
public
end;
var
Form1: TForm1;
Checks:Array[0..10] of TCheckBoxState;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.StringGrid1GetCheckboxState(Sender: TObject; ACol,
ARow: Integer; var Value: TCheckboxState);
begin
Value := Checks[ARow];
end;
procedure TForm1.StringGrid1SetCheckboxState(Sender: TObject; ACol,
ARow: Integer; const Value: TCheckboxState);
var
I:Integer;
begin
checks[aRow]:= Value;
If Value = cbChecked then
Begin
For I := Low(Checks) to High(Checks) do
If I <> aRow THen Checks[I]:= cbUnchecked;
TStringGrid(Sender).Repaint;
end;
end;
end.
In that example, the first column is used (1).