如何将Windows的AND/XOR掩码位图转换为QCursor?
如何将Windows的AND/XOR掩码光标位图转换为QCursor?
我正在实现远程桌面协议,需要在本地客户端显示远程桌面的光标位图,涉及单色位图设置鼠标指针类型。因为需要跨平台功能,所以选用Qt的QCursor。
Win32平台实现(已成功)
在Windows平台上,我已经能用Win32 API设置带掩码的光标并达到预期效果,核心代码示例如下:
HINSTANCE inst; HCURSOR cursor = CreateCursor(inst, pCursorData->xHotspot, pCursorData->yHotspot, pCursorData->width, pCursorData->height, (void*)pCursorData->pixelData, (void*)(pCursorData->pixelData + size)); SetCursor(cursor);
初次Qt尝试(效果不符)
之后我尝试用QImage转换单色位图并配置QCursor,但结果和原生Win32 API的效果不同:
// `height` 包含两个位图(AND和XOR) int size = pCursorData->width * pCursorData->height / 2 / 8; QImage image(pCursorData->pixelData, pCursorData->width,pCursorData->height / 2,QImage::Format_Mono); QImage maskImage((pCursorData->pixelData + size), pCursorData->width,pCursorData->height / 2,QImage::Format_Mono); pixmap = QPixmap::fromImage(image); pixmap.setMask(maskBitmap); QCursor cursor(pixmap, pCursorData->xHotspot, pCursorData->yHotspot); renderWidget->setCursor(cursor);
修改后的代码尝试(仍未成功)
查阅文档后我调整了代码,根据Windows和QCursor的位图位组合规则做了映射,但还是没成功:
/** * 单色位图包含AND位图和XOR位图,1位对应1像素 * * Windows 位组合规则: * AND位图 XOR位图 显示效果 * 0 0 黑色 * 0 1 白色 * 1 0 屏幕原色 * 1 1 反色屏幕 * * QCursor 位组合规则: * 光标位图(B)和掩码(M)的位组合规则如下: * B=1 且 M=1 显示黑色。 * B=0 且 M=1 显示白色。 * B=0 且 M=0 显示透明。 * B=1 且 M=0 在Windows下显示XOR结果,其他平台结果未定义。 * 使用Qt全局颜色Qt::color0绘制位图中的0像素,Qt::color1绘制1像素。 */ int pitch = pCursorData->dataLen / pCursorData->height; bool andPixel; bool xorPixel; // `height` 包含两个位图(AND和XOR) for(int y=0; y < pCursorData->height / 2; y++) { for(int x=0; x < pCursorData->width; x++) { quint8 bitMask = 0x80 >> (x % 8); quint8 uint8_x = x / 8; // 宽度是位尺寸,转换为字节索引 andPixel = pCursorData->pixelData[y * pitch + uint8_x] & bitMask; xorPixel = pCursorData->pixelData[(y + pCursorData->height / 2) * pitch + uint8_x] & bitMask; if (!andPixel && !xorPixel) { image.setPixelColor(x, y, QColor(Qt::color1)); maskImage.setPixelColor(x, y, QColor(Qt::color1)); } else if (!andPixel && xorPixel) { image.setPixelColor(x, y, QColor(Qt::color0)); maskImage.setPixelColor(x, y, QColor(Qt::color1)); } else if (andPixel && !xorPixel) { image.setPixelColor(x, y, QColor(Qt::color0)); maskImage.setPixelColor(x, y, QColor(Qt::color0)); } else if (andPixel && xorPixel) { image.setPixelColor(x, y, QColor(Qt::color1)); maskImage.setPixelColor(x, y, QColor(Qt::color0)); } } } pixmap = QPixmap::fromImage(image); pixmap.setMask(maskBitmap); QCursor cursor(pixmap, pCursorData->xHotspot, pCursorData->yHotspot); renderWidget->setCursor(cursor);
我研究过QCursor的Qt源代码,但里面有大量位运算,短时间内难以完全理解。现在想请教:如何正确将Windows的AND掩码和XOR掩码位图转换为QCursor?
内容的提问来源于stack exchange,提问作者gao.xiangyang
相关产品推荐
相关产品推荐

