次の方法で共有


Forms - Recibir notificaciones cuando hay cambios de sesión

Intermedio

Afortunadamente es muy fácil de hacer si hacemo uso de esta libreria:

Win32 Session Changes Notifier

Que he creado yo mismo y esta disponible en Github.

Lecturas recomendadas

Divide y vencerás!, mi principio favorito. Seguiremos estos tres pasos:

  1. Registrar la ventana para recibir notificaciones
  2. Modificar el comportamiento del WndProc
  3. Des registrar la ventana para dejar de recibir notificaciones

He creado una aplicacion Windows Forms en blanco, tan solo con un ListBox que se irá llenando a medida que lleguen notificaciones de cambios en las sesiones.

Registrar la ventana para recibir notificaciones

Para comenzar recibiendo notificaciones lo primero que debemos hacer es registrar nuestra Ventana (Form) utilizando la API para ello utilizamos la libreria que les he referenciado arriba, simplemente usamos el evento load del form.

 private void Form1_Load(object sender, EventArgs e)
{
    //Registramos la forma para recibir notificaciones
    W32HandleSessionChanges.WTSRegisterSessionNotification(this.Handle, NotifyType.NOTIFY_FOR_ALL_SESSIONS);
}

Con esto nuestra ventana ya comienza a recibir notificaciones de cambios en las sesiones.

Modificar el comportamiento del WndProc

Sino sabes qué es el
WndProc revisa las lecturas recomendadas más arriba.

Aunque ya estamos recibiendo las notificaciones lo cierto es que no estamos haciendo nada con ellas, para interceptarlas y comenzar a hacer algo es necesario hacerle override al WndProc del form y capturar el mensaje de notificación que se envía desde el sistema de ventanas.

Una vez interceptado debemos revisar la propiedad wParam del mensaje ya que esta nos da detalles adicionales acerca del evento que se ha generado.

Para efectos de este ejemplo simplemente convierto ese valor a su equivalente en los enum de la librería, y adiciono esa cadena al listbox para que nos vaya mostrando los mensajes que van llegando.

En este caso paso como parámetro NOTIFYFORALL_SESSIONS para recibir notificaciones de cambios en todas las sesiones no solo en la actual.

 protected override void WndProc(ref Message m)
{
    //Verificamos cuando el mensaje recibido sea el de cambios en la sesión
    if (m.Msg == W32HandleSessionChanges.WM_WTSSESSION_CHANGE)
    {
        //convertimos el valor de wParam a su equivalente en nombre del enum
        var name = Enum.GetName(typeof(SessionNotificationMsg), (SessionNotificationMsg)m.WParam);
        this.listBox1.Items.Add(name);
    }
    base.WndProc(ref m);
}

Des-registrar la ventana para dejar de recibir notificaciones

Esta es la parte más fácil, antes de cerrar la ventana la des registramos:

 private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
    //Des Registramos la forma para no recibir notificaciones
    W32HandleSessionChanges.WTSUnRegisterSessionNotification(this.Handle);
}

El resultado

Ejecutamos el programa, bloquemos nuestra sesión de Windows, volvemos a ingresar y… notificaciones de cambios en la sesión!

Notificaciones de cambios en la sesiónN