我正在尝试构建一个 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 应用程序时:
关于重新启动 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 本机代码的示例项目。