首页 > 解决方案 > 如何在写入图标(.ico)时为鼠标光标应用遮罩

问题描述

GetCursorInfo用来捕获光标,但在将光标保存为图标时,图标上会出现一些黑色矩形。

对于 windows 默认光标很好,但很少有自定义光标我面临这个问题http://www.cursors-4u.com/

在链接https://www.google.com/search?q=cursor+icon&rlz=1C1CHBD_enIN789IN789&source=lnms&tbm=isch&sa=X&ved=0ahUKEwix9aj_gq_iAhWCXCsKHcusD0oQ_AUIDigB&biw=1366&bih=657#imgrc=rOxlbRoBfnKs8M中放置了一个示例光标图标

HRESULT SaveIcon(HICON hIcon, const char* path) 
{
    // Create the IPicture intrface
    PICTDESC desc = { sizeof(PICTDESC) };
    desc.picType = PICTYPE_ICON;
    desc.icon.hicon = hIcon;
    IPicture* pPicture = 0;
    HRESULT hr = OleCreatePictureIndirect(&desc, IID_IPicture, FALSE, (void**)&pPicture);
    if (FAILED(hr)) return hr;

    // Create a stream and save the image
    IStream* pStream = 0;
    CreateStreamOnHGlobal(0, TRUE, &pStream);
    LONG cbSize = 0;
    hr = pPicture->SaveAsFile(pStream, TRUE, &cbSize);

    // Write the stream content to the file
    if (!FAILED(hr)) 
    {
        HGLOBAL hBuf = 0;
        GetHGlobalFromStream(pStream, &hBuf);
        void* buffer = GlobalLock(hBuf);
        HANDLE hFile = CreateFileA(path, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
        if (!hFile) 
        {
            hr = HRESULT_FROM_WIN32(GetLastError());
        }
        else 
        {
            DWORD written = 0;
            WriteFile(hFile, buffer, cbSize, &written, 0);
            CloseHandle(hFile);
        }
        GlobalUnlock(buffer);
    }
    // Cleanup
    pStream->Release();
    pPicture->Release();
    return hr;
}

//Capture cursor.
CURSORINFO getHCursor()
{
  CURSORINFO cursorInfo;
  cursorInfo.cbSize = sizeof(CURSORINFO);

  if (GetCursorInfo(&cursorInfo) == 0) 
  { 
    MessageBox(NULL, _T("Exception : GetCursorInfo creation failed"),_T("message"),MB_OK|MB_SYSTEMMODAL);       
    cursorInfo.hCursor = NULL;
    return cursorInfo;
  }

  return cursorInfo;
}

//Main Call
int _tmain(int argc, _TCHAR* argv[])
{
    while (true)
    {
        CURSORINFO CursorInfo = getHCursor();
        if (CursorInfo.hCursor == NULL) 
        {           
            ::Sleep(MinSleep);
            continue;
        }       

        SaveIcon((HICON)CursorInfo.hCursor, "C:\\Users\\Desktop\\myicon.ico");

        Sleep(MaxSleep);
    }   
    return 0;
}

我的议程是捕获光标并将光标保存到图标(.ico)文件或加载到缓冲区。

有没有其他方法可以将光标数据写入图标文件或缓冲区?

标签: c++winapicursor

解决方案


ICONINFO结构包含两个成员hbmMaskhbmColor,它们分别包含光标的掩码和颜色位图(有关官方文档,请参见MSDN页面ICONINFO)。

当您调用GetIconInfo()默认光标时,该ICONINFO结构包含有效的掩码和颜色位图。

可能有一种更好的方法来呈现 BitBlt()- BitBlt()-MakeTransparent()方法组合调用的光标。

参考@Tarsier的做法,虽然是C#,但是思路是一样的。

链接:捕获鼠标光标图像


推荐阅读