Files
DP44/DataPRO/DASFactory/DASFactory.WindowsNotification.cs

209 lines
7.7 KiB
C#
Raw Normal View History

2026-04-17 14:55:32 -04:00
using System;
using System.Collections.Concurrent;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using DTS.Common.USBFramework;
using DTS.Common.Utilities.Logging;
namespace DTS.DASLib.DASFactory
{
internal abstract class WindowsNotification : DeviceHandling
{
protected FileIODeclarations.SECURITY_ATTRIBUTES Security;
protected DeviceManagement MyDeviceManagement;
protected Guid DeviceGuid = Guid.Empty;
/// <summary>
/// Handle of the window which receives messages from Windows. This will be a form.
/// </summary>
protected IntPtr RecipientHandle;
protected IntPtr DeviceNotifyHandle;
protected NotificationForm NotificationWindow;
protected WindowsNotification(DASFactory _factory,
UpdateFinishedEventHandler _SerialUpdateFinished,
Guid _guid,
BlockingCollection<Tuple<QueueActions, DeviceHandling>> queueActionPerDevice
)
: base(_factory, _SerialUpdateFinished, queueActionPerDevice)
{
MyDeviceManagement = new DeviceManagement();
Security = new FileIODeclarations.SECURITY_ATTRIBUTES
{
lpSecurityDescriptor = 0,
bInheritHandle = Convert.ToInt32(true)
};
Security.nLength = Marshal.SizeOf(Security);
DeviceGuid = _guid;
NotificationWindow = new NotificationForm(NotificationWndProc);
NotificationWindow.Show(); // will be hidden immediately
DeviceNotifyHandle = IntPtr.Zero;
RecipientHandle = NotificationWindow.Handle;
if (!MyDeviceManagement.RegisterForDeviceNotifications(RecipientHandle,
DeviceGuid,
ref DeviceNotifyHandle))
{
throw new Exception("DASFactory.WindowsNotification: Unable to register device");
}
}
public override void Dispose()
{
if (DeviceNotifyHandle != IntPtr.Zero)
{
MyDeviceManagement.StopReceivingDeviceNotifications(DeviceNotifyHandle);
}
try
{
/*if (null != NotificationWindow)
{
if (NotificationWindow.InvokeRequired)
{
NotificationWindow.Invoke(new Action(() =>
{
if (NotificationWindow.IsHandleCreated)
{
NotificationWindow.Close();
NotificationWindow.Dispose();
NotificationWindow = null;
}
}));
}
else
{
if (NotificationWindow.IsHandleCreated)
{
NotificationWindow.Close();
NotificationWindow.Dispose();
NotificationWindow = null;
}
}
}*/
/* Cross-thread operation not valid: Control 'NotificationForm' accessed from a thread other than the thread it was created on. */
//NotificationWindow.Close();
}
catch (Exception ex) { APILogger.Log(ex.Message); }
base.Dispose();
}
/// <summary>
/// This gets called whenever anything happens to WinUSB devices
/// </summary>
/// <param name="m">The windows message</param>
protected virtual void NotificationWndProc(ref Message m)
{
//we detect the media arrival event
if (m.Msg != DeviceManagementDeclarations.WM_DEVICECHANGE)
{
return;
}
if (m.WParam.ToInt32() == DeviceManagementDeclarations.DBT_DEVICEARRIVAL)
{
if (Marshal.ReadInt32(m.LParam, 4) == DeviceManagementDeclarations.DBT_DEVTYP_DEVICEINTERFACE)
{
NotificationDeviceArrived(ref m);
}
}
else
{
if (m.WParam.ToInt32() == DeviceManagementDeclarations.DBT_DEVICEREMOVECOMPLETE)
{
if (Marshal.ReadInt32(m.LParam, 4) == DeviceManagementDeclarations.DBT_DEVTYP_DEVICEINTERFACE)
{
NotificationDeviceRemoved(ref m);
}
}
}
}
protected abstract void NotificationDeviceArrived(ref Message m);
protected abstract void NotificationDeviceRemoved(ref Message m);
/// <summary>
/// Hidden Form which we use to receive Windows messages
/// </summary>
internal class NotificationForm : Form
{
public delegate void WinMsgProc(ref Message m);
private Label label1;
private readonly WinMsgProc mDetector;
/// <summary>
/// Set up the hidden form.
/// </summary>
/// <param name="detector">DriveDetector object which will receive notification about USB drives, see WndProc</param>
public NotificationForm(WinMsgProc detector)
{
mDetector = detector;
MinimizeBox = false;
MaximizeBox = false;
ShowInTaskbar = false;
ShowIcon = false;
FormBorderStyle = FormBorderStyle.FixedToolWindow;
Load += Load_Form;
Activated += Form_Activated;
}
private void Load_Form(object sender, EventArgs e)
{
// We don't really need this, just to display the label in designer ...
InitializeComponent();
// Create really small form, invisible anyway.
Size = new Size(5, 5);
}
private void Form_Activated(object sender, EventArgs e)
{
//this.Visible = false;
}
/// <summary>
/// This function receives all the windows messages for this window (form).
/// We call the DASFactory from here so that is can pick up the messages
/// </summary>
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (mDetector != null)
{
mDetector(ref m);
}
}
private void InitializeComponent()
{
label1 = new Label();
SuspendLayout();
//
// label1
//
label1.AutoSize = true;
label1.Location = new Point(13, 30);
label1.Name = "label1";
label1.Size = new Size(314, 13);
label1.TabIndex = 0;
label1.Text = @"This is an invisible form.";
//
// DetectorForm
//
ClientSize = new Size(360, 80);
Controls.Add(label1);
Name = "NotificationForm";
Opacity = 0;
ResumeLayout(false);
PerformLayout();
}
}
}
}