HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2024
0324
GENKILocation API(COM)を使えるようになりたい6解決


GENKI

リンク

2024/3/24(Sun) 15:16:26|NO.101448

この掲示板で、「Windows11で位置情報(GPS緯度経度)を取得したい」 https://hsp.tv/play/pforum.php?mode=all&num=101431 の書き込みを見て調べていたのですが、どうやらcom(Win32 Location API)を使って緯度経度を取得できるようです。使い方を調べていたのですが、動にも行き詰ってしまったので質問に来ました。

というわけで改めまして「Win32 Location API(COMコンポーネント)」を使って現在の緯度経度を取得したいのですが行き詰ってしまいました。どなたか教えてください。
また、せっかくなのでHSP3でcomも使えるようになりたいので、HSPのCOMオブジェクト操作命令を使った方法で解決したいと考えています。Powershell、Windows.Devices.Geolocation、System.Device.Locationなどの利用は、無しの方向で(新規スレッド立てる方向で)お願いします。


まずは、現状の説明から。
私は今までCOMは避けていたので、こちらのサイトとHSPのマニュアルを参考にいろいろと試していますがうまくいっていません。HSP2時代の古いものですが、こちらのサイト以上に詳しいサイトを見つけることができませんでした。他にいいサイトがあれば知りたいです。

HSPからのCOM操作 - ちょくとのページ
https://chokuto.ifdef.jp/urawaza/com/index.html
IID Explorerは入手できないので、COMView https://www.japheth.de/COMView.html を参考に作業しています。OLE/COM オブジェクト ビューア https://learn.microsoft.com/en-us/windows/win32/com/ole-com-object-viewer も試してみたのですがこちらはよくわからずでした。

HSP3.7 プログラミング・マニュアル 4.10 COMコンポーネント呼び出し
https://www.onionsoft.net/hsp/v37/doclib/hspprog.htm#COM_COMPONENT

使用しようとしているCOMコンポーネントはこちら。

Location API - Microsoft
https://learn.microsoft.com/ja-jp/windows/win32/api/_winlocation/


とりあえずCLSIDとIID、使いたいメソッドが必要らいしので調べました。GUIDは、locationapi.hから抽出しています。

#define CLSID_Location "{E5B8E079-EE6D-4E33-A438-C87F2E959254}" #define CLSID_DefaultLocation "{8B7FBFE0-5CD7-494a-AF8C-283A65707506}" #define CLSID_LatLongReport "{ED81C073-1F84-4ca8-A161-183C776BC651}" #define CLSID_CivicAddressReport "{D39E7BDD-7D05-46b8-8721-80CF035F57D7}" #define IID_ICivicAddressReport "{C0B19F70-4ADF-445d-87F2-CAD8FD711792}" #define IID_IDefaultLocation "{A65AF77E-969A-4a2e-8ACA-33BB7CBB1235}" #define IID_ILatLongReport "{7FED806D-0EF8-4f07-80AC-36A0BEAE3134}" #define IID_ILocation "{AB2ECE69-56D9-4F28-B525-DE1B0EE44237}" #define IID_ILocationEvents "{CAE02BBF-798B-4508-A207-35A7906DC73D}" #define IID_ILocationPower "{193E7729-AB6B-4b12-8617-7596E1BB191C}" #define IID_ILocationReport "{C8B7F7EE-75D0-4db9-B62D-7A0F369CA456}"
あとは、ILatLongReportインターフェイスのメソッドを使えば緯度経度が出てくるはず。
ILatLongReport::GetLatitude 緯度
ILatLongReport::GetLongitude 経度
ちなみにProgIDは、"LocationApi"のようです。


以上を踏まえて、試してみたのがこちら。

#define IID_ILatLongReport "{7FED806D-0EF8-4f07-80AC-36A0BEAE3134}" newcom LocationApi, "LocationApi" mes stat querycom laLLRpt, LocationApi, IID_ILatLongReport mes stat comres res laLLRpt->"GetLatitude" lat ; #Error 39 -->外部オブジェクトの呼び出しに失敗しました ;LocationApi->"GetLatitude" lat ; 警告なしで終了
変数latに緯度を取得するつもりで書いたものです。GPSが搭載されていないパソコンでも、設定された既定の場所が表示されるはず?
オブジェクトの作成まではうまくいっているようですが、最後の2行のどちらを試してもエラーか強制終了するだけで期待通り動作しませんでした。

