first commit
This commit is contained in:
		
							
								
								
									
										40
									
								
								windows/runner/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								windows/runner/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
cmake_minimum_required(VERSION 3.14)
 | 
			
		||||
project(runner LANGUAGES CXX)
 | 
			
		||||
 | 
			
		||||
# Define the application target. To change its name, change BINARY_NAME in the
 | 
			
		||||
# top-level CMakeLists.txt, not the value here, or `flutter run` will no longer
 | 
			
		||||
# work.
 | 
			
		||||
#
 | 
			
		||||
# Any new source files that you add to the application should be added here.
 | 
			
		||||
add_executable(${BINARY_NAME} WIN32
 | 
			
		||||
  "flutter_window.cpp"
 | 
			
		||||
  "main.cpp"
 | 
			
		||||
  "utils.cpp"
 | 
			
		||||
  "win32_window.cpp"
 | 
			
		||||
  "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
 | 
			
		||||
  "Runner.rc"
 | 
			
		||||
  "runner.exe.manifest"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
# Apply the standard set of build settings. This can be removed for applications
 | 
			
		||||
# that need different build settings.
 | 
			
		||||
apply_standard_settings(${BINARY_NAME})
 | 
			
		||||
 | 
			
		||||
# Add preprocessor definitions for the build version.
 | 
			
		||||
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"")
 | 
			
		||||
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}")
 | 
			
		||||
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}")
 | 
			
		||||
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}")
 | 
			
		||||
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}")
 | 
			
		||||
 | 
			
		||||
# Disable Windows macros that collide with C++ standard library functions.
 | 
			
		||||
target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX")
 | 
			
		||||
 | 
			
		||||
# Add dependency libraries and include directories. Add any application-specific
 | 
			
		||||
# dependencies here.
 | 
			
		||||
target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app)
 | 
			
		||||
target_link_libraries(${BINARY_NAME} PRIVATE "dwmapi.lib")
 | 
			
		||||
target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}")
 | 
			
		||||
 | 
			
		||||
# Run the Flutter tool portions of the build. This must not be removed.
 | 
			
		||||
add_dependencies(${BINARY_NAME} flutter_assemble)
 | 
			
		||||
							
								
								
									
										121
									
								
								windows/runner/Runner.rc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								windows/runner/Runner.rc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,121 @@
 | 
			
		||||
// Microsoft Visual C++ generated resource script.
 | 
			
		||||
//
 | 
			
		||||
#pragma code_page(65001)
 | 
			
		||||
#include "resource.h"
 | 
			
		||||
 | 
			
		||||
#define APSTUDIO_READONLY_SYMBOLS
 | 
			
		||||
/////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
//
 | 
			
		||||
// Generated from the TEXTINCLUDE 2 resource.
 | 
			
		||||
//
 | 
			
		||||
#include "winres.h"
 | 
			
		||||
 | 
			
		||||
/////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
#undef APSTUDIO_READONLY_SYMBOLS
 | 
			
		||||
 | 
			
		||||
/////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// English (United States) resources
 | 
			
		||||
 | 
			
		||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
 | 
			
		||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
 | 
			
		||||
 | 
			
		||||
#ifdef APSTUDIO_INVOKED
 | 
			
		||||
/////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
//
 | 
			
		||||
// TEXTINCLUDE
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
1 TEXTINCLUDE
 | 
			
		||||
BEGIN
 | 
			
		||||
    "resource.h\0"
 | 
			
		||||
END
 | 
			
		||||
 | 
			
		||||
2 TEXTINCLUDE
 | 
			
		||||
BEGIN
 | 
			
		||||
    "#include ""winres.h""\r\n"
 | 
			
		||||
    "\0"
 | 
			
		||||
END
 | 
			
		||||
 | 
			
		||||
3 TEXTINCLUDE
 | 
			
		||||
BEGIN
 | 
			
		||||
    "\r\n"
 | 
			
		||||
    "\0"
 | 
			
		||||
END
 | 
			
		||||
 | 
			
		||||
#endif    // APSTUDIO_INVOKED
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
//
 | 
			
		||||
// Icon
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// Icon with lowest ID value placed first to ensure application icon
 | 
			
		||||
// remains consistent on all systems.
 | 
			
		||||
