2009-03-31 43 views
19

Tengo dificultades para mostrar un segundo formulario sobre el formulario principal sin perder el foco.Delphi: Mostrar ventana sin activación

He intentado ShowWindow(second.handle, SW_SHOWNOACTIVATE), pero la forma principal pierde el foco. Si fijo Visible := false en la segunda ventana, la llamada a ShowWindow no activar la segunda forma, pero las ventanas está vacío cuando se muestra ...

¿Alguien tiene una buena receta para esto?

ACTUALIZACIÓN: Lo que intento hacer es mostrar una ventana de notificación en un evento determinado. Es crucial que la forma principal no pierda enfoque en ningún momento.

+0

Hum ... Una de mis ediciones se ha ido ... ¿Supongo que TENÍA algunos problemas antes ...? – Vegar

Respuesta

24

Tiene que haber algún problema con su código.

He probado este código, funciona:

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    ShowWindow(Form2.Handle, SW_SHOWNOACTIVATE); 
    Form2.Visible := True; 
end; 

tener cuidado de usar Visible, no Show! De lo contrario, prevalecerá el SW_SHOWNOACTIVATE.

+0

Lo siento, pero todavía está activado :-( – Vegar

+0

Modifiqué mi respuesta y lo probé :) –

+0

Guau, es increíble :-) Los trucos parecen ser para que sea visible sea falso en designtime, y establecerlo en true después la llamada a showwindow(). ¡Gracias! – Vegar

2

Puede mostrar la ventana (no modal) y restablecer el enfoque a la ventana principal.

procedure TMainForm.ButtonClick(Sender: TObject); 
begin 
    OtherForm.Show; 
    SetFocus; 
end; 

probado en 2006.

Esto no muestra la otra forma en la parte superior. Pero es muy contrario a la intuición tener una ventana en la parte superior que no tenga el foco.

+0

Pero esto sería suficiente para desencadenar eventos y almacenamiento de datos, etc., y no quiero que ... – Vegar

+0

esto no funcione en diversas circunstancias, por ejemplo, si está trabajando (digamos editar texto) en una forma secundaria del formulario principal y el formulario principal necesita mostrar una notificación. Pierdes los caracteres que estás escribiendo y además, al volver a enfocar el formulario principal, no vuelvo a centrarlo en el formulario original en el que editabas. Este problema me persiguió durante mucho tiempo hasta que encontré que DR era simple (Debería haber pensado en eso) arreglarlo. – DeveloperChris

1

que he utilizado en el pasado

SetWindowPos(WindowHandle, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE or SWP_NOSIZE or SWP_NOMOVE); 

no he probado esto con las últimas versiones de Delphi, aunque ...

1

Si es posible, debe considerarse el uso de algún tipo de información sobre herramientas ventana para mostrar la información de notificación. Una sugerencia de herramienta no robará el enfoque de su ventana principal cuando se muestre o cuando un usuario haga clic en ella. Una forma regular tendrá un borde por defecto y si el usuario hace clic en ese borde, su forma principal perderá el foco.

Aquí hay algunos códigos básicos para hacer esto. La punta desaparece cuando se llama gratis; Sin embargo, sería mejor configurar un temporizador que usar el modo de suspensión.

with THintWindow.Create(nil) do 
    try 
    ActivateHint(MyRect, 'My Notification'); 
    Sleep(DisplayTime); 
    finally 
    Free; 
    end 
+0

Quizás esta es la forma más fácil de hacerlo, pero tendría que personalizar la ventana de entrada para mostrar algo más que texto simple ... – Vegar

1

Aquí son:

// you have set your 2nd form as non resizable, without border nor title etc... 
    Form2.Enabled := False; // prevent the 2nd form to grab focus even when clicked 
    SetWindowPos(Form2.Handle, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW or SWP_NOACTIVATE or SWP_NOSIZE or SWP_NOMOVE); 
    // be sure to hide it automatically when done as it is disabled... 
+0

Esto lo hace realmente visible sin configurar el formulario visible? –

1

Hice esto en el pasado, pero no tengo el código, ya que era propietaria en el último empleo (lo siento).

Si recuerdo bien, lo que hice fue:

  1. De clase de cliente una llamada a un procedimiento (o función) que no pertenece a ninguna clase (un método tradicional Pascal).
  2. De ese método, llame a algún método en una clase B que no hereda de TForm
  3. Del método en B, cree una instancia del formulario emergente P, pero sin padre o propietario; y llama a un método en la instancia.
  4. Desde el método llamado en la instancia, muéstrate.

El código (de la etapa 3) podría ser algo como esto:

var p: TPopupForm; 
begin 
    p := TPopupForm.Create(nil); 
    p.ShowWindow; 
    p.Release; 
end; 

Lo siento si esto no funciona, no tengo Delphi también.

0

código Daniels trabaja hasta ...

ShowWindow(Form2.Handle, SW_SHOWNOACTIVATE); 
Form2.Visible := True; 

Hasta que su segunda forma se crea de forma dinámica . Entonces su segunda forma se ubica en la posición 0,0 con ancho y alto predeterminados.

Por un breve momento cuando se ejecuta ShowWindow verá el segundo formulario en la pantalla, desapareciendo cuando se ejecuta la siguiente línea.

Estoy utilizando el código para un formulario de superposición transparente que se crea dinámicamente. El siguiente código es una combinación de las respuestas dadas y coloca el segundo formulario sin activación sobre el formulario principal.

SetWindowPos(Form2.Handle, HWND_TOP, Left, Top, Width, Height, SWP_NOACTIVATE); 
Form2.Visible := True; 
Cuestiones relacionadas