> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# XStoreQueryAssociatedProductsAsync

> XStoreQueryAssociatedProductsAsync

# XStoreQueryAssociatedProductsAsync

現在のゲーム内からユーザーが購入できる製品のストア登録情報を取得します。

## 構文

```cpp theme={null}
HRESULT XStoreQueryAssociatedProductsAsync(  
         const XStoreContextHandle storeContextHandle,  
         XStoreProductKind productKinds,  
         uint32_t maxItemsToRetrievePerPage,  
         XAsyncBlock* async  
)  
```

### パラメーター

*storeContextHandle*   \_In\_\
Type: XStoreContextHandle

[XStoreCreateContext](/ja-jp/reference/system/xstore/functions/xstorecreatecontext) から返される、ユーザーのストア コンテキスト ハンドル。

*productKinds*   \_In\_\
Type: [XStoreProductKind](/ja-jp/reference/system/xstore/enums/xstoreproductkind)

返す製品の種類。

*maxItemsToRetrievePerPage*   \_In\_\
Type: uint32\_t

1 ページあたりに取得する項目の最大数。
1 ページあたりに返される項目の数は、0 から `maxItemsToRetrievePerPage` まで異なる場合があります。
詳細については、[ページング](#paging)を参照してください。

*async*   \_Inout\_\
Type: [XAsyncBlock\*](/ja-jp/reference/system/xasync/structs/xasyncblock)

実行中の非同期処理を定義する [XAsyncBlock](/ja-jp/reference/system/xasync/structs/xasyncblock)。
[XAsyncBlock](/ja-jp/reference/system/xasync/structs/xasyncblock) を使用して、呼び出しの状態のポーリングと呼び出し結果の取得を行います。
詳細については、[XAsyncBlock](/ja-jp/reference/system/xasync/structs/xasyncblock) を参照してください。

### 戻り値

Type: HRESULT

HRESULT の成功またはエラー コード。

## 解説

この関数のストア登録情報と実行結果を取得するには、この関数を呼び出した後に [XStoreQueryAssociatedProductsResult](/ja-jp/reference/system/xstore/functions/xstorequeryassociatedproductsresult) を呼び出します。
[XStoreQueryAssociatedProductsResult](/ja-jp/reference/system/xstore/functions/xstorequeryassociatedproductsresult) には、[XStoreEnumerateProductsQuery](/ja-jp/reference/system/xstore/functions/xstoreenumerateproductsquery) を呼び出して列挙する `XStoreProductQueryHandle` が含まれます。

このクエリが返す製品の数を事前に知ることはできません。

この API は、ユーザーが Microsoft Store で参照できる、またはゲーム内で購入できる製品のみを返します。
結果には、非表示、期限切れ、またはストアから削除された製品は含まれません。
そのような製品の詳細が必要な場合は、[XStoreQueryProductsAsync](/ja-jp/reference/system/xstore/functions/xstorequeryproductsasync) を使用し、製品のストア ID を渡します。

## ページング

この関数は、複数のページにわたって製品を返します (1 ページに最大 `maxItemsToRetrievePerPage` 個の項目)。
[XStoreProductsQueryHasMorePages](/ja-jp/reference/system/xstore/functions/xstoreproductsqueryhasmorepages) と [XStoreProductsQueryNextPageAsync](/ja-jp/reference/system/xstore/functions/xstoreproductsquerynextpageasync)/[XStoreProductsQueryNextPageResult](/ja-jp/reference/system/xstore/functions/xstoreproductsquerynextpageresult) を使用して、ページング化されたすべての結果を処理します。
ページングは、`XStoreProductsQueryHasMorePages` が false を返すまで完了しません。

> [!NOTE]
>
> ページングは、サンドボックスと RETAIL の間で動作が異なる場合があります。
> サンドボックスでは、項目が `maxItemsToRetrievePerPage` に達するまで蓄積されてからページが返されます。
> RETAIL では、ページあたり 0～1 個の項目が返されるのが一般的です。
>
> この API を使用するすべてのゲームは、リリース前にページングを実装してテストすることが重要です。
>
> サンドボックスでページング動作をテストするには、`maxItemsToRetrievePerPage` を一時的にサンドボックスに公開された製品数より小さい値に設定します。
> ゲームのリリース前に RETAIL でテストするには、パートナー センターの \[価格と提供状況] ページで **\[プライベート対象ユーザーを有効にする]** オプションを使用して製品を公開します。
> ゲームのリリース後に RETAIL でテストするには、パッケージ フライトを使用します。

次のコードは、複数のページにわたる製品クエリ結果を取得する方法を示しています。

リークを避けるため、クエリ ハンドルがページングの再帰処理を通じて確実に受け渡されるようにします。

```cpp theme={null}
struct QueryContext
{
    uint32_t count = 0;  // used to accumulate count of products returned across pages
    XStoreProductQueryHandle handle = nullptr;  // handle to reuse for paged operations
};

void CleanupProductQuery(XAsyncBlock* async)
{
    if (!async) return;

    auto* ctx = static_cast<QueryContext*>(async->context);
    if (ctx)
    {
        if (ctx->handle)
        {
            XStoreCloseProductsQueryHandle(ctx->handle);
            ctx->handle = nullptr;
        }

        delete ctx;
        async->context = nullptr;
    }

    delete async;
}

bool CALLBACK ProductEnumerationCallback(const XStoreProduct* product, void* context)
{
    // Use result of query
    auto* ctx = static_cast<QueryContext*>(context);

    // Empty results are possible and should be skipped
    if (product)
    {
        printf("%s %s %u\n", product->title, product->storeId, product->productKind);
        ctx->count++;
    }

    return true;
}

void CALLBACK QueryAssociatedProductsCallback(XAsyncBlock* async)
{
    auto* ctx = static_cast<QueryContext*>(async->context);

    HRESULT hr = XStoreQueryAssociatedProductsResult(async, &ctx->handle);
    if (FAILED(hr)) { CleanupProductQuery(async); return; }

    hr = XStoreEnumerateProductsQuery(ctx->handle, ctx, ProductEnumerationCallback);
    if (FAILED(hr)) { CleanupProductQuery(async); return; }

    // Check if there are more pages to process
    if (XStoreProductsQueryHasMorePages(ctx->handle))
    {
        QueryNextPage(async);
        return;
    }

    printf("Enumeration complete, %u products found\n", ctx->count);
    CleanupProductQuery(async);
}

void QueryAssociatedProducts(XStoreContextHandle storeContextHandle, XTaskQueueHandle taskQueueHandle)
{
    auto async = new XAsyncBlock{};
    async->context = new QueryContext{ 0, nullptr };
    async->queue = taskQueueHandle;
    async->callback = QueryAssociatedProductsCallback;

    XStoreProductKind typeFilter =
        XStoreProductKind::Consumable |
        XStoreProductKind::Durable |
        XStoreProductKind::Game |
        XStoreProductKind::Pass |
        XStoreProductKind::UnmanagedConsumable;

    HRESULT hr = XStoreQueryAssociatedProductsAsync(
        storeContextHandle,
        typeFilter,
        25,          // Products per page (25 is a good default, can set lower to verify paging in sandbox)
        async);

    if (FAILED(hr))
    {
        CleanupProductQuery(async);
    }
}

// In RETAIL, content will be returned across multiple pages.
// Paging is not complete until XStoreProductsQueryHasMorePages returns false.
void QueryNextPage(XAsyncBlock *async)
{
    async->callback = [](XAsyncBlock* async)
    {
        auto* ctx = static_cast<QueryContext*>(async->context);

        XStoreProductQueryHandle next = nullptr;
        HRESULT hr = XStoreProductsQueryNextPageResult(async, &next);
        if (FAILED(hr)) { CleanupProductQuery(async); return; }

        // Safe swap: avoids leaks if 'next' is a new handle, avoids double-close if identical
        if (next && next != ctx->handle)
        {
            if (ctx->handle) XStoreCloseProductsQueryHandle(ctx->handle);
            ctx->handle = next;
        }
        else
        {
            ctx->handle = next; // covers null or same-handle cases
        }

        hr = XStoreEnumerateProductsQuery(ctx->handle, ctx, ProductEnumerationCallback);
        if (FAILED(hr)) { CleanupProductQuery(async); return; }

        // Check if there are more pages to process
        if (XStoreProductsQueryHasMorePages(ctx->handle))
        {
            QueryNextPage(async);
            return;
        }

        printf("Enumeration complete, %u products found\n", ctx->count);
        CleanupProductQuery(async);
    };

    auto* ctx = static_cast<QueryContext*>(async->context);
    HRESULT hr = XStoreProductsQueryNextPageAsync(ctx->handle, async);
    if (FAILED(hr))
    {
        CleanupProductQuery(async);
    }
}

```

## 要件

**ヘッダー:** XStore.h (XGameRuntime.h に含まれる)

**ライブラリ:** xgameruntime.lib

**サポートされているプラットフォーム:** Windows、XBOX One ファミリ本体、および XBOX Series 本体

## 関連概念ドキュメント

* [ゲームにゲーム内購入を実装する](https://learn.microsoft.com/gaming/gdk/docs/gdk-dev/pc-dev/tutorials/pc-e2e-guide/e2e-services/e2e-in-game-purchases)
* [ストアの基本操作](/ja-jp/publishing/xstore-commerce/xstore-basic-operations)
* [プレイヤーにアドオン コンテンツへのアクセス権を付与する](/ja-jp/publishing/xstore-commerce/xstore-granting-access)
* [GDK コマース システムの概要](/ja-jp/publishing/xstore-commerce/xstore-overview)
* [Microsoft Store API のきめ細かなレート制限](/ja-jp/publishing/xstore-commerce/xstore-fgrl)
* [ストア開発用エンタイトルメント ツール (DevEntitlementTool.exe)](/ja-jp/tools/tools-services/live-dev-entitlements-tool)

## 関連項目

[XStore](/ja-jp/reference/system/xstore/xstore_members)\
[XStoreQueryAssociatedProductsResult](/ja-jp/reference/system/xstore/functions/xstorequeryassociatedproductsresult)\
[XStoreEnumerateProductsQuery](/ja-jp/reference/system/xstore/functions/xstoreenumerateproductsquery)\
[XStoreProductsQueryHasMorePages](/ja-jp/reference/system/xstore/functions/xstoreproductsqueryhasmorepages)\
[XStoreProductsQueryNextPageAsync](/ja-jp/reference/system/xstore/functions/xstoreproductsquerynextpageasync)\
[ストアの基本操作](/ja-jp/publishing/xstore-commerce/xstore-basic-operations)\
[プレイヤーにアドオン コンテンツへのアクセス権を付与する](/ja-jp/publishing/xstore-commerce/xstore-granting-access)


## Related topics

- [XStoreQueryAssociatedProductsResult](/ja-jp/reference/system/xstore/functions/xstorequeryassociatedproductsresult.md)
- [XStoreQueryAssociatedProductsForStoreIdAsync](/ja-jp/reference/system/xstore/functions/xstorequeryassociatedproductsforstoreidasync.md)
- [XStoreQueryProductForPackageAsync](/ja-jp/reference/system/xstore/functions/xstorequeryproductforpackageasync.md)
- [XStoreProductQueryCallback](/ja-jp/reference/system/xstore/functions/xstoreproductquerycallback.md)
- [XStoreEnumerateProductsQuery](/ja-jp/reference/system/xstore/functions/xstoreenumerateproductsquery.md)
