#include "flutter_window.h" #include #include #include #include #include #include #include "flutter/generated_plugin_registrant.h" FlutterWindow::FlutterWindow(const flutter::DartProject& project) : project_(project) {} FlutterWindow::~FlutterWindow() {} bool FlutterWindow::OnCreate() { if (!Win32Window::OnCreate()) { return false; } RECT frame = GetClientArea(); flutter_controller_ = std::make_unique( frame.right - frame.left, frame.bottom - frame.top, project_); if (!flutter_controller_->engine() || !flutter_controller_->view()) { return false; } RegisterPlugins(flutter_controller_->engine()); static bool im_initialized = false; im_channel_ = std::make_unique>( flutter_controller_->engine()->messenger(), "com.fysxkj.oa/im", &flutter::StandardMethodCodec::GetInstance()); im_channel_->SetMethodCallHandler( [](const flutter::MethodCall& call, std::unique_ptr> result) { if (call.method_name() == "init") { im_initialized = true; flutter::EncodableMap map; map[flutter::EncodableValue("ok")] = flutter::EncodableValue(true); map[flutter::EncodableValue("initialized")] = flutter::EncodableValue(true); map[flutter::EncodableValue("engine")] = flutter::EncodableValue("dart-tcp"); result->Success(flutter::EncodableValue(map)); } else if (call.method_name() == "release") { im_initialized = false; flutter::EncodableMap map; map[flutter::EncodableValue("ok")] = flutter::EncodableValue(true); result->Success(flutter::EncodableValue(map)); } else if (call.method_name() == "engine") { result->Success(flutter::EncodableValue( im_initialized ? "dart-tcp" : "idle")); } else { result->NotImplemented(); } }); ota_channel_ = std::make_unique>( flutter_controller_->engine()->messenger(), "com.fysxkj.oa/ota", &flutter::StandardMethodCodec::GetInstance()); ota_channel_->SetMethodCallHandler( [](const flutter::MethodCall& call, std::unique_ptr> result) { if (call.method_name() == "startScreenshotWatch" || call.method_name() == "stopScreenshotWatch" || call.method_name() == "preferMaxRefresh") { result->Success(flutter::EncodableValue(true)); } else { result->NotImplemented(); } }); device_channel_ = std::make_unique>( flutter_controller_->engine()->messenger(), "com.fysxkj.oa/device", &flutter::StandardMethodCodec::GetInstance()); device_channel_->SetStreamHandler( std::make_unique>( [this](const flutter::EncodableValue*, std::unique_ptr>&& events) -> std::unique_ptr> { screenshot_sink_ = std::move(events); return nullptr; }, [this](const flutter::EncodableValue*) -> std::unique_ptr> { screenshot_sink_.reset(); return nullptr; })); SetChildContent(flutter_controller_->view()->GetNativeWindow()); AddClipboardFormatListener(GetHandle()); flutter_controller_->engine()->SetNextFrameCallback([&]() { this->Show(); }); flutter_controller_->ForceRedraw(); return true; } void FlutterWindow::EmitScreenshot() { const ULONGLONG now = GetTickCount64(); if (now - last_shot_at_ < 1500) return; last_shot_at_ = now; if (screenshot_sink_) { screenshot_sink_->Success(flutter::EncodableValue("screenshot")); } } void FlutterWindow::OnDestroy() { if (GetHandle()) { RemoveClipboardFormatListener(GetHandle()); } 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 result = flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, lparam); if (result) { return *result; } } switch (message) { case WM_FONTCHANGE: flutter_controller_->engine()->ReloadSystemFonts(); break; case WM_CLIPBOARDUPDATE: { if (OpenClipboard(nullptr)) { const bool image = IsClipboardFormatAvailable(CF_BITMAP) || IsClipboardFormatAvailable(CF_DIB) || IsClipboardFormatAvailable( RegisterClipboardFormatW(L"PNG")); CloseClipboard(); if (image) EmitScreenshot(); } break; } case WM_KEYUP: case WM_SYSKEYUP: if (wparam == VK_SNAPSHOT) { EmitScreenshot(); } break; } return Win32Window::MessageHandler(hwnd, message, wparam, lparam); }