Share via


Gestione della perdita di dispositivi video

Questo argomento descrive come rilevare la perdita di dispositivi quando si usa un dispositivo di acquisizione video. Contiene le sezioni seguenti:

Registrarsi per la notifica del dispositivo

Prima di iniziare l'acquisizione dal dispositivo, chiamare la funzione RegisterDeviceNotification per eseguire la registrazione per le notifiche del dispositivo. Eseguire la registrazione per la classe del dispositivo KSCATEGORY_CAPTURE , come illustrato nel codice seguente.

#include <Dbt.h>
#include <ks.h>
#include <ksmedia.h>

HDEVNOTIFY  g_hdevnotify = NULL;

BOOL RegisterForDeviceNotification(HWND hwnd)
{
    DEV_BROADCAST_DEVICEINTERFACE di = { 0 };
    di.dbcc_size = sizeof(di);
    di.dbcc_devicetype  = DBT_DEVTYP_DEVICEINTERFACE;
    di.dbcc_classguid  = KSCATEGORY_CAPTURE; 

    g_hdevnotify = RegisterDeviceNotification(
        hwnd,
        &di,
        DEVICE_NOTIFY_WINDOW_HANDLE
        );

    if (g_hdevnotify == NULL)
    {
        return FALSE;
    }

    return TRUE;
}

Enumerare i dispositivi video nel sistema, come descritto in Enumerazione dei dispositivi di acquisizione video. Scegliere un dispositivo dall'elenco e quindi eseguire una query sull'oggetto attivazione per l'attributo MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK , come illustrato nel codice seguente.

WCHAR      *g_pwszSymbolicLink = NULL;
UINT32     g_cchSymbolicLink = 0;

HRESULT GetSymbolicLink(IMFActivate *pActivate)
{
    return pActivate->GetAllocatedString(
        MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK,
        &g_pwszSymbolicLink,
        &g_cchSymbolicLink
        );
}

Gestire WM_DEVICECHANGE

Nel ciclo di messaggi ascoltare WM_DEVICECHANGE messaggi. Il parametro del messaggio lParam è un puntatore a una struttura DEV_BROADCAST_HDR .

    case WM_DEVICECHANGE:
        if (lParam != 0)
        {
            HRESULT hr = S_OK;
            BOOL bDeviceLost = FALSE;

            hr = CheckDeviceLost((PDEV_BROADCAST_HDR)lParam, &bDeviceLost);

            if (FAILED(hr) || bDeviceLost)
            {
                CloseDevice();

                MessageBox(hwnd, L"Lost the capture device.", NULL, MB_OK);
            }
        }
        return TRUE;

Confrontare quindi il messaggio di notifica del dispositivo con il collegamento simbolico del dispositivo, come indicato di seguito:

  1. Controllare il membro dbch_devicetype della struttura DEV_BROADCAST_HDR . Se il valore è DBT_DEVTYP_DEVICEINTERFACE, eseguire il cast del puntatore della struttura a una struttura DEV_BROADCAST_DEVICEINTERFACE .
  2. Confrontare il membro dbcc_name di questa struttura con il collegamento simbolico del dispositivo.
HRESULT CheckDeviceLost(DEV_BROADCAST_HDR *pHdr, BOOL *pbDeviceLost)
{
    DEV_BROADCAST_DEVICEINTERFACE *pDi = NULL;

    if (pbDeviceLost == NULL)
    {
        return E_POINTER;
    }

    *pbDeviceLost = FALSE;
    
    if (g_pSource == NULL)
    {
        return S_OK;
    }
    if (pHdr == NULL)
    {
        return S_OK;
    }
    if (pHdr->dbch_devicetype != DBT_DEVTYP_DEVICEINTERFACE)
    {
        return S_OK;
    }

    // Compare the device name with the symbolic link.

    pDi = (DEV_BROADCAST_DEVICEINTERFACE*)pHdr;

    if (g_pwszSymbolicLink)
    {
        if (_wcsicmp(g_pwszSymbolicLink, pDi->dbcc_name) == 0)
        {
            *pbDeviceLost = TRUE;
        }
    }

    return S_OK;
}

Annullare la registrazione per la notifica

Prima dell'uscita dall'applicazione, chiama UnregisterDeviceNotification per annullare la registrazione per le notifiche del dispositivo/

void OnClose(HWND /*hwnd*/)
{
    if (g_hdevnotify)
    {
        UnregisterDeviceNotification(g_hdevnotify);
    }

    PostQuitMessage(0);
}

Enumerazione dei dispositivi di acquisizione video

Acquisizione video