2

I am trying to programme a Sudoku solver, and I want to control 81 TEdit controls as array, but their names are Edit1, Edit2, Edit3 instead of Edit[1], Edit[2], etc.

I do not want to type OnChange event handlers for all 81 controls separately.

How can I solve this?

NGLN
  • 43,011
  • 8
  • 105
  • 200
Hasan A.
  • 23
  • 4

4 Answers4

6

You don't need to do it one by one. You can select multiple controls on a form using shft-click or ctrl-drag to select them by a rectangle.

So in general:

  • Use the Object Inspector to set up the OnChange handler for one Edit
  • Optionally rename it to a more general name using the Object Inspector
  • Select all other edits on the form
  • Select the handler you just created using the Object Inspector. It will be assigned to all edits you selected.
Marjan Venema
  • 19,136
  • 6
  • 65
  • 79
5

You can create the edits dynamically.

Be sure to set the owner and the parent of the edit boxes.

procedure TForm1.OnCreate(Sender: TObject);
var
  x, y : Integer;
begin
  for y := 1 to 9 do begin
    for x := 1 to 9 do begin
      FEdit[x,y] := TEdit.Create(self);
      FEdit[x,y].Parent := self;
      FEdit[x,y].Left :=   // function based on x
      FEdit[x,y].Top  :=   // function based on y
      FEdit[x,y].Name :=   // function based on x and y
      FEdit[x,y].Width     //  any value you like
      FEdit[x,y].Height    // any value you like
      FEdit[x,y].Tag = 10*y + x;
      FEdit[x,y].OnChange = OnHandleChange;
    end;
  end;
end;

procedure TForm1.OnHandleChange(Sender: TObject);
var
  x,y : Integer;
begin
  if not Sender is TEdit then Exit;
  y := TEdit(Sender).Tag div 10;
  x := TEdit(Sender).Tag mod 10;
  // Add check if x and y are valid  

 // You now know that FEdit[x,y] is changed and you can handle accordingly.
end;

FEdit is a two dimensional array field of the form.

Toon Krijthe
  • 52,876
  • 38
  • 145
  • 202
  • You missed to show how to commonly handle the `OnChange` event (what was the question I guess) and how to get from that `OnChange` event sender's `FEdit` array coordinates. – TLama Oct 14 '12 at 10:27
  • 1
    Just a small hint: runtime-made components do not have to get a `Name`. Because whatever name you would give it, you won't use it ever more; there is no variable and the array element is its reference now. – NGLN Oct 14 '12 at 23:20
  • 1
    @NGLN: I find a component name very useful in debugging. – Uli Gerhardt Jan 14 '13 at 14:49
2

You can do something like this:

var
  myedit: array[1..81] of TEdit;
  i: integer;
...
begin
...
for i := 1 to 81 do begin
  myedit[i] := TEdit.Create(form1);
  with myedit[i] do begin
    width := 50;
    top := 50 + (i * 55);
    left := 50;
    text := 'mytext '+inttostr(i);
    parent := form1;
    // more properties...
    end;
  end;
...

You can create whatever you want dynamically, using similar code.

Wh1T3h4Ck5
  • 8,399
  • 9
  • 59
  • 79
  • 2
    Wow, that will be a multilayer sudoku :-) – TLama Oct 14 '12 at 09:52
  • 1
    You missed to show how to commonly handle the `OnChange` event (what was the question I guess) and how to get from that `OnChange` event sender's `myedit` array index. And the `Left` coordinate is still constant in your code, what makes you playing field somehow multilayer :-) – TLama Oct 14 '12 at 10:30
  • @TLama, yes I missed onChange, Gamecat did it in his example. About Left coord. that's just an example how to set properties, nothing more. – Wh1T3h4Ck5 Oct 14 '12 at 10:58
  • Thanks all for help. I mostly liked N2, will try :D – Hasan A. Oct 14 '12 at 16:31
2

In addition to the use of a common OnChange event handler and creating the edits runtime, you could also fill an array with designtime made controls.

As I recently explained in this answer, you can add designtime made controls to your one- or two-dimensional array: by searching them on name with FindComponent, searching them on Tag property with a loop, or by manually adding them to the array by typing their 81 variables.

Community
  • 1
  • 1
NGLN
  • 43,011
  • 8
  • 105
  • 200
  • I managed to write those, but here is another problem, "access violation at adress in module". The code: procedure TForm1.OnHandleChange(Sender: TObject); var bx,by,x,y,len : Integer; begin ... if not (MyEdit[bx,by,x,y].text[1] in ['1'..'9']) then MyEdit[bx,by,x,y].text:=''; .... end; So, I searched internet 1 hour, it seems to be a common problem. – Hasan A. Oct 15 '12 at 08:47
  • 1
    @Hasan That's a whole different question (_how to implement a specific solution?_) which is difficult to address in a single comment. Please ask it in a new question. – NGLN Oct 15 '12 at 09:16