Hola!!!
Hace tiempo que había querido poder cerrar un formulario de nivel superior incluso normal desde el LOAD o INIT pero siempre se quedaba colgado el proceso en windows, es decir no se liberaba el ejecutable incluso en modo desarrollo se queda el proceso activo y tenia que ir al Menú Program y Cancel para detenerlo.
El problema no esta en el formulario como tal, ya que este ejecuta bien su función, el problema realmente esta en el READ EVENTS que no se libera porque no se entera de que fue lo que paso en el formulario al cerrarlo desde el Load o Init.
Por ejemplo el siguiente código en un archivo PRG
* Iniciar SET, rutas, etc etc
* Ejecutar formulario
Do formulario_principal.scx
Read Event
Al ejecutar esto, en el formulario se inician los eventos (son muchos) pero los que interesan, el LOAD y después el INIT y entonces salta el READ EVENTS, el formulario queda en pantalla y al presionar un botón salir o cerrar desde la X, se ejecuta el Destroy del formulario que debe tener un CLEAR EVENTS y entonces el READ EVENTS se finaliza.
En los foros, ayuda y paginas web dicen que pasa terminar un formulario desde el LOAD solo hay que poner un RETURN .F: y realmente si lo hace incluso lo mas correcto es poner así
Load del formulario
this.Destroy && Para que se ejecute el Clear Events o algo que se requiera
return .f.
El mismo caso sera para el evento INIT, que a diferencia de LOAD para que el INIT se libere es necesario poner primero This.Release o this.Destroy y luego el Return .f. para que el formulario salga correctamente
Init del formulario
* Uaar Release o Destroy
* this.Release
this.Destroy && Este es el mas recomendado
return .f.
Destroy del formulario
Clear Events
Pues bien ya hemos cerrado el formulario desde el Load o Init y se ejecuto el Clear Evens, pero de todas formas la siguiente linea que es se va a ejecutar es el Read Events y se quedara bloqueada la aplicación porque el Clear Events no sirve de nada porque aun no hay un READ EVENTS activo, es decir el formulario ejecuto el Clear Events y regreso el control al PRG que ejecutara por primera vez el Read Events.
El TRUCO, es saber que fue lo que paso dentro del formulario para entonces decidir si se ejecuta el READ EVENTS o no, así de sencillito, el código del PRG seria el siguiente
* PRG Inicial
* Iniciar SET, rutas, etc etc
* Variable para saber que paso dentro del formulario.
Private _errorLoad_Init as Boolean
_errorLoad_Init = .f.
* Ejecutar formulario
Do formulario_principal.scx
* Decidir que hacer
if _errorLoad_Init
* Hubo un error, no ejecutar read events
ELSE
Read Events
ENDIF
*Liberar objetos
clear all
close all
* etc etc
Código dentro del LOAD del formulario
* Cargar librerías
if this.librerias() && Ejemplo
* Bla bla bla
else
MESSAGEBOX("Error en el Load, no se cargaron las librerías")
_errorLoad_Init = .t.
endif
* Verificar si hubo un error
IF _errorLoad_Init
this.Destroy
RETURN .f.
ENDIF
Y con esto el programa ya no se quedara colgado y podemos cerrarlo sin problema desde el Load o Init.
NOTA: Si ejecutan un formulario dentro de otro formulario ya no es necesario usar el truco puesto que el segundo formulario no requiere de un Clear Events ni un Read Events, por lo que solo es para un formulario principal,
Para que serviría hacer algo así? bueno a veces necesitamos código que se ejecuta dentro del LOAD y si algo importante no se ejecuto es mejor notificar el problema y cerrar el formulario que dejarlo abierto y siga tronando como palomita de maíz!!
Espero que les sirva y haya quedado claro el problema y una posible solución.
Si alguien sabe de una mejor opción (probada no supuesta) sera bien recibida.
saludos
Antonio Meza