9 #include "flutter/fml/logging.h"
18 TaskRunnerWindow::TaskRunnerWindow() {
19 WNDCLASS window_class = RegisterWindowClass();
21 CreateWindowEx(0, window_class.lpszClassName, L
"", 0, 0, 0, 0, 0,
22 HWND_MESSAGE,
nullptr, window_class.hInstance,
nullptr);
25 SetWindowLongPtr(window_handle_, GWLP_USERDATA,
26 reinterpret_cast<LONG_PTR
>(
this));
28 auto error = GetLastError();
30 size_t size = FormatMessageW(
31 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
32 FORMAT_MESSAGE_IGNORE_INSERTS,
33 NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
34 reinterpret_cast<LPWSTR
>(&
message), 0, NULL);
42 DestroyWindow(window_handle_);
43 window_handle_ =
nullptr;
45 UnregisterClass(window_class_name_.c_str(),
nullptr);
49 static std::weak_ptr<TaskRunnerWindow> instance;
50 auto res = instance.lock();
60 if (!PostMessage(window_handle_, WM_NULL, 0, 0)) {
61 FML_LOG(ERROR) <<
"Failed to post message to main thread.";
66 delegates_.push_back(delegate);
67 SetTimer(std::chrono::nanoseconds::zero());
71 auto i = std::find(delegates_.begin(), delegates_.end(), delegate);
72 if (i != delegates_.end()) {
80 if (GetMessage(&msg, window_handle_, 0, 0)) {
81 TranslateMessage(&msg);
82 DispatchMessage(&msg);
87 void TaskRunnerWindow::ProcessTasks() {
88 auto next = std::chrono::nanoseconds::max();
89 auto delegates_copy(delegates_);
90 for (
auto delegate : delegates_copy) {
92 if (std::find(delegates_.begin(), delegates_.end(), delegate) !=
94 next = std::min(next, delegate->ProcessTasks());
100 void TaskRunnerWindow::SetTimer(std::chrono::nanoseconds when) {
101 if (when == std::chrono::nanoseconds::max()) {
102 KillTimer(window_handle_,
kTimerId);
104 auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(when);
105 ::SetTimer(window_handle_,
kTimerId, millis.count() + 1,
nullptr);
109 WNDCLASS TaskRunnerWindow::RegisterWindowClass() {
110 window_class_name_ = L
"FlutterTaskRunnerWindow";
112 WNDCLASS window_class{};
113 window_class.hCursor =
nullptr;
114 window_class.lpszClassName = window_class_name_.c_str();
115 window_class.style = 0;
116 window_class.cbClsExtra = 0;
117 window_class.cbWndExtra = 0;
118 window_class.hInstance = GetModuleHandle(
nullptr);
119 window_class.hIcon =
nullptr;
120 window_class.hbrBackground = 0;
121 window_class.lpszMenuName =
nullptr;
122 window_class.lpfnWndProc = WndProc;
123 RegisterClass(&window_class);
128 TaskRunnerWindow::HandleMessage(UINT
const message,
130 LPARAM
const lparam) noexcept {
144 return DefWindowProcW(window_handle_,
message, wparam, lparam);
147 LRESULT TaskRunnerWindow::WndProc(HWND
const window,
150 LPARAM
const lparam) noexcept {
151 if (
auto* that =
reinterpret_cast<TaskRunnerWindow*
>(
152 GetWindowLongPtr(window, GWLP_USERDATA))) {
153 return that->HandleMessage(
message, wparam, lparam);
155 return DefWindowProc(window,
message, wparam, lparam);