PDA

Ver la Versión Completa : Devolver foco desde Form No Modal al control llamante


gluglu
21-06-2007, 18:30:22
Hola Amigos !

Intento devolver el foco desde un Form No Modal en el momento de cerrarlo al control y form que lo llamaron, y a la vez liberarlo y cerrarlo correctamente.

Pero mi problema aparece que cuando intento hacer esto en el form no modal :
procedure TF_ClientSearch.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if Focus_Form <> nil then Focus_Form.SetFocus;
if Focus_Control <> nil then Focus_Form.SetFocusedControl(Focus_Control);
end;

antes de la terminación del evento FormClose me devuelve de hecho el foco al control que lo llamó (utilizo dos variables auxiliares, Focus_Form y Focus_Control), pero prosigue la ejecución en el otro form y no puedo cerrar y liberar F_ClientSearch.

Gracias por vuestra ayuda.

jhonny
21-06-2007, 20:17:07
A ver, estoy algo confundido con el asunto, pero tratare de contarte lo que entendí:

Tienes un TForm digamos que se llama Form1, en Form1 tienes un TWinControl con el que abres un Form2 y quieres cerciorarte de que cuando este ultimo se cierre, el TWinControl del Form1 tenga el foco.

Si la cosa es asi; yo sugeriría lo siguiente, en el Form1 llamar al Form2 desde el TWinControl pasándole como padre al Form2 el TWinControl... Suponiendo que el TWinControl fuera un TEdit(Edit1) la idea de llamarlo es algo asi:
Form2 := TForm2.Create(Edit1);

y luego en el OnClose del Form2 hacer algo asi:

TWinControl(Self.Owner).SetFocus;

Bueno, esa es la idea que se me ocurre según lo que te entendi :). Espero que esta vez si le atine a lo que necesitas :).

gluglu
22-06-2007, 00:08:00
Gracias Jhonny una vez más.

Sí, algo así es.

Si hasta ahí todo bien, tal y como expliqué yo también anteriormente. Me devuelve el foco correctamente y como yo quiero. Pero el problema es liberar el Form2.

Doy detalles concretos. El Form1 no puede recibir foco mientras exista Form2. Por lo tanto, en el OnActivate del Form1 compruebo si existe Form2, y si es así devuelvo el Foco al Form2.

Es por ello que necesito utilizar el evento OnActivate del Form1. Pero claro, si ahora, antes de cerrar y liberar el Form2, en algún momento devuelve el foco al control del Form1 que estaba activo antes de llamar al Form2, mediante por ejemplo Focus_Form.SetFocusedControl(Focus_Control); entonces salta el evento OnActivate del Form1 y prosigue ahí con la ejecución del programa !

Cuando libero Form2 ?

Si lo libero en alguna parte posterior del Form1.OnActivate entonces al terminar cualquier procedimiento concreto, vuelve a la línea del Form2 donde ejecuté el traspaso de foco, y al estar supuestamente liberado el Form2, salta un error.

Si sigo sin más, no libero el Form2 en ningún lado, y claro, otros tantos problemas más gordos todavía.

Por más vueltas que le doy, no logro aclararme.

A lo mejor es una tontería, pero no doy con la solución. :rolleyes:

jhonny
22-06-2007, 00:25:10
Bueno, Y ¿Porque no hace que el Form2 se vuelva Modal para que no activen el Form1, Así sea en tiempo de ejecución?

gluglu
22-06-2007, 00:33:12
Aaaaamigo !!!!

Eso es lo que tenía antes !! Y después me dí cuenta que no cumplía con lo que quería hacer.

Detallo más : Programa de reservas de Hotel. MDI. Puedo abrir cuentas reservas quieras en Forms MDI Child.

El famoso Form2 sería búsqueda de clientes. Si en una reserva busco un cliente, abro desde Form1 al Form2. Peeeeeero ahora resulta que en el Form2 de búsqueda de clientes, muestro para cada cliente las reservas anteriores que tiene ese cliente. Y quiero poder hacer click en el listado y que se me abra cualquier reserva anterior en una nueva ventana MDI. Además de tener total operatividad sobre la ventana de la reserva que acabo de abrir.

