Win32 API 日本語リファレンス
ホームDevices.Geolocation › ILocationEvents

ILocationEvents

COM
IIDcae02bbf-798b-4508-a207-35a7906dc73d継承元IUnknown自前メソッド開始 vtbl3

公式ドキュメント

ILocationEvents は、イベント通知を受け取りたい場合に実装する必要があるコールバックメソッドを提供します。

メソッド 2

vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。

vtbl 3 HRESULT OnLocationChanged(GUID* reportType, ILocationReport* pLocationReport)

新しい位置(ロケーション)レポートが利用可能になったときに呼び出されます。

reportTypeGUID*inpLocationReport に含まれるレポート型のインターフェース ID を格納する REFIID
pLocationReportILocationReport*inoptional新しい位置(ロケーション)レポートを含む ILocationReport インスタンスへのポインター。

戻り値

このメソッドが成功した場合は S_OK を返します。それ以外の場合は HRESULT エラーコードを返します。

解説(Remarks)

ILocationReport は、特定の位置(ロケーション)レポート型の基底インターフェースです。呼び出し元が pLocationReport として受け取る実際のインターフェースは、reportType で指定された型と一致します。

アプリケーションが位置(ロケーション)を初めて使用した結果として OnLocationChanged を呼び出すと、その呼び出しによってタスクバーに通知が表示され、イベントビューアーに Location Activity イベントが記録される場合があります。

Note  次の 2 つの条件がどちらも当てはまる場合、アプリケーションは OnLocationChanged から期待される位置(ロケーション)変更イベントを受け取りません。1 つ目は、アプリケーションが LOCALSERVICE、SYSTEM、または NETWORKSERVICE ユーザーアカウントのコンテキストでサービスとして実行されている場合です。2 つ目は、位置(ロケーション)変更イベントが既定の位置(ロケーション)の変更によって発生した場合です。これは、ユーザーがコントロールパネルで Default Location を選択して手動で変更した場合や、アプリケーションが IDefaultLocation::SetReport を呼び出してプログラムで変更した場合が該当します。
 

次の 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*)&currentTime))
                {
                    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;
}
vtbl 4 HRESULT OnStatusChanged(GUID* reportType, LOCATION_REPORT_STATUS newStatus)

レポートのステータスが変化したときに呼び出されます。

reportTypeGUID*inステータスが変化したレポート型のインターフェース ID を指定する REFIID
newStatusLOCATION_REPORT_STATUSin新しいステータスを表す 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 の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
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 指定が可能。