處理視訊裝置遺失
本主題描述如何使用視訊擷取裝置來偵測裝置遺失。 它包含下列區段:
註冊裝置通知
開始從裝置擷取之前,請先呼叫 RegisterDeviceNotification 函式來註冊裝置通知。 註冊 KSCATEGORY_CAPTURE 裝置類別,如下列程式碼所示。
#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;
}
取得裝置的符號連結
如列舉視訊擷取裝置中所述,列舉系統上 的視訊裝置。 從清單中選擇裝置,然後查詢 MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK 屬性的啟用物件,如下列程式碼所示。
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
);
}
處理WM_DEVICECHANGE
在您的訊息迴圈中,接聽 WM_DEVICECHANGE 訊息。 lParam訊息參數是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;
接下來,將裝置通知訊息與裝置的符號連結進行比較,如下所示:
- 檢查 DEV_BROADCAST_HDR 結構的 dbch_devicetype 成員。 如果值 DBT_DEVTYP_DEVICEINTERFACE,請將結構指標轉換成 DEV_BROADCAST_DEVICEINTERFACE 結構。
- 比較此結構的 dbcc_name 成員與裝置的符號連結。
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;
}
取消註冊通知
在應用程式結束之前,呼叫 UnregisterDeviceNotification 以取消註冊裝置通知/
void OnClose(HWND /*hwnd*/)
{
if (g_hdevnotify)
{
UnregisterDeviceNotification(g_hdevnotify);
}
PostQuitMessage(0);
}
相關主題