PDA

Ver la Versión Completa : Orden formularios


newtron
26-10-2011, 20:06:55
Hola a tod@s.

Sigo intentando hacer que mis formularios no se queden detrás del menú si se pincha en este y después de pruebas con mdi en principio está complicado hacerlo usando esta forma así que se me ha ocurrido intentar hacer que el menú principal esté siempre al fondo de todos los formularios, algo parecido al SendToBack, pero el problema es que el SendToBack lo pasa al fondo de cualquier formulario de cualquier programa abierto y eso tampoco me sirve.

Mi pregunta es si hay alguna forma de poner un formulario al fondo de todos los demás formularios del programa, algo parecido al zorder de VB.

Gracias y un saludo

Ñuño Martínez
26-10-2011, 20:57:13
De todas formas, buscando información sobre SendToBack, he encontrado este hilo en Delphi Pages Forum (http://www.delphipages.com/forum/showthread.php?t=84196) de un programador que parece querer hacer lo mismo que tú. Si necesitas traducción...

roman
26-10-2011, 22:06:03
Hola a tod@s.

Sigo intentando hacer que mis formularios no se queden detrás del menú si se pincha en este y después de pruebas con mdi en principio está complicado hacerlo usando esta forma así que se me ha ocurrido intentar hacer que el menú principal esté siempre al fondo de todos los formularios, algo parecido al SendToBack, pero el problema es que el SendToBack lo pasa al fondo de cualquier formulario de cualquier programa abierto y eso tampoco me sirve.

Mi pregunta es si hay alguna forma de poner un formulario al fondo de todos los demás formularios del programa, algo parecido al zorder de VB.

Gracias y un saludo

A ver, es que yo no acabo de entender qué es lo que quieres. Si no permites que el formulario principal venga al frente, ¿cómo quieres interactuar con él? ¿Que tal que una de las opciones que quieres escoger se encuentra detrás de otro formulario, cómo la escogerías? Y si todas las opciones están en un área no cubierta por otros formularios, ¿qué más te da que venga al frente?

¿No podrías explicar con dibujitos o algo más visual?

// Saludos

newtron
27-10-2011, 09:37:47
De todas formas, buscando información sobre SendToBack, he encontrado este hilo en Delphi Pages Forum (http://www.delphipages.com/forum/showthread.php?t=84196) de un programador que parece querer hacer lo mismo que tú. Si necesitas traducción...

Gracias, le echaré un vistazo. :)

A ver, es que yo no acabo de entender qué es lo que quieres. Si no permites que el formulario principal venga al frente, ¿cómo quieres interactuar con él? ¿Que tal que una de las opciones que quieres escoger se encuentra detrás de otro formulario, cómo la escogerías? Y si todas las opciones están en un área no cubierta por otros formularios, ¿qué más te da que venga al frente?

¿No podrías explicar con dibujitos o algo más visual?

// Saludos

A ver... el tema es que yo uso formularios no modales, entonces si abro un formulario más pequeño que el menú principal y con este abierto pico en el menú de nuevo el formulario abierto más pequeño se esconde detrás de este, espero que "mesentienda" :D.

La idea entonces (despues de probar varias cosas sin resultado) es que si pico en el menú el formulario más pequeño no se esconda y si tapa alguna opción del menú que se necesite que obligue a minimizarlo con lo cuál siempre estará visible de alguna forma.

Igual es una tontería pero es lo único que se me ocurre.

Saludos

newtron
27-10-2011, 09:45:36
De todas formas, buscando información sobre SendToBack, he encontrado este hilo en Delphi Pages Forum (http://www.delphipages.com/forum/showthread.php?t=84196) de un programador que parece querer hacer lo mismo que tú. Si necesitas traducción...

Mala suerte, esto hace lo mismo que el SendToBack, se lleva el formulario al fondo de todos los programas abiertos.

Seguiré buscando.... :)

Casimiro Notevi
27-10-2011, 10:05:27
Según las explicaciones, yo "veo" tu programa así:

http://farm7.static.flickr.com/6097/6285130693_15215dbe9c.jpg

Es cuestión de que todas las ventanas no estén en el lugar de la del menú para que no tengas problemas de que no se vean.
También puedes mover una ventana, por código, si ves que va a solapar a la del menú, así nunca quedaría ninguna detrás.

newtron
27-10-2011, 10:12:57
Es cuestión de que todas las ventanas no estén en el lugar de la del menú para que no tengas problemas de que no se vean.
También puedes mover una ventana, por código, si ves que va a solapar a la del menú, así nunca quedaría ninguna detrás.

¿Con mover te refieres a cambiar la posición X,Y?

Casimiro Notevi
27-10-2011, 10:20:55
¿Con mover te refieres a cambiar la posición X,Y?
Sí, a eso me refiero, que si una ventana solapa o se queda por completo detrás del menú, tú mismo le cambias su posición para que quede fuera.

newtron
27-10-2011, 10:35:04
Bueno, sería una solución. Si no encuentro la forma de hacer lo que comento probaré a ver como quedaría.

Gracias

Ñuño Martínez
27-10-2011, 10:46:41
Mala suerte, esto hace lo mismo que el SendToBack, se lleva el formulario al fondo de todos los programas abiertos.

Seguiré buscando.... :) Leí mal, creo. :o Aun así, ¿ninguno de los parámetros del procedimiento SetWindowPos permite acotar, de alguna forma, que sólo tenga en cuenta las ventanas de la aplicación? No sé, no me he leído la documentation, que estoy vago. :rolleyes:

¿O quizá se pueden obtener las "z" de las ventanas de tu aplicación y asignarles nuevos valores "z" con SetWindowPos? De nuevo hablo por hablar.

newtron
27-10-2011, 10:50:22
Leí mal, creo. :o Aun así, ¿ninguno de los parámetros del procedimiento SetWindowPos permite acotar, de alguna forma

Ya he pensado en eso, tengo que buscar información sobre ese procedimiento.


¿O quizá se pueden obtener las "z" de las ventanas de tu aplicación y asignarles nuevos valores "z" con SetWindowPos? De nuevo hablo por hablar.

Esa es la idea original, y la pregunta del millón es ¿cómo? :D

Casimiro Notevi
27-10-2011, 11:34:16
Esa es la idea original, y la pregunta del millón es ¿cómo? :D

Si te refieres a la posición de cada una para ordenarlas, puede servirte la propiedad 'tag' de cada una, sé que tengo algo hecho de hace muchos años que lo implementaba así, a ver si lo encuentro.

roman
27-10-2011, 18:08:44
si abro un formulario más pequeño que el menú principal y con este abierto pico en el menú de nuevo el formulario abierto más pequeño se esconde detrás de este, espero que "mesentienda"

Es que esto es lo que yo no entiendo. ¿Por qué tienes un formulario más pequeño que el menú? Si es un menú, entonces debería de ser como lo pinta Casimiro, osease como sucede con el mismísimo delphi, que tiene el formulario principal con la barra de componentes hasta arriba del monitor y, aunque sí es posible colocar otro formulario encima, por lo general nunca se estorban, precisamente porque ese menú es chiquito.

Ahora, esa idea se puede mejorar usando las llamadas "Desktop bars" que básicamente son como la barra de tareas del Windows, en el sentido de que al maximizar una ventana, por ejemplo, ésta ocupa sólo el área del monitor restante y no puedes colocarle una ventana encima a menos que sea de pantalla completa.

Estas "desktop bars" las puedes colocar en cualquier orilla del monitor.

// Saludos

roman
27-10-2011, 18:46:23
Aquí te pongo un ejemplo de una "desktop bar" a manera de menú. Si tienes delphi7, puedes ejecutar el ejecutable (valga la rebusznancia) así nada mas. Si no, tendrás que compilar.

Mira a ver si es lo que buscas.

// Saludos

newtron
27-10-2011, 18:48:53
El problema es que mi menú ocupa una gran parte del escritorio, si abro un formulario se queda de esta forma:

[/URL]http://img502.imageshack.us/img502/3412/pantalla1.jpg (http://www.clubdelphi.com/foros/http://img502.imageshack.us/img502/3412/pantalla1.jpg%20%20Uploaded%20with%20) Uploaded with ImageShack.us (http://imageshack.us)

y si estando de esta manera hago click en cualquier parte del menú el formulario se queda detrás de esta manera:

http://img337.imageshack.us/img337/6862/pantalla2x.jpg (http://www.clubdelphi.com/foros/[URL=http://imageshack.us/photo/my-images/337/pantalla2x.jpg/]http://img337.imageshack.us/img337/6862/pantalla2x.jpg%20%20Uploaded%20with%20) Uploaded with ImageShack.us (http://imageshack.us)

que es lo que estoy intentando evitar. :)

Casimiro Notevi
27-10-2011, 19:19:53
Es que eso no es un menú, eso es una ventana a pantalla completa, cualquier cosa que pongas quedará detrás :confused:

newtron
27-10-2011, 19:29:07
Es que eso no es un menú, eso es una ventana a pantalla completa, cualquier cosa que pongas quedará detrás :confused:

Pues por eso quiero que el menú se quede detrás de los formularios.... es duro esto de ser un incomprendido. :p

Amigo roman, lo que me propones serviría perfectamente, el problema es que lo veo demasiado espartano para mi gusto.

Si lo entendéis mejor de esta manera el resultado que quiero es exactamente como si fueran formularios mdi/child pero con formularios normales.

Saludos

roman
27-10-2011, 19:37:36
Ok. Ahí te va una aproximación a lo que quieres:


