C# 如何接收插头&;不使用windows窗体播放设备通知
我正在尝试编写一个类库,该类库可以捕获windows消息,以便在设备已连接或删除时通知我。通常,在windows窗体应用程序中,我只会覆盖WndProc方法,但在本例中没有WndProc方法。有没有其他方法可以让我收到这些信息?你需要一个窗口,没有办法。下面是一个示例实现。为DeviceChangeNotifier.DeviceNotify事件实现事件处理程序以获取通知。在程序开始时调用DeviceChangeNotifier.Start()方法。在程序结束时调用DeviceChangeNotifier.Stop()。请注意,DeviceNotify事件是在后台线程上引发的,请确保根据需要锁定,以确保代码线程安全C# 如何接收插头&;不使用windows窗体播放设备通知,c#,overriding,console-application,winforms,wndproc,C#,Overriding,Console Application,Winforms,Wndproc,我正在尝试编写一个类库,该类库可以捕获windows消息,以便在设备已连接或删除时通知我。通常,在windows窗体应用程序中,我只会覆盖WndProc方法,但在本例中没有WndProc方法。有没有其他方法可以让我收到这些信息?你需要一个窗口,没有办法。下面是一个示例实现。为DeviceChangeNotifier.DeviceNotify事件实现事件处理程序以获取通知。在程序开始时调用DeviceChangeNotifier.Start()方法。在程序结束时调用DeviceChangeNoti
using System;
using System.Windows.Forms;
using System.Threading;
class DeviceChangeNotifier : Form {
public delegate void DeviceNotifyDelegate(Message msg);
public static event DeviceNotifyDelegate DeviceNotify;
private static DeviceChangeNotifier mInstance;
public static void Start() {
Thread t = new Thread(runForm);
t.SetApartmentState(ApartmentState.STA);
t.IsBackground = true;
t.Start();
}
public static void Stop() {
if (mInstance == null) throw new InvalidOperationException("Notifier not started");
DeviceNotify = null;
mInstance.Invoke(new MethodInvoker(mInstance.endForm));
}
private static void runForm() {
Application.Run(new DeviceChangeNotifier());
}
private void endForm() {
this.Close();
}
protected override void SetVisibleCore(bool value) {
// Prevent window getting visible
if (mInstance == null) CreateHandle();
mInstance = this;
value = false;
base.SetVisibleCore(value);
}
protected override void WndProc(ref Message m) {
// Trap WM_DEVICECHANGE
if (m.Msg == 0x219) {
DeviceNotifyDelegate handler = DeviceNotify;
if (handler != null) handler(m);
}
base.WndProc(ref m);
}
}
我有一个正在工作的USB通信类,如果有人感兴趣,它以稍微不同的方式实现设备更改通知。它非常紧凑(没有注释),不依赖于客户机中的
线程
或OnSourceInitialized
和HwndHandler
内容。此外,您不需要前面提到的表单
或窗口。可以使用任何可以覆盖WndProc()
的类型。我使用控件
该示例仅包含通知所需的代码,而不包含其他内容。示例代码是C++/CLI,虽然我不赞成将可执行代码放入头文件的做法,但为了简洁起见,我在这里这样做
#pragma一次
#include//声明所需的数据类型。
#包含//WM_设备更改消息所需。
#包含//定义GUID定义所需的内容(见下文)。
命名空间USBComms
{
使用名称空间系统;
使用名称空间System::Runtime::InteropServices;
使用名称空间系统::Windows;
使用命名空间System::Windows::Forms;
//接收WM_设备更改消息时需要此功能。
//注意:名称重新映射为“RegisterDeviceNotificationUM”
[DllImport(“user32.dll”,CharSet=CharSet::Unicode,EntryPoint=“RegisterDeviceNotification”)]
外部“C”HDEVNOTIFY WINAPI注册表设备(
处理诚信问题,
LPVOID通知过滤器,
德沃德旗);
//usb设备的通用guid(参见。http://msdn.microsoft.com/en-us/library/windows/hardware/ff545972%28v=vs.85%29.aspx).
//注意:guid是特定于设备和操作系统的,可能需要修改。使用错误的guid将导致通知失败。
//您可能需要修改设备以找到合适的GUID。“hid.dll”有一个返回的函数“HidD_GetHidGuid”
//“HIDClass设备的设备接口GUID”(请参阅http://msdn.microsoft.com/en-us/library/windows/hardware/ff538924%28v=vs.85%29.aspx).
//但是,测试显示它并不总是返回有用的值
//{A5DCBF10-6530-11D2-901F-00C04FB951ED},曾使用手机、拇指驱动器等。有关更多信息,请参阅例如。
// http://msdn.microsoft.com/en-us/library/windows/hardware/ff553426%28v=vs.85%29.aspx.
定义GUID(GUID设备接口USB设备,0xA5DCBF10L、0x6530、0x11D2、0x90、0x1F、0x00、0xC0、0x4F、0xB9、0x51、0xED);
///
///为通知事件处理程序声明委托。
///
///附加事件处理程序的对象。
///事件数据。
公共委托无效NotificationEventHandler(对象^sender,事件参数^e);
///
///类,该类生成USB设备更改通知事件。
///
///
///表单不是必需的。可以使用任何可以重写WndProc()的类型。
///
public ref类EventNotifier:公共控件
{
私人:
///
///引发NotificationEvent。
///
///事件数据。
作废RaiseNotificationEvent(事件参数^e){
通知事件(本,e);
}
受保护的:
///
///重写基类WndProc方法。
///
///要处理的Windows消息。
///
///此方法接收Windows消息(WM_uxxxxxxxxx)和
///适当地引发我们的通知事件。您应该
///添加任何消息过滤(例如,用于WM_设备更改)和
///在引发事件(或不引发)之前进行预处理。
///
虚拟无效WndProc(消息%Message)覆盖{
如果(message.Msg==WM_DEVICECHANGE)
{
RaiseNotificationEvent(EventArgs::Empty);
}
__super::WndProc(消息);
}
公众:
///
///创建EventNotifier类的新实例。
///
事件通知程序(无效){
RequestNotifications(此->句柄);//注册为Windows消息处理器。
}
///
///为注册由句柄标识的对象
///Windows WM_设备更改消息。
///
///对象的句柄。
bool请求通知(IntPtr句柄){
开发广播设备接口通知过滤器;
零内存(&NotificationFilter,sizeof(NotificationFilter));
NotificationFilter.dbcc_devicetype=DBT_DEVTYP_DEVICEINTERFACE;
NotificationFilter.dbcc_size=sizeof(设备接口);
NotificationFilter.dbcc_reserved=0;
NotificationFilter.dbcc_classguid=GUID\u设备接口\u USB\u设备;
返回RegisterDeviceNotificationUM((句柄)句柄和NotificationFilter,设备\u NOTIFY\u WINDOW\u HANDLE)!=NULL;
}
///
///定义通知事件。
///
虚拟事件NotificationEventHandler^NotificationEvent;
};
}
然后,在“接收者”(订阅并使用我们的NotificationEvent
的对象)中,您所拥有的
public class MsgWindow : Microsoft.WindowsCE.Forms.MessageWindow {
public const int WM_SER = 0x500;
public const int WM_SER_SCANDONE = WM_SER + 0;
frmMain msgform { get; set; }
public MsgWindow(frmMain msgform) {
this.msgform = msgform;
}
protected override void WndProc(ref Microsoft.WindowsCE.Forms.Message m) {
switch (m.Msg) {
case WM_SER_SCANDONE:
this.msgform.RespondToMessage(WM_SER_SCANDONE);
break;
default:
break;
}
base.WndProc(ref m);
}
}
public partial class frmMain : Form {
public frmMain() {
InitializeComponent();
}
public void RespondToMessage(int nMsg) {
try {
switch (nMsg) {
case MsgWindow.WM_SER_SCANDONE:
// do something here based on the message
break;
default:
break;
}
} catch (Exception ex) {
MessageBox.Show(string.Format("{0} - {1}", ex.Message, ex.ToString()), "RespondToMessage() Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
// throw;
}
}
}