Claro, si Form2 es Modal, no puedo moverme por la reserva que acabo de abrir desde el listado de reservas anteriores de clientes en el Form2 de búsqueda de clientes.

Por eso me dí cuenta hoy que necesito que Form2 se abra No Modal para que tenga esa operativa.

Pero por otro lado, si elijo un cliente de la lista abierta en el Form2 de búsqueda de clientes, tengo que actualizar los datos de ese cliente única y exclusivamente en el Form1 de la reserva que llamó a la búsqueda de clientes, y en ningún otro.

Y además, si elijo el cliente del listado, se debe de cerrar Form2 y volver el foco al Form1 correspondiente a la reserva concreta que llamó a la búsqueda.

Ese es el problema !

Form2 lo tenía modal, pero hoy avancé con otras cosas y precisamente me dí cuenta que no podía ser modal.

No sé si esto aclara un poco las cosas, o por el contrario, lo he liado más aún. :p

gluglu
22-06-2007, 00:35:37
Añado algo más : Lo que decía antes de poder salir del Form2 de búsqueda.

Si pincho en cualquiera de los datos de una reserva que acabo de abrir desde la búsqueda, ese Form tiene que obtener el foco de manera normal y permitirme total operatividad.

Pero no debo de dejar volver a la reserva 'principal' que llamó originalmente al Form2 de búsqueda, si no se dá uno de los dos siguientes casos : que se cierre el Form2 y no se desee elegir ningún cliente, o que se elija un cliente en concreto para actualizarlo en el Form1 'llamante'.

jhonny
22-06-2007, 01:00:23
Pues quedo mas claro el asunto, lo único que se me ocurre de momento es que uses alguna variable global de tipo TSTringList, donde guardes todos los Forms2 que abras, y en el OnActive del Form1 no verifiques si el Form2 correspondiente a ese Form1 esta abierto, si no que mas bien verifiques si ese Form2 esta en dicha lista, entonces... si su form2 esta en esa lista hay que devolver el foco al form2, pero si no (Ya que al cerrar el form2 lo eliminarías de dicha lista), pues ahora si liberar lo que quede de él si es necesario.

Espero me haya hecho entender y que te sirva, por lo menos de "Norte", mientras se piensa en algo mejor. :)

roman
22-06-2007, 04:49:26
A ver que les parece esto. Llamemos frmPrincipal, frmReserva y frmClientes a los formularios principal, de reservas y de búsqueda de clentes respectivamente.

frmPrincipal es MDI, frmReserva es MDIChild y frmClientes es normal.

Cuando desde una reserva (frmReserva) abrimos una ventana de clientes hacemos esto:


with TfrmClientes.Create(Self) do
Show;

Self.Enabled := false;


Esto es, inhabilitamos todo el formulario de reserva, lo que impedirá interactuar con él hasta que alguien no lo habilite de nuevo. Este alguien será el frmReserva en su evento OnClose:


Action := caFree;

if Owner is TForm then
begin
TForm(Owner).Enabled := true;
TForm(Owner).SetFocus;
TForm(Owner).BringToFront;
end;


De todas formas y como comentario al margen, se me hace una interfaz confusa. Puede haber no sólo varias reservas abierta a un tiempo, sino también varias ventanas de búsqueda y no sé cómo hará el usuario para saber cuál corresponde a cuál.

// Saludos

gluglu
22-06-2007, 08:35:41
Muchas gracias Jhonny y Román de nuevo.

Un rápido comentario que ya tendré más tiempo esta tarde para extenderme más.

Exactamente así lo tenía, tal y como expone Román, excepto con el tema del Enable. No había caido en esa posibilidad. La aplicaré porque de hecho en otra parte del programa haga uso de ello para otra funcionalidad.

Y con respecto al comentario de Román de varias búsquedas abiertas, precisamente es lo que NO quiero yo tampoco. Sólo una búsqueda abierta. No quise incluir esa temática en este hilo. Está claro que por otro lado compruebo que sólo pueda haber una búsqueda abierta a la vez, pero tengo que saber a que Reserva corresponde esa búsqueda, lo cual no es problema.

Con el Enabled lo que me evito es la comprobación en el OnActivate de la reserva llamante, que será la clave del asunto.

Cuando lo tenga listo, expondré la solución.

Gracias una vez más.

ClNa2U ;)