2011-04-18 13 views
0

我想在後臺使用消息窗口獲取WM_DEVICECHANGE。我從pinvoke.com獲得的所有Windows API方法都經過了測試。我正在使用Windows的xbox 360控制器和Logitech G35耳機來測試代碼,但我從來沒有得到WM_DEVICECHANGE。GetMessage在我的MessageWindow中沒有收到WM_DEVICECHANGE

下面是代碼:

//Creats Message windwos Win32Core.HWND_MESSAGE=-3 
IntPtr hMessageWindow = Win32Core.CreateWindowEx(0, "static", "", 0, 0, 0, 0, 0, Win32Core.HWND_MESSAGE, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); 

//creat and populate the DEV_BROADCAST_DEVICEINTERFACE struct 
DEV_BROADCAST_DEVICEINTERFACE sDeviceFilter = new DEV_BROADCAST_DEVICEINTERFACE(); 
sDeviceFilter.dbcc_devicetype = (int)DBT_DEVTYP_DEVICEINTERFACE; //DBT_DEVTYP_DEVICEINTERFACE = 0x00000005 
sDeviceFilter.dbcc_reserved = 0; 
//sDeviceFilter.dbcc_classguid = ; irelevant becouse i am using DEVICE_NOTIFY_ALL_INTERFACE_CLASSES 
sDeviceFilter.dbcc_name = "EpicName\0"; 
sDeviceFilter.dbcc_size = Marshal.SizeOf(sDeviceFilter); 

//Marshel sDeviceFilter to hDeviceFilter pointer 
IntPtr hDeviceFilter = Marshal.AllocHGlobal(sDeviceFilter.dbcc_size); 
Marshal.StructureToPtr(sDeviceFilter, hDeviceFilter, false); 

//Register for WM_DEVICECHANGE DEVICE_NOTIFY_WINDOW_HANDLE =0x00000000 , DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = 0x00000004 
//The RegisterDeviceNotification Returns some non 0 value 
IntPtr hDeviceNotification = Win32Core.RegisterDeviceNotification(hMessageWindow, hDeviceFilter, DEVICE_NOTIFY_WINDOW_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES); 

//Message pump 
MSG sMsg = new MSG(); 
while (true) 
{ 
    if (Win32Core.GetMessage(out sMsg, hMessageWindow, 0, 0)) 
    { 
     if (sMsg.message == (int)WM.WM_DEVICECHANGE) 
     { 
      //Never gets here 
     } 
    } 
    Win32Core.DispatchMessage(ref sMsg); 
    sMsg = new MSG(); 
} 

//structs 
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] 
public struct DEV_BROADCAST_DEVICEINTERFACE 
{ 
    public int dbcc_size; 
    public int dbcc_devicetype; 
    public int dbcc_reserved; 
    public Guid dbcc_classguid; 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 255)] 
    public string dbcc_name; 
} 

回答

0

這是一個非排隊消息,並且因此它不通過消息隊列到達。你不要打電話給GetMessage()。而是直接發送到窗口。我建議您閱讀Windows消息的MSDN概述主題:About Messages and Message Queues

documentation for WM_DEVICECHANGE狀態如何如下的消息被傳遞:

一個窗口,通過它的 WindowProc函數接收該消息。

您需要重寫一個WndProc()方法來接收此消息。

我想你應該能夠從System.Windows.Forms.Control派生出來並覆蓋WndProc()以獲得此通知。更重要的是,您不需要在後臺線程中執行此操作。