mirror of
https://github.com/wgh136/flutter_qjs.git
synced 2025-09-27 05:27:23 +00:00
windows wrapper
This commit is contained in:
@@ -1 +0,0 @@
|
||||
6
|
@@ -7,12 +7,12 @@ add_executable(${BINARY_NAME} WIN32
|
||||
"run_loop.cpp"
|
||||
"utils.cpp"
|
||||
"win32_window.cpp"
|
||||
"window_configuration.cpp"
|
||||
"${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
|
||||
"Runner.rc"
|
||||
"runner.exe.manifest"
|
||||
)
|
||||
apply_standard_settings(${BINARY_NAME})
|
||||
target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX")
|
||||
target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app)
|
||||
target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}")
|
||||
add_dependencies(${BINARY_NAME} flutter_assemble)
|
||||
|
@@ -54,6 +54,57 @@ END
|
||||
// remains consistent on all systems.
|
||||
IDI_APP_ICON ICON "resources\\app_icon.ico"
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
#ifdef FLUTTER_BUILD_NUMBER
|
||||
#define VERSION_AS_NUMBER FLUTTER_BUILD_NUMBER
|
||||
#else
|
||||
#define VERSION_AS_NUMBER 1,0,0
|
||||
#endif
|
||||
|
||||
#ifdef FLUTTER_BUILD_NAME
|
||||
#define VERSION_AS_STRING #FLUTTER_BUILD_NAME
|
||||
#else
|
||||
#define VERSION_AS_STRING "1.0.0"
|
||||
#endif
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION VERSION_AS_NUMBER
|
||||
PRODUCTVERSION VERSION_AS_NUMBER
|
||||
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS VS_FF_DEBUG
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS VOS__WINDOWS32
|
||||
FILETYPE VFT_APP
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904e4"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "soko.ekibun" "\0"
|
||||
VALUE "FileDescription", "A new Flutter project." "\0"
|
||||
VALUE "FileVersion", VERSION_AS_STRING "\0"
|
||||
VALUE "InternalName", "example" "\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2020 soko.ekibun. All rights reserved." "\0"
|
||||
VALUE "OriginalFilename", "example.exe" "\0"
|
||||
VALUE "ProductName", "example" "\0"
|
||||
VALUE "ProductVersion", VERSION_AS_STRING "\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1252
|
||||
END
|
||||
END
|
||||
|
||||
#endif // English (United States) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@@ -15,22 +15,25 @@ bool FlutterWindow::OnCreate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The size here is arbitrary since SetChildContent will resize it.
|
||||
flutter_controller_ =
|
||||
std::make_unique<flutter::FlutterViewController>(100, 100, project_);
|
||||
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_.get());
|
||||
run_loop_->RegisterFlutterInstance(flutter_controller_.get());
|
||||
RegisterPlugins(flutter_controller_->engine());
|
||||
run_loop_->RegisterFlutterInstance(flutter_controller_->engine());
|
||||
SetChildContent(flutter_controller_->view()->GetNativeWindow());
|
||||
return true;
|
||||
}
|
||||
|
||||
void FlutterWindow::OnDestroy() {
|
||||
if (flutter_controller_) {
|
||||
run_loop_->UnregisterFlutterInstance(flutter_controller_.get());
|
||||
run_loop_->UnregisterFlutterInstance(flutter_controller_->engine());
|
||||
flutter_controller_ = nullptr;
|
||||
}
|
||||
|
||||
@@ -50,5 +53,12 @@ FlutterWindow::MessageHandler(HWND hwnd, UINT const message,
|
||||
return *result;
|
||||
}
|
||||
}
|
||||
|
||||
switch (message) {
|
||||
case WM_FONTCHANGE:
|
||||
flutter_controller_->engine()->ReloadSystemFonts();
|
||||
break;
|
||||
}
|
||||
|
||||
return Win32Window::MessageHandler(hwnd, message, wparam, lparam);
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
#ifndef FLUTTER_WINDOW_H_
|
||||
#define FLUTTER_WINDOW_H_
|
||||
#ifndef RUNNER_FLUTTER_WINDOW_H_
|
||||
#define RUNNER_FLUTTER_WINDOW_H_
|
||||
|
||||
#include <flutter/dart_project.h>
|
||||
#include <flutter/flutter_view_controller.h>
|
||||
@@ -36,4 +36,4 @@ class FlutterWindow : public Win32Window {
|
||||
std::unique_ptr<flutter::FlutterViewController> flutter_controller_;
|
||||
};
|
||||
|
||||
#endif // FLUTTER_WINDOW_H_
|
||||
#endif // RUNNER_FLUTTER_WINDOW_H_
|
||||
|
@@ -5,7 +5,6 @@
|
||||
#include "flutter_window.h"
|
||||
#include "run_loop.h"
|
||||
#include "utils.h"
|
||||
#include "window_configuration.h"
|
||||
|
||||
int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
|
||||
_In_ wchar_t *command_line, _In_ int show_command) {
|
||||
@@ -23,9 +22,9 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
|
||||
|
||||
flutter::DartProject project(L"data");
|
||||
FlutterWindow window(&run_loop, project);
|
||||
Win32Window::Point origin(kFlutterWindowOriginX, kFlutterWindowOriginY);
|
||||
Win32Window::Size size(kFlutterWindowWidth, kFlutterWindowHeight);
|
||||
if (!window.CreateAndShow(kFlutterWindowTitle, origin, size)) {
|
||||
Win32Window::Point origin(10, 10);
|
||||
Win32Window::Size size(1280, 720);
|
||||
if (!window.CreateAndShow(L"example", origin, size)) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
window.SetQuitOnClose(true);
|
||||
|
@@ -1,9 +1,6 @@
|
||||
#include "run_loop.h"
|
||||
|
||||
#include <Windows.h>
|
||||
// Don't stomp std::min/std::max
|
||||
#undef max
|
||||
#undef min
|
||||
#include <windows.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -47,20 +44,19 @@ void RunLoop::Run() {
|
||||
}
|
||||
|
||||
void RunLoop::RegisterFlutterInstance(
|
||||
flutter::FlutterViewController* flutter_instance) {
|
||||
flutter::FlutterEngine* flutter_instance) {
|
||||
flutter_instances_.insert(flutter_instance);
|
||||
}
|
||||
|
||||
void RunLoop::UnregisterFlutterInstance(
|
||||
flutter::FlutterViewController* flutter_instance) {
|
||||
flutter::FlutterEngine* flutter_instance) {
|
||||
flutter_instances_.erase(flutter_instance);
|
||||
}
|
||||
|
||||
RunLoop::TimePoint RunLoop::ProcessFlutterMessages() {
|
||||
TimePoint next_event_time = TimePoint::max();
|
||||
for (auto flutter_controller : flutter_instances_) {
|
||||
std::chrono::nanoseconds wait_duration =
|
||||
flutter_controller->ProcessMessages();
|
||||
for (auto instance : flutter_instances_) {
|
||||
std::chrono::nanoseconds wait_duration = instance->ProcessMessages();
|
||||
if (wait_duration != std::chrono::nanoseconds::max()) {
|
||||
next_event_time =
|
||||
std::min(next_event_time, TimePoint::clock::now() + wait_duration);
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#ifndef RUN_LOOP_H_
|
||||
#define RUN_LOOP_H_
|
||||
#ifndef RUNNER_RUN_LOOP_H_
|
||||
#define RUNNER_RUN_LOOP_H_
|
||||
|
||||
#include <flutter/flutter_view_controller.h>
|
||||
#include <flutter/flutter_engine.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <set>
|
||||
@@ -22,11 +22,11 @@ class RunLoop {
|
||||
|
||||
// Registers the given Flutter instance for event servicing.
|
||||
void RegisterFlutterInstance(
|
||||
flutter::FlutterViewController* flutter_instance);
|
||||
flutter::FlutterEngine* flutter_instance);
|
||||
|
||||
// Unregisters the given Flutter instance from event servicing.
|
||||
void UnregisterFlutterInstance(
|
||||
flutter::FlutterViewController* flutter_instance);
|
||||
flutter::FlutterEngine* flutter_instance);
|
||||
|
||||
private:
|
||||
using TimePoint = std::chrono::steady_clock::time_point;
|
||||
@@ -34,7 +34,7 @@ class RunLoop {
|
||||
// Processes all currently pending messages for registered Flutter instances.
|
||||
TimePoint ProcessFlutterMessages();
|
||||
|
||||
std::set<flutter::FlutterViewController*> flutter_instances_;
|
||||
std::set<flutter::FlutterEngine*> flutter_instances_;
|
||||
};
|
||||
|
||||
#endif // RUN_LOOP_H_
|
||||
#endif // RUNNER_RUN_LOOP_H_
|
||||
|
@@ -1,8 +1,8 @@
|
||||
#ifndef CONSOLE_UTILS_H_
|
||||
#define CONSOLE_UTILS_H_
|
||||
#ifndef RUNNER_UTILS_H_
|
||||
#define RUNNER_UTILS_H_
|
||||
|
||||
// Creates a console for the process, and redirects stdout and stderr to
|
||||
// it for both the runner and the Flutter library.
|
||||
void CreateAndAttachConsole();
|
||||
|
||||
#endif // CONSOLE_UTILS_H_
|
||||
#endif // RUNNER_UTILS_H_
|
||||
|
@@ -174,8 +174,7 @@ Win32Window::MessageHandler(HWND hwnd,
|
||||
return 0;
|
||||
}
|
||||
case WM_SIZE:
|
||||
RECT rect;
|
||||
GetClientRect(hwnd, &rect);
|
||||
RECT rect = GetClientArea();
|
||||
if (child_content_ != nullptr) {
|
||||
// Size and position the child window.
|
||||
MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left,
|
||||
@@ -188,11 +187,6 @@ Win32Window::MessageHandler(HWND hwnd,
|
||||
SetFocus(child_content_);
|
||||
}
|
||||
return 0;
|
||||
|
||||
// Messages that are directly forwarded to embedding.
|
||||
case WM_FONTCHANGE:
|
||||
SendMessage(child_content_, WM_FONTCHANGE, NULL, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return DefWindowProc(window_handle_, message, wparam, lparam);
|
||||
@@ -218,8 +212,7 @@ Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept {
|
||||
void Win32Window::SetChildContent(HWND content) {
|
||||
child_content_ = content;
|
||||
SetParent(content, window_handle_);
|
||||
RECT frame;
|
||||
GetClientRect(window_handle_, &frame);
|
||||
RECT frame = GetClientArea();
|
||||
|
||||
MoveWindow(content, frame.left, frame.top, frame.right - frame.left,
|
||||
frame.bottom - frame.top, true);
|
||||
@@ -227,6 +220,12 @@ void Win32Window::SetChildContent(HWND content) {
|
||||
SetFocus(child_content_);
|
||||
}
|
||||
|
||||
RECT Win32Window::GetClientArea() {
|
||||
RECT frame;
|
||||
GetClientRect(window_handle_, &frame);
|
||||
return frame;
|
||||
}
|
||||
|
||||
HWND Win32Window::GetHandle() {
|
||||
return window_handle_;
|
||||
}
|
||||
|
@@ -1,8 +1,7 @@
|
||||
#ifndef WIN32_WINDOW_H_
|
||||
#define WIN32_WINDOW_H_
|
||||
#ifndef RUNNER_WIN32_WINDOW_H_
|
||||
#define RUNNER_WIN32_WINDOW_H_
|
||||
|
||||
#include <Windows.h>
|
||||
#include <Windowsx.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
@@ -52,6 +51,9 @@ class Win32Window {
|
||||
// If true, closing this window will quit the application.
|
||||
void SetQuitOnClose(bool quit_on_close);
|
||||
|
||||
// Return a RECT representing the bounds of the current client area.
|
||||
RECT GetClientArea();
|
||||
|
||||
protected:
|
||||
// Processes and route salient window messages for mouse handling,
|
||||
// size change and DPI. Delegates handling of these to member overloads that
|
||||
@@ -93,4 +95,4 @@ class Win32Window {
|
||||
HWND child_content_ = nullptr;
|
||||
};
|
||||
|
||||
#endif // WIN32_WINDOW_H_
|
||||
#endif // RUNNER_WIN32_WINDOW_H_
|
||||
|
@@ -1,7 +0,0 @@
|
||||
#include "window_configuration.h"
|
||||
|
||||
const wchar_t* kFlutterWindowTitle = L"example";
|
||||
const unsigned int kFlutterWindowOriginX = 10;
|
||||
const unsigned int kFlutterWindowOriginY = 10;
|
||||
const unsigned int kFlutterWindowWidth = 1280;
|
||||
const unsigned int kFlutterWindowHeight = 720;
|
@@ -1,18 +0,0 @@
|
||||
#ifndef WINDOW_CONFIGURATION_
|
||||
#define WINDOW_CONFIGURATION_
|
||||
|
||||
// This is a temporary approach to isolate changes that people are likely to
|
||||
// make to main.cpp, where the APIs are still in flux. This will reduce the
|
||||
// need to resolve conflicts or re-create changes slightly differently every
|
||||
// time the Windows Flutter API surface changes.
|
||||
//
|
||||
// Longer term there should be simpler configuration options for common
|
||||
// customizations like this, without requiring native code changes.
|
||||
|
||||
extern const wchar_t* kFlutterWindowTitle;
|
||||
extern const unsigned int kFlutterWindowOriginX;
|
||||
extern const unsigned int kFlutterWindowOriginY;
|
||||
extern const unsigned int kFlutterWindowWidth;
|
||||
extern const unsigned int kFlutterWindowHeight;
|
||||
|
||||
#endif // WINDOW_CONFIGURATION_
|
Reference in New Issue
Block a user