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.commail: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;
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); } } }
转载自:
http://www.cnblogs.com/virusswb/archive/2008/08/22/1274085.html
转载于:https://www.cnblogs.com/wuhenke/archive/2010/05/07/1730039.html
相关资源:电脑常见问题与故障1000例(高清PDF中文版)