简体   繁体   中英

How to read HICON into a wchar array?

I've been trying to get string representation of HICON. I was able to get the HICON from here . I'm able to save it to a file using this answer . I know I can save to to a temp file and read and get the bytes, but I want to directly convert the stream into byte array. When I do a IStream::Read or IStream_Read , I consistently get Zero bytes. Can you tell me what I'm doing wrong or point me to some documentation on the same?

The following is the code that I've been working on:

std::wstring get_str(HICON hIcon) {
    // 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 L"Erorr creating empty pic";

    // Create a stream and save the image
    IStream *pStream = 0;
    // Use SHCreateMemStream?
    // https://docs.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-shcreatememstream
    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;
        std::wstring ret;
        char buffer[4096];
        hr = IStream_Read(pStream, &buffer, cbSize);
        if (FAILED(hr))
            return L"Uneven reading from buffer";  // + std::to_wstring(cbSize) + L" " + std::to_wstring(read_size);
        return L"Success";                         // std::wstring(buffer);
    }
    // Cleanup
    pStream->Release();
    pPicture->Release();
    return L"Fail fail fail";
}

You need to seek the stream's read position to the beginning of the stream after saving and before reading.

The following code works for me:

std::wstring get_str(HICON hIcon) {
    // 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 L"Erorr creating empty pic";
    // Create a stream and save the image
    IStream* pStream;
    // Use SHCreateMemStream?
    // https://docs.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-shcreatememstream

    if (SUCCEEDED(CreateStreamOnHGlobal(0, TRUE, &pStream)))
    {
        LONG cbSize = 0;
        hr = pPicture->SaveAsFile(pStream, TRUE, &cbSize);
        LARGE_INTEGER li;
        li.HighPart = 0;
        li.LowPart = 0;
        HRESULT hrr = pStream->Seek(li, STREAM_SEEK_SET, NULL);
        // Write the stream content to the file
        if (SUCCEEDED(hr)) {
            HGLOBAL hBuf = 0;
            std::wstring ret;
            char buffer[4096] = "";
            ULONG ll = 0;
            hr = pStream->Read(buffer, cbSize, &ll);
            if (FAILED(hr))
            {
                pStream->Release();
                pPicture->Release();
                return L"Uneven reading from buffer";  // + std::to_wstring(cbSize) + L" " + std::to_wstring(read_size);
            }
            pStream->Release();
            pPicture->Release();
            return L"Success";                         // std::wstring(buffer);
        }
        // Cleanup
        pStream->Release();
        pPicture->Release();
        
    }
    else
    {
        pPicture->Release();
        return L"Fail fail fail";
    }
}

@SimonMourier Gave the answer in the comments. For anyone looking for code:

std::wstring get_str(HICON hIcon) {
    // Create the IPicture interface
    PICTDESC desc = {sizeof(PICTDESC)};
    desc.picType = PICTYPE_ICON;
    desc.icon.hicon = hIcon;
    // Create an ATL smart pointer.
    CComPtr<IPicture> pPicture;
    LONG cbSize = 0;
    BYTE buffer[4096];
    // Create a Smart pointer stream and save the image
    IStreamPtr pStream;

    if (FAILED(OleCreatePictureIndirect(&desc, IID_IPicture, FALSE, (void **)&pPicture))) {
        LOG_EXCEPTION(L"Unable to create an empty image");
        return L"";
    }
    // Use SHCreateMemStream?
    // https://docs.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-shcreatememstream
    if (FAILED(CreateStreamOnHGlobal(0, TRUE, &pStream))) {
        LOG_EXCEPTION(L"Unable to create stream for icon.");
        return L"";
    }
    if (FAILED(pPicture->SaveAsFile(pStream, TRUE, &cbSize))) {
        LOG_EXCEPTION(L"Error saving as IPicture.");
        return L"";
    }
    if (IStream_Reset(pStream) != S_OK) {
        LOG_EXCEPTION(L"Error Seeking");
        return L"";
    }

    if (IStream_Read(pStream, &buffer, cbSize) != S_OK) {
        LOG_EXCEPTION(L"Uneven reading from buffer.");
        return L"";
    }
    std::vector<BYTE> data(buffer, buffer + (cbSize / sizeof(BYTE)));

    // Here some function could be type conversion or post processing
    std::wstring ans = some_function(data);

    return ans;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM