21 "createCustomCursor/windows";
43 "deleteCustomCursor/windows";
57 channel_->SetMethodCallHandler(
60 HandleMethodCall(call, std::move(result));
64 void CursorHandler::HandleMethodCall(
67 const std::string& method = method_call.
method_name();
69 const auto& arguments = std::get<EncodableMap>(*method_call.
arguments());
71 if (kind_iter == arguments.end()) {
72 result->Error(
"Argument error",
73 "Missing argument while trying to activate system cursor");
76 const auto& kind = std::get<std::string>(kind_iter->second);
77 FlutterWindowsView* view = engine_->
view();
78 if (view ==
nullptr) {
80 "Cursor is not available in Windows headless mode");
86 const auto& arguments = std::get<EncodableMap>(*method_call.
arguments());
89 if (name_iter == arguments.end()) {
92 "Missing argument name while trying to customize system cursor");
95 auto name = std::get<std::string>(name_iter->second);
98 if (buffer_iter == arguments.end()) {
101 "Missing argument buffer while trying to customize system cursor");
104 auto buffer = std::get<std::vector<uint8_t>>(buffer_iter->second);
107 if (width_iter == arguments.end()) {
110 "Missing argument width while trying to customize system cursor");
113 auto width = std::get<int>(width_iter->second);
116 if (height_iter == arguments.end()) {
119 "Missing argument height while trying to customize system cursor");
122 auto height = std::get<int>(height_iter->second);
125 if (hot_x_iter == arguments.end()) {
128 "Missing argument hotX while trying to customize system cursor");
131 auto hot_x = std::get<double>(hot_x_iter->second);
134 if (hot_y_iter == arguments.end()) {
137 "Missing argument hotY while trying to customize system cursor");
140 auto hot_y = std::get<double>(hot_y_iter->second);
142 if (cursor ==
nullptr) {
143 result->Error(
"Argument error",
144 "Argument must contains a valid rawBGRA bitmap");
148 custom_cursors_.emplace(name, std::move(cursor));
151 const auto& arguments = std::get<EncodableMap>(*method_call.
arguments());
154 if (name_iter == arguments.end()) {
155 result->Error(
"Argument error",
156 "Missing argument key while trying to set a custom cursor");
159 auto name = std::get<std::string>(name_iter->second);
160 if (custom_cursors_.find(name) == custom_cursors_.end()) {
163 "The custom cursor identified by the argument key cannot be found");
166 HCURSOR cursor = custom_cursors_[name];
167 FlutterWindowsView* view = engine_->
view();
168 if (view ==
nullptr) {
170 "Cursor is not available in Windows headless mode");
176 const auto& arguments = std::get<EncodableMap>(*method_call.
arguments());
179 if (name_iter == arguments.end()) {
182 "Missing argument key while trying to delete a custom cursor");
185 auto name = std::get<std::string>(name_iter->second);
186 auto it = custom_cursors_.find(name);
189 if (it != custom_cursors_.end()) {
190 DeleteObject(it->second);
191 custom_cursors_.erase(it);
195 result->NotImplemented();
204 HCURSOR cursor =
nullptr;
205 HDC display_dc = GetDC(NULL);
208 memset(&bmi, 0,
sizeof(bmi));
209 bmi.bmiHeader.biSize =
sizeof(BITMAPINFOHEADER);
210 bmi.bmiHeader.biWidth = width;
211 bmi.bmiHeader.biHeight = -height;
212 bmi.bmiHeader.biPlanes = 1;
213 bmi.bmiHeader.biBitCount = 32;
214 bmi.bmiHeader.biCompression = BI_RGB;
215 bmi.bmiHeader.biSizeImage = width * height * 4;
219 CreateDIBSection(display_dc, &bmi, DIB_RGB_COLORS, (
void**)&pixels, 0, 0);
220 ReleaseDC(0, display_dc);
221 if (!bitmap || !pixels) {
224 int bytes_per_line = width * 4;
225 for (
int y = 0; y < height; ++y) {
226 memcpy(pixels + y * bytes_per_line, &buffer[bytes_per_line * y],
233 icon_info.xHotspot = hot_x;
234 icon_info.yHotspot = hot_y;
235 icon_info.hbmMask = mask;
236 icon_info.hbmColor = bitmap;
237 cursor = CreateIconIndirect(&icon_info);
239 DeleteObject(bitmap);
244 HDC h_dc = ::GetDC(NULL);
245 HDC h_main_dc = ::CreateCompatibleDC(h_dc);
246 HDC h_and_mask_dc = ::CreateCompatibleDC(h_dc);
250 ::GetObject(bitmap,
sizeof(BITMAP), &bm);
251 mask_bitmap = ::CreateCompatibleBitmap(h_dc, bm.bmWidth, bm.bmHeight);
254 HBITMAP h_old_main_bitmap = (HBITMAP)::SelectObject(h_main_dc, bitmap);
255 HBITMAP h_old_and_mask_bitmap =
256 (HBITMAP)::SelectObject(h_and_mask_dc, mask_bitmap);
259 COLORREF main_bit_pixel;
260 for (
int x = 0; x < bm.bmWidth; ++x) {
261 for (
int y = 0; y < bm.bmHeight; ++y) {
262 main_bit_pixel = ::GetPixel(h_main_dc, x, y);
263 if (main_bit_pixel == RGB(0, 0, 0)) {
264 ::SetPixel(h_and_mask_dc, x, y, RGB(255, 255, 255));
266 ::SetPixel(h_and_mask_dc, x, y, RGB(0, 0, 0));
270 ::SelectObject(h_main_dc, h_old_main_bitmap);
271 ::SelectObject(h_and_mask_dc, h_old_and_mask_bitmap);
273 ::DeleteDC(h_and_mask_dc);
274 ::DeleteDC(h_main_dc);
276 ::ReleaseDC(NULL, h_dc);