domingo, 22 de agosto de 2021

SetFocus y un error muy común.

Casi todos los componentes visuales de Lazarus tienen un procedimiento llamado SetFocus, por lo que es normal que si tenemos 10 TEdit en un Form, queramos que el primero de ellos tenga el "focus", y luego el segundo y así sucesivamente. Y ahí el dicho "code first, think later" o "escribe el código primero, piensa después" se pone de manifiesto cuando intentamos un Edit1.SetFocus en el método FormCreate y tenemos un hermoso error en tiempo de ejecución. ¿Por qué?

[TCustomForm.SetFocus] Form1:TForm1 Can not focus.

Justamente porque pedimos poner el foco en algo que todavía no existe, el Edit1, en el evento FormCreate que hace lo que dice, crea el formulario, los TEdit todavía no existen.

Sí, todo muy lindo y suena hasta lógico, ¿pero entonces cómo lo consigo?

Opción 1: usando la opción "Orden de tabulación", click derecho sobre el formulario.

Opción 2: precisamente en el procedimiento FormCreate estableciendo el control activo de la siguiente forma: 

procedure TForm1.FormCreate(Sender: TObject);
begin
  ActiveControl:=Edit1;
end; 

Y la duda razonable, si no se puede un setfocus ¿por qué sí un ActiveControl?, la respuesta está en el código fuente de la unidad Forms (forms.pp), wincontrol.inc y customform.inc. La respuesta corta es que edit1.setfocus aún no está disponible porque estamos llamando a un evento de un TEdit en FormCreate, en cambio ActiveControl es una propiedad de TForm.

En el código de la unidad control.pp podemos encontrar:

    function CanFocus: Boolean; virtual;
    function CanSetFocus: Boolean; virtual;  

que son funciones públicas de la clase (class) TWinControl que hereda de TControl y también pueden ser usadas para evitar errores al utilizar el procedimiento SetFocus.

Otras opciones:

procedure TForm1.FormActivate(Sender: TObject);
begin
  Edit1.SetFocus;
end;    

procedure TForm1.FormShow(Sender: TObject);
begin
 Edit1.SetFocus;
end;    

Funcionan bien con formularios mostrados mediante ShowModal, no obstante recomiendo las dos primeras.

No hay comentarios:

Publicar un comentario