Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Orden formularios (https://www.clubdelphi.com/foros/showthread.php?t=76372)

Casimiro Notevi 31-10-2011 00:41:37

Corregido :)

escafandra 31-10-2011 00:50:25

Cita:

Empezado por Casimiro Notevi (Mensaje 417120)
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

Cita:

Empezado por newtron (Mensaje 417139)
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).

Cita:

Empezado por Casimiro Notevi (Mensaje 417142)
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)

Cita:

Empezado por roman (Mensaje 416932)
Ok. Ahí te va una aproximación a lo que quieres:

Código Delphi [-]
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

Cita:

Empezado por roman (Mensaje 417207)
...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:
Código Delphi [-]
// 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

Cita:

Empezado por roman (Mensaje 417213)
¡Ah! Ok. Entonces la parte del MouseActivate sale sobrando ¿no?

Bueno, relativamente. Si lo escribimos de la siguiente manera, funcionan los menús:
Código Delphi [-]
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;

Cita:

Empezado por roman (Mensaje 417213)
¿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

Cita:

Empezado por escafandra (Mensaje 417211)
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

Cita:

Empezado por José Luis Garcí (Mensaje 417385)
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

Cita:

Empezado por newtron (Mensaje 417354)
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í:

Código Delphi [-]
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

Intenta esto
 
Se me ocurre que puedes poner esto en el formulario que tiene el menu


Código Delphi [-]
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


La franja horaria es GMT +2. Ahora son las 21:16:58.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi