我正在使用Flutter Method Channel开发一个Windows桌面应用,遇到了应用内购买功能的问题。当触发时,购买模式对话框出现在主应用窗口后面,使其不可见。
事情是这样的:
1.通过点击按钮启动应用内购买。
1.应用内购买弹出窗口在应用主窗口后面启动,使其不可见(如第一张图所示)。
1.当RequestPurchaseAsync
在UI线程上运行时,应用程序变得无响应,这是预期的。
1.关闭应用程序后,我可以看到弹出窗口打开,它仍然是互动的(参考第二张图片)。
使用BringWindowToTop(hwnd)
和SetForegroundWindow(hwnd)
的尝试没有成功,因为它们会影响整个应用程序,而不仅仅是弹出窗口。
我正在寻求一个解决方案,使应用程序内购买弹出窗口的最前沿,但我的C++和Win32的知识是相当有限的。
的数据
的
#include <Unknwn.h>
#include <flutter/event_channel.h>
#include <flutter/event_sink.h>
#include <flutter/event_stream_handler_functions.h>
#include <flutter/method_channel.h>
#include <flutter/standard_method_codec.h>
#include <winrt/Windows.Services.Store.h>
#include <winrt/Windows.Foundation.h>
#include <windows.h>
#include <memory>
#include <optional>
#include <string>
#include <future>
#include <shobjidl.h>
#include "flutter_window.h"
#include "flutter/generated_plugin_registrant.h"
using namespace winrt;
using namespace Windows::Services::Store;
std::string store_id = "ABCDEFASD";
std::string success_key = "SUCCESS";
StoreContext storeContext = StoreContext::GetDefault();
FlutterWindow::FlutterWindow(const flutter::DartProject& project)
: project_(project) {}
FlutterWindow::~FlutterWindow() {}
std::string upgrade() {
if (!storeContext) {
return "storeContext not initialized";
}
// Retrieve the IInitializeWithWindow interface from the StoreContext
auto initWindow = storeContext.as<IInitializeWithWindow>();
// Get the current process main window handle
HWND hwnd = GetActiveWindow();
// Initialize the StoreContext with the window handle
initWindow->Initialize(hwnd);
try {
std::future<StorePurchaseResult> purchaseTask = std::async(std::launch::async, [&]() {
return storeContext.RequestPurchaseAsync(winrt::to_hstring(store_id)).get();
});
StorePurchaseResult result = purchaseTask.get();
if (result.ExtendedError().value != S_OK) {
return "ExtendedError";
}
switch (result.Status())
{
case StorePurchaseStatus::Succeeded:
return success_key;
case StorePurchaseStatus::AlreadyPurchased:
return "Already Purchased";
case StorePurchaseStatus::NotPurchased:
return "Purchase Not Completed";
case StorePurchaseStatus::NetworkError:
return "Network Error";
case StorePurchaseStatus::ServerError:
return "Server Error";
default:
return "Unknown Error";
}
}
catch (const winrt::hresult_error& ex) {
auto errorMessage = winrt::to_string(ex.message());
return "Exception: " + errorMessage;
}
catch (const std::exception& ex) {
return "Exception: " + std::string(ex.what());
}
}
bool FlutterWindow::OnCreate() {
if (!Win32Window::OnCreate()) {
return false;
}
RECT frame = GetClientArea();
// The size here must match the window dimensions to avoid unnecessary surface
// creation / destruction in the startup path.
flutter_controller_ = std::make_unique<flutter::FlutterViewController>(
frame.right - frame.left, frame.bottom - frame.top, project_);
// Ensure that basic setup of the controller was successful.
if (!flutter_controller_->engine() || !flutter_controller_->view()) {
return false;
}
RegisterPlugins(flutter_controller_->engine());
// Method Channel
flutter::MethodChannel<> channel(
flutter_controller_->engine()->messenger(), "method.channel.id",
&flutter::StandardMethodCodec::GetInstance());
channel.SetMethodCallHandler(
[](const flutter::MethodCall<>& call,
std::unique_ptr<flutter::MethodResult<>> result) {
if (call.method_name() == "purchase") {
std::string purchaseResult = upgrade();
if (purchaseResult == success_key) {
result->Success();
}
else {
result->Error("ERROR", purchaseResult);
}
}
else {
result->NotImplemented();
}
});
SetChildContent(flutter_controller_->view()->GetNativeWindow());
flutter_controller_->engine()->SetNextFrameCallback([&]() {
this->Show();
});
// Flutter can complete the first frame before the "show window" callback is
// registered. The following call ensures a frame is pending to ensure the
// window is shown. It is a no-op if the first frame hasn't completed yet.
flutter_controller_->ForceRedraw();
return true;
}
void FlutterWindow::OnDestroy() {
if (flutter_controller_) {
flutter_controller_ = nullptr;
}
Win32Window::OnDestroy();
}
LRESULT
FlutterWindow::MessageHandler(HWND hwnd, UINT const message,
WPARAM const wparam,
LPARAM const lparam) noexcept {
// Give Flutter, including plugins, an opportunity to handle window messages.
if (flutter_controller_) {
std::optional<LRESULT> result =
flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam,
lparam);
if (result) {
return *result;
}
}
switch (message) {
case WM_FONTCHANGE:
flutter_controller_->engine()->ReloadSystemFonts();
break;
}
return Win32Window::MessageHandler(hwnd, message, wparam, lparam);
}
字符串
1条答案
按热度按时间fcwjkofz1#
经过几个小时的努力,我终于找到了一个解决方案。下面的代码有效地显示了应用程序内购买弹出窗口的中心,并确保它是突出的前景。
使用前:
字符串
之后:
型