PDA

Ver la Versión Completa : mostrar frame como modal


peccatum
04-06-2008, 19:26:04
Hola

Estoy usando frames dentro de un formulario en Delphi, y no he hallado la forma de mostrarlos en forma modal... es decir, que cuando se muestren no se permita acceder al formulario de donde se creó el frame, por que no quiero que se modifiquen datos que tengo ahí....

¿Cómo puedo hacer para que se comporte así un Frame?

Saludos

dec
04-06-2008, 19:29:02
Hola,

Pues, me parece que podrías meter el "Frame" dentro de un formulario, y mostrar este "modalmente". Igual hay otra forma...

peccatum
04-06-2008, 19:39:10
claro, yo tengo los frames dentro del form...

pero desde el form no puedo hacer frame.showmodal, no existe ese procedimiento...

creo que debe ser algúna propiedad del frame, pero no se cual.... sigo probando...

es que no quiero tener que bloquear controles dentro del formulario principal ya que son muchos

dec
04-06-2008, 19:48:08
Hola,

Hum... ¿tal vez deshabilitando los controles del formulario, excepto los del frame en cuestión? ...

peccatum
04-06-2008, 20:11:01
Sip voy a hacer eso...

el problemita que tengo ahora, es que no puedo volver a activar los componentes del form principal...

No encuentro el evento OnClose... OnHide ... o algo por el estilo... el evento OnExit no se dispara cuando cierro el frame... :confused::mad::(

dec
04-06-2008, 20:25:36
Hola,

Pero, si "cierras el frame", tienes que hacerlo en algún sitio. Ese sería el lugar para volver a habilitar los controles, supongo. De todas formas, pienso que podrías mostrar el "frame" en un formulario, podrías usar un formulario vacío, que no contuviera el "frame" en tiempo de diseño, pero al que se lo insertaras en tiempo de ejecución (pienso en el mismo "frame" que muestras en el formulario "principal", por decirlo así). De este modo tendrías los eventos que necesitas. No sé qué te parece la idea.

dec
04-06-2008, 20:40:23
Hola,

Ahí te adjunto una especie de ejemplo de esto último que he comentado, a ver si entra dentro de tus expectativas.

peccatum
04-06-2008, 21:17:06
Hola Dec, muchas gracias por el ejemplo. Creo que antes de insertar el frame en tiempo de ejecución, prefiero usar directamente forms comunes...

El problema que tengo con ellos (frames) es que tienen arriba a la derecha el botón cerrar, y no se como capturar el evento cuando se cierran desde allí... Cuando cierro el frame desde otro lado si puedo volver a activar los controles sin problemas....

dec
04-06-2008, 21:56:25
Hola,

El evento de un botón situado en el "Frame" puedes "capturarlo" en el propio "Frame". Fíjate en el ejemplo que te envié. El botón que ves (que está dentro del "Frame") maneja su evento "OnClick". En este se averigua qué "Parent" tiene asignado el "Frame", de modo que se haga una cosa u otra.

Volviendo al ejemplo, el botón comprueba si su "Parent" es el formulario "principal" de la aplicación, y entonces no hace nada, simplemente. Pero, si el "Parent" es el formulario en el que incluimos el "Frame" en tiempo de ejecución, entonces cierra esta formulario, volviendo a asignarse como "Parent" el formulario "principal". No sé si te refieres a algo así o qué.

peccatum
04-06-2008, 22:36:02
No me refería al ejemplo, sino al botón de cerrar q tienen los frames en la esquina superior derecha...

Cuando cierran el frame desde allí es el evento que me interesa capturar y no se como

peccatum
05-06-2008, 03:47:54
Bueno por ahora lo que voy a hacer es dejar los frames estaticos, es decir con la propiedad DragKind a dkDrag, de esa forma no aparece el bendito botoncito de cerrar...

eventualmente voy a colocar los frames en forms de la forma que indicas amigo Dec, es que todavia no le veo la gracia de hacerlo de esa forma contra usar directamente forms :confused:

me queda la inquietud de como capturar el evento 'al cerrar frame', ya que el evento 'onExit' se dispara solo cuando sucede 'OnHide' y no cuando el usuario apreta el botoncito cerrar....

Gracias y saludos

dec
05-06-2008, 04:22:15
Hola,


No me refería al ejemplo, sino al botón de cerrar q tienen los frames en la esquina superior derecha...



(...) con la propiedad DragKind a dkDrag, de esa forma no aparece el bendito botoncito de cerrar..


Creo que me he perdido algo, porque, los "Frames" no tiene ningún botón "cerrar", si tú no se lo añades... me parece que estás hablando de formularios y no de "Frames"... como digo, los "Frames" son componentes que no incorporan botón alguno, son una especie de "lienzo" sobre el que situar los componentes que queramos, para reutilizarlos en otros lugares, algo así como "super paneles" (en el sentido de superhéroe), pero, no incorporan "nada" por sí mismos...

A ver qué está pasando aquí. ;)

peccatum
05-06-2008, 05:04:17
aquí está dentro de un circulo rojo el botoncito al que hago referencia :

http://img387.imageshack.us/my.php?image=botoncitooz0.jpg


seteando la propiedad dragMode a DMAautomatic y la otra que hago referencia arriba a dkDrag el frame en cuestion se puede mover fuera del form... y es cuando aparece... y no puedo capturar el evento cuando el usuario apreta allí... ahora se entiende un poco mas?

dec
05-06-2008, 05:15:48
Hola,


aquí está dentro de un circulo rojo el botoncito al que hago referencia :

http://img387.imageshack.us/my.php?i...toncitooz0.jpg