IDI_APP_ICON            ICON                    "resources\\app_icon.ico"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
//
 | 
			
		||||
// Version
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD)
 | 
			
		||||
#define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD
 | 
			
		||||
#else
 | 
			
		||||
#define VERSION_AS_NUMBER 1,0,0,0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(FLUTTER_VERSION)
 | 
			
		||||
#define VERSION_AS_STRING FLUTTER_VERSION
 | 
			
		||||
#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", "com.example" "\0"
 | 
			
		||||
            VALUE "FileDescription", "easy_settings_screen" "\0"
 | 
			
		||||
            VALUE "FileVersion", VERSION_AS_STRING "\0"
 | 
			
		||||
            VALUE "InternalName", "easy_settings_screen" "\0"
 | 
			
		||||
            VALUE "LegalCopyright", "Copyright (C) 2025 com.example. All rights reserved." "\0"
 | 
			
		||||
            VALUE "OriginalFilename", "easy_settings_screen.exe" "\0"
 | 
			
		||||
            VALUE "ProductName", "easy_settings_screen" "\0"
 | 
			
		||||
            VALUE "ProductVersion", VERSION_AS_STRING "\0"
 | 
			
		||||
        END
 | 
			
		||||
    END
 | 
			
		||||
    BLOCK "VarFileInfo"
 | 
			
		||||
    BEGIN
 | 
			
		||||
        VALUE "Translation", 0x409, 1252
 | 
			
		||||
    END
 | 
			
		||||
END
 | 
			
		||||
 | 
			
		||||
#endif    // English (United States) resources
 | 
			
		||||
/////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef APSTUDIO_INVOKED
 | 
			
		||||
/////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
//
 | 
			
		||||
// Generated from the TEXTINCLUDE 3 resource.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
#endif    // not APSTUDIO_INVOKED
 | 
			
		||||
							
								
								
									
										71
									
								
								windows/runner/flutter_window.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								windows/runner/flutter_window.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,71 @@
 | 
			
		||||
#include "flutter_window.h"
 | 
			
		||||
 | 
			
		||||
#include <optional>
 | 
			
		||||
 | 
			
		||||
