디바이스에서 이벤트 처리
WPD 애플리케이션에서 수행하는 또 다른 작업은 디바이스에서 발생하는 이벤트를 처리하는 것입니다.
이벤트 처리 작업은 다음 표에 설명된 인터페이스를 사용하여 수행됩니다.
인터페이스 | Description |
---|---|
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 클래스를 인스턴스화합니다. 이 함수는 새 연산자를 사용하여 콜백 개체의 instance 만듭니다. 그런 다음 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"";
}
관련 항목