Gestione di eventi dal dispositivo
Un'altra operazione eseguita da un'applicazione WPD è la gestione degli eventi generati dal dispositivo.
Le operazioni di gestione degli eventi vengono eseguite usando le interfacce descritte nella tabella seguente.
Interfaccia | Descrizione |
---|---|
Interfaccia IPortableDevice | Consente all'applicazione di registrarsi per ricevere callback asincroni. |
Interfaccia IPortableDeviceEventCallback | Contiene il gestore eventi dell'applicazione. |
La classe CPortableDeviceEventsCallback nel modulo DeviceEvents.cpp dell'applicazione di esempio illustra come un'applicazione può implementare IPortableDeviceEventCallback. L'implementazione del metodo OnEvent in questa classe scrive i parametri per qualsiasi evento nella finestra della console dell'applicazione. Oltre al metodo OnEvent, questa classe implementa AddRef e Release, che vengono usati per mantenere il conteggio dei riferimenti dell'oggetto.
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;
};
L'applicazione di esempio crea un'istanza della classe CPortableDeviceEventsCallback nella relativa funzione helper RegisterForEventNotifications. Questa funzione crea un'istanza dell'oggetto callback usando il nuovo operatore. Chiama quindi il metodo IPortableDevice::Advise per registrare il callback e iniziare a ricevere eventi.
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();
}
Quando l'applicazione di esempio riceve eventi, chiama la funzione helper UnregisterForEventNotifications. Questa funzione, a sua volta, chiama il metodo IPortableDevice::Unadvise per annullare la registrazione del callback dalla ricezione di eventi.
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"";
}
Argomenti correlati