U盘加载,卸载,拔出,插入,WM_DEVICECHANGE,WndProc,DBT_DEVICEARRIVAL,DBT_DEVICEREMOVECOMPLETE
2008-08-22 14:42 by virus, 4161 visits, 网摘, 收藏, 编辑最近在做一个和U盘有关的项目,有一个需求是要求显示插入的U盘的盘符,当然了,如果拔出U盘,也应该更新显示,就是显示U口上插入的全部移动设备的全部盘符。
其实就是重写
protected override void WndProc(ref Message m)
方法,根据得到的系统消息来处理,但是如果要实时更新的话,最好加上定时查询U口设备,将查询结果更新,时间的间隔可以自己定义,根据项目情况吧。
下面是完整的代码,如果大家有什么好的建议,欢迎大家一起交流。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Threading;
namespace WindowsApp
{
public partial class ComboBoxForm2 : Form
{
private IList<string> diskList = new List<string>();
delegate void SetTextCallback(string s);
delegate void ClearListBoxItem();
private Thread thread = null;
private BackgroundWorker backgroundworker;
public ComboBoxForm2()
{
InitializeComponent();
}
protected override void WndProc(ref Message m)
{
object ojb = new object();
try
{
//WM_DEVICECHANGE,系统硬件改变发出的系统消息
if (m.Msg == WndProMsgConst.WM_DEVICECHANGE)
{
switch (m.WParam.ToInt32())
{
case WndProMsgConst.WM_DEVICECHANGE:
break;
//DBT_DEVICEARRIVAL,设备检测结束,并且可以使用
case WndProMsgConst.DBT_DEVICEARRIVAL:
scanUDisk();
listBox1.Items.Clear();
foreach (string s in diskList)
{
listBox1.Items.Add(s);
}
break;
//DBT_DEVICEREMOVECOMPLETE,设备卸载或者拔出
case WndProMsgConst.DBT_DEVICEREMOVECOMPLETE:
scanUDisk();
listBox1.Items.Clear();
foreach (string s in diskList)
{
listBox1.Items.Add(s);
}
break;
}
}
}
catch (Exception ex)
{
MessageBox.Show("当前盘不能正确识别,请重新尝试!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
base.WndProc(ref m);
}
private void button1_Click(object sender, EventArgs e)
{
IList<string> diskList = new List<string>();
diskList.Add("k001");
diskList.Add("k002");
diskList.Add("k003");
diskList.Add("k004");
comboBox1.DataSource = diskList;
}
/// <summary>
/// 扫描U口设备
/// </summary>
/// <param name="obj"></param>
private void scanUDisk()
{
diskList.Clear();
DriveInfo[] drives = DriveInfo.GetDrives();
foreach (DriveInfo drive in drives)
{
if ((drive.DriveType == DriveType.Removable) && !drive.Name.Substring(0, 1).Equals("A"))
{
try
{
diskList.Add(drive.Name);
}
catch
{
MessageBox.Show("当前盘不能正确识别,请重新尝试!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
}
private void ComboBoxForm2_Load(object sender, EventArgs e)
{
System.Timers.Timer timer = new System.Timers.Timer(1000);
timer.Enabled = true;
timer.Elapsed += new System.Timers.ElapsedEventHandler(fi);
timer.AutoReset = true;
}
private void ThreadProcSafe()
{
scanUDisk();
//MessageBox.Show(diskList.Count.ToString());
foreach (string s in diskList)
{
SetText(s);
}
}
public void SetText(string text)
{
if (this.listBox1.InvokeRequired)
{
if (listBox1.Items.Contains(text))
return;
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
if (listBox1.Items.Contains(text))
return;
this.listBox1.Items.Add(text);
}
}
void fi(object sender, System.Timers.ElapsedEventArgs e)
{
scanUDisk();
//listBox1.Items.Clear();
foreach (string s in diskList)
{
SetText(s);
}
}
}
/// <summary>
/// windows消息的常量
/// </summary>
class WndProMsgConst
{
#region WndProc常量
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;
#endregion
}
}
设备的实时性还是差一点,还有啊,像这样的窗体有很多,我不能每个窗体都copy一遍这些代码吧,如何封装起来呢,控件的线程安全也是问题,还需要改进啊,谁有好的意见可以提出来。
msn:jorden008@hotmail.com
mail:jorden008@163.com
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Threading;
namespace WindowsApp
{
public partial class ComboBoxForm2 : Form
{
private IList<string> diskList = new List<string>();
delegate void SetTextCallback(string s);
delegate void ClearListBoxItem();
private Thread thread = null;
private BackgroundWorker backgroundworker;
public ComboBoxForm2()
{
InitializeComponent();
}
protected override void WndProc(ref Message m)
{
object ojb = new object();
try
{
//WM_DEVICECHANGE,系统硬件改变发出的系统消息
if (m.Msg == WndProMsgConst.WM_DEVICECHANGE)
{
switch (m.WParam.ToInt32())
{
case WndProMsgConst.WM_DEVICECHANGE:
break;
//DBT_DEVICEARRIVAL,设备检测结束,并且可以使用
case WndProMsgConst.DBT_DEVICEARRIVAL:
scanUDisk();
listBox1.Items.Clear();
foreach (string s in diskList)
{
listBox1.Items.Add(s);
}
break;
//DBT_DEVICEREMOVECOMPLETE,设备卸载或者拔出
case WndProMsgConst.DBT_DEVICEREMOVECOMPLETE:
scanUDisk();
listBox1.Items.Clear();
foreach (string s in diskList)
{
listBox1.Items.Add(s);
}
break;
}
}
}
catch (Exception ex)
{
MessageBox.Show("当前盘不能正确识别,请重新尝试!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
base.WndProc(ref m);
}
private void button1_Click(object sender, EventArgs e)
{
IList<string> diskList = new List<string>();
diskList.Add("k001");
diskList.Add("k002");
diskList.Add("k003");
diskList.Add("k004");
comboBox1.DataSource = diskList;
}
/// <summary>
/// 扫描U口设备
/// </summary>
/// <param name="obj"></param>
private void scanUDisk()
{
diskList.Clear();
DriveInfo[] drives = DriveInfo.GetDrives();
foreach (DriveInfo drive in drives)
{
if ((drive.DriveType == DriveType.Removable) && !drive.Name.Substring(0, 1).Equals("A"))
{
try
{
diskList.Add(drive.Name);
}
catch
{
MessageBox.Show("当前盘不能正确识别,请重新尝试!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
}
private void ComboBoxForm2_Load(object sender, EventArgs e)
{
System.Timers.Timer timer = new System.Timers.Timer(1000);
timer.Enabled = true;
timer.Elapsed += new System.Timers.ElapsedEventHandler(fi);
timer.AutoReset = true;
}
private void ThreadProcSafe()
{
scanUDisk();
//MessageBox.Show(diskList.Count.ToString());
foreach (string s in diskList)
{
SetText(s);
}
}
public void SetText(string text)
{
if (this.listBox1.InvokeRequired)
{
if (listBox1.Items.Contains(text))
return;
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
if (listBox1.Items.Contains(text))
return;
this.listBox1.Items.Add(text);
}
}
void fi(object sender, System.Timers.ElapsedEventArgs e)
{
scanUDisk();
//listBox1.Items.Clear();
foreach (string s in diskList)
{
SetText(s);
}
}
}
/// <summary>
/// windows消息的常量
/// </summary>
class WndProMsgConst
{
#region WndProc常量
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;
#endregion
}
}
设备的实时性还是差一点,还有啊,像这样的窗体有很多,我不能每个窗体都copy一遍这些代码吧,如何封装起来呢,控件的线程安全也是问题,还需要改进啊,谁有好的意见可以提出来。
msn:jorden008@hotmail.com
mail:jorden008@163.com
简单封装了一下,封装类如下:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.IO;
namespace WindowsApp
{
class Class1
{
private IList<string> diskList = new List<string>();
delegate void SetTextCallback(string s);
delegate void ClearListBoxItem();
private ListBox _listbox;
private Form _form;
private Thread thread = null;
//private BackgroundWorker backgroundworker;
public Class1()
{
System.Timers.Timer timer = new System.Timers.Timer(1000);
timer.Enabled = true;
timer.Elapsed += new System.Timers.ElapsedEventHandler(fi);
timer.AutoReset = true;
}
public void filldata(Form form, Message m,ListBox listbox)
{
_listbox = listbox;
_form = form;
try
{
//WM_DEVICECHANGE,系统硬件改变发出的系统消息
if (m.Msg == WndProMsgConst.WM_DEVICECHANGE)
{
switch (m.WParam.ToInt32())
{
case WndProMsgConst.WM_DEVICECHANGE:
break;
//DBT_DEVICEARRIVAL,设备检测结束,并且可以使用
case WndProMsgConst.DBT_DEVICEARRIVAL:
scanUDisk();
_listbox.Items.Clear();
foreach (string s in diskList)
{
_listbox.Items.Add(s);
}
break;
//DBT_DEVICEREMOVECOMPLETE,设备卸载或者拔出
case WndProMsgConst.DBT_DEVICEREMOVECOMPLETE:
scanUDisk();
_listbox.Items.Clear();
foreach (string s in diskList)
{
_listbox.Items.Add(s);
}
break;
}
}
}
catch (Exception ex)
{
MessageBox.Show("当前盘不能正确识别,请重新尝试!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
public void SetText(string text)
{
if (this._listbox.InvokeRequired)
{
if (_listbox.Items.Contains(text))
return;
SetTextCallback d = new SetTextCallback(SetText);
_form.Invoke(d, new object[] { text });
}
else
{
if (_listbox.Items.Contains(text))
return;
this._listbox.Items.Add(text);
}
}
void fi(object sender, System.Timers.ElapsedEventArgs e)
{
scanUDisk();
//listBox1.Items.Clear();
foreach (string s in diskList)
{
SetText(s);
}
}/// <summary>
/// 扫描U口设备
/// </summary>
/// <param name="obj"></param>
private void scanUDisk()
{
diskList.Clear();
DriveInfo[] drives = DriveInfo.GetDrives();
foreach (DriveInfo drive in drives)
{
if ((drive.DriveType == DriveType.Removable) && !drive.Name.Substring(0, 1).Equals("A"))
{
try
{
diskList.Add(drive.Name);
}
catch
{
MessageBox.Show("当前盘不能正确识别,请重新尝试!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
}
} /// <summary>
/// windows消息的常量
/// </summary>
class WndProMsgConst
{
#region WndProc常量
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;
#endregion
}
}
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.IO;
namespace WindowsApp
{
class Class1
{
private IList<string> diskList = new List<string>();
delegate void SetTextCallback(string s);
delegate void ClearListBoxItem();
private ListBox _listbox;
private Form _form;
private Thread thread = null;
//private BackgroundWorker backgroundworker;
public Class1()
{
System.Timers.Timer timer = new System.Timers.Timer(1000);
timer.Enabled = true;
timer.Elapsed += new System.Timers.ElapsedEventHandler(fi);
timer.AutoReset = true;
}
public void filldata(Form form, Message m,ListBox listbox)
{
_listbox = listbox;
_form = form;
try
{
//WM_DEVICECHANGE,系统硬件改变发出的系统消息
if (m.Msg == WndProMsgConst.WM_DEVICECHANGE)
{
switch (m.WParam.ToInt32())
{
case WndProMsgConst.WM_DEVICECHANGE:
break;
//DBT_DEVICEARRIVAL,设备检测结束,并且可以使用
case WndProMsgConst.DBT_DEVICEARRIVAL:
scanUDisk();
_listbox.Items.Clear();
foreach (string s in diskList)
{
_listbox.Items.Add(s);
}
break;
//DBT_DEVICEREMOVECOMPLETE,设备卸载或者拔出
case WndProMsgConst.DBT_DEVICEREMOVECOMPLETE:
scanUDisk();
_listbox.Items.Clear();
foreach (string s in diskList)
{
_listbox.Items.Add(s);
}
break;
}
}
}
catch (Exception ex)
{
MessageBox.Show("当前盘不能正确识别,请重新尝试!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
public void SetText(string text)
{
if (this._listbox.InvokeRequired)
{
if (_listbox.Items.Contains(text))
return;
SetTextCallback d = new SetTextCallback(SetText);
_form.Invoke(d, new object[] { text });
}
else
{
if (_listbox.Items.Contains(text))
return;
this._listbox.Items.Add(text);
}
}
void fi(object sender, System.Timers.ElapsedEventArgs e)
{
scanUDisk();
//listBox1.Items.Clear();
foreach (string s in diskList)
{
SetText(s);
}
}/// <summary>
/// 扫描U口设备
/// </summary>
/// <param name="obj"></param>
private void scanUDisk()
{
diskList.Clear();
DriveInfo[] drives = DriveInfo.GetDrives();
foreach (DriveInfo drive in drives)
{
if ((drive.DriveType == DriveType.Removable) && !drive.Name.Substring(0, 1).Equals("A"))
{
try
{
diskList.Add(drive.Name);
}
catch
{
MessageBox.Show("当前盘不能正确识别,请重新尝试!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
}
} /// <summary>
/// windows消息的常量
/// </summary>
class WndProMsgConst
{
#region WndProc常量
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;
#endregion
}
}
使用方法如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Threading;
namespace WindowsApp
{
public partial class ComboBoxForm2 : Form
{
public ComboBoxForm2()
{
InitializeComponent();
}
protected override void WndProc(ref Message m)
{
Class1 c=new Class1();
c.filldata(this,m, listBox1);
base.WndProc(ref m);
}
}
}
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Threading;
namespace WindowsApp
{
public partial class ComboBoxForm2 : Form
{
public ComboBoxForm2()
{
InitializeComponent();
}
protected override void WndProc(ref Message m)
{
Class1 c=new Class1();
c.filldata(this,m, listBox1);
base.WndProc(ref m);
}
}
}