Recent

Author Topic: Find the number of components on a form programmatically and SetFocus to each  (Read 382 times)

Aruna

  • Sr. Member
  • ****
  • Posts: 457
I have a form with different types of components. Buttons, Labels, Memo, Edit so on and so forth. The code to get the total number of components on the form works fine. So does the loop which shows each component by name. If I want to SetFocus to each component in turn in the loop how does one go about doing this, please?

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button7Click(Sender: TObject);
  2.   var
  3.   TotalComponents: Integer;
  4.   i: Integer;
  5.   component:String;
  6. begin
  7.   // Get the total number of components on the form
  8.   TotalComponents := ComponentCount;
  9.  
  10.   // Display the total number of components in a message box
  11.   ShowMessage('Total Components on Form: ' + IntToStr(TotalComponents));
  12.  
  13.   // Optionally, you can loop through the components
  14.   for i := 0 to TotalComponents - 1 do
  15.   begin
  16.     ShowMessage('Component ' + IntToStr(i + 1) + ': ' + Components[i].Name);
  17.   end;
  18. end;                                          

I tried getting the component name into a string variable and setting focus like this:

Code: Pascal  [Select][+][-]
  1. component := Components[i].Name;
  2. component.SetFocus;

but Lazarus complains saying unit1.pas(88,77) Error: Illegal qualifier
« Last Edit: August 02, 2024, 06:11:31 pm by Aruna »
Debian GNU/Linux 11 (bullseye)
https://pascal.chat/

VisualLab

  • Sr. Member
  • ****
  • Posts: 480
SetFocus is a method that is defined in the TWinControl class (only window controls can have focus). In your code, the variable Component is declared as a String type. String is a simple type, it doesn't have built-in methods and properties like classes. That's why the compiler throws an error. Also, focus can only be set for controls that are windowed. That's why it's better to use the Controls property instead of the Components property (components are often invisible). So the code should be as follows:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   i, ATotalCount: Integer;
  4.   AControl: TControl;
  5. begin
  6.   // display the total number of components in a message box
  7.   ATotalCount := Form1.ControlCount;
  8.   ShowMessage('Total components on form: ' + ATotalCount.ToString);
  9.   // optionally, you can loop through the components
  10.   Memo1.Lines.Clear;
  11.   for i := 0 to Self.ControlCount - 1 do
  12.    begin
  13.     Memo1.Lines.Add('Component ' + (i + 1).ToString + ': ' + Form1.Controls[i].Name);
  14.    end;
  15.   // focus on the last control if it is a windowed control
  16.   AControl := Form1.Controls[ATotalCount - 1];
  17.   if AControl is TWinControl
  18.    then (AControl as TWinControl).SetFocus;
  19. end;


Edit: I included a simple project using the example provided.
« Last Edit: August 02, 2024, 05:26:41 pm by VisualLab »

Aruna

  • Sr. Member
  • ****
  • Posts: 457
SetFocus is a method that is defined in the TWinControl class (only window controls can have focus). In your code, the variable Component is declared as a String type. String is a simple type, it doesn't have built-in methods and properties like classes. That's why the compiler throws an error. Also, focus can only be set for controls that are windowed. That's why it's better to use the Controls property instead of the Components property (components are often invisible). So the code should be as follows:
Your explanations were incredibly helpful and made a significant difference in my understanding. Thank you.

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   i, ATotalCount: Integer;
  4.   AControl: TControl;
  5. begin
  6.   // display the total number of components in a message box
  7.   ATotalCount := Form1.ControlCount;
  8.   ShowMessage('Total components on form: ' + ATotalCount.ToString);
  9.   // optionally, you can loop through the components
  10.   Memo1.Lines.Clear;
  11.   for i := 0 to Self.ControlCount - 1 do
  12.    begin
  13.     Memo1.Lines.Add('Component ' + (i + 1).ToString + ': ' + Form1.Controls[i].Name);
  14.    end;
  15.   // focus on the last control if it is a windowed control
  16.   AControl := Form1.Controls[ATotalCount - 1];
  17.   if AControl is TWinControl
  18.    then (AControl as TWinControl).SetFocus;
  19. end;


Edit: I included a simple project using the example provided.
Thank you again. I am going through it and learning.
Debian GNU/Linux 11 (bullseye)
https://pascal.chat/

 

TinyPortal © 2005-2018