Использование переопределения WndProc для определения, когда USB подключен или отключен

Этот вопрос привел меня туда, где я сейчас нахожусь. имя 'WM_DEVICECHANGE' не существует в текущем контексте

но у меня проблема с обнаружением правильных сообщений, когда они происходят, и я не уверен, что коды сообщений, которые я использую, неверны или я сделал ошибку в другом месте, но я просто хочу знать, как я могу использовать переопределенный метод для обнаружения ТОЛЬКО USB-подключение или отсоединение, или, может быть, где-нибудь есть более убедительная статья, в которой подробно показано, что такое каждый код в WM_DEVICECHANGE?

    private const int WM_DEVICECHANGE = 0x0219;
    private const int DBT_DEVICEARRIVAL = 0x8000; // system detected a new device
    private const int DBT_DEVICEREMOVECOMPLETE = 0x8004; //device was removed

    [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
    protected override void WndProc(ref Message m) {
        base.WndProc(ref m);

        switch (m.Msg) {
            case WM_DEVICECHANGE:
                if (m.WParam.ToInt64() == DBT_DEVICEARRIVAL)
                    MessageBox.Show("TEST");
                if (m.WParam.ToInt64() == DBT_DEVICEREMOVECOMPLETE)
                    MessageBox.Show("DETACHED");
                break;
        }

    }

моя проблема в том, что если я попытаюсь следовать примеру в заданном выше вопросе, я получаю сообщение об ошибке «Оператор '==' не может быть применен к операндам типа 'System.IntPtr' и 'int'», но если я оставлю его как показано в моем примере кода, то он не срабатывает, потому что число в WParam никогда не совпадает с числом в DBT_DEVICEARRIVAL или DBT_DEVICEREMOVECOMPLETE.


person Community    schedule 06.08.2013    source источник
comment
Знаешь что! вы решили проблему, с которой я сталкивался с 1:00 до 8:00, с помощью вашего очень простого кода, я не могу найти способ поблагодарить вас, а также сообщество стека. слава Богу :)   -  person Amr SubZero    schedule 11.08.2015


Ответы (1)


ToInt64() просто вернет адрес (или дескриптор) в виде целого числа. Я считаю, что вы хотите получить значение, хранящееся там, и в этом случае вы бы сделали

if(Marshal.ReadInt64(m.wParam) == DBT_DEVICEARRIVAL)
//and so on

Marshal находится в пространстве имен System.Runtime.InteropServices.

Также убедитесь, что это то место, откуда должно извлекаться значение, т. е. это может быть старшее слово или младшее слово или что-то в этом роде, а не все 64/32 бита.

person user1132959    schedule 06.08.2013
comment
Я попробовал ваше решение, а затем попытался проверить все поля в m на наличие числа, совпадающего с тем, что было DBT_DEVICEARRIVAL, и НИ ОДИН из них не совпал после того, как USB был вставлен и произошло событие WM_DEVICECHANGE. Возможно ли, что я определил DBT_DEVICEARRIVAL с неправильными кодами? Если да, то как они работали должным образом для кого-либо еще? - person ; 06.08.2013
comment
@JBeck У вас правильный код. Попробуйте ReadInt32() вместо ReadInt64() - person user1132959; 06.08.2013
comment
По-прежнему ничего не используется, если (Marshal.ReadInt32(m.wParam) == DBT_DEVICEARRIVAL) он никогда не получает число, такое же, как DBT_DEVICEARRIVAL. Определенное значение для него действительно должно быть 0x8000? - person ; 06.08.2013
comment
@JBeck Вы зарегистрировали свое приложение, чтобы получать уведомления? msdn.microsoft.com/en-us/library/windows/ рабочий стол/aa363431.aspx - person user1132959; 06.08.2013
comment
О стрелять! Нет, я не думаю, что я сделал это. Как мне это сделать на С#? - person ; 06.08.2013
comment
@JBeck Взгляните сюда: pinvoke.net/default.aspx/user32.registerdevicenotification В основном вы будете вызывать его при загрузке вашего приложения. Возможно, вам придется найти учебник, если в нем недостаточно информации. - person user1132959; 07.08.2013