type
TForm1 = class(TForm)
private
procedure WMMouseActivate(var Message: TWMMouseActivate); message WM_MOUSEACTIVATE;
end;

implementation

procedure TForm1.WMMouseActivate(var Message: TWMMouseActivate);
begin
Message.Result := MA_NOACTIVATE;
end;


// Saludos

José Luis Garcí
27-10-2011, 19:49:13
Newtron, te propongo lo siguiente si donde tienes el menú, ese form lo haces del alto de lo necesario para el menú y el statusbar e inamovible de la posición x,y=0, y luego todas las ventanas las creas normalmente, pero solo evitando, que su posición top, nunca sea inferior a 0+(form del menu.heigh)+1, ten en cuanta que escribo de memoria, de esta manera el menú siempre estará visible, por que las ventanas no podrán superar, el borde inferior del form del menú, claro está este no debe poder ser cambiado de tamaño, cerrado en la x ni movible, aunque si creo que deberías poder minimizar la aplicación y poder restaurarla.

Espero te pueda ser de utilidad.:D:D:D

roman
27-10-2011, 19:56:13
De hecho, eso mismo es lo que le propongo con la "desktop bar", pero él quiere el dibujo azul bonito.

// Saludos

Casimiro Notevi
27-10-2011, 19:57:03
De hecho, eso mismo es lo que le propongo con la "desktop bar", pero él quiere el dibujo azul bonito.
// Saludos

Que lo ponga transparente :D

newtron
27-10-2011, 19:58:41
Gracias José Luis por la idea.

De hecho, eso mismo es lo que le propongo con la "desktop bar", pero él quiere el dibujo azul bonito.


A ver.... si encima que mis programas no funcionan los hago feos ¿qué les quedaría a mis clientes? :D:D

newtron
27-10-2011, 19:59:49
Ok. Ahí te va una aproximación a lo que quieres:

Código Delphi [-] (http://www.clubdelphi.com/foros/#)type TForm1 = class(TForm) private procedure WMMouseActivate(var Message: TWMMouseActivate); message WM_MOUSEACTIVATE; end; implementation procedure TForm1.WMMouseActivate(var Message: TWMMouseActivate); begin Message.Result := MA_NOACTIVATE; end;


// Saludos

... por cierto... ¿y esto qué es lo que hace?

José Luis Garcí
27-10-2011, 20:00:25
Cierto Román, lo que pasa es que no conocia rel termino, ni cai en la cuenta de ello, de todas maneras, lo del fondo bonito que lo ponga en otro form que ocupe el resto de la pantalla, que no se pueda cerrar y que haga lo mismo que el Form del menú, así aunque otros form se abran encima, el menu es independiente, eso pienso yo, por lo menos, pero no me hagais mucho caso.:o:p:rolleyes:

José Luis Garcí
27-10-2011, 20:08:51
Acabo de probar la demo de Román y es aún mejor de lo que yo pensaba, me parece super útil.

newtron
27-10-2011, 20:10:10
Que lo ponga transparente :D

Que sepas que te ríes de mi y me da sentimiendo. :p

... por cierto... ¿y esto qué es lo que hace?

Uh... ya veo... que no le haga caso si picas en el menú.

Tampoco me sirve porque el programa se convertiría en Modal.

Yo quiero poder hacer algo así:

http://img11.imageshack.us/img11/6323/pantall3.jpg (http://imageshack.us/photo/my-images/11/pantall3.jpg/) Uploaded with ImageShack.us (http://imageshack.us)

Casimiro Notevi
27-10-2011, 20:22:20
Yo quiero poder hacer algo así:

http://img11.imageshack.us/img11/6323/pantall3.jpg (http://imageshack.us/photo/my-images/11/pantall3.jpg/)

Vale, y si alguien pincha en la ventana de menú que está detrás, ¿qué quiéres que haga?, es que creo que no tiene sentido lo que quieres, si pinchas en el menú, por fuerza, debe ponerse delante para hacer lo que quieras hacer con el menú, por lo tanto las ventanas que están delante quedarán detrás, es lógico, ¿qué quiéres hacer con esas ventanas? :confused:

roman
27-10-2011, 21:13:20
Uh... ya veo... que no le haga caso si picas en el menú.

Tampoco me sirve porque el programa se convertiría en Modal.


A ver, por eso dije que era una aproximación. Con ese código no inhabilitas por completo el formulario menú, simplemente le impides activarse. Entonces, si para tu menú usas, por ejemplo, SpeedButtons, puedes pinchar uno de ellos y su acción se ejecutará aun cuando el formulario permanezca en el fondo.

Ahora, si no quieres usar botoncitos speedbutton entonces puede hacer como dice JoséLuis. Dejas el menú solito en una "desktop bar" y en otro formulario pones tu dibujo. En este formulario pones el código que te puse.

Claro, creo que ese formulario tiene otros botoncitos pero es que como dice Casimiro, lo que quieres es imposible: quieres que el usuario pinche un botón al cual no tiene acceso porque no quieres que se monte arriba de lo demás.

// Saludos

ecfisa
27-10-2011, 21:54:03
Hola newtron.

Como te dije antes, sigo pensando que la opcion más simple es usar MDI...
Según la imágen de tu form principal (que ahora veo), hay uno o dos botones y algunos items que ignoro si responden a eventos del mouse pero no parece que ninguno de ellos necesiten capturar el foco del teclado.

Si mál no recuerdo tu problema era que los controles ubicados en el área cliente del MDIForm, quedan al frente de la ventana MDIChild abierta (comportamiento normal con MDI y TWinControl).
Entonces, una solución es que en lugar de usar descendientes de TWinControl, guardes esos botones e items como imágenes y utilices para mostrarlos unos TImage. De esa forma no tendras problemas de que solapen al MDIChild ya que al ser descendientes de TGraphicControl no tienen handle de ventana y no interferirán con el normal desempeño MDI.

Un saludo.

Casimiro Notevi
27-10-2011, 22:32:43
Vamos a cambiarle el nombre, ahora será Newtron, El Incomprendido :)

