发布:2024/5/5 21:12:23作者:管理员 来源:本站 浏览次数:417
C# Winform中WndProc 函数作用:
主要用在拦截并处理系统消息和自定义消息
比如:
windows程序会产生很多消息,比如你单击鼠标,移动窗口都会产生消息。这个函数就是默认的消息处理函数。你可以重载这个函数来制定自己的消息处理流程.
在Winform程序中,可以重写WndProc函数,来捕捉所有发生的窗口消息。
这样,我们就可以"篡改"传入的消息,而人为的让窗口改变行为。
我们用C#实现检测U盘插拔的功能,是用重写C# WndProc函数来做到的。
参考 https://www.cnblogs.com/peterYong/p/16208125.html
简单测试代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO; //添加IO命名空间
namespace CheckUdisk
{
public partial class Form1 : Form
{
//定义常量
public const int WM_DEVICECHANGE = 0x219;
public const int DBT_DEVICEARRIVAL = 0x8000;
public const int DBT_CONFIGCHANGECANCELED = 0x0019;
public const int DBT_CONFIGCHANGED = 0x0018;
public const int DBT_CUSTOMEVENT = 0x8006;
public const int DBT_DEVICEQUERYREMOVE = 0x8001;
public const int DBT_DEVICEQUERYREMOVEFAILED = 0x8002;
public const int DBT_DEVICEREMOVECOMPLETE = 0x8004;
public const int DBT_DEVICEREMOVEPENDING = 0x8003;
public const int DBT_DEVICETYPESPECIFIC = 0x8005;
public const int DBT_DEVNODES_CHANGED = 0x0007;
public const int DBT_QUERYCHANGECONFIG = 0x0017;
public const int DBT_USERDEFINED = 0xFFFF;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
protected override void WndProc(ref Message m)
{
try
{
if (m.Msg == WM_DEVICECHANGE)
{
switch (m.WParam.ToInt32())
{
case WM_DEVICECHANGE:
break;
case DBT_DEVICEARRIVAL:
DriveInfo[] s = DriveInfo.GetDrives();
foreach (DriveInfo drive in s)
{
if (drive.DriveType == DriveType.Removable)
{
this.richTextBox1.AppendText("U盘已插入,盘符是" + drive.Name.ToString() + "\r\n");
break;
}
}
break;
case DBT_CONFIGCHANGECANCELED:
MessageBox.Show("2");
break;
case DBT_CONFIGCHANGED:
MessageBox.Show("3");
break;
case DBT_CUSTOMEVENT:
MessageBox.Show("4");
break;
case DBT_DEVICEQUERYREMOVE:
MessageBox.Show("5");
break;
case DBT_DEVICEQUERYREMOVEFAILED:
MessageBox.Show("6");
break;
case DBT_DEVICEREMOVECOMPLETE:
this.richTextBox1.AppendText("U盘已卸载");
break;
case DBT_DEVICEREMOVEPENDING:
MessageBox.Show("7");
break;
case DBT_DEVICETYPESPECIFIC:
MessageBox.Show("8");
break;
case DBT_DEVNODES_CHANGED:
MessageBox.Show("9");
break;
case DBT_QUERYCHANGECONFIG:
MessageBox.Show("10");
break;
case DBT_USERDEFINED:
MessageBox.Show("11");
break;
default:
break;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
base.WndProc(ref m);
}
private void ScanDisk()
{
DriveInfo[] drives = DriveInfo.GetDrives();
foreach (var drive in drives)
{
// 可移动存储设备,且不是A盘
if ((drive.DriveType == DriveType.Removable) && false == drive.Name.Substring(0, 1).Equals("A"))
{
Console.WriteLine("找到一个U盘:" + drive.Name);
}
}
}
}
}
WindowsAPI示例-C#版_监控usb设备插拔
1、Winform代码:
public partial class USBDeviceMode : Form
{
public USBDeviceMode()
{
InitializeComponent();
UsbNotification.RegisterUsbDeviceNotification(this.Handle);
}
private void RFIDReaderMode_Load(object sender, EventArgs e)
{
}
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == (int)HandleNotification_MessageMsg.DBT_DEVTYP_DEVICEINTERFACE_Msg)
{
switch ((int)m.WParam)
{
case (int)HandleNotification_MessageWParam.DBT_DEVTYP_Removecomplete:
textBox1.AppendText(@"
检测到有设备拔出");
break;
case (int)HandleNotification_MessageWParam.DBT_DEVTYP_Arrival:
textBox1.AppendText(@"
检测到有设备插入");
break;
}
}
}
}
2、UsbNotification类:
using System;
using System.Runtime.InteropServices;
using static ZhiBiXiaobai.WindowAPIHelper.WindowsAPI_DeviceManagement;
namespace WinFormsApp1
{
/// <summary>
/// 监听USB设备插拔
/// </summary>
public class UsbNotification
{
#region 常量
private static readonly Guid GuidDevinterfaceUSBDevice = new("A5DCBF10-6530-11D2-901F-00C04FB951ED"); // 用作USB设备标签
#endregion 常量
private static IntPtr notificationHandle; // 通知句柄(这里给窗口句柄)
/// <summary>
/// 指定(注册)一个窗口,以便在USB设备插入或拔出时接收通知。
/// </summary>
/// <param name="windowHandle">接收通知的窗口句柄。</param>
public static void RegisterUsbDeviceNotification(IntPtr windowHandle)
{
DEV_BROADCAST_DEVICEINTERFACE dbi = new() // 存储设备信息的对象
{
dbch_devicetype = DEV_BROADCAST_DEVICEINTERFACE_Devicetype.DBT_DEVTYP_DEVICEINTERFACE, // 通知类别为“设备的类”
dbch_reserved = 0, // 保留不使用
dbch_classguid = GuidDevinterfaceUSBDevice,
dbch_name = '0'
};
dbi.dbch_size = Marshal.SizeOf(dbi); // 从进程的非托管内存中给DevBroadcastDeviceinterface分配内存
//IntPtr buffer = Marshal.AllocHGlobal(dbi.dbch_size); // 从进程的非托管内存中给DevBroadcastDeviceinterface分配内存
//Marshal.StructureToPtr(dbi, buffer, true); // 将数据从托管对象封送到非托管内存块(dbi->buffer,删除旧的数据)
notificationHandle = RegisterDeviceNotification(windowHandle, dbi, 0);
}
/// <summary>
/// 注销USB设备通知窗口
/// </summary>
public static void UnregisterUsbDeviceNotification()
{
UnregisterDeviceNotification(notificationHandle);
}
}
}
3、WindowsAPI类:
WindowsAPI-C#版_设备管理常用API
4、HandleNotification_MessageMsg与HandleNotification_MessageWParam:
WindowsAPI-C#版_句柄回调常用通知类型汇总(HandleNotification)
5、补充-WPF写法:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
if (source != null)
{
IntPtr windowHandle = source.Handle;
source.AddHook(HwndHandler); // 添加方法
UsbNotification.RegisterUsbDeviceNotification(windowHandle);
}
}
/// <summary>
/// 钩子执行的方法
/// </summary>
private IntPtr HwndHandler(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == (int)HandleNotification_MessageMsg.DBT_DEVTYP_DEVICEINTERFACE_Msg)
{
switch ((int)wParam)
{
case (int)HandleNotification_MessageWParam.DBT_DEVTYP_Removecomplete:
lblT1.Content+=(@"
检测到有设备拔出");
break;
case (int)HandleNotification_MessageWParam.DBT_DEVTYP_Arrival:
lblT1.Content += (@"
检测到有设备插入");
break;
}
}
handled = false;
return IntPtr.Zero;
}
}
参考 https://www.cnblogs.com/qq2806933146xiaobai/p/16899198.html
© Copyright 2014 - 2024 柏港建站平台 ejk5.com. 渝ICP备16000791号-4