Wpf e la message pump
Quindi?
E’ un po’ contorto ma alla fine con una manciata di righe di codice ci si arriva:
definiamo quello che vogliamo ottenere: un semplice observer.Public Interface IHardwareMonitor Event DeviceAttached As EventHandler Event DeviceRemoved As EventHandler End Interface
The Trick
A questo punto lo possiamo implementare, ad esempio, in questo modo:
Il giochetto di fondo è quello di risuscire a ricavare l’handle di una finestra, top level, che in Wpf non serve:Public NotInheritable Class WpfHardwareMonitor Implements IHardwareMonitor Public Event DeviceAttached(ByVal sender As Object, ByVal e As System.EventArgs) Implements Plc.IHardwareMonitor.DeviceAttached Private Sub OnDeviceAttached() RaiseEvent DeviceAttached(Me, EventArgs.Empty) End Sub Public Event DeviceRemoved(ByVal sender As Object, ByVal e As System.EventArgs) Implements Plc.IHardwareMonitor.DeviceRemoved Private Sub OnDeviceRemoved() RaiseEvent DeviceRemoved(Me, EventArgs.Empty) End Sub Dim source As HwndSource Public Sub New() AddHandler Application.Current.Exit, AddressOf OnAppExit AddHandler Application.Current.MainWindow.Loaded, AddressOf OnLoaded End Sub Sub OnAppExit(ByVal sender As Object, ByVal e As ExitEventArgs) source.RemoveHook(New HwndSourceHook(AddressOf WndProc)) RemoveHandler Application.Current.Exit, AddressOf OnAppExit End Sub Sub OnLoaded(ByVal sender As Object, ByVal e As RoutedEventArgs) source = HwndSource.FromHwnd(New WindowInteropHelper(Application.Current.MainWindow).Handle) source.AddHook(New HwndSourceHook(AddressOf WndProc)) RemoveHandler Application.Current.MainWindow.Loaded, AddressOf OnLoaded End Sub Const WM_DEVICECHANGE As Integer = &H219 Const DBT_DEVICEARRIVAL As Integer = &H8000 Const DBT_DEVICEREMOVECOMPLETE As Integer = &H8004 Function WndProc(ByVal hwnd As IntPtr, ByVal msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr, ByRef handled As Boolean) As IntPtr If msg = WM_DEVICECHANGE Then If wParam.ToInt32() = DBT_DEVICEARRIVAL Then Me.OnDeviceAttached() ElseIf wParam.ToInt32() = DBT_DEVICEREMOVECOMPLETE Then Me.OnDeviceRemoved() End If End If End Function End Class
Il resto è normale codice per la gestione dei messaggi.source = HwndSource.FromHwnd(New WindowInteropHelper(Application.Current.MainWindow).Handle) source.AddHook(New HwndSourceHook(AddressOf WndProc))
ndr.m
E’ VB.Net :-), mamma mia che fatica! non so se è perchè lo uso veramente di rado ma lo trovo decisamente ostico, decisamente. E’ evidente che dal punto di vista delle potenzialità non c’è differenza ma alcune cose mi laciano molto perplesso, molto.