[C++] 225 Visual C++ : ストアアプリ決済画面への遷移 FLTK

[Windows11, Visual C++2017, FLTK 1.3.8, GNU Make 3.81, NO IDE]

ようやく決済画面に遷移できるようになりました。たった十数行のために丸2日掛かりました。

MicrosoftのドキュメントではC#ユーザーに手厚くサポートし、C++ユーザーには仕組みだけ用意して放置です。サンプルコードが圧倒的に不足しています。

結局、Windows kitsにあるcppwinrtのbase.h(約9000行)から必要な関数を自分で探し出しました。

あとStackOverFlow英語版にまたもや助けられました。ここの情報がなかったらもう数日遅れていたでしょう。

次はアドオンの中身を実装してストアに申請し、決済などの検証を行います。

アドオンを登録していないのでMicrosoftログインから先には進めない
アプリ本体(無料)の製品IDで決済画面を呼び出した場合
#include "AddOnPurchase.h"
#include "AddOnDialog.h"
#include <unknwn.h>
#include <iostream>
#include <string>
#include <vector>
#include <winrt/Windows.Services.Store.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <ppltasks.h>
#include <shobjidl.h>

using std::cout; using std::endl;
using std::vector; using std::string;

using namespace winrt;
using namespace winrt::Windows::Services::Store;
using namespace winrt::Windows::Foundation::Collections;
// using namespace winrt::Windows::Foundation; エラーの原因 このnamespaceは使わないこと
using namespace concurrency;
using namespace winrt::impl;

extern vector<string> AddOnLabels;

AddOnPurchase::AddOnPurchase(int w, int h, const char* title)
    : Fl_Window(w, h, title) {

    int ws1, hs1, ws2, hs2; 
    int xs1, ys1, xs2, ys2;

    // ボタンのサイズと位置
    ws1 = 100; hs1 = 50;
    ws2 = 100; hs2 = 50;
    xs1 = 150; ys1 = 390;
    xs2 = 350; ys2 = 390;

    this->color(fl_rgb_color(238, 238, 238));

    // 説明画像
    Fl_Box* img_box = new Fl_Box(20, 12, 560, 360);
    string img_path = "AddOnDescribe.png";
    Fl_PNG_Image *png = new Fl_PNG_Image(img_path.c_str());
    img_box -> image(png);
    img_box -> redraw();

    // Purchaseボタン
    Fl_Button* md_button = new Fl_Button(xs1, ys1, ws1, hs1, AddOnLabels[4].c_str());
    md_button->parent(this);
    md_button->callback(PushButtonPurchase, this);
    md_button->down_box(FL_UP_BOX);
    md_button->labelsize(14);

    // QUITボタン
    Fl_Button* md_button2 = new Fl_Button(xs2, ys2, ws2, hs2, "QUIT");
    md_button2->parent(this);
    md_button2->callback(PushButtonQuit, this);
    md_button2->down_box(FL_UP_BOX);
    md_button2->labelsize(14);

    resizable(this);
    end();
}

AddOnPurchase::~AddOnPurchase()
{
}

void AddOnPurchase::PushButtonPurchase(Fl_Widget* widget, void* x)
{
    Fl_Group* window = widget->parent();
    window->hide();

	// StoreContext取得
    StoreContext _storeContext = StoreContext::GetDefault();

	// StoreContext を IInitializeWithWindow へキャストする
	IInitializeWithWindow* initWithWindow;
	winrt::Windows::Foundation::IInspectable* inspect = reinterpret_cast<winrt::Windows::Foundation::IInspectable*>(&_storeContext);
	HRESULT hr = inspect -> as(IID_PPV_ARGS(&initWithWindow));

	// Fl_Windowのハンドラを決済画面に渡す
	if (!FAILED(hr)){
		extern Fl_Window* window;
        initWithWindow->Initialize((HWND)fl_xid(window));
        initWithWindow->Release();
    } else {
		return;
	}
        
	// 購入手続
	winrt::Windows::Foundation::IAsyncOperation<StorePurchaseResult> _StorePurchaseResult = _storeContext.RequestPurchaseAsync(L"製品ID");
}

void AddOnPurchase::PushButtonQuit(Fl_Widget* widget, void* x)
{
    Fl_Group* window = widget->parent();
    window->hide();
}

参考サイト1
参考サイト2(StackOverFlow英語版)