デバイスからのイベントの処理
WPD アプリケーションによって実行されるもう 1 つの操作は、デバイスによって発生するイベントの処理です。
イベント処理操作は、次の表で説明するインターフェイスを使用して実行されます。
インターフェイス | 説明 |
---|---|
IPortableDevice インターフェイス | アプリケーションを登録して非同期コールバックを受信できるようにします。 |
IPortableDeviceEventCallback インターフェイス | アプリケーションのイベント ハンドラーを格納します。 |
サンプル アプリケーションの DeviceEvents.cpp モジュールの CPortableDeviceEventsCallback クラスは、アプリケーションで IPortableDeviceEventCallback を実装する方法を示しています。 このクラスの OnEvent メソッドの実装は、任意のイベントのパラメーターをアプリケーションのコンソール ウィンドウに書き込みます。 OnEvent メソッドに加えて、このクラスは AddRef と Release を実装します。これは、オブジェクトの参照カウントを維持するために使用されます。
class CPortableDeviceEventsCallback : public IPortableDeviceEventCallback
{
public:
CPortableDeviceEventsCallback() : m_cRef(1)
{
}
~CPortableDeviceEventsCallback()
{
}
HRESULT __stdcall QueryInterface(
REFIID riid,
LPVOID* ppvObj)
{
HRESULT hr = S_OK;
if (ppvObj == NULL)
{
hr = E_INVALIDARG;
return hr;
}
if ((riid == IID_IUnknown) ||
(riid == IID_IPortableDeviceEventCallback))
{
AddRef();
*ppvObj = this;
}
else
{
hr = E_NOINTERFACE;
}
return hr;
}
ULONG __stdcall AddRef()
{
InterlockedIncrement((long*) &m_cRef);
return m_cRef;
}
ULONG __stdcall Release()
{
ULONG ulRefCount = m_cRef - 1;
if (InterlockedDecrement((long*) &m_cRef) == 0)
{
delete this;
return 0;
}
return ulRefCount;
}
HRESULT __stdcall OnEvent(
IPortableDeviceValues* pEventParameters)
{
HRESULT hr = S_OK;
if (pEventParameters != NULL)
{
printf("***************************\n** Device event received **\n***************************\n");
DisplayStringProperty(pEventParameters, WPD_EVENT_PARAMETER_PNP_DEVICE_ID, L"WPD_EVENT_PARAMETER_PNP_DEVICE_ID");
DisplayGuidProperty(pEventParameters, WPD_EVENT_PARAMETER_EVENT_ID, L"WPD_EVENT_PARAMETER_EVENT_ID");
}
return hr;
}
ULONG m_cRef;
};
サンプル アプリケーションは、RegisterForEventNotifications ヘルパー関数で CPortableDeviceEventsCallback クラスをインスタンス化します。 この関数は、new 演算子を使用してコールバック オブジェクトのインスタンスを作成します。 その後、 IPortableDevice::Advise メソッドを呼び出してコールバックを登録し、イベントの受信を開始します。
void RegisterForEventNotifications(IPortableDevice* pDevice)
{
HRESULT hr = S_OK;
LPWSTR wszEventCookie = NULL;
CPortableDeviceEventsCallback* pCallback = NULL;
if (pDevice == NULL)
{
return;
}
// Check to see if we already have an event registration cookie. If so,
// then avoid registering again.
// NOTE: An application can register for events as many times as they want.
// This sample only keeps a single registration cookie around for
// simplicity.
if (g_strEventRegistrationCookie.GetLength() > 0)
{
printf("This application has already registered to receive device events.\n");
return;
}
// Create an instance of the callback object. This will be called when events
// are received.
if (hr == S_OK)
{
pCallback = new CPortableDeviceEventsCallback();
if (pCallback == NULL)
{
hr = E_OUTOFMEMORY;
printf("Failed to allocate memory for IPortableDeviceEventsCallback object, hr = 0x%lx\n",hr);
}
}
// Call Advise to register the callback and receive events.
if (hr == S_OK)
{
hr = pDevice->Advise(0, pCallback, NULL, &wszEventCookie);
if (FAILED(hr))
{
printf("! Failed to register for device events, hr = 0x%lx\n",hr);
}
}
// Save the event registration cookie if event registration was successful.
if (hr == S_OK)
{
g_strEventRegistrationCookie = wszEventCookie;
}
// Free the event registration cookie, if one was returned.
if (wszEventCookie != NULL)
{
CoTaskMemFree(wszEventCookie);
wszEventCookie = NULL;
}
if (hr == S_OK)
{
printf("This application has registered for device event notifications and was returned the registration cookie '%ws'", g_strEventRegistrationCookie.GetString());
}
// If a failure occurs, remember to delete the allocated callback object, if one exists.
if (pCallback != NULL)
{
pCallback->Release();
}
サンプル アプリケーションがイベントを受信すると、UnregisterForEventNotifications ヘルパー関数が呼び出されます。 次に、この関数は IPortableDevice::Unadvise メソッドを呼び出して、イベントの受信からコールバックを登録解除します。
void UnregisterForEventNotifications(IPortableDevice* pDevice)
{
HRESULT hr = S_OK;
if (pDevice == NULL)
{
return;
}
hr = pDevice->Unadvise(g_strEventRegistrationCookie);
if (FAILED(hr))
{
printf("! Failed to unregister for device events using registration cookie '%ws', hr = 0x%lx\n",g_strEventRegistrationCookie.GetString(), hr);
}
if (hr == S_OK)
{
printf("This application used the registration cookie '%ws' to unregister from receiving device event notifications", g_strEventRegistrationCookie.GetString());
}
g_strEventRegistrationCookie = L"";
}
関連トピック