该任务的实质如下:您需要使用 xlib 从应用程序窗口中获取一个图标,并将其放置在 wxIcon 对象(或 wxImage 或 wxBitmap - 没关系)中。正如我所发现的,有两种方法可以做到这一点:使用窗口的属性_NET_WM_ICON
或使用调用XGetWMHints
来获取对象XWMHints
,然后从中获取icon_pixmap
。但是,使用第二种方法,从一开始就出现了问题:icon_pixmap
它被定义为正常unsigned long
的,我没有找到如何从那里获取图标的 XPM 内容。这是我实现第一个选项的尝试:
void ApplicationHelper::GetIcon(SRunningWindow* pDesc, void* pDisplay,
TWindow iWindow, unsigned long uiIconAtom)
{
unsigned long nitems, bytesafter;
unsigned char *ret;
int format;
Atom type;
XGetWindowProperty((Display*) pDisplay, iWindow, uiIconAtom, 0, 1, 0, AnyPropertyType, &type, &format, &nitems, &bytesafter, &ret);
int width = *(int*)ret;
XFree(ret);
XGetWindowProperty((Display*) pDisplay, iWindow, uiIconAtom, 1, 1, 0, AnyPropertyType, &type, &format, &nitems, &bytesafter, &ret);
int height = *(int*)ret;
XFree(ret);
int size = width * height;
XGetWindowProperty((Display*) pDisplay, iWindow, uiIconAtom, 2, size, 0, AnyPropertyType, &type, &format, &nitems, &bytesafter, &ret);
unsigned char* imgData = new unsigned char[width * height * 3]; // RGB data
unsigned char* alphaData = new unsigned char[width * height]; // alpha chanel
int offset = sizeof(long) == 8 ? 8 : 4; // for 64bit systems data represented in order: blue, green, red, alpha, followed by 4 zeros
int imgIdx = 0;
int alphaIdx = 0;
for (int i=0; i < nitems; i += offset)
{
imgData[imgIdx] = ret[i + 2]; // R
imgData[imgIdx + 1] = ret[i + 1]; // G
imgData[imgIdx + 2] = ret[i]; // B
alphaData[alphaIdx++] = ret[i + 3]; // A
imgIdx += 3;
}
XFree(ret);
wxImage img(width, height, imgData, alphaData);
img.Rescale(16, 16);
wxBitmap bmp(img);
pDesc->icon.CopyFromBitmap(bmp);
}
在它的帮助下,结果显示出某种图片,但它与应用程序所拥有的完全不同:
前三个窗口应该是终端图标,如下所示:
但事实上,事实证明有些事情是不对的。看起来他的一切都是按照规范去做的,但到头来却是一派胡言。有人能告诉我我的实现有什么问题或如何从中获取图标的 XPM 内容icon_pixmap
吗?谢谢你。
万一其他人遇到这个问题,这里是对我有用的解决方案。这个想法是从图标的 ARGB 表示中组装 wxImage,不要忘记 _NET_WM_ICON 返回 BGRA 格式的内容。