Display field properties for a feature class
DisplayFieldInfo.cpp
// Copyright 2011 ESRI
// 
// All rights reserved under the copyright laws of the United States
// and applicable international laws, treaties, and conventions.
// 
// You may freely redistribute and use this sample code, with or
// without modification, provided you include the original copyright
// notice and use restrictions.
// 
// See the use restrictions.
// 

  
#include "DisplayFieldInfo.h"

HRESULT DisplayFieldInfo(IFeatureClass* pFeatureClass)
{
  if (pFeatureClass == 0)
    return E_POINTER;

  // Name
  CComBSTR bsName;  
  ((IDatasetPtr) pFeatureClass)->get_Name(&bsName);
  std::wcerr << L"Dataset Name  : " << (BSTR) bsName << std::endl;

  // Alias Name
  ((IObjectClassPtr) pFeatureClass)->get_AliasName(&bsName);
  std::wcerr << L"Alias Name    : " << (BSTR) bsName << std::endl;  

  // Feature Class Type
  // In this section, the implementation of the code is shown with the raw 
  //   type (BSTR), as opposed to the smart pointer type (CComBSTR), in order 
  //   to show the AoAllocBSTR() and AoFreeBSTR() C++ API calls. However,
  //   as shown in a later section similar to this one, you could instead 
  //   use a CComBSTR for the string representation of the feature type.
  BSTR bsFeatureType;
  esriFeatureType featType;
  pFeatureClass->get_FeatureType(&featType);
  switch (featType)
  {
  case esriFTSimple :
    bsFeatureType = ::AoAllocBSTR(L"Simple"); 
    break;
  case esriFTSimpleJunction:
    bsFeatureType = ::AoAllocBSTR(L"Simple Junction"); 
    break;
  case esriFTSimpleEdge:
    bsFeatureType = ::AoAllocBSTR(L"Simple Edge"); 
    break;
  case esriFTComplexJunction:
    bsFeatureType = ::AoAllocBSTR(L"Complex Junction"); 
    break;
  case esriFTComplexEdge:
    bsFeatureType = ::AoAllocBSTR(L"Complex Edge"); 
    break;
  case esriFTAnnotation:
    bsFeatureType = ::AoAllocBSTR(L"Annotation"); 
    break;
  case esriFTCoverageAnnotation:
    bsFeatureType = ::AoAllocBSTR(L"Coverage Annotation"); 
    break;
  case esriFTDimension:
    bsFeatureType = ::AoAllocBSTR(L"Dimension"); 
    break;
  default:
    bsFeatureType = ::AoAllocBSTR(L"Not Supported");
  }
  std::wcerr << L"Feature Type  : " << (BSTR) bsFeatureType << std::endl;  
  ::AoFreeBSTR(bsFeatureType);

  // Display the Geometry Type
  CComBSTR bsShapeFieldName;
  pFeatureClass->get_ShapeFieldName(&bsShapeFieldName);
  long lngIndex;
  pFeatureClass->FindField(bsShapeFieldName, &lngIndex);
  // return S_FALSE since there were no errors, but we were not completely 
  //   sucessfull.
  if (lngIndex == -1) 
    return S_FALSE;

  IFieldsPtr ipFields;
  pFeatureClass->get_Fields(&ipFields);
  IFieldPtr ipField;
  ipFields->get_Field(lngIndex, &ipField);
  IGeometryDefPtr ipGeomDef;
  ipField->get_GeometryDef(&ipGeomDef);

  CComBSTR bsGeomType;
  esriGeometryType geomType;
  ipGeomDef->get_GeometryType(&geomType);
  switch (geomType)
  {
  case esriGeometryPoint:
    bsGeomType = L"Point"; 
    break;
  case esriGeometryMultipoint:
    bsGeomType = L"Multipoint"; 
    break;
  case esriGeometryPolyline:
    bsGeomType = L"Polyline"; 
    break;
  case esriGeometryPolygon:
    bsGeomType = L"Polygon"; 
    break;
  case esriGeometryMultiPatch:
    bsGeomType = L"MultiPatch"; 
    break;
  default:
    bsGeomType = L"Not Supported";
  }
  std::wcerr << L"Geometry Type : " << (BSTR) bsGeomType << std::endl;  

  // Now diplay information about the fields
  DisplayFields(pFeatureClass);

  return S_OK;
}

HRESULT DisplayFields(IFeatureClass* pFeatureClass)
{
  if (pFeatureClass == 0)
    return E_POINTER;

  IFieldsPtr ipFields;
  pFeatureClass->get_Fields(&ipFields);

  long lngFieldCount;
  ipFields->get_FieldCount(&lngFieldCount);
  IFieldPtr ipField;
  for (long i = 0; i < lngFieldCount; ++i)
  {
    if (FAILED(ipFields->get_Field(i, &ipField)))
      continue;
    DisplayFieldInformation(ipField);
  } 

  return S_OK;
}

HRESULT DisplayFieldInformation(IField* pField)
{
  if (pField == NULL)
    return E_POINTER;

  // Physical Name
  CComBSTR bsName;
  pField->get_Name(&bsName);
  std::wcerr << L"Physical Name : " << (BSTR) bsName << std::endl;  

  // Alias Name
  CComBSTR bsAlias;
  char strAlias[50];
  pField->get_AliasName(&bsAlias);
  std::wcerr << L"Alias Name    : " << (BSTR) bsAlias << std::endl;  

  // Field type
  esriFieldType fieldType;
  pField->get_Type(&fieldType);
  CComBSTR bsFieldType;
  switch(fieldType)
  {
  case esriFieldTypeSmallInteger:
    bsFieldType = L"Small Integer";
    break;
  case esriFieldTypeInteger:
    bsFieldType = L"Integer"; 
    break;
  case esriFieldTypeSingle:
    bsFieldType = L"Single"; 
    break;
  case esriFieldTypeDouble:
    bsFieldType = L"Double"; 
    break;
  case esriFieldTypeString:
    bsFieldType = L"String"; 
    break;
  case esriFieldTypeDate:
    bsFieldType = L"Date"; 
    break;
  case esriFieldTypeOID:
    bsFieldType = L"Object Identifer"; 
    break;
  case esriFieldTypeGeometry:
    bsFieldType = L"Geometry"; 
    break;
  case esriFieldTypeBlob:
    bsFieldType = L"Blob Storage"; 
    break;
  default:
    bsFieldType = L"Not Supported";
  }
  std::wcerr << L"Type          : " << (BSTR) bsFieldType << std::endl;

  // Field length
  long lLength;
  pField->get_Length(&lLength);
  std::cerr << "Length        : " << lLength << std::endl;

  // Field precision
  long lPrecision;
  pField->get_Precision(&lPrecision);
  std::cerr << "Precision     : " << lPrecision << std::endl;
    
  // Editable
  VARIANT_BOOL vbEditable;
  pField->get_Editable(&vbEditable);
  CComBSTR bsEditable = (vbEditable == VARIANT_TRUE ? L"true" : L"false");
  std::wcerr << L"Editable      : " << (BSTR) bsEditable << std::endl;

  // Default Value
  CComVariant varDefault;
  HRESULT hr = pField->get_DefaultValue(&varDefault);
  if (varDefault.vt == VT_NULL || FAILED(hr))
    std::cerr << "Default Value : <UnSpecified>" << std::endl;
  else
  {
    hr = varDefault.ChangeType(VT_BSTR);
    if (SUCCEEDED(hr))
      std::wcerr << L"Default Value : " << (BSTR) varDefault.bstrVal 
                 << std::endl;
  }
  
  return S_OK;
}