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);
81 if (view ==
nullptr) {
83 "Cursor is not available in Windows headless mode");
89 const auto& arguments = std::get<EncodableMap>(*method_call.
arguments());
92 if (name_iter == arguments.end()) {
95 "Missing argument name while trying to customize system cursor");
98 auto name = std::get<std::string>(name_iter->second);
101 if (buffer_iter == arguments.end()) {
104 "Missing argument buffer while trying to customize system cursor");
107 auto buffer = std::get<std::vector<uint8_t>>(buffer_iter->second);
110 if (width_iter == arguments.end()) {
113 "Missing argument width while trying to customize system cursor");
116 auto width = std::get<int>(width_iter->second);
119 if (height_iter == arguments.end()) {
122 "Missing argument height while trying to customize system cursor");
125 auto height = std::get<int>(height_iter->second);
128 if (hot_x_iter == arguments.end()) {
131 "Missing argument hotX while trying to customize system cursor");
134 auto hot_x = std::get<double>(hot_x_iter->second);
137 if (hot_y_iter == arguments.end()) {
140 "Missing argument hotY while trying to customize system cursor");
143 auto hot_y = std::get<double>(hot_y_iter->second);
145 if (cursor ==
nullptr) {
146 result->Error(
"Argument error",
147 "Argument must contains a valid rawBGRA bitmap");
151 custom_cursors_.emplace(name, std::move(cursor));
154 const auto& arguments = std::get<EncodableMap>(*method_call.
arguments());
157 if (name_iter == arguments.end()) {
158 result->Error(
"Argument error",
159 "Missing argument key while trying to set a custom cursor");
162 auto name = std::get<std::string>(name_iter->second);
163 if (custom_cursors_.find(name) == custom_cursors_.end()) {
166 "The custom cursor identified by the argument key cannot be found");
169 HCURSOR cursor = custom_cursors_[name];
174 if (view ==
nullptr) {
176 "Cursor is not available in Windows headless mode");
182 const auto& arguments = std::get<EncodableMap>(*method_call.
arguments());
185 if (name_iter == arguments.end()) {
188 "Missing argument key while trying to delete a custom cursor");
191 auto name = std::get<std::string>(name_iter->second);
192 auto it = custom_cursors_.find(name);
195 if (it != custom_cursors_.end()) {
196 DeleteObject(it->second);
197 custom_cursors_.erase(it);
201 result->NotImplemented();
210 HCURSOR cursor =
nullptr;
211 HDC display_dc = GetDC(NULL);
214 memset(&bmi, 0,
sizeof(bmi));
215 bmi.bmiHeader.biSize =
sizeof(BITMAPINFOHEADER);
216 bmi.bmiHeader.biWidth = width;
217 bmi.bmiHeader.biHeight = -height;
218 bmi.bmiHeader.biPlanes = 1;
219 bmi.bmiHeader.biBitCount = 32;
220 bmi.bmiHeader.biCompression = BI_RGB;
221 bmi.bmiHeader.biSizeImage = width * height * 4;
225 CreateDIBSection(display_dc, &bmi, DIB_RGB_COLORS, (
void**)&pixels, 0, 0);
226 ReleaseDC(0, display_dc);
227 if (!bitmap || !pixels) {
230 int bytes_per_line = width * 4;
231 for (
int y = 0; y < height; ++y) {
232 memcpy(pixels + y * bytes_per_line, &buffer[bytes_per_line * y],
239 icon_info.xHotspot = hot_x;
240 icon_info.yHotspot = hot_y;
241 icon_info.hbmMask = mask;
242 icon_info.hbmColor = bitmap;
243 cursor = CreateIconIndirect(&icon_info);
245 DeleteObject(bitmap);
250 HDC h_dc = ::GetDC(NULL);
251 HDC h_main_dc = ::CreateCompatibleDC(h_dc);
252 HDC h_and_mask_dc = ::CreateCompatibleDC(h_dc);
256 ::GetObject(bitmap,
sizeof(BITMAP), &bm);
257 mask_bitmap = ::CreateCompatibleBitmap(h_dc, bm.bmWidth, bm.bmHeight);
260 HBITMAP h_old_main_bitmap = (HBITMAP)::SelectObject(h_main_dc, bitmap);
261 HBITMAP h_old_and_mask_bitmap =
262 (HBITMAP)::SelectObject(h_and_mask_dc, mask_bitmap);
265 COLORREF main_bit_pixel;
266 for (
int x = 0; x < bm.bmWidth; ++x) {
267 for (
int y = 0; y < bm.bmHeight; ++y) {
268 main_bit_pixel = ::GetPixel(h_main_dc, x, y);
269 if (main_bit_pixel == RGB(0, 0, 0)) {
270 ::SetPixel(h_and_mask_dc, x, y, RGB(255, 255, 255));
272 ::SetPixel(h_and_mask_dc, x, y, RGB(0, 0, 0));
276 ::SelectObject(h_main_dc, h_old_main_bitmap);
277 ::SelectObject(h_and_mask_dc, h_old_and_mask_bitmap);
279 ::DeleteDC(h_and_mask_dc);
280 ::DeleteDC(h_main_dc);
282 ::ReleaseDC(NULL, h_dc);