エラーは出てないけど、querycomの使い方間違ってるのかなと、次に試したのがこちら。

#define CLSID_LatLongReport "{ED81C073-1F84-4ca8-A161-183C776BC651}" #define IID_ILatLongReport "{7FED806D-0EF8-4f07-80AC-36A0BEAE3134}" #usecom ID_ILatLongReport IID_ILatLongReport CLSID_LatLongReport newcom laLLRpt, ID_ILatLongReport mes stat ; エラー ;comres res ;laLLRpt->"GetLatitude" lat ; #Error 39 -->外部オブジェクトの呼び出しに失敗しました ;LocationApi->"GetLatitude" lat ; #Error 21 -->サポートされない機能を選択しました
こちらはオブジェクト作成時にエラーとなりました。何も間違っている気がしないのですが、何かを間違えているようです。

そして、もしかしてILatLongReport::GetLatitudeを使う前にILocation::GetReportを使わないといけない?などと考えてあがいてみたのがこちら。

#define CLSID_Location "{E5B8E079-EE6D-4E33-A438-C87F2E959254}" #define IID_ILocation "{AB2ECE69-56D9-4F28-B525-DE1B0EE44237}" #define CLSID_LatLongReport "{ED81C073-1F84-4ca8-A161-183C776BC651}" #define IID_ILatLongReport "{7FED806D-0EF8-4f07-80AC-36A0BEAE3134}" newcom LocationApi, "LocationApi" mes stat querycom laL, LocationApi, IID_ILocation mes stat ;#usecom ID_ILocation IID_ILocation CLSID_Location ;newcom laL, ID_ILocation ;mes stat querycom laLLRpt, LocationApi, IID_ILatLongReport mes stat comres res mcall laL, "GetReport", IID_ILatLongReport, laLLRpt ;#Error 30 -->無効な名前がパラメーターに指定されています
という感じでエラーとなります。
#comfuncを使えば解決するのかな?とも考えたのですが、メソッドのインデックスをどこでどう調べればいいかわからずという状況です。

どこを間違えているのかわからず、そもそも何かを理解してないのか、次の手段がなくお手上げとなっています。
エラーが出る原因と対策法方法について、どなたか教えていただけないでしょうか。



この記事に返信する


TOMATO

リンク

2024/3/24(Sun) 17:42:59|NO.101451

参考になりそうなので貼っておきます。

>メソッドのインデックスをどこでどう調べればいいかわからず

HSP3のCOMのメソッドインデックスの取得方法
https://www.hinekure.net/dotou_hsp/hsp3x/COMMethodIndex.htm



GENKI

リンク

2024/3/24(Sun) 19:13:27|NO.101453

ありがとうございます。紹介していただいたサイトを見てきました。IID_IShellLinkAは、ShObjIdl_core.hに見つけることができ、手順を確認できました。
早速locationapi.hでも同様の手順で調べてみました。ICivicAddressReportとILatLongReportはILocationReportから継承しているのでそこだけ注意ですね。

#define QueryInterface 0 #define AddRef 1 #define Release 2 #define IDefaultLocation_SetReport 3 #define IDefaultLocation_GetReport 4 #define ILocation_RegisterForReport 3 #define ILocation_UnregisterForReport 4 #define ILocation_GetReport 5 #define ILocation_GetReportStatus 6 #define ILocation_GetReportInterval 7 #define ILocation_SetReportInterval 8 #define ILocation_GetDesiredAccuracy 9 #define ILocation_SetDesiredAccuracy 10 #define ILocation_RequestPermissions 11 #define ILocationEvents_OnLocationChanged 3 #define ILocationEvents_OnStatusChanged 4 #define ILocationPower_Connect 3 #define ILocationPower_Disconnect 4 #define ILocationReport_GetSensorID 3 #define ILocationReport_GetTimestamp 4 #define ILocationReport_GetValue 5 #define ICivicAddressReport_GetSensorID 3 #define ICivicAddressReport_GetTimestamp 4 #define ICivicAddressReport_GetValue 5 #define ICivicAddressReport_GetAddressLine1 6 #define ICivicAddressReport_GetAddressLine2 7 #define ICivicAddressReport_GetCity 8 #define ICivicAddressReport_GetStateProvince 9 #define ICivicAddressReport_GetPostalCode 10 #define ICivicAddressReport_GetCountryRegion 11 #define ICivicAddressReport_GetDetailLevel 12 #define ILatLongReport_GetSensorID 3 #define ILatLongReport_GetTimestamp 4 #define ILatLongReport_GetValue 5 #define ILatLongReport_GetLatitude 6 #define ILatLongReport_GetLongitude 7 #define ILatLongReport_GetErrorRadius 8 #define ILatLongReport_GetAltitude 9 #define ILatLongReport_GetAltitudeError 10
これで一つ試せる手段が出来ました。



