GDI+ Flat API

Windows GDI+ exposes a flat API that consists of about 600 functions, which are implemented in Gdiplus.dll and declared in Gdiplusflat.h. The functions in the GDI+ flat API are wrapped by a collection of about 40 C++ classes. It is recommended that you do not directly call the functions in the flat API. Whenever you make calls to GDI+, you should do so by calling the methods and functions provided by the C++ wrappers. Microsoft Product Support Services will not provide support for code that calls the flat API directly.

As an alternative to the C++ wrappers, the Microsoft .NET Framework provides a set of managed-code wrapper classes for GDI+. The managed-code wrappers for GDI+ belong to the following namespaces.

Both sets of wrappers (C++ and managed code) use an object-oriented approach, so there are some differences between the way parameters are passed to the wrapper methods and the way parameters are passed to functions in the flat API. For example, one of the C++ wrappers is the Matrix class. Each Matrix object has a field, nativeMatrix, that points to an internal variable of type GpMatrix. When you pass parameters to a method of a Matrix object, that method passes those parameters (or a set of related parameters) along to one of the functions in the GDI+ flat API. But that method also passes the nativeMatrix field (as an input parameter) to the flat API function. The following code shows how the Matrix::Shear method calls the GdipShearMatrix(GpMatrix *matrix, REAL shearX, REAL shearY, GpMatrixOrder order) function.

Status Shear(
      IN REAL shearX, 
      IN REAL shearY,
      IN MatrixOrder order = MatrixOrderPrepend)
{
   ...
   GdipShearMatrix(nativeMatrix, shearX, shearY, order);
   ...
}

The Matrix constructors pass the address of a GpMatrix pointer variable (as an output parameter) to the GdipCreateMatrix(GpMatrix **matrix) function. GdipCreateMatrix creates and initializes an internal GpMatrix variable and then assigns the address of the GpMatrix to the pointer variable. Then the constructor copies the value of the pointer to the nativeMatrix field.

Matrix()
{
   GpMatrix *matrix = NULL;
   lastResult = DllExports::GdipCreateMatrix(&matrix);
   SetNativeMatrix(matrix);
}

VOID SetNativeMatrix(GpMatrix *nativeMatrix)
{
   this->nativeMatrix = nativeMatrix;
}

Clone methods in the wrapper classes receive no parameters but often pass two parameters to the underlying function in the GDI+ flat API. For example, the Matrix::Clone method passes nativeMatrix (as an input parameter) and the address of a GpMatrix pointer variable (as an output parameter) to the GdipCloneMatrix function. The following code shows how the Matrix::Clone method calls the GdipCloneMatrix(GpMatrix *matrix, GpMatrix **cloneMatrix) function.

Matrix *Clone() const
{
   GpMatrix *cloneMatrix = NULL;
   ...
   GdipCloneMatrix(nativeMatrix, &cloneMatrix));
   ...
   return new Matrix(cloneMatrix);
 }

The functions in the flat API return a value of type GpStatus. The GpStatus enumeration is identical to the Status enumeration used by the wrapper methods. In GdiplusGpStubs.h, GpStatus is defined as follows:

typedef Status GpStatus;

Most of the methods in the wrapper classes return a status value that indicates whether the method succeeded. However, some of the wrapper methods return state values. When you call a wrapper method that returns a state value, the wrapper method passes the appropriate parameters to the underlying function in the GDI+ flat API. For example, the Matrix class has an Matrix::IsInvertible method that passes the nativeMatrix field and the address of a BOOL variable (as an output parameter) to the GdipIsMatrixInvertible function. The following code shows how the Matrix::IsInvertible method calls the GdipIsMatrixInvertible(GDIPCONST GpMatrix *matrix, BOOL *result) function.

BOOL IsInvertible() const
{
   BOOL result = FALSE;
   ...
   GdipIsMatrixInvertible(nativeMatrix, &result);
   return result;
}

Another one of the wrappers is the Color class. A Color object has a single field of type ARGB, which is defined as a DWORD. When you pass a Color object to one of the wrapper methods, that method passes the ARGB field along to the underlying function in the GDI+ flat API. The following code shows how the Pen::SetColor method calls the GdipSetPenColor(GpPen *pen, ARGB argb) function. The Color::GetValue method returns the value of the ARGB field.

Status SetColor(IN const Color& color)
{
   ...
   GdipSetPenColor(nativePen, color.GetValue());
}

The following topics show the relationship between the GDI+ flat API and the C++ wrapper methods.