views:

329

answers:

2

How I can find out the position (row and column index) of controls inside TGridPanel? I'd like to use common OnClick event for number of buttons and need to know the X,Y position of the button.

I'm using Delphi 2007.

+1  A: 

You can use Sender cast as a tButton and then ask it for its top and left for example:

Procedure TForm1.OnClick(Sender:tObject);
var
  X,Y : Integer;
begin
  if Sender is TButton then
    begin
      X := TButton(Sender).Top;
      Y := TButton(Sender).Left;
      // do something with X & Y
    end;
end;

Or if your just wanting to know what button was pressed, you can also use the TAG property to insert a number into each button, and then retrieve the tag value in your onclick event. Just remember to first set the Tag property to something. You can do this in the form designer if your just dropping buttons into the grid panel or in the routine your using to create and insert your buttons.

Procedure TForm1.OnClick(Sender:tObject);
var
  iButton : integer;
begin
  if Sender is TComponent then
    begin
      iButton := TComponent(Sender).Tag;
      // do something with iButton
    end;
end;

You can also use the tag property to store more than just an integer, since a pointer currently uses the same memory size as the integer you can cast a pointer to an integer and insert that value into the tag property. Just be aware that any pointer you place in this field is still treated as an integer. You are responsible for the memory it points to, it will not be managed by the component.

skamradt
Would be good with a regular TPanel, but does not address the specific question of TGridPanel where embedded controls have a Row and Column properties to be used instead of Top and Left. (as in Object Inspector)
François
+2  A: 

Unfortunately, because of the magic of TGridPanel, it is a little more complicated than just getting the Top and Left properties...

This should do it for any Control, adapt it to your needs:

procedure GetRowColumn(const AControl: TControl; var ARow, AColumn: Integer);
var
  I: Integer;
begin
  if AControl.Parent is TGridPanel then
  begin
    I := TGridPanel(AControl.Parent).ControlCollection.IndexOf(AControl);
    if I > -1 then
    begin
      ARow := TGridPanel(AControl.Parent).ControlCollection[I].Row;
      AColumn := TGridPanel(AControl.Parent).ControlCollection[I].Column;
    end;
  end;
end;

procedure TForm1.ButtonClick(Sender: TObject);
var
  Row, Column : Integer;
begin
  GetRowColumn(Sender as TControl, Row, Column);
  // do something with Row and Column
  ShowMessage( Format('row=%d - col=%d',[Row, Column]));
end;
François