Author: Tomas Rutkauskas
I want the following: A StringGrid with 1 column of buttons in it. The number of
rows in the grid is not known at design time, so the buttons are created at runtime.
Answer:
TSpeedButton will work and you won't have to worry about the TabStop. The problem
with using the Rect that comes in as a param, it doesn't hit all the cells in the
column. So what you end up with is buttons displaying in the wrong cells. If it
doesn't matter, then you're ok. But if it does, then you'll need to update the
entire column for all the visible cells. Here's what I came up with:
1 { ... }2 var3 HelpButtons: arrayof TSpeedButton;
4 5 procedure Form1.CreateTheButtons;
6 var7 i: Integer;
8 begin9 SetLength(HelpButtons, ParamGrid.RowCount - 1);
10 for i := 0 to ParamGrid.RowCount - 2 do11 begin12 HelpButtons[i] := TSpeedButton.Create(Self);
13 HelpButtons[i].Visible := False;
14 HelpButtons[i].Parent := ParamGrid;
15 HelpButtons[i].Caption := IntToStr(i) + ' ?';
16 HelpButtons[i].Width := 34;
17 HelpButtons[i].Height := 18;
18 HelpButtons[i].Tag := i;
19 HelpButtons[i].OnClick := ParamGridButtonClick;
20 end;
21 {Force the buttons to show}22 ParamGrid.Refresh;
23 end;
24 25 procedure TForm1.ParamGridDrawCell(Sender: TObject; ACol, ARow: Integer;
26 Rect: TRect; State: TGridDrawState);
27 28 procedure UpdateTheColumn;
29 var30 i: Integer;
31 R: TRect;
32 begin33 for i := ParamGrid.TopRow to (ParamGrid.VisibleRowCount + ParamGrid.TopRow) do34 begin35 if i >= ParamGrid.RowCount then36 Break;
37 R := ParamGrid.CellRect(2, i);
38 HelpButtons[i - 1].Top := R.Top;
39 HelpButtons[i - 1].Left := R.Left;
40 ifnot HelpButtons[i - 1].Visible then41 HelpButtons[i - 1].Visible := True;
42 end;
43 end;
44 45 begin46 if Length(HelpButtons) = 0 then47 Exit;
48 ifnot FRefresh then49 Exit;
50 if ((ACol = 2) and (ARow > 0)) then51 begin52 UpdateTheColumn;
53 end;
54 end;
55 56 procedure TForm1.ParamGridButtonClick(Sender: TObject);
57 begin58 ShowMessage('Click ' + Sender.ClassName + ' ' + IntToStr(TControl(Sender).Tag));
59 end;