3
3
// This must be included before many other Windows headers.
4
4
#include < windows.h>
5
5
6
- // For getPlatformVersion; remove unless needed for your plugin implementation.
7
- #include < VersionHelpers.h>
8
-
6
+ #include < flutter/event_channel.h>
7
+ #include < flutter/event_stream_handler_functions.h>
9
8
#include < flutter/method_channel.h>
10
9
#include < flutter/plugin_registrar_windows.h>
11
10
#include < flutter/standard_method_codec.h>
12
11
12
+ #include < codecvt>
13
13
#include < map>
14
14
#include < memory>
15
15
#include < sstream>
16
16
17
17
namespace {
18
18
19
- class UniLinksDesktopPlugin : public flutter ::Plugin {
19
+ class UniLinksDesktopPlugin : public flutter ::Plugin,
20
+ flutter::StreamHandler<flutter::EncodableValue> {
20
21
public:
21
- static void RegisterWithRegistrar (flutter::PluginRegistrarWindows *registrar);
22
+ static void RegisterWithRegistrar (flutter::PluginRegistrarWindows* registrar);
23
+
24
+ UniLinksDesktopPlugin (
25
+ flutter::PluginRegistrarWindows* registrar,
26
+ std::unique_ptr<flutter::MethodChannel<flutter::EncodableValue>> channel);
22
27
23
- UniLinksDesktopPlugin ();
28
+ flutter::MethodChannel<flutter::EncodableValue>* channel () const {
29
+ return channel_.get ();
30
+ }
31
+
32
+ std::string UniLinksDesktopPlugin::GetInitialLink ();
24
33
25
34
virtual ~UniLinksDesktopPlugin ();
26
35
27
36
private:
37
+ flutter::PluginRegistrarWindows* registrar_;
38
+ std::unique_ptr<flutter::MethodChannel<flutter::EncodableValue>> channel_ =
39
+ nullptr ;
40
+ std::unique_ptr<flutter::EventSink<flutter::EncodableValue>> event_sink_;
41
+
42
+ int32_t window_proc_id_ = -1 ;
43
+
44
+ std::optional<LRESULT> HandleWindowProc (HWND hwnd,
45
+ UINT message,
46
+ WPARAM wparam,
47
+ LPARAM lparam);
48
+
28
49
// Called when a method is called on this plugin's channel from Dart.
29
50
void HandleMethodCall (
30
- const flutter::MethodCall<flutter::EncodableValue> & method_call,
51
+ const flutter::MethodCall<flutter::EncodableValue>& method_call,
31
52
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
53
+
54
+ std::unique_ptr<flutter::StreamHandlerError<>> OnListenInternal (
55
+ const flutter::EncodableValue* arguments,
56
+ std::unique_ptr<flutter::EventSink<>>&& events) override ;
57
+ std::unique_ptr<flutter::StreamHandlerError<>> OnCancelInternal (
58
+ const flutter::EncodableValue* arguments) override ;
32
59
};
33
60
34
61
// static
35
62
void UniLinksDesktopPlugin::RegisterWithRegistrar (
36
- flutter::PluginRegistrarWindows *registrar) {
37
- auto channel =
63
+ flutter::PluginRegistrarWindows* registrar) {
64
+ auto plugin = std::make_unique<UniLinksDesktopPlugin>(
65
+ registrar,
38
66
std::make_unique<flutter::MethodChannel<flutter::EncodableValue>>(
39
- registrar->messenger (), " uni_links_desktop" ,
40
- &flutter::StandardMethodCodec::GetInstance ());
67
+ registrar->messenger (), " uni_links/messages" ,
68
+ &flutter::StandardMethodCodec::GetInstance ()));
69
+ plugin->channel ()->SetMethodCallHandler (
70
+ [plugin_pointer = plugin.get ()](const auto & call, auto result) {
71
+ plugin_pointer->HandleMethodCall (call, std::move (result));
72
+ });
41
73
42
- auto plugin = std::make_unique<UniLinksDesktopPlugin>();
74
+ auto eventChannel =
75
+ std::make_unique<flutter::EventChannel<flutter::EncodableValue>>(
76
+ registrar->messenger (), " uni_links/events" ,
77
+ &flutter::StandardMethodCodec::GetInstance ());
43
78
44
- channel->SetMethodCallHandler (
45
- [plugin_pointer = plugin.get ()](const auto &call, auto result) {
46
- plugin_pointer->HandleMethodCall (call, std::move (result));
79
+ auto atreamHandler = std::make_unique<flutter::StreamHandlerFunctions<>>(
80
+ [plugin_pointer = plugin.get ()](
81
+ const flutter::EncodableValue* arguments,
82
+ std::unique_ptr<flutter::EventSink<>>&& events)
83
+ -> std::unique_ptr<flutter::StreamHandlerError<>> {
84
+ return plugin_pointer->OnListen (arguments, std::move (events));
85
+ },
86
+ [plugin_pointer = plugin.get ()](const flutter::EncodableValue* arguments)
87
+ -> std::unique_ptr<flutter::StreamHandlerError<>> {
88
+ return plugin_pointer->OnCancel (arguments);
47
89
});
48
90
91
+ eventChannel->SetStreamHandler (std::move (atreamHandler));
92
+
49
93
registrar->AddPlugin (std::move (plugin));
50
94
}
51
95
52
- UniLinksDesktopPlugin::UniLinksDesktopPlugin () {}
96
+ UniLinksDesktopPlugin::UniLinksDesktopPlugin (
97
+ flutter::PluginRegistrarWindows* registrar,
98
+ std::unique_ptr<flutter::MethodChannel<flutter::EncodableValue>> channel)
99
+ : registrar_(registrar), channel_(std::move(channel)) {
100
+ window_proc_id_ = registrar->RegisterTopLevelWindowProcDelegate (
101
+ [this ](HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
102
+ return HandleWindowProc (hwnd, message, wparam, lparam);
103
+ });
104
+ }
105
+
106
+ UniLinksDesktopPlugin::~UniLinksDesktopPlugin () {
107
+ registrar_->UnregisterTopLevelWindowProcDelegate (window_proc_id_);
108
+ }
53
109
54
- UniLinksDesktopPlugin::~UniLinksDesktopPlugin () {}
110
+ std::optional<LRESULT> UniLinksDesktopPlugin::HandleWindowProc (HWND hwnd,
111
+ UINT message,
112
+ WPARAM wparam,
113
+ LPARAM lparam) {
114
+ switch (message) {
115
+ case WM_COPYDATA:
116
+ COPYDATASTRUCT* cds = {0 };
117
+ cds = (COPYDATASTRUCT*)lparam;
118
+
119
+ if (cds->dwData == UNI_LINKS_DESKTOP_MSG_ID) {
120
+ std::string url ((char *)((LPCWSTR)cds->lpData ));
121
+
122
+ if (event_sink_) {
123
+ event_sink_->Success (flutter::EncodableValue (url.c_str ()));
124
+ }
125
+ }
126
+ break ;
127
+ }
128
+ return std::nullopt ;
129
+ }
130
+
131
+ std::string UniLinksDesktopPlugin::GetInitialLink () {
132
+ int argc;
133
+ wchar_t ** argv = ::CommandLineToArgvW (::GetCommandLineW (), &argc);
134
+ if (argv == nullptr || argc < 2 ) {
135
+ return " " ;
136
+ }
137
+
138
+ std::wstring_convert<std::codecvt_utf8_utf16<wchar_t >> converter;
139
+ std::string url = converter.to_bytes (argv[1 ]);
140
+ ::LocalFree (argv);
141
+ return url;
142
+ }
55
143
56
144
void UniLinksDesktopPlugin::HandleMethodCall (
57
- const flutter::MethodCall<flutter::EncodableValue> & method_call,
145
+ const flutter::MethodCall<flutter::EncodableValue>& method_call,
58
146
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
59
- if (method_call.method_name ().compare (" getPlatformVersion" ) == 0 ) {
60
- std::ostringstream version_stream;
61
- version_stream << " Windows " ;
62
- if (IsWindows10OrGreater ()) {
63
- version_stream << " 10+" ;
64
- } else if (IsWindows8OrGreater ()) {
65
- version_stream << " 8" ;
66
- } else if (IsWindows7OrGreater ()) {
67
- version_stream << " 7" ;
68
- }
69
- result->Success (flutter::EncodableValue (version_stream.str ()));
147
+ if (method_call.method_name ().compare (" getInitialLink" ) == 0 ) {
148
+ std::string value = GetInitialLink ();
149
+ result->Success (flutter::EncodableValue (value.c_str ()));
70
150
} else {
71
151
result->NotImplemented ();
72
152
}
73
153
}
74
154
155
+ std::unique_ptr<flutter::StreamHandlerError<flutter::EncodableValue>>
156
+ UniLinksDesktopPlugin::OnListenInternal (
157
+ const flutter::EncodableValue* arguments,
158
+ std::unique_ptr<flutter::EventSink<flutter::EncodableValue>>&& events) {
159
+ event_sink_ = std::move (events);
160
+ return nullptr ;
161
+ }
162
+
163
+ std::unique_ptr<flutter::StreamHandlerError<flutter::EncodableValue>>
164
+ UniLinksDesktopPlugin::OnCancelInternal (
165
+ const flutter::EncodableValue* arguments) {
166
+ event_sink_ = nullptr ;
167
+ return nullptr ;
168
+ }
169
+
75
170
} // namespace
76
171
77
172
void UniLinksDesktopPluginRegisterWithRegistrar (
@@ -80,3 +175,22 @@ void UniLinksDesktopPluginRegisterWithRegistrar(
80
175
flutter::PluginRegistrarManager::GetInstance ()
81
176
->GetRegistrar <flutter::PluginRegistrarWindows>(registrar));
82
177
}
178
+
179
+ void DispatchToUniLinksDesktop (HWND hwnd) {
180
+ int argc;
181
+ wchar_t ** argv = ::CommandLineToArgvW (::GetCommandLineW (), &argc);
182
+ if (argv == nullptr || argc < 2 ) {
183
+ return ;
184
+ }
185
+
186
+ std::wstring_convert<std::codecvt_utf8_utf16<wchar_t >> converter;
187
+ std::string url = converter.to_bytes (argv[1 ]);
188
+ ::LocalFree (argv);
189
+
190
+ COPYDATASTRUCT cds = {0 };
191
+ cds.dwData = UNI_LINKS_DESKTOP_MSG_ID;
192
+ cds.cbData = (DWORD)(strlen (url.c_str ()) + 1 );
193
+ cds.lpData = (PVOID)url.c_str ();
194
+
195
+ SendMessage (hwnd, WM_COPYDATA, 0 , (LPARAM)&cds);
196
+ }
0 commit comments