Flutter平台通道在Windows上

huangapple go评论67阅读模式
英文:

Flutter platform-channel on windows

问题

以下是您要翻译的内容:

"I need to access Windows Desktop API to change network settings. I have read flutter document and experiences with flutter platform channel. When I ran the code, I just got true in output, but I expect receiving string message from host.

Any help would be appreciated.

windows/runner/flutter_windows.cpp file

#include "flutter_window.h"

#include <optional>
#include "flutter/generated_plugin_registrant.h"

#include <flutter/binary_messenger.h>
#include <flutter/standard_method_codec.h>
#include <flutter/method_channel.h>
#include <flutter/method_result_functions.h>

#include <iostream>
using namespace std;

FlutterWindow::FlutterWindow(const flutter::DartProject& project)
    : project_(project) {}

FlutterWindow::~FlutterWindow() {}
void initMethodChannel(flutter::FlutterEngine* flutter_instance) {
    const static std::string channel_name("test_channel");
    flutter::BinaryMessenger *messenger = FlEngine->messenger();
    const flutter::StandardMethodCodec *codec = &flutter::StandardMethodCodec::GetInstance();
    auto channel = std::make_unique<flutter::MethodChannel<>>(messenger ,channel_name ,codec);

    auto channel =
        std::make_unique<flutter::MethodChannel<>>(
            flutter_instance->messenger(), channel_name,
            &flutter::StandardMethodCodec::GetInstance());

        channel->SetMethodCallHandler(
            [](const flutter::MethodCall<>& call,
        std::unique_ptr<flutter::MethodResult<>> result) {

                // check method name called from dart
                if (call.method_name().compare("test") == 0) {
                // do what ever you want
                res = flutter::EncodableValue("Channel is working!");
                result->Success(res);
                }
                else {
                    result->NotImplemented();
                }
            }
        );
 }
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());
  initMethodChannel(flutter_controller_->engine());
  SetChildContent(flutter_controller_->view()->GetNativeWindow());

  flutter_controller_->engine()->SetNextFrameCallback([&]() {
    this->Show();
  });

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

调用dart中的平台和方法通道

MethodChannel channel = const MethodChannel('test_channel');
print(await channel.invokeMethod("test"));

输出

flutter: true

但期望在输出中获得 Channel is working!。"

英文:

I need to access Windows Desktop API to change network settings. I have read flutter document and experiences with flutter platform channel. When I ran the code, I just got true in output, but I expect receiving string message from host.

Any help would be appreciated.

windows/runner/flutter_windows.cpp file

#include "flutter_window.h"
#include <optional>
#include "flutter/generated_plugin_registrant.h"
#include <flutter/binary_messenger.h>
#include <flutter/standard_method_codec.h>
#include <flutter/method_channel.h>
#include <flutter/method_result_functions.h>
#include <iostream>
using namespace std;
FlutterWindow::FlutterWindow(const flutter::DartProject& project)
: project_(project) {}
FlutterWindow::~FlutterWindow() {}
void initMethodChannel(flutter::FlutterEngine* flutter_instance) {
const static std::string channel_name("test_channel");
flutter::BinaryMessenger *messenger = FlEngine->messenger();
const flutter::StandardMethodCodec *codec = &flutter::StandardMethodCodec::GetInstance();
auto channel = std::make_unique<flutter::MethodChannel<>>(messenger ,channel_name ,codec);
auto channel =
std::make_unique<flutter::MethodChannel<>>(
flutter_instance->messenger(), channel_name,
&flutter::StandardMethodCodec::GetInstance());
channel->SetMethodCallHandler(
[](const flutter::MethodCall<>& call,
std::unique_ptr<flutter::MethodResult<>> result) {
// check method name called from dart
if (call.method_name().compare("test") == 0) {
// do what ever you want
res = flutter::EncodableValue("Channel is working!");
result->Success(res);
}
else {
result->NotImplemented();
}
}
);
}
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());
initMethodChannel(flutter_controller_->engine());
SetChildContent(flutter_controller_->view()->GetNativeWindow());
flutter_controller_->engine()->SetNextFrameCallback([&]() {
this->Show();
});
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);
}

Calling the platform and method channel in dart

MethodChannel channel = const MethodChannel('test_channel');
print(await channel.invokeMethod("test"));

Output

flutter: true

But expect getting Channel is working! in the output.

答案1

得分: 0

flutter_window.cpp 文件中存在一些错误:

1- 缺少头文件引用

我在文件顶部添加了这些头文件:

> + #include <string>
> + #include <flutter/encodable_value.h>
> + #include <../standard_codec.cc>
> + #include "windows.h"
> + #include "windef.h"
> + #include "windowsx.h"

并删除了这些头文件:

> - #include <iostream>
> - 使用命名空间 std;

2- 重复的 channel 声明:

在这种情况下,我需要这样声明:

auto channel = std::make_unique<flutter::MethodChannel<>>(messenger ,channel_name ,codec);

3- 未定义的 res 变量:

在使用之前,只需像下面这样定义它:

flutter::EncodableValue res;
res = flutter::EncodableValue("pass result here");
result->Success(res);

经过所有这些更改,它可以正常工作。

最终的 flutter_window.cpp 文件如下所示:

