简体   繁体   中英

How can I (is there a way to) convert an HRESULT into a system specific error message?

According to this , there's no way to convert a HRESULT error code into a Win32 error code. Therefore (at least to my understanding), my use of FormatMessage in order to generate error messages (ie

std::wstring Exception::GetWideMessage() const
{
    using std::tr1::shared_ptr;
    shared_ptr<void> buff;
    LPWSTR buffPtr;
    DWORD bufferLength = FormatMessageW(
        FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        GetErrorCode(),
        0,
        reinterpret_cast<LPWSTR>(&buffPtr),
        0,
        NULL);
    buff.reset(buffPtr, LocalFreeHelper());
    return std::wstring(buffPtr, bufferLength);
}

) does not work for HRESULTs.

How do I generate these kinds of system-specific error strings for HRESULTs?

This answer incorporates Raymond Chen's ideas, and correctly discerns the incoming HRESULT, and returns an error string using the correct facility to obtain the error message:

/////////////////////////////
// ComException

CString FormatMessage(HRESULT result)
{
    CString strMessage;
    WORD facility = HRESULT_FACILITY(result);
    CComPtr<IErrorInfo> iei;
    if (S_OK == GetErrorInfo(0, &iei) && iei)
    {
        // get the error description from the IErrorInfo 
        BSTR bstr = NULL;
        if (SUCCEEDED(iei->GetDescription(&bstr)))
        {
            // append the description to our label
            strMessage.Append(bstr);

            // done with BSTR, do manual cleanup
            SysFreeString(bstr);
        }
    }
    else if (facility == FACILITY_ITF)
    {
        // interface specific - no standard mapping available
        strMessage.Append(_T("FACILITY_ITF - This error is interface specific.  No further information is available."));
    }
    else
    {
        // attempt to treat as a standard, system error, and ask FormatMessage to explain it
        CString error;
        CErrorMessage::FormatMessage(error, result); // <- This is just a wrapper for ::FormatMessage, left to reader as an exercise :)
        if (!error.IsEmpty())
            strMessage.Append(error);
    }
    return strMessage;
}

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