roman
27-10-2011, 22:55:41
Creo que ya dec lo dijo una vez: Lo que quiere hacer no se puede, y, además, es imposible.

// Saludos

Al González
27-10-2011, 23:32:57
No es lo mismo:
[...] que el usuario pinche [...]
que:

...el pinche usuario que...

:D

ecfisa
28-10-2011, 03:09:31
Hola de nuevo mi incompredido amigo... :)

Más o menos esto es de lo que te hablaba en el mensaje anterior:

http://www.imagengratis.org/thumbs/newtronns8qn.jpg (http://www.imagengratis.org/?v=newtronns8qn.jpg)

Culpa tuya ahora todo el mundo se dará cuenta que mi manejo de imágenes (y mi gusto con las mísmas) son pésimos... :mad: :D

Un saludo.

Al González
28-10-2011, 05:20:28
[...] el resultado que quiero es exactamente como si fueran formularios mdi/child pero con formularios normales.

Tal vez me perdí de algo, pero creo que esa frase resume lo que estás buscando.

Mi pregunta es: ¿por qué no le das al formulario principal (el que tiene el menú) el estilo fsMDIForm y a los demás el estilo fsMDIChild? Eso le otorgaría a tu aplicación el comportamiento que, pienso yo, estás necesitando.

Tú quieres que la aplicación trabaje bajo el modelo MDI, pero con formularios "normales". Pues bien, ¿por qué no nos explicas qué inconvenientes habría si los estableces como fsMDIChild? Varias de las desventajas naturales de este esquema, creo yo, podrían ser salvables.

Saludos.

newtron
28-10-2011, 09:20:35
Vamos a cambiarle el nombre, ahora será Newtron, El Incomprendido

Si, estoy pensando en cambiar mi avatar a este:

http://img802.imageshack.us/img802/7531/73180246.jpg (http://imageshack.us/photo/my-images/802/73180246.jpg/)

Hola de nuevo mi incompredido amigo... :)

Más o menos esto es de lo que te hablaba en el mensaje anterior:

http://www.imagengratis.org/thumbs/newtronns8qn.jpg (http://www.imagengratis.org/?v=newtronns8qn.jpg)

Culpa tuya ahora todo el mundo se dará cuenta que mi manejo de imágenes (y mi gusto con las mísmas) son pésimos... :mad: :D

Un saludo.

Pues a mi me mola, tiene un cierto toque galáctico. :)


Tú quieres que la aplicación trabaje bajo el modelo MDI, pero con formularios "normales". Pues bien, ¿por qué no nos explicas qué inconvenientes habría si los estableces como fsMDIChild? Varias de las desventajas naturales de este esquema, creo yo, podrían ser salvables.


El problema es que mis formularios son complejos y me está resultando complicado pasarlos a MDIChild pero creo que para dejar de ser el hazmerreir del foro :D voy a zanjar esto y seguiré trabajando en convertir los formularios a MDIChild, si es posible, porque me estoy encontrando con algún problema duro.

Como siempre gracias a todos por vuestra atención.

ecfisa
28-10-2011, 10:14:24
voy a zanjar esto y seguiré trabajando en convertir los formularios a MDIChild, si es posible, porque me estoy encontrando con algún problema duro.
Entre tantos para aportar ideas, no habrá duro que no se ablande.

Vos andá tirando las dificultades que se te presenten y desde yá, contá con mi ayuda para que las cosas difíciles no te resulten sencillas. :D

Saludos. :)

Casimiro Notevi
28-10-2011, 10:35:57
Si, estoy pensando en cambiar mi avatar a este:

