ILocationEvents
COM公式ドキュメント
ILocationEvents は、イベント通知を受け取りたい場合に実装する必要があるコールバックメソッドを提供します。
メソッド 2
vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。
新しい位置(ロケーション)レポートが利用可能になったときに呼び出されます。
| reportType | GUID* | in | pLocationReport に含まれるレポート型のインターフェース ID を格納する REFIID。 |
| pLocationReport | ILocationReport* | inoptional | 新しい位置(ロケーション)レポートを含む ILocationReport インスタンスへのポインター。 |
戻り値
このメソッドが成功した場合は S_OK を返します。それ以外の場合は HRESULT エラーコードを返します。
解説(Remarks)
ILocationReport は、特定の位置(ロケーション)レポート型の基底インターフェースです。呼び出し元が pLocationReport として受け取る実際のインターフェースは、reportType で指定された型と一致します。
アプリケーションが位置(ロケーション)を初めて使用した結果として OnLocationChanged を呼び出すと、その呼び出しによってタスクバーに通知が表示され、イベントビューアーに Location Activity イベントが記録される場合があります。
例
次の OnLocationChanged のサンプル実装は、緯度/経度レポートの位置(ロケーション)変更イベントを処理します。この実装は、緯度/経度の位置(ロケーション)変更イベントについて、タイムスタンプ、センサー ID、緯度、経度、誤差半径、高度、高度誤差の各情報を出力します。
// This is called when there is a new location report
STDMETHODIMP CLocationEvents::OnLocationChanged(REFIID reportType, ILocationReport* pLocationReport)
{
// If the report type is a Latitude/Longitude report (as opposed to IID_ICivicAddressReport or another type)
if (IID_ILatLongReport == reportType)
{
CComPtr<ILatLongReport> spLatLongReport;
// Get the ILatLongReport interface from ILocationReport
if ((SUCCEEDED(pLocationReport->QueryInterface(IID_PPV_ARGS(&spLatLongReport)))) && (NULL != spLatLongReport.p))
{
// Print the Report Type GUID
wchar_t szGUID[64];
wprintf(L"\nReportType: %s", GUIDToString(IID_ILatLongReport, szGUID, ARRAYSIZE(szGUID)));
// Print the Timestamp and the time since the last report
SYSTEMTIME systemTime;
if (SUCCEEDED(spLatLongReport->GetTimestamp(&systemTime)))
{
// Compute the number of 100ns units that difference between the current report's time and the previous report's time.
ULONGLONG currentTime = 0, diffTime = 0;
if (TRUE == SystemTimeToFileTime(&systemTime, (FILETIME*)¤tTime))
{
diffTime = (currentTime > m_previousTime) ? (currentTime - m_previousTime) : 0;
}
wprintf(L"\nTimestamp: YY:%d, MM:%d, DD:%d, HH:%d, MM:%d, SS:%d, MS:%d [%I64d]\n",
systemTime.wYear,
systemTime.wMonth,
systemTime.wDay,
systemTime.wHour,
systemTime.wMinute,
systemTime.wSecond,
systemTime.wMilliseconds,
diffTime / 10000); // Display in milliseconds
m_previousTime = currentTime; // Set the previous time to the current time for the next report.
}
// Print the Sensor ID GUID
GUID sensorID = {0};
if (SUCCEEDED(spLatLongReport->GetSensorID(&sensorID)))
{
wchar_t szGUID[64];
wprintf(L"SensorID: %s\n", GUIDToString(sensorID, szGUID, ARRAYSIZE(szGUID)));
}
DOUBLE latitude = 0, longitude = 0, altitude = 0, errorRadius = 0, altitudeError = 0;
// Print the Latitude
if (SUCCEEDED(spLatLongReport->GetLatitude(&latitude)))
{
wprintf(L"Latitude: %f\n", latitude);
}
// Print the Longitude
if (SUCCEEDED(spLatLongReport->GetLongitude(&longitude)))
{
wprintf(L"Longitude: %f\n", longitude);
}
// Print the Altitude
if (SUCCEEDED(spLatLongReport->GetAltitude(&altitude)))
{
wprintf(L"Altitude: %f\n", altitude);
}
else
{
// Altitude is optional and may not be available
wprintf(L"Altitude: Not available.\n");
}
// Print the Error Radius
if (SUCCEEDED(spLatLongReport->GetErrorRadius(&errorRadius)))
{
wprintf(L"Error Radius: %f\n", errorRadius);
}
// Print the Altitude Error
if (SUCCEEDED(spLatLongReport->GetAltitudeError(&altitudeError)))
{
wprintf(L"Altitude Error: %f\n", altitudeError);
}
else
{
// Altitude Error is optional and may not be available
wprintf(L"Altitude Error: Not available.\n");
}
}
}
return S_OK;
}
レポートのステータスが変化したときに呼び出されます。
| reportType | GUID* | in | ステータスが変化したレポート型のインターフェース ID を指定する REFIID。 |
| newStatus | LOCATION_REPORT_STATUS | in | 新しいステータスを表す LOCATION_REPORT_STATUS 列挙型の定数。 |
戻り値
このメソッドが成功した場合は S_OK を返します。それ以外の場合は HRESULT エラーコードを返します。
解説(Remarks)
このイベントは、新しいレポートのレポートステータスを提供します。最新のレポートは、このイベントで報告されるステータスに関係なく、ILocation::GetReport を通じて引き続き利用できます。
例
次は、緯度/経度レポートのステータス変更イベントを処理する OnStatusChanged のサンプル実装です。
// This is called when the status of a report type changes.
// The LOCATION_REPORT_STATUS enumeration is defined in LocApi.h in the SDK
STDMETHODIMP CLocationEvents::OnStatusChanged(REFIID reportType, LOCATION_REPORT_STATUS status)
{
if (IID_ILatLongReport == reportType)
{
switch (status)
{
case REPORT_NOT_SUPPORTED:
wprintf(L"\nNo devices detected.\n");
break;
case REPORT_ERROR:
wprintf(L"\nReport error.\n");
break;
case REPORT_ACCESS_DENIED:
wprintf(L"\nAccess denied to reports.\n");
break;
case REPORT_INITIALIZING:
wprintf(L"\nReport is initializing.\n");
break;
case REPORT_RUNNING:
wprintf(L"\nRunning.\n");
break;
}
}
else if (IID_ICivicAddressReport == reportType)
{
}
return S_OK;
}
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_ILocationEvents "{CAE02BBF-798B-4508-A207-35A7906DC73D}" #usecom global ILocationEvents IID_ILocationEvents "{}" #comfunc global ILocationEvents_OnLocationChanged 3 var,sptr #comfunc global ILocationEvents_OnStatusChanged 4 var,int ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。#define global IID_ILocationEvents "{CAE02BBF-798B-4508-A207-35A7906DC73D}" #usecom global ILocationEvents IID_ILocationEvents "{}" #comfunc global ILocationEvents_OnLocationChanged 3 sptr,sptr #comfunc global ILocationEvents_OnStatusChanged 4 sptr,int ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。