Files
WPinternals/WinUSBNet/DeviceNotifyHook.cs
T
Gustave Monce a2a1c2302b Code cleanup
2019-12-22 12:25:48 +01:00

167 lines
5.7 KiB
C#

/* WinUSBNet library
* (C) 2010 Thomas Bleeker (www.madwizard.org)
*
* Licensed under the MIT license, see license.txt or:
* http://www.opensource.org/licenses/mit-license.php
*/
using System;
using System.Windows;
using System.Windows.Interop;
namespace MadWizard.WinUSBNet
{
internal class DeviceNotifyHook : IDisposable
{
// http://msdn.microsoft.com/en-us/library/system.windows.forms.nativewindow.aspx
// TODO: disposed exception when disposed
private USBNotifier _notifier;
private Guid _guid;
private IntPtr _notifyHandle;
public DeviceNotifyHook(USBNotifier notifier, Guid guid)
{
// _parent = parent;
_guid = guid;
// _parent.HandleCreated += new EventHandler(this.OnHandleCreated);
// _parent.HandleDestroyed += new EventHandler(this.OnHandleDestroyed);
_notifier = notifier;
IntPtr hWnd = IntPtr.Zero;
if (Application.Current.MainWindow != null)
hWnd = new WindowInteropHelper(Application.Current.MainWindow).Handle;
if (hWnd == IntPtr.Zero) throw new USBException("Main window not loaded yet. Cannot connect with USB yet.");
API.DeviceManagement.RegisterForDeviceNotifications(hWnd, _guid, ref _notifyHandle);
HwndSource source = PresentationSource.FromVisual(Application.Current.MainWindow) as HwndSource;
source.AddHook(WndProc);
}
~DeviceNotifyHook()
{
Dispose(false);
}
/*
// Listen for the control's window creation and then hook into it.
internal void OnHandleCreated(object sender, EventArgs e)
{
try
{
// Window is now created, assign handle to NativeWindow.
IntPtr handle = ((Control)sender).Handle;
AssignHandle(handle);
if (_notifyHandle != IntPtr.Zero)
{
API.DeviceManagement.StopDeviceDeviceNotifications(_notifyHandle);
_notifyHandle = IntPtr.Zero;
}
API.DeviceManagement.RegisterForDeviceNotifications(handle, _guid, ref _notifyHandle);
}
catch (API.APIException ex)
{
throw new USBException("Failed to register new window handle for device notification.", ex);
}
}
internal void OnHandleDestroyed(object sender, EventArgs e)
{
try
{
// Window was destroyed, release hook.
ReleaseHandle();
if (_notifyHandle != null)
{
API.DeviceManagement.StopDeviceDeviceNotifications(_notifyHandle);
_notifyHandle = IntPtr.Zero;
}
}
catch (API.APIException ex)
{
throw new USBException("Failed to unregister destroyed window handle for device notification.", ex);
}
}
protected override void WndProc(ref Message m)
{
// Listen for operating system messages
switch (m.Msg)
{
case API.DeviceManagement.WM_DEVICECHANGE:
_notifier.HandleDeviceChange(m);
break;
}
base.WndProc(ref m);
}
*/
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
// Listen for operating system messages
switch (msg)
{
case API.DeviceManagement.WM_DEVICECHANGE:
return (IntPtr)_notifier.HandleDeviceChange(msg, wParam, lParam);
//break;
}
return IntPtr.Zero;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// clean managed resources
// do not clean the notifier here. the notifier owns and will dispose this object.
}
if (_notifyHandle != IntPtr.Zero)
{
API.DeviceManagement.StopDeviceDeviceNotifications(_notifyHandle);
try
{
/*
if ((Application.Current != null) && (Application.Current.MainWindow != null))
{
HwndSource source = PresentationSource.FromVisual(Application.Current.MainWindow) as HwndSource;
source.RemoveHook(WndProc);
}
*/
Action RemoveHookAction = () =>
{
if (Application.Current.MainWindow != null)
{
HwndSource source = PresentationSource.FromVisual(Application.Current.MainWindow) as HwndSource;
source.RemoveHook(WndProc);
}
};
if (Application.Current != null)
{
if (Application.Current.Dispatcher.Thread.ManagedThreadId == System.Threading.Thread.CurrentThread.ManagedThreadId)
RemoveHookAction();
else
Application.Current.Dispatcher.Invoke(RemoveHookAction);
}
}
catch { }
}
}
}
}