To reference ArcGIS interfaces, types, and objects, you will need to import the definitions into Visual C++ types. The #import command automates the creation of the necessary files required by the compiler. The #import was developed to support Direct-To-Com (see DTC Smart Types). When importing ArcGIS type libraries, there are a number of parameters that must be passed.
[VCPP] #pragma warning(push)
#pragma warning(disable : 4192) /* Ignore warnings for types that are
duplicated in win32 header files */
#pragma warning(disable : 4146) /* Ignore warnings for use of minus on unsigned
types */
#import "\Program Files\ArcGIS\com\esriSystem.olb" /* Type library to generate
C++ wrappers */ \
raw_interfaces_only, /* Don't add raw_ to method
names */ \
raw_native_types, /* Don't map to DTC smart
types */ \
no_namespace, /* Don't wrap with C++ name
space */ \
named_guids, /* Named guids and declspecs
*/ \
exclude("OLE_COLOR", "OLE_HANDLE", "VARTYPE") /* Exclude conflicting types
*/
#pragma warning(pop)
The main use of #import is to create C++ code for interface definitions and GUID constants (LIBID, CLSID, and IID) and to define smart pointers. The exclude (OLE_COLOR, OLE_HANDLE, VARTYPE) is required because Windows defines these to be unsigned longs, which conflicts with the ArcGIS definition of long - this was required to support Visual Basic as a client of ArcObjects, since Visual Basic has no support for unsigned types. There are no issues with excluding these.
You can view the code generated by #import in the type library header (.tlh) files, which are similar in format to a .h file. You may also find a type library implementation (.tli) file, which corresponds to a .cpp file. These files can be large but are only regenerated when the type libraries change.
There are many type libraries at ArcGIS 9 for different functional areas. You can start by importing those that contain the definitions you require. However, #import does not automatically include all other definitions that the imported type library requires. For example, when importing the type library esriGeometry, it will contain references to types that are defined in esriSystem, so esriSystem must be imported before esriGeometry.
A complete list of library dependencies can be found in the Overview topic for each library.
Choosing the minimum set of type libraries helps reduce compilation time, although this is not always significant. Here are some steps to help determine the minimum number type libraries required:
- Do a compilation and look at the "missing type definition" errors generated from code, for example, ICommand not found.
- Place a #import statement for the library you need a reference for into your stdafx.h file. Use the component help to assist in this task.
- Compile the project a second time.
- The compiler will issue errors for types it cannot resolve in the imported type libraries; these are typically type definitions such as WKSPoint or interfaces that are inherited into other interfaces. For example, if working with geometry objects such as points, start by importing esriGeometry. The compiler will issue various error messages such as:
c:\temp\sample\debug\esrigeometry.tlh(869) : error C2061: syntax error : identifier 'WKSPoint'
Looking up the definition of WKSPoint, you see it is defined in esriSystem. Therefore, importing esriSystem before esriGeometry will resolve all these issues.
Below is a typical list of imports for working with the ActiveX controls.
[VCPP] #pragma warning(push)
#pragma warning(disable : 4192) /* Ignore warnings for types that are
duplicated in win32 header files */
#pragma warning(disable : 4146) /* Ignore warnings for use of minus on unsigned
types */
#import "\Program Files\ArcGIS\com\esriSystem.olb" raw_interfaces_only,
raw_native_types, no_namespace, named_guids, exclude("OLE_COLOR",
"OLE_HANDLE", "VARTYPE")
#import "\Program Files\ArcGIS\com\esriSystemUI.olb" raw_interfaces_only,
raw_native_types, no_namespace, named_guids
#import "\Program Files\ArcGIS\com\esriGeometry.olb" raw_interfaces_only,
raw_native_types, no_namespace, named_guids
#import "\Program Files\ArcGIS\com\esriDisplay.olb" raw_interfaces_only,
raw_native_types, no_namespace, named_guids
#import "\Program Files\ArcGIS\com\esriOutput.olb" raw_interfaces_only,
raw_native_types, no_namespace, named_guids
#import "\Program Files\ArcGIS\com\esriGeoDatabase.olb" raw_interfaces_only,
raw_native_types, no_namespace, named_guids
#import "\Program Files\ArcGIS\com\esriCarto.olb" raw_interfaces_only,
raw_native_types, no_namespace, named_guids
// Some of the Engine controls
#import "\Program Files\ArcGIS\bin\TOCControl.ocx" raw_interfaces_only,
raw_native_types, no_namespace, named_guids
#import "\Program Files\ArcGIS\bin\ToolbarControl.ocx" raw_interfaces_only,
raw_native_types, no_namespace, named_guids
#import "\Program Files\ArcGIS\bin\MapControl.ocx" raw_interfaces_only,
raw_native_types, no_namespace, named_guids
#import "\Program Files\ArcGIS\bin\PageLayoutControl.ocx" raw_interfaces_only,
raw_native_types, no_namespace, named_guids
// additionally for 3D controls
#import "\Program Files\ArcGIS\com\esri3DAnalyst.olb" raw_interfaces_only,
raw_native_types, no_namespace, named_guids
#import "\Program Files\ArcGIS\com\esriGlobeCore.olb" raw_interfaces_only,
raw_native_types, no_namespace, named_guids
#import "\Program Files\ArcGIS\bin\SceneControl.ocx" raw_interfaces_only,
raw_native_types, no_namespace, named_guids
#import "\Program Files\ArcGIS\bin\GlobeControl.ocx" raw_interfaces_only,
raw_native_types, no_namespace, named_guids
#pragma warning(pop)
A similar issue arises when writing IDL that contains definitions from other type libraries. In this situation, use importlib just after the library definition. For example, writing an external command for ArcMap would require you to create a COM object implementing ICommand. This definition is in esriSystemUI and is imported into the IDL as follows:
[VCPP] library WALKTHROUGH1CPPLib
{
importlib("stdole32.tlb");
importlib("stdole2.tlb");
importlib("\Program Files\ArcGIS\com\esriSystemUI.olb");
coclass ZoomIn
{
[default] interface IUnknown;
interface ICommand;
}
};