I've already shown some simple error handling, using the SUCCEEDED
and FAILED
macros. Now I'll give some more details on what to do with the HRESULT
s returned from COM methods.
An HRESULT
is a 32-bit signed integer, with nonnegative values indicating success, and negative values indicating failure. An HRESULT
has three fields: the severity bit (to indicate success or failure), the facility code, and the status code. The "facility" indicates what component or program theHRESULT
is coming from. Microsoft assigns facility codes to the various components, for exampleCOM has one, the Task Scheduler has one, and so on. The "code" is a 16-bit field that has no intrinsic meaning; the codes are just an arbitrary association between a number and a meaning, just like the values returned by GetLastError()
.
If you look up error codes in the winerror.h
file, you'll see a lot of HRESULT
s listed, with the naming convention [facility]_[severity]_[description]. Generic HRESULT
s that can be returned by anycomponent (like E_OUTOFMEMORY
) have no facility in their name. Examples:
REGDB_E_READREGDB
: Facility = REGDB, for "registry database"; E = error; READREGDB is a description of the error (couldn't read the database).S_OK
: Facility = generic; S = success; OK is a description of the status (everything's OK).
Fortunately, there are easier ways to determine the meaning of an HRESULT
than looking throughwinerror.h
. HRESULT
s for built-in facilities can be looked up with the Error Lookup tool. For example, say you forgot to call CoInitialize()
before CoCreateInstance()
.CoCreateInstance()
will return a value of 0x800401F0. You can enter that value into Error Lookup and you'll see the description: "CoInitialize has not been called."
You can also look up HRESULT
descriptions in the debugger. If you have an HRESULT
variable calledhres
, you can view the description in the Watch window by entering "hres,hr" as the value to watch. The ",hr" tells VC to display the value as an HRESULT
description.