http://img802.imageshack.us/img802/7531/73180246.jpg (http://imageshack.us/photo/my-images/802/73180246.jpg/)

Hombre, pero si es mi amigo Calimero :)

para dejar de ser el hazmerreir del foro :D voy a zanjar esto
Tampoco es eso, es simplemente que no se le ve mucha lógica, según nuestra lógica, que puede diferir de la lógica de los demás, como es lógico.

newtron
28-10-2011, 17:09:49
Entre tantos para aportar ideas, no habrá duro que no se ablande.

Vos andá tirando las dificultades que se te presenten y desde yá, contá con mi ayuda para que las cosas difíciles no te resulten sencillas. :D

Saludos. :)

Gracias amigo. :)


Tampoco es eso, es simplemente que no se le ve mucha lógica, según nuestra lógica, que puede diferir de la lógica de los demás, como es lógico.

Si, totalmente lógico. :p

escafandra
30-10-2011, 22:07:41
Me gustaría aportar mi granito de arena.

Si no entiendo mal, pretendes realizar una aplicación multiformulario que no sea MDI. Entonces Tu formulario principal se pone delante de todos tapándolos cuando se activa, siendo esto lo que quieres evitar. ¿Es así?.

Aunque pienso, coincidiendo con otros, que lo mejor es usar MDI, te propongo este ejemplo de aplicación multiformulario no MDI:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
procedure WndProc(var Message: TMessage); override;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

uses Unit2, Unit3;

{$R *.dfm}

function GetBackForm(Form: TForm): TForm;
var
hWnd: Cardinal;
begin
hWnd:= Form.Handle;
Result:= Form;
repeat
if (FindControl(hWnd) is TForm) then Result:= FindControl(hWnd) as TForm;
hWnd:= GetNextWindow(hWnd, GW_HWNDNEXT);
until hWnd = 0;
end;

// Mostramos o creamos varios formularios
procedure TForm1.Button1Click(Sender: TObject);
begin
Form2.Show;
Form3.Show;
end;

// Interceptamos los mensajes de MainForm
procedure TForm1.WndProc(var Message: TMessage);
begin
case Message.Msg of
WM_MOUSEACTIVATE:
begin
if Lo(Message.lParam) = HTCAPTION then
Message.Result := MA_NOACTIVATEANDEAT
else
Message.Result:= MA_NOACTIVATE;
exit;
end;
WM_WINDOWPOSCHANGED:
begin
// Aseguramos que MainForm esté siempre detrás
SetWindowPos(Handle, GetBackForm(self).Handle, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE);
exit;
end;
end;
inherited WndProc(Message);
end;

end.


Aunque no me termina de convencer del todo, este ejemplo mantiene al formulario principal, siempre detrás del resto de los formularios de la aplicación.


Saludos.

escafandra
31-10-2011, 00:33:55
Perdón :o.

Releyendo el código me he dado cuenta de que deje un gazapo al eliminar partes del código inútil tras realizar pruebas. Como no lo puedo editar, muestro aquí el gazapo y la corrección:

Donde dice:
if not S then inherited WndProc(Message);

Debe decir:
inherited WndProc(Message);

S es una variable que elimine...

Saludos.

Casimiro Notevi
31-10-2011, 00:41:37
Corregido :)

escafandra
31-10-2011, 00:50:25
Corregido :)

Gracias :D


Saludos.

newtron
31-10-2011, 09:32:54
Gracias escafandra. Parece que tú has sido el único con la sensibilidad suficiente para entender mis penas. :D

"Bucearé" en tu código y te cuento.

Gracias de nuevo y un saludo

