U盘加载,卸载,拔出,插入,WM_DEVICECHANGE,WndProc,DBT_DEVICEARRIVAL,DBT_DEVICEREMOVECOMPLETE


最近在做一个和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:[email protected]
mail:[email protected]


简单封装了一下,封装类如下:

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);
        }
       
    }
   
}


你可能感兴趣的:(remove)