seteando la propiedad dragMode a DMAautomatic y la otra que hago referencia arriba a dkDrag el frame en cuestion se puede mover fuera del form... y es cuando aparece... y no puedo capturar el evento cuando el usuario apreta allí... ahora se entiende un poco mas?


Sí; desde luego. Y me disculpo, pues desconocía esa cualidad de los "Frames".

Estoy tratando de hacer alguna prueba, pero, no consigo que el "Frame" se me muestre fuera del formulario (con el botón), ni aun usando las propiedades y valores que has mencionado, ¿tal vez el formulario también está implicado y necesito establecer alguna de sus propiedades de alguna manera?

Tal como imagino, tal vez podría capturarse el mensaje que Windows envíe a la ventana del "Frame" cuando se pulsa en el botón cerrar: el "Frame" no implementa un evento "OnClose", pero, podríamos mirar de capturar el mensaje de Windows susomentado. Pero como veo que el "Frame" tiene más eventos relacionados con el "Drag"... y yo en esto estoy pez... igual alguno de estos eventos sería el indicado...

peccatum
05-06-2008, 15:56:07
y la otra que hago referencia arriba a dkDrag


perdon, la propiedad DragKind la pongo a dkDock, entonces se puede mover el frame a cualquier lugar, incluso se puede resizear en tiempo de ejecución...

sacar el botón de algúna forma también me serviría...

Saludos!

roman
05-06-2008, 16:39:38
Interesante cuestión :)

El problema aquí es que ese botón realmente no pertenece al Frame. Cualquier derivado de TWinControl tiene la capacidad de arrastrarse fuera de su contenedor; lo mismo que haces con el Frame, puedes hacerlo con un Panel, por ejemplo, o ¡incluso con un Button! Al hacerlo con este último queda más clara la situación: al arrastar el control fuera del formulario, lo que sucede es que la VCL crea un formulario en caliente, de tipo TCustomDockForm e inserta en él el control.

Así pues, es con este último formulario con quien tenemos que lidiar.

Para ello, hay que capturar el mensaje CM_FLOAT del control (el Frame) que se le manda cuando -justamente- se pone a flotar y se crea el CutomDockForm.

El mensaje manda como parámetro dicho formulario y lo que podemos hacer es reemplazar su WindowProc por uno nuestro para interceptar el mensaje WM_CLOSE.

Aquí más o menos la idea:


type
TFrame2 = class(TFrame)
private
OldHostWndProc: TWndMethod;

procedure CMFloat(var Msg: TCMFloat); message CM_FLOAT;
procedure HostWndProc(var Message: TMessage);
end;

implementation

{ TFrame2 }

procedure TFrame2.CMFloat(var Msg: TCMFloat);
begin
inherited;
if (TObject(Msg.DockSource.DragTarget) is TCustomDockForm) then
begin
OldHostWndProc := TCustomDockForm(Msg.DockSource.DragTarget).WindowProc;
TCustomDockForm(Msg.DockSource.DragTarget).WindowProc := HostWndProc;
end;
end;

procedure TFrame2.HostWndProc(var Message: TMessage);
begin
if Message.Msg = WM_CLOSE then
ShowMessage('Frame Closed!');

OldHostWndProc(Message);
end;


// Saludos

dec
05-06-2008, 16:45:01
Hola,

Ahí es nada Román. Yo me ví ayer tratando de sustituir el "WindowProc" (siguiendo código tuyo, por cierto) del "Frame" y... nada de nada. Y ahora se comprende perfectamente porqué no era posible hacerlo de ese modo, por lo menos hasta donde yo llegué. Nada, nada, que el que sabe, sabe, y el que no que aprenda. :)

egostar
05-06-2008, 16:56:35
Hola,

Ahí es nada Román. Yo me ví ayer tratando de sustituir el "WindowProc" (siguiendo código tuyo, por cierto) del "Frame" y... nada de nada. Y ahora se comprende perfectamente porqué no era posible hacerlo de ese modo, por lo menos hasta donde yo llegué. Nada, nada, que el que sabe, sabe, y el que no que aprenda. :)

Hola, he estado siguendo este hilo porque nunca he usado frames, no se que beneficios aporte pero veo que tiene sus detalles, bien dices amigo dec el que sabe sabe y yo pues........ me pongo a estudiar :D:D:D

Salud OS

peccatum
05-06-2008, 17:56:06
Gracias roman por el esclarecimiento de este tema, igualmente el codigo no me resulta del todo amistoso, jeje, voy a ver como lo soluciono.

Me queda una incógnita y es cómo hacer para que el usuario pueda mover uno de estos componentes libremente dentro del form, tal cual uno los mueve en tiempo de diseño, no en modo 'flotante' digamos.... quizás es una simple configuración de propiedades pero no he dado con ella...

Saludos y gracias...

roman
05-06-2008, 19:18:23
Hola, he estado siguendo este hilo porque nunca he usado frames, no se que beneficios aporte pero veo que tiene sus detalles

En realidad, como dije arriba, no son detalles de los frames. La flotación y anclaje (floating and docking :D) son intrínsecas de cualquier control de ventana (TWinControl).

Los frames son simplemente (creo que ya lo mencionó dec) un "super panel": como un panel, puede agrupar distintos controles, pero, además tiene dos grandes ventajas:

1. Puede diseñarse como si se tratase de un formulario, esto es, en una ventana aparte, lo cual es muy cómodo cuando, por ejemplo, quieres trabajar con varios grupos de controles en un mismo formulario (alternándolos) y no quieres estar liándote con veinte páneles en tiempo de diseño.

2. Son reusables. Un Frame es como un componente que puedes insertar en uno o más formularios; le puedes definir propiedades y métodos.

// Saludos