Casimiro Notevi
31-10-2011, 09:49:18
Gracias escafandra. Parece que tú has sido el único con la sensibilidad suficiente para entender mis penas.
Eso me ha herido, que uno también tiene su corazoncito :(
:D

newtron
31-10-2011, 10:42:22
Amigo escafandra.

El ejemplo que me has propuesto hace más de lo que yo necesitaba, he usado la parte del código que mantiene el formulario principal al fondo de los demás y me sirve a la perfección, era lo que estaba buscando (aunque os parezca raro, bueno, yo es que soy un tío raro :p).

Eso me ha herido, que uno también tiene su corazoncito


No te pongas triste, ven que te dé un chillaito.... ayyyyyyyyyyyyyyyyyyyyyyyyy.... :P

Gracias a todos por vuestra atención y un saludo.

roman
31-10-2011, 19:37:51
A ver, no entiendo. Yo iba por el mismo camino que escafandra (aunque no tan completo)

Ok. Ahí te va una aproximación a lo que quieres:


type
TForm1 = class(TForm)
private
procedure WMMouseActivate(var Message: TWMMouseActivate); message WM_MOUSEACTIVATE;
end;

implementation

procedure TForm1.WMMouseActivate(var Message: TWMMouseActivate);
begin
Message.Result := MA_NOACTIVATE;
end;




y sin embargo, mi opción la descartaste. Probando el código de escafandra noto que tampoco permite seleccionar opciones del menú. ¿Entonces?

Me siento ofendido, ja, ja :D

// Saludos

escafandra
31-10-2011, 20:15:14
...mi opción la descartaste. Probando el código de escafandra noto que tampoco permite seleccionar opciones del menú. ¿Entonces?...


Bueno quizás mi código tiene dos partes. Una muy similar al tuyo y otra con otra filisofía. Newtron se quedó con la segunda:
// Interceptamos los mensajes de MainForm
procedure TForm1.WndProc(var Message: TMessage);
begin
case Message.Msg of
{
WM_MOUSEACTIVATE:
begin
if Lo(Message.lParam) = HTCAPTION then
Message.Result := MA_NOACTIVATEANDEAT
else
Message.Result:= MA_NOACTIVATE;
exit;
end;
}
WM_WINDOWPOSCHANGED:
begin
// Aseguramos que MainForm esté siempre detrás
SetWindowPos(Handle, GetBackForm(self).Handle, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE);
exit;
end;
end;
inherited WndProc(Message);
end;

Esta segunda si permite accionar el menú pero tiene un efecto visual un poco "raro" en PCs mas antiguos. :)


Saludos.

roman
31-10-2011, 20:28:38
¡Ah! Ok. Entonces la parte del MouseActivate sale sobrando ¿no?

¿Cuál es el efecto raro en pcs viejos?

// Saludos

escafandra
01-11-2011, 02:11:46
¡Ah! Ok. Entonces la parte del MouseActivate sale sobrando ¿no?
Bueno, relativamente. Si lo escribimos de la siguiente manera, funcionan los menús:
procedure TForm1.WndProc(var Message: TMessage);
begin
case Message.Msg of
WM_MOUSEACTIVATE:
begin
if Lo(Message.lParam) = HTMENU then
Message.Result:= MA_ACTIVATE
else if Lo(Message.lParam) = HTCAPTION then
Message.Result := MA_NOACTIVATEANDEAT
else
Message.Result:= MA_NOACTIVATE;
exit;
end;
WM_WINDOWPOSCHANGED:
begin
// Aseguramos que MainForm esté siempre detrás
SetWindowPos(Handle, GetBackForm(self).Handle, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE);
exit;
end;
end;
inherited WndProc(Message);
end;


¿Cuál es el efecto raro en pcs viejos?
El efecto es que si el PC es lento se aprecia sutilmente que la ventana principal se activa y luego se va hacia atrás. Se aprecia una aparición rápida y fugaz de los bordes del MainForm si se solapan con ventanas secundarias. Es por eso que incluí WM_MOUSEACTIVATE, con sus efectos secundarios, y el motivo por el que anuncié que no me terminaba de convencer. :)

Saludos.

newtron
01-11-2011, 09:27:23
Bueno quizás mi código tiene dos partes. Una muy similar al tuyo y otra con otra filisofía. Newtron se quedó con la segunda:

Exacto, de esta manera simulo que tengo formularios mdi, puedo seleccionar opciones del menú y las ventanas siguen al frente. Si te estorba alguna ventana porque se quede encima de alguna opción del menú la puedes mover o minimizar.

La razón de no usar mdi es porque yo uso un formulario propio que necesita crearse y asignarle una serie de propiedades antes de hacer el show, con los formularios mdi se ejecuta el show en el momento de crearlos. No sé si esto lo hubiera podido solucionar pero este y otros problemas los vería duros de resolver, era más fácil buscar la solución al tema de los menús.

newtron
02-11-2011, 10:26:47
Amigo escafandra.

Esto se ha quedado estupendamente pero hay un pequeño detalle que rompe mi "paz interior" y es que si tengo un formulario abierto encima del menú y minimizo el menú, al volver a maximizarlo el formulario se queda detrás del menú. ¿Hay forma de arreglar eso?

Gracias y un saludo.

José Luis Garcí
02-11-2011, 15:45:25
Una pregunta newtron, porque no pones una variable, que antes de entrar en el menu, o sea al peder el active un Form, grave el nombre del form, con lo cual al salir de la acción del menu abra el form guardado en la variable, vamos es una idea.

newtron
02-11-2011, 16:57:29
Una pregunta newtron, porque no pones una variable, que antes de entrar en el menu, o sea al peder el active un Form, grave el nombre del form, con lo cual al salir de la acción del menu abra el form guardado en la variable, vamos es una idea.

Bueno, una opción sería recorrer los formularios abiertos y traerlos al frente pero preguntaba al hilo de lo que estabamos tratando si había alguna forma de evitar ese comportamiento variando algo de lo que ya hay.

