20 "createCustomCursor/windows";
42 "deleteCustomCursor/windows";
56 channel_->SetMethodCallHandler(
59 HandleMethodCall(call, std::move(result));
63 void CursorHandler::HandleMethodCall(
66 const std::string& method = method_call.
method_name();
68 const auto& arguments = std::get<EncodableMap>(*method_call.
arguments());
70 if (kind_iter == arguments.end()) {
71 result->Error(
"Argument error",
72 "Missing argument while trying to activate system cursor");
75 const auto& kind = std::get<std::string>(kind_iter->second);
79 const auto& arguments = std::get<EncodableMap>(*method_call.
arguments());
82 if (name_iter == arguments.end()) {
85 "Missing argument name while trying to customize system cursor");
88 auto name = std::get<std::string>(name_iter->second);
91 if (buffer_iter == arguments.end()) {
94 "Missing argument buffer while trying to customize system cursor");
97 auto buffer = std::get<std::vector<uint8_t>>(buffer_iter->second);
100 if (width_iter == arguments.end()) {
103 "Missing argument width while trying to customize system cursor");
106 auto width = std::get<int>(width_iter->second);
109 if (height_iter == arguments.end()) {
112 "Missing argument height while trying to customize system cursor");
115 auto height = std::get<int>(height_iter->second);
118 if (hot_x_iter == arguments.end()) {
121 "Missing argument hotX while trying to customize system cursor");
124 auto hot_x = std::get<double>(hot_x_iter->second);
127 if (hot_y_iter == arguments.end()) {
130 "Missing argument hotY while trying to customize system cursor");
133 auto hot_y = std::get<double>(hot_y_iter->second);
135 if (cursor ==
nullptr) {
136 result->Error(
"Argument error",
137 "Argument must contains a valid rawBGRA bitmap");
141 custom_cursors_.emplace(name, std::move(cursor));
144 const auto& arguments = std::get<EncodableMap>(*method_call.
arguments());
147 if (name_iter == arguments.end()) {
148 result->Error(
"Argument error",
149 "Missing argument key while trying to set a custom cursor");
152 auto name = std::get<std::string>(name_iter->second);
153 if (custom_cursors_.find(name) == custom_cursors_.end()) {
156 "The custom cursor identified by the argument key cannot be found");
159 HCURSOR cursor = custom_cursors_[name];
163 const auto& arguments = std::get<EncodableMap>(*method_call.
arguments());
166 if (name_iter == arguments.end()) {
169 "Missing argument key while trying to delete a custom cursor");
172 auto name = std::get<std::string>(name_iter->second);
173 auto it = custom_cursors_.find(name);
176 if (it != custom_cursors_.end()) {
177 DeleteObject(it->second);
178 custom_cursors_.erase(it);
182 result->NotImplemented();
191 HCURSOR cursor =
nullptr;
192 HDC display_dc = GetDC(NULL);
195 memset(&bmi, 0,
sizeof(bmi));
196 bmi.bmiHeader.biSize =
sizeof(BITMAPINFOHEADER);
197 bmi.bmiHeader.biWidth = width;
198 bmi.bmiHeader.biHeight = -height;
199 bmi.bmiHeader.biPlanes = 1;
200 bmi.bmiHeader.biBitCount = 32;
201 bmi.bmiHeader.biCompression = BI_RGB;
202 bmi.bmiHeader.biSizeImage = width * height * 4;
206 CreateDIBSection(display_dc, &bmi, DIB_RGB_COLORS, (
void**)&pixels, 0, 0);
207 ReleaseDC(0, display_dc);
208 if (!bitmap || !pixels) {
211 int bytes_per_line = width * 4;
212 for (
int y = 0; y < height; ++y) {
213 memcpy(pixels + y * bytes_per_line, &buffer[bytes_per_line * y],
220 icon_info.xHotspot = hot_x;
221 icon_info.yHotspot = hot_y;
222 icon_info.hbmMask = mask;
223 icon_info.hbmColor = bitmap;
224 cursor = CreateIconIndirect(&icon_info);
226 DeleteObject(bitmap);
231 HDC h_dc = ::GetDC(NULL);
232 HDC h_main_dc = ::CreateCompatibleDC(h_dc);
233 HDC h_and_mask_dc = ::CreateCompatibleDC(h_dc);
237 ::GetObject(bitmap,
sizeof(BITMAP), &bm);
238 mask_bitmap = ::CreateCompatibleBitmap(h_dc, bm.bmWidth, bm.bmHeight);
241 HBITMAP h_old_main_bitmap = (HBITMAP)::SelectObject(h_main_dc, bitmap);
242 HBITMAP h_old_and_mask_bitmap =
243 (HBITMAP)::SelectObject(h_and_mask_dc, mask_bitmap);
246 COLORREF main_bit_pixel;
247 for (
int x = 0; x < bm.bmWidth; ++x) {
248 for (
int y = 0; y < bm.bmHeight; ++y) {
249 main_bit_pixel = ::GetPixel(h_main_dc, x, y);
250 if (main_bit_pixel == RGB(0, 0, 0)) {
251 ::SetPixel(h_and_mask_dc, x, y, RGB(255, 255, 255));
253 ::SetPixel(h_and_mask_dc, x, y, RGB(0, 0, 0));
257 ::SelectObject(h_main_dc, h_old_main_bitmap);
258 ::SelectObject(h_and_mask_dc, h_old_and_mask_bitmap);
260 ::DeleteDC(h_and_mask_dc);
261 ::DeleteDC(h_main_dc);
263 ::ReleaseDC(NULL, h_dc);
CursorHandler(flutter::BinaryMessenger *messenger, flutter::FlutterWindowsEngine *engine)
void UpdateFlutterCursor(const std::string &cursor_name) const
void SetFlutterCursor(HCURSOR cursor) const
const std::string & method_name() const
const T * arguments() const
static constexpr char kDeleteCustomCursorMethod[]
static constexpr char kActivateSystemCursorMethod[]
static constexpr char kCustomCursorHotXKey[]
static constexpr char kCustomCursorWidthKey[]
static constexpr char kKindKey[]
static constexpr char kChannelName[]
static constexpr char kCustomCursorHotYKey[]
static constexpr char kCustomCursorNameKey[]
static constexpr char kCreateCustomCursorMethod[]
static constexpr char kSetCustomCursorMethod[]
static constexpr char kCustomCursorBufferKey[]
static constexpr char kCursorError[]
static constexpr char kCustomCursorHeightKey[]
void GetMaskBitmaps(HBITMAP bitmap, HBITMAP &mask_bitmap)
HCURSOR GetCursorFromBuffer(const std::vector< uint8_t > &buffer, double hot_x, double hot_y, int width, int height)