API semplice GDI+

Windows GDI+ espone un'API flat costituita da circa 600 funzioni, implementate in Gdiplus.dll e dichiarate in Gdiplusflat.h. Le funzioni nell'API flat GDI+ sono incapsulate da una raccolta di circa 40 classi C++. È consigliabile non chiamare direttamente le funzioni nell'API flat. Ogni volta che si effettuano chiamate a GDI+, è necessario chiamare i metodi e le funzioni forniti dai wrapper C++. Il Servizio Supporto Tecnico Clienti Microsoft non fornirà supporto per il codice che chiama direttamente l'API flat.

In alternativa ai wrapper C++, Microsoft .NET Framework fornisce un set di classi wrapper con codice gestito per GDI+. I wrapper di codice gestito per GDI+ appartengono agli spazi dei nomi seguenti.

Entrambi i set di wrapper (C++ e codice gestito) usano un approccio orientato agli oggetti, quindi esistono alcune differenze tra il modo in cui i parametri vengono passati ai metodi wrapper e il modo in cui i parametri vengono passati alle funzioni nell'API flat. Ad esempio, uno dei wrapper C++ è la classe Matrix. Ogni oggetto Matrix ha un campo, nativeMatrix, che punta a una variabile interna di tipo GpMatrix. Quando si passano parametri a un metodo di un oggetto Matrix , tale metodo passa tali parametri (o un set di parametri correlati) insieme a una delle funzioni nell'API flat GDI+. Ma questo metodo passa anche il campo nativeMatrix (come parametro di input) alla funzione API flat. Il codice seguente illustra come il metodo Matrix::Shear chiama la funzione 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);
   ...
}

I costruttori Matrix passano l'indirizzo di una variabile puntatore GpMatrix (come parametro di output) alla funzione GdipCreateMatrix(GpMatrix **matrix). GdipCreateMatrix crea e inizializza una variabile GpMatrix interna e quindi assegna l'indirizzo di GpMatrix alla variabile puntatore. Il costruttore copia quindi il valore del puntatore nel campo nativeMatrix .

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

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

I metodi clone nelle classi wrapper non ricevono parametri, ma spesso passano due parametri alla funzione sottostante nell'API flat GDI+. Ad esempio, il metodo Matrix::Clone passa nativeMatrix (come parametro di input) e l'indirizzo di una variabile puntatore GpMatrix (come parametro di output) alla funzione GdipCloneMatrix . Il codice seguente illustra come il metodo Matrix::Clone chiama la funzione GdipCloneMatrix(GpMatrix *matrix, GpMatrix **cloneMatrix).

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

Le funzioni nell'API flat restituiscono un valore di tipo GpStatus. L'enumerazione GpStatus è identica all'enumerazione Status usata dai metodi wrapper. In GdiplusGpStubs.h GpStatus è definito come segue:

typedef Status GpStatus;

La maggior parte dei metodi nelle classi wrapper restituisce un valore di stato che indica se il metodo ha avuto esito positivo. Tuttavia, alcuni dei metodi wrapper restituiscono valori di stato. Quando si chiama un metodo wrapper che restituisce un valore di stato, il metodo wrapper passa i parametri appropriati alla funzione sottostante nell'API flat GDI+. Ad esempio, la classe Matrix ha un metodo Matrix::IsInvertible che passa il campo nativeMatrix e l'indirizzo di una variabile BOOL (come parametro di output) alla funzione GdipIsMatrixInvertible. Il codice seguente illustra come il metodo Matrix::IsInvertible chiama la funzione GdipIsMatrixInvertible(GDIPCONST GpMatrix *matrix, BOOL *result).

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

Un altro wrapper è la classe Color. Un oggetto Color ha un singolo campo di tipo ARGB, definito come DWORD. Quando si passa un oggetto Color a uno dei metodi wrapper, tale metodo passa il campo ARGB alla funzione sottostante nell'API flat GDI+. Il codice seguente illustra come il metodo Pen::SetColor chiama la funzione GdipSetPenColor(GpPen *pen, ARGB argb). Il metodo Color::GetValue restituisce il valore del campo ARGB .

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

Gli argomenti seguenti illustrano la relazione tra l'API flat GDI+ e i metodi wrapper C++.