Gracias y un saludo

escafandra
02-11-2011, 18:16:42
Amigo escafandra.

Esto se ha quedado estupendamente pero hay un pequeño detalle que rompe mi "paz interior" y es que si tengo un formulario abierto encima del menú y minimizo el menú, al volver a maximizarlo el formulario se queda detrás del menú. ¿Hay forma de arreglar eso?

Gracias y un saludo.

Haber si te entiendo. ¿Dices que si tienes un formulario abierto delante del Form Principal (al que tu, perece ser, llamas menú) y minimizas el Form Principal, al restaurarlo éste tapa al Form secundario?

Con el ejemplo que he usado eso no ocurre :confused:, es posible que no te entienda bien o que tengas incluidas cosas en tu código distintas a las mías.

Saludos.

newtron
03-11-2011, 11:33:48
Solucionado.

El problema es que tenía ya redireccionado los mensajes del programa y no podía usar tu código tal cuál entonces puse la instrucción para pasar el formulario principal al fondo en el evento "activate" pero claro, este evento no se dispara al volver al formulario después de minimizarlo, he capturado el evento OnRestore y ahí si que me funciona.

Gracias y un saludo

escafandra
03-11-2011, 13:00:06
Si quieres simplificarte, no trabajes con los eventos VCL, captura el mensaje WM_WINDOWPOSCHANGED con un procedimiento tal que así:

procedure WMWindowPosChanged(var Message: TWMWindowPosChanged); message WM_WINDOWPOSCHANGED;
//.......................

procedure TForm1.WMWindowPosChanged(var Message: TWMWindowPosChanged);
begin
SetWindowPos(Handle, GetBackForm(self).Handle, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE);
end;


Sería el equivalente al código que anteriormente puse, sólo que lo hice en el WndProc(var Message: TMessage); para manejar varios mensajes en un sólo procedimiento.


Saludos.

newtron
03-11-2011, 14:15:37
Estupendo.

Gracias. :)

alsn
10-03-2013, 14:55:55
Hola, ya sé que este hilo es muy antiguo, pero es que un enlace reciente de Newtron me ha llevado hasta aquí.

No sé si entiendo bien lo que Newtron quería, pero ¿No hubiera bastado con dejar el formulario principal (llamado menú) con su propiedad FormStyle en fsNormal y establecer esa propiedad en fsStayOnTop para todos los demás formularios?

Un saludo

ricardopl65
10-03-2013, 15:49:23
Se me ocurre que puedes poner esto en el formulario que tiene el menu


protected
procedure CreateParams(var Params: TCreateParams); override;

procedure TMiForm.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
with Params do
begin
ExStyle := ExStyle or WS_EX_NOACTIVATE;
WndParent := GetDesktopwindow;
end;



De esta manera el formulario nunca gana el foco, es decir no se activa

alsn
10-03-2013, 18:06:58
Hola Ricardo, el código que pones no impide que el formulario principal menú adquiera el foco. Por lo menos en las pruebas que he hecho. De todas formas, lo que creo que buscaba Newtron es que el formulario principal no se colocara por encima de los demás formularios de la aplicación, tapandolos, pero que sí mantuviera su capacidad de uso.

Ya encontraron una solución satisfactoria. Si he resubido el hilo (con más de un año) es porque tenía la impresión de que eso mismo se podía conseguir de una manera más simple.

Un saludo

ricardopl65
10-03-2013, 18:26:02
Pues acabo de volver a probarlo y a mi me funciona.
Prueba este dpr:

alsn
10-03-2013, 19:17:33
Sigue sin funcionarme. Igual es la versión de Delphi. Para poder probarlo, he tenido que quitar en los "uses" todas las referencias: "Winapi." "Vcl." "System." ya que no las reconocía, y eliminar entonces los uses dobles que quedaban.

alsn
12-03-2013, 13:50:50
Hay un truco, que conozco desde mi época de Visual Basic, para crear ventanas flotantes (tipo barras de herramientas de Office), que consistiría en:

const
SWW_hParent = -8;

...

SetWindowLong(FormFlotante.Handle, SWW_hParent, FormPadre.Handle)


Esta forma permite más posibilidades, como crear una jerarquía de ventanas.

Ejemplo:

procedure TForm1.FormShow(Sender: TObject);
const
SWW_hParent = -8;
begin
SetWindowLong(Form2.Handle,SWW_hParent,Form1.Handle);
Form2.Show;

SetWindowLong(Form3.Handle,SWW_hParent,Form2.Handle);
Form3.Show;
end;

Chris
12-03-2013, 16:44:40
Algo más sencillo que puedes usar en las nuevas versiones de Delphi

Establece la propiedad PopupMode del formulario a pmAuto y por último, crea el formulario superior como hijo directo del formulario padre/principal. Por ejemplo:

