如何从使用“Project Centennial 转换器"转换为 UWP 的 Win32 应用程序访问 Windows.Services.Store 命名空间启用应用内购买? [英] How to access Windows.Services.Store namespace from a Win32 app converted to UWP with the "Project Centennial converter" to enable in-app purchases?

查看:30
本文介绍了如何从使用“Project Centennial 转换器"转换为 UWP 的 Win32 应用程序访问 Windows.Services.Store 命名空间启用应用内购买?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个在 VS 2008 中开发的本机 C++/MFC 应用程序,没有 .NET 内容,我使用 Project Centennial 转换器.所以现在我有一个 .appx 包,它作为 UWP 应用在 Windows 10 v 1607 中运行.

I have a native C++/MFC app that is developed in VS 2008, no .NET stuff, that I converted into a UWP app using the Project Centennial converter. So now I have an .appx package that runs in Windows 10 v 1607 as a UWP app.

我的下一个目标是在提交到 Windows 应用商店之前添加应用内购买支持.

My next goal is to add in-app purchase support before submission to Windows Store.

问题是我如何访问 Windows.Services.从原生 C 或 C++ 代码的纯 Win32 应用程序存储命名空间?

The question though is how do I access Windows.Services.Store namespace from a pure Win32 app from a native C or C++ code?

推荐答案

使用 WRL.以下是有关如何购买应用内购买的示例:

Use WRL. Here's an example on how to purchase an in app purchase:

#include <windows.h>
#include <Windows.Services.Store.h>
#include <wrl.h>

using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::Services::Store;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;

#define CheckHr(hr) do { if (FAILED(hr)) __debugbreak(); } while (false)

const wchar_t kItemFriendlyName[] = L"10 coins";
const wchar_t kItemStoreId[] = L"ten_coins";

void OnPurchaseOperationDone(IAsyncOperation<StorePurchaseResult*>* operation, AsyncStatus status);

void Purchase10Coins()
{
    ComPtr<IStoreContextStatics> storeContextStatics;
    auto hr = RoGetActivationFactory(HStringReference(L"Windows.Services.Store.StoreContext").Get(), __uuidof(storeContextStatics), &storeContextStatics);
    CheckHr(hr);

    ComPtr<IStoreContext> storeContext;
    hr = storeContextStatics->GetDefault(&storeContext);
    CheckHr(hr);

    ComPtr<IStorePurchasePropertiesFactory> purchasePropertiesFactory;
    hr = RoGetActivationFactory(HStringReference(L"Windows.Services.Store.StorePurchaseProperties").Get(), __uuidof(purchasePropertiesFactory), &purchasePropertiesFactory);
    CheckHr(hr);

    ComPtr<IStorePurchaseProperties> purchaseProperties;
    hr = purchasePropertiesFactory->Create(HStringReference(kItemFriendlyName).Get(), &purchaseProperties);
    CheckHr(hr);

    ComPtr<IAsyncOperation<StorePurchaseResult*>> purchaseOperation;
    hr = storeContext->RequestPurchaseWithPurchasePropertiesAsync(HStringReference(kItemStoreId).Get(), purchaseProperties.Get(), &purchaseOperation);
    CheckHr(hr);

    // Change the following line to call Callback<IAsyncOperationCompletedHandler<StorePurchaseResult*>> if you want the callback to happen back on the UI thread
    // Implementing FtmBase allows it to fire on the thread the operation finished
    auto onCompletedCallback = Callback<Implements<RuntimeClassFlags<ClassicCom>, IAsyncOperationCompletedHandler<StorePurchaseResult*>, FtmBase>>(
        [](IAsyncOperation<StorePurchaseResult*>* operation, AsyncStatus status)
    {
        OnPurchaseOperationDone(operation, status);
        return S_OK;
    });

    hr = purchaseOperation->put_Completed(onCompletedCallback.Get());
    CheckHr(hr);
}

void OnPurchaseOperationDone(IAsyncOperation<StorePurchaseResult*>* operation, AsyncStatus status)
{
    if (status != AsyncStatus::Completed)
    {
        // It failed for some reason. Find out why.
        ComPtr<IAsyncInfo> asyncInfo;
        auto hr = operation->QueryInterface(__uuidof(asyncInfo), &asyncInfo);
        CheckHr(hr);

        HRESULT errorCode;
        hr = asyncInfo->get_ErrorCode(&errorCode);
        CheckHr(hr);

        // Do something with the errorCode


        // Return once error is handled
        return;
    }

    ComPtr<IStorePurchaseResult> purchaseResult;
    auto hr = operation->GetResults(&purchaseResult);
    CheckHr(hr);

    StorePurchaseStatus purchaseStatus;
    hr = purchaseResult->get_Status(&purchaseStatus);
    CheckHr(hr);

    switch (purchaseStatus)
    {
    case StorePurchaseStatus_Succeeded:
    case StorePurchaseStatus_AlreadyPurchased:
        // Success. Product was purchased
        break;

    case StorePurchaseStatus_NotPurchased:
        // User canceled the purchase
        break;

    case StorePurchaseStatus_NetworkError:
        // The device could not reach windows store
        break;

    case StorePurchaseStatus_ServerError:
        // Something broke on the server
        break;
    }
}

以下是检查应用程序是否处于试用状态的方法:

Here's how to check if application is on trial:

void CheckIsTrial(std::function<void(bool)> onCompleted)
{
    ComPtr<IStoreContextStatics> storeContextStatics;
    auto hr = RoGetActivationFactory(HStringReference(L"Windows.Services.Store.StoreContext").Get(), __uuidof(storeContextStatics), &storeContextStatics);
    CheckHr(hr);

    ComPtr<IStoreContext> storeContext;
    hr = storeContextStatics->GetDefault(&storeContext);
    CheckHr(hr);

    ComPtr<IAsyncOperation<StoreAppLicense*>> getLicenseOperation;
    hr = storeContext->GetAppLicenseAsync(&getLicenseOperation);
    CheckHr(hr);

    hr = getLicenseOperation->put_Completed(Callback<Implements<RuntimeClassFlags<ClassicCom>, IAsyncOperationCompletedHandler<StoreAppLicense*>, FtmBase>>(
        [onCompleted{ std::move(onCompleted) }](IAsyncOperation<StoreAppLicense*>* operation, AsyncStatus status)
    {
        if (status != AsyncStatus::Completed)
        {
            // It failed for some reason. Find out why.
            ComPtr<IAsyncInfo> asyncInfo;
            auto hr = operation->QueryInterface(__uuidof(asyncInfo), &asyncInfo);
            CheckHr(hr);

            HRESULT errorCode;
            hr = asyncInfo->get_ErrorCode(&errorCode);
            CheckHr(hr);

            // Do something with the errorCode

            // Return once error is handled
            return S_OK;
        }

        ComPtr<IStoreAppLicense> appLicense;
        auto hr = operation->GetResults(&appLicense);
        CheckHr(hr);

        boolean isActive, isTrial = false;

        hr = appLicense->get_IsActive(&isActive);
        CheckHr(hr);

        if (isActive)
        {
            hr = appLicense->get_IsTrial(&isTrial);
            CheckHr(hr);
        }

        onCompleted(static_cast<bool>(isActive));
        return S_OK;
    }).Get());
    CheckHr(hr);
}

这篇关于如何从使用“Project Centennial 转换器"转换为 UWP 的 Win32 应用程序访问 Windows.Services.Store 命名空间启用应用内购买?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