API plana de GDI+

Windows GDI+ expone una API plana que consta de aproximadamente 600 funciones, que se implementan en Gdiplus.dll y se declaran en Gdiplusflat.h. Las funciones de la API plana de GDI+ se encapsulan mediante una colección de aproximadamente 40 clases de C++. Se recomienda no llamar directamente a las funciones de la API plana. Siempre que realice llamadas a GDI+, debe hacerlo llamando a los métodos y funciones proporcionados por los contenedores de C++. Los Servicios de soporte técnico de productos de Microsoft no proporcionarán compatibilidad con el código que llama directamente a la API plana.

Como alternativa a los contenedores de C++, Microsoft .NET Framework proporciona un conjunto de clases contenedoras de código administrado para GDI+. Los contenedores de código administrado para GDI+ pertenecen a los siguientes espacios de nombres.

Ambos conjuntos de contenedores (C++ y código administrado) usan un enfoque orientado a objetos, por lo que hay algunas diferencias entre la forma en que se pasan los parámetros al método contenedor y la forma en que los parámetros se pasan a las funciones de la API plana. Por ejemplo, uno de los contenedores de C++ es la clase Matrix . Cada objeto Matrix tiene un campo, nativeMatrix, que apunta a una variable interna de tipo GpMatrix. Cuando se pasan parámetros a un método de un objeto Matrix , ese método pasa esos parámetros (o un conjunto de parámetros relacionados) junto a una de las funciones de la API plana de GDI+. Pero ese método también pasa el campo nativeMatrix (como parámetro de entrada) a la función de API plana. El código siguiente muestra cómo el método Matrix::Shear llama a la función GdipShearMatrix(GpMatrix *matrix, REAL shearX, REAL shearY, GpMatrixOrder order).

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

Los constructores Matrix pasan la dirección de una variable de puntero GpMatrix (como parámetro de salida) a la función GdipCreateMatrix(GpMatrix **matrix). GdipCreateMatrix crea e inicializa una variable gpMatrix interna y, a continuación, asigna la dirección de GpMatrix a la variable de puntero. A continuación, el constructor copia el valor del puntero al campo nativeMatrix .

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

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

Los métodos clonados en las clases contenedoras no reciben parámetros, pero a menudo pasan dos parámetros a la función subyacente en la API plana de GDI+. Por ejemplo, el método Matrix::Clone pasa nativeMatrix (como parámetro de entrada) y la dirección de una variable de puntero GpMatrix (como parámetro de salida) a la función GdipCloneMatrix . El código siguiente muestra cómo el método Matrix::Clone llama a la función GdipCloneMatrix(GpMatrix *matrix, GpMatrix **cloneMatrix).

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

Las funciones de la API plana devuelven un valor de tipo GpStatus. La enumeración GpStatus es idéntica a la enumeración Status usada por los métodos contenedor. En GdiplusGpStubs.h, GpStatus se define de la siguiente manera:

typedef Status GpStatus;

La mayoría de los métodos de las clases contenedoras devuelven un valor de estado que indica si el método se realizó correctamente. Sin embargo, algunos de los métodos contenedores devuelven valores de estado. Cuando se llama a un método contenedor que devuelve un valor de estado, el método contenedor pasa los parámetros adecuados a la función subyacente en la API plana de GDI+. Por ejemplo, la clase Matrix tiene un método Matrix::IsInvertible que pasa el campo nativeMatrix y la dirección de una variable BOOL (como parámetro de salida) a la función GdipIsMatrixInvertible . El código siguiente muestra cómo el método Matrix::IsInvertible llama a la función GdipIsMatrixInvertible(GDIPCONST GpMatrix *matrix, BOOL *result).

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

Otro de los contenedores es la clase Color . Un objeto Color tiene un único campo de tipo ARGB, que se define como DWORD. Cuando se pasa un objeto Color a uno de los métodos contenedor, ese método pasa el campo ARGB a la función subyacente de la API plana de GDI+. El código siguiente muestra cómo el método Pen::SetColor llama a la función GdipSetPenColor(GpPen *pen, ARGB argb). El método Color::GetValue devuelve el valor del campo ARGB .

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

En los temas siguientes se muestra la relación entre la API plana de GDI+ y los métodos contenedoras de C++.