FormHijo := TFormHijo.Create(FormPadre);

Saludos!

Enlaces:
Propiedad PopupMode (http://docwiki.embarcadero.com/Libraries/XE3/en/Vcl.Forms.TForm.PopupMode).
WS_POPUP (http://msdn.microsoft.com/en-us/library/windows/desktop/ms632600(v=vs.85).aspx) (Para versiones de Delphi que no traen la propiedad PopupMode de TCustomForm.

alsn
12-03-2013, 18:05:26
Sí, es eso mismo. Incluso se puede establecer la propiedad PopupMode por código a posteriori:

FormHijo := TFormHijo.Create(FormPadre);
FormHijo.PopupMode := pmAuto;
FormHijo.Show;

Aunque no se comporta exactamente igual. Me explico, con el siguiente código:

procedure TForm1.Button1Click(Sender: TObject);
begin
Form2 := TForm2.Create(Form1);
Form2.PopupMode := pmAuto;
Form2.Show;

Form3 := TForm3.Create(Form1);
Form3.PopupMode := pmAuto;
Form3.Show;
end;

El Form3 se comporta como si fuese hijo del Form2, no del Form1. Y no entiendo por qué.

Saludos!

Chris
12-03-2013, 18:21:19
Sí, es eso mismo. Incluso se puede establecer la propiedad PopupMode por código a posteriori

Aunque lo puedes hacer, la documentación de Delphi aconseja que lo hagas esclusivamente en tiempo de Diseño.


Aunque no se comporta exactamente igual. Me explico, con el siguiente código:

procedure TForm1.Button1Click(Sender: TObject);
begin
....
end;

El Form3 se comporta como si fuese hijo del Form2, no del Form1. Y no entiendo por qué.

Saludos!

No entiendo realmente que esté pasando. Hace un tiempo hice una aplicación (http://clubdelphi.com/foros/showthread.php?t=75272) usando estas propiedades, pero los formularios no se comportan a cómo mencionas. No recuerdo que configuración en especial estaba utilizando para que no me diera este inconveniente. Habría que probar distintas combinaciones.

Saludos.

PD.: Probá estableciendo la propiedad PopupMode en tiempo de diseño exclusivamente.

alsn
12-03-2013, 18:28:39
También lo había probado así, por si fuera eso.

Saludos!

alsn
12-03-2013, 18:52:00
A ver, si hago lo siguiente:

procedure TForm1.Button1Click(Sender: TObject);
begin
Form2 := TForm2.Create(Form1);
Form2.Show;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
Form3 := TForm3.Create(Form1);
Form3.Show;
end;

Sí se comportan de la manera esperada. Pero, estando en el mismo procedimiento se comportan como he dicho anteriormente.

Saludos

ricardopl65
13-03-2013, 20:36:36
Al menos en XE2 funciona con el ejemplo que te di. Mira este video a ver si se acerca a lo que quieres.
http://www.ricardoplaza.com/download/formdetras.mp4

alsn
14-03-2013, 12:43:54
Efectivamente, es eso Ricardo. En el uso de CreateParams me funcionan, por ejemplo, los códigos de esta página:
http://delphi.about.com/od/formsdialogs/l/aa073101b.htm
Pero con WS_EX_NOACTIVATE no marcha en mi caso.

Un saludo

ricardopl65
14-03-2013, 14:03:15
que sistema operativo tienes? versión de delphi?

alsn
14-03-2013, 14:44:59
Lo he probado en una máquina virtual con Windows XP y Turbo Delphi.
No me dedico a la programación, es más bien una afición. Aunque en alguna ocasión le he sacado provecho.

ricardopl65
14-03-2013, 15:24:06
deberias probar con un windows real y un delphi completo, a ver que tal, seguro ese es el problema

Chris
14-03-2013, 20:55:21
procedure TForm1.Button1Click(Sender: TObject);
begin
Form2 := TForm2.Create(Form1);
Form2.PopupMode := pmAuto;
Form2.Show;

Form3 := TForm3.Create(Form1);
Form3.PopupMode := pmAuto;
Form3.Show;
end;

El Form3 se comporta como si fuese hijo del Form2, no del Form1. Y no entiendo por qué.

Saludos!

Si aún lo quieres hacer así, la siguiente oración que extraigo de una entrada de la ayuda (http://docwiki.embarcadero.com/Libraries/XE3/en/Vcl.Forms.TCustomForm.PopupParent) de Delphi te puede aclarar:
If the PopupMode property is set to pmAuto, Screen.ActiveForm is used as the PopupParent property.

En este caso tendrás que establecer las propiedades PopupMode a pmExplicit y PopupParent a Form1 (en este caso Form1 es el formulario padre).

Saludos!

alsn
15-03-2013, 09:38:57
Así sí se puede elegir el formulario padre de manera precisa.

Muchas gracias!