Flutter-Windows:如何使 main.dart 文件读取使用发送消息传递的消息

问题描述 投票:0回答:0

我正在尝试构建一个 flutter 应用程序,它从本机代码接收 sendMessage,在本例中是 C++。 sendMessage 仅在现有应用程序实例重新启动时发送。

在这里我附上了代码,以便更清楚地了解我正在尝试做的事情。

main.dart 的代码

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String _message = 'Hello world';

  @override
  void initState() {
    super.initState();
    //trying to call the c++ sendmessage to read the message and setstate of _message to the Hello from c++
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter App'),
      ),
      body: Center(
        child: Text(
          _message,
          style: TextStyle(fontSize: 24),
        ),
      ),
    );
  }
}

main.cpp 的代码

#include <Windows.h>
#include <flutter/dart_project.h>
#include <flutter/flutter_view_controller.h>
#include <string>

#include "flutter_window.h"
#include "utils.h"


// Constants
const wchar_t kMutexName[] = L"helloworld";  // Unique name for the mutex
const wchar_t kFlutterWindowTitle[] = L"helloworld";  // Title of the app's window
const wchar_t kClassName[] = L"helloworld";  // Class name for the app's window
const wchar_t kMessage[] = L"Hello from C++";  // Message to send from C++ to Dart


// Global variables
HWND g_hWnd = nullptr;  // Handle to the app's window

// Function to check if the app is already running
bool IsAppAlreadyRunning() {
  HANDLE hMutex = CreateMutex(nullptr, TRUE, kMutexName);
  if (GetLastError() == ERROR_ALREADY_EXISTS) {
    CloseHandle(hMutex);
    return true;
  }
  return false;
}

// Function to bring the running instance window to foreground
void BringWindowToForeground() {
  if (g_hWnd) {
    ShowWindow(g_hWnd, 9);
    SetForegroundWindow(g_hWnd);
  }
}

// Function to send message from C++ to Dart
void SendMessageToDart() {
  if (g_hWnd) {
    COPYDATASTRUCT cds;
    cds.dwData = 0;
    cds.cbData = (DWORD)((wcslen(kMessage) + 1) * sizeof(wchar_t));
    cds.lpData = (LPVOID)kMessage;
    SendMessage(g_hWnd, WM_COPYDATA, (WPARAM)(HWND)nullptr, (LPARAM)(LPVOID)&cds);
  }
}

// Window procedure for the app's window
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
  switch (msg) {
    case WM_COPYDATA: {
      PCOPYDATASTRUCT pcds = (PCOPYDATASTRUCT)lParam;
      if (pcds->cbData > 0 && pcds->lpData != nullptr) {
        // Update the "Hello world" text with the passed message
        std::wstring message(reinterpret_cast<const wchar_t*>(pcds->lpData), pcds->cbData / sizeof(wchar_t));
        SetWindowText(hWnd, message.c_str());
      }
      return TRUE;
    }
    // Add any other window messages to handle here if needed
  }
  return DefWindowProc(hWnd, msg, wParam, lParam);
}

// Entry point of the app
 int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
  g_hWnd = FindWindow(0, kFlutterWindowTitle);
 // Check if the app is already running
  if (IsAppAlreadyRunning()) {
    // Bring the running instance window to foreground
    BringWindowToForeground();

    // Send message from C++ to Dart
    SendMessageToDart();

    return FALSE;
  }
 
  // Attach to console when present (e.g., 'flutter run') or create a
  // new console when running with a debugger.
  if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) {
    CreateAndAttachConsole();
  }

  // Initialize COM, so that it is available for use in the library and/or
  // plugins.
  ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);

  flutter::DartProject project(L"data");

  std::vector<std::string> command_line_arguments =
      GetCommandLineArguments();

  project.set_dart_entrypoint_arguments(std::move(command_line_arguments));

  FlutterWindow window(project);
  Win32Window::Point origin(10, 10);
  Win32Window::Size size(1280, 720);
  if (!window.Create(L"helloworld", origin, size)) {
    return EXIT_FAILURE;
  }
  window.SetQuitOnClose(true);

  ::MSG msg;
  while (::GetMessage(&msg, nullptr, 0, 0)) {
    ::TranslateMessage(&msg);
    ::DispatchMessage(&msg);
  }

  ::CoUninitialize();
  return EXIT_SUCCESS;
}

构建和运行以下代码的步骤: 在第一次启动 flutter 应用程序时:

  1. 为 windows uisng flutter build window --debug 构建 flutter 代码
  2. 打开命令行并将命令行路径更改为../helloworld/build/windows/runner/debug
  3. 运行 exe 'helloworld.exe' 现在应用程序打开 enter image description here 让实例处于运行状态。

关于重新启动 flutter 应用程序: 4.打开命令行,修改命令行路径为../helloworld/build/windows/runner/debug 5. 运行 exe 'helloworld.exe' 根据 main.cpp 重新启动时,它会检查现有应用程序,然后它将现有应用程序置于前台,然后执行 sendMessage(hwnd, msg, wparam, lparam)。但无法在 flutter 中处理 sendMessage 是否有人可以帮助我。 重新启动的预期结果是它应该将 hello world 文本替换为 C++ 中的 Hello。

因为我是 flutter 的新手,所以我不知道如何实现 flutter 代码来读取从 c++ 发送的消息,而且我在 github 上也找不到任何使用 Windows 本机代码的示例项目。

c++ dart sendmessage flutter-windows flutter-channel
© www.soinside.com 2019 - 2024. All rights reserved.