Flutter Engine
plugin_registrar_windows.h
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_CLIENT_WRAPPER_INCLUDE_FLUTTER_PLUGIN_REGISTRAR_WINDOWS_H_
6 #define FLUTTER_SHELL_PLATFORM_WINDOWS_CLIENT_WRAPPER_INCLUDE_FLUTTER_PLUGIN_REGISTRAR_WINDOWS_H_
7 
8 #include <flutter_windows.h>
9 #include <windows.h>
10 
11 #include <memory>
12 #include <optional>
13 
14 #include "flutter_view.h"
15 #include "plugin_registrar.h"
16 
17 namespace flutter {
18 
19 // A delegate callback for WindowProc delegation.
20 //
21 // Implementations should return a value only if they have handled the message
22 // and want to stop all further handling.
23 using WindowProcDelegate = std::function<std::optional<
24  LRESULT>(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)>;
25 
26 // An extension to PluginRegistrar providing access to Windows-specific
27 // functionality.
29  public:
30  // Creates a new PluginRegistrar. |core_registrar| and the messenger it
31  // provides must remain valid as long as this object exists.
33  FlutterDesktopPluginRegistrarRef core_registrar)
34  : PluginRegistrar(core_registrar) {
35  view_ = std::make_unique<FlutterView>(
36  FlutterDesktopPluginRegistrarGetView(core_registrar));
37  }
38 
40  // Must be the first call.
41  ClearPlugins();
42  // Explicitly cleared to facilitate destruction order testing.
43  view_.reset();
44  }
45 
46  // Prevent copying.
49 
50  FlutterView* GetView() { return view_.get(); }
51 
52 #ifndef WINUWP
53  // Registers |delegate| to receive WindowProc callbacks for the top-level
54  // window containing this Flutter instance. Returns an ID that can be used to
55  // unregister the handler.
56  //
57  // Delegates are not guaranteed to be called:
58  // - The application may choose not to delegate WindowProc calls.
59  // - If multiple plugins are registered, the first one that returns a value
60  // from the delegate message will "win", and others will not be called.
61  // The order of delegate calls is not defined.
62  //
63  // Delegates should be implemented as narrowly as possible, only returning
64  // a value in cases where it's important that other delegates not run, to
65  // minimize the chances of conflicts between plugins.
67  if (window_proc_delegates_.empty()) {
69  registrar(), PluginRegistrarWindows::OnTopLevelWindowProc, this);
70  }
71  int delegate_id = next_window_proc_delegate_id_++;
72  window_proc_delegates_.emplace(delegate_id, std::move(delegate));
73  return delegate_id;
74  }
75 
76  // Unregisters a previously registered delegate.
78  window_proc_delegates_.erase(proc_id);
79  if (window_proc_delegates_.empty()) {
81  registrar(), PluginRegistrarWindows::OnTopLevelWindowProc);
82  }
83  }
84 #endif
85 
86  private:
87 #ifndef WINUWP
88  // A FlutterDesktopWindowProcCallback implementation that forwards back to
89  // a PluginRegistarWindows instance provided as |user_data|.
90  static bool OnTopLevelWindowProc(HWND hwnd,
91  UINT message,
92  WPARAM wparam,
93  LPARAM lparam,
94  void* user_data,
95  LRESULT* result) {
96  const auto* registrar = static_cast<PluginRegistrarWindows*>(user_data);
97  std::optional optional_result = registrar->CallTopLevelWindowProcDelegates(
98  hwnd, message, wparam, lparam);
99  if (optional_result) {
100  *result = *optional_result;
101  }
102  return optional_result.has_value();
103  }
104 
105  std::optional<LRESULT> CallTopLevelWindowProcDelegates(HWND hwnd,
106  UINT message,
107  WPARAM wparam,
108  LPARAM lparam) const {
109  std::optional<LRESULT> result;
110  for (const auto& pair : window_proc_delegates_) {
111  result = pair.second(hwnd, message, wparam, lparam);
112  // Stop as soon as any delegate indicates that it has handled the message.
113  if (result) {
114  break;
115  }
116  }
117  return result;
118  }
119 #endif
120 
121  // The associated FlutterView, if any.
122  std::unique_ptr<FlutterView> view_;
123 
124 #ifndef WINUWP
125  // The next ID to return from RegisterWindowProcDelegate.
126  int next_window_proc_delegate_id_ = 1;
127 
128  std::map<int, WindowProcDelegate> window_proc_delegates_;
129 #endif
130 };
131 
132 } // namespace flutter
133 
134 #endif // FLUTTER_SHELL_PLATFORM_WINDOWS_CLIENT_WRAPPER_INCLUDE_FLUTTER_PLUGIN_REGISTRAR_WINDOWS_H_
int RegisterTopLevelWindowProcDelegate(WindowProcDelegate delegate)
void FlutterDesktopPluginRegistrarRegisterTopLevelWindowProcDelegate(FlutterDesktopPluginRegistrarRef registrar, FlutterDesktopWindowProcCallback delegate, void *user_data)
void * user_data
Dart_NativeFunction function
Definition: fuchsia.cc:51
GAsyncResult * result
LONG_PTR LRESULT
Definition: windows_types.h:61
UINT_PTR WPARAM
Definition: windows_types.h:59
PluginRegistrarWindows(FlutterDesktopPluginRegistrarRef core_registrar)
void UnregisterTopLevelWindowProcDelegate(int proc_id)
PluginRegistrarWindows & operator=(PluginRegistrarWindows const &)=delete
void FlutterDesktopPluginRegistrarUnregisterTopLevelWindowProcDelegate(FlutterDesktopPluginRegistrarRef registrar, FlutterDesktopWindowProcCallback delegate)
std::function< std::optional< LRESULT >(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)> WindowProcDelegate
LONG_PTR LPARAM
Definition: windows_types.h:60
FlutterDesktopPluginRegistrarRef registrar()
unsigned int UINT
Definition: windows_types.h:32
FlutterDesktopViewRef FlutterDesktopPluginRegistrarGetView(FlutterDesktopPluginRegistrarRef controller)