18.04.2015 Views

ArcGIS Engine Developer Guide

ArcGIS Engine Developer Guide

ArcGIS Engine Developer Guide

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

VISUAL C++<br />

.ocx files. While it is possible to engineer a header file from a type library, it is a<br />

tedious process. The #import command automates the creation of the necessary<br />

files required by the compiler. Since the command was developed to support<br />

DTC, when using it to import <strong>ArcGIS</strong> type libraries, there are a number of<br />

parameters that must be passed so the correct import takes place. For further<br />

information on this process, see the later section ‘Importing <strong>ArcGIS</strong> type libraries’.<br />

Handling errors in ATL<br />

It is possible to just return an E_FAIL HRESULT code to indicate the failure<br />

within a method; however, this does not give the caller any indication of the<br />

nature of the failure. There are a number of Windows-standard HRESULTs<br />

available, for example, E_INVALIDARG (one or more arguments are invalid)<br />

and E_POINTER (invalid pointer). These error codes are listed in the window<br />

header file winerror.h. Not all development environments have comprehensive<br />

support for HRESULT; Visual Basic clients often see error results as “Automation<br />

Error—Unspecified Error”. ATL provides a simple mechanism for working with<br />

the COM error information object that can provide an error string description, as<br />

well as an error code.<br />

When creating an ATL object, the Object wizard has an option to support<br />

ISupportErrorInfo. If you toggle the option on, when the wizard completes, your<br />

object will implement the interface ISupportErrorInfo, and a method will be added<br />

that looks something like this:<br />

STDMETHODIMP MyClass::InterfaceSupportsErrorInfo(REFIID riid)<br />

{<br />

static const IID* arr[] =<br />

{<br />

&IID_IMyClass,<br />

};<br />

for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)<br />

{<br />

if (InlineIsEqualGUID(*arr[i], riid))<br />

return S_OK;<br />

}<br />

Although Visual C++ does support an exception<br />

mechanism (try ... catch), it is not recommended<br />

to mix this with COM code. If an exception<br />

unwinds out of a COM interface, there is no<br />

guarantee the client will be able to catch this,<br />

and the most likely result is a crash.<br />

}<br />

return S_FALSE;<br />

It is now possible to return rich error messages by calling one of the ATL error<br />

functions. These functions even work with resource files to ensure easy internationalization<br />

of the message strings.<br />

// Return a simple string.<br />

AtlReportError(CLSID_MyClass, _T("No connection to Database."),<br />

IID_IMyClass, E_FAIL);<br />

// Get the Error Text from a resource string<br />

AtlReportError(CLSID_MyClass, IDS_DBERROR, IID_IMyClass, E_FAIL,<br />

_Module.m_hInstResource);<br />

To extract an error string from a failed method, use the Windows function<br />

GetErrorInfo. This is used to retrieve the last IErrorInfo object on the current<br />

thread and clears the current error state.<br />

Chapter 4 • <strong>Developer</strong> environments • 101

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!