You can use _com_error:
_com_error err(hr);
LPCTSTR errMsg = err.ErrorMessage();
If you don’t want to use _com_error
for whatever reason, you can still take a look at its source, and see how it’s done.
Don’t forget to include the header comdef.h