Domanda

vi scrivo un'estensione per un'applicazione esistente che deve gestire gli eventi di inserimento USB / rimozione. So che il VID / PID del dispositivo di interesse. Tuttavia, non ho accesso alla maniglia della finestra, quindi non so se RegisterDeviceNotification sarà di grande utilità, a meno che non ci sia un modo per ottenere la maniglia attraverso il WINAPI. Quale sarebbe il modo migliore per rilevare eventi di inserimento / rimozione USB con C ++?

Questo codice di esempio sul sito Web Microsoft mostra come ricevere le notifiche degli eventi tramite WMI:

Come potrebbe essere modificato per ricevere gli eventi di inserimento / rimozione USB? Oppure, c'è un altro modo che dovrei andare su questo? Sto usando Visual Studio 2008. Grazie.

informazioni aggiuntive

Questo è quello che ho finora (meno di gestione degli errori):

DEFINE_GUID(GUID_INTERFACE_CP210x, 0x993f7832, 0x6e2d, 0x4a0f, 0xb2, 0x72, 0xe2, 0xc7, 0x8e, 0x74, 0xf9, 0x3e);

MyClass::MyClass()
{
    // Generate message-only window
    _pWndClassEx = (WNDCLASSEX *)malloc( sizeof(WNDCLASSEX) );
    memset( _pWndClassEx, 0, sizeof(WNDCLASSEX) );
    _pWndClassEx->cbSize = sizeof(WNDCLASSEX);
    _pWndClassEx->lpfnWndProc = (WNDPROC)WndProc; // function which will handle messages
    _pWndClassEx->hInstance = GetCurrentModule();
    _pWndClassEx->lpszClassName = pClassName;
    atom = RegisterClassEx( _pWndClassEx );
    _hWnd = CreateWindowEx( 0, pClassName, pWindowName, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL );

    // Register the USB device for notification
    _pDevIF = (DEV_BROADCAST_DEVICEINTERFACE *)malloc( sizeof(DEV_BROADCAST_DEVICEINTERFACE) );
    memset( _pDevIF, 0, sizeof(DEV_BROADCAST_DEVICEINTERFACE) );
    _pDevIF->dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
    _pDevIF->dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
    _pDevIF->dbcc_classguid = GUID_INTERFACE_CP210x;
    _hNotifyDevNode = RegisterDeviceNotification( _hWnd, _pDevIF, DEVICE_NOTIFY_WINDOW_HANDLE );
}

static bool OnDeviceChange(UINT nEventType, DWORD dwData)
{
    switch ( nEventType )
    {
    case DBT_DEVICEARRIVAL:
        // A device has been inserted adn is now available.
        break;

    case DBT_DEVICEREMOVECOMPLETE:
        // Device has been removed.
        break;

    default:
        break;
    }

    return true;
}

static LRESULT WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
{
    switch ( message )
    {
    case WM_DEVICECHANGE:
        OnDeviceChange( wParam, lParam ); // Set breakpoint (never gets here)
        break;

    default:
        break;
    }

    return DefWindowProc(hwnd, message, wParam, lParam);
}

Il PC entra nel WndProc, ma non quando rimuovo / inserto mio dispositivo USB. Il PC non sembra mai entrare in OnDeviceChange. Eventuali suggerimenti sarebbe apprezzato. Ho bisogno di gestire imprevisti inserimenti / rimozioni del dispositivo USB. Se si fa la differenza, la periferica USB appare come una porta COM virtuale a Windows. Grazie.

Info Aditional: "Impossibile trovare la classe finestra" Calling CreateWindowEx utilizzando la atom classe restituita dal RegisterClassEx non riesce con il messaggio di errore,

_hWnd = CreateWindowEx( 0, (LPCTSTR)&atom, pWindowName, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL );

NUOVO APPROCCIO