#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();
 | 
			
		||||
 | 
			
		||||
  // 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());
 | 
			
		||||
  SetChildContent(flutter_controller_->view()->GetNativeWindow());
 | 
			
		||||
 | 
			
		||||
  flutter_controller_->engine()->SetNextFrameCallback([&]() {
 | 
			
		||||
    this->Show();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // Flutter can complete the first frame before the "show window" callback is
 | 
			
		||||
  // registered. The following call ensures a frame is pending to ensure the
 | 
			
		||||
  // window is shown. It is a no-op if the first frame hasn't completed yet.
 | 
			
		||||
  flutter_controller_->ForceRedraw();
 | 
			
		||||
 | 
			
		||||
  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);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										33
									
								
								windows/runner/flutter_window.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								windows/runner/flutter_window.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
#ifndef RUNNER_FLUTTER_WINDOW_H_
 | 
			
		||||
#define RUNNER_FLUTTER_WINDOW_H_
 | 
			
		||||
 | 
			
		||||
#include <flutter/dart_project.h>
 | 
			
		||||
#include <flutter/flutter_view_controller.h>
 | 
			
		||||
 | 
			
		||||
#include <memory>
 | 
			
		||||
 | 
			
		||||
#include "win32_window.h"
 | 
			
		||||
 | 
			
		||||
// A window that does nothing but host a Flutter view.
 | 
			
		||||
class FlutterWindow : public Win32Window {
 | 
			
		||||
 public:
 | 
			
		||||
  // Creates a new FlutterWindow hosting a Flutter view running |project|.
 | 
			
		||||
  explicit FlutterWindow(const flutter::DartProject& project);
 | 
			
		||||
  virtual ~FlutterWindow();
 | 
			
		||||
 | 
			
		||||
 protected:
 | 
			
		||||
  // Win32Window:
 | 
			
		||||
  bool OnCreate() override;
 | 
			
		||||
  void OnDestroy() override;
 | 
			
		||||
  LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam,
 | 
			
		||||
                         LPARAM const lparam) noexcept override;
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  // The project to run.
 | 
			
		||||
  flutter::DartProject project_;
 | 
			
		||||
 | 
			
		||||
  // The Flutter instance hosted by this window.
 | 
			
		||||
  std::unique_ptr<flutter::FlutterViewController> flutter_controller_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif  // RUNNER_FLUTTER_WINDOW_H_
 | 
			
		||||
							
								
								
									
										43
									
								
								windows/runner/main.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								windows/runner/main.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
#include <flutter/dart_project.h>
 | 
			
		||||
#include <flutter/flutter_view_controller.h>
 | 
			
		||||
#include <windows.h>
 | 
			
		||||
 | 
			
		||||
#include "flutter_window.h"
 | 
			
		||||
#include "utils.h"
 | 
			
		||||
 | 
			
		||||
int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
 | 
			
		||||
                      _In_ wchar_t *command_line, _In_ int show_command) {
 | 
			
		||||
  // 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"easy_settings_screen", origin, size)) {
 | 
			
		||||
    return EXIT_FAILURE;
 | 
			
		||||
  }
 | 
			
		||||
  window.SetQuitOnClose(true);
 | 
			
		||||
 | 
			
		||||
  ::MSG msg;
 | 
			
		||||
  while (::GetMessage(&msg, nullptr, 0, 0)) {
 | 
			
		||||
    ::TranslateMessage(&msg);
 | 
			
		||||
    ::DispatchMessage(&msg);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ::CoUninitialize();
 | 
			
		||||
  return EXIT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										16
									
								
								windows/runner/resource.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								windows/runner/resource.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
//{{NO_DEPENDENCIES}}
 | 
			
		||||
// Microsoft Visual C++ generated include file.
 | 
			
		||||
// Used by Runner.rc
 | 
			
		||||
//
 | 
			
		||||
#define IDI_APP_ICON                    101
 | 
			
		||||
 | 
			
		||||
// Next default values for new objects
 | 
			
		||||
//
 | 
			
		||||
#ifdef APSTUDIO_INVOKED
 | 
			
		||||
#ifndef APSTUDIO_READONLY_SYMBOLS
 | 
			
		||||
#define _APS_NEXT_RESOURCE_VALUE        102
 | 
			
		||||
#define _APS_NEXT_COMMAND_VALUE         40001
 | 
			
		||||
#define _APS_NEXT_CONTROL_VALUE         1001
 | 
			
		||||
#define _APS_NEXT_SYMED_VALUE           101
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								windows/runner/resources/app_icon.ico
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								windows/runner/resources/app_icon.ico
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 33 KiB  | 
							
								
								
									
										14
									
								
								windows/runner/runner.exe.manifest
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								windows/runner/runner.exe.manifest
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 | 
			
		||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
 | 
			
		||||
  <application xmlns="urn:schemas-microsoft-com:asm.v3">
 | 
			
		||||
    <windowsSettings>
 | 
			
		||||
      <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
 | 
			
		||||
    </windowsSettings>
 | 
			
		||||
  </application>
 | 
			
		||||
  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
 | 
			
		||||
    <application>
 | 
			
		||||
      <!-- Windows 10 and Windows 11 -->
 | 
			
		||||
      <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
 | 
			
		||||
    </application>
 | 
			
		||||
  </compatibility>
 | 
			
		||||
</assembly>
 | 
			
		||||
							
								
								
									
										65
									
								
								windows/runner/utils.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								windows/runner/utils.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,65 @@
 | 
			
		||||
#include "utils.h"
 | 
			
		||||
 | 
			
		||||
#include <flutter_windows.h>
 | 
			
		||||
#include <io.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <windows.h>
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
void CreateAndAttachConsole() {
 | 
			
		||||
  if (::AllocConsole()) {
 | 
			
		||||
    FILE *unused;
 | 
			
		||||
    if (freopen_s(&unused, "CONOUT$", "w", stdout)) {
 | 
			
		||||
      _dup2(_fileno(stdout), 1);
 | 
			
		||||
    }
 | 
			
		||||
    if (freopen_s(&unused, "CONOUT$", "w", stderr)) {
 | 
			
		||||
      _dup2(_fileno(stdout), 2);
 | 
			
		||||
    }
 | 
			
		||||
    std::ios::sync_with_stdio();
 | 
			
		||||
    FlutterDesktopResyncOutputStreams();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::vector<std::string> GetCommandLineArguments() {
 | 
			
		||||
  // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use.
 | 
			
		||||
  int argc;
 | 
			
		||||
  wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
 | 
			
		||||
  if (argv == nullptr) {
 | 
			
		||||
    return std::vector<std::string>();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  std::vector<std::string> command_line_arguments;
 | 
			
		||||
 | 
			
		||||
  // Skip the first argument as it's the binary name.
 | 
			
		||||
  for (int i = 1; i < argc; i++) {
 | 
			
		||||
    command_line_arguments.push_back(Utf8FromUtf16(argv[i]));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ::LocalFree(argv);
 | 
			
		||||
 | 
			
		||||
  return command_line_arguments;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string Utf8FromUtf16(const wchar_t* utf16_string) {
 | 
			
		||||
  if (utf16_string == nullptr) {
 | 
			
		||||
    return std::string();
 | 
			
		||||
  }
 | 
			
		||||
  unsigned int target_length = ::WideCharToMultiByte(
 | 
			
		||||
      CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string,
 | 
			
		||||
      -1, nullptr, 0, nullptr, nullptr)
 | 
			
		||||
    -1; // remove the trailing null character
 | 
			
		||||
  int input_length = (int)wcslen(utf16_string);
 | 
			
		||||
  std::string utf8_string;
 | 
			
		||||
  if (target_length == 0 || target_length > utf8_string.max_size()) {
 | 
			
		||||
    return utf8_string;
 | 
			
		||||
  }
 | 
			
		||||
  utf8_string.resize(target_length);
 | 
			
		||||
  int converted_length = ::WideCharToMultiByte(
 | 
			
		||||
      CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string,
 | 
			
		||||
      input_length, utf8_string.data(), target_length, nullptr, nullptr);
 | 
			
		||||
  if (converted_length == 0) {
 | 
			
		||||
    return std::string();
 | 
			
		||||
  }
 | 
			
		||||
  return utf8_string;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										19
									
								
								windows/runner/utils.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								windows/runner/utils.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
#ifndef RUNNER_UTILS_H_
 | 
			
		||||
#define RUNNER_UTILS_H_
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
// Creates a console for the process, and redirects stdout and stderr to
 | 
			
		||||
// it for both the runner and the Flutter library.
 | 
			
		||||
void CreateAndAttachConsole();
 | 
			
		||||
 | 
			
		||||
// Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string
 | 
			
		||||
// encoded in UTF-8. Returns an empty std::string on failure.
 | 
			
		||||
std::string Utf8FromUtf16(const wchar_t* utf16_string);
 | 
			
		||||
 | 
			
		||||
// Gets the command line arguments passed in as a std::vector<std::string>,
 | 
			
		||||
// encoded in UTF-8. Returns an empty std::vector<std::string> on failure.
 | 
			
		||||
std::vector<std::string> GetCommandLineArguments();
 | 
			
		||||
 | 
			
		||||
#endif  // RUNNER_UTILS_H_
 | 
			
		||||
							
								
								
									
										288
									
								
								windows/runner/win32_window.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										288
									
								
								windows/runner/win32_window.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,288 @@
 | 
			
		||||
#include "win32_window.h"
 | 
			
		||||
 | 
			
		||||
#include <dwmapi.h>
 | 
			
		||||
#include <flutter_windows.h>
 | 
			
		||||
 | 
			
		||||
#include "resource.h"
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
/// Window attribute that enables dark mode window decorations.
 | 
			
		||||
///
 | 
			
		||||
/// Redefined in case the developer's machine has a Windows SDK older than
 | 
			
		||||
/// version 10.0.22000.0.
 | 
			
		||||
/// See: https://docs.microsoft.com/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute
 | 
			
		||||
#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE
 | 
			
		||||
#define DWMWA_USE_IMMERSIVE_DARK_MODE 20
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW";
 | 
			
		||||
 | 
			
		||||
/// Registry key for app theme preference.
 | 
			
		||||
///
 | 
			
		||||
/// A value of 0 indicates apps should use dark mode. A non-zero or missing
 | 
			
		||||
/// value indicates apps should use light mode.
 | 
			
		||||
constexpr const wchar_t kGetPreferredBrightnessRegKey[] =
 | 
			
		||||
  L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize";
 | 
			
		||||
constexpr const wchar_t kGetPreferredBrightnessRegValue[] = L"AppsUseLightTheme";
 | 
			
		||||
 | 
			
		||||
// The number of Win32Window objects that currently exist.
 | 
			
		||||
static int g_active_window_count = 0;
 | 
			
		||||
 | 
			
		||||
using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd);
 | 
			
		||||
 | 
			
		||||
// Scale helper to convert logical scaler values to physical using passed in
 | 
			
		||||
// scale factor
 | 
			
		||||
int Scale(int source, double scale_factor) {
 | 
			
		||||
  return static_cast<int>(source * scale_factor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Dynamically loads the |EnableNonClientDpiScaling| from the User32 module.
 | 
			
		||||
// This API is only needed for PerMonitor V1 awareness mode.
 | 
			
		||||
void EnableFullDpiSupportIfAvailable(HWND hwnd) {
 | 
			
		||||
  HMODULE user32_module = LoadLibraryA("User32.dll");
 | 
			
		||||
  if (!user32_module) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  auto enable_non_client_dpi_scaling =
 | 
			
		||||
      reinterpret_cast<EnableNonClientDpiScaling*>(
 | 
			
		||||
          GetProcAddress(user32_module, "EnableNonClientDpiScaling"));
 | 
			
		||||
  if (enable_non_client_dpi_scaling != nullptr) {
 | 
			
		||||
    enable_non_client_dpi_scaling(hwnd);
 | 
			
		||||
  }
 | 
			
		||||
  FreeLibrary(user32_module);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}  // namespace
 | 
			
		||||
 | 
			
		||||
// Manages the Win32Window's window class registration.
 | 
			
		||||
class WindowClassRegistrar {
 | 
			
		||||
 public:
 | 
			
		||||
  ~WindowClassRegistrar() = default;
 | 
			
		||||
 | 
			
		||||
  // Returns the singleton registrar instance.
 | 
			
		||||
  static WindowClassRegistrar* GetInstance() {
 | 
			
		||||
    if (!instance_) {
 | 
			
		||||
      instance_ = new WindowClassRegistrar();
 | 
			
		||||
    }
 | 
			
		||||
    return instance_;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Returns the name of the window class, registering the class if it hasn't
 | 
			
		||||
  // previously been registered.
 | 
			
		||||
  const wchar_t* GetWindowClass();
 | 
			
		||||
 | 
			
		||||
  // Unregisters the window class. Should only be called if there are no
 | 
			
		||||
  // instances of the window.
 | 
			
		||||
  void UnregisterWindowClass();
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  WindowClassRegistrar() = default;
 | 
			
		||||
 | 
			
		||||
  static WindowClassRegistrar* instance_;
 | 
			
		||||
 | 
			
		||||
  bool class_registered_ = false;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr;
 | 
			
		||||
 | 
			
		||||
const wchar_t* WindowClassRegistrar::GetWindowClass() {
 | 
			
		||||
  if (!class_registered_) {
 | 
			
		||||
    WNDCLASS window_class{};
 | 
			
		||||
    window_class.hCursor = LoadCursor(nullptr, IDC_ARROW);
 | 
			
		||||
    window_class.lpszClassName = kWindowClassName;
 | 
			
		||||
    window_class.style = CS_HREDRAW | CS_VREDRAW;
 | 
			
		||||
    window_class.cbClsExtra = 0;
 | 
			
		||||
    window_class.cbWndExtra = 0;
 | 
			
		||||
    window_class.hInstance = GetModuleHandle(nullptr);
 | 
			
		||||
    window_class.hIcon =
 | 
			
		||||
        LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON));
 | 
			
		||||
    window_class.hbrBackground = 0;
 | 
			
		||||
    window_class.lpszMenuName = nullptr;
 | 
			
		||||
    window_class.lpfnWndProc = Win32Window::WndProc;
 | 
			
		||||
    RegisterClass(&window_class);
 | 
			
		||||
    class_registered_ = true;
 | 
			
		||||
  }
 | 
			
		||||
  return kWindowClassName;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WindowClassRegistrar::UnregisterWindowClass() {
 | 
			
		||||
  UnregisterClass(kWindowClassName, nullptr);
 | 
			
		||||
  class_registered_ = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Win32Window::Win32Window() {
 | 
			
		||||
  ++g_active_window_count;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Win32Window::~Win32Window() {
 | 
			
		||||
  --g_active_window_count;
 | 
			
		||||
  Destroy();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Win32Window::Create(const std::wstring& title,
 | 
			
		||||
                         const Point& origin,
 | 
			
		||||
                         const Size& size) {
 | 
			
		||||
  Destroy();
 | 
			
		||||
 | 
			
		||||
  const wchar_t* window_class =
 | 
			
		||||
      WindowClassRegistrar::GetInstance()->GetWindowClass();
 | 
			
		||||
 | 
			
		||||
  const POINT target_point = {static_cast<LONG>(origin.x),
 | 
			
		||||
                              static_cast<LONG>(origin.y)};
 | 
			
		||||
  HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST);
 | 
			
		||||
  UINT dpi = FlutterDesktopGetDpiForMonitor(monitor);
 | 
			
		||||
  double scale_factor = dpi / 96.0;
 | 
			
		||||
 | 
			
		||||
  HWND window = CreateWindow(
 | 
			
		||||
      window_class, title.c_str(), WS_OVERLAPPEDWINDOW,
 | 
			
		||||
      Scale(origin.x, scale_factor), Scale(origin.y, scale_factor),
 | 
			
		||||
      Scale(size.width, scale_factor), Scale(size.height, scale_factor),
 | 
			
		||||
      nullptr, nullptr, GetModuleHandle(nullptr), this);
 | 
			
		||||
 | 
			
		||||
  if (!window) {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  UpdateTheme(window);
 | 
			
		||||
 | 
			
		||||
  return OnCreate();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Win32Window::Show() {
 | 
			
		||||
  return ShowWindow(window_handle_, SW_SHOWNORMAL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// static
 | 
			
		||||
LRESULT CALLBACK Win32Window::WndProc(HWND const window,
 | 
			
		||||
                                      UINT const message,
 | 
			
		||||
                                      WPARAM const wparam,
 | 
			
		||||
                                      LPARAM const lparam) noexcept {
 | 
			
		||||
  if (message == WM_NCCREATE) {
 | 
			
		||||
    auto window_struct = reinterpret_cast<CREATESTRUCT*>(lparam);
 | 
			
		||||
    SetWindowLongPtr(window, GWLP_USERDATA,
 | 
			
		||||
                     reinterpret_cast<LONG_PTR>(window_struct->lpCreateParams));
 | 
			
		||||
 | 
			
		||||
    auto that = static_cast<Win32Window*>(window_struct->lpCreateParams);
 | 
			
		||||
    EnableFullDpiSupportIfAvailable(window);
 | 
			
		||||
    that->window_handle_ = window;
 | 
			
		||||
  } else if (Win32Window* that = GetThisFromHandle(window)) {
 | 
			
		||||
    return that->MessageHandler(window, message, wparam, lparam);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return DefWindowProc(window, message, wparam, lparam);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
LRESULT
 | 
			
		||||
Win32Window::MessageHandler(HWND hwnd,
 | 
			
		||||
                            UINT const message,
 | 
			
		||||
                            WPARAM const wparam,
 | 
			
		||||
                            LPARAM const lparam) noexcept {
 | 
			
		||||
  switch (message) {
 | 
			
		||||
    case WM_DESTROY:
 | 
			
		||||
      window_handle_ = nullptr;
 | 
			
		||||
      Destroy();
 | 
			
		||||
      if (quit_on_close_) {
 | 
			
		||||
        PostQuitMessage(0);
 | 
			
		||||
      }
 | 
			
		||||
      return 0;
 | 
			
		||||
 | 
			
		||||
    case WM_DPICHANGED: {
 | 
			
		||||
      auto newRectSize = reinterpret_cast<RECT*>(lparam);
 | 
			
		||||
      LONG newWidth = newRectSize->right - newRectSize->left;
 | 
			
		||||
      LONG newHeight = newRectSize->bottom - newRectSize->top;
 | 
			
		||||
 | 
			
		||||
      SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth,
 | 
			
		||||
                   newHeight, SWP_NOZORDER | SWP_NOACTIVATE);
 | 
			
		||||
 | 
			
		||||
      return 0;
 | 
			
		||||
    }
 | 
			
		||||
    case WM_SIZE: {
 | 
			
		||||
      RECT rect = GetClientArea();
 | 
			
		||||
      if (child_content_ != nullptr) {
 | 
			
		||||
        // Size and position the child window.
 | 
			
		||||
        MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left,
 | 
			
		||||
                   rect.bottom - rect.top, TRUE);
 | 
			
		||||
      }
 | 
			
		||||
      return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    case WM_ACTIVATE:
 | 
			
		||||
      if (child_content_ != nullptr) {
 | 
			
		||||
        SetFocus(child_content_);
 | 
			
		||||
      }
 | 
			
		||||
      return 0;
 | 
			
		||||
 | 
			
		||||
    case WM_DWMCOLORIZATIONCOLORCHANGED:
 | 
			
		||||
      UpdateTheme(hwnd);
 | 
			
		||||
      return 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return DefWindowProc(window_handle_, message, wparam, lparam);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Win32Window::Destroy() {
 | 
			
		||||
  OnDestroy();
 | 
			
		||||
 | 
			
		||||
  if (window_handle_) {
 | 
			
		||||
    DestroyWindow(window_handle_);
 | 
			
		||||
    window_handle_ = nullptr;
 | 
			
		||||
  }
 | 
			
		||||
  if (g_active_window_count == 0) {
 | 
			
		||||
    WindowClassRegistrar::GetInstance()->UnregisterWindowClass();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept {
 | 
			
		||||
  return reinterpret_cast<Win32Window*>(
 | 
			
		||||
      GetWindowLongPtr(window, GWLP_USERDATA));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Win32Window::SetChildContent(HWND content) {
 | 
			
		||||
  child_content_ = content;
 | 
			
		||||
  SetParent(content, window_handle_);
 | 
			
		||||
  RECT frame = GetClientArea();
 | 
			
		||||
 | 
			
		||||
  MoveWindow(content, frame.left, frame.top, frame.right - frame.left,
 | 
			
		||||
             frame.bottom - frame.top, true);
 | 
			
		||||
 | 
			
		||||
  SetFocus(child_content_);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RECT Win32Window::GetClientArea() {
 | 
			
		||||
  RECT frame;
 | 
			
		||||
  GetClientRect(window_handle_, &frame);
 | 
			
		||||
  return frame;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
HWND Win32Window::GetHandle() {
 | 
			
		||||
  return window_handle_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Win32Window::SetQuitOnClose(bool quit_on_close) {
 | 
			
		||||
  quit_on_close_ = quit_on_close;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Win32Window::OnCreate() {
 | 
			
		||||
  // No-op; provided for subclasses.
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Win32Window::OnDestroy() {
 | 
			
		||||
  // No-op; provided for subclasses.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Win32Window::UpdateTheme(HWND const window) {
 | 
			
		||||
  DWORD light_mode;
 | 
			
		||||
  DWORD light_mode_size = sizeof(light_mode);
 | 
			
		||||
  LSTATUS result = RegGetValue(HKEY_CURRENT_USER, kGetPreferredBrightnessRegKey,
 | 
			
		||||
                               kGetPreferredBrightnessRegValue,
 | 
			
		||||
                               RRF_RT_REG_DWORD, nullptr, &light_mode,
 | 
			
		||||
                               &light_mode_size);
 | 
			
		||||
 | 
			
		||||
  if (result == ERROR_SUCCESS) {
 | 
			
		||||
    BOOL enable_dark_mode = light_mode == 0;
 | 
			
		||||
    DwmSetWindowAttribute(window, DWMWA_USE_IMMERSIVE_DARK_MODE,
 | 
			
		||||
                          &enable_dark_mode, sizeof(enable_dark_mode));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										102
									
								
								windows/runner/win32_window.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								windows/runner/win32_window.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,102 @@
 | 
			
		||||
#ifndef RUNNER_WIN32_WINDOW_H_
 | 
			
		||||
#define RUNNER_WIN32_WINDOW_H_
 | 
			
		||||
 | 
			
		||||
#include <windows.h>
 | 
			
		||||
 | 
			
		||||
#include <functional>
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
// A class abstraction for a high DPI-aware Win32 Window. Intended to be
 | 
			
		||||
// inherited from by classes that wish to specialize with custom
 | 
			
		||||
// rendering and input handling
 | 
			
		||||
class Win32Window {
 | 
			
		||||
 public:
 | 
			
		||||
  struct Point {
 | 
			
		||||
    unsigned int x;
 | 
			
		||||
    unsigned int y;
 | 
			
		||||
    Point(unsigned int x, unsigned int y) : x(x), y(y) {}
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  struct Size {
 | 
			
		||||
    unsigned int width;
 | 
			
		||||
    unsigned int height;
 | 
			
		||||
    Size(unsigned int width, unsigned int height)
 | 
			
		||||
        : width(width), height(height) {}
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  Win32Window();
 | 
			
		||||
  virtual ~Win32Window();
 | 
			
		||||
 | 
			
		||||
  // Creates a win32 window with |title| that is positioned and sized using
 | 
			
		||||
  // |origin| and |size|. New windows are created on the default monitor. Window
 | 
			
		||||
  // sizes are specified to the OS in physical pixels, hence to ensure a
 | 
			
		||||
  // consistent size this function will scale the inputted width and height as
 | 
			
		||||
  // as appropriate for the default monitor. The window is invisible until
 | 
			
		||||
  // |Show| is called. Returns true if the window was created successfully.
 | 
			
		||||
  bool Create(const std::wstring& title, const Point& origin, const Size& size);
 | 
			
		||||
 | 
			
		||||
  // Show the current window. Returns true if the window was successfully shown.
 | 
			
		||||
  bool Show();
 | 
			
		||||
 | 
			
		||||
  // Release OS resources associated with window.
 | 
			
		||||
  void Destroy();
 | 
			
		||||
 | 
			
		||||
  // Inserts |content| into the window tree.
 | 
			
		||||
  void SetChildContent(HWND content);
 | 
			
		||||
 | 
			
		||||
  // Returns the backing Window handle to enable clients to set icon and other
 | 
			
		||||
  // window properties. Returns nullptr if the window has been destroyed.
 | 
			
		||||
  HWND GetHandle();
 | 
			
		||||
 | 
			
		||||
  // 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
 | 
			
		||||
  // inheriting classes can handle.
 | 
			
		||||
  virtual LRESULT MessageHandler(HWND window,
 | 
			
		||||
                                 UINT const message,
 | 
			
		||||
                                 WPARAM const wparam,
 | 
			
		||||
                                 LPARAM const lparam) noexcept;
 | 
			
		||||
 | 
			
		||||
  // Called when CreateAndShow is called, allowing subclass window-related
 | 
			
		||||
  // setup. Subclasses should return false if setup fails.
 | 
			
		||||
  virtual bool OnCreate();
 | 
			
		||||
 | 
			
		||||
  // Called when Destroy is called.
 | 
			
		||||
  virtual void OnDestroy();
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  friend class WindowClassRegistrar;
 | 
			
		||||
 | 
			
		||||
  // OS callback called by message pump. Handles the WM_NCCREATE message which
 | 
			
		||||
  // is passed when the non-client area is being created and enables automatic
 | 
			
		||||
  // non-client DPI scaling so that the non-client area automatically
 | 
			
		||||
  // responds to changes in DPI. All other messages are handled by
 | 
			
		||||
  // MessageHandler.
 | 
			
		||||
  static LRESULT CALLBACK WndProc(HWND const window,
 | 
			
		||||
                                  UINT const message,
 | 
			
		||||
                                  WPARAM const wparam,
 | 
			
		||||
                                  LPARAM const lparam) noexcept;
 | 
			
		||||
 | 
			
		||||
  // Retrieves a class instance pointer for |window|
 | 
			
		||||
  static Win32Window* GetThisFromHandle(HWND const window) noexcept;
 | 
			
		||||
 | 
			
		||||
  // Update the window frame's theme to match the system theme.
 | 
			
		||||
  static void UpdateTheme(HWND const window);
 | 
			
		||||
 | 
			
		||||
  bool quit_on_close_ = false;
 | 
			
		||||
 | 
			
		||||
  // window handle for top level window.
 | 
			
		||||
  HWND window_handle_ = nullptr;
 | 
			
		||||
 | 
			
		||||
  // window handle for hosted content.
 | 
			
		||||
  HWND child_content_ = nullptr;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif  // RUNNER_WIN32_WINDOW_H_
 | 
			
		||||
		Reference in New Issue
	
	Block a user