2016-09-28 6 views
9

У меня есть родное приложение C++/MFC, разработанное в VS 2008, без использования .NET, которое я преобразовал в приложение UWP, используя Project Centennial converter. Итак, теперь у меня есть пакет .appx, который работает в Windows 10 v 1607 как приложение UWP.Как получить доступ к пространству имен Windows.Services.Store из приложения Win32, преобразованного в UWP с помощью «Project Centennial converter», чтобы включить покупки в приложении?

Следующей целью является добавление поддержки при покупке приложений перед отправкой в ​​Windows Store.

Вопрос в том, как я могу получить доступ к пространству имен Windows.Services.Store из чистого приложения Win32 из собственного кода на C или C++?

ответ

7

Использование WRL. Вот пример того, как приобрести в 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; 
    } 
} 

Вот как проверить, если приложение на суде:

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); 
} 
+0

Спасибо. Где взять «Windows.Services.Store.h»? – c00000fd

+1

Это в Windows SDK. Он находится на моей машине: «C: \ Program Files (x86) \ Windows Kits \ 10 \ Include \ 10.0.14393.0 \ winrt \ windows.services.store.h". Поскольку API был добавлен только в 14393 SDK, вам нужно будет обновить SDK на своем компьютере, если вы на старом. – Sunius

+0

Ох. ОК. Благодарю. Вот почему у меня его не было. – c00000fd

1

Смотрите здесь: https://msdn.microsoft.com/en-us/library/windows/apps/Windows.Services.Store.StoreContext.aspx

Она гласит:

Примечание. В настольном приложении Windows, использующем Desktop Bridge, вам необходимо авторизоваться. d дополнительный код для настройки объекта StoreContext , прежде чем ваше приложение сможет использовать этот объект. Дополнительные сведения см. В разделе Использование класса StoreContext в настольном приложении, использующем мост рабочего стола. https://msdn.microsoft.com/windows/uwp/monetize/in-app-purchases-and-trials#desktop

0

Со следующими изменениями, это компилируется и работает для меня:

1) #include <utility.h>

2) написать OnCompleted обработчик:

void onCompleted(bool bActiveLicense) 
{ 
//  App has active license or not 
} 

3) Изменение захвата, как следует:

[=, onCompleted{ std::move(onCompleted) }]