Frage

Ich schreibe eine Erweiterung für eine bestehende Anwendung, die Bedürfnisse USB Einfügen / Entfernen-Ereignisse zu behandeln. Ich kenne die VID / PID der Vorrichtung von Interesse. Aber ich habe keinen Zugriff auf den Fenstergriff, so dass ich weiß nicht, ob RegisterDeviceNotification von großem Nutzen sein wird, es sei denn, es ist ein Weg der Griff über die WINAPI zu erhalten. Was wäre der beste Weg, USB Einfügen / Entfernen Ereignisse mit C ++?

erkennen

Dieser Beispielcode auf der Microsoft-Website zeigt, wie Ereignisbenachrichtigungen über WMI erhalten:

Wie könnte es geändert werden USB Einfügen / Entfernen Ereignisse zu empfangen? Oder gibt es eine andere Art und Weise ich darüber gehen sollte? Ich bin mit Visual Studio 2008. Dank.

WEITERE INFO

Das ist, was ich habe bisher (minus Fehlerbehandlung):

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

Der PC wird in WndProc, aber nicht, wenn ich entfernen / Insert mein USB-Gerät. Der PC scheint nie in OnDeviceChange zu bekommen. Irgendwelche Tipps wäre sehr hilfreich. Ich muss unerwartete Einfügungen / Umzug des USB-Geräts handhaben. Wenn es einen Unterschied macht, wird das USB-Gerät als virtueller COM-Port auf Windows. Danke.

Zusatzinfo: „Kann nicht Fensterklasse finden“ aufrufen CreateWindowEx die Klasse atom von RegisterClassEx zurück fehl mit der Fehlermeldung

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

NEUER ANSATZ

Ich versuche, auch diesen neuen Ansatz. Ich versuche, eine Nachricht nur für Fenster zu erhalten, schreiben die Option Gerät Benachrichtigungsnachrichten für ein USB-Gerät zu empfangen. Ich bin mit MFC, C ++ und Visual Studio 2008. Alles kompiliert, und es läuft ohne Absturz oder Einsperren, aber der Event-Handler wird nie ausgelöst. Das Gerät von Interesse auf Windows als virtueller COM-Port installiert ist.

Meine Hauptanwendung instanziiert die Klasse weiter unten beschrieben wartet dann auf eine Zeicheneingabe über die Tastatur Polling eine while-Schleife verwenden. Es ist während dieser Wartezeit, dass ich entfernen und mein USB-Gerät einlegen das Ereignis erwartet gefeuert werden.

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

Der Einfachheit halber habe ich entfernt alle die Bereinigung und Fehlerbehandlung:

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

Alle Gedanken oder Vorschläge würden sehr geschätzt. Wenn irgendwelche Details fehlen, lassen Sie mich wissen, und ich werde mich freuen, um sie hinzuzufügen. Danke.

Ist die Nachricht nur für Fenster müssen in einem neuen Thread gestartet werden, oder hat sich ein neues Fenster zu schaffen automatisch Spin-off einem neuen Thread?

War es hilfreich?

Lösung

ein Dummy-Fenster erstellen, die nichts tut, sondern für WM_DEVICECHANGE warten und registrieren das Fenster RegisterDeviceNotification verwenden. WMI ist zuviel des Guten hier, meiner Meinung nach.

Andere Tipps

Es gibt eine MSDN Probe speziell für Ihr Fall in nativen Code.

  

Die Registrierung für Geräte Mitteilung

Besser es auf diese Weise als über WMI zu tun.

Ich folgte Ihr „neues Konzept“ und auch festgestellt, dass OnDeviceChange nicht genannt wurde. Das Problem war, dass es keine Nachrichtenschleife war, weil es sich um eine Konsole app war. Der Aufruf der folgenden Funktion in regelmäßigen Abständen es festgelegt.

void check_for_device_change()
{
    MSG msg; 

    const int val = PeekMessage( &msg, 0, 0, 0, PM_REMOVE );

    if( val > 0 )
    { 
        TranslateMessage( &msg );
        DispatchMessage( &msg );
    } 
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top