2011-03-21 9 views
6

En Delphi 2009, hago un simple:¿Cómo puedo evitar que FindDialog se mantenga en la cima (Delphi)?

FindDialog.Execute; 

La ventana FindDialog permanece encima de la ventana principal de mi programa como debería.

Sin embargo, si abro otra ventana de otro programa sobre la ventana de mi propio programa, la ventana FindDialog permanece en la parte superior de la otra ventana.

Si pruebo esto con un FindDialog de otro programa (por ejemplo, el Bloc de notas), esto no sucede. Abrir la ventana de otro programa sobre el Bloc de notas y su FindDialog cubrirá tanto el Bloc de notas como las ventanas de FindDialog. Este parece ser el comportamiento correcto y esperado.

¿Esto es algo que estoy haciendo mal o es un problema con la forma en que Delphi implementó FindDialog? ¿Hay algo que pueda hacer para que funcione de la manera del Bloc de notas?


Gracias a todos por los comentarios. El hecho de que no puedas reproducir mi problema ya es una pista de que es otra cosa lo que está causando esto. Esto me ayudará a rastrearlo. Investigaré un poco más y publicaré información adicional aquí cuando descubra algo.


Muy interesante. Mi PrintDialog no se mantiene en la parte superior. Todavía no sé por qué mi FindDialog sí lo hace. Todavía investigando ...


Cambié la llamada a: FindDialog.Execute (Handle); Aún en la cima.


que añade otra FindDialog (esta vez FindDialog1) a mi forma principal y ejecutarlo en el inicio de mi programa. Tiene el mismo comportamiento de permanecer en la cima. Eso al menos indica que no tenía nada que ver con mi FindDialog o las personalizaciones que hice para hacer con él. Entonces debe ser un ajuste en mi forma principal.


Parece que no soy el único que ha encontrado esto. Ver: Resource Tuner: Version History que parece ser una aplicación Delphi, donde en la versión 1.99 dice: "Corrección de errores: la ventana de vista previa del diálogo (búsqueda) se mantuvo en la parte superior cuando se cambia a otra aplicación." Podría intentar contactarlos y ver si pueden recordar cuál fue su solución.


añado algunos nuevos diálogos a mi forma y poner estas llamadas en un solo lugar:

FindDialog1.Execute(); 
PrintDialog1.Execute(); 
ReplaceDialog1.Execute(); 
FontDialog1.Execute(); 

El FindDialog y ReplaceDialog estar al frente de las demás ventanas. PrintDialog y FontDialog no se mantienen en la parte superior y funcionan como deberían.

Entonces, ¿qué hay de diferente entre los dos juegos de diálogos que hacen que los dos primeros lo hagan mal?


Además, este problema ocurre en una versión antigua de mi programa que fue compilado con Delphi 4. chillidos. Ahora veo que este problema no ocurrió en mi versión anterior que usaba Delphi 4.

Y fue un usuario quien informó este problema. Él usa Windows XP, y estoy desarrollando en Vista, por lo que sucede bajo diferentes sistemas operativos.


Confirmación: Sí, creo un nuevo formulario y agrego un FindDialog en él. FindDialog NO tiene el problema. Esto indica que algo en mi programa está causando que FindDialog permanezca en la parte superior. Ahora, tengo que averiguar qué es eso. ¿Alguna idea más? Si alguien me da una respuesta que incluso me da una pista para ayudarme a resolver esto, entonces obtendrán la respuesta aceptada.


Solución: edición de Sertac a su respuesta me dio la solución:

Application.NormalizeTopMosts; 
    FindDialog.Execute(); 
    Application.RestoreTopMosts; 

De este modo impide la FindDialog de ser TopMost cuando la aplicación no es más alta.

... Pero todavía no lo entiendo (la ayuda de Delphi en NormalizeTopMosts) es muy confuso y no indica que deba hacer esto.

Esperemos que este "arreglo" no cause otros problemas.

+4

No se puede reproducir este (D2009 totalmente actualizada). Se utiliza tanto 'FindDialog1.Execute;' y 'FindDialog1.Execute (.),' Lo que debe tanto no producen ningún mango aprobada en Al abrir el cuadro de diálogo Buscar, a continuación, abra alguna otra aplicación (Bloc de notas en mi caso) y pasar por encima de mi La aplicación Delphi con diálogo, tanto su ventana principal como el diálogo de búsqueda están cubiertos por la ventana del Bloc de notas. –

