2009-01-18 23 views
9

Estoy intentando alternar la visualización de una ventana pequeña basada en el clic del icono de notificación en una aplicación de bandeja del sistema. Esto es lo suficientemente simple de implementar, sin embargo, cuando se visualiza la ventana pequeña y otra aplicación toma el foco y por lo tanto se mueve delante de ella (orden z), quiero alternar para asumir que la ventana pequeña ahora está oculta, aunque su visibilidad es todavía establecido en visible. De lo contrario, al hacer clic en el ícono se establecería la visibilidad de Windows en oculto aunque ya esté oculto detrás de otro. He intentado capturar/anular los métodos de activación y desactivación para realizar un seguimiento, pero al hacer clic en el icono de notificación siempre se activará primero el evento de desactivación. Tampoco funcionó un enfoque similar utilizando foco/foco perdido ya que la ventana parecía pensar que aún tenía foco, incluso cuando estaba escondido detrás de otra ventana de aplicaciones en uso activo. Al final tuve que recurrir a código nativo y el método WindowFromPoint de la siguiente manera:Cuál es la mejor manera de determinar si una ventana es realmente visible en WPF

using System.Windows.Interop; 
using System.Runtime.InteropServices; 
using System.Drawing; 

[DllImport("user32.dll")] 
public static extern IntPtr WindowFromPoint(Point lpPoint); 

public static bool IsWindowVisible(System.Windows.Window window) { 
    WindowInteropHelper win = new WindowInteropHelper(window); 
    int x = (int)(window.Left + (window.Width/2)); 
    int y = (int)(window.Top + (window.Height/2)); 
    Point p = new Point(x, y); 
    return (win.Handle == WindowFromPoint(p)); 
} 

Esto comprueba si la ventana volvió a las coordenadas del centro de la ventana en los partidos de interrogación dicha ventana. es decir, el centro de la ventana en cuestión es visible.

Esto parece un poco hacky, ¿hay alguna manera más agradable de lograr el mismo resultado?

+0

+1 para una pregunta muy interesante. No pude encontrar una mejor manera, así que usé tu enfoque :-) – Joon

+1

1. Estoy con Joon. Buena solución. 2. Es posible que desee consultar más que solo el centro (por ejemplo, esquinas de ventanas). 3. Cuidado al no usar 'System.Windows.Point' u obtienes alguna fea excepción –

Respuesta

2

Puede que no desee confiar en si una ventana está obstruida, ya que hay muchos factores que pueden cambiar el tamaño de la ventana, la posición, etc. y todos ellos se relacionan con características de accesibilidad que agregan aún más complejidades.

En su lugar, es posible que desee comprobar si la ventana tiene o no el foco. Así es como MSN Messenger sabe si flashear o no naranja en la barra de tareas; dispara una notificación y si no tiene foco, la barra de tareas parpadea.

+0

Descubrí que cuando verifiqué la propiedad focus de la ventana, volvería a mostrar que tenía foco a pesar de que estaba detrás de otra ventana. Luego probé los eventos de activación y desactivación, que funcionaron, pero se desactivaron al disparar cuando hice clic en el ícono de la bandeja del conmutador, aunque la ventana estaba visible – LaserJesus

Cuestiones relacionadas