Pregunta

Tengo una aplicación Delphi que tiene un navegador de documentos como formulario principal. Cuando el usuario abre un documento, abrimos una ventana de editor. Queremos tener cada editor con un botón en la barra de tareas, así como el formulario principal. He aplicado el código normal para hacer esto (a continuación), pero cuando hago clic en el formulario principal después de usar la ventana del editor, el editor se deja en la parte superior, mientras que el foco está en el formulario principal. No puedo determinar qué está causando este comportamiento.

Configuración de escenario: abro el formulario principal y un formulario de documento.

  1. Haga clic en otra aplicación, haga clic en el formulario principal, el formulario principal permanece enfocado. (Comportándose como se esperaba)

  2. Haga clic en el formulario del documento, haga clic en el formulario principal, el formulario del documento viene de atrás hacia adelante, pero se muestra inactivo. (La imagen muestra el resultado)

texto alternativo http://www.matthew-jones.com/temp_xfer/titlebarfailure .jpg

Primer paso, este es Delphi 2007, y tengo en el proyecto:

Application.MainFormOnTaskBar := True;

Para el formulario principal, no tengo código adicional.

Para el formulario del documento, tengo

procedure TCommonEditForm.CreateParams(var params: TCreateParams);
begin
  inherited;
  params.WndParent := 0; // GetDeskTopWindow; no diff
end;

He intentado averiguar si hay un mensaje que hace que esto suceda, pero no puedo encontrar nada apropiado. He buscado en el código cualquier cosa que tenga que ver con & Quot; activar & Quot ;. ¡Pistas bienvenidas!

¿Fue útil?

Solución

Mi aplicación funciona de la manera que usted describe. Aquí está el enfoque que tomé. Me hubiera gustado encontrar un enfoque más simple pero nunca lo hice.

Comencé leyendo estos artículos. Este primero es un gran artículo escrito por Peter a continuación:

http: // groups -beta.google.com/group/borland.public.delphi.winapi/msg/e9f75ff48ce960eb?hl=es

También se encontró otra información aquí, sin embargo, esto no resultó ser una solución válida: para mi uso:    http://blogs.teamb.com/DeepakShenoy/archive/ 2005/04/26 / 4050.aspx

Finalmente, aquí es con lo que terminé.

Mi pantalla de inicio también funciona como el formulario principal de la aplicación. El formulario principal tiene un vínculo especial con el objeto de aplicación. Usar todos los formularios secundarios me da el comportamiento que estaba buscando.

En cada formulario que quiero en la barra de tareas, anulo CreateParams. Hago esto en mis formularios de edición y lo que los usuarios ven como & Quot; formulario principal & Quot;

procedure TUaarSalesMain.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
  Params.WndParent := GetDesktopWindow;
end;

Mi " Principal " En lo que respecta a Delphi, la forma carga la verdadera forma principal en su función Activitate. Utilizo una variable miembro para realizar un seguimiento de la primera activación. Luego, al final de la función, oculto el formulario de presentación, pero no lo cierro. Esto fue importante para mí porque si el usuario estaba editando un documento y cerraba el formulario principal, no quería que las pantallas de edición se cerraran al mismo tiempo. De esta forma, todos los formularios visibles se tratan de la misma manera.

    if FFirstActivate = false then
      exit;

    FFristActivate := false;

    /* 
       Main Load code here 
       Update Splash label, repaint
       Application.CreateForm
       etc.
    */


    // I can't change visible here but I can change the size of the window
    Self.Height := 0;
    Self.Width := 0;
    Self.Enabled := false;

    //  It is tempting to set Self.Visible := false here but that is not
    // possible because you can't change the Visible status inside this
    // function.  So we need to send a message instead.
    ShowWindow(Self.Handle, SW_HIDE);

  end;

Pero todavía hay un problema. Necesita cerrar la ventana principal / de bienvenida cuando todos los demás formularios están cerrados. Tengo un control adicional en mis rutinas cercanas para Parent & Lt; & Gt; nulo porque utilizo formularios como complementos (mis propósitos funcionan mejor que los marcos).

Realmente no me gustó usar el evento Idle, pero no noto que esto sea un lastre para la CPU.

{
  TApplicationManager.ApplicationEventsIdle
  ---------------------------------------------------------------------------
}
procedure TApplicationManager.ApplicationEventsIdle(Sender: TObject;
  var Done: Boolean);
begin

  if Screen.FormCount < 2 then
    Close;
end;

{
  TApplicationManager.FormCloseQuery
  ---------------------------------------------------------------------------
}
procedure TApplicationManager.FormCloseQuery(Sender: TObject;
  var CanClose: Boolean);
var
  i: integer;
begin

  for i := 0 to Screen.FormCount - 1 do
  begin
    if Screen.Forms[i] <> self then
    begin
      // Forms that have a parent will be cleaned up by that parent so
      // ignore them here and only attempt to close the parent forms
      if Screen.Forms[i].Parent = nil then
      begin
        if Screen.Forms[i].CloseQuery = false then
        begin
          CanClose := false;
          break;
        end;
      end;
    end;
  end;

end;

{
  TApplicationManager.FormClose
  ---------------------------------------------------------------------------
}
procedure TApplicationManager.FormClose(Sender: TObject;
  var Action: TCloseAction);
var
  i: integer;
begin

  for i := Screen.FormCount - 1 downto 0 do
  begin
    if Screen.Forms[i] <> self then
    begin
      // Forms that have a parent will be cleaned up by that parent so
      // ignore them here and only attempt to close the parent forms
      if Screen.Forms[i].Parent = nil then
      begin
        Screen.Forms[i].Close;
      end;
    end;
  end;

end;

Esto me ha servido bien hasta ahora. Realicé un pequeño cambio en Vista porque el ícono de mi & Quot; Main / Splash & Quot; la pantalla todavía se mostraba. Sin embargo, no recuerdo qué fue eso. Probablemente no necesite establecer ancho, alto, habilitado y enviar el mensaje oculto en la pantalla de inicio. Solo quería asegurarme de que no apareciera :-).

Era necesario lidiar con los eventos cercanos. Si recuerdo correctamente, eso era necesario para cuando Windows envió un mensaje de apagado. Creo que solo el formulario principal recibe ese mensaje.

Otros consejos

Lo siento si esto es realmente estúpido, pero no tienes el estilo de formulario establecido en fsStayOnTop, ¿verdad? Esto explicaría este comportamiento.

quizás agregue esto en createparams

Params.ExStyle := Params.ExStyle OR WS_EX_APPWINDOW;

o intente esto en cualquier parte del código. Personalmente lo uso en los formularios. Evento OnCreate.

SetWindowLong(Wnd, GWL_EXSTYLE, 
  GetWindowLong(Wnd, GWL_EXSTYLE) or WS_EX_APPWINDOW) ;

la desventaja de esto es que si el formulario principal se minimiza, los otros formularios también se esconden, pero se restauran cuando el formulario principal lo hace.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top