GENKI

リンク

2024/3/24(Sun) 19:35:02|NO.101454

メソッドのインデックスが分かったので、#comfuncを試してみました。上手くいかない…。

#define CLSID_LatLongReport "{ED81C073-1F84-4ca8-A161-183C776BC651}" #define IID_ILatLongReport "{7FED806D-0EF8-4f07-80AC-36A0BEAE3134}" #define ILatLongReport_GetLatitude 6 newcom LocationApi, "LocationApi" querycom laLLRpt, LocationApi, IID_ILatLongReport #usecom ID_ILatLongReport IID_ILatLongReport CLSID_LatLongReport #comfunc GetLatitude ILatLongReport_GetLatitude var mes stat lat = 0.0 GetLatitude laLLRpt, lat ;GetLatitude LocationApi, lat ; #Error 39 -->外部オブジェクトの呼び出しに失敗しました



TOMATO

リンク

2024/3/24(Sun) 19:46:17|NO.101455

Location APIはWindows 10や11では動作しない可能性が高そうです。
Microsoftのサンプルプログラム(C++)にLocation APIを使ったものがあるのですが、
Windows 10や11では「No devices detected.」となってしまいました。
Windows 7の環境を用意して動作させたところ、緯度,経度がきちんと表示されました。
https://github.com/microsoft/Windows-classic-samples/tree/main/Samples/LocationSynchronousAccess/cpp

検証に使用したGPSデバイスとドライバは以下です。
GPS-353
https://www.amazon.co.jp/gp/product/B071R6T9V3

ubloxGnss_sensorDeviceDriver_windows_3264_v2.40.exe
https://web.archive.org/web/20200421154628/https://www.u-blox.com/en/ubx-viewer/view/ubloxGnss_sensorDeviceDriver_windows_3264_v2.40.exe?url=https%3A%2F%2Fwww.u-blox.com%2Fsites%2Fdefault%2Ffiles%2FubloxGnss_sensorDeviceDriver_windows_3264_v2.40.exe



TOMATO

リンク

2024/3/24(Sun) 21:09:10|NO.101457

C++のサンプルコードからHSPに移植してみました。
https://github.com/microsoft/Windows-classic-samples/tree/main/Samples/LocationSynchronousAccess/cpp

エラー処理,開放系などは端折っている箇所があります。