#include "flutter_window.h"
#include <optional>
#include "flutter/generated_plugin_registrant.h"
#include <string>
#include <flutter/binary_messenger.h>
#include <flutter/standard_method_codec.h>
#include <flutter/method_channel.h>
#include <flutter/method_result_functions.h>
#include <flutter/encodable_value.h>
#include <../standard_codec.cc>
#include "windows.h"
#include "windef.h"
#include "windowsx.h"
FlutterWindow::FlutterWindow(const flutter::DartProject& project)
: project_(project) {}
FlutterWindow::~FlutterWindow() {}
void initMethodChannel(flutter::FlutterEngine* flutter_instance) {
const static std::string channel_name("test");
flutter::BinaryMessenger* messenger = flutter_instance->messenger();
const flutter::StandardMethodCodec* codec = &flutter::StandardMethodCodec::GetInstance();
auto channel = std::make_unique<flutter::MethodChannel<>>(messenger ,channel_name ,codec);
channel->SetMethodCallHandler(
[](const flutter::MethodCall<>& call,
std::unique_ptr<flutter::MethodResult<>> result) {
// 检查从 Dart 调用的方法名
if (call.method_name().compare("test") == 0) {
// 做你想做的事情
flutter::EncodableValue res;
res = flutter::EncodableValue("pass result here");
result->Success(res);
}
else {
result->NotImplemented();
}
}
);
}
bool FlutterWindow::OnCreate() {
if (!Win32Window::OnCreate()) {
return false;
}
RECT frame = GetClientArea();
// 这里的大小必须与窗口尺寸相匹配,以避免在启动路径中不必要的表面创建/销毁。
flutter_controller_ = std::make_unique<flutter::FlutterViewController>(
frame.right - frame.left, frame.bottom - frame.top, project_);
// 确保控制器的基本设置成功。
if (!flutter_controller_->engine() || !flutter_controller_->view()) {
return false;
}
RegisterPlugins(flutter_controller_->engine());
initMethodChannel(flutter_controller_->engine());
SetChildContent(flutter_controller_->view()->GetNativeWindow());
flutter_controller_->engine()->SetNextFrameCallback([&]() {
this->Show();
});
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 {
// 让 Flutter,包括插件,有机会处理窗口消息。
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);
}

> 祝编码愉快!

英文:

There were some errors in the flutter_window.cpp file:

1- Missing Header Inclusion

I added these headers at the top of the file:

> + #include <string>
> + #include <flutter/encodable_value.h>
> + #include <../standard_codec.cc>
> + #include "windows.h"
> + #include "windef.h"
> + #include "windowsx.h"

And removed these headers:

> - #include &lt;iostream&gt;
> - using namespace std;

2- Duplicated channel declaration:

This is what I need in this situation:

auto channel = std::make_unique&lt;flutter::MethodChannel&lt;&gt;&gt;(messenger ,channel_name ,codec);

3- Undefined res variable:

just defined it as below, before using it:

flutter::EncodableValue res;
res = flutter::EncodableValue(&quot;pass result here&quot;);
result-&gt;Success(res);

After all of those changes, It got working fine.

The final flutter_window.cpp file is like that:

#include &quot;flutter_window.h&quot;
#include &lt;optional&gt;
#include &quot;flutter/generated_plugin_registrant.h&quot;
#include &lt;string&gt;
#include &lt;flutter/binary_messenger.h&gt;
#include &lt;flutter/standard_method_codec.h&gt;
#include &lt;flutter/method_channel.h&gt;
#include &lt;flutter/method_result_functions.h&gt;
#include &lt;flutter/encodable_value.h&gt;
#include &lt;../standard_codec.cc&gt;
#include &quot;windows.h&quot;
#include &quot;windef.h&quot;
#include &quot;windowsx.h&quot;
FlutterWindow::FlutterWindow(const flutter::DartProject&amp; project)
: project_(project) {}
FlutterWindow::~FlutterWindow() {}
void initMethodChannel(flutter::FlutterEngine* flutter_instance) {
const static std::string channel_name(&quot;test&quot;);
flutter::BinaryMessenger* messenger = flutter_instance-&gt;messenger();
const flutter::StandardMethodCodec* codec = &amp;flutter::StandardMethodCodec::GetInstance();
auto channel = std::make_unique&lt;flutter::MethodChannel&lt;&gt;&gt;(messenger ,channel_name ,codec);
channel-&gt;SetMethodCallHandler(
[](const flutter::MethodCall&lt;&gt;&amp; call,
std::unique_ptr&lt;flutter::MethodResult&lt;&gt;&gt; result) {
// check method name called from dart
if (call.method_name().compare(&quot;test&quot;) == 0) {
// do what ever you want
flutter::EncodableValue res;
res = flutter::EncodableValue(&quot;pass result here&quot;);
result-&gt;Success(res);
}
else {
result-&gt;NotImplemented();
}
}
);
}
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&lt;flutter::FlutterViewController&gt;(
frame.right - frame.left, frame.bottom - frame.top, project_);
// Ensure that basic setup of the controller was successful.
if (!flutter_controller_-&gt;engine() || !flutter_controller_-&gt;view()) {
return false;
}
RegisterPlugins(flutter_controller_-&gt;engine());
initMethodChannel(flutter_controller_-&gt;engine());
SetChildContent(flutter_controller_-&gt;view()-&gt;GetNativeWindow());
flutter_controller_-&gt;engine()-&gt;SetNextFrameCallback([&amp;]() {
this-&gt;Show();
});
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&lt;LRESULT&gt; result =
flutter_controller_-&gt;HandleTopLevelWindowProc(hwnd, message, wparam,
lparam);
if (result) {
return *result;
}
}
switch (message) {
case WM_FONTCHANGE:
flutter_controller_-&gt;engine()-&gt;ReloadSystemFonts();
break;
}
return Win32Window::MessageHandler(hwnd, message, wparam, lparam);
}

> Happy coding!

huangapple
  • 本文由 发表于 2023年7月18日 15:40:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/76710500.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定