我正在尝试构建一个Flutter插件,让我可以创建Windows系统托盘图标。现在,我可以将图像设置为从
.ico
文件,或者是
default images
窗户也有。然而,我无法使用内存中的图像工作(特别是通过在颤振中绘制某些东西创建的图像)。当然,代码可以编译,在运行时我没有收到任何错误,但托盘图标将始终为空(它占用空间,工具提示也可以工作,但它完全透明/不可见)。
我使用的代码是
abridged from the AWT source code
,但我也试过
this StackOverflow answer
没用。
这是我用来创建
HICON
#pragma warning(disable : 4244)
HICON CreateIconFromBytes(HWND hWnd, int width, int height, uint32_t *bytes, TrayIcon *icon)
{
BITMAPV5HEADER bmhHeader = {0};
bmhHeader.bV5Size = sizeof(BITMAPV5HEADER);
bmhHeader.bV5Width = width;
bmhHeader.bV5Height = -height;
bmhHeader.bV5Planes = 1;
bmhHeader.bV5BitCount = 32;
bmhHeader.bV5Compression = BI_BITFIELDS;
bmhHeader.bV5RedMask = 0x00FF0000;
bmhHeader.bV5GreenMask = 0x0000FF00;
bmhHeader.bV5BlueMask = 0x000000FF;
bmhHeader.bV5AlphaMask = 0xFF000000;
char *ptrImageData = new char[width * height * 4];
auto dc = GetDC(hWnd);
HBITMAP hbmpBitmap = CreateDIBSection(dc, (BITMAPINFO *)&bmhHeader, DIB_RGB_COLORS, (void **)&ptrImageData, NULL, 0);
uint32_t *srcPtr = bytes;
char *dstPtr = ptrImageData;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
uint32_t pixel = *srcPtr++;
uint8_t alpha = (pixel >> 24) & 0xFF;
uint8_t blue = (pixel >> 16) & 0xFF;
uint8_t green = (pixel >> 8) & 0xFF;
uint8_t red = pixel & 0xFF;
*dstPtr++ = blue;
*dstPtr++ = green;
*dstPtr++ = red;
*dstPtr++ = alpha;
}
}
#pragma warning(default : 4244)
HBITMAP hBitmap = CreateDIBitmap(dc, (BITMAPINFOHEADER *)&bmhHeader, CBM_INIT, ptrImageData, (BITMAPINFO *)&bmhHeader, DIB_RGB_COLORS);
ReleaseDC(hWnd, dc);
DeleteObject(hbmpBitmap);
HBITMAP hMask = CreateBitmap(width, height, 1, 1, NULL);
ICONINFO iconInfo;
memset(&iconInfo, 0, sizeof(ICONINFO));
iconInfo.hbmMask = hMask;
iconInfo.hbmColor = hBitmap;
iconInfo.fIcon = TRUE;
iconInfo.xHotspot = 0;
iconInfo.yHotspot = 0;
HICON hIcon = CreateIconIndirect(&iconInfo);
DeleteObject(hBitmap);
DeleteObject(hMask);
return hIcon;
}
我有另一个函数,最后调用
Shell_NotifyIcon()
并采取了
希肯
作为论据。这个函数也从处理获取
希肯
从一个
.ico
文件或来自默认Windows资源(前者通过
LoadImage()
,后者通过
LoadIcon()
).
通过调试和查看内存视图,我知道
bytes
签名正是我所期望的。在Flatter中,为了进行测试,我将画布作为图像保存到磁盘,字节与我在颜色选择器中看到的颜色对齐。
在这一点上我有点崇拜货物,因为我没有得到错误;我都不知道
什么
这不管用。