Mostrando entradas con la etiqueta Form. Mostrar todas las entradas
Mostrando entradas con la etiqueta Form. Mostrar todas las entradas

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.

domingo, 30 de junio de 2019

Formularios MDI.

Mucho debate genera este tema, como que es obsoleto, antiguo, etc. Siempre que busqué información terminé abandonando, porque encontré paquetes abandonados, que use frames y miles de consejos de no usarlos. A mí me parece más ridículo programar todo con showmodal, si bien es más cómodo, fácil y, hasta si se quiere, seguro; pero no dejo de tener en mis programas un formulario principal eternamente vacío, en la mayoría de los casos. No me refiero a los formularios en cascada, sino a que cada vez que se abra un formulario, el mismo ocupe el espacio que hay en el formulario principal. También algunos usuarios prefieren este método a un formulario showmodal flotando. Probablemente esto pueda hacerse mejor usando frames, pero de momento lo desconozco.
La solución se me ocurrió simplemente pensando en la propiedad aling:=alClient pensé que si funciona con un TMemo, ¿por qué no con un Form? y así encontré en el foro, utilizando la búsqueda avanzada, la clave: FromStyle, uno debe ser fsMDIForm y el otro fsMDIChild sin olvidar Aling alClient.

En el video se muestra, con errores como el que se ve en el minuto 3:30 donde intento establecer el parentesco del Form1 respecto de Form2 sin notar que el Form2 se crea después que el Form1 obteniendo un hermoso SIGSEGV apreciable en el minuto 5.



Este error se soluciona cambiando en el archivo del proyecto el orden de creación de los formularios y estableciendo el parentesco en el evento Create del Form1.



Es solo un ejemplo, la mayoría de los formularios los creo, los muestro y los libero: Fomr2.Crate(nil); Form2.ShowModal; FreeAndNil(Form2); todavía no probé como hacerlo, pero ya sé que ShowModal no se utiliza con un Form de estilo fsMDIChild, y es lógico.

Código fuente Formularios MDI.

sábado, 13 de enero de 2018

Cambiar el ícono del programa y formularios

Esto que explicaré a continuación no cambia el icono del ejecutable, solo del programa en ejecución y los formularios (ventanas).

Para cambiar el icono principal, del programa, tenemos que ir a opciones del proyecto:


Es la primera opción así que encontrarla es bastante simple. Es importante respetar el tamaño y los bits por pulgada (bpp). No importa desde donde cargamos la imagen ya que pasará a ser parte del ejecutable. El formato debe ser .ico. Cualquier imagen se puede convertir a ICO usando GIMP se logra esto desde archivos--> Exportar como y escribir el nombrearchivo.ico y guardar.

Cuando se ejecute el programa en el panel se verá así:


Para cambiar o agregar un icono a un formulario (Form) desde el inspector de objetos ir a la propiedad icon y pulsar sobre los tres puntos (...):


para que se abra la siguiente ventana:


presionar "Cargar" el icono y aceptar.

martes, 9 de enero de 2018

Formularios: establecer tamaños límites.

Si deseamos que un formulario pueda ser redimensionado por el usuario pero sobre un rango de valores mínimos y máximos, podemos valernos de las constraints (limitaciones) ya sea desde el inspector de objetos, previamente seleccionando el formulario, o por código.


Aquí vemos que MaxHeight y MaxWidth tiene valor cero, eso significa que puede agrandarse el formulario sin límites. En cambio en MinHeight y MinWidth le especificamos los valores mínimos del formulario, de esta forma si el usuario quiere achicarlo fuera de ese rango, le será imposible. Podrá achicarlo a por ejemplo 50x50 pero ni bien suelte el click del mouse, el formulario se redimensionará automáticamente a sus valores mínimos.
Lo mismo es válido para el tamaño máximo, solo hay que especificar los valores.

sábado, 12 de agosto de 2017

Deshabilitar todos los componentes de un formulario

  for i:=0 to ComponentCount-1 do
    if Components[i] is TControl then TControl(Components[i]).Enabled:=False;