我们有什么办法可以将 HICON
或 HCURSOR
转换为字节数组吗?我用谷歌搜索了所有方法,但没有找到一个通用的解决方案,下面我尝试转换HICON
颜色和掩码 BITMAP 到字节数组,并通过套接字发送它并使用 CreateIconIndirect
API 创建我的图标,但如果我能够发送 直接 >HICON
就好了。
int ProcessMouse()
{
BYTE m_hbmMaskBits[70000];
BYTE m_hbmColorBits[70000];
CURSORINFO CursorInfo;
CursorInfo.cbSize = sizeof(CursorInfo);
GetCursorInfo(&CursorInfo);
ICONINFO iconInfo;
if (!GetIconInfo(CursorInfo.hCursor, &iconInfo))
{
MessageBox(NULL, _T("CreateCursor Failed"),_T("message"),MB_OK|MB_SYSTEMMODAL);
}
bool isColorShape = (iconInfo.hbmColor != NULL);
bool isMaskShape = (iconInfo.hbmMask != NULL);
LONG cbSize = 0; int nWidth = 0; int nHeight = 0; int actualHeight = 0; int bmPlanes = 0;
int bmBitsPixel = 0; int xHotspot = 0; int yHotspot = 0; int widthBytes = 0;
// Return width,height,actualheight,bmplanes,bmbitspixel,hotsopt of cursor.
if(!CopyIconInfo( CursorInfo.hCursor,
nWidth,
nHeight,
actualHeight,
bmPlanes,
bmBitsPixel,
xHotspot,
yHotspot,
widthBytes ))
{
return 0;
}
std::vector<BYTE> bColor;
std::vector<BYTE> bMask;
int sz_hbmColor = 0;
int sz_hbmMask = 0;
_tempWidth = nWidth;
_tempHeight = nHeight;
//If HCURSOR have both color and mask go with regular approach.
if(isColorShape)
{
//Convert iconInfo.hbmColor HBITMAP to Byte array.
bColor = HBIMAPtoBYTE(iconInfo.hbmColor,sz_hbmColor);
//Convert iconInfo.hbmMask HBITMAP to Byte array.
bMask = HBIMAPtoBYTE(iconInfo.hbmMask,sz_hbmMask);
}
// If HCURSOR have only mask data go with new approach(split mask bitmap to color and mask).
else if(isMaskShape)
{
std::vector<BYTE> bSrcBitmap;
int sz_hbmBitmap = 0;
//Convert iconInfo.hbmMask HBITMAP to Byte array.
bSrcBitmap = HBIMAPtoBYTE(iconInfo.hbmMask,sz_hbmBitmap);
sz_hbmColor = sz_hbmBitmap/2;
sz_hbmMask = sz_hbmBitmap/2;
bMask.resize(bMask.size() + sz_hbmBitmap/2);
memcpy(&bMask[bSrcBitmap.size() - sz_hbmBitmap], &bSrcBitmap[0], sz_hbmBitmap/2 * sizeof(BYTE));
bColor.resize(bColor.size() + sz_hbmBitmap/2);
memcpy(&bColor[bSrcBitmap.size() - sz_hbmBitmap], &bSrcBitmap[sz_hbmBitmap/2], sz_hbmBitmap/2 * sizeof(BYTE));
//Clear at end.
bSrcBitmap.clear();
}
try{
err = memcpy_s((m_hbmMaskBits), sz_hbmMask, &(bMask[0]), sz_hbmMask );
err = memcpy_s((m_hbmColorBits),sz_hbmColor,&(bColor[0]),sz_hbmColor);
//Clear at end.
bMask.clear();
bColor.clear();
return 1;
}catch(...) {
if(err) {
MessageBox(NULL, _T("memcopy failed at mask or color copy"),_T("message"),MB_OK|MB_SYSTEMMODAL);
}
}
}
我尝试了以下方式,但它不支持少数单色光标。
PICTDESC pd = {sizeof(pd), PICTYPE_ICON};
pd.icon.hicon = CursorInfo.hCursor;
CComPtr<IPicture> pPict = NULL;
CComPtr<IStream> pStrm = NULL;
BOOL res = FALSE;
res = SUCCEEDED( ::CreateStreamOnHGlobal(NULL, TRUE, &pStrm) );
res = SUCCEEDED( ::OleCreatePictureIndirect(&pd, IID_IPicture, TRUE, (void**)&pPict) );
res = SUCCEEDED( pPict->SaveAsFile( pStrm, TRUE, &cbSize ) );
if( res )
{
// rewind stream to the beginning
LARGE_INTEGER li = {0};
pStrm->Seek(li, STREAM_SEEK_SET, NULL);
// write to file
DWORD dwWritten = 0, dwRead = 0, dwDone = 0;
while( dwDone < cbSize )
{
if( SUCCEEDED(pStrm->Read(bCursorBuff, sizeof(bCursorBuff), &dwRead)) )
{
dwDone += dwRead;
}
}
_ASSERTE(dwDone == cbSize);
}
//End of Cursor image
pStrm.Release();
pPict.Release();
最佳答案
HICON 和 HCURSOR 是系统句柄,因此它们仅适用于当前计算机。
通过网络只能发送实际数据(位图字节)。然后该机器可以为其创建自己的句柄。
使用 HBITMAP 字节是正确的方法。您可以在这里找到一些详细信息: How to convert HICON to HBITMAP in VC++?
您可以使用 GetDIBits() 获取原始 HBITMAP 位。更多信息:C++/Win32: How to get the alpha channel from an HBITMAP?
关于c++ - 将 HICON/HCURSOR 复制到字节数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57688782/