Sto anche cercando di questo nuovo approccio. Sto cercando di ottenere scrivere una finestra di messaggio-solo per ricevere i messaggi di notifica di cambio per una periferica USB. Sto usando MFC, C ++ e Visual Studio 2008. compila tutto, e funziona senza crash o bloccarsi, ma il gestore di eventi è mai attivato. Il dispositivo di interesse è installato su Windows come una porta COM virtuale.

La mia applicazione principale un'istanza della classe descritto di seguito quindi attende un ingresso di carattere dalla polling della tastiera utilizzando un ciclo while. E 'durante questo tempo di attesa che io rimuovere e inserire il dispositivo USB in attesa della manifestazione di essere licenziato.

class CMessageOnlyWindow : public CWnd
{
    DECLARE_DYNAMIC(CMessageOnlyWindow)
private:
    DEV_BROADCAST_DEVICEINTERFACE * _pDevIF; // The notification filter.
    HDEVNOTIFY _hNotifyDev;             // The device notification handle.
public:
    CMessageOnlyWindow();
    virtual ~CMessageOnlyWindow();
protected:
    afx_msg BOOL OnDeviceChange( UINT nEventType, DWORD dwData );
private:
    void RegisterNotification( void );
    void UnregisterNotification( void );
protected:
    DECLARE_MESSAGE_MAP()               // Must be last.
};

Per semplicità, ho rimosso tutto il pulizia e di gestione degli errori:

DEFINE_GUID(GUID_INTERFACE_CP210x, 0x993f7832, 0x6e2d, 0x4a0f, \
    0xb2, 0x72, 0xe2, 0xc7, 0x8e, 0x74, 0xf9, 0x3e);

IMPLEMENT_DYNAMIC(CMessageOnlyWindow, CWnd)

CMessageOnlyWindow::CMessageOnlyWindow()
{
    CString cstrWndClassName = ::AfxRegisterWndClass( NULL );
    BOOL bCreated = this->CreateEx( 0, cstrWndClassName,
        L"CMessageOnlyWindow", 0, 0, 0, 0, 0, HWND_MESSAGE, 0 );
    this->RegisterNotification();
}

CMessageOnlyWindow::~CMessageOnlyWindow() {}

BEGIN_MESSAGE_MAP(CMessageOnlyWindow, CWnd)
    ON_WM_DEVICECHANGE()
END_MESSAGE_MAP()

afx_msg BOOL CMessageOnlyWindow::OnDeviceChange( UINT nEventType, DWORD dwData )
{
    switch ( nEventType ) // <-- Never gets here.
    {
    case DBT_DEVICEARRIVAL:
        break;

    case DBT_DEVICEREMOVECOMPLETE:
        break;

    default:
        break;
    }

    return TRUE;
}

void CMessageOnlyWindow::RegisterNotification(void)
{
    _pDevIF = (DEV_BROADCAST_DEVICEINTERFACE *)malloc( sizeof(DEV_BROADCAST_DEVICEINTERFACE) );
    memset( _pDevIF, 0, sizeof(DEV_BROADCAST_DEVICEINTERFACE) );
    _pDevIF->dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
    _pDevIF->dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
    _pDevIF->dbcc_classguid = GUID_INTERFACE_CP210x;
    _hNotifyDev = RegisterDeviceNotification( this->m_hWnd, _pDevIF, DEVICE_NOTIFY_WINDOW_HANDLE );
}

void CMessageOnlyWindow::UnregisterNotification(void)
{
    UnregisterDeviceNotification( _hNotifyDev );
}

Ogni pensiero o suggerimenti sarebbe molto apprezzato. Se alcuni dettagli mancanti, fatemelo sapere, e sarò felice di aggiungerli. Grazie.

La finestra di necessità messaggio-solo per essere avviato in un nuovo thread, o se creare una nuova finestra automaticamente spin off un nuovo thread?

È stato utile?

Soluzione

Crea una finestra fittizio che non fa altro che aspettare per WM_DEVICECHANGE e registrare quella finestra utilizzando RegisterDeviceNotification. WMI è un peso inutile qui, IMHO.

scroll top