I am trying to build a minesweeper program. So far, I made a two-dimensional array of buttons with the variable Buttons[rows][cols]
, so you can target every button on the field. The buttons are created on the form at runtime. Now I need to know how I can determine whether a button was clicked.
I know you can check if Sender = Button
but how does it work with two-dimensional arrays? And since I created the Buttons at runtime (FormCreate), how do I create the procedure in which the code can be executed, because it certainly shouldn't check if a button was clicked at runtime.
Would anyone be so kind and show me how I can disable a button after it was clicked? For this, obviously, I need to know how to determine which button was clicked.
When you create the buttons, set their Tag
property to an ID:
Button.Tag := Col + Row*ColCount;
Give each button the same OnClick
event handler.
Button.OnClick := ButtonClick;
These two lines of code will be inside a loop like this:
for Row := 0 to RowCount-1 do
for Col := 0 to ColCount-1 do
begin
Button := TButton.Create(Self);
Button.Parent := Self;
Button.Left := ...;
Button.Top := ...;
Button.Tag := ...;
Button.OnClick := ...;
Buttons[Row,Col] := Button;
end;
I expect you already have code like this.
Implement the event handler to decode the ID like this:
procedure TMyForm.ButtonClick(Sender: TObject);
var
Button: TButton;
Row, Col: Integer;
begin
Button := Sender as TButton;
Row := Button.Tag div ColCount;
Col := Button.Tag mod ColCount;
// respond to click
end;
Disable a control by setting its Enabled
property to False
.
Here I've assumed zero based indexing, and that your buttons are TButton
. If these assumptions are wrong, you'll clearly need to adapt to your scenario.
I think this answers the question you asked. However, using a button for each grid square is probably the wrong way to implement Minesweeper. You would be better off with a TPaintBox
, a non-visual structure to hold the state, and a single OnClick
handler for the paint box.