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
- Ottenere il collegamento simbolico del dispositivo
- Gestire WM_DEVICECHANGE
- Annullare la registrazione per la notifica
- Argomenti correlati
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;
}
Ottenere il collegamento simbolico del dispositivo
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:
- 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 .
- 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);
}
Argomenti correlati