#uselib "Rpcrt4.dll" #func UuidToString "UuidToStringA" var, var #func RpcStringFree "RpcStringFreeA" var #define CLSID_Location "{E5B8E079-EE6D-4E33-A438-C87F2E959254}" #define IID_ILocation "{AB2ECE69-56D9-4F28-B525-DE1B0EE44237}" #usecom ILocation IID_ILocation CLSID_Location #comfunc ILocation_GetReport 5 int,var #comfunc ILocation_GetReportStatus 6 int,var #comfunc ILocation_RequestPermissions 11 int,int,int,int #define IID_ILocationReport "{C8B7F7EE-75D0-4db9-B62D-7A0F369CA456}" #define CLSID_LatLongReport "{ED81C073-1F84-4ca8-A161-183C776BC651}" #usecom ILocationReport IID_ILocationReport CLSID_LatLongReport #comfunc ILocationReport_GetSensorID 3 var #define IID_ILatLongReport "{7FED806D-0EF8-4f07-80AC-36A0BEAE3134}" #usecom ILatLongReport IID_ILatLongReport CLSID_LatLongReport #comfunc ILatLongReport_GetSensorID 3 var #comfunc ILatLongReport_GetLatitude 6 var #comfunc ILatLongReport_GetLongitude 7 var #enum LOCATION_REPORT_STATUS_REPORT_NOT_SUPPORTED = 0 #enum LOCATION_REPORT_STATUS_REPORT_ERROR = 1 #enum LOCATION_REPORT_STATUS_REPORT_ACCESS_DENIED = 2 #enum LOCATION_REPORT_STATUS_REPORT_INITIALIZING = 3 #enum LOCATION_REPORT_STATUS_REPORT_RUNNING = 4 IID_ILatLongReport_BIN = 0x7FED806D, 0x4f070EF8, 0xA036AC80, 0x3431AEBE IID_ILatLongReport_PTR = varptr(IID_ILatLongReport_BIN) newcom pLocation, ILocation ILocation_RequestPermissions pLocation, hwnd, IID_ILatLongReport_PTR, 1, 1/*TRUE*/ if (stat < 0) : mes "Warning: Unable to request permissions." status = LOCATION_REPORT_STATUS_REPORT_NOT_SUPPORTED ILocation_GetReportStatus pLocation, IID_ILatLongReport_PTR, status if (stat >= 0) { fCachedData = 1/*TRUE*/ switch status case LOCATION_REPORT_STATUS_REPORT_RUNNING fCachedData = 0 swbreak case LOCATION_REPORT_STATUS_REPORT_NOT_SUPPORTED mes "No devices detected." swbreak case LOCATION_REPORT_STATUS_REPORT_ERROR mes "Report error." swbreak case LOCATION_REPORT_STATUS_REPORT_ACCESS_DENIED mes "Access denied to reports." swbreak case LOCATION_REPORT_STATUS_REPORT_INITIALIZING mes "Report is initializing." swbreak swend if (1/*TRUE*/ == fCachedData) { mes "The following is cached data:" } } ppLocationReport = 0 ILocation_GetReport pLocation, IID_ILatLongReport_PTR, ppLocationReport if (stat >= 0) { newcom pLocationReport, ILocationReport, -1, ppLocationReport querycom pLatLongReport, pLocationReport, ILatLongReport // Print the Sensor ID GUID dim sensorID, 4 ILocationReport_GetSensorID pLatLongReport, sensorID if (stat >= 0) { pStrSensorID = 0 UuidToString sensorID, pStrSensorID dupptr sensorID_STR, pStrSensorID, 39, vartype("str") mes "SensorID: " + sensorID_STR RpcStringFree pStrSensorID } // Print the Latitude latitude = 0.0 ILatLongReport_GetLatitude pLatLongReport, latitude if (stat >= 0) { mes "Latitude: " + latitude } // Print the Longitude longitude = 0.0 ILatLongReport_GetLongitude pLatLongReport, longitude if (stat >= 0) { mes "Longitude: " + longitude } }



GENKI

リンク

2024/3/24(Sun) 21:59:05|NO.101458

ありがとうございます。
こちらでもステータス0「No devices detected.(デバイスが検出されませんでした。)」が出ました。
Windows10環境ではもうLocation APIは、使えないみたいですね。
Microsoftのマニュアルに反映しててほしかった…。

ということで、Location APIはWindows10以降は使えないということでこのスレは解決とします。



記事削除

記事NO.パスワード
(質問が解決したスレッドは他の利用者に活用してもらうため、削除しないようお願いします)

NO.101448への返信

マスコット

好きなマスコットを選んでください。

名前

e-mail
HOME
  1. 初めて利用する方は、HSP3掲示板の使い方をお読みください。
  2. 不要部分の多い長いスクリプトの投稿は ご遠慮ください。
  3. 書き込みは自動改行されません。適度に改行を入れてください。
  4. スクリプトは小文字の<pre>〜</pre>で囲むと見やすく表示できます。

削除用パスワード

解決したら質問者本人がここをチェックしてください。

エラー発生時、再送信すると二重送信になることがあります。
回答が得られたら、お礼書き込み時に[解決]チェックしてください。
SPAM防止のためURLから始まる文章は投稿できません。
SPAM防止のため英文字のみの本文を投稿することはできません。

ONION software Copyright 1997-2023(c) All rights reserved.