You can't, it looks by design. Details are below, but in short you have three options:
- Do not return a message and a VB-friendly COM error, that is, one well-known VB runtime in accordance with this KB article ; VB runtime will translate this “COM error” into a VB error message.
- Returns an error message and DISP_E_EXCEPTION; The VB runtime will go through this “Server Error” and your error message. This is what happens implicitly in the second example, see below for details.
- Do not return a message or any other COM error, i.e. one unknown at runtime VB; the VB runtime will use raw HRESULT plus the generic message "
Method '~' of object '~' failed ".- Please note that this behavior during operation also applies if you deliver an error message here, that is, your message will simply be ignored! This is what happens in your first example, see below for details.
For this task, it comes down to two options:
- If you want to provide contextually correct "COM errors" for automation clients such as VB (and most likely you should), you should omit the error messages.
- If you want to provide custom error messages for "Server Errors" (that is, custom error conditions regarding functionality within the automation server), the only option is DISP_E_EXCEPTION.
More details
The VB runtime seems to offer only very limited processing regarding COM errors. This is probably due to historical and / or technical reasons specific to the way VB is implemented, and not of particular interest (the keywords will be IDispatch only against the dual interface and ActiveX as a “subset” of COM).
While I could not handle the explicit specification of the behavior described above, you can understand how it delved into other sources:
From an article in KB justadreamer already states :
[...] a call is made to the GetErrorInfo method to retrieve the available error information. runtime determines whether bstrDescription has a value other than ZERO. If the runtime finds a value other than NULL, [...] the raw HRESULT value is used in this script. If runtime finds a NULL value, [...] Then Visual Basic uses HRESULT to find the corresponding Visual Basic error.
This explains the behavior of your example: you sent an error message, so the runtime simply uses its generic message “ Method '~' of object '~' failed " plus your HRESULT .
The behavior of your second example is also consistent if you look at the constructor definition (first list) for CComCoClass::Error : it has default values for parameters not specified, especially "hRes = 0". The Remarks section further states that "If hRes is zero, then the first four versions of Error return DISP_E_EXCEPTION." Therefore, this implicitly raises a “Server Error” error through behavior.
Finally, for a specific example of a C ++ implementation for VB, such as the behavior of an automation client, see, for example, the paragraphs “Error handling” and the following “Exercise 5” in Automating Microsoft Office 97 and Microsoft Office 2000 .