C# – Recibir notificaciones cuando hayan cambios de sesión parte 3 – WPF
June 2nd, 2011 by JuanK
ArtÃculos de este tema:
- C# – Recibir notificaciones cuando hayan cambios de sesión parte 1
- C# – Recibir notificaciones cuando hayan cambios de sesión parte 2 – Windows Forms
- C# – Recibir notificaciones cuando hayan cambios de sesión parte 3 – WPF
*Realmente son 6 articulos si contamos los mini post a los que se hace referencia
En artÃculos anteriores enseñe como crear una librerÃa para interceptar las notificaciones generadas en el sistema cuando se hacen cambios de sesión y como utilizar esa librerÃa en Windows Forms. En este artÃculo enseñare como hacer uso de ese componente en una aplicación para Windows Presentation Foundation – WPF.
LETS CODE!
Para Windows forms esta tarea es bastante sencilla e intuitiva, pero este no es el caso de WPF dadas las propias caracterÃsticas de esta tecnologÃa.
He creado una aplicacion WPF sencilla con un ListBox que se irá llenando a medida que lleguen notificaciones de cambios en las sesiones.
Para comenzar recibiendo notificaciones lo primero que se supone debemos hacer es registrar nuestra Ventana ya que eso dice en la documentación de msdn:
WTSRegisterSessionNotificationSession change notifications are sent in the form of a WM_WTSSESSION_CHANGE message. These notifications are sent only to the windows that have registered for them using this function.
Para el caso de WPF esto no es necesario ya que al parecer PresentationCore ya lo hace por nosotros.
Ya que por defecto ya estamos recibiendo las notificaciones de cambios en las sesiones, lo que debemos hacer es interceptar estos mensajes en el WndProc de manera muy similar a como lo hicimos con Windows Forms en el artÃculo anterior. Fácil, solo que… una ventana de WPF no expone el WndProc pequeño problema.
En resumen lo que debemos tener en cuenta para poder interceptar los mensajes desde WPF es:
- Obtener el manejador de la ventana, ya que lo necesitamos para el siguiente punto , y de paso también por default es inaccesible para WPF.
- Crear un Hook para el WndProc nativo, el cual es por default inaccesible desde WPF
- (No)Registrar la ventana para recibir notificaciones
- Modificar el comportamiento del WndProc
Obtener el manejador de la ventana
Como ya lo comente necesitamos el manejador para posteriormente crear un Hook al WndProc, en este mini artÃculo explico C# – Como obtener un manejador (handle) para una ventana de WPF , pero en resumen el código esta acá:
WindowInteropHelper interopHelper; private void Window_Loaded(object sender, RoutedEventArgs e) { //Conseguir el Handle de la ventana interopHelper = new WindowInteropHelper(this); }Crear un Hook para el nativo
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 usar el WndProc de la ventana WPF y capturar el mensaje de notificación que se envÃa desde el sistema de ventanas.
Como ya lo escribà arriba, el WndProc no esta disponible para una ventana WCF, para utilizarlo debemos obtener el manejador de la ventana, cosa que ya hicimos y crear un Hook al WndProc, en este artÃculo explico C# – Como usar el WndProc en una Ventana WPF , pero en resumen el código esta acá:
WindowInteropHelper interopHelper; private void Window_Loaded(object sender, RoutedEventArgs e) { //Conseguir el Handle de la ventana interopHelper = new WindowInteropHelper(this); //Crear un hook al WndProc HwndSource sourceWindow = HwndSource.FromHwnd(interopHelper.Handle); sourceWindow.AddHook(WndProc); }Donde el parámetro WndProc es realmente un delegado a un método llamado intencionalmente asÃ, como lo veremos más adelante.
Una vez creado el hook, debemos interceptar los mensajes del WndProc, revisamos la variable 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 creada en el articulo previo, y adiciono esa cadena al listbox para que básicamente nos vaya mostrando los mensajes que van llegando.
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { if (msg == W32HandleSessionChanges.WM_WTSSESSION_CHANGE) { var name = Enum.GetName(typeof(SessionNotificationMsg), (SessionNotificationMsg)wParam); this.listBoxOne.Items.Add(name); handled = true; return (IntPtr)1; } return IntPtr.Zero; }NOTA IMPORTANTE
WPF por defecto nos permite recibir notificaciones de la sesión actual, si queremos recibir notificaciones de todas las sesiones debemos des registrar la ventana y luego registrarla nuevamente con el parámetro NOTIFY_FOR_ALL_SESSIONS, asÃ:
//Conseguir el Handle de la ventana interopHelper = new WindowInteropHelper(this); //Des Registramos W32HandleSessionChanges.WTSUnRegisterSessionNotification(interopHelper.Handle); //Registramos la forma para recibir notificaciones W32HandleSessionChanges.WTSRegisterSessionNotification(interopHelper.Handle, NotifyType.NOTIFY_FOR_ALL_SESSIONS);El resultado
Ejecutamos el programa
Bloquemos nuestra sesión de Windows, volvemos a ingresar y…
Perfecto!!
eso fue todo.
- 2 Comentarios »
- Publicado en la categoría 'C#, Windows'



Wordpress
2 comentarios to “C# – Recibir notificaciones cuando hayan cambios de sesión parte 3 – WPF ”
June 3rd, 2011 at 12:37 am
[...] C# – Recibir notificaciones cuando hayan cambios de sesión parte 3 – WPF *Realmente son 6 articulos si contamos los mini post a los que se hace referencia [...]
June 10th, 2011 at 12:10 pm
[...] C# – Recibir notificaciones cuando hayan cambios de sesión parte 3 – WPF *Realmente son 6 articulos si contamos los mini post a los que se hace referencia [...]