+1

Podría haber entendido mal algo aquí, pero no puedo reproducirlo en Delphi XE. –

+2

FWIW No puedo reproducir este comportamiento en D2010. ¿Estás pasando un HWND al método Execute? Si no, intente pasar el control del formulario principal y vea si eso ayuda. –

Respuesta

3

Al mirar el código VCL, la única forma posible de que un cuadro de diálogo Buscar permanezca en la parte superior es que ya hay una ventana superior cuando se invoca 'Ejecutar'. Así es como está codificado, el diálogo es propiedad de un 'TRedirectorWindow', que pertenece a la ventana superior en orden z en la aplicación. Si esta 'ventana superior' es una ventana superior, entonces el diálogo buscar también lo es.

procedure TForm1.Button1Click(Sender: TObject); 
var 
    f: TForm; 
begin 
    f := TForm.CreateNew(Self); 
    f.FormStyle := fsStayOnTop; 
    f.Show; 
    FindDialog1.Execute; 
end; 

o,

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    FormStyle := fsStayOnTop; 
    FindDialog1.Execute; 
    FormStyle := fsNormal; 
end; 


Las muestras anteriores crearán un diálogo de más arriba encontrar. Pero una forma de mantenerse en la cima posiblemente no pasaría desapercibida, así que supongo que este no sería el origen de su problema.

En cualquier caso, es eso o de alguna manera está cambiando los estilos en el cuadro de diálogo por alguna otra pieza de código.


Por cierto, no te molestes en pasar las diferentes asas a FindDialog1.Execute(), no tendrá ningún efecto, mira mi comentario a tu pregunta.

edición:

¿Qué tal este:

procedure TForm1.Button4Click(Sender: TObject); 
var 
    f: TForm; 
begin 
    f := TForm.CreateNew(Self); 
    f.FormStyle := fsStayOnTop; 
    f.Show; 
    f.Hide; 
    FindDialog1.Execute; 
end; 

El punto es, una ventana no tiene que ser visible para conseguir enumerado por EnumThreadWindows. Por lo tanto, cualquier forma existente de permanecer en la cima podría causar que el diálogo de búsqueda muestre este comportamiento.

Mejor prueba y ver que adivinar. Ejecute la prueba siguiente justo antes de iniciar su cuadro de diálogo Buscar. Esto incorpora la lógica 'dialogs.pas' realiza para encontrar el diálogo una base, y levantaría una excepción si el diálogo fuera el más alto.

function EnumThreadWndProc(hwnd: HWND; var lParam: LPARAM): Bool; stdcall; 
var 
    Window: TWinControl; 
begin 
    Result := True; 
    Window := FindControl(hwnd); 
    if Assigned(Window) and (Window is TForm) then begin 
    Result := False; 
    lParam := Longint(Window); 
    end; 
end; 

procedure TForm1.Button6Click(Sender: TObject); 
var 
    OnTopForm: Longint; 
begin 
    OnTopForm := 0; 
    EnumThreadWindows(GetCurrentThreadId, @EnumThreadWndProc, LPARAM(@OnTopForm)); 
// if (OnTopForm <> 0) and (TForm(OnTopForm).FormStyle = fsStayOnTop) then 
    if (OnTopForm <> 0) and (GetWindowLong(TForm(OnTopForm).Handle, 
          GWL_EXSTYLE) and WS_EX_TOPMOST = WS_EX_TOPMOST) then 
    raise Exception.Create('darn! got one: ' + TForm(OnTopForm).Name); 
end; 


Otra prueba podría ser llamar NormalizeTopMosts de la aplicación antes de iniciar el diálogo, pero sé con algunas versiones de Delphi este método no funciona y no hace su trabajo.

+0

Hmmm. Tengo 3 formularios que son FormStyle: = fsStayOnTop, pero estos son formularios de funciones especiales (como mi cuadro Acerca de) que aún no están abiertos cuando ocurre este problema. Tu respuesta me hace pensar, sin embargo. Gracias. – lkessler

+0

+1 Buen hallazgo :) – jachguate

+0

NormalizeTopMosts parece resolverlo por mí. Ver mi respuesta editada. Gracias Sertac !! – lkessler

Cuestiones relacionadas