2011-04-18 5 views
0

메시지 창을 사용하여 백그라운드에서 WM_DEVICECHANGE를 가져 오려고합니다. 모든 Windows API 메서드는 pinvoke.com에서 가져 와서 작동합니다. 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()을 재정의 할 수 있어야한다고 생각합니다. 더 이상 당신은 배경 스레드에서 이것을 할 필요가 없습니다.

관련 문제